package config import ( "strings" "testing" ) // TestCacheMaxBytesExplicitValueUsedWithoutFloor verifies that an // explicitly configured cache_max_bytes value is used exactly as // given: the 500 MiB floor applies only to the computed default, never // to explicit values. func TestCacheMaxBytesExplicitValueUsedWithoutFloor(t *testing.T) { t.Parallel() yamlContent := "signing_key: " + validTestSigningKey + "\ncache_max_bytes: 1024\n" c, err := configFromYAML(t, yamlContent) if err != nil { t.Fatalf("explicit cache_max_bytes must be accepted, got error: %v", err) } if c.CacheMaxBytes != 1024 { t.Errorf("CacheMaxBytes = %d, want 1024 (no floor for explicit values)", c.CacheMaxBytes) } } // TestCacheMaxBytesZeroIsValidAndDisablesCache verifies that an // explicit zero is a valid value (it disables the disk cache), not an // error. func TestCacheMaxBytesZeroIsValidAndDisablesCache(t *testing.T) { t.Parallel() yamlContent := "signing_key: " + validTestSigningKey + "\ncache_max_bytes: 0\n" c, err := configFromYAML(t, yamlContent) if err != nil { t.Fatalf("cache_max_bytes: 0 must be accepted, got error: %v", err) } if c.CacheMaxBytes != 0 { t.Errorf("CacheMaxBytes = %d, want 0", c.CacheMaxBytes) } } // TestCacheMaxBytesLargeExplicitValueParses verifies that values above // 32-bit range parse correctly (the field is an int64 byte count). func TestCacheMaxBytesLargeExplicitValueParses(t *testing.T) { t.Parallel() yamlContent := "signing_key: " + validTestSigningKey + "\ncache_max_bytes: 10737418240\n" c, err := configFromYAML(t, yamlContent) if err != nil { t.Fatalf("large cache_max_bytes must be accepted, got error: %v", err) } if c.CacheMaxBytes != 10737418240 { t.Errorf("CacheMaxBytes = %d, want 10737418240", c.CacheMaxBytes) } } // TestCacheMaxBytesInvalidValuesAbortStartup verifies that a SET but // invalid cache_max_bytes value aborts startup naming the key and the // offending value, per the no-silent-fallback rule: defaults apply // only to omitted keys. func TestCacheMaxBytesInvalidValuesAbortStartup(t *testing.T) { t.Parallel() signingKeyLine := "signing_key: " + validTestSigningKey + "\n" cases := []struct { name string yaml string // wantErrSubstrings must all appear in the error message. wantErrSubstrings []string }{ { name: "negative", yaml: signingKeyLine + "cache_max_bytes: -1024\n", wantErrSubstrings: []string{keyCacheMaxBytes, "-1024"}, }, { name: "float", yaml: signingKeyLine + "cache_max_bytes: 3.5\n", wantErrSubstrings: []string{keyCacheMaxBytes, "3.5"}, }, { name: "non-numeric string", yaml: signingKeyLine + "cache_max_bytes: banana\n", wantErrSubstrings: []string{keyCacheMaxBytes, "banana"}, }, { name: "explicit null", yaml: signingKeyLine + "cache_max_bytes: null\n", wantErrSubstrings: []string{keyCacheMaxBytes, "null"}, }, { name: "bare key no value", yaml: signingKeyLine + "cache_max_bytes:\n", wantErrSubstrings: []string{keyCacheMaxBytes, "null"}, }, { name: "boolean", yaml: signingKeyLine + "cache_max_bytes: true\n", wantErrSubstrings: []string{keyCacheMaxBytes, "true"}, }, { name: "list", yaml: signingKeyLine + "cache_max_bytes:\n - 1\n", wantErrSubstrings: []string{keyCacheMaxBytes}, }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { t.Parallel() c, err := configFromYAML(t, tc.yaml) if err == nil { t.Fatalf( "config with %s cache_max_bytes must abort startup, got config: %+v", tc.name, c) } t.Logf("got expected error: %v", err) for _, want := range tc.wantErrSubstrings { if !strings.Contains(err.Error(), want) { t.Errorf("error %q does not mention %q", err.Error(), want) } } }) } } // TestCacheMaxBytesExplicitIsRecorded verifies that an omitted // cache_max_bytes is recorded as not explicit, so the cache works out // the default when it opens, and that an explicit zero is recorded as // explicit, so it disables the disk cache instead. func TestCacheMaxBytesExplicitIsRecorded(t *testing.T) { t.Parallel() signingKeyLine := "signing_key: " + validTestSigningKey + "\n" omitted, err := configFromYAML(t, signingKeyLine) if err != nil { t.Fatalf("minimal config should be valid, got error: %v", err) } if omitted.CacheMaxBytesExplicit { t.Error("omitted cache_max_bytes recorded as explicit") } zero, err := configFromYAML(t, signingKeyLine+"cache_max_bytes: 0\n") if err != nil { t.Fatalf("cache_max_bytes: 0 must be accepted, got error: %v", err) } if !zero.CacheMaxBytesExplicit { t.Error("cache_max_bytes: 0 not recorded as explicit") } }