tinyrelayfile
tinyrelay/internal/daemon/health_test.go/

internal/daemon/health_test.go raw
1package daemon
2
3import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "testing"
8)
9
10func TestProcessHealthAndReadinessLifecycle(t *testing.T) {
11 a, err := New(context.Background(), Config{DataDir: t.TempDir(), DefaultTenant: "missing"})
12 if err != nil {
13 t.Fatal(err)
14 }
15 ready := func() *httptest.ResponseRecorder {
16 req := httptest.NewRequest(http.MethodGet, "http://relay.test/readyz", nil)
17 res := httptest.NewRecorder()
18 a.ServeHTTP(res, req)
19 return res
20 }
21 if got := ready().Code; got != http.StatusServiceUnavailable {
22 t.Fatalf("before start readiness = %d", got)
23 }
24 if err := a.Start(context.Background(), "http://relay.test"); err != nil {
25 t.Fatal(err)
26 }
27 if got := ready().Code; got != http.StatusOK {
28 t.Fatalf("after start readiness = %d", got)
29 }
30 healthReq := httptest.NewRequest(http.MethodGet, "http://relay.test/healthz", nil)
31 healthRes := httptest.NewRecorder()
32 a.ServeHTTP(healthRes, healthReq)
33 if healthRes.Code != http.StatusOK {
34 t.Fatalf("liveness = %d", healthRes.Code)
35 }
36 if err := a.Close(context.Background()); err != nil {
37 t.Fatal(err)
38 }
39 if got := ready().Code; got != http.StatusServiceUnavailable {
40 t.Fatalf("after close readiness = %d", got)
41 }
42}
43
44func TestProcessReadinessReportsCatalogFailure(t *testing.T) {
45 a, err := New(context.Background(), Config{DataDir: t.TempDir()})
46 if err != nil {
47 t.Fatal(err)
48 }
49 if err := a.Start(context.Background(), "http://relay.test"); err != nil {
50 t.Fatal(err)
51 }
52 if err := a.catalog.Close(); err != nil {
53 t.Fatal(err)
54 }
55 req := httptest.NewRequest(http.MethodGet, "http://relay.test/readyz", nil)
56 res := httptest.NewRecorder()
57 a.ServeHTTP(res, req)
58 if res.Code != http.StatusServiceUnavailable {
59 t.Fatalf("closed catalog readiness = %d", res.Code)
60 }
61 _ = a.Close(context.Background())
62}
63
64func TestTenantHealthObeysMaintenanceAndStorage(t *testing.T) {
65 a, tenant := testTenant(t)
66 request := func(path string) int {
67 req := httptest.NewRequest(http.MethodGet, "http://relay.test"+path, nil)
68 res := httptest.NewRecorder()
69 a.ServeHTTP(res, req)
70 return res.Code
71 }
72 if got := request("/r/main/healthz"); got != http.StatusOK {
73 t.Fatalf("tenant health = %d", got)
74 }
75 _, release, err := tenant.beginMaintenance(context.Background())
76 if err != nil {
77 t.Fatal(err)
78 }
79 if got := request("/r/main/readyz"); got != http.StatusServiceUnavailable {
80 t.Fatalf("tenant readiness during maintenance = %d", got)
81 }
82 release()
83 if got := request("/r/main/readyz"); got != http.StatusOK {
84 t.Fatalf("tenant readiness after maintenance = %d", got)
85 }
86 // Stop the tenant workers before closing their shared store. Closing the
87 // database underneath a live queue claim races cleanup and can turn this
88 // health probe into an unrelated "database is closed" failure.
89 if err := tenant.closeServices(context.Background()); err != nil {
90 t.Fatal(err)
91 }
92 if err := tenant.store.Close(); err != nil {
93 t.Fatal(err)
94 }
95 if got := request("/r/main/healthz"); got != http.StatusServiceUnavailable {
96 t.Fatalf("tenant health after storage close = %d", got)
97 }
98}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs