Skip to content

refactor: split format/cos.go view-model build from render (#4657)#4684

Merged
psaab merged 1 commit into
masterfrom
refactor/4657-cos-split
Jul 8, 2026
Merged

refactor: split format/cos.go view-model build from render (#4657)#4684
psaab merged 1 commit into
masterfrom
refactor/4657-cos-split

Conversation

@psaab

@psaab psaab commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Closes #4657.

format/cos.go had grown to 865 LOC with FormatCoSInterfaceSummary
interleaving the config+runtime view-model join with every render block.
This mirrors the #4656 status.go aggregate-then-render split.

Pure code motion — output byte-identical

  • View-model build → cos_sections.go: configuredCoSInterfaceViews,
    cosRuntimeIndex + buildCoSRuntimeIndex + lookup +
    cosRuntimeCandidateNames, buildCoSQueueViews,
    isOldJSONSyntheticDefaultQueue — the only places that join the
    CoS/interface stanzas with the runtime snapshot.
  • Render sections → cos_sections.go: the FormatCoSInterfaceSummary
    loop was decomposed into writeCoSInterfaceHeader (config + runtime +
    waterfill header), writeCoSQueueTable (the aligned tabwriter grid), and
    writeCoSQueueDetail (the interleaved Drops / Sojourn / Surplus /
    Equal-flow / OwnerProfile / DrainShape / Waterfill rows).
    renderBindingScopedTelemetry + the histogram helpers move alongside.
  • cos.go keeps the cosInterfaceView / cosQueueView types, the
    FormatCoSInterfaceSummary orchestrator, and the leaf formatters
    (cos.go 280 LOC, cos_sections.go 632 LOC).

The queue view slice is still built exactly once per interface by the
orchestrator and shared between the binding-scoped telemetry line and the
queue table — no extra fetches, no re-iteration.

Byte-identity gate

Added TestFormatCoSInterfaceSummaryGolden (testdata/cos_summary.golden).
The golden was generated from the pre-refactor code with a fixture that
exercises every conditional header/queue/detail block; the refactored code
reproduces it byte-for-byte. It reuses the package-level -update flag from
status_golden_test.go.

Validation

  • go build ./... clean
  • go vet ./pkg/dataplane/userspace/format/ clean
  • go test ./pkg/dataplane/userspace/format/ green (golden + all 24 existing
    CoS tests)
  • gofmt clean

No operator-facing contract change (output unchanged), so no module doc update
is needed.

🤖 Generated with Claude Code

https://claude.ai/code/session_015oARShYtiJJ2H4UB4nXGqi

format/cos.go had grown to 865 LOC with FormatCoSInterfaceSummary
interleaving the config+runtime view-model join with every render
block (per-interface header, binding telemetry, the tabwriter queue
grid, and the interleaved per-queue Drops / Sojourn / Surplus /
Equal-flow / OwnerProfile / DrainShape / Waterfill detail rows). This
mirrors the #4656 status.go aggregate-then-render split.

Pure code motion, output byte-identical. The change:

  - Move the view-model construction into a new cos_sections.go:
    configuredCoSInterfaceViews, cosRuntimeIndex + buildCoSRuntimeIndex
    + lookup + cosRuntimeCandidateNames, buildCoSQueueViews, and
    isOldJSONSyntheticDefaultQueue are the only places that join the
    CoS/interface stanzas with the runtime snapshot.

  - Decompose the FormatCoSInterfaceSummary render loop into per-section
    helpers (also in cos_sections.go): writeCoSInterfaceHeader (config +
    runtime + waterfill header), writeCoSQueueTable (the aligned
    tabwriter grid), and writeCoSQueueDetail (the interleaved detail
    rows). renderBindingScopedTelemetry and the histogram-percentile
    helpers move alongside them.

  - cos.go keeps the cosInterfaceView / cosQueueView types, the
    FormatCoSInterfaceSummary orchestrator, and the leaf formatters
    (cos.go 280 LOC, cos_sections.go 632 LOC).

The queue view slice is still built exactly once per interface by the
orchestrator and shared between the binding-scoped telemetry line and
the queue table — no extra fetches, no re-iteration.

Validation: added TestFormatCoSInterfaceSummaryGolden
(testdata/cos_summary.golden) as the byte-identity gate. The golden was
generated from the pre-refactor code with a fixture that exercises every
conditional header/queue/detail block, and the refactored code
reproduces it byte-for-byte; it reuses the package-level -update flag.
go build ./... clean, go vet clean, and go test
./pkg/dataplane/userspace/format/ green (golden + all 24 existing CoS
tests). No operator-facing contract change (output unchanged), so no
module doc update is needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oARShYtiJJ2H4UB4nXGqi
Copilot AI review requested due to automatic review settings July 8, 2026 16:15
@psaab
psaab merged commit 11caf95 into master Jul 8, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the CoS interface summary formatter to separate view-model construction from rendering, keeping the output byte-identical while making the code easier to follow and safer to evolve.

Changes:

  • Extracted config+runtime joining and per-section rendering helpers from cos.go into new cos_sections.go.
  • Added a golden test (TestFormatCoSInterfaceSummaryGolden) plus testdata/cos_summary.golden to enforce byte-identical output.
  • Logged the refactor in _Log.md.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/dataplane/userspace/format/cos.go Keeps core types/orchestrator; delegates header/table/detail rendering to section helpers.
pkg/dataplane/userspace/format/cos_sections.go New file containing view-model build + section render helpers and histogram/telemetry helpers.
pkg/dataplane/userspace/format/cos_golden_test.go New golden test guarding byte-identical output for FormatCoSInterfaceSummary.
pkg/dataplane/userspace/format/testdata/cos_summary.golden New golden output fixture used by the golden test.
_Log.md Adds required log entry for the refactor.

Comment on lines +333 to +335
// `total` is the authoritative sample count (drain_invocations). When
// `total == 0`, emit "0µs" rather than "nan" or "-" so the field
// aligns visually across queues and the zero value is obvious.
Comment on lines +121 to +124
got := FormatCoSInterfaceSummary(testCoSConfig(), goldenCoSSummaryStatus(), "")
goldenPath := filepath.Join("testdata", "cos_summary.golden")
if *updateGolden {
if err := os.MkdirAll("testdata", 0o755); err != nil {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: format/cos.go (865 LOC) — separate view-model build from render

2 participants