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  }