Files
at-container-registry/pkg/hold/config_test.go
T
2026-02-09 22:39:38 -06:00

306 lines
8.5 KiB
Go

package hold
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func init() {
// Point metadata endpoint to a closed listener so it fails instantly instead of
// waiting 2s for the real 169.254.169.254 to timeout on non-cloud machines.
metadataEndpoint = "http://127.0.0.1:1"
}
// setupEnv sets environment variables for testing and returns a cleanup function
func setupEnv(t *testing.T, vars map[string]string) func() {
// Save original env
original := make(map[string]string)
for k := range vars {
original[k] = os.Getenv(k)
}
// Set test env vars
for k, v := range vars {
if err := os.Setenv(k, v); err != nil {
t.Fatalf("Failed to set env %s: %v", k, err)
}
}
// Return cleanup function
return func() {
for k, v := range original {
if v == "" {
os.Unsetenv(k)
} else {
os.Setenv(k, v)
}
}
}
}
func TestLoadConfig_Success(t *testing.T) {
cleanup := setupEnv(t, map[string]string{
"HOLD_SERVER_PUBLIC_URL": "https://hold.example.com",
"HOLD_SERVER_ADDR": ":9000",
"HOLD_SERVER_PUBLIC": "true",
"HOLD_SERVER_TEST_MODE": "true",
"HOLD_REGISTRATION_OWNER_DID": "did:plc:owner123",
"HOLD_REGISTRATION_ALLOW_ALL_CREW": "true",
"S3_BUCKET": "test-bucket",
"AWS_ACCESS_KEY_ID": "test-key",
"AWS_SECRET_ACCESS_KEY": "test-secret",
"HOLD_DATABASE_PATH": "/tmp/test-db",
"HOLD_DATABASE_KEY_PATH": "/tmp/test-key.pem",
})
defer cleanup()
cfg, err := LoadConfig("")
if err != nil {
t.Fatalf("Expected success, got error: %v", err)
}
// Verify server config
if cfg.Server.PublicURL != "https://hold.example.com" {
t.Errorf("Expected PublicURL=https://hold.example.com, got %s", cfg.Server.PublicURL)
}
if cfg.Server.Addr != ":9000" {
t.Errorf("Expected Addr=:9000, got %s", cfg.Server.Addr)
}
if !cfg.Server.Public {
t.Error("Expected Public=true")
}
if !cfg.Server.TestMode {
t.Error("Expected TestMode=true")
}
if cfg.Server.ReadTimeout != 5*time.Minute {
t.Errorf("Expected ReadTimeout=5m, got %v", cfg.Server.ReadTimeout)
}
// Verify registration config
if cfg.Registration.OwnerDID != "did:plc:owner123" {
t.Errorf("Expected OwnerDID=did:plc:owner123, got %s", cfg.Registration.OwnerDID)
}
if !cfg.Registration.AllowAllCrew {
t.Error("Expected AllowAllCrew=true")
}
// Verify database config
if cfg.Database.Path != "/tmp/test-db" {
t.Errorf("Expected Database.Path=/tmp/test-db, got %s", cfg.Database.Path)
}
if cfg.Database.KeyPath != "/tmp/test-key.pem" {
t.Errorf("Expected Database.KeyPath=/tmp/test-key.pem, got %s", cfg.Database.KeyPath)
}
}
func TestLoadConfig_MissingPublicURL(t *testing.T) {
cleanup := setupEnv(t, map[string]string{
"HOLD_SERVER_PUBLIC_URL": "", // Missing required field
"S3_BUCKET": "test-bucket",
})
defer cleanup()
_, err := LoadConfig("")
if err == nil {
t.Error("Expected error for missing HOLD_SERVER_PUBLIC_URL")
}
}
func TestLoadConfig_MissingS3Bucket(t *testing.T) {
cleanup := setupEnv(t, map[string]string{
"HOLD_SERVER_PUBLIC_URL": "https://hold.example.com",
"S3_BUCKET": "", // Missing required field
})
defer cleanup()
_, err := LoadConfig("")
if err == nil {
t.Error("Expected error for missing S3_BUCKET")
}
}
func TestLoadConfig_Defaults(t *testing.T) {
cleanup := setupEnv(t, map[string]string{
"HOLD_SERVER_PUBLIC_URL": "https://hold.example.com",
"S3_BUCKET": "test-bucket",
"AWS_ACCESS_KEY_ID": "test-key",
"AWS_SECRET_ACCESS_KEY": "test-secret",
// Don't set optional vars - test defaults
"HOLD_SERVER_ADDR": "",
"HOLD_SERVER_PUBLIC": "",
"HOLD_SERVER_TEST_MODE": "",
"HOLD_REGISTRATION_OWNER_DID": "",
"HOLD_REGISTRATION_ALLOW_ALL_CREW": "",
"AWS_REGION": "",
"HOLD_DATABASE_PATH": "",
})
defer cleanup()
cfg, err := LoadConfig("")
if err != nil {
t.Fatalf("Expected success, got error: %v", err)
}
// Verify defaults
if cfg.Server.Addr != ":8080" {
t.Errorf("Expected default Addr=:8080, got %s", cfg.Server.Addr)
}
if cfg.Server.Public {
t.Error("Expected default Public=false")
}
if cfg.Server.TestMode {
t.Error("Expected default TestMode=false")
}
if cfg.Registration.OwnerDID != "" {
t.Error("Expected default OwnerDID to be empty")
}
if cfg.Registration.AllowAllCrew {
t.Error("Expected default AllowAllCrew=false")
}
if cfg.Database.Path != "/var/lib/atcr-hold" {
t.Errorf("Expected default Database.Path=/var/lib/atcr-hold, got %s", cfg.Database.Path)
}
}
func TestLoadConfig_KeyPathDefault(t *testing.T) {
cleanup := setupEnv(t, map[string]string{
"HOLD_SERVER_PUBLIC_URL": "https://hold.example.com",
"S3_BUCKET": "test-bucket",
"AWS_ACCESS_KEY_ID": "test-key",
"AWS_SECRET_ACCESS_KEY": "test-secret",
"HOLD_DATABASE_PATH": "/custom/db/path",
"HOLD_DATABASE_KEY_PATH": "", // Should default to {Database.Path}/signing.key
})
defer cleanup()
cfg, err := LoadConfig("")
if err != nil {
t.Fatalf("Expected success, got error: %v", err)
}
expectedKeyPath := filepath.Join("/custom/db/path", "signing.key")
if cfg.Database.KeyPath != expectedKeyPath {
t.Errorf("Expected KeyPath=%s, got %s", expectedKeyPath, cfg.Database.KeyPath)
}
}
func TestBuildStorageConfigFromFields_S3_Complete(t *testing.T) {
sc := StorageConfig{
AccessKey: "test-access-key",
SecretKey: "test-secret-key",
Region: "us-west-2",
Bucket: "test-bucket",
Endpoint: "https://s3.example.com",
}
cfg := buildStorageConfigFromFields(sc)
s3Params, ok := cfg["s3"]
if !ok {
t.Fatal("Expected s3 storage config")
}
params := map[string]any(s3Params)
if params["accesskey"] != "test-access-key" {
t.Errorf("Expected accesskey=test-access-key, got %v", params["accesskey"])
}
if params["secretkey"] != "test-secret-key" {
t.Errorf("Expected secretkey=test-secret-key, got %v", params["secretkey"])
}
if params["region"] != "us-west-2" {
t.Errorf("Expected region=us-west-2, got %v", params["region"])
}
if params["bucket"] != "test-bucket" {
t.Errorf("Expected bucket=test-bucket, got %v", params["bucket"])
}
if params["regionendpoint"] != "https://s3.example.com" {
t.Errorf("Expected regionendpoint=https://s3.example.com, got %v", params["regionendpoint"])
}
}
func TestBuildStorageConfigFromFields_S3_NoEndpoint(t *testing.T) {
sc := StorageConfig{
AccessKey: "test-key",
SecretKey: "test-secret",
Region: "us-east-1",
Bucket: "test-bucket",
Endpoint: "", // No custom endpoint
}
cfg := buildStorageConfigFromFields(sc)
s3Params, ok := cfg["s3"]
if !ok {
t.Fatal("Expected s3 storage config")
}
params := map[string]any(s3Params)
// Should have default region
if params["region"] != "us-east-1" {
t.Errorf("Expected default region=us-east-1, got %v", params["region"])
}
// Should not have regionendpoint
if _, exists := params["regionendpoint"]; exists {
t.Error("Expected no regionendpoint when Endpoint not set")
}
}
func TestDefaultConfig_Hold(t *testing.T) {
cfg := DefaultConfig()
if cfg.Version != "0.1" {
t.Errorf("DefaultConfig().Version = %q, want \"0.1\"", cfg.Version)
}
if cfg.LogLevel != "info" {
t.Errorf("DefaultConfig().LogLevel = %q, want \"info\"", cfg.LogLevel)
}
if cfg.Server.Addr != ":8080" {
t.Errorf("DefaultConfig().Server.Addr = %q, want \":8080\"", cfg.Server.Addr)
}
if cfg.Storage.Region != "us-east-1" {
t.Errorf("DefaultConfig().Storage.Region = %q, want \"us-east-1\"", cfg.Storage.Region)
}
if cfg.Database.Path != "/var/lib/atcr-hold" {
t.Errorf("DefaultConfig().Database.Path = %q, want \"/var/lib/atcr-hold\"", cfg.Database.Path)
}
if cfg.Server.ReadTimeout != 5*time.Minute {
t.Errorf("DefaultConfig().Server.ReadTimeout = %v, want 5m", cfg.Server.ReadTimeout)
}
}
func TestExampleYAML_Hold(t *testing.T) {
out, err := ExampleYAML()
if err != nil {
t.Fatalf("ExampleYAML() error: %v", err)
}
s := string(out)
// Should contain the title
if !strings.Contains(s, "ATCR Hold Service Configuration") {
t.Error("expected title in YAML output")
}
// Should contain key fields with defaults
if !strings.Contains(s, "addr:") {
t.Error("expected addr field in YAML output")
}
if !strings.Contains(s, "bucket:") {
t.Error("expected bucket field in YAML output")
}
// Should contain comments
if !strings.Contains(s, "# Listen address") {
t.Error("expected comment for addr field")
}
if !strings.Contains(s, "# S3 bucket") {
t.Error("expected comment for bucket field")
}
}