Skip to content

Commit

Permalink
Add string check and isNil Panic protection (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
jguerra6 authored Feb 21, 2023
1 parent 2e95db9 commit 0dc2fbe
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 12 deletions.
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

0 comments on commit 0dc2fbe

Please sign in to comment.