Heavy security and file splitting
CI / Go Tests (push) Successful in 15s
CI / Build (push) Successful in 9s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 2s
Release Artifacts / Build and release executables (push) Successful in 15s
Release Artifacts / Build and release Docker image (push) Successful in 28s
CI / Go Tests (push) Successful in 15s
CI / Build (push) Successful in 9s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 2s
Release Artifacts / Build and release executables (push) Successful in 15s
Release Artifacts / Build and release Docker image (push) Successful in 28s
This commit is contained in:
@@ -19,6 +19,9 @@ func TestValidateAppliesDefaultsAndParsedFields(t *testing.T) {
|
||||
if err := cfg.Validate(); err != nil {
|
||||
t.Fatalf("Validate() returned error: %v", err)
|
||||
}
|
||||
if err := cfg.PrepareDataDir(); err != nil {
|
||||
t.Fatalf("PrepareDataDir() returned error: %v", err)
|
||||
}
|
||||
|
||||
if cfg.Limits.MaxUploadSizeBytes != 100*1024*1024 {
|
||||
t.Fatalf("MaxUploadSizeBytes = %d, want %d", cfg.Limits.MaxUploadSizeBytes, int64(100*1024*1024))
|
||||
@@ -35,6 +38,9 @@ func TestValidateAppliesDefaultsAndParsedFields(t *testing.T) {
|
||||
if cfg.Server.IdleTimeoutDur != 120*time.Second {
|
||||
t.Fatalf("IdleTimeoutDur = %s, want 120s", cfg.Server.IdleTimeoutDur)
|
||||
}
|
||||
if cfg.Server.ShutdownTimeoutDur != 10*time.Second {
|
||||
t.Fatalf("ShutdownTimeoutDur = %s, want 10s", cfg.Server.ShutdownTimeoutDur)
|
||||
}
|
||||
if cfg.Server.MaxHeaderBytes != 1<<20 {
|
||||
t.Fatalf("MaxHeaderBytes = %d, want %d", cfg.Server.MaxHeaderBytes, 1<<20)
|
||||
}
|
||||
@@ -68,6 +74,9 @@ func TestValidateAppliesDefaultsAndParsedFields(t *testing.T) {
|
||||
if got := cfg.Security.AllowedPrefixes[0]; got != netip.MustParsePrefix("127.0.0.1/32") {
|
||||
t.Fatalf("AllowedPrefixes[0] = %v, want 127.0.0.1/32", got)
|
||||
}
|
||||
if !cfg.Security.HSTSEnabled {
|
||||
t.Fatalf("HSTSEnabled = false, want true (default)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadParsesConfiguredFields(t *testing.T) {
|
||||
@@ -116,6 +125,7 @@ security:
|
||||
enabled: true
|
||||
requests_per_minute: 12
|
||||
burst: 4
|
||||
hsts_enabled: false
|
||||
`
|
||||
if err := os.WriteFile(configPath, []byte(content), 0o644); err != nil {
|
||||
t.Fatalf("WriteFile() error = %v", err)
|
||||
@@ -125,6 +135,9 @@ security:
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v", err)
|
||||
}
|
||||
if err := cfg.PrepareDataDir(); err != nil {
|
||||
t.Fatalf("PrepareDataDir() error = %v", err)
|
||||
}
|
||||
|
||||
if cfg.Server.ListenAddr != "127.0.0.1:9090" {
|
||||
t.Fatalf("ListenAddr = %q, want %q", cfg.Server.ListenAddr, "127.0.0.1:9090")
|
||||
@@ -141,6 +154,9 @@ security:
|
||||
if cfg.Server.IdleTimeoutDur != 90*time.Second {
|
||||
t.Fatalf("IdleTimeoutDur = %s, want 90s", cfg.Server.IdleTimeoutDur)
|
||||
}
|
||||
if cfg.Server.ShutdownTimeoutDur != 10*time.Second {
|
||||
t.Fatalf("ShutdownTimeoutDur = %s, want 10s", cfg.Server.ShutdownTimeoutDur)
|
||||
}
|
||||
if cfg.Server.MaxHeaderBytes != 2*1024*1024 {
|
||||
t.Fatalf("MaxHeaderBytes = %d, want %d", cfg.Server.MaxHeaderBytes, 2*1024*1024)
|
||||
}
|
||||
@@ -186,6 +202,9 @@ security:
|
||||
if cfg.Security.RateLimitAPIWrite.RequestsPerMinute != 12 || cfg.Security.RateLimitAPIWrite.Burst != 4 {
|
||||
t.Fatalf("unexpected rate_limit_api_write values: %+v", cfg.Security.RateLimitAPIWrite)
|
||||
}
|
||||
if cfg.Security.HSTSEnabled {
|
||||
t.Fatalf("HSTSEnabled = true, want false (from config)")
|
||||
}
|
||||
if len(cfg.Security.AllowedPrefixes) != 2 {
|
||||
t.Fatalf("AllowedPrefixes len = %d, want 2", len(cfg.Security.AllowedPrefixes))
|
||||
}
|
||||
@@ -244,6 +263,13 @@ func TestValidateRejectsInvalidValues(t *testing.T) {
|
||||
},
|
||||
wantErr: "server.idle_timeout",
|
||||
},
|
||||
{
|
||||
name: "invalid shutdown timeout",
|
||||
mutate: func(cfg *Config) {
|
||||
cfg.Server.ShutdownTimeout = "bogus"
|
||||
},
|
||||
wantErr: "server.shutdown_timeout",
|
||||
},
|
||||
{
|
||||
name: "invalid max header bytes",
|
||||
mutate: func(cfg *Config) {
|
||||
@@ -432,13 +458,23 @@ storage:
|
||||
t.Fatalf("Load() error = %v, want nil", err)
|
||||
}
|
||||
|
||||
// First prepare creates the data dir (mkdir probe) so we can write the bad key file for test.
|
||||
// (Load no longer has side effects.)
|
||||
cfgForBad, err := Load(validConfigPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Load(valid) error = %v", err)
|
||||
}
|
||||
if err := cfgForBad.PrepareDataDir(); err != nil {
|
||||
t.Fatalf("PrepareDataDir (to create dir) error = %v", err)
|
||||
}
|
||||
|
||||
keyPath := filepath.Join(tmp, "store", dataDirEncryptionKeyFilename)
|
||||
if err := os.WriteFile(keyPath, []byte("not-base64"), 0o600); err != nil {
|
||||
t.Fatalf("WriteFile(invalid key) error = %v", err)
|
||||
}
|
||||
_, err = Load(validConfigPath)
|
||||
if err == nil || !strings.Contains(err.Error(), "storage encryption key setup failed") {
|
||||
t.Fatalf("Load() error = %v, want invalid key base64 error", err)
|
||||
// Re-prepare (or load+prepare) now hits the bad key decode inside ensure.
|
||||
if err := cfgForBad.PrepareDataDir(); err == nil || !strings.Contains(err.Error(), "storage encryption key setup failed") {
|
||||
t.Fatalf("PrepareDataDir after bad key error = %v, want setup failed containing 'storage encryption key setup failed'", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,9 +501,13 @@ storage:
|
||||
t.Fatalf("WriteFile(config) error = %v", err)
|
||||
}
|
||||
|
||||
_, err := Load(configPath)
|
||||
cfg, err := Load(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v, want success (pure validate)", err)
|
||||
}
|
||||
err = cfg.PrepareDataDir()
|
||||
if err == nil || !strings.Contains(err.Error(), "refusing to generate missing") {
|
||||
t.Fatalf("Load() error = %v, want missing-key safety error", err)
|
||||
t.Fatalf("PrepareDataDir() error = %v, want missing-key safety error containing 'refusing to generate missing'", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +519,7 @@ func TestLoadFromEnvParsesConfiguredFields(t *testing.T) {
|
||||
t.Setenv("SCRATCHBOX_SERVER_READ_TIMEOUT", "20s")
|
||||
t.Setenv("SCRATCHBOX_SERVER_WRITE_TIMEOUT", "40s")
|
||||
t.Setenv("SCRATCHBOX_SERVER_IDLE_TIMEOUT", "80s")
|
||||
t.Setenv("SCRATCHBOX_SERVER_SHUTDOWN_TIMEOUT", "5s")
|
||||
t.Setenv("SCRATCHBOX_SERVER_MAX_HEADER_BYTES", "2097152")
|
||||
t.Setenv("SCRATCHBOX_SERVER_ACCESS_LOG_ENABLED", "false")
|
||||
t.Setenv("SCRATCHBOX_SERVER_ACCESS_LOG_FILE_PATH", "/tmp/access.log")
|
||||
@@ -505,11 +546,15 @@ func TestLoadFromEnvParsesConfiguredFields(t *testing.T) {
|
||||
t.Setenv("SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_ENABLED", "true")
|
||||
t.Setenv("SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_REQUESTS_PER_MINUTE", "40")
|
||||
t.Setenv("SCRATCHBOX_SECURITY_RATE_LIMIT_API_WRITE_BURST", "12")
|
||||
t.Setenv("SCRATCHBOX_SECURITY_HSTS_ENABLED", "false")
|
||||
|
||||
cfg, err := LoadFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("LoadFromEnv() error = %v", err)
|
||||
}
|
||||
if err := cfg.PrepareDataDir(); err != nil {
|
||||
t.Fatalf("PrepareDataDir() error = %v", err)
|
||||
}
|
||||
|
||||
if cfg.Server.ListenAddr != "127.0.0.1:19090" {
|
||||
t.Fatalf("ListenAddr = %q, want %q", cfg.Server.ListenAddr, "127.0.0.1:19090")
|
||||
@@ -526,6 +571,9 @@ func TestLoadFromEnvParsesConfiguredFields(t *testing.T) {
|
||||
if cfg.Server.IdleTimeoutDur != 80*time.Second {
|
||||
t.Fatalf("IdleTimeoutDur = %s, want 80s", cfg.Server.IdleTimeoutDur)
|
||||
}
|
||||
if cfg.Server.ShutdownTimeoutDur != 5*time.Second {
|
||||
t.Fatalf("ShutdownTimeoutDur = %s, want 5s", cfg.Server.ShutdownTimeoutDur)
|
||||
}
|
||||
if cfg.Server.MaxHeaderBytes != 2*1024*1024 {
|
||||
t.Fatalf("MaxHeaderBytes = %d, want %d", cfg.Server.MaxHeaderBytes, 2*1024*1024)
|
||||
}
|
||||
@@ -571,6 +619,9 @@ func TestLoadFromEnvParsesConfiguredFields(t *testing.T) {
|
||||
if cfg.Security.RateLimitAPIWrite.RequestsPerMinute != 40 || cfg.Security.RateLimitAPIWrite.Burst != 12 {
|
||||
t.Fatalf("unexpected rate_limit_api_write values: %+v", cfg.Security.RateLimitAPIWrite)
|
||||
}
|
||||
if cfg.Security.HSTSEnabled {
|
||||
t.Fatalf("HSTSEnabled from env = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRejectsInvalidBool(t *testing.T) {
|
||||
@@ -616,6 +667,7 @@ func TestParseHumanSizeVariants(t *testing.T) {
|
||||
{in: "abc", wantErr: "does not start with a number"},
|
||||
{in: "5XB", wantErr: "unsupported unit"},
|
||||
{in: "", wantErr: "size is empty"},
|
||||
{in: "100000000000000000GiB", wantErr: "size too large"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
||||
Reference in New Issue
Block a user