You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							226 lines
						
					
					
						
							6.3 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							226 lines
						
					
					
						
							6.3 KiB
						
					
					
				| package config | |
| 
 | |
| import ( | |
| 	"testing" | |
| ) | |
| 
 | |
| // Test structs that mirror the actual configuration structure | |
| type TestBaseConfigForSchema struct { | |
| 	Enabled             bool `json:"enabled"` | |
| 	ScanIntervalSeconds int  `json:"scan_interval_seconds"` | |
| 	MaxConcurrent       int  `json:"max_concurrent"` | |
| } | |
| 
 | |
| // ApplySchemaDefaults implements ConfigWithDefaults for test struct | |
| func (c *TestBaseConfigForSchema) ApplySchemaDefaults(schema *Schema) error { | |
| 	return schema.ApplyDefaultsToProtobuf(c) | |
| } | |
| 
 | |
| // Validate implements ConfigWithDefaults for test struct | |
| func (c *TestBaseConfigForSchema) Validate() error { | |
| 	return nil | |
| } | |
| 
 | |
| type TestTaskConfigForSchema struct { | |
| 	TestBaseConfigForSchema | |
| 	TaskSpecificField    float64 `json:"task_specific_field"` | |
| 	AnotherSpecificField string  `json:"another_specific_field"` | |
| } | |
| 
 | |
| // ApplySchemaDefaults implements ConfigWithDefaults for test struct | |
| func (c *TestTaskConfigForSchema) ApplySchemaDefaults(schema *Schema) error { | |
| 	return schema.ApplyDefaultsToProtobuf(c) | |
| } | |
| 
 | |
| // Validate implements ConfigWithDefaults for test struct | |
| func (c *TestTaskConfigForSchema) Validate() error { | |
| 	return nil | |
| } | |
| 
 | |
