internal/store/mergequeue_test.go

v1.40.1
gitbay/internal/store/mergequeue_test.go history · blame · raw

136 lines · 4221 bytes

  1package store
  2
  3import (
  4	"slices"
  5	"testing"
  6)
  7
  8// A queued merge rides on the merge request row, re-queueing replaces
  9// the queuer and strategy and clears the reason, and dequeueing says
 10// whether there was anything to take off.
 11func TestMergeQueueRoundTrip(t *testing.T) {
 12	s, repoID, uid := mrFixture(t)
 13	mr, err := s.MRByNumber(repoID, 1)
 14	if err != nil {
 15		t.Fatal(err)
 16	}
 17	if mr.QueuedAt != "" {
 18		t.Fatalf("fresh MR is queued: %+v", mr)
 19	}
 20	if err := s.QueueMerge(mr.ID, uid, "ff", 0, 0); err != nil {
 21		t.Fatal(err)
 22	}
 23	if err := s.SetMergeQueueReason(mr.ID, "checks pending"); err != nil {
 24		t.Fatal(err)
 25	}
 26	mr, _ = s.MRByNumber(repoID, 1)
 27	if mr.QueuedAt == "" || mr.QueuedBy != "cmc" || mr.QueuedByID != uid || mr.QueueStrategy != "ff" || mr.QueueReason != "checks pending" {
 28		t.Fatalf("queued MR: %+v", mr)
 29	}
 30	byID, err := s.MRByID(mr.ID)
 31	if err != nil || byID.Number != 1 || byID.QueueStrategy != "ff" {
 32		t.Fatalf("MRByID = %+v, %v", byID, err)
 33	}
 34
 35	if err := s.QueueMerge(mr.ID, uid, "merge", 0, 0); err != nil {
 36		t.Fatal(err)
 37	}
 38	mr, _ = s.MRByNumber(repoID, 1)
 39	if mr.QueueStrategy != "merge" || mr.QueueReason != "" {
 40		t.Fatalf("re-queued MR: %+v", mr)
 41	}
 42
 43	ids, err := s.QueuedMRsAtHead(repoID, "abc123")
 44	if err != nil || !slices.Equal(ids, []int64{mr.ID}) {
 45		t.Fatalf("QueuedMRsAtHead = %v, %v", ids, err)
 46	}
 47	if ids, _ := s.QueuedMRsAtHead(repoID, "other"); len(ids) != 0 {
 48		t.Fatalf("QueuedMRsAtHead(other) = %v", ids)
 49	}
 50
 51	if ok, err := s.DequeueMerge(mr.ID); err != nil || !ok {
 52		t.Fatalf("DequeueMerge = %v, %v", ok, err)
 53	}
 54	if ok, _ := s.DequeueMerge(mr.ID); ok {
 55		t.Fatal("second DequeueMerge found a row")
 56	}
 57}
 58
 59// A merge request that leaves the open states leaves the queue with it,
 60// whichever path merged or closed it.
 61func TestMergeQueueLeftOnMergeOrClose(t *testing.T) {
 62	s, repoID, uid := mrFixture(t)
 63	mr, _ := s.MRByNumber(repoID, 1)
 64	for _, mark := range []func() error{
 65		func() error { return s.MarkMerged(mr.ID, "base", uid, "") },
 66		func() error { return s.MarkClosed(mr.ID, uid, "") },
 67	} {
 68		if err := s.SetMRState(mr.ID, "open"); err != nil {
 69			t.Fatal(err)
 70		}
 71		if err := s.QueueMerge(mr.ID, uid, "", 0, 0); err != nil {
 72			t.Fatal(err)
 73		}
 74		if err := mark(); err != nil {
 75			t.Fatal(err)
 76		}
 77		got, _ := s.MRByNumber(repoID, 1)
 78		if got.QueuedAt != "" {
 79			t.Fatalf("%s MR still queued: %+v", got.State, got)
 80		}
 81	}
 82	// source_gone keeps it: the branch can come back.
 83	if err := s.SetMRState(mr.ID, "open"); err != nil {
 84		t.Fatal(err)
 85	}
 86	s.QueueMerge(mr.ID, uid, "", 0, 0)
 87	s.SetMRState(mr.ID, "source_gone")
 88	if got, _ := s.MRByNumber(repoID, 1); got.QueuedAt == "" {
 89		t.Fatal("source_gone dropped the queued merge")
 90	}
 91}
 92
 93// A queued merge remembers the credential it was queued with, and a
 94// removed key or revoked token reads back as gone rather than as some
 95// later credential that reused the id.
 96func TestMergeQueueCredential(t *testing.T) {
 97	s, repoID, uid := mrFixture(t)
 98	mr, _ := s.MRByNumber(repoID, 1)
 99	if err := s.AddSSHKey(uid, "SHA256:k1", "ssh-ed25519", []byte("b1"), "full", ""); err != nil {
100		t.Fatal(err)
101	}
102	key, err := s.SSHKeyByFingerprint("SHA256:k1")
103	if err != nil {
104		t.Fatal(err)
105	}
106	if err := s.QueueMerge(mr.ID, uid, "", key.ID, 0); err != nil {
107		t.Fatal(err)
108	}
109	if q, err := s.MergeQueueCredential(mr.ID); err != nil || q.Kind != "key" || q.KeyID != key.ID {
110		t.Fatalf("credential = %+v, %v", q, err)
111	}
112	if err := s.RemoveSSHKey(uid, "SHA256:k1"); err != nil {
113		t.Fatal(err)
114	}
115	if q, _ := s.MergeQueueCredential(mr.ID); q.Kind != "key" || q.KeyID != 0 {
116		t.Fatalf("credential after key removal = %+v, want key with id 0", q)
117	}
118	if err := s.QueueMerge(mr.ID, uid, "", 0, 0); err != nil {
119		t.Fatal(err)
120	}
121	if q, _ := s.MergeQueueCredential(mr.ID); q.Kind != "" {
122		t.Fatalf("web-queued credential = %+v", q)
123	}
124}
125
126// A merge request whose source branch is gone is not one a status can
127// merge.
128func TestQueuedMRsAtHeadSkipsSourceGone(t *testing.T) {
129	s, repoID, uid := mrFixture(t)
130	mr, _ := s.MRByNumber(repoID, 1)
131	s.QueueMerge(mr.ID, uid, "", 0, 0)
132	s.SetMRState(mr.ID, "source_gone")
133	if ids, _ := s.QueuedMRsAtHead(repoID, "abc123"); len(ids) != 0 {
134		t.Fatalf("QueuedMRsAtHead = %v, want none", ids)
135	}
136}