85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
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)
|
|
}
|
|
}
|