Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions internal/submit/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ func Run(ctx context.Context, opts Options) (*Result, error) {
p.Successf("Submitted — tracebloc is validating your data and loading it into the table.")
}

// One greppable id across every layer (backend#1028 item 3): this key
// becomes the ingestor Job's TRACEBLOC_INGEST_CORRELATION_ID env and
// its tracebloc.io/ingestion-run label, shows up in the ingestor's
// log next to its per-process ingestor_id, and reaches the backend
// inside the dataset registration payload. Printed on every path
// (fresh and replay) — it's the thread support asks for.
p.Hintf("Correlation id: %s", req.IdempotencyKey)

if opts.Detach {
// --detach: report and bail. The run continues in the cluster;
// there is no CLI re-attach verb yet, so the honest way back is
Expand Down
58 changes: 58 additions & 0 deletions internal/submit/submit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,64 @@ func TestRun_PassesRequestFieldsThrough(t *testing.T) {
}
}

// TestRun_PrintsCorrelationId_GeneratedKey: the auto-generated
// idempotency key doubles as the end-to-end correlation id
// (backend#1028 item 3) — the same string becomes the Job's
// TRACEBLOC_INGEST_CORRELATION_ID env, its ingestion-run label, and
// the backend registration payload's correlation_id. Without this
// line the customer has no copy of the one id that threads all
// layers together.
func TestRun_PrintsCorrelationId_GeneratedKey(t *testing.T) {
sub := &fakeSubmitter{
resp: &SubmitResponse{JobName: "j", Namespace: "ns"},
}
var out bytes.Buffer

_, err := Run(context.Background(), Options{
Submitter: sub,
Client: fake.NewClientset(),
IngestConfigYAML: "yaml",
Detach: true,
Out: &out,
})
if err != nil {
t.Fatalf("Run: %v", err)
}
if sub.gotRequest == nil {
t.Fatal("submitter never called")
}
want := "Correlation id: " + sub.gotRequest.IdempotencyKey
if !strings.Contains(out.String(), want) {
t.Errorf("output missing %q in:\n%s", want, out.String())
}
}

// TestRun_PrintsCorrelationId_OverrideAndReplay: an explicit
// --idempotency-key override is echoed verbatim, and the line also
// prints on the replay path — a replayed run is exactly when the
// customer reaches for the id to find the already-running Job.
func TestRun_PrintsCorrelationId_OverrideAndReplay(t *testing.T) {
sub := &fakeSubmitter{
resp: &SubmitResponse{JobName: "j", Namespace: "ns", Replay: true},
}
var out bytes.Buffer

_, err := Run(context.Background(), Options{
Submitter: sub,
Client: fake.NewClientset(),
IngestConfigYAML: "yaml",
IdempotencyKey: "nightly-claims-2026.07",
Detach: true,
Out: &out,
})
if err != nil {
t.Fatalf("Run: %v", err)
}
if !strings.Contains(out.String(), "Correlation id: nightly-claims-2026.07") {
t.Errorf("output missing correlation id line in:\n%s", out.String())
}
}

// TestRun_NilOutDefaultsToDiscard: callers passing nil Out
// shouldn't panic. The orchestrator silently discards output.
func TestRun_NilOutDefaultsToDiscard(t *testing.T) {
Expand Down
Loading