Files
LINUX-AETHERFORGE/internal/testutil/server.go
drjones 3678b199d0
Some checks failed
Test / test (push) Has been cancelled
Initial commit: AetherForge Linux (forge-mesh) v0.1.0-dev
2026-07-04 09:31:23 +00:00

137 lines
2.8 KiB
Go

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("<html><body>test</body></html>")},
}
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
}
}