Skip to content

Commit f631894

Browse files
committed
Reuse DumpPodsAndLogs.
Signed-off-by: Revital Sur <eres@il.ibm.com>
1 parent ba1a1ab commit f631894

3 files changed

Lines changed: 47 additions & 39 deletions

File tree

test/coordinator/e2e/coordinator/coordinator_test.go

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,7 @@ func runCoordinatorPipeline(body []byte, expectedSteps []string, expectedImages
127127
if !ginkgo.CurrentSpecReport().Failed() && !printCoordinatorLogs {
128128
return
129129
}
130-
dumpDeploymentLogs(nsName, "llm-d-coordinator", "coordinator")
131-
dumpDeploymentLogs(nsName, eppName+"-encode", "epp")
132-
dumpDeploymentLogs(nsName, eppName+"-prefill", "epp")
133-
dumpDeploymentLogs(nsName, eppName+"-decode", "epp")
134-
dumpDeploymentLogs(nsName, "envoy", "envoy")
130+
testutils.DumpPodsAndLogs(testConfig, nsName, testutils.WithFullLogs())
135131
dumpEnvoyClusters(nsName)
136132
})
137133

@@ -177,21 +173,6 @@ func runCoordinatorPipeline(body []byte, expectedSteps []string, expectedImages
177173
verifyCoordinatorSteps(nsName, expectedSteps, expectedImages, true, true)
178174
}
179175

180-
// dumpDeploymentLogs writes a deployment's container logs to the Ginkgo output.
181-
// A kubectl error is reported inline rather than failing the spec.
182-
func dumpDeploymentLogs(nsName, deployment, container string) {
183-
args := []string{"logs", "deployment/" + deployment, "-c", container, "--namespace=" + nsName}
184-
if k8sContext != "" {
185-
args = append(args, "--context="+k8sContext)
186-
}
187-
out, err := exec.Command("kubectl", args...).CombinedOutput()
188-
if err != nil {
189-
fmt.Fprintf(ginkgo.GinkgoWriter, "\n--- %s logs (kubectl error: %v) ---\n%s\n---\n", deployment, err, string(out))
190-
return
191-
}
192-
fmt.Fprintf(ginkgo.GinkgoWriter, "\n--- %s logs ---\n%s\n---\n", deployment, string(out))
193-
}
194-
195176
// dumpEnvoyClusters writes Envoy's admin /clusters (resolved endpoints and health
196177
// per cluster) to the Ginkgo output. Best-effort; yields nothing if the envoy
197178
// image lacks a usable HTTP client.

