mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-02 16:26:56 +00:00
306 lines
8.5 KiB
Go
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")
|
|
}
|
|
}
|