Files
at-container-registry/pkg/hold/config_test.go
T
Evan JarrettandClaude Fable 5.1 0080957a21 remove the runtime test_mode switch; the testmode build tag is the only one
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
2026-09-11 11:09:44 -05:00

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")
}
}