internal/store/queues_test.go

ba0a7d33f3a65ce53aafb074fda1682cf1cecfdf
gitbay/internal/store/queues_test.go history · blame · raw

118 lines · 3333 bytes

  1package store
  2
  3import (
  4	"testing"
  5	"time"
  6)
  7
  8// Push is a worker queue like the others, and the one failure config
  9// validation cannot catch — a key_id Apple did not issue — dead-letters
 10// every row on its first attempt. Without a count and the rows here an
 11// admin has no way to see that happening.
 12func TestQueuesReportsPush(t *testing.T) {
 13	s := open(t)
 14	if err := s.MigrateUp(); err != nil {
 15		t.Fatal(err)
 16	}
 17	uid, err := s.CreateUser("cmc", true)
 18	if err != nil {
 19		t.Fatal(err)
 20	}
 21	id, err := s.AddPushDevice(uid, "tok-a", "iphone")
 22	if err != nil {
 23		t.Fatal(err)
 24	}
 25	for i := 0; i < 3; i++ {
 26		if err := s.EnqueuePush(uid, "krz/gitbay", "cmc opened issue #1", "krz/gitbay/issues/1"); err != nil {
 27			t.Fatal(err)
 28		}
 29	}
 30	due, err := s.DuePush(20)
 31	if err != nil {
 32		t.Fatal(err)
 33	}
 34	if len(due) != 3 {
 35		t.Fatalf("queued %d, want 3", len(due))
 36	}
 37	next := time.Now().Add(time.Minute)
 38	if err := s.MarkPushFailed(due[0].ID, "apns 503", &next); err != nil {
 39		t.Fatal(err)
 40	}
 41	if err := s.MarkPushFailed(due[1].ID, "apns 403 InvalidProviderToken", nil); err != nil {
 42		t.Fatal(err)
 43	}
 44
 45	q, err := s.QueueStatus()
 46	if err != nil {
 47		t.Fatal(err)
 48	}
 49	if q.Push.Pending != 2 || q.Push.Retrying != 1 || q.Push.Failed != 1 {
 50		t.Fatalf("counts: %+v", q.Push)
 51	}
 52	if q.Push.OldestPending == "" {
 53		t.Fatalf("no oldest pending: %+v", q.Push)
 54	}
 55	// Retrying and dead-lettered rows, newest first, as the mail queue
 56	// lists them.
 57	if len(q.Push.Items) != 2 {
 58		t.Fatalf("items: %+v", q.Push.Items)
 59	}
 60	if q.Push.Items[0].DeviceID != id || q.Push.Items[0].FailedAt == "" ||
 61		q.Push.Items[0].LastError != "apns 403 InvalidProviderToken" {
 62		t.Fatalf("dead-lettered row: %+v", q.Push.Items[0])
 63	}
 64	if q.Push.Items[1].Attempts != 1 || q.Push.Items[1].FailedAt != "" {
 65		t.Fatalf("retrying row: %+v", q.Push.Items[1])
 66	}
 67	// A device token is never echoed, here included.
 68	for _, it := range q.Push.Items {
 69		if it.Title != "krz/gitbay" || it.CreatedAt == "" {
 70			t.Fatalf("row: %+v", it)
 71		}
 72	}
 73}
 74
 75// The build queue lists pending builds as well as running ones, so an
 76// admin can see what no runner is claiming without walking every repo.
 77func TestQueuesListsPendingBuilds(t *testing.T) {
 78	s := open(t)
 79	if err := s.MigrateUp(); err != nil {
 80		t.Fatal(err)
 81	}
 82	uid, err := s.CreateUser("cmc", true)
 83	if err != nil {
 84		t.Fatal(err)
 85	}
 86	if _, err := s.CreateRepo("user", uid, "orgo", "public"); err != nil {
 87		t.Fatal(err)
 88	}
 89	running, err := s.CreateBuild(1, "test", "abc123", "main", `["true"]`, "", "", true)
 90	if err != nil {
 91		t.Fatal(err)
 92	}
 93	pending, err := s.CreateBuild(1, "pages", "abc123", "main", `["true"]`, "", "", true)
 94	if err != nil {
 95		t.Fatal(err)
 96	}
 97	if _, ok, err := s.ClaimBuild(nil, false); err != nil || !ok {
 98		t.Fatalf("claim: %v ok=%v", err, ok)
 99	}
100
101	q, err := s.QueueStatus()
102	if err != nil {
103		t.Fatal(err)
104	}
105	if q.Builds.Pending != 1 || q.Builds.Running != 1 {
106		t.Fatalf("counts: %+v", q.Builds)
107	}
108	items := q.Builds.Items
109	if len(items) != 2 {
110		t.Fatalf("items: %+v", items)
111	}
112	if items[0].Number != running || items[0].Status != "running" || items[0].StartedAt == "" {
113		t.Fatalf("running row first: %+v", items[0])
114	}
115	if items[1].Number != pending || items[1].Status != "pending" || items[1].StartedAt != "" || items[1].CreatedAt == "" {
116		t.Fatalf("pending row after: %+v", items[1])
117	}
118}