Enhance environment variable documentation and configuration
Format / gofmt (push) Successful in 5s
CI / Build (push) Successful in 12s
CI / Go Tests (push) Successful in 22s
Release Artifacts / Validate release tag (push) Successful in 1s
Release Artifacts / Build and release executables (push) Successful in 33s
Release Artifacts / Build and release Docker image (push) Successful in 3m10s
Format / gofmt (push) Successful in 5s
CI / Build (push) Successful in 12s
CI / Go Tests (push) Successful in 22s
Release Artifacts / Validate release tag (push) Successful in 1s
Release Artifacts / Build and release executables (push) Successful in 33s
Release Artifacts / Build and release Docker image (push) Successful in 3m10s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -79,6 +79,27 @@ func TestValidateAppliesDefaultsAndParsedFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAllowsZeroReadAndWriteTimeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := defaults()
|
||||
cfg.Storage.DataDir = t.TempDir()
|
||||
// 0 disables the deadline (net/http semantics). Needed for multi-GiB uploads
|
||||
// where a fixed 30s body/response timeout cannot work.
|
||||
cfg.Server.ReadTimeout = "0s"
|
||||
cfg.Server.WriteTimeout = "0"
|
||||
|
||||
if err := cfg.Validate(); err != nil {
|
||||
t.Fatalf("Validate() returned error: %v", err)
|
||||
}
|
||||
if cfg.Server.ReadTimeoutDur != 0 {
|
||||
t.Fatalf("ReadTimeoutDur = %s, want 0", cfg.Server.ReadTimeoutDur)
|
||||
}
|
||||
if cfg.Server.WriteTimeoutDur != 0 {
|
||||
t.Fatalf("WriteTimeoutDur = %s, want 0", cfg.Server.WriteTimeoutDur)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadParsesConfiguredFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -249,6 +270,13 @@ func TestValidateRejectsInvalidValues(t *testing.T) {
|
||||
},
|
||||
wantErr: "server.read_timeout",
|
||||
},
|
||||
{
|
||||
name: "negative read timeout",
|
||||
mutate: func(cfg *Config) {
|
||||
cfg.Server.ReadTimeout = "-1s"
|
||||
},
|
||||
wantErr: "server.read_timeout",
|
||||
},
|
||||
{
|
||||
name: "invalid write timeout",
|
||||
mutate: func(cfg *Config) {
|
||||
@@ -256,6 +284,13 @@ func TestValidateRejectsInvalidValues(t *testing.T) {
|
||||
},
|
||||
wantErr: "server.write_timeout",
|
||||
},
|
||||
{
|
||||
name: "negative write timeout",
|
||||
mutate: func(cfg *Config) {
|
||||
cfg.Server.WriteTimeout = "-1s"
|
||||
},
|
||||
wantErr: "server.write_timeout",
|
||||
},
|
||||
{
|
||||
name: "invalid idle timeout",
|
||||
mutate: func(cfg *Config) {
|
||||
@@ -713,3 +748,46 @@ func TestGenerateEncryptionKey(t *testing.T) {
|
||||
t.Fatalf("decoded key length = %d, want 32", len(b1))
|
||||
}
|
||||
}
|
||||
|
||||
// TestEnvDocumentationIsUpToDate ensures .env.example and the env var
|
||||
// documentation + example in README.md stay in sync with the env vars
|
||||
// actually supported by the code (envSuffixes in config.go).
|
||||
// See the comment on envSuffixes for the list of places that must point back to it.
|
||||
//
|
||||
// This is the guard against the recurring "example env and readme have
|
||||
// become out of sync" problem. When you add a new field that is loaded via
|
||||
// applyEnvOverrides, you must:
|
||||
// - add its suffix to envSuffixes
|
||||
// - add a line (with example value + comment) to .env.example
|
||||
// - add it to the list and the ```dotenv example in README.md
|
||||
//
|
||||
// The test will fail loudly until the docs are updated.
|
||||
func TestEnvDocumentationIsUpToDate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Check .env.example (at repo root). Note: go test for this package
|
||||
// runs with cwd set to the package directory (internal/config), so we
|
||||
// need to go up two levels.
|
||||
envExample, err := os.ReadFile("../../.env.example")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read .env.example: %v", err)
|
||||
}
|
||||
for _, suffix := range envSuffixes {
|
||||
name := "SCRATCHBOX_" + suffix
|
||||
if !strings.Contains(string(envExample), name) {
|
||||
t.Errorf(".env.example is missing %s (add it with a default/example value and a comment matching the style of the others)", name)
|
||||
}
|
||||
}
|
||||
|
||||
// Check README.md env documentation (the supported list and the example block)
|
||||
readme, err := os.ReadFile("../../README.md")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read README.md: %v", err)
|
||||
}
|
||||
for _, suffix := range envSuffixes {
|
||||
name := "SCRATCHBOX_" + suffix
|
||||
if !strings.Contains(string(readme), name) {
|
||||
t.Errorf("README.md env docs (supported list or example .env block) are missing %s; update both the bullet list and the ```dotenv block", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user