Skip to content

Ensure Snapshot.Disks marshals as [] instead of null - #94

Merged
LarsLaskowski merged 2 commits into
mainfrom
claude/lucid-fermat-2bo5nh
Aug 19, 2026
Merged

Ensure Snapshot.Disks marshals as [] instead of null#94
LarsLaskowski merged 2 commits into
mainfrom
claude/lucid-fermat-2bo5nh

Conversation

@LarsLaskowski

@LarsLaskowski LarsLaskowski commented Aug 19, 2026

Copy link
Copy Markdown
Owner

📖 Description

docs/API.md documents that fields may briefly read as "empty arrays" right after process start, before the first collection tick completes. In practice, Snapshot.Disks []Disk has no omitempty (unlike Network), and its Go zero value (nil) marshals to JSON null, not []. Strict JSON consumers iterating disks would trip on null. This also applied after any tick where disk collection failed or found no eligible mountpoints (DiskCollector.Collect used var disks []Disk, which stays nil when nothing is appended).

Fix: keep Snapshot.Disks a non-nil (possibly empty) slice everywhere:

  • internal/collector/disk.go: DiskCollector.Collect now allocates with make([]Disk, 0, len(order)) instead of a nil var disks []Disk.
  • internal/collector/collector.go: the Collector's initial latest snapshot now starts with Disks: []Disk{} (covers the window before the first fast tick), and fastTick normalizes a nil result from DiskCollector.Collect (e.g. on a read error) before storing it.

This is a docs-consistency fix, not a JSON shape change — the field itself (disks) is unchanged, only its zero-state value goes from null to [], which is what docs/API.md already promised.

🎫 Issues

Closes #70

👩‍💻 Reviewer Notes

Changes are confined to internal/collector. No API surface, config, or packaging changes.

📑 Test Plan

  • Added TestCollector_Disks_NeverMarshalsAsNull in internal/collector/collector_test.go, which JSON-marshals a Snapshot both before the first fastTick and after, asserting "disks" is never "null".
  • Added TestDiskCollector_Collect_NoMountsReturnsEmptyNotNilSlice in internal/collector/disk_test.go covering the case where no mountpoint qualifies (all excluded pseudo filesystems).
  • Extended the existing TestDiskCollector_Collect_SkipsFailingStatfs to assert the returned slice is non-nil.
  • go build ./..., go vet ./..., go test ./... -race -cover, and golangci-lint run all pass locally.

✅ Checklist

General

  • I have added/updated tests for my changes (go test ./... -race -cover passes locally).
  • go vet ./... and golangci-lint run are clean.
  • I have tested my changes.
  • I have read the CONTRIBUTING documentation and followed the project's code style guidelines.
  • I have updated ARCHITECTURE.md if this changes a documented design decision. (not applicable — no design change)

REST API / configuration / packaging

  • I have updated docs/API.md to reflect a REST API change. (not needed — the doc already describes this exact behavior; the code now matches it)
  • No breaking change to /api/v1/... response shapes, or a new API version (/api/v2/...) was introduced instead.
  • I have updated README.md / packaging/pimonitor.example.yaml(not applicable)
  • I have updated packaging/install.sh or the systemd units — (not applicable)

⏭ Next Steps

None.

claude added 2 commits August 19, 2026 04:51
docs/API.md says fields may briefly read as "empty arrays" right after
startup, but the []Disk zero value marshals to JSON null (Disks has no
omitempty, unlike Network), which trips strict JSON consumers iterating
disks. Initialize the slice on Collector construction and normalize a
nil result from DiskCollector.Collect (empty/failed collection) so
Snapshot.Disks is always a non-nil slice, matching the documented
behavior.

Closes #70
SonarCloud's quality gate flagged the nil-normalization branch added
for #70 as untested new code: DiskCollector.Collect now always
returns a non-nil slice on success, which left fastTick's nil check
(covering a failed collection, e.g. /proc/mounts unreadable) with no
test exercising it directly.
@sonarqubecloud

Copy link
Copy Markdown

@LarsLaskowski
LarsLaskowski merged commit 20679e3 into main Aug 19, 2026
5 checks passed
@LarsLaskowski
LarsLaskowski deleted the claude/lucid-fermat-2bo5nh branch August 19, 2026 15:53
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.

API nit: disks is null (not []) before the first tick, contradicting API.md

2 participants