Conversation
`container run --cpus` takes a whole number; Compose allows a fraction. A compose file using `cpus: "0.5"` failed outright: Error: The value '0.5' is invalid for '--cpus <cpus>' Rounded up rather than down, because down turns 0.5 into 0, which container also rejects, and a slightly loose cap fails less destructively than none. Reported on stdout, the same way the 200 MiB memory floor already is. Also fixes a quieter instance of the same input on the build path, which read the limit as `Int64(...) ?? 2`. Int64 cannot parse "0.5", so a service asking for half a CPU silently got two - four times its request, with no message. Only the run path failing loudly is why this was noticed.
The regression test added with the previous commit called clampCPULimit and asserted on its result, which passes whether or not buildService uses it - mutation-checked: reverting that line to `Int64(...) ?? 2` left the suite green. Second time this shape appeared in this branch. Extracting builderCPUCount also separated two things the old expression conflated: the default for a service that declares no limit, and the fallback for a limit that cannot be parsed. They are now testable apart.
`Int(Double)` traps rather than saturating, so `clampCPULimit` crashed the process on three shapes a compose file can legally contain: `cpus: 1e400` parses as infinity, `cpus: nan` as NaN, and `cpus: 1e20` is finite but larger than `Int` can hold — the case an `isFinite` check alone still misses. A value this tool cannot express is now passed through untouched, so `container run` rejects it and names the service. That is a better outcome than a fatal error with no service in it, and it leaves the ordinary path unchanged: 0.5 still rounds to 1, 2.5 to 3, and a whole number is left alone. Six tests, one per shape plus the unchanged path and the builder fallback.
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.
Split out of #153 at the maintainer's request.
container run --cpustakes a whole number while Compose allows a fraction, socpus: 0.5reached the runtime as-is and was rejected. This rounds up to the smallest expressible limit rather than down — 0.5 would otherwise become 0, and a slightly loose cap fails less destructively than none at all. The change is reported to the caller the same way the memory floor is.Two seams so the mapping is covered where it is decided:
clampCPULimitfor the run path, andbuilderCPUCountfor the build path, which had its own fallback of 2 and so silently turned "half a CPU" into four times what was asked for.Range validation
Int(Double)traps rather than saturating, so the value is range-checked before the conversion. Three shapes a compose file can legally contain crashed the process:cpus:1e400nan1e20Intcan hold — the case anisFinitecheck alone missesA value this tool cannot express is now passed through untouched, so
container runrejects it and names the service. That reads better than a fatal error with no service in it.Verified by removing the guard and running the suite: the test process dies with signal 5, reporting
Fatal error: Double value cannot be converted to Int because the result would be greater than Int.maxand... because it is either infinite or NaN. With the guard the same inputs return unchanged.The ordinary path is untouched: 0.5 → 1, 2.5 → 3, and a whole number is left alone.
Static suite: 255 tests / 24 suites green.