package config import ( "strings" "testing" ) func TestValidate(t *testing.T) { tests := []struct { name string cfg Config wantErr bool errSub string // substring to match in error if wantErr }{ { name: "valid default", cfg: GetDefaultConfig(), wantErr: false, }, { name: "valid zero concurrency", cfg: func() Config { c := GetDefaultConfig() c.MaxConcurrentRequests = 0 c.MaxRequestsPerClient = 0 return c }(), wantErr: false, }, { name: "valid negative? no, but zero ok; positive values", cfg: func() Config { c := GetDefaultConfig() c.MaxConcurrentRequests = 100 c.MaxRequestsPerClient = 10 c.Cache.Memory.GCAlgorithm = "lru" c.Cache.Disk.GCAlgorithm = "hybrid" c.Cache.Disk.Size = "10GB" c.Cache.Disk.Path = "/tmp/cache" return c }(), wantErr: false, }, { name: "negative max concurrent requests", cfg: func() Config { c := GetDefaultConfig() c.MaxConcurrentRequests = -1 return c }(), wantErr: true, errSub: "negative concurrency not allowed", }, { name: "negative max requests per client", cfg: func() Config { c := GetDefaultConfig() c.MaxRequestsPerClient = -5 return c }(), wantErr: true, errSub: "negative per-client limit not allowed", }, { name: "invalid memory gc algorithm", cfg: func() Config { c := GetDefaultConfig() c.Cache.Memory.GCAlgorithm = "invalid-alg" return c }(), wantErr: true, errSub: "invalid memory gc algorithm: invalid-alg", }, { name: "empty memory gc ok (treated as default)", cfg: func() Config { c := GetDefaultConfig() c.Cache.Memory.GCAlgorithm = "" return c }(), wantErr: false, }, { name: "valid memory gc values", cfg: func() Config { c := GetDefaultConfig() for _, alg := range []string{"lru", "lfu", "fifo", "largest", "smallest", "hybrid"} { c.Cache.Memory.GCAlgorithm = alg if err := c.Validate(); err != nil { t.Errorf("valid gc %s should not error: %v", alg, err) } } return c // last one }(), wantErr: false, }, { name: "disk enabled (non-zero size) but no path", cfg: func() Config { c := GetDefaultConfig() c.Cache.Disk.Size = "50GB" c.Cache.Disk.Path = "" return c }(), wantErr: true, errSub: "disk cache enabled but no path specified", }, { name: "disk size 0 (disabled) no path ok", cfg: func() Config { c := GetDefaultConfig() c.Cache.Disk.Size = "0" c.Cache.Disk.Path = "" return c }(), wantErr: false, }, { name: "disk size empty (disabled) no path ok", cfg: func() Config { c := GetDefaultConfig() c.Cache.Disk.Size = "" c.Cache.Disk.Path = "" return c }(), wantErr: false, }, { name: "disk enabled with path ok", cfg: func() Config { c := GetDefaultConfig() c.Cache.Disk.Size = "1TB" c.Cache.Disk.Path = "./disk" return c }(), wantErr: false, }, { name: "disk gc invalid does not fail (not validated by current impl)", cfg: func() Config { c := GetDefaultConfig() c.Cache.Disk.GCAlgorithm = "bad-disk-gc" c.Cache.Disk.Size = "10GB" c.Cache.Disk.Path = "/p" return c }(), wantErr: false, }, { name: "p1 new fields default ok (maxobj 0 + empty trusted proxies)", cfg: func() Config { c := GetDefaultConfig() c.MaxObjectSize = "0" c.TrustedProxies = nil return c }(), wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := tt.cfg.Validate() if (err != nil) != tt.wantErr { t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) return } if tt.wantErr && tt.errSub != "" && err != nil { if !strings.Contains(err.Error(), tt.errSub) { t.Errorf("Validate() error %q does not contain %q", err.Error(), tt.errSub) } } }) } }