package deployments import ( "os" "path/filepath" "runtime" "strings" "testing" "gopkg.in/yaml.v3" ) func repoRoot(t *testing.T) string { t.Helper() _, filename, _, ok := runtime.Caller(0) if !ok { t.Fatalf("failed to resolve caller path") } return filepath.Clean(filepath.Join(filepath.Dir(filename), "..", "..", "..")) } func asMap(t *testing.T, v any) map[string]any { t.Helper() m, ok := v.(map[string]any) if !ok { t.Fatalf("expected map[string]any, got %T", v) } return m } func asSlice(t *testing.T, v any) []any { t.Helper() s, ok := v.([]any) if !ok { t.Fatalf("expected []any, got %T", v) } return s } func TestProdTraefikComposeHasExpectedConfig(t *testing.T) { t.Parallel() composePath := filepath.Join(repoRoot(t), "deployments", "docker-compose.prod.yml") b, err := os.ReadFile(composePath) if err != nil { t.Fatalf("read compose file: %v", err) } var doc map[string]any if err := yaml.Unmarshal(b, &doc); err != nil { t.Fatalf("parse compose yaml: %v", err) } services := asMap(t, doc["services"]) api := asMap(t, services["api-server"]) labels := asSlice(t, api["labels"]) labelStrs := make([]string, 0, len(labels)) for _, l := range labels { ls, ok := l.(string) if !ok { t.Fatalf("expected label string, got %T", l) } labelStrs = append(labelStrs, ls) } wantLabelPrefixes := []string{ "traefik.enable=true", "traefik.docker.network=", "traefik.http.services.fetchml.loadbalancer.server.port=9101", "traefik.http.routers.fetchml.rule=", "traefik.http.routers.fetchml.entrypoints=", "traefik.http.routers.fetchml.tls=true", } for _, wantPrefix := range wantLabelPrefixes { found := false for _, l := range labelStrs { if strings.HasPrefix(l, wantPrefix) { found = true break } } if !found { t.Fatalf("missing label with prefix %q; labels=%v", wantPrefix, labelStrs) } } nets := asSlice(t, api["networks"]) foundTraefikNet := false for _, n := range nets { ns, ok := n.(string) if !ok { t.Fatalf("expected network name string, got %T", n) } if ns == "traefik" { foundTraefikNet = true break } } if !foundTraefikNet { t.Fatalf("api-server is not attached to traefik network; networks=%v", nets) } networks := asMap(t, doc["networks"]) traefik := asMap(t, networks["traefik"]) external, ok := traefik["external"].(bool) if !ok { t.Fatalf("expected networks.traefik.external to be bool, got %T", traefik["external"]) } if !external { t.Fatalf("expected networks.traefik.external to be true") } }