From 634a8957e1cc29374a170aaa8c2113b8fbbfe7e4 Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Fri, 4 Nov 2016 18:30:34 +0100 Subject: Add stub of preflight integration tests --- .../integration/openshift_health_checker/common.go | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 test/integration/openshift_health_checker/common.go (limited to 'test/integration/openshift_health_checker/common.go') diff --git a/test/integration/openshift_health_checker/common.go b/test/integration/openshift_health_checker/common.go new file mode 100644 index 000000000..aea85342f --- /dev/null +++ b/test/integration/openshift_health_checker/common.go @@ -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) +} -- cgit v1.2.1