mirror of
https://github.com/openshift/openshift-ansible.git
synced 2026-02-05 06:46:04 +01:00
Add stub of preflight integration tests
This commit is contained in:
committed by
Luke Meyer
parent
ff8356b926
commit
634a8957e1
@@ -12,3 +12,4 @@ coverage==4.3.4
|
||||
mock==2.0.0
|
||||
pytest==3.0.7
|
||||
pytest-cov==2.4.0
|
||||
docker-py==1.10.6
|
||||
|
||||
12
test/integration/README.md
Normal file
12
test/integration/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Integration tests
|
||||
|
||||
Integration tests exercise the OpenShift Ansible playbooks by performing
|
||||
simulated installations in Docker containers.
|
||||
|
||||
## Running the tests
|
||||
|
||||
From the repository root, run with:
|
||||
|
||||
```
|
||||
tox -e integration
|
||||
```
|
||||
99
test/integration/openshift_health_checker/common.go
Normal file
99
test/integration/openshift_health_checker/common.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A PlaybookTest executes a given Ansible playbook and checks the exit code and
|
||||
// output contents.
|
||||
type PlaybookTest struct {
|
||||
// inputs
|
||||
Path string
|
||||
// expected outputs
|
||||
ExitCode int
|
||||
Output []string // zero or more strings that should be in the output
|
||||
}
|
||||
|
||||
// Run runs the PlaybookTest.
|
||||
func (p PlaybookTest) Run(t *testing.T) {
|
||||
// A PlaybookTest is intended to be run in parallel with other tests.
|
||||
t.Parallel()
|
||||
|
||||
cmd := exec.Command("ansible-playbook", p.Path)
|
||||
cmd.Env = append(os.Environ(), "ANSIBLE_FORCE_COLOR=1")
|
||||
b, err := cmd.CombinedOutput()
|
||||
|
||||
// Check exit code.
|
||||
if (err == nil) && (p.ExitCode != 0) {
|
||||
p.checkExitCode(t, 0, p.ExitCode, cmd, b)
|
||||
}
|
||||
if (err != nil) && (p.ExitCode == 0) {
|
||||
got, ok := getExitCode(err)
|
||||
if !ok {
|
||||
t.Logf("unexpected error (%T): %[1]v", err)
|
||||
p.logCmdAndOutput(t, cmd, b)
|
||||
t.FailNow()
|
||||
}
|
||||
p.checkExitCode(t, got, p.ExitCode, cmd, b)
|
||||
}
|
||||
|
||||
// Check output contents.
|
||||
var missing []string
|
||||
for _, s := range p.Output {
|
||||
if !bytes.Contains(b, []byte(s)) {
|
||||
missing = append(missing, s)
|
||||
}
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
t.Logf("missing in output: %q", missing)
|
||||
p.logCmdAndOutput(t, cmd, b)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// getExitCode returns an exit code and true if the exit code could be taken
|
||||
// from err, false otherwise.
|
||||
// The implementation is GOOS-specific, and currently only supports Linux.
|
||||
func getExitCode(err error) (int, bool) {
|
||||
exitErr, ok := err.(*exec.ExitError)
|
||||
if !ok {
|
||||
return -1, false
|
||||
}
|
||||
waitStatus, ok := exitErr.Sys().(syscall.WaitStatus)
|
||||
if !ok {
|
||||
return -1, false
|
||||
}
|
||||
return waitStatus.ExitStatus(), true
|
||||
}
|
||||
|
||||
// checkExitCode marks the test as failed when got is different than want.
|
||||
func (p PlaybookTest) checkExitCode(t *testing.T, got, want int, cmd *exec.Cmd, output []byte) {
|
||||
if got == want {
|
||||
return
|
||||
}
|
||||
t.Logf("got exit code %v, want %v", got, want)
|
||||
p.logCmdAndOutput(t, cmd, output)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// logCmdAndOutput logs how to re-run a command and a summary of the output of
|
||||
// its last execution for debugging.
|
||||
func (p PlaybookTest) logCmdAndOutput(t *testing.T, cmd *exec.Cmd, output []byte) {
|
||||
const maxLines = 10
|
||||
lines := bytes.Split(bytes.TrimRight(output, "\n"), []byte("\n"))
|
||||
if len(lines) > maxLines {
|
||||
lines = append([][]byte{[]byte("...")}, lines[len(lines)-maxLines:len(lines)]...)
|
||||
}
|
||||
output = bytes.Join(lines, []byte("\n"))
|
||||
dir, err := filepath.Abs(cmd.Dir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t.Logf("\n$ (cd %s && %s)\n%s", dir, strings.Join(cmd.Args, " "), output)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. ".."
|
||||
)
|
||||
|
||||
// TestPing and TestFail below are just examples of tests that involve running
|
||||
// 'ansible-playbook' with a given playbook and verifying the outcome. Real
|
||||
// tests look similar, but call more interesting playbooks.
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
PlaybookTest{
|
||||
Path: "playbooks/test_ping.yml",
|
||||
Output: []string{"[test ping]"},
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestFail(t *testing.T) {
|
||||
PlaybookTest{
|
||||
Path: "playbooks/test_fail.yml",
|
||||
ExitCode: 2,
|
||||
Output: []string{"[test fail]", `"msg": "Failed as requested from task"`},
|
||||
}.Run(t)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
# This is just a placeholder playbook. Our aim is to make it:
|
||||
# 1. Build one or more Docker images with a certain interesting state;
|
||||
# 2. Ensure one or more containers (with random names) are running with the
|
||||
# latest build of the image;
|
||||
# 3. Run the byo OpenShift installation playbook targeting the container.
|
||||
- hosts: localhost
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: waste some time
|
||||
pause:
|
||||
seconds: 1
|
||||
- name: test fail
|
||||
fail:
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
# This is just a placeholder playbook. Our aim is to make it:
|
||||
# 1. Build one or more Docker images with a certain interesting state;
|
||||
# 2. Ensure one or more containers (with random names) are running with the
|
||||
# latest build of the image;
|
||||
# 3. Run the byo OpenShift installation playbook targeting the container.
|
||||
- hosts: localhost
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: waste some time
|
||||
pause:
|
||||
seconds: 1
|
||||
- name: test ping
|
||||
ping:
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- include: setup_container.yml
|
||||
vars:
|
||||
name: preflight_fail_all
|
||||
|
||||
- name: Run preflight checks
|
||||
include: ../../../../../playbooks/byo/openshift-preflight/check.yml
|
||||
|
||||
# - include: tasks/teardown_container.yml
|
||||
# vars:
|
||||
# name: preflight_fail_all
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# Required vars:
|
||||
# * name = name of the container to be started
|
||||
|
||||
- name: Start CentOS 7 container
|
||||
gather_facts: no
|
||||
hosts: localhost
|
||||
connection: local
|
||||
vars:
|
||||
container_name: openshift_ansible_test_{{ name }}
|
||||
tasks:
|
||||
- name: start container
|
||||
docker_container:
|
||||
name: "{{ container_name }}"
|
||||
image: centos:7
|
||||
command: sleep infinity
|
||||
recreate: yes
|
||||
- name: add host
|
||||
add_host:
|
||||
name: "{{ container_name }}"
|
||||
ansible_connection: docker
|
||||
groups: OSEv3,masters,nodes
|
||||
deployment_type: origin
|
||||
@@ -0,0 +1,24 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. ".."
|
||||
)
|
||||
|
||||
func TestPreflightFailAll(t *testing.T) {
|
||||
PlaybookTest{
|
||||
Path: "playbooks/preflight_fail_all.yml",
|
||||
ExitCode: 2,
|
||||
Output: []string{
|
||||
"Failure summary",
|
||||
"Cannot install all of the necessary packages",
|
||||
"origin-clients",
|
||||
"origin-master",
|
||||
"origin-node",
|
||||
"origin-sdn-ovs",
|
||||
"python-httplib2",
|
||||
"failed=1",
|
||||
},
|
||||
}.Run(t)
|
||||
}
|
||||
8
tox.ini
8
tox.ini
@@ -3,6 +3,7 @@ minversion=2.3.1
|
||||
envlist =
|
||||
py{27,35}-{flake8,pylint,unit}
|
||||
py27-{yamllint,ansible_syntax,generate_validation}
|
||||
integration
|
||||
skipsdist=True
|
||||
skip_missing_interpreters=True
|
||||
|
||||
@@ -13,6 +14,8 @@ deps =
|
||||
-rtest-requirements.txt
|
||||
py35-flake8: flake8-bugbear==17.3.0
|
||||
|
||||
whitelist_externals = env
|
||||
|
||||
commands =
|
||||
unit: pip install -e utils
|
||||
unit: pytest {posargs}
|
||||
@@ -22,3 +25,8 @@ commands =
|
||||
generate_validation: python setup.py generate_validation
|
||||
# TODO(rhcarvalho): check syntax of other important entrypoint playbooks
|
||||
ansible_syntax: python setup.py ansible_syntax
|
||||
|
||||
# Unset GOPATH because tests use relative imports. This should be removed if
|
||||
# we require openshift-ansible to live in a Go work space and use absolute
|
||||
# imports in tests (desirable).
|
||||
integration: env -u GOPATH go test -v ./test/integration/...
|
||||
|
||||
Reference in New Issue
Block a user