diff --git a/config/config.go b/config/config.go index aad1a08..90f5076 100644 --- a/config/config.go +++ b/config/config.go @@ -18,6 +18,15 @@ const ( EnvResponseTimeout = "RESPONSE_TIMEOUT" ) +// Default configuration values +const ( + DefaultLogLevel = zerolog.InfoLevel + DefaultNumWorkers = 5 + DefaultWorkerBatchSize = 100 + DefaultMaxResponseSize = 1048576 // 1MB + DefaultResponseTimeout = 30 // seconds +) + // Config holds the application configuration loaded from environment variables type Config struct { LogLevel zerolog.Level // Logging level (debug, info, warn, error) @@ -28,6 +37,14 @@ type Config struct { WorkerBatchSize int // Batch size for worker processing } +// String returns a string representation of the configuration +func (c *Config) String() string { + return fmt.Sprintf( + "Config{LogLevel: %s, RootPath: %s, MaxResponseSize: %d, NumWorkers: %d, ResponseTimeout: %d, WorkerBatchSize: %d}", + c.LogLevel, c.RootPath, c.MaxResponseSize, c.NumOfWorkers, c.ResponseTimeout, c.WorkerBatchSize, + ) +} + var CONFIG Config // parsePositiveInt parses and validates positive integer values @@ -57,6 +74,9 @@ func GetConfig() *Config { return nil }, EnvRootPath: func(v string) error { + if _, err := os.Stat(v); err != nil { + return fmt.Errorf("invalid root path: %w", err) + } config.RootPath = v return nil }, diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 0000000..ace8aca --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,63 @@ +package config + +import ( + "os" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" +) + +func TestGetConfig(t *testing.T) { + // Set up test environment variables + envVars := map[string]string{ + EnvLogLevel: "debug", + EnvRootPath: ".", + EnvNumWorkers: "5", + EnvWorkerBatchSize: "100", + EnvMaxResponseSize: "1048576", + EnvResponseTimeout: "30", + } + + for k, v := range envVars { + os.Setenv(k, v) + defer os.Unsetenv(k) + } + + // Get configuration + config := GetConfig() + + // Assert configuration values + assert.Equal(t, zerolog.DebugLevel, config.LogLevel) + assert.Equal(t, ".", config.RootPath) + assert.Equal(t, 5, config.NumOfWorkers) + assert.Equal(t, 100, config.WorkerBatchSize) + assert.Equal(t, 1048576, config.MaxResponseSize) + assert.Equal(t, 30, config.ResponseTimeout) +} + +func TestParsePositiveInt(t *testing.T) { + tests := []struct { + name string + input string + want int + wantErr bool + }{ + {"valid positive", "42", 42, false}, + {"zero", "0", 0, true}, + {"negative", "-1", 0, true}, + {"invalid", "abc", 0, true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parsePositiveInt(tt.input) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + } + }) + } +}