package link import ( "encoding/json" "reflect" "strings" "testing" "time" ) // The start of a try names no repository and no commit (novox/hq issue 686): the forge's holder writes // mesh/merge-gate pending on the open pull request whose head a start names, and nothing on the forge moves // for a try. A pull request's check still names both. func TestATrysStartNamesNoCommitTheForgeCouldMatch(t *testing.T) { sha := strings.Repeat("c0ffee", 7)[:40] at := time.Date(2026, 10, 14, 0, 0, 0, 0, time.UTC) try := BuildRequest{ID: "build-1", Repository: "https://forge/novox/a.git", Ref: sha, Check: &CheckRequest{Owner: "novox", Repo: "a", Try: true}} body, _ := json.Marshal(startOf(try, "ace", 1, at)) if strings.Contains(string(body), sha) || strings.Contains(string(body), "novox/a") { t.Fatalf("a try's start names what the forge matches a pull request by: %s", body) } if s := startOf(try, "ace", 2, at); s.ID != "build-1" || s.On != "ace" || !s.Try || s.Delivery != 2 || s.At == "" { t.Fatalf("a try's start lost what the queue reads: %+v", s) } pull := try pull.Check = &CheckRequest{Owner: "novox", Repo: "a", Number: 7} if s := startOf(pull, "ace", 1, at); s.Ref != sha || s.Repository == "" || s.Try { t.Fatalf("a pull request's check's start: %+v", s) } } // A try stays behind every delivery and every pull request's check, however long it has waited: the ten // minutes that put a check ahead of later deliveries never promote a try (novox/hq issue 686). func TestATryIsNeverHandedOutBeforeADeliveryOrAPullRequestsCheck(t *testing.T) { now := time.Date(2026, 10, 12, 12, 0, 0, 0, time.UTC) try := func(seq uint64, id string, asked time.Time) QueuedAsk { a := anAsk(seq, id, asked, true) a.Request.Check.Try = true return a } waiting := []QueuedAsk{ try(1, "try-old", now.Add(-40*time.Minute)), try(2, "try-young", now.Add(-time.Minute)), anAsk(3, "check-young", now.Add(-2*time.Minute), true), anAsk(4, "delivery", now.Add(-time.Minute), false), } want := []string{"delivery", "check-young", "try-old", "try-young"} if got := idsOf(QueueOrder(waiting, now)); !reflect.DeepEqual(got, want) { t.Fatalf("handed out as %v, want %v", got, want) } if !SafeBuildID("build-20261014T000000-1a2b") || SafeBuildID("x.>") || SafeBuildID("*") || SafeBuildID("") { t.Fatal("an id that is a pattern passes for a build's id") } }