package testutil import ( "database/sql" "net/http/httptest" "os" "path/filepath" "testing" "testing/fstest" "forge-mesh/internal/api" "forge-mesh/internal/config" "forge-mesh/internal/db" "forge-mesh/internal/forge" ) const ( DefaultBasicUser = "admin" DefaultBasicPass = "changeme" DefaultFleetSecret = "test-fleet-secret" ) // TestServer wraps an httptest server with auth helpers. type TestServer struct { URL string BasicUser string BasicPass string FleetSecret string SQL *sql.DB close func() } // Close shuts down the test server and database. func (ts *TestServer) Close() { if ts.close != nil { ts.close() } } // NewTestServer spins up a full forge-mesh HTTP server on a random port. func NewTestServer(t *testing.T) *TestServer { t.Helper() dir := t.TempDir() cfgPath := filepath.Join(dir, "config.json") writeConfig(t, cfgPath, dir) cfg, err := config.Load(cfgPath) if err != nil { t.Fatalf("load config: %v", err) } if err := cfg.EnsureDataDirs(); err != nil { t.Fatalf("ensure dirs: %v", err) } conn, err := db.Open(cfg.DatabasePath) if err != nil { t.Fatalf("open db: %v", err) } kp, err := forge.LoadOrCreateKey(cfg.Forge.SigningKeyPath) if err != nil { conn.Close() t.Fatalf("signing key: %v", err) } repoRoot, err := findRepoRoot() if err != nil { conn.Close() t.Fatalf("repo root: %v", err) } tmplPath := filepath.Join(repoRoot, "scripts", "install.sh.tpl") static := fstest.MapFS{ "index.html": &fstest.MapFile{Data: []byte("test")}, } srv, err := api.NewServer(cfg, conn, static, "integration-test", tmplPath, kp.PublicKeyHex()) if err != nil { conn.Close() t.Fatalf("new server: %v", err) } hts := httptest.NewServer(srv.Handler()) return &TestServer{ URL: hts.URL, BasicUser: DefaultBasicUser, BasicPass: DefaultBasicPass, FleetSecret: DefaultFleetSecret, SQL: conn, close: func() { hts.Close() conn.Close() }, } } func writeConfig(t *testing.T, path, dir string) { t.Helper() content := `{ "listen_addr": ":0", "data_dir": "` + dir + `", "database_path": "` + filepath.Join(dir, "test.db") + `", "operator_clearance": 4, "auth": { "basic_username": "admin", "basic_password": "changeme", "fleet_secret": "test-fleet-secret" }, "forge": { "signing_key_path": "` + filepath.Join(dir, "signing.key") + `", "artifacts_dir": "` + filepath.Join(dir, "artifacts") + `" } }` if err := os.WriteFile(path, []byte(content), 0o644); err != nil { t.Fatalf("write config: %v", err) } } func findRepoRoot() (string, error) { wd, err := os.Getwd() if err != nil { return "", err } dir := wd for { if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil { return dir, nil } parent := filepath.Dir(dir) if parent == dir { return wd, nil } dir = parent } }