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