github.com/snowflakedb/gosnowflake@v1.9.0/client_configuration_test.go (about) 1 // Copyright (c) 2023 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "fmt" 7 "os" 8 "path" 9 "path/filepath" 10 "strings" 11 "testing" 12 ) 13 14 func TestFindConfigFileFromConnectionParameters(t *testing.T) { 15 dirs := createTestDirectories(t) 16 connParameterConfigPath := createFile(t, "conn_parameters_config.json", "random content", dirs.dir) 17 envConfigPath := createFile(t, "env_var_config.json", "random content", dirs.dir) 18 t.Setenv(clientConfEnvName, envConfigPath) 19 createFile(t, defaultConfigName, "random content", dirs.predefinedDir1) 20 createFile(t, defaultConfigName, "random content", dirs.predefinedDir2) 21 22 clientConfigFilePath, err := findClientConfigFilePath(connParameterConfigPath, predefinedTestDirs(dirs)) 23 24 assertEqualE(t, err, nil) 25 assertEqualE(t, clientConfigFilePath, connParameterConfigPath, "config file path") 26 } 27 28 func TestFindConfigFileFromEnvVariable(t *testing.T) { 29 dirs := createTestDirectories(t) 30 envConfigPath := createFile(t, "env_var_config.json", "random content", dirs.dir) 31 t.Setenv(clientConfEnvName, envConfigPath) 32 createFile(t, defaultConfigName, "random content", dirs.predefinedDir1) 33 createFile(t, defaultConfigName, "random content", dirs.predefinedDir2) 34 35 clientConfigFilePath, err := findClientConfigFilePath("", predefinedTestDirs(dirs)) 36 37 assertEqualE(t, err, nil) 38 assertEqualE(t, clientConfigFilePath, envConfigPath, "config file path") 39 } 40 41 func TestFindConfigFileFromFirstPredefinedDir(t *testing.T) { 42 dirs := createTestDirectories(t) 43 configPath := createFile(t, defaultConfigName, "random content", dirs.predefinedDir1) 44 createFile(t, defaultConfigName, "random content", dirs.predefinedDir2) 45 46 clientConfigFilePath, err := findClientConfigFilePath("", predefinedTestDirs(dirs)) 47 48 assertEqualE(t, err, nil) 49 assertEqualE(t, clientConfigFilePath, configPath, "config file path") 50 } 51 52 func TestFindConfigFileFromSubsequentDirectoryIfNotFoundInPreviousOne(t *testing.T) { 53 dirs := createTestDirectories(t) 54 createFile(t, "wrong_file_name.json", "random content", dirs.predefinedDir1) 55 configPath := createFile(t, defaultConfigName, "random content", dirs.predefinedDir2) 56 57 clientConfigFilePath, err := findClientConfigFilePath("", predefinedTestDirs(dirs)) 58 59 assertEqualE(t, err, nil) 60 assertEqualE(t, clientConfigFilePath, configPath, "config file path") 61 } 62 63 func TestNotFindConfigFileWhenNotDefined(t *testing.T) { 64 dirs := createTestDirectories(t) 65 createFile(t, "wrong_file_name.json", "random content", dirs.predefinedDir1) 66 createFile(t, "wrong_file_name.json", "random content", dirs.predefinedDir2) 67 68 clientConfigFilePath, err := findClientConfigFilePath("", predefinedTestDirs(dirs)) 69 70 assertEqualE(t, err, nil) 71 assertEqualE(t, clientConfigFilePath, "", "config file path") 72 } 73 74 func TestCreatePredefinedDirs(t *testing.T) { 75 exeDir, _ := os.Executable() 76 appDir := filepath.Dir(exeDir) 77 homeDir, err := os.UserHomeDir() 78 assertNilF(t, err, "get home dir error") 79 80 locations := clientConfigPredefinedDirs() 81 82 assertEqualF(t, len(locations), 2, "size") 83 assertEqualE(t, locations[0], appDir, "driver directory") 84 assertEqualE(t, locations[1], homeDir, "home directory") 85 } 86 87 func TestGetClientConfig(t *testing.T) { 88 dir := t.TempDir() 89 fileName := "config.json" 90 configContents := createClientConfigContent("INFO", "/some-path/some-directory") 91 createFile(t, fileName, configContents, dir) 92 filePath := path.Join(dir, fileName) 93 94 clientConfigFilePath, _, err := getClientConfig(filePath) 95 96 assertNilF(t, err) 97 assertNotNilF(t, clientConfigFilePath) 98 assertEqualE(t, clientConfigFilePath.Common.LogLevel, "INFO", "log level") 99 assertEqualE(t, clientConfigFilePath.Common.LogPath, "/some-path/some-directory", "log path") 100 } 101 102 func TestNoResultForGetClientConfigWhenNoFileFound(t *testing.T) { 103 clientConfigFilePath, _, err := getClientConfig("") 104 105 assertNilF(t, err) 106 assertNilF(t, clientConfigFilePath) 107 } 108 109 func TestParseConfiguration(t *testing.T) { 110 dir := t.TempDir() 111 testCases := []struct { 112 testName string 113 fileName string 114 fileContents string 115 expectedLogLevel string 116 expectedLogPath string 117 }{ 118 { 119 testName: "TestWithLogLevelUpperCase", 120 fileName: "config_1.json", 121 fileContents: createClientConfigContent("INFO", "/some-path/some-directory"), 122 expectedLogLevel: "INFO", 123 expectedLogPath: "/some-path/some-directory", 124 }, 125 { 126 testName: "TestWithLogLevelLowerCase", 127 fileName: "config_2.json", 128 fileContents: createClientConfigContent("info", "/some-path/some-directory"), 129 expectedLogLevel: "info", 130 expectedLogPath: "/some-path/some-directory", 131 }, 132 { 133 testName: "TestWithMissingValues", 134 fileName: "config_3.json", 135 fileContents: `{ 136 "common": {} 137 }`, 138 expectedLogLevel: "", 139 expectedLogPath: "", 140 }, 141 } 142 for _, tc := range testCases { 143 t.Run(tc.testName, func(t *testing.T) { 144 fileName := createFile(t, tc.fileName, tc.fileContents, dir) 145 146 config, err := parseClientConfiguration(fileName) 147 148 assertNilF(t, err, "parse client configuration error") 149 assertEqualE(t, config.Common.LogLevel, tc.expectedLogLevel, "log level") 150 assertEqualE(t, config.Common.LogPath, tc.expectedLogPath, "log path") 151 }) 152 } 153 } 154 155 func TestParseAllLogLevels(t *testing.T) { 156 dir := t.TempDir() 157 for _, logLevel := range []string{"OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"} { 158 t.Run(logLevel, func(t *testing.T) { 159 fileContents := fmt.Sprintf(`{ 160 "common": { 161 "log_level" : "%s", 162 "log_path" : "/some-path/some-directory" 163 } 164 }`, logLevel) 165 fileName := createFile(t, fmt.Sprintf("config_%s.json", logLevel), fileContents, dir) 166 167 config, err := parseClientConfiguration(fileName) 168 169 assertNilF(t, err, "parse client config error") 170 assertEqualE(t, config.Common.LogLevel, logLevel, "log level") 171 }) 172 } 173 } 174 175 func TestParseConfigurationFails(t *testing.T) { 176 dir := t.TempDir() 177 testCases := []struct { 178 testName string 179 fileName string 180 FileContents string 181 expectedErrorMessageToContain string 182 }{ 183 { 184 testName: "TestWithWrongLogLevel", 185 fileName: "config_1.json", 186 FileContents: createClientConfigContent("something weird", "/some-path/some-directory"), 187 expectedErrorMessageToContain: "unknown log level", 188 }, 189 { 190 testName: "TestWithWrongTypeOfLogLevel", 191 fileName: "config_2.json", 192 FileContents: `{ 193 "common": { 194 "log_level" : 15, 195 "log_path" : "/some-path/some-directory" 196 } 197 }`, 198 expectedErrorMessageToContain: "ClientConfigCommonProps.common.log_level", 199 }, 200 { 201 testName: "TestWithWrongTypeOfLogPath", 202 fileName: "config_3.json", 203 FileContents: `{ 204 "common": { 205 "log_level" : "INFO", 206 "log_path" : true 207 } 208 }`, 209 expectedErrorMessageToContain: "ClientConfigCommonProps.common.log_path", 210 }, 211 { 212 testName: "TestWithoutCommon", 213 fileName: "config_4.json", 214 FileContents: "{}", 215 expectedErrorMessageToContain: "common section in client config not found", 216 }, 217 } 218 for _, tc := range testCases { 219 t.Run(tc.testName, func(t *testing.T) { 220 fileName := createFile(t, tc.fileName, tc.FileContents, dir) 221 222 _, err := parseClientConfiguration(fileName) 223 224 assertNotNilF(t, err, "parse client configuration error") 225 errMessage := fmt.Sprint(err) 226 expectedPrefix := "parsing client config failed" 227 assertHasPrefixE(t, errMessage, expectedPrefix, "error message") 228 assertStringContainsE(t, errMessage, tc.expectedErrorMessageToContain, "error message") 229 }) 230 } 231 } 232 233 func TestUnknownValues(t *testing.T) { 234 testCases := []struct { 235 testName string 236 inputString string 237 expectedOutput map[string]string 238 }{ 239 { 240 testName: "EmptyCommon", 241 inputString: `{ 242 "common": {} 243 }`, 244 expectedOutput: map[string]string{}, 245 }, 246 { 247 testName: "CommonMissing", 248 inputString: `{ 249 }`, 250 expectedOutput: map[string]string{}, 251 }, 252 { 253 testName: "UnknownProperty", 254 inputString: `{ 255 "common": { 256 "unknown_key": "unknown_value" 257 } 258 }`, 259 expectedOutput: map[string]string{ 260 "unknown_key": "unknown_value", 261 }, 262 }, 263 { 264 testName: "KnownAndUnknownProperty", 265 inputString: `{ 266 "common": { 267 "lOg_level": "level", 268 "log_PATH": "path", 269 "unknown_key": "unknown_value" 270 } 271 }`, 272 expectedOutput: map[string]string{ 273 "unknown_key": "unknown_value", 274 }, 275 }, 276 { 277 testName: "KnownProperties", 278 inputString: `{ 279 "common": { 280 "log_level": "level", 281 "log_path": "path" 282 } 283 }`, 284 expectedOutput: map[string]string{}, 285 }, 286 287 { 288 testName: "EmptyInput", 289 inputString: "", 290 expectedOutput: map[string]string{}, 291 }, 292 } 293 294 for _, tc := range testCases { 295 t.Run(tc.testName, func(t *testing.T) { 296 inputBytes := []byte(tc.inputString) 297 result := getUnknownValues(inputBytes) 298 assertEqualE(t, fmt.Sprint(result), fmt.Sprint(tc.expectedOutput)) 299 }) 300 } 301 } 302 303 func createFile(t *testing.T, fileName string, fileContents string, directory string) string { 304 fullFileName := path.Join(directory, fileName) 305 err := os.WriteFile(fullFileName, []byte(fileContents), 0644) 306 assertNilF(t, err, "create file error") 307 return fullFileName 308 } 309 310 func createTestDirectories(t *testing.T) struct { 311 dir string 312 predefinedDir1 string 313 predefinedDir2 string 314 } { 315 dir := t.TempDir() 316 predefinedDir1 := path.Join(dir, "dir1") 317 err := os.Mkdir(predefinedDir1, 0700) 318 assertNilF(t, err, "predefined dir1 error") 319 predefinedDir2 := path.Join(dir, "dir2") 320 err = os.Mkdir(predefinedDir2, 0700) 321 assertNilF(t, err, "predefined dir2 error") 322 return struct { 323 dir string 324 predefinedDir1 string 325 predefinedDir2 string 326 }{ 327 dir: dir, 328 predefinedDir1: predefinedDir1, 329 predefinedDir2: predefinedDir2, 330 } 331 } 332 333 func predefinedTestDirs(dirs struct { 334 dir string 335 predefinedDir1 string 336 predefinedDir2 string 337 }) []string { 338 return []string{dirs.predefinedDir1, dirs.predefinedDir2} 339 } 340 341 func createClientConfigContent(logLevel string, logPath string) string { 342 return fmt.Sprintf(`{ 343 "common": { 344 "log_level" : "%s", 345 "log_path" : "%s" 346 } 347 }`, 348 logLevel, 349 strings.ReplaceAll(logPath, "\\", "\\\\"), 350 ) 351 }