Skip to content

Commit 0963e79

Browse files
committed
feat: add OperationMeta support to text output
Use type switch on StepMeta.GetContext() to handle both CompositionMeta and OperationMeta context types in text output formatting. OperationMeta displays Operation name and UID fields instead of XR/Composition fields.
1 parent cebb131 commit 0963e79

File tree

2 files changed

+121
-6
lines changed

2 files changed

+121
-6
lines changed

server/server.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,23 @@ func (i *Inspector) logJSON(eventType string, meta *pipelinev1alpha1.StepMeta, p
142142

143143
func (i *Inspector) logText(eventType string, meta *pipelinev1alpha1.StepMeta, payload any, errMsg string) {
144144
_, _ = fmt.Fprintf(i.out, "=== %s ===\n", eventType)
145-
cm := meta.GetCompositionMeta()
146-
_, _ = fmt.Fprintf(i.out, " XR: %s/%s (%s)\n", cm.GetCompositeResourceApiVersion(), cm.GetCompositeResourceKind(), cm.GetCompositeResourceName())
147-
_, _ = fmt.Fprintf(i.out, " XR UID: %s\n", cm.GetCompositeResourceUid())
148-
if ns := cm.GetCompositeResourceNamespace(); ns != "" {
149-
_, _ = fmt.Fprintf(i.out, " XR NS: %s\n", ns)
145+
146+
// Handle context-specific fields using type switch (idiomatic for oneofs).
147+
switch ctx := meta.GetContext().(type) {
148+
case *pipelinev1alpha1.StepMeta_CompositionMeta:
149+
cm := ctx.CompositionMeta
150+
_, _ = fmt.Fprintf(i.out, " XR: %s/%s (%s)\n", cm.GetCompositeResourceApiVersion(), cm.GetCompositeResourceKind(), cm.GetCompositeResourceName())
151+
_, _ = fmt.Fprintf(i.out, " XR UID: %s\n", cm.GetCompositeResourceUid())
152+
if ns := cm.GetCompositeResourceNamespace(); ns != "" {
153+
_, _ = fmt.Fprintf(i.out, " XR NS: %s\n", ns)
154+
}
155+
_, _ = fmt.Fprintf(i.out, " Composition: %s\n", cm.GetCompositionName())
156+
case *pipelinev1alpha1.StepMeta_OperationMeta:
157+
om := ctx.OperationMeta
158+
_, _ = fmt.Fprintf(i.out, " Operation: %s\n", om.GetOperationName())
159+
_, _ = fmt.Fprintf(i.out, " Op UID: %s\n", om.GetOperationUid())
150160
}
151-
_, _ = fmt.Fprintf(i.out, " Composition: %s\n", cm.GetCompositionName())
161+
152162
_, _ = fmt.Fprintf(i.out, " Step: %s (index %d, iteration %d)\n", meta.GetStepName(), meta.GetStepIndex(), meta.GetIteration())
153163
_, _ = fmt.Fprintf(i.out, " Function: %s\n", meta.GetFunctionName())
154164
_, _ = fmt.Fprintf(i.out, " Trace ID: %s\n", meta.GetTraceId())

server/server_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,111 @@ func TestEmitResponse_Text_WithError(t *testing.T) {
275275
}
276276
}
277277

278+
func TestEmitRequest_Text_OperationMeta(t *testing.T) {
279+
var buf bytes.Buffer
280+
inspector := NewInspector("text", WithOutput(&buf))
281+
282+
meta := &pipelinev1alpha1.StepMeta{
283+
StepName: "my-operation-step",
284+
FunctionName: "my-operation-function",
285+
TraceId: "trace-op-abc",
286+
SpanId: "span-op-def",
287+
StepIndex: 0,
288+
Iteration: 0,
289+
Timestamp: timestamppb.New(time.Date(2026, 1, 15, 10, 30, 0, 0, time.UTC)),
290+
Context: &pipelinev1alpha1.StepMeta_OperationMeta{
291+
OperationMeta: &pipelinev1alpha1.OperationMeta{
292+
OperationName: "reconcile",
293+
OperationUid: "op-uid-789",
294+
},
295+
},
296+
}
297+
298+
req := &pipelinev1alpha1.EmitRequestRequest{
299+
Request: []byte(`{"operation":"reconcile"}`),
300+
Meta: meta,
301+
}
302+
303+
_, _ = inspector.EmitRequest(context.Background(), req)
304+
305+
want := "=== REQUEST ===\n" +
306+
" Operation: reconcile\n" +
307+
" Op UID: op-uid-789\n" +
308+
" Step: my-operation-step (index 0, iteration 0)\n" +
309+
" Function: my-operation-function\n" +
310+
" Trace ID: trace-op-abc\n" +
311+
" Span ID: span-op-def\n" +
312+
" Timestamp: 2026-01-15T10:30:00.000Z\n" +
313+
" Payload:\n" +
314+
" operation: reconcile\n" +
315+
"\n\n"
316+
if diff := cmp.Diff(want, buf.String()); diff != "" {
317+
t.Errorf("EmitRequest text output mismatch (-want +got):\n%s", diff)
318+
}
319+
}
320+
321+
func TestEmitRequest_JSON_OperationMeta(t *testing.T) {
322+
var buf bytes.Buffer
323+
inspector := NewInspector("json", WithOutput(&buf))
324+
325+
meta := &pipelinev1alpha1.StepMeta{
326+
TraceId: "trace-op-123",
327+
SpanId: "span-op-456",
328+
StepIndex: 0,
329+
Iteration: 0,
330+
FunctionName: "function-operation",
331+
Timestamp: timestamppb.New(time.Now()),
332+
Context: &pipelinev1alpha1.StepMeta_OperationMeta{
333+
OperationMeta: &pipelinev1alpha1.OperationMeta{
334+
OperationName: "reconcile",
335+
OperationUid: "op-uid-abc",
336+
},
337+
},
338+
}
339+
340+
req := &pipelinev1alpha1.EmitRequestRequest{
341+
Request: []byte(`{"operation":"reconcile"}`),
342+
Meta: meta,
343+
}
344+
345+
_, err := inspector.EmitRequest(context.Background(), req)
346+
if err != nil {
347+
t.Fatalf("EmitRequest failed: %v", err)
348+
}
349+
350+
output := buf.String()
351+
if !strings.Contains(output, `"type":"REQUEST"`) {
352+
t.Errorf("expected type REQUEST in output, got: %s", output)
353+
}
354+
if !strings.Contains(output, `"functionName":"function-operation"`) {
355+
t.Errorf("expected functionName in output, got: %s", output)
356+
}
357+
358+
// Verify it's valid JSON.
359+
var result map[string]any
360+
if err := json.Unmarshal([]byte(output), &result); err != nil {
361+
t.Errorf("output is not valid JSON: %v", err)
362+
}
363+
364+
// Verify meta is included and contains operationMeta.
365+
metaVal, ok := result["meta"].(map[string]any)
366+
if !ok {
367+
t.Fatalf("expected meta field in output, got: %s", output)
368+
}
369+
370+
opMeta, ok := metaVal["operationMeta"].(map[string]any)
371+
if !ok {
372+
t.Fatalf("expected operationMeta in meta, got: %v", metaVal)
373+
}
374+
375+
if opMeta["operationName"] != "reconcile" {
376+
t.Errorf("expected operationName 'reconcile', got: %v", opMeta["operationName"])
377+
}
378+
if opMeta["operationUid"] != "op-uid-abc" {
379+
t.Errorf("expected operationUid 'op-uid-abc', got: %v", opMeta["operationUid"])
380+
}
381+
}
382+
278383
func TestDecodeJSONPayload(t *testing.T) {
279384
tests := []struct {
280385
name string

0 commit comments

Comments
 (0)