143 lines
4.4 KiB
Go
143 lines
4.4 KiB
Go
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)
|
|
}
|
|
}
|