Skip to content

Commit

Permalink
test: adding 100% test coverage for parser
Browse files Browse the repository at this point in the history
  • Loading branch information
bl4ko committed Mar 19, 2024
1 parent 7569ec9 commit 47f2b1e
Show file tree
Hide file tree
Showing 28 changed files with 618 additions and 194 deletions.
20 changes: 10 additions & 10 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func validateNetboxConfig(config *Config) error {
}
if len(config.Netbox.SourcePriority) > 0 {
if len(config.Netbox.SourcePriority) != len(config.Sources) {
return fmt.Errorf("netbox.sourcePriority: len(config.Netbox.SourcePriority != len(config.Sources))")
return fmt.Errorf("netbox.sourcePriority: len(config.Netbox.SourcePriority != len(config.Sources)")
}
for _, sourceName := range config.Netbox.SourcePriority {
contains := false
Expand All @@ -159,7 +159,7 @@ func validateNetboxConfig(config *Config) error {
}
}
if !contains {
return fmt.Errorf("netbox.sourcePriority: source[%s] doesn't exist in sources array", sourceName)
return fmt.Errorf("netbox.sourcePriority: source[%s] doesn't exist in the sources array", sourceName)
}
}
}
Expand All @@ -172,26 +172,26 @@ func validateSourceConfig(config *Config) error {
externalSource := &config.Sources[i]
externalSourceStr := "source[" + externalSource.Name + "]"
if externalSource.Name == "" {
return fmt.Errorf("%s: name cannot be empty", externalSourceStr)
return fmt.Errorf("%s.name: cannot be empty", externalSourceStr)
}
if externalSource.HTTPScheme == "" {
externalSource.HTTPScheme = "https"
} else if externalSource.HTTPScheme != HTTP && externalSource.HTTPScheme != HTTPS {
return fmt.Errorf("%s.httpScheme must be either http or https. Is %s", externalSourceStr, string(externalSource.HTTPScheme))
return fmt.Errorf("%s.httpScheme: must be either http or https. Is %s", externalSourceStr, string(externalSource.HTTPScheme))
}
if externalSource.Hostname == "" {
return fmt.Errorf("%s: hostname cannot be empty", externalSourceStr)
return fmt.Errorf("%s.hostname: cannot be empty", externalSourceStr)
}
if externalSource.Port == 0 {
externalSource.Port = 443
} else if externalSource.Port < 0 || externalSource.Port > 65535 {
return fmt.Errorf("%s: port must be between 0 and 65535. Is %d", externalSourceStr, externalSource.Port)
return fmt.Errorf("%s.port: must be between 0 and 65535. Is %d", externalSourceStr, externalSource.Port)
}
if externalSource.Username == "" {
return fmt.Errorf("%s: username cannot be empty", externalSourceStr)
return fmt.Errorf("%s.username: cannot be empty", externalSourceStr)
}
if externalSource.Password == "" {
return fmt.Errorf("%s: password cannot be empty", externalSourceStr)
return fmt.Errorf("%s.password: cannot be empty", externalSourceStr)
}
if externalSource.Tag == "" {
externalSource.Tag = fmt.Sprintf("Source: %s", externalSource.Name)
Expand All @@ -214,14 +214,14 @@ func validateSourceConfig(config *Config) error {
if len(externalSource.IgnoredSubnets) > 0 {
for _, ignoredSubnet := range externalSource.IgnoredSubnets {
if !utils.VerifySubnet(ignoredSubnet) {
return fmt.Errorf("%s.ignoredSubnets wrong format: %s", externalSourceStr, ignoredSubnet)
return fmt.Errorf("%s.ignoredSubnets: wrong format: %s", externalSourceStr, ignoredSubnet)
}
}
}
// Try to compile interfaceFilter
_, err = regexp.Compile(externalSource.InterfaceFilter)
if err != nil {
return fmt.Errorf("%s.interfaceFilter wrong format: %s", externalSourceStr, err)
return fmt.Errorf("%s.interfaceFilter: wrong format: %s", externalSourceStr, err)
}
}
return nil
Expand Down
92 changes: 0 additions & 92 deletions internal/parser/parser_invalid_test.go

This file was deleted.

174 changes: 174 additions & 0 deletions internal/parser/parser_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package parser

import (
"fmt"
"path/filepath"
"reflect"
"testing"

"github.com/bl4ko/netbox-ssot/internal/constants"
)

func TestValidonfig(t *testing.T) {
filename := filepath.Join("testdata", "valid_config1.yaml")
want := &Config{
Logger: &LoggerConfig{
Level: 2,
Dest: "test",
},
Netbox: &NetboxConfig{
APIToken: "netbox-token",
Hostname: "netbox.example.com",
HTTPScheme: "https",
Port: 666,
ValidateCert: false, // Default
Timeout: constants.DefaultAPITimeout,
Tag: constants.DefaultSourceName, // Default
TagColor: "00add8", // Default
RemoveOrphans: true, // Default
},
Sources: []SourceConfig{
{
Name: "testolvm",
Type: "ovirt",
HTTPScheme: "http",
Port: 443,
Hostname: "testolvm.example.com",
Username: "admin@internal",
Password: "adminpass",
IgnoredSubnets: []string{
"172.16.0.0/12",
"192.168.0.0/16",
"fd00::/8",
},
ValidateCert: true,
Tag: "testing",
TagColor: "ff0000",
},
{
Name: "prodolvm",
Type: "ovirt",
Port: 80,
HTTPScheme: "https",
Hostname: "ovirt.example.com",
Username: "admin",
Password: "adminpass",
IgnoredSubnets: []string{
"172.16.0.0/12",
},
ValidateCert: false,
Tag: "Source: prodolvm", // Default
TagColor: "aa1409", // Default
ClusterSiteRelations: []string{
"Cluster_NYC = New York",
"Cluster_FFM.* = Frankfurt",
"Datacenter_BERLIN/* = Berlin",
},
HostSiteRelations: []string{
".* = Berlin",
},
ClusterTenantRelations: []string{
".*Stark = Stark Industries",
".* = Default",
},
HostTenantRelations: []string{
".*Health = Health Department",
".* = Default",
},
VMTenantRelations: []string{
".*Health = Health Department",
".* = Default",
},
},
},
}
got, err := ParseConfig(filename)
if err != nil {
t.Errorf("ParseConfig() error = %v", err)
return
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got = %v\nwant %v\n", got, want)
}

// test string method
fmt.Printf("config: %v\n", got)
}

func TestParseValidConfigs(t *testing.T) {
testCases := []struct {
filename string
}{
{
filename: "valid_config1.yaml",
},
{
filename: "valid_config2.yaml",
},
}
for _, tc := range testCases {
t.Run(tc.filename, func(t *testing.T) {
filename := filepath.Join("testdata", tc.filename)
config, err := ParseConfig(filename)
if err != nil {
t.Errorf("error parsing config: %s", err)
}
// Verify that logger config String() method works correctly
fmt.Println(config.Logger)
})
}
}

// Test case struct.
type configTestCase struct {
filename string
expectedErr string
}

// TestParseConfigInvalidConfigs runs through test cases of invalid configurations.
func TestParseConfigInvalidConfigs(t *testing.T) {
testCases := []configTestCase{
{filename: "invalid_config1.yaml", expectedErr: "netbox.hostname: cannot be empty"},
{filename: "invalid_config2.yaml", expectedErr: "netbox.port: must be between 0 and 65535. Is 333333"},
{filename: "invalid_config3.yaml", expectedErr: "source[testolvm].type is not valid"},
{filename: "invalid_config4.yaml", expectedErr: "netbox.httpScheme: must be either http or https. Is httpd"},
{filename: "invalid_config5.yaml", expectedErr: "source[prodovirt].httpScheme: must be either http or https. Is httpd"},
{filename: "invalid_config6.yaml", expectedErr: "source[testolvm].hostTenantRelations: invalid regex relation: This should not work. Should be of format: regex = value"},
{filename: "invalid_config7.yaml", expectedErr: "source[prodolvm].hostTenantRelations: invalid regex: [a-z++, in relation: [a-z++ = Should not work"},
{filename: "invalid_config8.yaml", expectedErr: "source[testolvm].port: must be between 0 and 65535. Is 1111111"},
{filename: "invalid_config9.yaml", expectedErr: "logger.level: must be between 0 and 3"},
{filename: "invalid_config10.yaml", expectedErr: "netbox.timeout: cannot be negative"},
{filename: "invalid_config11.yaml", expectedErr: "netbox.apiToken: cannot be empty"},
{filename: "invalid_config12.yaml", expectedErr: "netbox.tagColor: must be a string of 6 hexadecimal characters"},
{filename: "invalid_config13.yaml", expectedErr: "netbox.tagColor: must be a string of 6 lowercase hexadecimal characters"},
{filename: "invalid_config14.yaml", expectedErr: "netbox.sourcePriority: len(config.Netbox.SourcePriority != len(config.Sources)"},
{filename: "invalid_config15.yaml", expectedErr: "netbox.sourcePriority: source[wrongone] doesn't exist in the sources array"},
{filename: "invalid_config16.yaml", expectedErr: "source[].name: cannot be empty"},
{filename: "invalid_config17.yaml", expectedErr: "source[wrong].hostname: cannot be empty"},
{filename: "invalid_config18.yaml", expectedErr: "source[wrong].username: cannot be empty"},
{filename: "invalid_config19.yaml", expectedErr: "source[wrong].password: cannot be empty"},
{filename: "invalid_config20.yaml", expectedErr: "source[wrong].ignoredSubnets: wrong format: 172.16.0.1"},
{filename: "invalid_config21.yaml", expectedErr: "source[wrong].interfaceFilter: wrong format: error parsing regexp: missing closing ): `($a[ba]`"},
{filename: "invalid_config22.yaml", expectedErr: "source[wrong].hostSiteRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config23.yaml", expectedErr: "source[wrong].clusterSiteRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config24.yaml", expectedErr: "source[wrong].clusterTenantRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config25.yaml", expectedErr: "source[wrong].hostTenantRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config26.yaml", expectedErr: "source[wrong].vmTenantRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config27.yaml", expectedErr: "source[wrong].vlanGroupRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config28.yaml", expectedErr: "source[wrong].vlanTenantRelations: invalid regex: (wrong(), in relation: (wrong() = wwrong"},
{filename: "invalid_config29.yaml", expectedErr: "yaml: unmarshal errors:\n line 2: cannot unmarshal !!str `2dasf` into int"},
{filename: "invalid_config1111.yaml", expectedErr: "open testdata/invalid_config1111.yaml: no such file or directory"},
}

for _, tc := range testCases {
t.Run(tc.filename, func(t *testing.T) {
filename := filepath.Join("testdata", tc.filename)
_, err := ParseConfig(filename)
if err == nil {
t.Errorf("Expected error for %v, got nil", tc.filename)
} else if err.Error() != tc.expectedErr {
t.Errorf("Expected error: %v, got: %v", tc.expectedErr, err)
}
})
}
}
Loading

0 comments on commit 47f2b1e

Please sign in to comment.