template / ci-testing / files / config_test.go
Branch ci-testing · default branch · all branches
config_test.go
763c260d 2022-10-06 Pavel Safronov | 1 | package main |
| 2 | ||
| 3 | import ( | |
| 4 | "errors" | |
| 5 | "os" | |
748e3056 2022-11-19 Pavel Safronov | 6 | "path/filepath" |
763c260d 2022-10-06 Pavel Safronov | 7 | "testing" |
| 8 | ||
| 9 | "github.com/stretchr/testify/assert" | |
| 10 | ) | |
| 11 | ||
e86c26ae 2022-11-02 Pavel Safronov | 12 | // Compares YAML representation of two objects |
| 13 | func compareObjectYaml(t *testing.T, expected, actual interface{}) { | |
| 14 | expectedYaml, err := getYaml(expected) | |
| 15 | assert.Nil(t, err, "Error marshalling expected") | |
| 16 | actualYaml, err := getYaml(actual) | |
| 17 | assert.Nil(t, err, "Error marshalling actual") | |
5e424f1b 2022-11-12 Pavel Safronov | 18 | assert.Equal(t, len(expectedYaml), len(actualYaml), "Expected YAML and actual YAML are different lengths") |
e86c26ae 2022-11-02 Pavel Safronov | 19 | assert.Equal(t, expectedYaml, actualYaml) |
| 20 | } | |
| 21 | ||
763c260d 2022-10-06 Pavel Safronov | 22 | func TestSaveLoadConfig(t *testing.T) { |
748e3056 2022-11-19 Pavel Safronov | 23 | const configPath string = "./test/test-config.yaml" |
| 24 | configDir := filepath.Dir(configPath) | |
| 25 | err := os.Mkdir(configDir, 0755) | |
| 26 | if err != nil && !errors.Is(err, os.ErrExist) { | |
| 27 | assert.Nil(t, err, "Error creating config directory") | |
| 28 | } | |
| 29 | defer os.Remove(configDir) | |
05f9e8ef 2022-10-06 Pavel Safronov | 30 | |
763c260d 2022-10-06 Pavel Safronov | 31 | config := defaultConfig() |
| 32 | ||
| 33 | // save config | |
748e3056 2022-11-19 Pavel Safronov | 34 | err = saveConfig(configPath, config) |
763c260d 2022-10-06 Pavel Safronov | 35 | assert.Nil(t, err, "Error saving config") |
| 36 | ||
| 37 | // load config | |
| 38 | loadedConfig, err := loadConfig(configPath) | |
| 39 | assert.Nil(t, err, "Error loading config") | |
| 40 | ||
| 41 | // test config | |
e86c26ae 2022-11-02 Pavel Safronov | 42 | compareObjectYaml(t, loadedConfig, config) |
763c260d 2022-10-06 Pavel Safronov | 43 | |
| 44 | // test load non-existent config | |
9573ca02 2022-11-16 Pavel Safronov | 45 | _, err = loadConfig("./test/non-existent-file.yaml") |
763c260d 2022-10-06 Pavel Safronov | 46 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") |
| 47 | ||
| 48 | // test load invalid yaml | |
748e3056 2022-11-19 Pavel Safronov | 49 | err = os.WriteFile("./invalid-yaml.yaml", []byte("invalid yaml"), 0644) |
75a066b2 2022-11-16 Pavel Safronov | 50 | assert.Nil(t, err, "Error writing invalid yaml file") |
748e3056 2022-11-19 Pavel Safronov | 51 | _, err = loadConfig("./invalid-yaml.yaml") |
763c260d 2022-10-06 Pavel Safronov | 52 | assert.NotNil(t, err, "Expected to fail to parse config, but succeeded") |
4ed1650c 2022-11-19 Pavel Safronov | 53 | os.Remove("./invalid-yaml.yaml") |
763c260d 2022-10-06 Pavel Safronov | 54 | |
| 55 | // test saving config to invalid path | |
| 56 | err = saveConfig("invalid/path/invalid-config.yaml", config) | |
| 57 | assert.NotNil(t, err, "Expected to fail to save config, but succeeded") | |
| 58 | ||
| 59 | // remove config | |
| 60 | os.Remove(configPath) | |
| 61 | ||
| 62 | // test default config creation | |
| 63 | _, err = os.Stat(configPath) | |
| 64 | assert.True(t, errors.Is(err, os.ErrNotExist), "Expected config file to not exist, but it does") | |
| 65 | ||
ae89a42a 2022-11-02 Pavel Safronov | 66 | // fail to get config |
| 67 | _, err = loadConfig(configPath) | |
| 68 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") | |
| 69 | ||
| 70 | // create default config | |
| 71 | err = saveConfig(configPath, defaultConfig()) | |
e86c26ae 2022-11-02 Pavel Safronov | 72 | assert.Nil(t, err, "Error saving config") |
763c260d 2022-10-06 Pavel Safronov | 73 | |
| 74 | // test config | |
e86c26ae 2022-11-02 Pavel Safronov | 75 | compareObjectYaml(t, loadedConfig, config) |
763c260d 2022-10-06 Pavel Safronov | 76 | |
| 77 | // verify config file exists | |
| 78 | stat1, err := os.Stat(configPath) | |
| 79 | assert.Nil(t, err, "Expected config file to exist, but it does not") | |
| 80 | ||
| 81 | // get and create config | |
ae89a42a 2022-11-02 Pavel Safronov | 82 | loadedConfig, err = loadConfig(configPath) |
763c260d 2022-10-06 Pavel Safronov | 83 | assert.Nil(t, err, "Error loading config") |
| 84 | ||
| 85 | // test config | |
e86c26ae 2022-11-02 Pavel Safronov | 86 | compareObjectYaml(t, loadedConfig, config) |
763c260d 2022-10-06 Pavel Safronov | 87 | |
| 88 | // verify config file wasn't updated | |
| 89 | stat2, err := os.Stat(configPath) | |
| 90 | assert.Nil(t, err, "Expected config file to exist, but it does not") | |
| 91 | assert.Equal(t, stat1.ModTime(), stat2.ModTime(), "Expected config file to not be modified, but it was") | |
| 92 | } | |
| 93 | ||
| 94 | func TestValidateDefaultConfig(t *testing.T) { | |
| 95 | config := defaultConfig() | |
b0586433 2022-10-21 Pavel Safronov | 96 | err := validateConfig(&config) |
763c260d 2022-10-06 Pavel Safronov | 97 | if err != nil { |
| 98 | t.Errorf("Expected to validate config, but failed: %v", err) | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | func TestValidateConfig(t *testing.T) { | |
05f9e8ef 2022-10-06 Pavel Safronov | 103 | testFailure := func(config Config, errorText string) { |
b0586433 2022-10-21 Pavel Safronov | 104 | err := validateConfig(&config) |
763c260d 2022-10-06 Pavel Safronov | 105 | if err == nil { |
| 106 | t.Errorf("Expected to fail to validate config, but succeeded") | |
| 107 | } | |
05f9e8ef 2022-10-06 Pavel Safronov | 108 | assert.Contains(t, err.Error(), errorText) |
763c260d 2022-10-06 Pavel Safronov | 109 | } |
| 110 | ||
05f9e8ef 2022-10-06 Pavel Safronov | 111 | testFailure(Config{}, "no profiles found") |
| 112 | testFailure(Config{Profiles: []Profile{}}, "no profiles found") | |
| 113 | testFailure(Config{Profiles: []Profile{ | |
| 114 | { | |
| 115 | Name: "daily", | |
| 116 | IsDefault: true, | |
1a02ef4e 2022-10-21 Pavel Safronov | 117 | NamePatterns: []ParameterizedText{"daily"}, |
b0586433 2022-10-21 Pavel Safronov | 118 | File: File{ |
| 119 | Template: "foo", | |
| 120 | }, | |
05f9e8ef 2022-10-06 Pavel Safronov | 121 | }, |
| 122 | }}, "error validating profile") | |
763c260d 2022-10-06 Pavel Safronov | 123 | testFailure(Config{Profiles: []Profile{ |
| 124 | { | |
05f9e8ef 2022-10-06 Pavel Safronov | 125 | Name: "daily", |
| 126 | IsDefault: true, | |
1a02ef4e 2022-10-21 Pavel Safronov | 127 | NamePatterns: []ParameterizedText{"daily"}, |
05f9e8ef 2022-10-06 Pavel Safronov | 128 | Type: FileType, |
8c15a714 2022-11-04 Pavel Safronov | 129 | Path: "foo", |
b0586433 2022-10-21 Pavel Safronov | 130 | File: File{ |
| 131 | Template: "foo", | |
| 132 | }, | |
763c260d 2022-10-06 Pavel Safronov | 133 | }, |
| 134 | { | |
05f9e8ef 2022-10-06 Pavel Safronov | 135 | Name: "daily2", |
| 136 | IsDefault: true, | |
1a02ef4e 2022-10-21 Pavel Safronov | 137 | NamePatterns: []ParameterizedText{"daily"}, |
05f9e8ef 2022-10-06 Pavel Safronov | 138 | Type: FileType, |
8c15a714 2022-11-04 Pavel Safronov | 139 | Path: "foo", |
b0586433 2022-10-21 Pavel Safronov | 140 | File: File{ |
| 141 | Template: "foo", | |
| 142 | }, | |
763c260d 2022-10-06 Pavel Safronov | 143 | }, |
05f9e8ef 2022-10-06 Pavel Safronov | 144 | }}, "multiple default profiles found") |
9573ca02 2022-11-16 Pavel Safronov | 145 | testFailure(Config{Profiles: []Profile{ |
| 146 | { | |
| 147 | Name: "daily", | |
| 148 | IsDefault: true, | |
| 149 | NamePatterns: []ParameterizedText{"daily"}, | |
| 150 | Type: FileType, | |
| 151 | Path: "foo", | |
| 152 | File: File{ | |
| 153 | Template: "foo", | |
| 154 | }, | |
| 155 | }, | |
| 156 | { | |
| 157 | Name: "daily", | |
| 158 | IsDefault: true, | |
| 159 | NamePatterns: []ParameterizedText{"daily"}, | |
| 160 | Type: FileType, | |
| 161 | Path: "foo", | |
| 162 | File: File{ | |
| 163 | Template: "foo", | |
| 164 | }, | |
| 165 | }, | |
| 166 | }}, "duplicate profile name 'daily'") | |
| 167 | } | |
| 168 | ||
| 169 | func TestLoadConfig(t *testing.T) { | |
| 170 | bytes := []byte(` | |
| 171 | profiles: | |
| 172 | - name: | |
| 173 | `) | |
748e3056 2022-11-19 Pavel Safronov | 174 | err := os.WriteFile("./invalid-config.yaml", bytes, 0644) |
75a066b2 2022-11-16 Pavel Safronov | 175 | assert.Nil(t, err, "Error writing invalid config file") |
4ed1650c 2022-11-19 Pavel Safronov | 176 | defer os.Remove("./invalid-config.yaml") |
9573ca02 2022-11-16 Pavel Safronov | 177 | |
| 178 | // load config | |
748e3056 2022-11-19 Pavel Safronov | 179 | _, err = loadConfig("./invalid-config.yaml") |
9573ca02 2022-11-16 Pavel Safronov | 180 | assert.NotNil(t, err, "Expected to fail to load config, but succeeded") |
| 181 | assert.Contains(t, err.Error(), "error validating profile : Profile name is required") | |
| 182 | } | |
| 183 | ||
| 184 | func TestSaveConfig(t *testing.T) { | |
| 185 | config := Config{Profiles: []Profile{}} | |
748e3056 2022-11-19 Pavel Safronov | 186 | err := saveConfig("./invalid-config.yaml", config) |
9573ca02 2022-11-16 Pavel Safronov | 187 | assert.NotNil(t, err, "Expected to fail to save config, but succeeded") |
| 188 | assert.Contains(t, err.Error(), "no profiles found") | |
| 189 | } | |
| 190 | ||
| 191 | func TestMergeConfigs(t *testing.T) { | |
| 192 | defaultConfig := defaultConfig() | |
| 193 | testSuccess := func(config1 Config, config2 Config) Config { | |
| 194 | config, err := mergeConfigs(config1, config2) | |
| 195 | // compareObjectYaml(t, mergedConfig, expected) | |
| 196 | assert.Nil(t, err, "Expected to merge configs, but failed") | |
| 197 | return config | |
| 198 | } | |
| 199 | testFailure := func(config1 Config, config2 Config, errorText string) { | |
| 200 | _, err := mergeConfigs(config1, config2) | |
| 201 | assert.NotNil(t, err, "Expected to fail to merge configs, but succeeded") | |
| 202 | assert.Contains(t, err.Error(), errorText) | |
| 203 | } | |
| 204 | testFailure(Config{}, Config{}, "no profiles found") | |
748e3056 2022-11-19 Pavel Safronov | 205 | testFailure(Config{Profiles: []Profile{{}}}, Config{}, "error validating config a: error validating profile : Profile name is required") |
9573ca02 2022-11-16 Pavel Safronov | 206 | testFailure(Config{Profiles: []Profile{defaultConfig.Profiles[0]}}, Config{}, "error validating config b: no profiles found") |
| 207 | ||
| 208 | profile1 := defaultConfig.Profiles[0] | |
| 209 | profile2 := defaultConfig.Profiles[1] | |
| 210 | testSuccess(Config{Profiles: []Profile{profile1}}, Config{Profiles: []Profile{profile2}}) | |
| 211 | ||
| 212 | profile1_updated := profile1 | |
| 213 | profile1_updated.Description += " This profile has been updated!" | |
| 214 | ||
| 215 | result := testSuccess(Config{Profiles: []Profile{profile1}}, Config{Profiles: []Profile{profile1_updated}}) | |
| 216 | assert.Equal(t, 1, len(result.Profiles)) | |
| 217 | assert.Equal(t, profile1_updated.Name, result.Profiles[0].Name) | |
763c260d 2022-10-06 Pavel Safronov | 218 | } |