package monitor import ( "context" "net" "net/http" "net/http/httptest" "os" "path/filepath" "runtime" "testing" ) func TestHTTPProbe(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })) defer srv.Close() c := Probe(context.Background(), Input{Type: "http", Target: srv.URL, TimeoutMS: 1000, ExpectedMin: 200, ExpectedMax: 299}) if !c.OK || c.StatusCode != http.StatusNoContent { t.Fatalf("unexpected check: %+v", c) } } func TestTCPProbe(t *testing.T) { ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer ln.Close() c := Probe(context.Background(), Input{Type: "tcp", Target: ln.Addr().String(), TimeoutMS: 1000}) if !c.OK { t.Fatalf("unexpected check: %+v", c) } } func TestAggregateServiceStatus(t *testing.T) { cases := []struct { name string monitors []Monitor want string }{ {"all up", []Monitor{{Status: "up"}, {Status: "up"}}, "up"}, {"one fault", []Monitor{{Status: "up"}, {Status: "down"}}, "down"}, {"maintenance", []Monitor{{Status: "up"}, {Status: "maintenance"}}, "maintenance"}, {"empty", nil, "unknown"}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { if got := aggregateStatus(tc.monitors); got != tc.want { t.Fatalf("got %s want %s", got, tc.want) } }) } } func TestDockerProbeRunningAndHealthy(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("shell fixture") } d := t.TempDir() path := filepath.Join(d, "docker") if err := os.WriteFile(path, []byte("#!/bin/sh\nprintf '%s\\n' '{\"Running\":true,\"Status\":\"running\",\"Health\":{\"Status\":\"healthy\"}}'\n"), 0755); err != nil { t.Fatal(err) } t.Setenv("PATH", d+string(os.PathListSeparator)+os.Getenv("PATH")) c := Probe(context.Background(), Input{Type: "docker", Target: "app", TimeoutMS: 1000, RequireHealthy: true}) if !c.OK { t.Fatalf("expected healthy docker probe, got %+v", c) } } func TestDockerProbeHealthRequiredWithoutHealthcheck(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("shell fixture") } d := t.TempDir() path := filepath.Join(d, "docker") if err := os.WriteFile(path, []byte("#!/bin/sh\nprintf '%s\\n' '{\"Running\":true,\"Status\":\"running\",\"Health\":null}'\n"), 0755); err != nil { t.Fatal(err) } t.Setenv("PATH", d+string(os.PathListSeparator)+os.Getenv("PATH")) c := Probe(context.Background(), Input{Type: "docker", Target: "app", TimeoutMS: 1000, RequireHealthy: true}) if c.OK || c.Message != "container has no healthcheck" { t.Fatalf("unexpected docker check: %+v", c) } }