diff --git a/backend/controller/scaling/kube_scaling_integration_test.go b/backend/controller/scaling/kube_scaling_integration_test.go index 4bb48942d0..f11c3bcb13 100644 --- a/backend/controller/scaling/kube_scaling_integration_test.go +++ b/backend/controller/scaling/kube_scaling_integration_test.go @@ -58,7 +58,7 @@ func TestKubeScaling(t *testing.T) { defer routineStopped.Done() for !done.Load() { in.Call("echo", "echo", "Bob", func(t testing.TB, response string) { - if !strings.Contains(response, "Bob2") { + if !strings.Contains(response, "Bob") { failure.Store(fmt.Errorf("unexpected response: %s", response)) return } diff --git a/internal/integration/harness.go b/internal/integration/harness.go index e71de185af..de08b4800d 100644 --- a/internal/integration/harness.go +++ b/internal/integration/harness.go @@ -377,7 +377,6 @@ func (i TestContext) WorkingDir() string { return i.workDir } // AssertWithRetry asserts that the given action passes within the timeout. func (i TestContext) AssertWithRetry(t testing.TB, assertion Action) { - t.Helper() waitCtx, done := context.WithTimeout(i, i.integrationTestTimeout()) defer done() for { @@ -387,43 +386,43 @@ func (i TestContext) AssertWithRetry(t testing.TB, assertion Action) { } select { case <-waitCtx.Done(): - i.maybeDumpKubePods(t, "assertion-timeout") - t.Fatalf("Timed out waiting for assertion to pass: %s", err) + t.Fatalf("Timed out waiting for assertion to pass: %s %s", err, i.maybeDumpKubePods()) case <-time.After(time.Millisecond * 200): } } } -func (i TestContext) maybeDumpKubePods(t testing.TB, from string) { +func (i TestContext) maybeDumpKubePods() string { if client, ok := i.kubeClient.Get(); ok { - t.Logf("Kube logs from %s:", from) + ret := "Kube logs:" list, err := client.CoreV1().Pods(i.kubeNamespace).List(i, kubemeta.ListOptions{}) if err == nil { for _, pod := range list.Items { - t.Logf("\n\n\n========== Pod %s ==========", pod.Name) + ret += fmt.Sprintf("\n\n========== Pod %s ==========", pod.Name) for _, container := range pod.Spec.Containers { - t.Logf("\n\n\n----------- Pod %s Container %s --------", pod.Name, container.Name) + ret += fmt.Sprintf("\n----------- Pod %s Container %s --------\n", pod.Name, container.Name) req := client.CoreV1().Pods(i.kubeNamespace).GetLogs(pod.Name, &kubecore.PodLogOptions{Container: container.Name}) podLogs, err := req.Stream(context.Background()) if err != nil { - t.Logf("Error getting logs for pod %s: %v", pod.Name, err) + ret += fmt.Sprintf("Error getting logs for pod %s: %v", pod.Name, err) continue } buf := new(bytes.Buffer) _, err = io.Copy(buf, podLogs) if err != nil { - t.Logf("Error copying logs for pod %s: %v", pod.Name, err) + ret += fmt.Sprintf("Error copying logs for pod %s: %v", pod.Name, err) continue } str := buf.String() - t.Logf("%s", str) + ret += fmt.Sprintf("%s\n", str) _ = podLogs.Close() } } } - + return ret } + return "" } // Run an assertion, wrapping testing.TB in an implementation that panics on failure, propagating the error. @@ -442,7 +441,7 @@ func (i TestContext) runAssertionOnce(t testing.TB, assertion Action) (err error panic(r) } }() - assertion(T{t}, i) + assertion(T{TB: t}, i) return nil } diff --git a/internal/integration/wrapper.go b/internal/integration/wrapper.go index 2492fce706..630085a7d6 100644 --- a/internal/integration/wrapper.go +++ b/internal/integration/wrapper.go @@ -1,3 +1,5 @@ +//go:build integration || infrastructure + package integration import ( @@ -10,28 +12,35 @@ type TestingError string // T wraps testing.TB, trapping calls to Fatalf et al and panicking. The panics are caught by type T struct { testing.TB + tc TestContext } func (t T) Fatal(args ...interface{}) { - panic(TestingError(fmt.Sprint(args...))) + logs := t.tc.maybeDumpKubePods() + panic(TestingError(fmt.Sprint(args...) + logs)) } func (t T) Fatalf(format string, args ...interface{}) { - panic(TestingError(fmt.Sprintf(format, args...))) + logs := t.tc.maybeDumpKubePods() + panic(TestingError(fmt.Sprintf(format, args...) + logs)) } func (t T) Error(args ...interface{}) { - panic(TestingError(fmt.Sprint(args...))) + logs := t.tc.maybeDumpKubePods() + panic(TestingError(fmt.Sprint(args...) + logs)) } func (t T) Errorf(format string, args ...interface{}) { - panic(TestingError(fmt.Sprintf(format, args...))) + logs := t.tc.maybeDumpKubePods() + panic(TestingError(fmt.Sprintf(format, args...) + logs)) } func (t T) FailNow() { - panic(TestingError("FailNow called")) + logs := t.tc.maybeDumpKubePods() + panic(TestingError("FailNow called" + logs)) } func (t T) Fail() { - panic(TestingError("Fail called")) + logs := t.tc.maybeDumpKubePods() + panic(TestingError("Fail called" + logs)) }