Skip to content

chore(deps): bump cloud-commitments-go; scale money on extended-support cuts - #2197

Merged
cristim merged 1 commit into
mainfrom
chore/2195-bump-go-libs
Oct 13, 2026
Merged

cristim merged 1 commit into
mainfrom
chore/2195-bump-go-libs

Conversation

@cristim

@cristim cristim commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Closes #2195

What

  • Bumps pkg and providers/{aws,azure,gcp} to cloud-commitments-go main 9b35837e (go#365 SP partial-upfront recurring, go#374 MemoryDB, go#377 EC2 Convertible pricing, go#376 computed break-even, go#379 coverage drop reason, EC2 platform engine filter, common.ResizeCount).
  • cmd/helpers_test.go: --coverage rounding to zero now expects DropCoverageSizedToZero (--coverage-sized-to-zero).
  • A10 CLI part: the extended-support cut in adjustRecommendationForExcludedVersions set Count and kept the full recommendation's money. It now goes through common.ResizeCount (resizeAfterExclusion); a count of 0 stays the caller's drop signal, and a resize the library refuses drops the row rather than keeping unscaled money.
  • Test fixtures follow the library: the EC2 request now carries the Convertible ServiceSpecification, and the Compute SP no-upfront recurring fixture is 1459.75 (was 1460.00).
  • docs/cli/filtering.md: break-even formula and the drop of uncomputable break-even with an upfront; --coverage rounds down and drops rows that round to 0; --exclude-engines windows does not match "Windows with SQL Server"; --regions is ignored for Savings Plans (--include-regions works); region discovery now comes from Cost Explorer (stale since cli#2194).

Tests

TestAdjustRecommendationForExcludedVersions_ScalesMoneyWithCount (1 of 3 Aurora instances excluded: count 2, commitment 600 of 900, on-demand 400 of 600, savings 100 of 150, recurring 20 of 30). It fails with the old rec.Count = newCount and passes now. go vet clean; go test ./cmd passes (29s; TestQueryMajorEngineVersions_ErrorHandling skipped locally because it hangs in this session independent of this change).

Live dry run (read-only, payer-account credentials, no purchase flags)

  • EC2 Instance Savings Plans, 1yr partial-upfront, 30d: recurring values 1007.38 / 179.18 / 102.15 per month for hourly commitments 2.76 / 0.491 / 0.28 (upfront 12089 / 2151 / 1227), matching the ~1007 / 179 / 102 implied by CE hourly and upfront.
  • EC2 RIs, 1yr no-upfront, 30d, no --regions: 24 recommendations, total estimated savings 1472.70/mo; Cost Explorer with the CONVERTIBLE specification returns 24 recommendations totalling 1472.69/mo.
  • --max-break-even-months 6 on the SP run now filters: 3 of 3 dropped with break-even 9.5 / 8.1 / 8.5 months exceeds maximum 6 months, drop summary break-even: 3.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Recommendations reduced by excluded versions now have their cost and savings amounts scaled to match the remaining count.
    • Coverage-sized rows rounded down to zero are now reported with the coverage-specific drop reason.
  • Documentation

    • Clarified how region and engine filters work, how break-even is calculated, and how coverage sizing affects counts, amounts, and dropped rows.

…pport cuts

Bump pkg and the AWS, Azure and GCP providers to go main 9b35837e, which
brings the SP partial-upfront recurring fix, MemoryDB, EC2 Convertible
pricing, computed break-even, the coverage drop reason and
common.ResizeCount.

- helpers_test: expect DropCoverageSizedToZero for --coverage (Closes #2195).
- extended-support cut: use common.ResizeCount so the money fields scale
  with the reduced count instead of keeping the full recommendation's cost.
- tests: expect the Convertible service specification and the new
  Savings Plan recurring figure.
- docs: break-even formula, coverage rounding, EC2 platform engine matching,
  --regions on Savings Plans, region discovery from Cost Explorer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-sprint Within the current sprint impact/many Affects most users effort/s Hours type/bug Defect labels Oct 13, 2026
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-cli/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: be212e7f-df13-420d-8362-8d8e78f255ee
📥 Commits

Reviewing files that changed from the base of the PR and between 83a5aed and f0ea822.

⛔ Files ignored due to path filters: 1
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing: 7
  • cmd/helpers_test.go
  • cmd/multi_service_engine_versions.go
  • cmd/multi_service_engine_versions_test.go
  • cmd/recommendation_completeness_test.go
  • cmd/reservation_expiry_command_test.go
  • docs/cli/filtering.md
  • go.mod

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📝 Walkthrough

The PR updates four cloud-commitments module requirements, resizes recommendation money fields when version exclusions reduce counts, and updates command tests and CLI filtering documentation.

Changes: CLI compatibility

Layer / File(s) Summary
Resize recommendations after version exclusions
go.mod, cmd/multi_service_engine_versions.go, cmd/multi_service_engine_versions_test.go
The CLI now resizes recommendation money fields when excluded versions reduce the count. The test checks the scaled fields and confirms the input monthly-cost value remains unchanged.
Update coverage sizing expectations
cmd/helpers_test.go, docs/cli/filtering.md
The coverage sizing test expects DropCoverageSizedToZero. The documentation describes count and money scaling, and the drop reason for rows sized to zero.
Clarify filtering behavior
docs/cli/filtering.md
The documentation clarifies region selection, EC2 platform matching, and break-even filtering rules.
Update command test expectations
cmd/recommendation_completeness_test.go, cmd/reservation_expiry_command_test.go
The tests update the expected recurring monthly cost and the EC2 offering class in a purchase-recommendation request.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to f0ea8

This updates the cloud-commitments dependency, scales recommendation costs correctly after version exclusions, and refreshes the related tests and filtering docs. No merge-blocking risk was found.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 5 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies both primary changes: the cloud-commitments-go dependency update and money scaling for extended-support exclusions.
Linked Issues check Passed Issue #2195 requires the coverage floor-to-zero test to expect common.DropCoverageSizedToZero and requires review of user-facing coverage drop documentation. cmd/helpers_test.go now expects the ne…
Out of Scope Changes check Passed The reviewed changes support the dependency bump and its integration. The added resizing logic and test cover changed recommendation behavior from the bumped library. Fixture updates align tests with …
Full details: Docstring Coverage

Explanation

Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 5 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@cristim

cristim commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

Independent review (claude-opus-5-5) of f0ea822: APPROVE

No blocking findings. Reviewed in a fresh clone at the head SHA (merge-base = current main 83a5aed), with the PR body treated as a claim to test.

Non-blocking findings

  1. docs/cli/filtering.md:174: "If net savings are not positive the break-even is infinite" does not match common.BreakEven (pkg common/breakeven.go). The result is +Inf only when gross savings EstimatedSavings + upfront/termMonths <= 0, that is net savings <= -(upfront / term months). Net savings of exactly 0 give a break-even equal to the term (12 or 36 months), not infinity. Suggest: "If gross monthly savings are not positive (net savings at or below minus the amortized upfront) the break-even is infinite and the recommendation is dropped."
  2. docs/cli/filtering.md:42: "--include-regions / --exclude-regions are what narrow Savings Plan results" holds only for EC2 Instance plans. Compute, SageMaker and Database plans are region-agnostic and always pass the region filter (cmd/multi_service_filters.go:128). Worth one clause.
  3. cmd/multi_service_engine_versions.go:519-528: the ResizeCount error branch is unreachable. newCount is rec.Count - excludedCount with excludedCount > 0 and newCount != rec.Count, and the < 1 guard runs first, so ResizeCount always sees a positive source count and newCount in [1, Count-1]. Deletion probe: changing the guard to newCount < 0 keeps every test green (both paths return Count 0; only the log line differs). Harmless, but the PR body's "a resize the library refuses drops the row" describes a state that cannot occur.
  4. Pre-existing, not caused by this PR (see flake diagnosis): cmd/helpers.go:92 GetAccountAlias caches the raw account ID on any DescribeAccount error. --exclude-accounts matches names, so one transient Organizations error makes a name-based exclusion fail open and the excluded account's rows are sized and listed for purchase. Suggest a follow-up issue: fail loud (or refuse the run) when an account filter is set and a name cannot be resolved.
  5. go main is now a4fc226d, 3 commits past the pin (sec(auth): login endpoint leaks MFA enrollment status via distinct error messages #388, security(iac/aws-target): OIDC trust policy allows any subject when oidc_subject_claim is empty #381, security(iac/aws): cleanup-staging.yml hardcodes feat/multicloud-web-frontend branch ref #386), all gcp/computeengine. The CLI recommendation path only builds awsprovider.NewRecommendationsClient (cmd/multi_service.go:172), so they do not affect the CLI. Fine to leave for the next bump.

Checks

CI flake diagnosis (TestReservationExpiryCommand/filtered-subset, run 38472545369 attempt 1)

The failed run shows 3 data rows where 2 were expected. The third account's AccountName column held its raw ID instead of expiry-account-3, so --exclude-accounts expiry-account-3 did not match. Target-coverage then sized all three rows from the 3-account average (count 12, not 18). The proxy recorded DescribeAccount:3 and always answers with a name, so the client saw an error on that call and GetAccountAlias fell back to the ID (cmd/helpers.go:91-93). The child runs with AWS_MAX_ATTEMPTS=1, so one transient tunnel/TLS error on a loaded runner is enough. No DATA RACE appears in the log.

Not caused by this PR: the PR only changes the expected GetReservationPurchaseRecommendation body. A mismatch there would fail every run, and on that call, not on DescribeAccount. The same completeness harness flaked on other branches (run 38017690356 attempt 1: a duplicated DescribeSavingsPlans; 37624743342: savingsplans-database/api-error).

Local reproduction attempts, all passing with no race reports:

  • -run '^TestReservationExpiryCommand$' -count=50 -race: head 50/50 (300 subtests); main 50/50, run concurrently.
  • filtered-subset 60x -race, with DescribeAccount errors logged and run alongside the other two loops: 0 failures, 0 alias errors.

Verdict: a pre-existing, low-rate harness flake. The production issue under it is finding 4.

Live dry run (read-only, head binary, no purchase flags)

Payer credentials, linked scope, 30-day lookback, --coverage 100.

  • EC2 Instance SP, 1yr partial-upfront: 3 rows (eu-west-2 m5, eu-central-2 m5, eu-west-2 m5a). Raw aws ce get-savings-plans-purchase-recommendation gives hourly 2.76 / 0.491 / 0.28 and upfront 12089 / 2151 / 1227. The formula gives 1007.38 / 179.18 / 102.15, and the CSV matches all three exactly. The old 730 x hourly would have shown 2014.80 / 358.43 / 204.40.
  • EC2 RI, 1yr no-upfront, no --regions: 24 rows, 40 instances, CSV savings sum 1472.70/mo. Raw CE with EC2Specification={OfferingClass=CONVERTIBLE} returns 24 rows / 40 instances / 1472.69 (rounding). STANDARD would have been 25 rows / 42 instances / 2651.68, so the request is Convertible as claimed. One region's DescribeReservedInstances returned 401, which the dry run logged as a warning (pre-existing, unrelated).
  • --max-break-even-months:
    • At 6: 3 of 3 dropped as "break-even 9.5 / 8.1 / 8.5 months exceeds maximum 6 months", drop summary break-even: 3.
    • At 9: only the 9.5 row is dropped and 2 pass.
    • Independent computation from raw CE, upfront / (savings + upfront/12) = 9.52 / 8.11 / 8.52, matches.
  • Coverage gap: an RDS run had no instances on extended-support versions, so resizeAfterExclusion was not exercised live. It is covered by the unit test and the mutations above.

Six dimensions

Completeness, correctness, security, bugs, duplication: no blocking issues. The change reuses common.ResizeCount rather than re-implementing scaling, and the test checks that the input's recurring pointer is not mutated. Over-engineering: finding 3 only.

State at review time

Head f0ea822 unchanged. Mergeable / CLEAN. All CI checks pass on this SHA (Unit Tests green on attempt 2). CodeRabbit reviewed 83a5aed..f0ea822 with no actionable comments.

@cristim
cristim merged commit 9806c9d into main Oct 13, 2026
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(cmd): expect DropCoverageSizedToZero for --coverage floor drops on the pkg bump

1 participant