test: mutation-test the subscription state machine#2
Open
brodapeethar wants to merge 97 commits into
Open
Conversation
changes made successfully
changes made successfully
* Issue Stellabill#277: Implement webhook endpoints * Issue Stellabill#277: Add pgx-based outbox repository --------- Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
changes made successfully Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: brodapeethar <brodapeethar@gmail.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Stellabill#314) * test: add rate-limiter whitelist and burst integration tests * test: add rate-limiter whitelist and burst integration tests --------- Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…sitory layers (Stellabill#315) - Fix missing 'context' import in handlers/subscriptions.go - Add OTel spans to SubscriptionRepo.FindByIDAndTenant and UpdateStatus in internal/repository/postgres/subscription_repo.go - Service layer (GetDetail, ChangeStatus) and handler layer (GetSubscription, ChangeSubscriptionStatus, ListPlans, ListSubscriptions) already had spans; repository layer now completes the end-to-end trace - Add otel_spans_test.go verifying handler→service span propagation and shared trace IDs across all four span tests Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…#316) Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…Stellabill#88) (Stellabill#317) - Add FeeService with GetFeeHistory returning records + trend analysis - Add SwapRouter with SwapExactTokensForTokens and SwapTokensForExactTokens using constant-product AMM (x*y=k) with 0.3% fee - Register GET /api/v1/fees/history and POST /api/v1/swap/exact-in, POST /api/v1/swap/exact-out routes - Add OpenAPI spec entries for all three new endpoints - Fix pre-existing syntax error in cached_plan_repo.go (dangling else) - Fix pre-existing type mismatch in cmd/server/main.go (cfg vs *cfg) Closes Stellabill#162 Closes Stellabill#88 Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
* feat: graceful HTTP server shutdown on SIGINT/SIGTERM * feat: add PostgreSQL-backed PlanRepository --------- Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…ts (Stellabill#320) Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…sociated unit tests (Stellabill#321) Co-authored-by: Adam <thlpkee20@gmail.com>
…l#322) * feat: implement subscription and plan handlers with pagination and associated unit tests * feat: implement database connection pool management and wire application routing layers
Add subscriber key registration, JWE encryption for sensitive event types, dead-letter routing on missing keys, and documentation for the envelope format. Closes Stellabill#355 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add OpenAPI paths for subscriber-keys and outbox admin routes, enforce RBAC on v1 plans/statements, move rate limiting after auth for user-mode keys, harden merchant statement tenant filtering, and skip integration tests in default go test runs. Co-authored-by: Cursor <cursoragent@cursor.com>
Add dispatcher and JWE unit tests, expand subscriber key repository coverage, fix k6 installation in benchmarks workflow, and tune CI coverage thresholds (40% outbox, 65% repo-wide). Co-authored-by: Cursor <cursoragent@cursor.com>
Synchronize mock publisher state for -race builds and avoid apt gpg failures when installing k6 in the benchmark workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
Use base64rawurl HMAC output and include tenant claims required by auth middleware. Co-authored-by: Cursor <cursoragent@cursor.com>
Provide DATABASE_URL and auth secrets so cmd/server boots in benchmark CI before k6 smoke tests run. Co-authored-by: Cursor <cursoragent@cursor.com>
Satisfy config secret validation and auth middleware role extraction during k6 smoke tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Use raw HMAC digest with base64url encoding instead of base64rawurl output encoding. Co-authored-by: Cursor <cursoragent@cursor.com>
k6 no longer accepts raw HMAC output; convert standard base64 to base64url for signatures. Co-authored-by: Cursor <cursoragent@cursor.com>
k6 HMAC output encodings differ from golang-jwt; mint tokens via gentoken in benchmark workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…l#384) - Add SlackPublisher implementing outbox.Publisher - Map Event.Type to a Block Kit template registry (built-in templates for subscription.created, subscription.charged, subscription.cancelled, test.event; custom templates via RegisterTemplate) - Webhook URL fetched at runtime from SecretsProvider (never config files) - Honor 429 Retry-After headers (seconds and HTTP-date formats) - Route 4xx non-429 responses to dead-letter via PermanentPublishError - sleepFn field allows time injection in tests (no real sleeps) - Add IsPermanentPublishError fast-path in per-publisher drain loop - Fix pre-existing build errors: duplicate Config fields, duplicate PostgresPgxRepository methods, missing Repository interface methods - Tests: 100% coverage on all exported functions; Publish 95.8% Closes Stellabill#335 Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…ev mode (Stellabill#387) Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
* update * feat: add tenant notification channels and preferences --------- Co-authored-by: babigdk <babigdk.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
* feat: add GraphQL gateway over plan, subscription and statement services - Add internal/graphql package: schema (Plan/Subscription/Statement types), tenant-scoped resolvers reusing existing services, depth/complexity limits (max depth 5, max complexity 50), and a Gin handler - Wire POST /api/v1/graphql behind AuthMiddleware + RateLimitMiddleware + TenantRateLimitMiddleware in internal/routes/routes.go - Add github.com/graphql-go/graphql v0.8.1 dependency - Fix pre-existing build errors: duplicate struct field in config.go, copy() shadowing in cache/memory_object_store.go, duplicate methods in outbox/postgres_pgx_repository.go, duplicate type in cached_plan_repo.go, missing ExportStatements impl in statement_service.go, missing Logger interface in logger package - Tests: 98% coverage on internal/graphql (depth/complexity rejection, tenant scope isolation, not-found, forbidden-caller, resolver error paths) Closes Stellabill#323 * feat: emit trace exemplars from HTTP duration histogram Attach trace_id and span_id exemplars to http_request_duration_seconds via ObserveWithExemplar when the active OTel span is sampled and recording. Falls back to plain Observe for unsampled/non-recording spans. - spanExemplar(ctx) extracts trace_id/span_id from the span context; returns nil when IsSampled()==false or IsRecording()==false - MetricsMiddleware casts the observer to prometheus.ExemplarObserver before calling ObserveWithExemplar — safe with promauto histograms - Tests: 100% statement coverage on new paths; covers sampled, unsampled, no-span, and ended-span edge cases Scrape config required to expose exemplars: prometheus.yml: enable_native_histograms: true (or use OpenMetrics content type: Accept: application/openmetrics-text) Closes Stellabill#324 --------- Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Closes Stellabill#360 Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Replace the dynamically-derived exhaustive test with a hardcoded transition matrix so that mutants that flip guards are always caught. Add go-mutesting infrastructure, Makefile target, CI workflow with 80 % killed threshold, and reproduction documentation.
- Add internal/integrations/pagerduty: Events v2 client with trigger/resolve and exponential-backoff retry on 5xx (max 3 attempts); 4xx are not retried - Add DeadLetterWatcher job (internal/worker/deadletter_watcher.go): queries dead_letter_events view, triggers PagerDuty incident when inflow in the configured window >= threshold, auto-resolves when it drops below; stable dedup_key prevents duplicate incidents across restarts - Wire watcher into cmd/server/main.go startup; PAGERDUTY_ROUTING_KEY is optional — watcher runs silently when unset - Add config vars: PAGERDUTY_ROUTING_KEY, DEADLETTER_THRESHOLD (default 5), DEADLETTER_WINDOW (default 60s) - Fix pre-existing build errors: duplicate Config.SecurityFrameAncestors field, missing SecurityCSPReportURI field, cache copy-builtin shadow, duplicate pgx repository methods, missing Repository interface methods - Tests: pagerduty client (trigger, resolve, 5xx retry, 4xx no-retry, ctx cancel) and watcher (threshold edge, dedup, resolve, no-double-fire, nil client, DB error, Start ctx cancel)
Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…#395) Co-authored-by: deltron-fr <kayceoogbonnaya2304@gmail.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: deltron-fr <kayceoogbonnaya2304@gmail.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…ing and audit logging (Stellabill#397) Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
…ed refresh (Stellabill#398) * feat: implement fraud detection engine with sliding window rate limiting and audit logging * feat: implement fee revenue materialized view refresh worker and API handlers --------- Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: uche102 <your-uche102-email@example.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
Co-authored-by: ajulaybeeb <ajulaybeeb@users.noreply.github.com> Co-authored-by: thlpkee20-wq <thlpkee20@gmail.com>
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.
Summary
Mutation-test the subscription state machine (
internal/subscriptions/) to surface assertions that pass for the wrong reason. Replaces the dynamically-derived exhaustive test with a hardcoded transition matrix so that mutants are reliably killed.Changes
internal/subscriptions/state_machine_test.goTestCanTransition_Exhaustive(derived expectations from the function under test) withTestCanTransition_ExplicitMatrixusing a hardcoded transition matrix + addTestCanTransition_UnknownSource.github/workflows/mutation.ymlgo-mutestingoninternal/subscriptions/, gates merges at ≥ 80 % killedMakefilemutation-state-machinetargetdocs/mutation-testing.md.gitignorereport.jsonMutation results
All 4 generated mutants are killed (100 %), well above the 80 % gate.
Mutants covered
return nilfrom thefrom == tono-op branchreturn nilfrom the transition-match branchbreakbefore the match checkAll are detected and killed by the explicit matrix.
Local reproduction
Closes Stellabill#341