Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/integration/version_counter_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/integration/version_counter_test.go |
| Original SHA-256 | c0a66f9400ee1ca9284c8718978413c83f4ba8dc9ff0d953a8f17cdaec3e464c |
| Git blob SHA | 13355ce99a26ee97fc6fd24afcf36d5ed786e773 |
| Reading-copy SHA-256 | c0a66f9400ee1ca9284c8718978413c83f4ba8dc9ff0d953a8f17cdaec3e464c |
Recovered source transcript
Download complete source text ↓199 lines · 8.5 KB
//go:build integration
package integration
import (
"context"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/missionworkforce/missionmatch/internal/modules/opportunities"
)
// FINDING D9, REPRODUCED THEN FIXED. Production held one opportunity with version 1 flagged is_current FALSE,
// so there was no current version at all. sam-sync read the next version number from the row joined ON
// is_current, that join matched nothing, the number read 0, and every run asked to insert version 1 again on
// an opportunity that already had one. The unique constraint refused it and the error was logged and skipped,
// so the next run computed 0 again. Permanently stuck, and silent.
//
// THIS TEST BUILDS THAT EXACT STATE, because a fix for a bug nobody can reproduce is a guess.
func seedStuckVersionState(t *testing.T) (org, opp uuid.UUID, notice string) {
t.Helper()
ctx := context.Background()
org = seedOrg(t)
opp = uuid.New()
notice = "D9-" + opp.String()[:8]
if _, err := migrator.Exec(ctx, `
INSERT INTO sam_opportunities (notice_id, title, department, naics_code, raw, source)
VALUES ($1, 'Elevator Preventive Maintenance', 'DEPT OF THE ARMY', '238290', '{}'::jsonb, 'test')
ON CONFLICT (notice_id) DO NOTHING`, notice); err != nil {
t.Fatalf("seed public cache: %v", err)
}
if _, err := migrator.Exec(ctx, `
INSERT INTO tracked_opportunities (organization_id, id, sam_notice_id, source_type, title, status)
VALUES ($1, $2, $3, 'sam_gov', 'Elevator Preventive Maintenance', 'qualifying')`,
org, opp, notice); err != nil {
t.Fatalf("seed tracked opportunity: %v", err)
}
// THE STUCK SHAPE: version 1 exists and is NOT current. This is what production actually held.
if _, err := migrator.Exec(ctx, `
INSERT INTO opportunity_versions (organization_id, opportunity_id, version_number, amendment_number,
source_version_label, source_payload_hash, normalized_payload,
fetched_at, is_current)
VALUES ($1, $2, 1, '', 'Solicitation', 'hash-v1', '{}'::jsonb, now(), false)`,
org, opp); err != nil {
t.Fatalf("seed retired version 1: %v", err)
}
t.Cleanup(func() {
c := context.Background()
// opportunity_versions refuses DELETE by trigger, which is correct and is why the fixture cleanup
// disables it for this row set only. The trigger is restored immediately afterwards.
_, _ = migrator.Exec(c, `ALTER TABLE opportunity_versions DISABLE TRIGGER opportunity_versions_immutable_trg`)
_, _ = migrator.Exec(c, `DELETE FROM opportunity_versions WHERE organization_id=$1`, org)
_, _ = migrator.Exec(c, `ALTER TABLE opportunity_versions ENABLE TRIGGER opportunity_versions_immutable_trg`)
_, _ = migrator.Exec(c, `DELETE FROM alerts WHERE organization_id=$1`, org)
_, _ = migrator.Exec(c, `DELETE FROM tracked_opportunities WHERE organization_id=$1`, org)
_, _ = migrator.Exec(c, `DELETE FROM sam_opportunities WHERE notice_id=$1`, notice)
})
return org, opp, notice
}
// THE POSITIVE CONTROL, and it runs FIRST. It reproduces the OLD behaviour by computing the next number the
// way the broken code did, from the row flagged current, and asserts that it collides. If this ever stops
// colliding, the test below proves nothing, because the bug it guards has changed shape.
func TestD9OldNumberingCollidesOnTheStuckState(t *testing.T) {
if migrator == nil {
t.Skip("integration pools not configured")
}
ctx := context.Background()
org, opp, _ := seedStuckVersionState(t)
var oldStyleNext int
if err := migrator.QueryRow(ctx, `
SELECT COALESCE(MAX(v.version_number), 0) + 1
FROM tracked_opportunities t
LEFT JOIN opportunity_versions v
ON v.organization_id = t.organization_id AND v.opportunity_id = t.id AND v.is_current
WHERE t.organization_id = $1 AND t.id = $2`, org, opp).Scan(&oldStyleNext); err != nil {
t.Fatalf("old style numbering query: %v", err)
}
if oldStyleNext != 1 {
t.Fatalf("the old numbering produced %d, expected 1. The stuck state is no longer reproducible, so "+
"the fix below is being verified against the wrong bug", oldStyleNext)
}
// And prove the collision is real rather than theoretical.
_, err := migrator.Exec(ctx, `
INSERT INTO opportunity_versions (organization_id, opportunity_id, version_number, amendment_number,
source_version_label, source_payload_hash, normalized_payload,
fetched_at, is_current)
VALUES ($1, $2, $3, '', 'Amendment', 'hash-v2', '{}'::jsonb, now(), true)`, org, opp, oldStyleNext)
if err == nil {
t.Fatal("inserting version 1 a second time SUCCEEDED. The unique constraint that made D9 visible is " +
"gone, which is a bigger problem than D9 was")
}
t.Logf("positive control OK: the old numbering asked for version %d and the database refused it", oldStyleNext)
}
// THE FIX. NextVersionNumber reads the highest number ever written, so it is right whatever the is_current
// flags say.
func TestD9NextVersionNumberEscapesTheStuckState(t *testing.T) {
if migrator == nil {
t.Skip("integration pools not configured")
}
ctx := context.Background()
org, opp, _ := seedStuckVersionState(t)
var next int
err := pgx.BeginFunc(ctx, migrator, func(tx pgx.Tx) error {
var iErr error
next, iErr = opportunities.NextVersionNumber(ctx, tx, org.String(), opp.String())
return iErr
})
if err != nil {
t.Fatalf("NextVersionNumber: %v", err)
}
if next != 2 {
t.Fatalf("next version = %d, want 2. Version 1 exists, so the successor is 2 regardless of which row "+
"is flagged current", next)
}
// And the write actually lands, which is the thing that had been impossible since 27 July.
err = pgx.BeginFunc(ctx, migrator, func(tx pgx.Tx) error {
if rErr := opportunities.RetireCurrentVersions(ctx, tx, org.String(), opp.String()); rErr != nil {
return rErr
}
_, iErr := tx.Exec(ctx, `
INSERT INTO opportunity_versions (organization_id, opportunity_id, version_number, amendment_number,
source_version_label, source_payload_hash, normalized_payload,
fetched_at, is_current)
VALUES ($1, $2, $3, '', 'Amendment', 'hash-v2', '{}'::jsonb, now(), true)`, org, opp, next)
return iErr
})
if err != nil {
t.Fatalf("writing the successor version still fails: %v", err)
}
// EXACTLY ONE CURRENT VERSION AFTERWARDS. This is the invariant whose breach caused D9 in the first place.
var currentCount, total int
if err := migrator.QueryRow(ctx, `
SELECT count(*) FILTER (WHERE is_current), count(*)
FROM opportunity_versions WHERE organization_id=$1 AND opportunity_id=$2`,
org, opp).Scan(¤tCount, &total); err != nil {
t.Fatalf("count versions: %v", err)
}
if currentCount != 1 {
t.Errorf("current versions = %d, want exactly 1", currentCount)
}
if total != 2 {
t.Errorf("total versions = %d, want 2, nothing overwritten", total)
}
t.Logf("escaped the stuck state: version 2 written, %d total versions, exactly %d current", total, currentCount)
}
// AND IT KEEPS WORKING. A third amendment must become version 3, so the counter advances rather than merely
// unsticking once.
func TestD9CounterKeepsAdvancing(t *testing.T) {
if migrator == nil {
t.Skip("integration pools not configured")
}
ctx := context.Background()
org, opp, _ := seedStuckVersionState(t)
for want := 2; want <= 4; want++ {
var next int
if err := pgx.BeginFunc(ctx, migrator, func(tx pgx.Tx) error {
var iErr error
if next, iErr = opportunities.NextVersionNumber(ctx, tx, org.String(), opp.String()); iErr != nil {
return iErr
}
if rErr := opportunities.RetireCurrentVersions(ctx, tx, org.String(), opp.String()); rErr != nil {
return rErr
}
_, iErr = tx.Exec(ctx, `
INSERT INTO opportunity_versions (organization_id, opportunity_id, version_number, amendment_number,
source_version_label, source_payload_hash, normalized_payload,
fetched_at, is_current)
VALUES ($1, $2, $3, '', 'Amendment', 'h', '{}'::jsonb, now(), true)`, org, opp, next)
return iErr
}); err != nil {
t.Fatalf("round for version %d: %v", want, err)
}
if next != want {
t.Fatalf("round produced version %d, want %d", next, want)
}
}
var currentCount int
if err := migrator.QueryRow(ctx,
`SELECT count(*) FILTER (WHERE is_current) FROM opportunity_versions
WHERE organization_id=$1 AND opportunity_id=$2`, org, opp).Scan(¤tCount); err != nil {
t.Fatalf("count current: %v", err)
}
if currentCount != 1 {
t.Errorf("after four versions, current = %d, want exactly 1", currentCount)
}
}