mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-24 11:14:14 +00:00
server.test_mode survived the build-tag refactor only to feed five behavioral branches: the registry's fall-back to the default hold when the user's hold is unreachable, backfill warning suppression for external holds, the appview listener close on shutdown, the hold's relay-crawl skip, and the hold's appview-issuer tolerance. Every one of them is a "this is a local development build" decision, which is what the tag already says, and local development has to build with the tag or nothing resolves. So they read atproto.TestModeBuild now, and the flag, SetTestMode, IsTestMode, the middleware option, the backfill constructor parameter, the never-read field on RemoteHoldAuthorizer, the example and template YAML lines, and the docker-compose env vars are gone. The registry keeps the fallback as a field seeded from the constant so the production-path tests can pin it off under the tag. The 24 SetTestMode calls in tests were dead already: stripping them and running the affected packages tagged changed nothing. Tests that resolve a loopback did:web used to t.Fatal naming the tag, which left a bare `go test ./...` permanently red in five packages. They now live under `//go:build testmode`: whole-file constraints where every test needs it, and sibling *_testmode_test.go files holding the moved tests plus their fixtures where a file mixed. The harness carries the constraint too, with its package doc in an untagged doc.go so the package still exists without it. An untagged run compiles those tests out and passes; make test keeps the tag and runs everything. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UwYzaG3Yy7uA8FbZ5qk3tQ
284 lines
8.0 KiB
Go
284 lines
8.0 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_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.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_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.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 TestS3Params_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",
|
|
}
|
|
|
|
params := sc.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 TestS3Params_NoEndpoint(t *testing.T) {
|
|
sc := StorageConfig{
|
|
AccessKey: "test-key",
|
|
SecretKey: "test-secret",
|
|
Region: "us-east-1",
|
|
Bucket: "test-bucket",
|
|
Endpoint: "", // No custom endpoint
|
|
}
|
|
|
|
params := sc.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")
|
|
}
|
|
}
|