package config import ( "os" "path/filepath" "testing" "time" ) func TestLoad(t *testing.T) { // Create a temporary directory for test files tempDir := t.TempDir() configPath := filepath.Join(tempDir, "test-config.yaml") // Create a test configuration file testConfig := `server: port: 9090 read_timeout: 60 write_timeout: 60 idle_timeout: 120 proxy: targets: - name: "test-target" address: "http://localhost:8080" protocol: "http" weight: 1 load_balancer: "leastconn" health_check_path: "/healthz" health_check_interval: 60 nat: enabled: true stun_server: "stun:stun.example.com:3478" turn_server: "turn:turn.example.com:3478" turn_username: "testuser" turn_password: "testpass" logging: level: "debug" format: "text" output: "file" file: "/var/log/gorz.log" monitor: enabled: true port: 8081 path: "/stats" auth: true username: "admin" password: "secret" ` err := os.WriteFile(configPath, []byte(testConfig), 0644) if err != nil { t.Fatalf("Failed to write test config file: %v", err) } // Test loading the configuration cfg, err := Load(configPath) if err != nil { t.Fatalf("Failed to load configuration: %v", err) } // Verify server configuration if cfg.Server.Port != 9090 { t.Errorf("Expected port 9090, got %d", cfg.Server.Port) } if cfg.Server.ReadTimeout != 60 { t.Errorf("Expected read timeout 60, got %d", cfg.Server.ReadTimeout) } // Verify proxy configuration if cfg.Proxy.LoadBalancer != "leastconn" { t.Errorf("Expected load balancer 'leastconn', got %s", cfg.Proxy.LoadBalancer) } if len(cfg.Proxy.Targets) != 1 { t.Errorf("Expected 1 target, got %d", len(cfg.Proxy.Targets)) } if cfg.Proxy.Targets[0].Name != "test-target" { t.Errorf("Expected target name 'test-target', got %s", cfg.Proxy.Targets[0].Name) } // Verify NAT configuration if !cfg.NAT.Enabled { t.Error("Expected NAT enabled to be true") } if cfg.NAT.STUNServer != "stun:stun.example.com:3478" { t.Errorf("Expected STUN server 'stun:stun.example.com:3478', got %s", cfg.NAT.STUNServer) } // Verify logging configuration if cfg.Logging.Level != "debug" { t.Errorf("Expected log level 'debug', got %s", cfg.Logging.Level) } if cfg.Logging.Output != "file" { t.Errorf("Expected log output 'file', got %s", cfg.Logging.Output) } // Verify monitor configuration if !cfg.Monitor.Enabled { t.Error("Expected monitor enabled to be true") } if cfg.Monitor.Port != 8081 { t.Errorf("Expected monitor port 8081, got %d", cfg.Monitor.Port) } if !cfg.Monitor.Auth { t.Error("Expected monitor auth to be true") } } func TestLoadNonexistentFile(t *testing.T) { _, err := Load("/nonexistent/path/config.yaml") if err == nil { t.Error("Expected error for nonexistent file, got nil") } } func TestLoadInvalidYAML(t *testing.T) { // Create a temporary directory for test files tempDir := t.TempDir() configPath := filepath.Join(tempDir, "invalid-config.yaml") // Create an invalid YAML file invalidYAML := `server: port: 8080 read_timeout: "not a number" ` err := os.WriteFile(configPath, []byte(invalidYAML), 0644) if err != nil { t.Fatalf("Failed to write invalid config file: %v", err) } _, err = Load(configPath) if err == nil { t.Error("Expected error for invalid YAML, got nil") } } func TestSetDefaults(t *testing.T) { cfg := &Config{} // Apply defaults setDefaults(cfg) // Verify default server values if cfg.Server.Port != 8080 { t.Errorf("Expected default port 8080, got %d", cfg.Server.Port) } if cfg.Server.ReadTimeout != 30 { t.Errorf("Expected default read timeout 30, got %d", cfg.Server.ReadTimeout) } // Verify default proxy values if cfg.Proxy.LoadBalancer != "roundrobin" { t.Errorf("Expected default load balancer 'roundrobin', got %s", cfg.Proxy.LoadBalancer) } if cfg.Proxy.HealthCheckPath != "/health" { t.Errorf("Expected default health check path '/health', got %s", cfg.Proxy.HealthCheckPath) } // Verify default NAT values if cfg.NAT.Enabled { t.Error("Expected default NAT enabled to be false") } if cfg.NAT.STUNServer != "stun:stun.l.google.com:19302" { t.Errorf("Expected default STUN server 'stun:stun.l.google.com:19302', got %s", cfg.NAT.STUNServer) } // Verify default logging values if cfg.Logging.Level != "info" { t.Errorf("Expected default log level 'info', got %s", cfg.Logging.Level) } if cfg.Logging.Format != "json" { t.Errorf("Expected default log format 'json', got %s", cfg.Logging.Format) } // Verify default monitor values if !cfg.Monitor.Enabled { t.Error("Expected default monitor enabled to be true") } if cfg.Monitor.Port != 9090 { t.Errorf("Expected default monitor port 9090, got %d", cfg.Monitor.Port) } } func TestCreateDefaultConfig(t *testing.T) { // Create a temporary directory for test files tempDir := t.TempDir() configPath := filepath.Join(tempDir, "default-config.yaml") // Create default configuration err := CreateDefaultConfig(configPath) if err != nil { t.Fatalf("Failed to create default configuration: %v", err) } // Verify the file was created if _, err := os.Stat(configPath); os.IsNotExist(err) { t.Error("Expected config file to be created") } // Load and verify the configuration cfg, err := Load(configPath) if err != nil { t.Fatalf("Failed to load created configuration: %v", err) } // Verify some default values if cfg.Server.Port != 8080 { t.Errorf("Expected default port 8080, got %d", cfg.Server.Port) } if cfg.Proxy.LoadBalancer != "roundrobin" { t.Errorf("Expected default load balancer 'roundrobin', got %s", cfg.Proxy.LoadBalancer) } if cfg.Logging.Level != "info" { t.Errorf("Expected default log level 'info', got %s", cfg.Logging.Level) } } func TestCreateDefaultConfigDirectoryCreation(t *testing.T) { // Create a temporary directory for test files tempDir := t.TempDir() nestedDir := filepath.Join(tempDir, "nested", "directory") configPath := filepath.Join(nestedDir, "config.yaml") // Create default configuration in a nested directory err := CreateDefaultConfig(configPath) if err != nil { t.Fatalf("Failed to create default configuration: %v", err) } // Verify the directory was created if _, err := os.Stat(nestedDir); os.IsNotExist(err) { t.Error("Expected nested directory to be created") } // Verify the file was created if _, err := os.Stat(configPath); os.IsNotExist(err) { t.Error("Expected config file to be created") } }