Repository navigation
refactor(get): move the get command's body into internal/get - #26
Merged
Merged
Conversation
Closes #25. cmd/get.go held the PoolManager construction and the json/text/spew output switch inside a cobra Run closure, none of it reachable from a test. That is the same shape server.go had before #20, and it is why the mutation survivors in #24 had to be accepted rather than covered. internal/get exposes Run(cfg, w io.Writer) error, writing to an injected writer so every format can be asserted. cmd/get.go is now a Config, a call, and an exit code. One behaviour change falls out of it: an unrecognised --out value is an error rather than a logged message, so it exits non-zero instead of silently succeeding with no output. Writing to stdout is also checked now, so a failed write is reported rather than discarded.
The first pass only checked that each label appeared, against a fixture whose values were all zero, so dropping any single row was invisible. Each field now carries a distinct value, and the blank separator between pools and the wrapping of an overlong value are asserted too.
The configured ScrapeTimeout was not asserted, so dropping it and silently falling back to the package default went unnoticed. Writing the wrapping test also corrected an assumption: uitable elides an overlong cell at MaxColWidth rather than wrapping it, so a scrape URI longer than 80 characters is shown truncated. The test now documents that rather than claiming the value is preserved. Uses a generic pool name in the fixture.
…res twice Following the principle that a mutation survivor no test can kill is either dead code or a missing test, rather than something to accept. The JSON encode error was unreachable: everything PoolManager marshals is a string, int64, map or slice, and both custom MarshalJSON methods return a nil error unconditionally. Encoding straight to the writer removes the branch and leaves one error a caller can actually hit, the write. uitable's Wrap had no effect: rendering the same table with it on and off is byte-identical, because MaxColWidth elides the cell first. Deleted rather than pinned. The width itself does matter and is now asserted through its effect, by measuring the widest rendered cell, so an off-by-one either way fails. Pool.error logged every scrape failure and so did collectPools, so the server path emitted two lines per failure per scrape. That predates this branch; adding the joined error to Update made it three. Pool.error now only records, leaving the line that carries context. The test logger was discarding Info, Debug and Error, which is why the first attempt at this test passed against the very duplication it was meant to catch.
The width assertion compared the measured cell against maxColWidth, so changing the constant moved the expectation with it and the test could never fail. It now compares against 80 directly, which is the contract a reader of the output depends on.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #25.
What
cmd/get.goheld the PoolManager construction and the json/text/spew output switch inside a cobraRunclosure, none of it reachable from a test. That is the shapeserver.gohad before #20, and it is why the mutation survivors in #24 had to be accepted rather than covered.internal/getnow exposesRun(cfg, w io.Writer) error, writing to an injected writer so every format can be asserted.cmd/get.gois aConfig, a call, and an exit code.Chasing the survivors found three real defects
Rather than accept what the mutation gate reported, each survivor was treated as either dead code or a missing test. Three turned out to be dead or wrong code:
The JSON encode error was unreachable. Everything
PoolManagermarshals is a string, int64, map or slice, and both customMarshalJSONmethods return a nil error unconditionally, sojson.Marshalcannot fail. Encoding straight to the writer removes the branch and leaves one error a caller can actually hit — the write.uitable.Wrapwas dead. Rendering the same table with it on and off is byte-identical, becauseMaxColWidthelides the cell first. Deleted rather than pinned. The width itself does matter and is now asserted through its effect, by measuring the widest rendered cell.Every failed scrape was logged twice.
Pool.errorlogged it andcollectPoolslogged it again with context, so the server path emitted two identical-ish lines per failure per scrape. That predates this branch; returning the joined error fromUpdatein #24 had quietly made it three.Pool.errornow only records, leaving the line that carries context.And two broken tests of my own
Worth stating, because both passed while testing nothing:
Info,DebugandError, keeping only the*fvariants. The duplicate-logging test therefore passed against the exact duplication it was written to catch.maxColWidth, so mutating the constant moved both sides together. It now compares against80directly and fails on an off-by-one in either direction, which I verified by making the change and watching it fail.Behaviour changes
--outvalue is an error rather than a logged message, so it exits non-zero instead of silently succeeding with no output.--out jsongains a trailing newline, a side effect of streaming throughjson.Encoder. Parsers do not care;jqpipelines are unaffected.Verification
All three output formats checked against the built binary, plus the exit codes (1 on scrape failure, 0 otherwise).
golangci-lint(v2.12.2, as CI pins): 4 issues, unchanged from master, none new.Mutation survivors went 23 → 7. The remaining 7 are all in
cmd/get.go— theConfigliteral, theif err != nil, and thelog.Error— and are accepted because covering them means putting tests back intocmd, which is what this PR exists to avoid. Nothing ininternal/orphpfpm/survives.