Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
9.1 kB ยท 304 lines
Go
at incident-api
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305package server_test
import ( "context" "encoding/json" "io" "log" "net/http" "os" "testing" "time"
"connectrpc.com/connect" "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" "github.com/openstatushq/openstatus/apps/private-location/internal/server" "github.com/openstatushq/openstatus/apps/private-location/internal/tinybird" "github.com/openstatushq/openstatus/apps/private-location/internal/workflows" private_locationv1 "github.com/openstatushq/openstatus/apps/private-location/proto/private_location/v1" "github.com/stretchr/testify/require")
func testDB() *sqlx.DB {
f, err := os.CreateTemp("", "db") if err != nil { log.Fatalln(err) } db, err := sqlx.Connect("sqlite3", f.Name()) if err != nil { log.Fatalln(err) } dat, err := os.ReadFile("./db_testdata") db.MustExec(string(dat))
return db}
type interceptorHTTPClient struct { f func(req *http.Request) (*http.Response, error)}
func (i *interceptorHTTPClient) RoundTrip(req *http.Request) (*http.Response, error) { return i.f(req)}
func (i *interceptorHTTPClient) GetHTTPClient() *http.Client { return &http.Client{ Transport: i, }}
func getTBClient(ctx context.Context) tinybird.Client { interceptor := &interceptorHTTPClient{ f: func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusAccepted, }, nil }, }
client := tinybird.NewClient(interceptor.GetHTTPClient(), "apiKey") return client}
func TestIngestHTTP_Unauthenticated(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{}) // No token header resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for missing token, got nil") } if connect.CodeOf(err) != connect.CodeUnauthenticated { t.Errorf("expected unauthenticated code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_DBError(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{}) req.Header().Set("openstatus-token", "token123") req.Msg.Id = "monitor1" req.Msg.MonitorId = "nonexistent" req.Msg.Timestamp = 1234567890 resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for db failure, got nil") } if connect.CodeOf(err) != connect.CodeInternal { t.Errorf("expected internal code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_MonitorNotExist(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{}) req.Header().Set("openstatus-token", "my-secret-key") req.Msg.Id = "monitor1" req.Msg.MonitorId = "nonexistent" req.Msg.Timestamp = 1234567890 resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for db failure, got nil") } if connect.CodeOf(err) != connect.CodeInternal { t.Errorf("expected internal code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_MonitorExist(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{}) req.Header().Set("openstatus-token", "my-secret-key") req.Msg.Id = "monitor1" req.Msg.MonitorId = "5" req.Msg.Timestamp = 1234567890 resp, err := h.IngestHTTP(context.Background(), req) if err != nil { t.Fatalf("expected nil error, got %v", err) }
if resp == nil { t.Errorf("expected not nil response, got %v", resp) }}
func TestIngestHTTP_ValidationError_EmptyMonitorID(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ MonitorId: "", Timestamp: 1234567890, }) req.Header().Set("openstatus-token", "my-secret-key")
resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for validation failure, got nil") } if connect.CodeOf(err) != connect.CodeInvalidArgument { t.Errorf("expected invalid argument code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_ValidationError_InvalidTimestamp(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ MonitorId: "5", Timestamp: 0, }) req.Header().Set("openstatus-token", "my-secret-key")
resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for validation failure, got nil") } if connect.CodeOf(err) != connect.CodeInvalidArgument { t.Errorf("expected invalid argument code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_ValidationError_NegativeLatency(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ MonitorId: "5", Latency: -100, Timestamp: 1234567890, }) req.Header().Set("openstatus-token", "my-secret-key")
resp, err := h.IngestHTTP(context.Background(), req) if err == nil { t.Fatalf("expected error for validation failure, got nil") } if connect.CodeOf(err) != connect.CodeInvalidArgument { t.Errorf("expected invalid argument code, got %v", connect.CodeOf(err)) } if resp != nil { t.Errorf("expected nil response, got %v", resp) }}
func TestIngestHTTP_WithFullData(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ Id: "request-1", MonitorId: "5", Timestamp: 1234567890, Latency: 150, CronTimestamp: 1234567800, Url: "https://example.com/api", StatusCode: 200, Timing: "150ms", Body: `{"status": "ok"}`, Headers: `{"Content-Type": "application/json"}`, }) req.Header().Set("openstatus-token", "my-secret-key")
resp, err := h.IngestHTTP(context.Background(), req) if err != nil { t.Fatalf("expected nil error, got %v", err) } if resp == nil { t.Errorf("expected not nil response, got nil") }}
// TestIngestHTTP_ForwardsErrorAndMessage guards against the probe's error flag// and failure message being dropped on the way to Tinybird and alerting: the// `error` column stayed 0 for every private check and alerts had empty bodies.func TestIngestHTTP_ForwardsErrorAndMessage(t *testing.T) { var capturedBody []byte interceptor := &interceptorHTTPClient{ f: func(req *http.Request) (*http.Response, error) { if req.Body != nil { capturedBody, _ = io.ReadAll(req.Body) } return &http.Response{StatusCode: http.StatusAccepted}, nil }, } h := server.NewPrivateLocationServer(testDB(), tinybird.NewClient(interceptor.GetHTTPClient(), "apiKey")) workflowsClient := recordingWorkflows{called: make(chan workflows.Payload, 1)} h.WorkflowsClient = workflowsClient
const message = "Request failed with status code 500" req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ Id: "request-err", MonitorId: "5", Timestamp: 1234567890, CronTimestamp: 1234567800, Url: "https://example.com/api", RequestStatus: "error", StatusCode: 500, Error: 1, Message: message, }) req.Header().Set("openstatus-token", "my-secret-key")
_, err := h.IngestHTTP(context.Background(), req) require.NoError(t, err)
var event struct { Error uint8 `json:"error"` Message string `json:"message"` } require.NoError(t, json.Unmarshal(capturedBody, &event)) require.Equal(t, uint8(1), event.Error) require.Equal(t, message, event.Message)
select { case payload := <-workflowsClient.called: require.Equal(t, "error", payload.Status) require.Equal(t, message, payload.Message) case <-time.After(2 * time.Second): t.Fatal("expected the failed check to be forwarded to the workflows service") }}
func TestIngestHTTP_WithError(t *testing.T) { h := server.NewPrivateLocationServer(testDB(), getTBClient(context.Background()))
req := connect.NewRequest(&private_locationv1.IngestHTTPRequest{ Id: "request-1", MonitorId: "5", Timestamp: 1234567890, Latency: 0, CronTimestamp: 1234567800, Url: "https://example.com/api", Error: 1, Message: "Connection timeout", }) req.Header().Set("openstatus-token", "my-secret-key")
resp, err := h.IngestHTTP(context.Background(), req) if err != nil { t.Fatalf("expected nil error, got %v", err) } if resp == nil { t.Errorf("expected not nil response, got nil") }}