Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions remoteconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ func ReadJSONValidate(cfgReader io.Reader, configStruct interface{}) error {
return nil
}

func isNilFixed(v reflect.Value) bool {
switch v.Kind() {
case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
//use of IsNil method
return v.IsNil()
}
return false
}

// Validates a configuration struct.
// Uses reflection to determine and call the correct Validation methods for each type.
func validateConfigWithReflection(c interface{}) error {
Expand Down Expand Up @@ -78,9 +87,9 @@ func validateConfigWithReflection(c interface{}) error {
continue
}

if valueField.IsNil() && !optional {
if isNilFixed(valueField) && !optional {
return fmt.Errorf("Field: %s, not set", typeField.Name)
} else if valueField.IsNil() && optional {
} else if isNilFixed(valueField) && optional {
continue
}

Expand Down Expand Up @@ -115,14 +124,22 @@ func validateConfigWithReflection(c interface{}) error {
continue
}

// If this is a string field, check that it isn't empty (unless optional)
// If this is a string pointer field, check that it isn't empty (unless optional)
if s, ok := valueField.Interface().(*string); ok {
if *s == "" {
return fmt.Errorf("String Field: %s, contains an empty string", typeField.Name)
}
continue
}

// If this is a string field, check that it isn't empty (unless optional)
if s, ok := valueField.Interface().(string); ok {
if s == "" {
return fmt.Errorf("String Field: %s, contains an empty string", typeField.Name)
}
continue
}

// If the Validater interface is implemented, call the Validate method
if typeField.Type.Implements(validaterType) {
if err := valueField.Interface().(Validater).Validate(); err != nil {
Expand Down
65 changes: 56 additions & 9 deletions remoteconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ type SampleConfig struct {
SQSClient *SQSClientConfig `json:"sqs_client,omitempty"`
DynamoDBTable *DynamoDBTableConfig `json:"dynamodb_table,omitempty"`
DynamoDBClient *DynamoDBClientConfig `json:"dynamodb_client,omitempty"`
Str *string `json:"str,omitempty"`
Str string `json:"str,omitempty"`
StrPointer *string `json:"str_pointer,omitempty"`
StorageConfig *StorageConfig `json:"storage_config,omitempty"`
StorageConfigSlice []*StorageConfig `json:"storage_config_slice,omitempty"`
StorageConfigMap map[string]*StorageConfig `json:"storage_config_map,omitempty"`
Expand Down Expand Up @@ -79,6 +80,7 @@ var validConfigJSON = `
"table_name" : "testTable"
},
"str" : "testStr",
"str_pointer" : "testStr",
"storage_config" : {
"provider" : "aws",
"location" : "us-west-2"
Expand Down Expand Up @@ -151,7 +153,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionWithOptional() {
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
StrPointer: &str,
StorageConfig: storageConfig,
StorageConfigSlice: []*StorageConfig{storageConfig},
StorageConfigMap: map[string]*StorageConfig{"one": storageConfig},
Expand Down Expand Up @@ -348,12 +351,52 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrNotSet() {
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: nil,
Str: "testString",
StrPointer: nil,
}

err := validateConfigWithReflection(c)
assert.NotNil(s.T(), err)
assert.Equal(s.T(), errors.New("Field: Str, not set"), err)
assert.Equal(s.T(), errors.New("Field: StrPointer, not set"), err)
}

func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrPointerEmpty() {
sqsRegion := VALID_REMOTE_CONFIG_SQS_REGION
sqsAWSAccountID := VALID_REMOTE_CONFIG_SQS_AWS_ACCOUNT_ID
sqsQueueName := VALID_REMOTE_CONFIG_SQS_QUEUE_NAME
sqsQueue := &SQSQueueConfig{
Region: &sqsRegion,
AWSAccountID: &sqsAWSAccountID,
QueueName: &sqsQueueName,
}
sqsClient := &SQSClientConfig{
Region: &sqsRegion,
}

dynamodbTableName := VALID_REMOTE_CONFIG_DYNAMODB_TABLE_NAME
dynamodbTable := &DynamoDBTableConfig{
TableName: &dynamodbTableName,
}

dynamodbClientRegion := VALID_REMOTE_CONFIG_DYNAMODB_CLIENT_REGION
dynamodbClient := &DynamoDBClientConfig{
Region: &dynamodbClientRegion,
}

str := ""

c := &SampleConfig{
SQSQueue: sqsQueue,
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: "testString",
StrPointer: &str,
}

err := validateConfigWithReflection(c)
assert.NotNil(s.T(), err)
assert.Equal(s.T(), errors.New("String Field: StrPointer, contains an empty string"), err)
}

func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrEmpty() {
Expand Down Expand Up @@ -386,7 +429,7 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStrEmpty() {
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
}

err := validateConfigWithReflection(c)
Expand Down Expand Up @@ -424,7 +467,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigNo
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
StrPointer: &str,
StorageConfig: nil,
}

Expand Down Expand Up @@ -470,7 +514,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigSl
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
StrPointer: &str,
StorageConfig: storageConfig,
StorageConfigSlice: nil,
}
Expand Down Expand Up @@ -549,7 +594,8 @@ func (s *RemoteConfigSuite) TestValidateConfigWithReflectionErrorStorageConfigSl
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
StrPointer: &str,
StorageConfig: storageConfig,
StorageConfigSlice: []*StorageConfig{},
}
Expand Down Expand Up @@ -691,7 +737,8 @@ func (s *RemoteConfigSuite) buildValidSampleConfig() *SampleConfig {
SQSClient: sqsClient,
DynamoDBTable: dynamodbTable,
DynamoDBClient: dynamodbClient,
Str: &str,
Str: str,
StrPointer: &str,
StorageConfig: storageConfig,
StorageConfigSlice: []*StorageConfig{storageConfig},
StorageConfigMap: map[string]*StorageConfig{"one": storageConfig},
Expand Down