| func createTestSchema() *Schema { | |
| 	return &Schema{ | |
| 		Fields: []*Field{ | |
| 			{ | |
| 				Name:         "enabled", | |
| 				JSONName:     "enabled", | |
| 				Type:         FieldTypeBool, | |
| 				DefaultValue: true, | |
| 			}, | |
| 			{ | |
| 				Name:         "scan_interval_seconds", | |
| 				JSONName:     "scan_interval_seconds", | |
| 				Type:         FieldTypeInt, | |
| 				DefaultValue: 1800, | |
| 			}, | |
| 			{ | |
| 				Name:         "max_concurrent", | |
| 				JSONName:     "max_concurrent", | |
| 				Type:         FieldTypeInt, | |
| 				DefaultValue: 3, | |
| 			}, | |
| 			{ | |
| 				Name:         "task_specific_field", | |
| 				JSONName:     "task_specific_field", | |
| 				Type:         FieldTypeFloat, | |
| 				DefaultValue: 0.25, | |
| 			}, | |
| 			{ | |
| 				Name:         "another_specific_field", | |
| 				JSONName:     "another_specific_field", | |
| 				Type:         FieldTypeString, | |
| 				DefaultValue: "default_value", | |
| 			}, | |
| 		}, | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_WithEmbeddedStruct(t *testing.T) { | |
| 	schema := createTestSchema() | |
| 
 | |
| 	// Start with zero values | |
| 	config := &TestTaskConfigForSchema{} | |
| 
 | |
| 	err := schema.ApplyDefaultsToConfig(config) | |
| 	if err != nil { | |
| 		t.Fatalf("ApplyDefaultsToConfig failed: %v", err) | |
| 	} | |
| 
 | |
| 	// Verify embedded struct fields got default values | |
| 	if config.Enabled != true { | |
| 		t.Errorf("Expected Enabled=true (default), got %v", config.Enabled) | |
| 	} | |
| 
 | |
| 	if config.ScanIntervalSeconds != 1800 { | |
| 		t.Errorf("Expected ScanIntervalSeconds=1800 (default), got %v", config.ScanIntervalSeconds) | |
| 	} | |
| 
 | |
| 	if config.MaxConcurrent != 3 { | |
| 		t.Errorf("Expected MaxConcurrent=3 (default), got %v", config.MaxConcurrent) | |
| 	} | |
| 
 | |
| 	// Verify task-specific fields got default values | |
| 	if config.TaskSpecificField != 0.25 { | |
| 		t.Errorf("Expected TaskSpecificField=0.25 (default), got %v", config.TaskSpecificField) | |
| 	} | |
| 
 | |
| 	if config.AnotherSpecificField != "default_value" { | |
| 		t.Errorf("Expected AnotherSpecificField='default_value' (default), got %v", config.AnotherSpecificField) | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_PartiallySet(t *testing.T) { | |
| 	schema := createTestSchema() | |
| 
 | |
| 	// Start with some pre-set values | |
| 	config := &TestTaskConfigForSchema{ | |
| 		TestBaseConfigForSchema: TestBaseConfigForSchema{ | |
| 			Enabled:             true, // Non-zero value, should not be overridden | |
| 			ScanIntervalSeconds: 0,    // Should get default | |
| 			MaxConcurrent:       5,    // Non-zero value, should not be overridden | |
| 		}, | |
| 		TaskSpecificField:    0.0,      // Should get default | |
| 		AnotherSpecificField: "custom", // Non-zero value, should not be overridden | |
| 	} | |
| 
 | |
| 	err := schema.ApplyDefaultsToConfig(config) | |
| 	if err != nil { | |
| 		t.Fatalf("ApplyDefaultsToConfig failed: %v", err) | |
| 	} | |
| 
 | |
| 	// Verify already-set values are preserved | |
| 	if config.Enabled != true { | |
| 		t.Errorf("Expected Enabled=true (pre-set), got %v", config.Enabled) | |
| 	} | |
| 
 | |
| 	if config.MaxConcurrent != 5 { | |
| 		t.Errorf("Expected MaxConcurrent=5 (pre-set), got %v", config.MaxConcurrent) | |
| 	} | |
| 
 | |
| 	if config.AnotherSpecificField != "custom" { | |
| 		t.Errorf("Expected AnotherSpecificField='custom' (pre-set), got %v", config.AnotherSpecificField) | |
| 	} | |
| 
 | |
| 	// Verify zero values got defaults | |
| 	if config.ScanIntervalSeconds != 1800 { | |
| 		t.Errorf("Expected ScanIntervalSeconds=1800 (default), got %v", config.ScanIntervalSeconds) | |
| 	} | |
| 
 | |
| 	if config.TaskSpecificField != 0.25 { | |
| 		t.Errorf("Expected TaskSpecificField=0.25 (default), got %v", config.TaskSpecificField) | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_NonPointer(t *testing.T) { | |
| 	schema := createTestSchema() | |
| 	config := TestTaskConfigForSchema{} | |
| 	// This should fail since we need a pointer to modify the struct | |
| 	err := schema.ApplyDefaultsToProtobuf(config) | |
| 	if err == nil { | |
| 		t.Fatal("Expected error for non-pointer config, but got nil") | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_NonStruct(t *testing.T) { | |
| 	schema := createTestSchema() | |
| 	var config interface{} = "not a struct" | |
| 	err := schema.ApplyDefaultsToProtobuf(config) | |
| 	if err == nil { | |
| 		t.Fatal("Expected error for non-struct config, but got nil") | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_EmptySchema(t *testing.T) { | |
| 	schema := &Schema{Fields: []*Field{}} | |
| 	config := &TestTaskConfigForSchema{} | |
| 
 | |
| 	err := schema.ApplyDefaultsToConfig(config) | |
| 	if err != nil { | |
| 		t.Fatalf("ApplyDefaultsToConfig failed for empty schema: %v", err) | |
| 	} | |
| 
 | |
| 	// All fields should remain at zero values since no defaults are defined | |
| 	if config.Enabled != false { | |
| 		t.Errorf("Expected Enabled=false (zero value), got %v", config.Enabled) | |
| 	} | |
| } | |
| 
 | |
| func TestApplyDefaults_MissingSchemaField(t *testing.T) { | |
| 	// Schema with fewer fields than the struct | |
| 	schema := &Schema{ | |
| 		Fields: []*Field{ | |
| 			{ | |
| 				Name:         "enabled", | |
| 				JSONName:     "enabled", | |
| 				Type:         FieldTypeBool, | |
| 				DefaultValue: true, | |
| 			}, | |
| 			// Note: missing scan_interval_seconds and other fields | |
| 		}, | |
| 	} | |
| 
 | |
| 	config := &TestTaskConfigForSchema{} | |
| 	err := schema.ApplyDefaultsToConfig(config) | |
| 	if err != nil { | |
| 		t.Fatalf("ApplyDefaultsToConfig failed: %v", err) | |
| 	} | |
| 
 | |
| 	// Only the field with a schema definition should get a default | |
| 	if config.Enabled != true { | |
| 		t.Errorf("Expected Enabled=true (has schema), got %v", config.Enabled) | |
| 	} | |
| 
 | |
| 	// Fields without schema should remain at zero values | |
| 	if config.ScanIntervalSeconds != 0 { | |
| 		t.Errorf("Expected ScanIntervalSeconds=0 (no schema), got %v", config.ScanIntervalSeconds) | |
| 	} | |
| } | |
| 
 | |
| func BenchmarkApplyDefaults(b *testing.B) { | |
| 	schema := createTestSchema() | |
| 	config := &TestTaskConfigForSchema{} | |
| 
 | |
| 	b.ResetTimer() | |
| 	for i := 0; i < b.N; i++ { | |
| 		_ = schema.ApplyDefaultsToConfig(config) | |
| 	} | |
| }
 |