From 347bc5248e6b86e50e3056b300fb51492bff0d79 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 19 Jun 2026 16:40:02 +0200 Subject: [PATCH 1/2] fix(ci): run Dockerfile.test E2E runner as a non-root user trivy >=0.70.0 flags DS-0002 (no non-root USER) on Dockerfile.test, failing the pre-commit trivy-config hook for any contributor on a newer local trivy (CI pins v0.69.3, which did not report it). Add a dedicated non-root user and point GOCACHE at its home so both the build-time pre-compile and the runtime `go test` run unprivileged. tests/e2e is stdlib-only, so no module downloads are needed. Verified with `docker build -f Dockerfile.test`: go vet and go test run cleanly as the non-root user. --- Dockerfile.test | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Dockerfile.test b/Dockerfile.test index 2b319e850..0e50a0446 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -7,9 +7,18 @@ # keep the digest in sync with the builder stage there. FROM golang:1.25.4-alpine3.21@sha256:3289aac2aac769e031d644313d094dbda745f28af81cd7a94137e73eefd58b33 +# Run the suite as a non-root user (trivy DS-0002). tests/e2e is a stdlib-only +# module so no module downloads are needed; GOCACHE lives in the user's home, +# which it owns and can write to during both the pre-compile below and the +# runtime CMD. +RUN adduser -D -u 10001 e2e +ENV GOCACHE=/home/e2e/.cache/go-build + WORKDIR /e2e -COPY tests/e2e/ ./ +COPY --chown=e2e:e2e tests/e2e/ ./ + +USER e2e # Pre-compile the test binary so `docker compose up` failures are runtime # failures, not compile errors discovered after the stack is already up. From 1e37d228dff20d3722d9be26201dc1f687e924c7 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 19 Jun 2026 16:40:10 +0200 Subject: [PATCH 2/2] refactor(config): cut recEffectiveSavingsPct cyclomatic complexity (closes #1222) recEffectiveSavingsPct had cyclomatic complexity 12, above the pre-commit gocyclo `-over 10` threshold, so every PR's pre-commit CI job failed regardless of what it touched. Extract the on-demand baseline derivation into a new helper recOnDemandBaseline, bringing both functions under the threshold. Behavior is identical: the helper returns the same (baseline, ok) for every input branch (explicit OnDemandCost, monthly_cost reconstruction, AWS-without-baseline and no-monthly_cost guards), so the net-savings semantics from #1103/#1148 are unchanged. --- .../config/store_postgres_recommendations.go | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/internal/config/store_postgres_recommendations.go b/internal/config/store_postgres_recommendations.go index f8d05f2fc..ce3c3a722 100644 --- a/internal/config/store_postgres_recommendations.go +++ b/internal/config/store_postgres_recommendations.go @@ -325,24 +325,33 @@ func recEffectiveSavingsPct(rec *RecommendationRecord) (float64, bool) { if rec.Term == 0 { return 0, false } - hasOnDemand := rec.OnDemandCost != nil && *rec.OnDemandCost > 0 - if !hasOnDemand && rec.MonthlyCost == nil { + onDemand, ok := recOnDemandBaseline(rec) + if !ok || onDemand == 0 { return 0, false } - if rec.Provider == providerAWS && !hasOnDemand { + return (rec.Savings / onDemand) * 100, true +} + +// recOnDemandBaseline returns the monthly on-demand baseline used as the +// denominator in recEffectiveSavingsPct, and whether one could be determined. +// It prefers the provider-reported OnDemandCost; otherwise it reconstructs the +// baseline as monthly_cost + net savings + amortized upfront. It returns +// ok=false when no baseline can be derived: no explicit on-demand and no +// monthly_cost, or an AWS row without an explicit on-demand baseline (the +// reconstruction diverges from Cost Explorer's true baseline -- the frontend's +// #323 guard). Callers must ensure rec.Term != 0 before calling. +func recOnDemandBaseline(rec *RecommendationRecord) (float64, bool) { + if rec.OnDemandCost != nil && *rec.OnDemandCost > 0 { + return *rec.OnDemandCost, true + } + if rec.MonthlyCost == nil { return 0, false } - var onDemand float64 - if hasOnDemand { - onDemand = *rec.OnDemandCost - } else { - amortized := rec.UpfrontCost / float64(rec.Term*12) - onDemand = *rec.MonthlyCost + rec.Savings + amortized - } - if onDemand == 0 { + if rec.Provider == providerAWS { return 0, false } - return (rec.Savings / onDemand) * 100, true + amortized := rec.UpfrontCost / float64(rec.Term*12) + return *rec.MonthlyCost + rec.Savings + amortized, true } // ListStoredRecommendations reads recommendations matching the filter.