Skip to content

Commit

Permalink
Merge d87361b into f017f5a
Browse files Browse the repository at this point in the history
  • Loading branch information
rhcarvalho committed Mar 7, 2017
2 parents f017f5a + d87361b commit 9d10241
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 2 deletions.
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ python:
install:
- pip install tox-travis coveralls

env:
- TEST_SUITE=unit
- TEST_SUITE=integration

script:
- tox
# REVIEW(rhcarvalho): if our Travis account doesn't support more than one
# build at a time, there is no point in parallelizing unit/integration tests.
- "make test-$TEST_SUITE"

after_success:
- coveralls
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: test-unit
test-unit:
tox

.PHONY: test-integration
test-integration:
go test -v ./test/integration/...
12 changes: 12 additions & 0 deletions test/integration/README.md
Original file line number Diff line number Diff line change
@@ -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:

```
make test-integration
```
99 changes: 99 additions & 0 deletions test/integration/openshift_health_checker/common.go
Original file line number Diff line number Diff line change
@@ -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)
}
22 changes: 22 additions & 0 deletions test/integration/openshift_health_checker/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package test

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: "test_ping.yml",
Output: []string{"[test ping]"},
}.Run(t)
}

func TestFail(t *testing.T) {
PlaybookTest{
Path: "test_fail.yml",
ExitCode: 2,
Output: []string{"[test fail]", `"msg": "Failed as requested from task"`},
}.Run(t)
}
11 changes: 11 additions & 0 deletions test/integration/openshift_health_checker/test_fail.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 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: test fail
fail:
11 changes: 11 additions & 0 deletions test/integration/openshift_health_checker/test_ping.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 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: test ping
ping:
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import unittest

sys.path = [os.path.abspath(os.path.dirname(__file__) + "/../library/")] + sys.path
sys.path = [os.path.abspath(os.path.dirname(__file__) + "/../../library/")] + sys.path

# pylint: disable=import-error
from modify_yaml import set_key # noqa: E402
Expand Down

0 comments on commit 9d10241

Please sign in to comment.