From c603d2bf9552ed169e5baf012ad44305a54056a4 Mon Sep 17 00:00:00 2001 From: Dmitriy Matrenichev Date: Fri, 7 Jun 2024 14:00:00 +0300 Subject: [PATCH] chore: output more info when `ExecuteCommandInPod` fails This should make investigating things like [this](https://github.com/siderolabs/talos/actions/runs/9411253542/job/25924192027) easier. Signed-off-by: Dmitriy Matrenichev --- internal/integration/api/common.go | 43 +++++++++++++++++++++--------- internal/integration/base/k8s.go | 16 ++++++++--- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/internal/integration/api/common.go b/internal/integration/api/common.go index ddb0047006..60dc436ceb 100644 --- a/internal/integration/api/common.go +++ b/internal/integration/api/common.go @@ -156,28 +156,47 @@ func (suite *CommonSuite) TestDNSResolver() { suite.Require().NoError(err) - defer suite.Clientset.CoreV1().Pods(namespace).Delete(suite.ctx, pod, metav1.DeleteOptions{}) //nolint:errcheck + suite.T().Cleanup(func() { + cleanUpCtx, cleanupCancel := context.WithTimeout(context.Background(), time.Minute) + defer cleanupCancel() + + suite.Require().NoError( + suite.Clientset.CoreV1().Pods(namespace).Delete(cleanUpCtx, pod, metav1.DeleteOptions{}), + ) + }) // wait for the pod to be ready suite.Require().NoError(suite.WaitForPodToBeRunning(suite.ctx, time.Minute, namespace, pod)) - stdout, stderr, err := suite.ExecuteCommandInPod(suite.ctx, namespace, pod, "wget https://www.google.com/") - suite.Require().NoError(err) + stdout, stderr, err := suite.ExecuteCommandInPod(suite.ctx, namespace, pod, "wget -S https://www.google.com/") + suite.Assert().NoError(err) + suite.Assert().Equal("", stdout) + suite.Assert().Contains(stderr, "'index.html' saved") - suite.Require().Equal("", stdout) - suite.Require().Contains(stderr, "'index.html' saved") + if suite.T().Failed() { + suite.T().FailNow() + } _, stderr, err = suite.ExecuteCommandInPod(suite.ctx, namespace, pod, "apk add --update bind-tools") - suite.Require().NoError(err) - suite.Require().Empty(stderr) + + suite.Assert().NoError(err) + suite.Assert().Empty(stderr, "stderr: %s", stderr) + + if suite.T().Failed() { + suite.T().FailNow() + } stdout, stderr, err = suite.ExecuteCommandInPod(suite.ctx, namespace, pod, "dig really-long-record.dev.siderolabs.io") - suite.Require().NoError(err) - suite.Require().Contains(stdout, "status: NOERROR") - suite.Require().Contains(stdout, "ANSWER: 34") - suite.Require().NotContains(stdout, "status: NXDOMAIN") - suite.Require().Equal(stderr, "") + suite.Assert().NoError(err) + suite.Assert().Contains(stdout, "status: NOERROR") + suite.Assert().Contains(stdout, "ANSWER: 34") + suite.Assert().NotContains(stdout, "status: NXDOMAIN") + suite.Assert().Equal(stderr, "") + + if suite.T().Failed() { + suite.T().FailNow() + } } func init() { diff --git a/internal/integration/base/k8s.go b/internal/integration/base/k8s.go index 6bd22373a1..ca5ac3ab23 100644 --- a/internal/integration/base/k8s.go +++ b/internal/integration/base/k8s.go @@ -14,6 +14,7 @@ import ( "fmt" "io" "slices" + "strings" "time" "github.com/siderolabs/gen/xslices" @@ -304,17 +305,26 @@ func (k8sSuite *K8sSuite) ExecuteCommandInPod(ctx context.Context, namespace, po return "", "", err } - var stdout, stderr bytes.Buffer + var stdout, stderr strings.Builder err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{ Stdout: &stdout, Stderr: &stderr, }) if err != nil { - return "", "", err + k8sSuite.T().Logf( + "error executing command in pod %s/%s: %v\n\ncommand %q stdout:\n%s\n\ncommand %q stderr:\n%s", + namespace, + podName, + err, + command, + stdout.String(), + command, + stderr.String(), + ) } - return stdout.String(), stderr.String(), nil + return stdout.String(), stderr.String(), err } // GetPodsWithLabel returns the pods with the given label in the specified namespace.