test/coordinator/e2e/coordinator/setup_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,18 @@ func applyManifest(path string, subs map[string]string, excludeKinds ...string)
245245
// churn per spec. Mirrors the non-coordinator e2e, which creates the EPP
246246
// Services and RBAC once in its setup and recreates only the Deployment per test.
247247
func createStableInfra() []string {
248-
objects := make([]string, 0, 12)
248+
eppManifests := []string{encodeEPPManifest, prefillEPPManifest, decodeEPPManifest}
249+
// Coordinator Service + ServiceAccount, plus Service + ServiceAccount +
250+
// RoleBinding per EPP.
251+
objects := make([]string, 0, 2+len(eppManifests)*3)
249252

250253
docs := e2eutil.RunKustomize(coordinatorComponentDir)
251254
docs = e2eutil.FilterKinds(docs, "ConfigMap", "Deployment")
252255
docs = e2eutil.SubstituteMany(docs, coordinatorSubstitutions())
253256
docs = e2eutil.RemoveEmptyArgs(docs)
254257
objects = append(objects, testutils.CreateObjsFromYaml(testConfig, docs, getNamespace())...)
255258

256-
for _, manifest := range []string{encodeEPPManifest, prefillEPPManifest, decodeEPPManifest} {
259+
for _, manifest := range eppManifests {
257260
objects = append(objects, applyManifest(manifest, eppSubstitutions(), "Deployment")...)
258261
}
259262
return objects

test/utils/dump.go

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,36 @@ const (
3737
dumpLimitBytes = int64(1 << 20) // 1MiB
3838
)
3939

40+
// dumpConfig controls how much container log DumpPodsAndLogs fetches.
41+
type dumpConfig struct {
42+
tailLines int64
43+
limitBytes int64
44+
}
45+
46+
// DumpOption overrides DumpPodsAndLogs defaults.
47+
type DumpOption func(*dumpConfig)
48+
49+
// WithFullLogs streams complete container logs instead of the default tail, for
50+
// callers that need the entire log (e.g. a gateway access log). A non-positive
51+
// tail/limit disables that cap.
52+
func WithFullLogs() DumpOption {
53+
return func(c *dumpConfig) { c.tailLines, c.limitBytes = 0, 0 }
54+
}
55+
4056
// DumpPodsAndLogs prints pod statuses and container logs for the given namespace
4157
// to the Ginkgo writer. Call this before cleanup to ensure the information is
4258
// available when CI tests fail.
43-
func DumpPodsAndLogs(cfg *TestConfig, nsName string) {
59+
func DumpPodsAndLogs(cfg *TestConfig, nsName string, opts ...DumpOption) {
4460
if cfg == nil || cfg.KubeCli == nil {
4561
ginkgo.GinkgoWriter.Println("Skipping pod dump: cluster not initialized")
4662
return
4763
}
4864

65+
dc := dumpConfig{tailLines: dumpTailLines, limitBytes: dumpLimitBytes}
66+
for _, opt := range opts {
67+
opt(&dc)
68+
}
69+
4970
ginkgo.GinkgoWriter.Printf("\n=== Dumping pod states and logs (namespace: %s) ===\n", nsName)
5071

5172
ctx, cancel := context.WithTimeout(cfg.Context, dumpTimeout)
@@ -113,15 +134,15 @@ func DumpPodsAndLogs(cfg *TestConfig, nsName string) {
113134

114135
for _, c := range pod.Spec.InitContainers {
115136
if restarted[c.Name] {
116-
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, true)
137+
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, true, dc)
117138
}
118-
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, false)
139+
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, false, dc)
119140
}
120141
for _, c := range pod.Spec.Containers {
121142
if restarted[c.Name] {
122-
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, true)
143+
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, true, dc)
123144
}
124-
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, false)
145+
dumpContainerLogs(ctx, cfg, pod.Namespace, pod.Name, c.Name, false, dc)
125146
}
126147
}
127148
ginkgo.GinkgoWriter.Println("=== End of pod dump ===")
@@ -138,15 +159,15 @@ func printContainerStatus(kind string, cs corev1.ContainerStatus) {
138159
ginkgo.GinkgoWriter.Println(status)
139160
}
140161

141-
func dumpContainerLogs(ctx context.Context, cfg *TestConfig, nsName, podName, containerName string, previous bool) {
142-
tailLines := dumpTailLines
143-
limitBytes := dumpLimitBytes
144-
req := cfg.KubeCli.CoreV1().Pods(nsName).GetLogs(podName, &corev1.PodLogOptions{
145-
Container: containerName,
146-
TailLines: &tailLines,
147-
LimitBytes: &limitBytes,
148-
Previous: previous,
149-
})
162+
func dumpContainerLogs(ctx context.Context, cfg *TestConfig, nsName, podName, containerName string, previous bool, dc dumpConfig) {
163+
logOpts := &corev1.PodLogOptions{Container: containerName, Previous: previous}
164+
if dc.tailLines > 0 {
165+
logOpts.TailLines = &dc.tailLines
166+
}
167+
if dc.limitBytes > 0 {
168+
logOpts.LimitBytes = &dc.limitBytes
169+
}
170+
req := cfg.KubeCli.CoreV1().Pods(nsName).GetLogs(podName, logOpts)
150171
stream, err := req.Stream(ctx)
151172
if err != nil {
152173
ginkgo.GinkgoWriter.Printf(" [logs] %s/%s: failed to stream logs: %v\n", podName, containerName, err)
@@ -163,9 +184,12 @@ func dumpContainerLogs(ctx context.Context, cfg *TestConfig, nsName, podName, co
163184
ginkgo.GinkgoWriter.Printf(" [logs] %s/%s: failed to read logs: %v\n", podName, containerName, err)
164185
return
165186
}
166-
label := fmt.Sprintf("last %d lines", dumpTailLines)
187+
scope := "full log"
188+
if dc.tailLines > 0 {
189+
scope = fmt.Sprintf("last %d lines", dc.tailLines)
190+
}
167191
if previous {
168-
label = fmt.Sprintf("previous instance, last %d lines", dumpTailLines)
192+
scope = "previous instance, " + scope
169193
}
170-
ginkgo.GinkgoWriter.Printf(" [logs] %s/%s (%s):\n%s\n", podName, containerName, label, buf.String())
194+
ginkgo.GinkgoWriter.Printf(" [logs] %s/%s (%s):\n%s\n", podName, containerName, scope, buf.String())
171195
}

0 commit comments

Comments
 (0)