package service import ( "encoding/json" "net/http" "net/http/httptest" "testing" ) func kubeClientFactoryForURL(baseURL string, client *http.Client) *kubeClient { return &kubeClient{ baseURL: baseURL, token: "test-token", client: client, } } func installKubeFactory(t *testing.T, baseURL string, client *http.Client) { t.Helper() origFactory := kubeClientFactory kubeClientFactory = func() (*kubeClient, error) { return kubeClientFactoryForURL(baseURL, client), nil } t.Cleanup(func() { kubeClientFactory = origFactory }) } func TestClusterActiveRemotePodLoadsCountsOnlyLivePods(t *testing.T) { kube := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet || r.URL.Path != "/api/v1/namespaces/maintenance/pods" { http.NotFound(w, r) return } if got := r.URL.Query().Get("labelSelector"); got != "app=metis-remote,metis-run=build" { t.Fatalf("unexpected labelSelector %q", got) } _ = json.NewEncoder(w).Encode(map[string]any{ "items": []any{ map[string]any{ "metadata": map[string]any{"labels": map[string]string{"app": "metis-remote", "metis-run": "build"}}, "spec": map[string]any{"nodeName": "titan-04"}, "status": map[string]any{"phase": "Running"}, }, map[string]any{ "metadata": map[string]any{"labels": map[string]string{"app": "metis-remote", "metis-run": "build"}}, "spec": map[string]any{"nodeName": "titan-04"}, "status": map[string]any{"phase": "Pending"}, }, map[string]any{ "metadata": map[string]any{"labels": map[string]string{"app": "metis-remote", "metis-run": "build"}}, "spec": map[string]any{"nodeName": "titan-05"}, "status": map[string]any{"phase": "Succeeded"}, }, }, }) })) defer kube.Close() installKubeFactory(t, kube.URL, kube.Client()) loads := clusterActiveRemotePodLoads("maintenance", "build") if loads["titan-04"] != 2 { t.Fatalf("expected titan-04 load 2, got %#v", loads) } if _, ok := loads["titan-05"]; ok { t.Fatalf("expected succeeded pod to be ignored, got %#v", loads) } } func TestSelectBuilderHostAvoidsBusyBuilderWhenPeersAreFree(t *testing.T) { kube := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case r.Method == http.MethodGet && r.URL.Path == "/api/v1/nodes": _ = json.NewEncoder(w).Encode(map[string]any{ "items": []any{ map[string]any{ "metadata": map[string]any{ "name": "titan-04", "labels": map[string]string{ "kubernetes.io/arch": "arm64", "hardware": "rpi5", "node-role.kubernetes.io/worker": "true", }, }, "spec": map[string]any{"unschedulable": false}, }, map[string]any{ "metadata": map[string]any{ "name": "titan-05", "labels": map[string]string{ "kubernetes.io/arch": "arm64", "hardware": "rpi5", "node-role.kubernetes.io/worker": "true", }, }, "spec": map[string]any{"unschedulable": false}, }, }, }) case r.Method == http.MethodGet && r.URL.Path == "/api/v1/namespaces/maintenance/pods": selector := r.URL.Query().Get("labelSelector") var items []any switch selector { case "app=metis-remote,metis-run=build": items = []any{ map[string]any{ "metadata": map[string]any{"labels": map[string]string{"app": "metis-remote", "metis-run": "build"}}, "spec": map[string]any{"nodeName": "titan-04"}, "status": map[string]any{"phase": "Running"}, }, } case "app=metis-remote": items = []any{ map[string]any{ "metadata": map[string]any{"labels": map[string]string{"app": "metis-remote", "metis-run": "build"}}, "spec": map[string]any{"nodeName": "titan-04"}, "status": map[string]any{"phase": "Running"}, }, } default: t.Fatalf("unexpected labelSelector %q", selector) } _ = json.NewEncoder(w).Encode(map[string]any{"items": items}) default: http.NotFound(w, r) } })) defer kube.Close() installKubeFactory(t, kube.URL, kube.Client()) app := newTestApp(t) app.settings.Namespace = "maintenance" node, err := app.selectBuilderHost("arm64", "") if err != nil { t.Fatalf("selectBuilderHost: %v", err) } if node.Name != "titan-05" { t.Fatalf("expected titan-05 builder, got %s", node.Name) } }