Skip to content

Commit 62ee4be

Browse files
committed
[aiconformance]: dump per-test kube objects into artifacts
1 parent 8aca9ac commit 62ee4be

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

  • tests/e2e/scenarios/ai-conformance/validators

tests/e2e/scenarios/ai-conformance/validators/kube.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ limitations under the License.
1717
package validators
1818

1919
import (
20+
"bytes"
2021
"context"
2122
"fmt"
23+
"os"
24+
"os/exec"
25+
"path/filepath"
2226
"strings"
2327
"time"
2428

@@ -186,6 +190,8 @@ func (h *ValidatorHarness) TestNamespace() string {
186190
h.testNamespace = ns
187191

188192
h.t.Cleanup(func() {
193+
h.dumpNamespaceResources(ns)
194+
189195
h.Logf("Deleting test namespace %q", ns)
190196
ctx := context.WithoutCancel(h.Context())
191197
err := h.DynamicClient().Resource(namespaceGVR).Delete(ctx, ns, metav1.DeleteOptions{})
@@ -204,3 +210,58 @@ func (h *ValidatorHarness) ApplyManifest(namespace string, manifestPath string)
204210
h.Logf("Applying manifest %q to namespace %q", manifestPath, namespace)
205211
h.ShellExec(fmt.Sprintf("kubectl apply -n %s -f %s", namespace, manifestPath))
206212
}
213+
214+
// dumpNamespaceResources dumps key resources from the namespace to the artifacts directory for debugging.
215+
func (h *ValidatorHarness) dumpNamespaceResources(ns string) {
216+
artifactsDir := os.Getenv("ARTIFACTS")
217+
if artifactsDir == "" {
218+
artifactsDir = "_artifacts"
219+
}
220+
221+
testName := strings.ReplaceAll(h.t.Name(), "/", "_")
222+
clusterInfoDir := filepath.Join(artifactsDir, "per-test", testName, "cluster-info", ns)
223+
if err := os.MkdirAll(clusterInfoDir, 0o755); err != nil {
224+
h.Logf("failed to create cluster-info directory: %v", err)
225+
return
226+
}
227+
228+
resourceTypes := []string{
229+
"pods",
230+
"jobs",
231+
"deployments",
232+
"statefulsets",
233+
"services",
234+
"events",
235+
}
236+
237+
for _, resourceType := range resourceTypes {
238+
if err := h.dumpResource(ns, resourceType, filepath.Join(clusterInfoDir, resourceType+".yaml")); err != nil {
239+
h.Logf("failed to dump resource %s: %v", resourceType, err)
240+
}
241+
}
242+
}
243+
244+
// dumpResource runs kubectl get for a resource type and writes the output to a file.
245+
// Errors are logged but do not fail the test.
246+
func (h *ValidatorHarness) dumpResource(ns string, resourceType string, outputPath string) error {
247+
args := []string{"get", resourceType}
248+
if ns != "" {
249+
args = append(args, "-n", ns)
250+
}
251+
args = append(args, "-o", "yaml")
252+
cmd := exec.CommandContext(context.WithoutCancel(h.Context()), "kubectl", args...)
253+
var stdout bytes.Buffer
254+
var stderr bytes.Buffer
255+
cmd.Stdout = &stdout
256+
cmd.Stderr = &stderr
257+
258+
if err := cmd.Run(); err != nil {
259+
return fmt.Errorf("failed to dump %s in namespace %s: %v (stderr: %s)", resourceType, ns, err, stderr.String())
260+
}
261+
262+
if err := os.WriteFile(outputPath, stdout.Bytes(), 0o644); err != nil {
263+
return fmt.Errorf("failed to write %s dump to %s: %w", resourceType, outputPath, err)
264+
}
265+
266+
return nil
267+
}

0 commit comments

Comments
 (0)