Files
neural-hunt/internal/customer/docker_test.go
groot 28e125ffe3
All checks were successful
release-tag / release-image (push) Successful in 4m50s
RC-13
2026-08-13 12:40:51 +02:00

118 lines
3.8 KiB
Go

package customer
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"sync/atomic"
"testing"
)
func TestEnsureImagePullsMissingImage(t *testing.T) {
var present atomic.Bool
var pulls atomic.Int32
image := "registry.example.com/neuralhunt/worker:v4.1"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.HasPrefix(r.URL.Path, "/images/") && strings.HasSuffix(r.URL.Path, "/json"):
if !present.Load() {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"Id":"sha256:test"}`))
case r.Method == http.MethodPost && r.URL.Path == "/images/create":
if got := r.URL.Query().Get("fromImage"); got != image {
t.Fatalf("fromImage=%q want %q", got, image)
}
pulls.Add(1)
present.Store(true)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte("{\"status\":\"Pull complete\"}\n"))
default:
http.Error(w, "unexpected request", http.StatusBadRequest)
}
}))
defer ts.Close()
d := &DockerClient{hc: ts.Client(), base: ts.URL}
if err := d.EnsureImage(context.Background(), image, true, ""); err != nil {
t.Fatal(err)
}
if pulls.Load() != 1 {
t.Fatalf("pulls=%d want 1", pulls.Load())
}
if err := d.EnsureImage(context.Background(), image, true, ""); err != nil {
t.Fatal(err)
}
if pulls.Load() != 1 {
t.Fatalf("second ensure pulled again: pulls=%d", pulls.Load())
}
}
func TestEnsureImageCanRequirePrePulledImage(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r)
}))
defer ts.Close()
d := &DockerClient{hc: ts.Client(), base: ts.URL}
if err := d.EnsureImage(context.Background(), "neuralhunt-worker:local", false, ""); err == nil || !strings.Contains(err.Error(), "CS_WORKER_AUTO_PULL") {
t.Fatalf("unexpected error: %v", err)
}
}
func TestRegistryAuthHeader(t *testing.T) {
h, err := RegistryAuthHeader("robot", "token", "registry.example.com")
if err != nil {
t.Fatal(err)
}
if h == "" {
t.Fatal("expected registry auth header")
}
if _, err := RegistryAuthHeader("robot", "", "registry.example.com"); err == nil {
t.Fatal("incomplete registry credentials should fail")
}
}
func TestCreateWorkerUsesImageEntrypointByDefault(t *testing.T) {
var got map[string]any
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/containers/create" {
http.Error(w, "unexpected", 400)
return
}
if err := json.NewDecoder(r.Body).Decode(&got); err != nil {
t.Fatal(err)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"Id":"container-1"}`))
}))
defer ts.Close()
d := &DockerClient{hc: ts.Client(), base: ts.URL}
cfg := WorkerContainerConfig{Image: "neuralhunt-worker:local", Network: "nh", GameURL: "http://app:8080", RegisterURL: "http://cs:8092/internal/workers/register", WorkerID: "wrk_1", RegisterToken: "secret", TaskID: "task_1", BeaconPath: "auto", Volume: "vol_1", Name: "worker-1"}
if _, err := d.CreateWorker(context.Background(), cfg); err != nil {
t.Fatal(err)
}
if _, exists := got["Entrypoint"]; exists {
t.Fatalf("dedicated worker image should keep its image ENTRYPOINT: %#v", got["Entrypoint"])
}
host, _ := got["HostConfig"].(map[string]any)
rp, _ := host["RestartPolicy"].(map[string]any)
if rp["Name"] != "unless-stopped" {
t.Fatalf("worker restart policy=%#v want unless-stopped", rp)
}
cfg.Name = "worker-2"
cfg.Entrypoint = "/app/neuralhunt-client"
if _, err := d.CreateWorker(context.Background(), cfg); err != nil {
t.Fatal(err)
}
if _, exists := got["Entrypoint"]; !exists {
t.Fatal("compatibility Entrypoint override was not sent")
}
}