github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/config/database_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package config
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"fmt"
    10  	"os"
    11  	"strings"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/jmoiron/sqlx"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  
    19  	"github.com/masterhung0112/hk_server/v5/config"
    20  )
    21  
    22  func getDsn(driver string, source string) string {
    23  	if driver == model.DATABASE_DRIVER_MYSQL {
    24  		return driver + "://" + source
    25  	}
    26  	return source
    27  }
    28  
    29  func setupConfigDatabase(t *testing.T, cfg *model.Config, files map[string][]byte) (string, func()) {
    30  	if testing.Short() {
    31  		t.SkipNow()
    32  	}
    33  	t.Helper()
    34  	os.Clearenv()
    35  	truncateTables(t)
    36  
    37  	cfgData, err := marshalConfig(cfg)
    38  	require.NoError(t, err)
    39  
    40  	db := sqlx.NewDb(mainHelper.GetSQLStore().GetMaster().Db, *mainHelper.GetSQLSettings().DriverName)
    41  	err = initializeConfigurationsTable(db)
    42  	require.NoError(t, err)
    43  
    44  	id := model.NewId()
    45  	_, err = db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:Id, :Value, :CreateAt, TRUE)", map[string]interface{}{
    46  		"Id":       id,
    47  		"Value":    cfgData,
    48  		"CreateAt": model.GetMillis(),
    49  	})
    50  	require.NoError(t, err)
    51  
    52  	for name, data := range files {
    53  		params := map[string]interface{}{
    54  			"name":      name,
    55  			"data":      data,
    56  			"create_at": model.GetMillis(),
    57  			"update_at": model.GetMillis(),
    58  		}
    59  
    60  		_, err = db.NamedExec("INSERT INTO ConfigurationFiles (Name, Data, CreateAt, UpdateAt) VALUES (:name, :data, :create_at, :update_at)", params)
    61  		require.NoError(t, err)
    62  	}
    63  
    64  	return id, func() {
    65  		truncateTables(t)
    66  	}
    67  }
    68  
    69  // getActualDatabaseConfig returns the active configuration in the database without relying on a config store.
    70  func getActualDatabaseConfig(t *testing.T) (string, *model.Config) {
    71  	t.Helper()
    72  
    73  	if *mainHelper.GetSQLSettings().DriverName == "postgres" {
    74  		var actual struct {
    75  			ID    string `db:"id"`
    76  			Value []byte `db:"value"`
    77  		}
    78  		db := sqlx.NewDb(mainHelper.GetSQLStore().GetMaster().Db, *mainHelper.GetSQLSettings().DriverName)
    79  		err := db.Get(&actual, "SELECT Id, Value FROM Configurations WHERE Active")
    80  		require.NoError(t, err)
    81  
    82  		var actualCfg *model.Config
    83  		err = json.Unmarshal(actual.Value, &actualCfg)
    84  		require.NoError(t, err)
    85  		return actual.ID, actualCfg
    86  	}
    87  	var actual struct {
    88  		ID    string `db:"Id"`
    89  		Value []byte `db:"Value"`
    90  	}
    91  	db := sqlx.NewDb(mainHelper.GetSQLStore().GetMaster().Db, *mainHelper.GetSQLSettings().DriverName)
    92  	err := db.Get(&actual, "SELECT Id, Value FROM Configurations WHERE Active")
    93  	require.NoError(t, err)
    94  
    95  	var actualCfg *model.Config
    96  	err = json.Unmarshal(actual.Value, &actualCfg)
    97  	require.NoError(t, err)
    98  	return actual.ID, actualCfg
    99  }
   100  
   101  // assertDatabaseEqualsConfig verifies the active in-database configuration equals the given config.
   102  func assertDatabaseEqualsConfig(t *testing.T, expectedCfg *model.Config) {
   103  	t.Helper()
   104  
   105  	_, actualCfg := getActualDatabaseConfig(t)
   106  	assert.Equal(t, expectedCfg, actualCfg)
   107  }
   108  
   109  // assertDatabaseNotEqualsConfig verifies the in-database configuration does not equal the given config.
   110  func assertDatabaseNotEqualsConfig(t *testing.T, expectedCfg *model.Config) {
   111  	t.Helper()
   112  
   113  	_, actualCfg := getActualDatabaseConfig(t)
   114  	assert.NotEqual(t, expectedCfg, actualCfg)
   115  }
   116  
   117  func newTestDatabaseStore(customDefaults *model.Config) (*Store, error) {
   118  	sqlSettings := mainHelper.GetSQLSettings()
   119  	dss, err := NewDatabaseStore(getDsn(*sqlSettings.DriverName, *sqlSettings.DataSource))
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	cStore, err := NewStoreFromBacking(dss, customDefaults, false)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	return cStore, nil
   130  }
   131  
   132  func TestDatabaseStoreNew(t *testing.T) {
   133  	if testing.Short() {
   134  		t.SkipNow()
   135  	}
   136  	sqlSettings := mainHelper.GetSQLSettings()
   137  
   138  	t.Run("no existing configuration - initialization required", func(t *testing.T) {
   139  		ds, err := newTestDatabaseStore(nil)
   140  		require.NoError(t, err)
   141  		defer ds.Close()
   142  
   143  		assert.Equal(t, "", *ds.Get().ServiceSettings.SiteURL)
   144  	})
   145  
   146  	t.Run("no existing configuration with custom defaults", func(t *testing.T) {
   147  		truncateTables(t)
   148  		ds, err := newTestDatabaseStore(customConfigDefaults)
   149  		require.NoError(t, err)
   150  		defer ds.Close()
   151  
   152  		assert.Equal(t, *customConfigDefaults.ServiceSettings.SiteURL, *ds.Get().ServiceSettings.SiteURL)
   153  		assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
   154  	})
   155  
   156  	t.Run("existing config, initialization required", func(t *testing.T) {
   157  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   158  		defer tearDown()
   159  
   160  		ds, err := newTestDatabaseStore(nil)
   161  		require.NoError(t, err)
   162  		defer ds.Close()
   163  
   164  		assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
   165  		assertDatabaseNotEqualsConfig(t, testConfig)
   166  	})
   167  
   168  	t.Run("existing config with custom defaults, initialization required", func(t *testing.T) {
   169  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   170  		defer tearDown()
   171  
   172  		ds, err := newTestDatabaseStore(customConfigDefaults)
   173  		require.NoError(t, err)
   174  		defer ds.Close()
   175  
   176  		// already existing value should not be overwritten by the
   177  		// custom default value
   178  		assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
   179  		// not existing value should be overwritten by the custom
   180  		// default value
   181  		assert.Equal(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
   182  		assertDatabaseNotEqualsConfig(t, testConfig)
   183  	})
   184  
   185  	t.Run("already minimally configured", func(t *testing.T) {
   186  		_, tearDown := setupConfigDatabase(t, minimalConfigNoFF, nil)
   187  		defer tearDown()
   188  
   189  		ds, err := newTestDatabaseStore(nil)
   190  		require.NoError(t, err)
   191  		defer ds.Close()
   192  
   193  		assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
   194  		assertDatabaseEqualsConfig(t, minimalConfigNoFF)
   195  	})
   196  
   197  	t.Run("already minimally configured with custom defaults", func(t *testing.T) {
   198  		_, tearDown := setupConfigDatabase(t, minimalConfigNoFF, nil)
   199  		defer tearDown()
   200  
   201  		ds, err := newTestDatabaseStore(customConfigDefaults)
   202  		require.NoError(t, err)
   203  		defer ds.Close()
   204  
   205  		// as the whole config has default values already, custom
   206  		// defaults should have no effect
   207  		assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
   208  		assert.NotEqual(t, *customConfigDefaults.DisplaySettings.ExperimentalTimezone, *ds.Get().DisplaySettings.ExperimentalTimezone)
   209  		assertDatabaseEqualsConfig(t, minimalConfigNoFF)
   210  	})
   211  
   212  	t.Run("invalid url", func(t *testing.T) {
   213  		_, err := NewDatabaseStore("")
   214  		require.Error(t, err)
   215  
   216  		_, err = NewDatabaseStore("mysql")
   217  		require.Error(t, err)
   218  	})
   219  
   220  	t.Run("unsupported scheme", func(t *testing.T) {
   221  		_, err := NewDatabaseStore("invalid")
   222  		require.Error(t, err)
   223  	})
   224  
   225  	t.Run("unsupported scheme with valid data source", func(t *testing.T) {
   226  		_, err := NewDatabaseStore(fmt.Sprintf("invalid://%s", *sqlSettings.DataSource))
   227  		require.Error(t, err)
   228  	})
   229  }
   230  
   231  func TestDatabaseStoreGet(t *testing.T) {
   232  	_, tearDown := setupConfigDatabase(t, testConfig, nil)
   233  	defer tearDown()
   234  
   235  	ds, err := newTestDatabaseStore(nil)
   236  	require.NoError(t, err)
   237  	defer ds.Close()
   238  
   239  	cfg := ds.Get()
   240  	assert.Equal(t, "http://TestStoreNew", *cfg.ServiceSettings.SiteURL)
   241  
   242  	cfg2 := ds.Get()
   243  	assert.Equal(t, "http://TestStoreNew", *cfg.ServiceSettings.SiteURL)
   244  
   245  	assert.True(t, cfg == cfg2, "Get() returned different configuration instances")
   246  }
   247  
   248  func TestDatabaseStoreGetEnivironmentOverrides(t *testing.T) {
   249  	t.Run("get override for a string variable", func(t *testing.T) {
   250  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   251  		defer tearDown()
   252  
   253  		ds, err := newTestDatabaseStore(nil)
   254  		require.NoError(t, err)
   255  		defer ds.Close()
   256  
   257  		assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
   258  		assert.Empty(t, ds.GetEnvironmentOverrides())
   259  
   260  		os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://override")
   261  		defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   262  
   263  		ds, err = newTestDatabaseStore(nil)
   264  		require.NoError(t, err)
   265  		defer ds.Close()
   266  
   267  		assert.Equal(t, "http://override", *ds.Get().ServiceSettings.SiteURL)
   268  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides())
   269  	})
   270  
   271  	t.Run("get override for a string variable with a custom default value", func(t *testing.T) {
   272  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   273  		defer tearDown()
   274  
   275  		ds, err := newTestDatabaseStore(customConfigDefaults)
   276  		require.NoError(t, err)
   277  		defer ds.Close()
   278  
   279  		assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL)
   280  		assert.Empty(t, ds.GetEnvironmentOverrides())
   281  
   282  		os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://override")
   283  		defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   284  
   285  		ds, err = newTestDatabaseStore(customConfigDefaults)
   286  		require.NoError(t, err)
   287  		defer ds.Close()
   288  
   289  		// environment override should take priority over the custom default value
   290  		assert.Equal(t, "http://override", *ds.Get().ServiceSettings.SiteURL)
   291  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides())
   292  	})
   293  
   294  	t.Run("get override for a bool variable", func(t *testing.T) {
   295  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   296  		defer tearDown()
   297  
   298  		ds, err := newTestDatabaseStore(nil)
   299  		require.NoError(t, err)
   300  		defer ds.Close()
   301  
   302  		assert.Equal(t, false, *ds.Get().PluginSettings.EnableUploads)
   303  		assert.Empty(t, ds.GetEnvironmentOverrides())
   304  
   305  		os.Setenv("MM_PLUGINSETTINGS_ENABLEUPLOADS", "true")
   306  		defer os.Unsetenv("MM_PLUGINSETTINGS_ENABLEUPLOADS")
   307  
   308  		ds, err = newTestDatabaseStore(nil)
   309  		require.NoError(t, err)
   310  		defer ds.Close()
   311  
   312  		assert.Equal(t, true, *ds.Get().PluginSettings.EnableUploads)
   313  		assert.Equal(t, map[string]interface{}{"PluginSettings": map[string]interface{}{"EnableUploads": true}}, ds.GetEnvironmentOverrides())
   314  	})
   315  
   316  	t.Run("get override for an int variable", func(t *testing.T) {
   317  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   318  		defer tearDown()
   319  
   320  		ds, err := newTestDatabaseStore(nil)
   321  		require.NoError(t, err)
   322  		defer ds.Close()
   323  
   324  		assert.Equal(t, model.TEAM_SETTINGS_DEFAULT_MAX_USERS_PER_TEAM, *ds.Get().TeamSettings.MaxUsersPerTeam)
   325  		assert.Empty(t, ds.GetEnvironmentOverrides())
   326  
   327  		os.Setenv("MM_TEAMSETTINGS_MAXUSERSPERTEAM", "3000")
   328  		defer os.Unsetenv("MM_TEAMSETTINGS_MAXUSERSPERTEAM")
   329  
   330  		ds, err = newTestDatabaseStore(nil)
   331  		require.NoError(t, err)
   332  		defer ds.Close()
   333  
   334  		assert.Equal(t, 3000, *ds.Get().TeamSettings.MaxUsersPerTeam)
   335  		assert.Equal(t, map[string]interface{}{"TeamSettings": map[string]interface{}{"MaxUsersPerTeam": true}}, ds.GetEnvironmentOverrides())
   336  	})
   337  
   338  	t.Run("get override for an int64 variable", func(t *testing.T) {
   339  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   340  		defer tearDown()
   341  
   342  		ds, err := newTestDatabaseStore(nil)
   343  		require.NoError(t, err)
   344  		defer ds.Close()
   345  
   346  		assert.Equal(t, int64(63072000), *ds.Get().ServiceSettings.TLSStrictTransportMaxAge)
   347  		assert.Empty(t, ds.GetEnvironmentOverrides())
   348  
   349  		os.Setenv("MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE", "123456")
   350  		defer os.Unsetenv("MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE")
   351  
   352  		ds, err = newTestDatabaseStore(nil)
   353  		require.NoError(t, err)
   354  		defer ds.Close()
   355  
   356  		assert.Equal(t, int64(123456), *ds.Get().ServiceSettings.TLSStrictTransportMaxAge)
   357  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"TLSStrictTransportMaxAge": true}}, ds.GetEnvironmentOverrides())
   358  	})
   359  
   360  	t.Run("get override for a slice variable - one value", func(t *testing.T) {
   361  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   362  		defer tearDown()
   363  
   364  		ds, err := newTestDatabaseStore(nil)
   365  		require.NoError(t, err)
   366  		defer ds.Close()
   367  
   368  		assert.Equal(t, []string{}, ds.Get().SqlSettings.DataSourceReplicas)
   369  		assert.Empty(t, ds.GetEnvironmentOverrides())
   370  
   371  		os.Setenv("MM_SQLSETTINGS_DATASOURCEREPLICAS", "user:pwd@db:5432/test-db")
   372  		defer os.Unsetenv("MM_SQLSETTINGS_DATASOURCEREPLICAS")
   373  
   374  		ds, err = newTestDatabaseStore(nil)
   375  		require.NoError(t, err)
   376  		defer ds.Close()
   377  
   378  		assert.Equal(t, []string{"user:pwd@db:5432/test-db"}, ds.Get().SqlSettings.DataSourceReplicas)
   379  		assert.Equal(t, map[string]interface{}{"SqlSettings": map[string]interface{}{"DataSourceReplicas": true}}, ds.GetEnvironmentOverrides())
   380  	})
   381  
   382  	t.Run("get override for a slice variable - three values", func(t *testing.T) {
   383  		// This should work, but Viper (or we) don't parse environment variables to turn strings with spaces into slices.
   384  		t.Skip("not implemented yet")
   385  
   386  		_, tearDown := setupConfigDatabase(t, testConfig, nil)
   387  		defer tearDown()
   388  
   389  		ds, err := newTestDatabaseStore(nil)
   390  		require.NoError(t, err)
   391  		defer ds.Close()
   392  
   393  		assert.Equal(t, []string{}, ds.Get().SqlSettings.DataSourceReplicas)
   394  		assert.Empty(t, ds.GetEnvironmentOverrides())
   395  
   396  		os.Setenv("MM_SQLSETTINGS_DATASOURCEREPLICAS", "user:pwd@db:5432/test-db user:pwd@db2:5433/test-db2 user:pwd@db3:5434/test-db3")
   397  		defer os.Unsetenv("MM_SQLSETTINGS_DATASOURCEREPLICAS")
   398  
   399  		ds, err = newTestDatabaseStore(nil)
   400  		require.NoError(t, err)
   401  		defer ds.Close()
   402  
   403  		assert.Equal(t, []string{"user:pwd@db:5432/test-db", "user:pwd@db2:5433/test-db2", "user:pwd@db3:5434/test-db3"}, ds.Get().SqlSettings.DataSourceReplicas)
   404  		assert.Equal(t, map[string]interface{}{"SqlSettings": map[string]interface{}{"DataSourceReplicas": true}}, ds.GetEnvironmentOverrides())
   405  	})
   406  }
   407  
   408  func TestDatabaseStoreSet(t *testing.T) {
   409  	if testing.Short() {
   410  		t.SkipNow()
   411  	}
   412  
   413  	t.Run("set same pointer value", func(t *testing.T) {
   414  		t.Skip("not yet implemented")
   415  
   416  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   417  		defer tearDown()
   418  
   419  		ds, err := newTestDatabaseStore(nil)
   420  		require.NoError(t, err)
   421  		defer ds.Close()
   422  
   423  		_, _, err = ds.Set(ds.Get())
   424  		if assert.Error(t, err) {
   425  			assert.EqualError(t, err, "old configuration modified instead of cloning")
   426  		}
   427  	})
   428  
   429  	t.Run("defaults required", func(t *testing.T) {
   430  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   431  		defer tearDown()
   432  
   433  		ds, err := newTestDatabaseStore(nil)
   434  		require.NoError(t, err)
   435  		defer ds.Close()
   436  
   437  		newCfg := &model.Config{}
   438  
   439  		_, _, err = ds.Set(newCfg)
   440  		require.NoError(t, err)
   441  
   442  		assert.Equal(t, "", *ds.Get().ServiceSettings.SiteURL)
   443  	})
   444  
   445  	t.Run("desanitization required", func(t *testing.T) {
   446  		_, tearDown := setupConfigDatabase(t, ldapConfig, nil)
   447  		defer tearDown()
   448  
   449  		ds, err := newTestDatabaseStore(nil)
   450  		require.NoError(t, err)
   451  		defer ds.Close()
   452  
   453  		newCfg := &model.Config{}
   454  		newCfg.LdapSettings.BindPassword = model.NewString(model.FAKE_SETTING)
   455  
   456  		_, _, err = ds.Set(newCfg)
   457  		require.NoError(t, err)
   458  
   459  		assert.Equal(t, "password", *ds.Get().LdapSettings.BindPassword)
   460  	})
   461  
   462  	t.Run("invalid", func(t *testing.T) {
   463  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   464  		defer tearDown()
   465  
   466  		ds, err := newTestDatabaseStore(nil)
   467  		require.NoError(t, err)
   468  		defer ds.Close()
   469  
   470  		newCfg := &model.Config{}
   471  		newCfg.ServiceSettings.SiteURL = model.NewString("invalid")
   472  
   473  		_, _, err = ds.Set(newCfg)
   474  		if assert.Error(t, err) {
   475  			assert.EqualError(t, err, "new configuration is invalid: Config.IsValid: model.config.is_valid.site_url.app_error, ")
   476  		}
   477  
   478  		assert.Equal(t, "", *ds.Get().ServiceSettings.SiteURL)
   479  	})
   480  
   481  	t.Run("duplicate ignored", func(t *testing.T) {
   482  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   483  		defer tearDown()
   484  
   485  		ds, err := newTestDatabaseStore(nil)
   486  		require.NoError(t, err)
   487  		defer ds.Close()
   488  
   489  		_, _, err = ds.Set(ds.Get())
   490  		require.NoError(t, err)
   491  
   492  		beforeID, _ := getActualDatabaseConfig(t)
   493  		_, _, err = ds.Set(ds.Get())
   494  		require.NoError(t, err)
   495  
   496  		afterID, _ := getActualDatabaseConfig(t)
   497  		assert.Equal(t, beforeID, afterID, "new record should not have been written")
   498  	})
   499  
   500  	t.Run("read-only ignored", func(t *testing.T) {
   501  		_, tearDown := setupConfigDatabase(t, readOnlyConfig, nil)
   502  		defer tearDown()
   503  
   504  		ds, err := newTestDatabaseStore(nil)
   505  		require.NoError(t, err)
   506  		defer ds.Close()
   507  
   508  		newCfg := &model.Config{
   509  			ServiceSettings: model.ServiceSettings{
   510  				SiteURL: model.NewString("http://new"),
   511  			},
   512  		}
   513  
   514  		_, _, err = ds.Set(newCfg)
   515  		require.NoError(t, err)
   516  
   517  		assert.Equal(t, "http://new", *ds.Get().ServiceSettings.SiteURL)
   518  	})
   519  
   520  	t.Run("set with automatic save", func(t *testing.T) {
   521  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   522  		defer tearDown()
   523  
   524  		ds, err := newTestDatabaseStore(nil)
   525  		require.NoError(t, err)
   526  		defer ds.Close()
   527  
   528  		newCfg := &model.Config{
   529  			ServiceSettings: model.ServiceSettings{
   530  				SiteURL: model.NewString("http://new"),
   531  			},
   532  		}
   533  
   534  		_, _, err = ds.Set(newCfg)
   535  		require.NoError(t, err)
   536  
   537  		err = ds.Load()
   538  		require.NoError(t, err)
   539  
   540  		assert.Equal(t, "http://new", *ds.Get().ServiceSettings.SiteURL)
   541  	})
   542  
   543  	t.Run("persist failed", func(t *testing.T) {
   544  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   545  		defer tearDown()
   546  
   547  		ds, err := newTestDatabaseStore(nil)
   548  		require.NoError(t, err)
   549  		defer ds.Close()
   550  
   551  		sqlSettings := mainHelper.GetSQLSettings()
   552  		db := sqlx.NewDb(mainHelper.GetSQLStore().GetMaster().Db, *sqlSettings.DriverName)
   553  		_, err = db.Exec("DROP TABLE Configurations")
   554  		require.NoError(t, err)
   555  
   556  		newCfg := minimalConfig
   557  
   558  		_, _, err = ds.Set(newCfg)
   559  		require.Error(t, err)
   560  		assert.True(t, strings.HasPrefix(err.Error(), "failed to persist: failed to query active configuration"), "unexpected error: "+err.Error())
   561  
   562  		assert.Equal(t, "", *ds.Get().ServiceSettings.SiteURL)
   563  	})
   564  
   565  	t.Run("persist failed: too long", func(t *testing.T) {
   566  		if *mainHelper.Settings.DriverName == "postgres" {
   567  			t.Skip("No limit for postgres")
   568  		}
   569  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   570  		defer tearDown()
   571  
   572  		ds, err := newTestDatabaseStore(nil)
   573  		require.NoError(t, err)
   574  		defer ds.Close()
   575  
   576  		longSiteURL := fmt.Sprintf("http://%s", strings.Repeat("a", MaxWriteLength))
   577  		newCfg := emptyConfig.Clone()
   578  		newCfg.ServiceSettings.SiteURL = model.NewString(longSiteURL)
   579  
   580  		_, _, err = ds.Set(newCfg)
   581  		require.Error(t, err)
   582  		assert.True(t, strings.HasPrefix(err.Error(), "failed to persist: marshalled configuration failed length check: value is too long"), "unexpected error: "+err.Error())
   583  	})
   584  
   585  	t.Run("listeners notified", func(t *testing.T) {
   586  		activeID, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   587  		defer tearDown()
   588  
   589  		ds, err := newTestDatabaseStore(nil)
   590  		require.NoError(t, err)
   591  		defer ds.Close()
   592  
   593  		called := make(chan bool, 1)
   594  		callback := func(oldfg, newCfg *model.Config) {
   595  			called <- true
   596  		}
   597  		ds.AddListener(callback)
   598  
   599  		newCfg := minimalConfig
   600  
   601  		_, _, err = ds.Set(newCfg)
   602  		require.NoError(t, err)
   603  
   604  		id, _ := getActualDatabaseConfig(t)
   605  		assert.NotEqual(t, activeID, id, "new record should have been written")
   606  
   607  		require.True(t, wasCalled(called, 5*time.Second), "callback should have been called when config written")
   608  	})
   609  
   610  	t.Run("setting config without persistent feature flag", func(t *testing.T) {
   611  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   612  		defer tearDown()
   613  
   614  		ds, err := newTestDatabaseStore(nil)
   615  		require.NoError(t, err)
   616  		defer ds.Close()
   617  
   618  		ds.SetReadOnlyFF(true)
   619  		_, _, err = ds.Set(minimalConfig)
   620  		require.NoError(t, err)
   621  
   622  		assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
   623  		assertDatabaseEqualsConfig(t, minimalConfigNoFF)
   624  	})
   625  
   626  	t.Run("setting config with persistent feature flags", func(t *testing.T) {
   627  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   628  		defer tearDown()
   629  
   630  		ds, err := newTestDatabaseStore(nil)
   631  		require.NoError(t, err)
   632  		defer ds.Close()
   633  
   634  		ds.SetReadOnlyFF(false)
   635  
   636  		_, _, err = ds.Set(minimalConfig)
   637  		require.NoError(t, err)
   638  
   639  		assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
   640  		assertDatabaseEqualsConfig(t, minimalConfig)
   641  	})
   642  
   643  }
   644  
   645  func TestDatabaseStoreLoad(t *testing.T) {
   646  	if testing.Short() {
   647  		t.SkipNow()
   648  	}
   649  
   650  	t.Run("active configuration no longer exists", func(t *testing.T) {
   651  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   652  		defer tearDown()
   653  
   654  		ds, err := newTestDatabaseStore(nil)
   655  		require.NoError(t, err)
   656  		defer ds.Close()
   657  
   658  		truncateTables(t)
   659  
   660  		err = ds.Load()
   661  		require.NoError(t, err)
   662  		assertDatabaseNotEqualsConfig(t, emptyConfig)
   663  	})
   664  
   665  	t.Run("honour environment", func(t *testing.T) {
   666  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   667  		defer tearDown()
   668  
   669  		ds, err := newTestDatabaseStore(nil)
   670  		require.NoError(t, err)
   671  		defer ds.Close()
   672  
   673  		assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL)
   674  
   675  		os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://override")
   676  		defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   677  
   678  		err = ds.Load()
   679  		require.NoError(t, err)
   680  		assert.Equal(t, "http://override", *ds.Get().ServiceSettings.SiteURL)
   681  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides())
   682  	})
   683  
   684  	t.Run("do not persist environment variables - string", func(t *testing.T) {
   685  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   686  		defer tearDown()
   687  
   688  		os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://overridePersistEnvVariables")
   689  		defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   690  
   691  		ds, err := newTestDatabaseStore(nil)
   692  		require.NoError(t, err)
   693  		defer ds.Close()
   694  
   695  		_, _, err = ds.Set(ds.Get())
   696  		require.NoError(t, err)
   697  
   698  		assert.Equal(t, "http://overridePersistEnvVariables", *ds.Get().ServiceSettings.SiteURL)
   699  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides())
   700  		// check that in DB config does not include overwritten variable
   701  		_, actualConfig := getActualDatabaseConfig(t)
   702  		assert.Equal(t, "http://minimal", *actualConfig.ServiceSettings.SiteURL)
   703  	})
   704  
   705  	t.Run("do not persist environment variables - boolean", func(t *testing.T) {
   706  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   707  		defer tearDown()
   708  
   709  		os.Setenv("MM_PLUGINSETTINGS_ENABLEUPLOADS", "true")
   710  		defer os.Unsetenv("MM_PLUGINSETTINGS_ENABLEUPLOADS")
   711  
   712  		ds, err := newTestDatabaseStore(nil)
   713  		require.NoError(t, err)
   714  		defer ds.Close()
   715  
   716  		assert.Equal(t, true, *ds.Get().PluginSettings.EnableUploads)
   717  
   718  		_, _, err = ds.Set(ds.Get())
   719  		require.NoError(t, err)
   720  
   721  		assert.Equal(t, true, *ds.Get().PluginSettings.EnableUploads)
   722  		assert.Equal(t, map[string]interface{}{"PluginSettings": map[string]interface{}{"EnableUploads": true}}, ds.GetEnvironmentOverrides())
   723  		// check that in DB config does not include overwritten variable
   724  		_, actualConfig := getActualDatabaseConfig(t)
   725  		assert.Equal(t, false, *actualConfig.PluginSettings.EnableUploads)
   726  	})
   727  
   728  	t.Run("do not persist environment variables - int", func(t *testing.T) {
   729  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   730  		defer tearDown()
   731  
   732  		os.Setenv("MM_TEAMSETTINGS_MAXUSERSPERTEAM", "3000")
   733  		defer os.Unsetenv("MM_TEAMSETTINGS_MAXUSERSPERTEAM")
   734  
   735  		ds, err := newTestDatabaseStore(nil)
   736  		require.NoError(t, err)
   737  		defer ds.Close()
   738  
   739  		assert.Equal(t, 3000, *ds.Get().TeamSettings.MaxUsersPerTeam)
   740  
   741  		_, _, err = ds.Set(ds.Get())
   742  		require.NoError(t, err)
   743  
   744  		assert.Equal(t, 3000, *ds.Get().TeamSettings.MaxUsersPerTeam)
   745  		assert.Equal(t, map[string]interface{}{"TeamSettings": map[string]interface{}{"MaxUsersPerTeam": true}}, ds.GetEnvironmentOverrides())
   746  		// check that in DB config does not include overwritten variable
   747  		_, actualConfig := getActualDatabaseConfig(t)
   748  		assert.Equal(t, model.TEAM_SETTINGS_DEFAULT_MAX_USERS_PER_TEAM, *actualConfig.TeamSettings.MaxUsersPerTeam)
   749  	})
   750  
   751  	t.Run("do not persist environment variables - int64", func(t *testing.T) {
   752  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   753  		defer tearDown()
   754  
   755  		os.Setenv("MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE", "123456")
   756  		defer os.Unsetenv("MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE")
   757  
   758  		ds, err := newTestDatabaseStore(nil)
   759  		require.NoError(t, err)
   760  		defer ds.Close()
   761  
   762  		assert.Equal(t, int64(123456), *ds.Get().ServiceSettings.TLSStrictTransportMaxAge)
   763  
   764  		_, _, err = ds.Set(ds.Get())
   765  		require.NoError(t, err)
   766  
   767  		assert.Equal(t, int64(123456), *ds.Get().ServiceSettings.TLSStrictTransportMaxAge)
   768  		assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"TLSStrictTransportMaxAge": true}}, ds.GetEnvironmentOverrides())
   769  		// check that in DB config does not include overwritten variable
   770  		_, actualConfig := getActualDatabaseConfig(t)
   771  		assert.Equal(t, int64(63072000), *actualConfig.ServiceSettings.TLSStrictTransportMaxAge)
   772  	})
   773  
   774  	t.Run("do not persist environment variables - string slice beginning with default", func(t *testing.T) {
   775  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   776  		defer tearDown()
   777  
   778  		os.Setenv("MM_SQLSETTINGS_DATASOURCEREPLICAS", "user:pwd@db:5432/test-db")
   779  		defer os.Unsetenv("MM_SQLSETTINGS_DATASOURCEREPLICAS")
   780  
   781  		ds, err := newTestDatabaseStore(nil)
   782  		require.NoError(t, err)
   783  		defer ds.Close()
   784  
   785  		assert.Equal(t, []string{"user:pwd@db:5432/test-db"}, ds.Get().SqlSettings.DataSourceReplicas)
   786  
   787  		_, _, err = ds.Set(ds.Get())
   788  		require.NoError(t, err)
   789  
   790  		assert.Equal(t, []string{"user:pwd@db:5432/test-db"}, ds.Get().SqlSettings.DataSourceReplicas)
   791  		assert.Equal(t, map[string]interface{}{"SqlSettings": map[string]interface{}{"DataSourceReplicas": true}}, ds.GetEnvironmentOverrides())
   792  		// check that in DB config does not include overwritten variable
   793  		_, actualConfig := getActualDatabaseConfig(t)
   794  		assert.Equal(t, []string{}, actualConfig.SqlSettings.DataSourceReplicas)
   795  	})
   796  
   797  	t.Run("do not persist environment variables - string slice beginning with slice of three", func(t *testing.T) {
   798  		modifiedMinimalConfig := minimalConfig.Clone()
   799  		modifiedMinimalConfig.SqlSettings.DataSourceReplicas = []string{"user:pwd@db:5432/test-db", "user:pwd@db2:5433/test-db2", "user:pwd@db3:5434/test-db3"}
   800  		_, tearDown := setupConfigDatabase(t, modifiedMinimalConfig, nil)
   801  		defer tearDown()
   802  
   803  		os.Setenv("MM_SQLSETTINGS_DATASOURCEREPLICAS", "user:pwd@db:5432/test-db")
   804  		defer os.Unsetenv("MM_SQLSETTINGS_DATASOURCEREPLICAS")
   805  
   806  		ds, err := newTestDatabaseStore(nil)
   807  		require.NoError(t, err)
   808  		defer ds.Close()
   809  
   810  		assert.Equal(t, []string{"user:pwd@db:5432/test-db"}, ds.Get().SqlSettings.DataSourceReplicas)
   811  
   812  		_, _, err = ds.Set(ds.Get())
   813  		require.NoError(t, err)
   814  
   815  		assert.Equal(t, []string{"user:pwd@db:5432/test-db"}, ds.Get().SqlSettings.DataSourceReplicas)
   816  		assert.Equal(t, map[string]interface{}{"SqlSettings": map[string]interface{}{"DataSourceReplicas": true}}, ds.GetEnvironmentOverrides())
   817  		// check that in DB config does not include overwritten variable
   818  		_, actualConfig := getActualDatabaseConfig(t)
   819  		assert.Equal(t, []string{"user:pwd@db:5432/test-db", "user:pwd@db2:5433/test-db2", "user:pwd@db3:5434/test-db3"}, actualConfig.SqlSettings.DataSourceReplicas)
   820  	})
   821  
   822  	t.Run("invalid", func(t *testing.T) {
   823  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   824  		defer tearDown()
   825  
   826  		ds, err := newTestDatabaseStore(nil)
   827  		require.NoError(t, err)
   828  		defer ds.Close()
   829  
   830  		cfgData, err := marshalConfig(invalidConfig)
   831  		require.NoError(t, err)
   832  
   833  		sqlSettings := mainHelper.GetSQLSettings()
   834  		db := sqlx.NewDb(mainHelper.GetSQLStore().GetMaster().Db, *sqlSettings.DriverName)
   835  		truncateTables(t)
   836  		id := model.NewId()
   837  		_, err = db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:Id, :Value, :CreateAt, TRUE)", map[string]interface{}{
   838  			"Id":       id,
   839  			"Value":    cfgData,
   840  			"CreateAt": model.GetMillis(),
   841  		})
   842  		require.NoError(t, err)
   843  
   844  		err = ds.Load()
   845  		if assert.Error(t, err) {
   846  			assert.EqualError(t, err, "invalid config: Config.IsValid: model.config.is_valid.site_url.app_error, ")
   847  		}
   848  	})
   849  
   850  	t.Run("fixes required", func(t *testing.T) {
   851  		_, tearDown := setupConfigDatabase(t, fixesRequiredConfig, nil)
   852  		defer tearDown()
   853  
   854  		ds, err := newTestDatabaseStore(nil)
   855  		require.NoError(t, err)
   856  		defer ds.Close()
   857  
   858  		err = ds.Load()
   859  		require.NoError(t, err)
   860  		assertDatabaseNotEqualsConfig(t, fixesRequiredConfig)
   861  		assert.Equal(t, "http://trailingslash", *ds.Get().ServiceSettings.SiteURL)
   862  	})
   863  
   864  	t.Run("listeners notifed on change", func(t *testing.T) {
   865  		_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
   866  		defer tearDown()
   867  
   868  		ds, err := newTestDatabaseStore(nil)
   869  		require.NoError(t, err)
   870  		defer ds.Close()
   871  
   872  		called := make(chan bool, 1)
   873  		callback := func(oldfg, newCfg *model.Config) {
   874  			called <- true
   875  		}
   876  		ds.AddListener(callback)
   877  		newCfg := minimalConfig.Clone()
   878  		dbStore, ok := ds.backingStore.(*DatabaseStore)
   879  		require.True(t, ok)
   880  		err = dbStore.persist(newCfg)
   881  		require.NoError(t, err)
   882  
   883  		err = ds.Load()
   884  		require.NoError(t, err)
   885  
   886  		require.True(t, wasCalled(called, 5*time.Second), "callback should have been called when config changed on load")
   887  	})
   888  }
   889  
   890  func TestDatabaseGetFile(t *testing.T) {
   891  	_, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{
   892  		"empty-file": {},
   893  		"test-file":  []byte("test"),
   894  	})
   895  	defer tearDown()
   896  
   897  	ds, err := newTestDatabaseStore(nil)
   898  	require.NoError(t, err)
   899  	defer ds.Close()
   900  
   901  	t.Run("get empty filename", func(t *testing.T) {
   902  		_, err := ds.GetFile("")
   903  		require.Error(t, err)
   904  	})
   905  
   906  	t.Run("get non-existent file", func(t *testing.T) {
   907  		_, err := ds.GetFile("unknown")
   908  		require.Error(t, err)
   909  	})
   910  
   911  	t.Run("get empty file", func(t *testing.T) {
   912  		data, err := ds.GetFile("empty-file")
   913  		require.NoError(t, err)
   914  		require.Empty(t, data)
   915  	})
   916  
   917  	t.Run("get non-empty file", func(t *testing.T) {
   918  		data, err := ds.GetFile("test-file")
   919  		require.NoError(t, err)
   920  		require.Equal(t, []byte("test"), data)
   921  	})
   922  }
   923  
   924  func TestDatabaseSetFile(t *testing.T) {
   925  	_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   926  	defer tearDown()
   927  
   928  	ds, err := newTestDatabaseStore(nil)
   929  	require.NoError(t, err)
   930  	defer ds.Close()
   931  
   932  	t.Run("set new file", func(t *testing.T) {
   933  		err := ds.SetFile("new", []byte("new file"))
   934  		require.NoError(t, err)
   935  
   936  		data, err := ds.GetFile("new")
   937  		require.NoError(t, err)
   938  		require.Equal(t, []byte("new file"), data)
   939  	})
   940  
   941  	t.Run("overwrite existing file", func(t *testing.T) {
   942  		err := ds.SetFile("existing", []byte("existing file"))
   943  		require.NoError(t, err)
   944  
   945  		err = ds.SetFile("existing", []byte("overwritten file"))
   946  		require.NoError(t, err)
   947  
   948  		data, err := ds.GetFile("existing")
   949  		require.NoError(t, err)
   950  		require.Equal(t, []byte("overwritten file"), data)
   951  	})
   952  
   953  	t.Run("max length", func(t *testing.T) {
   954  		if *mainHelper.Settings.DriverName == "postgres" {
   955  			t.Skip("No limit for postgres")
   956  		}
   957  		longFile := bytes.Repeat([]byte("a"), MaxWriteLength)
   958  
   959  		err := ds.SetFile("toolong", longFile)
   960  		require.NoError(t, err)
   961  	})
   962  
   963  	t.Run("too long", func(t *testing.T) {
   964  		if *mainHelper.Settings.DriverName == "postgres" {
   965  			t.Skip("No limit for postgres")
   966  		}
   967  		longFile := bytes.Repeat([]byte("a"), MaxWriteLength+1)
   968  
   969  		err := ds.SetFile("toolong", longFile)
   970  		if assert.Error(t, err) {
   971  			assert.True(t, strings.HasPrefix(err.Error(), "file data failed length check: value is too long"))
   972  		}
   973  	})
   974  }
   975  
   976  func TestDatabaseHasFile(t *testing.T) {
   977  	t.Run("has non-existent", func(t *testing.T) {
   978  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   979  		defer tearDown()
   980  
   981  		ds, err := newTestDatabaseStore(nil)
   982  		require.NoError(t, err)
   983  		defer ds.Close()
   984  
   985  		has, err := ds.HasFile("non-existent")
   986  		require.NoError(t, err)
   987  		require.False(t, has)
   988  	})
   989  
   990  	t.Run("has existing", func(t *testing.T) {
   991  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
   992  		defer tearDown()
   993  
   994  		ds, err := newTestDatabaseStore(nil)
   995  		require.NoError(t, err)
   996  		defer ds.Close()
   997  
   998  		err = ds.SetFile("existing", []byte("existing file"))
   999  		require.NoError(t, err)
  1000  
  1001  		has, err := ds.HasFile("existing")
  1002  		require.NoError(t, err)
  1003  		require.True(t, has)
  1004  	})
  1005  
  1006  	t.Run("has manually created file", func(t *testing.T) {
  1007  		_, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{
  1008  			"manual": []byte("manual file"),
  1009  		})
  1010  		defer tearDown()
  1011  
  1012  		ds, err := newTestDatabaseStore(nil)
  1013  		require.NoError(t, err)
  1014  		defer ds.Close()
  1015  
  1016  		has, err := ds.HasFile("manual")
  1017  		require.NoError(t, err)
  1018  		require.True(t, has)
  1019  	})
  1020  
  1021  	t.Run("has non-existent empty string", func(t *testing.T) {
  1022  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
  1023  		defer tearDown()
  1024  
  1025  		ds, err := newTestDatabaseStore(nil)
  1026  		require.NoError(t, err)
  1027  		defer ds.Close()
  1028  
  1029  		has, err := ds.HasFile("")
  1030  		require.NoError(t, err)
  1031  		require.False(t, has)
  1032  	})
  1033  }
  1034  
  1035  func TestDatabaseRemoveFile(t *testing.T) {
  1036  	t.Run("remove non-existent", func(t *testing.T) {
  1037  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
  1038  		defer tearDown()
  1039  
  1040  		ds, err := newTestDatabaseStore(nil)
  1041  		require.NoError(t, err)
  1042  		defer ds.Close()
  1043  
  1044  		err = ds.RemoveFile("non-existent")
  1045  		require.NoError(t, err)
  1046  	})
  1047  
  1048  	t.Run("remove existing", func(t *testing.T) {
  1049  		_, tearDown := setupConfigDatabase(t, minimalConfig, nil)
  1050  		defer tearDown()
  1051  
  1052  		ds, err := newTestDatabaseStore(nil)
  1053  		require.NoError(t, err)
  1054  		defer ds.Close()
  1055  
  1056  		err = ds.SetFile("existing", []byte("existing file"))
  1057  		require.NoError(t, err)
  1058  
  1059  		err = ds.RemoveFile("existing")
  1060  		require.NoError(t, err)
  1061  
  1062  		has, err := ds.HasFile("existing")
  1063  		require.NoError(t, err)
  1064  		require.False(t, has)
  1065  
  1066  		_, err = ds.GetFile("existing")
  1067  		require.Error(t, err)
  1068  	})
  1069  
  1070  	t.Run("remove manually created file", func(t *testing.T) {
  1071  		_, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{
  1072  			"manual": []byte("manual file"),
  1073  		})
  1074  		defer tearDown()
  1075  
  1076  		ds, err := newTestDatabaseStore(nil)
  1077  		require.NoError(t, err)
  1078  		defer ds.Close()
  1079  
  1080  		err = ds.RemoveFile("manual")
  1081  		require.NoError(t, err)
  1082  
  1083  		has, err := ds.HasFile("manual")
  1084  		require.NoError(t, err)
  1085  		require.False(t, has)
  1086  
  1087  		_, err = ds.GetFile("manual")
  1088  		require.Error(t, err)
  1089  	})
  1090  }
  1091  
  1092  func TestDatabaseStoreString(t *testing.T) {
  1093  	if testing.Short() {
  1094  		t.SkipNow()
  1095  	}
  1096  	_, tearDown := setupConfigDatabase(t, emptyConfig, nil)
  1097  	defer tearDown()
  1098  
  1099  	ds, err := newTestDatabaseStore(nil)
  1100  	require.NoError(t, err)
  1101  	require.NotNil(t, ds)
  1102  	defer ds.Close()
  1103  
  1104  	if *mainHelper.GetSQLSettings().DriverName == "postgres" {
  1105  		maskedDSN := ds.String()
  1106  		assert.True(t, strings.HasPrefix(maskedDSN, "postgres://"))
  1107  		assert.True(t, strings.Contains(maskedDSN, "hkuser"))
  1108  		assert.False(t, strings.Contains(maskedDSN, "mostest"))
  1109  	} else {
  1110  		maskedDSN := ds.String()
  1111  		assert.True(t, strings.HasPrefix(maskedDSN, "mysql://"))
  1112  		assert.True(t, strings.Contains(maskedDSN, "hkuser"))
  1113  		assert.False(t, strings.Contains(maskedDSN, "mostest"))
  1114  	}
  1115  }