2019-02-15 10:05:29 -04:00
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2019-11-29 12:59:40 +01:00
// See LICENSE.txt for license information.
2019-02-15 10:05:29 -04:00
2021-05-19 13:30:26 +02:00
package config
2019-02-15 10:05:29 -04:00
import (
"bytes"
2020-10-29 15:54:39 -07:00
"encoding/json"
2022-06-14 14:58:15 +05:30
"errors"
2019-02-15 10:05:29 -04:00
"fmt"
"os"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2023-06-11 10:54:35 +05:30
"github.com/mattermost/mattermost/server/public/model"
2019-02-15 10:05:29 -04:00
)
2020-02-06 15:15:18 +01:00
func getDsn ( driver string , source string ) string {
2021-07-12 20:05:36 +02:00
if driver == model . DatabaseDriverMysql {
2020-02-06 15:15:18 +01:00
return driver + "://" + source
}
return source
}
2019-03-06 15:06:45 -05:00
func setupConfigDatabase ( t * testing . T , cfg * model . Config , files map [ string ] [ ] byte ) ( string , func ( ) ) {
2020-03-02 17:13:39 +01:00
if testing . Short ( ) {
t . SkipNow ( )
}
2019-02-15 10:05:29 -04:00
t . Helper ( )
os . Clearenv ( )
truncateTables ( t )
2021-05-19 13:30:26 +02:00
cfgData , err := marshalConfig ( cfg )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2022-03-08 15:07:37 +03:00
ds := & DatabaseStore {
driverName : * mainHelper . GetSQLSettings ( ) . DriverName ,
db : mainHelper . GetSQLStore ( ) . GetMasterX ( ) . DB ,
dataSourceName : * mainHelper . Settings . DataSource ,
}
err = ds . initializeConfigurationsTable ( )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
id := model . NewId ( )
2022-07-05 09:46:50 +03:00
_ , err = ds . db . NamedExec ( "INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:Id, :Value, :CreateAt, TRUE)" , map [ string ] any {
2019-02-15 10:05:29 -04:00
"Id" : id ,
"Value" : cfgData ,
"CreateAt" : model . GetMillis ( ) ,
} )
require . NoError ( t , err )
2019-03-06 15:06:45 -05:00
for name , data := range files {
2022-07-05 09:46:50 +03:00
params := map [ string ] any {
2019-03-06 15:06:45 -05:00
"name" : name ,
"data" : data ,
"create_at" : model . GetMillis ( ) ,
"update_at" : model . GetMillis ( ) ,
}
2022-03-08 15:07:37 +03:00
_ , err = ds . db . NamedExec ( "INSERT INTO ConfigurationFiles (Name, Data, CreateAt, UpdateAt) VALUES (:name, :data, :create_at, :update_at)" , params )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
}
2019-02-15 10:05:29 -04:00
return id , func ( ) {
truncateTables ( t )
}
}
// getActualDatabaseConfig returns the active configuration in the database without relying on a config store.
2019-03-06 15:06:45 -05:00
func getActualDatabaseConfig ( t * testing . T ) ( string , * model . Config ) {
2019-02-15 10:05:29 -04:00
t . Helper ( )
2020-02-06 15:15:18 +01:00
if * mainHelper . GetSQLSettings ( ) . DriverName == "postgres" {
var actual struct {
ID string ` db:"id" `
Value [ ] byte ` db:"value" `
}
2022-03-15 19:49:19 +05:30
err := mainHelper . GetSQLStore ( ) . GetMasterX ( ) . Get ( & actual , "SELECT Id, Value FROM Configurations WHERE Active" )
2020-02-06 15:15:18 +01:00
require . NoError ( t , err )
2020-10-29 15:54:39 -07:00
var actualCfg * model . Config
err = json . Unmarshal ( actual . Value , & actualCfg )
2021-04-12 12:51:31 +02:00
require . NoError ( t , err )
2020-02-06 15:15:18 +01:00
return actual . ID , actualCfg
}
2019-03-06 15:06:45 -05:00
var actual struct {
2020-01-07 23:00:56 +07:00
ID string ` db:"Id" `
2019-03-06 15:06:45 -05:00
Value [ ] byte ` db:"Value" `
}
2022-03-15 19:49:19 +05:30
err := mainHelper . GetSQLStore ( ) . GetMasterX ( ) . Get ( & actual , "SELECT Id, Value FROM Configurations WHERE Active" )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2020-10-29 15:54:39 -07:00
var actualCfg * model . Config
err = json . Unmarshal ( actual . Value , & actualCfg )
2021-04-12 12:51:31 +02:00
require . NoError ( t , err )
2020-01-07 23:00:56 +07:00
return actual . ID , actualCfg
2019-02-15 10:05:29 -04:00
}
// assertDatabaseEqualsConfig verifies the active in-database configuration equals the given config.
func assertDatabaseEqualsConfig ( t * testing . T , expectedCfg * model . Config ) {
t . Helper ( )
2019-03-06 15:06:45 -05:00
_ , actualCfg := getActualDatabaseConfig ( t )
2019-02-15 10:05:29 -04:00
assert . Equal ( t , expectedCfg , actualCfg )
}
// assertDatabaseNotEqualsConfig verifies the in-database configuration does not equal the given config.
func assertDatabaseNotEqualsConfig ( t * testing . T , expectedCfg * model . Config ) {
t . Helper ( )
2019-03-06 15:06:45 -05:00
_ , actualCfg := getActualDatabaseConfig ( t )
2019-02-15 10:05:29 -04:00
assert . NotEqual ( t , expectedCfg , actualCfg )
}
2021-05-19 13:30:26 +02:00
func newTestDatabaseStore ( customDefaults * model . Config ) ( * Store , error ) {
2020-10-29 15:54:39 -07:00
sqlSettings := mainHelper . GetSQLSettings ( )
2021-05-19 13:30:26 +02:00
dss , err := NewDatabaseStore ( getDsn ( * sqlSettings . DriverName , * sqlSettings . DataSource ) )
2021-02-09 23:52:27 +06:00
if err != nil {
return nil , err
}
2020-10-29 15:54:39 -07:00
2021-05-19 13:30:26 +02:00
cStore , err := NewStoreFromBacking ( dss , customDefaults , false )
2021-02-09 23:52:27 +06:00
if err != nil {
return nil , err
}
2020-10-29 15:54:39 -07:00
return cStore , nil
}
2019-02-15 10:05:29 -04:00
func TestDatabaseStoreNew ( t * testing . T ) {
2020-03-02 17:13:39 +01:00
if testing . Short ( ) {
t . SkipNow ( )
}
2020-01-20 18:32:20 +07:00
sqlSettings := mainHelper . GetSQLSettings ( )
2019-02-19 19:50:11 +05:30
2019-02-15 10:05:29 -04:00
t . Run ( "no existing configuration - initialization required" , func ( t * testing . T ) {
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2019-06-06 20:57:01 +03:00
assert . Equal ( t , "" , * ds . Get ( ) . ServiceSettings . SiteURL )
2019-02-15 10:05:29 -04:00
} )
2020-11-16 15:25:48 +01:00
t . Run ( "no existing configuration with custom defaults" , func ( t * testing . T ) {
truncateTables ( t )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( customConfigDefaults )
2020-11-16 15:25:48 +01:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , * customConfigDefaults . ServiceSettings . SiteURL , * ds . Get ( ) . ServiceSettings . SiteURL )
} )
2019-02-15 10:05:29 -04:00
t . Run ( "existing config, initialization required" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , "http://TestStoreNew" , * ds . Get ( ) . ServiceSettings . SiteURL )
assertDatabaseNotEqualsConfig ( t , testConfig )
} )
2020-11-16 15:25:48 +01:00
t . Run ( "existing config with custom defaults, initialization required" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( customConfigDefaults )
2020-11-16 15:25:48 +01:00
require . NoError ( t , err )
defer ds . Close ( )
// already existing value should not be overwritten by the
// custom default value
assert . Equal ( t , "http://TestStoreNew" , * ds . Get ( ) . ServiceSettings . SiteURL )
// not existing value should be overwritten by the custom
// default value
assertDatabaseNotEqualsConfig ( t , testConfig )
} )
2019-02-15 10:05:29 -04:00
t . Run ( "already minimally configured" , func ( t * testing . T ) {
2021-02-03 21:03:09 +01:00
_ , tearDown := setupConfigDatabase ( t , minimalConfigNoFF , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , "http://minimal" , * ds . Get ( ) . ServiceSettings . SiteURL )
2021-02-03 21:03:09 +01:00
assertDatabaseEqualsConfig ( t , minimalConfigNoFF )
2019-02-15 10:05:29 -04:00
} )
2020-11-16 15:25:48 +01:00
t . Run ( "already minimally configured with custom defaults" , func ( t * testing . T ) {
2021-02-03 21:03:09 +01:00
_ , tearDown := setupConfigDatabase ( t , minimalConfigNoFF , nil )
2020-11-16 15:25:48 +01:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( customConfigDefaults )
2020-11-16 15:25:48 +01:00
require . NoError ( t , err )
defer ds . Close ( )
// as the whole config has default values already, custom
// defaults should have no effect
assert . Equal ( t , "http://minimal" , * ds . Get ( ) . ServiceSettings . SiteURL )
2021-02-03 21:03:09 +01:00
assertDatabaseEqualsConfig ( t , minimalConfigNoFF )
2020-11-16 15:25:48 +01:00
} )
2019-02-15 10:05:29 -04:00
t . Run ( "invalid url" , func ( t * testing . T ) {
2021-05-19 13:30:26 +02:00
_ , err := NewDatabaseStore ( "" )
2019-02-15 10:05:29 -04:00
require . Error ( t , err )
2020-03-04 00:42:17 +08:00
2021-05-19 13:30:26 +02:00
_ , err = NewDatabaseStore ( "mysql" )
2020-03-04 00:42:17 +08:00
require . Error ( t , err )
2019-02-15 10:05:29 -04:00
} )
t . Run ( "unsupported scheme" , func ( t * testing . T ) {
2021-05-19 13:30:26 +02:00
_ , err := NewDatabaseStore ( "invalid" )
2019-02-15 10:05:29 -04:00
require . Error ( t , err )
} )
2019-09-20 06:22:40 +02:00
t . Run ( "unsupported scheme with valid data source" , func ( t * testing . T ) {
2021-05-19 13:30:26 +02:00
_ , err := NewDatabaseStore ( fmt . Sprintf ( "invalid://%s" , * sqlSettings . DataSource ) )
2019-09-20 06:22:40 +02:00
require . Error ( t , err )
} )
2019-02-15 10:05:29 -04:00
}
func TestDatabaseStoreGet ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
cfg := ds . Get ( )
assert . Equal ( t , "http://TestStoreNew" , * cfg . ServiceSettings . SiteURL )
cfg2 := ds . Get ( )
assert . Equal ( t , "http://TestStoreNew" , * cfg . ServiceSettings . SiteURL )
assert . True ( t , cfg == cfg2 , "Get() returned different configuration instances" )
}
2022-02-28 04:31:00 -05:00
func TestDatabaseStoreGetEnvironmentOverrides ( t * testing . T ) {
2019-07-05 18:10:48 -04:00
t . Run ( "get override for a string variable" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2019-02-15 10:05:29 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2020-11-16 15:25:48 +01:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , "http://TestStoreNew" , * ds . Get ( ) . ServiceSettings . SiteURL )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_SERVICESETTINGS_SITEURL" , "http://override" )
defer os . Unsetenv ( "MM_SERVICESETTINGS_SITEURL" )
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2020-11-16 15:25:48 +01:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , "http://override" , * ds . Get ( ) . ServiceSettings . SiteURL )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "SiteURL" : true } } , ds . GetEnvironmentOverrides ( ) )
2020-11-16 15:25:48 +01:00
} )
t . Run ( "get override for a string variable with a custom default value" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( customConfigDefaults )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2019-02-15 10:05:29 -04:00
2019-07-05 18:10:48 -04:00
assert . Equal ( t , "http://TestStoreNew" , * ds . Get ( ) . ServiceSettings . SiteURL )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
2019-02-15 10:05:29 -04:00
2019-07-05 18:10:48 -04:00
os . Setenv ( "MM_SERVICESETTINGS_SITEURL" , "http://override" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SERVICESETTINGS_SITEURL" )
2019-02-15 10:05:29 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( customConfigDefaults )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2020-11-16 15:25:48 +01:00
// environment override should take priority over the custom default value
2019-07-05 18:10:48 -04:00
assert . Equal ( t , "http://override" , * ds . Get ( ) . ServiceSettings . SiteURL )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "SiteURL" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "get override for a bool variable" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , false , * ds . Get ( ) . PluginSettings . EnableUploads )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_PLUGINSETTINGS_ENABLEUPLOADS" , "true" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_PLUGINSETTINGS_ENABLEUPLOADS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , true , * ds . Get ( ) . PluginSettings . EnableUploads )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "PluginSettings" : map [ string ] any { "EnableUploads" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "get override for an int variable" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2021-07-12 20:05:36 +02:00
assert . Equal ( t , model . TeamSettingsDefaultMaxUsersPerTeam , * ds . Get ( ) . TeamSettings . MaxUsersPerTeam )
2019-07-05 18:10:48 -04:00
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_TEAMSETTINGS_MAXUSERSPERTEAM" , "3000" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_TEAMSETTINGS_MAXUSERSPERTEAM" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , 3000 , * ds . Get ( ) . TeamSettings . MaxUsersPerTeam )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "TeamSettings" : map [ string ] any { "MaxUsersPerTeam" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "get override for an int64 variable" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , int64 ( 63072000 ) , * ds . Get ( ) . ServiceSettings . TLSStrictTransportMaxAge )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE" , "123456" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , int64 ( 123456 ) , * ds . Get ( ) . ServiceSettings . TLSStrictTransportMaxAge )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "TLSStrictTransportMaxAge" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "get override for a slice variable - one value" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , [ ] string { } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" , "user:pwd@db:5432/test-db" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , [ ] string { "user:pwd@db:5432/test-db" } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "SqlSettings" : map [ string ] any { "DataSourceReplicas" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "get override for a slice variable - three values" , func ( t * testing . T ) {
// This should work, but Viper (or we) don't parse environment variables to turn strings with spaces into slices.
t . Skip ( "not implemented yet" )
_ , tearDown := setupConfigDatabase ( t , testConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2019-02-15 10:05:29 -04:00
2019-07-05 18:10:48 -04:00
assert . Equal ( t , [ ] string { } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
assert . Empty ( t , ds . GetEnvironmentOverrides ( ) )
os . Setenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" , "user:pwd@db:5432/test-db user:pwd@db2:5433/test-db2 user:pwd@db3:5434/test-db3" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err = newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
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 )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "SqlSettings" : map [ string ] any { "DataSourceReplicas" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
} )
2019-02-15 10:05:29 -04:00
}
func TestDatabaseStoreSet ( t * testing . T ) {
2020-03-02 17:13:39 +01:00
if testing . Short ( ) {
t . SkipNow ( )
}
2019-02-19 19:50:11 +05:30
2019-02-15 10:05:29 -04:00
t . Run ( "set same pointer value" , func ( t * testing . T ) {
t . Skip ( "not yet implemented" )
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-02-15 10:05:29 -04:00
if assert . Error ( t , err ) {
assert . EqualError ( t , err , "old configuration modified instead of cloning" )
}
} )
t . Run ( "defaults required" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
newCfg := & model . Config { }
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2019-06-06 20:57:01 +03:00
assert . Equal ( t , "" , * ds . Get ( ) . ServiceSettings . SiteURL )
2019-02-15 10:05:29 -04:00
} )
t . Run ( "desanitization required" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , ldapConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
newCfg := & model . Config { }
2021-07-12 20:05:36 +02:00
newCfg . LdapSettings . BindPassword = model . NewString ( model . FakeSetting )
2019-02-15 10:05:29 -04:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
assert . Equal ( t , "password" , * ds . Get ( ) . LdapSettings . BindPassword )
} )
t . Run ( "invalid" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
newCfg := & model . Config { }
2021-05-19 13:30:26 +02:00
newCfg . ServiceSettings . SiteURL = model . NewString ( "invalid" )
2019-02-15 10:05:29 -04:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-15 10:05:29 -04:00
if assert . Error ( t , err ) {
2022-04-13 22:20:46 +05:30
assert . EqualError ( t , err , "new configuration is invalid: Config.IsValid: model.config.is_valid.site_url.app_error, parse \"invalid\": invalid URI for request" )
2019-02-15 10:05:29 -04:00
}
2019-06-06 20:57:01 +03:00
assert . Equal ( t , "" , * ds . Get ( ) . ServiceSettings . SiteURL )
2019-02-15 10:05:29 -04:00
} )
2019-03-06 15:06:45 -05:00
t . Run ( "duplicate ignored" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
2020-01-07 23:00:56 +07:00
beforeID , _ := getActualDatabaseConfig ( t )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
2020-01-07 23:00:56 +07:00
afterID , _ := getActualDatabaseConfig ( t )
assert . Equal ( t , beforeID , afterID , "new record should not have been written" )
2019-03-06 15:06:45 -05:00
} )
2019-02-15 10:05:29 -04:00
t . Run ( "read-only ignored" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , readOnlyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
newCfg := & model . Config {
ServiceSettings : model . ServiceSettings {
2021-05-19 13:30:26 +02:00
SiteURL : model . NewString ( "http://new" ) ,
2019-02-15 10:05:29 -04:00
} ,
}
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
assert . Equal ( t , "http://new" , * ds . Get ( ) . ServiceSettings . SiteURL )
} )
2019-02-28 10:51:42 -05:00
t . Run ( "set with automatic save" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
2019-02-28 10:51:42 -05:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-28 10:51:42 -05:00
require . NoError ( t , err )
defer ds . Close ( )
newCfg := & model . Config {
ServiceSettings : model . ServiceSettings {
2021-05-19 13:30:26 +02:00
SiteURL : model . NewString ( "http://new" ) ,
2019-02-28 10:51:42 -05:00
} ,
}
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-28 10:51:42 -05:00
require . NoError ( t , err )
err = ds . Load ( )
require . NoError ( t , err )
assert . Equal ( t , "http://new" , * ds . Get ( ) . ServiceSettings . SiteURL )
} )
2019-02-15 10:05:29 -04:00
t . Run ( "persist failed" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2022-03-15 19:49:19 +05:30
_ , err = mainHelper . GetSQLStore ( ) . GetMasterX ( ) . Exec ( "DROP TABLE Configurations" )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2021-05-19 13:30:26 +02:00
newCfg := minimalConfig
2019-02-15 10:05:29 -04:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-09-27 09:10:38 -03:00
require . Error ( t , err )
assert . True ( t , strings . HasPrefix ( err . Error ( ) , "failed to persist: failed to query active configuration" ) , "unexpected error: " + err . Error ( ) )
2019-02-15 10:05:29 -04:00
2019-06-06 20:57:01 +03:00
assert . Equal ( t , "" , * ds . Get ( ) . ServiceSettings . SiteURL )
2019-02-15 10:05:29 -04:00
} )
2019-09-27 09:10:38 -03:00
t . Run ( "persist failed: too long" , func ( t * testing . T ) {
2020-02-06 15:15:18 +01:00
if * mainHelper . Settings . DriverName == "postgres" {
t . Skip ( "No limit for postgres" )
}
2019-09-27 09:10:38 -03:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-09-27 09:10:38 -03:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-19 13:30:26 +02:00
longSiteURL := fmt . Sprintf ( "http://%s" , strings . Repeat ( "a" , MaxWriteLength ) )
2019-09-27 09:10:38 -03:00
newCfg := emptyConfig . Clone ( )
2021-05-19 13:30:26 +02:00
newCfg . ServiceSettings . SiteURL = model . NewString ( longSiteURL )
2019-09-27 09:10:38 -03:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-09-27 09:10:38 -03:00
require . Error ( t , err )
assert . True ( t , strings . HasPrefix ( err . Error ( ) , "failed to persist: marshalled configuration failed length check: value is too long" ) , "unexpected error: " + err . Error ( ) )
} )
2019-02-15 10:05:29 -04:00
t . Run ( "listeners notified" , func ( t * testing . T ) {
2020-01-07 23:00:56 +07:00
activeID , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
called := make ( chan bool , 1 )
callback := func ( oldfg , newCfg * model . Config ) {
called <- true
}
ds . AddListener ( callback )
2021-05-19 13:30:26 +02:00
newCfg := minimalConfig
2019-02-15 10:05:29 -04:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( newCfg )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2019-03-06 15:06:45 -05:00
id , _ := getActualDatabaseConfig ( t )
2020-01-07 23:00:56 +07:00
assert . NotEqual ( t , activeID , id , "new record should have been written" )
2019-03-06 15:06:45 -05:00
2019-11-13 13:41:26 +05:30
require . True ( t , wasCalled ( called , 5 * time . Second ) , "callback should have been called when config written" )
2019-02-15 10:05:29 -04:00
} )
2021-02-03 21:03:09 +01:00
t . Run ( "setting config without persistent feature flag" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2021-02-03 21:03:09 +01:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-19 13:30:26 +02:00
ds . SetReadOnlyFF ( true )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( minimalConfig )
2021-02-03 21:03:09 +01:00
require . NoError ( t , err )
assert . Equal ( t , "http://minimal" , * ds . Get ( ) . ServiceSettings . SiteURL )
assertDatabaseEqualsConfig ( t , minimalConfigNoFF )
} )
t . Run ( "setting config with persistent feature flags" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2021-02-03 21:03:09 +01:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-19 13:30:26 +02:00
ds . SetReadOnlyFF ( false )
2021-02-03 21:03:09 +01:00
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( minimalConfig )
2021-02-03 21:03:09 +01:00
require . NoError ( t , err )
assert . Equal ( t , "http://minimal" , * ds . Get ( ) . ServiceSettings . SiteURL )
assertDatabaseEqualsConfig ( t , minimalConfig )
} )
2019-02-15 10:05:29 -04:00
}
func TestDatabaseStoreLoad ( t * testing . T ) {
2020-03-02 17:13:39 +01:00
if testing . Short ( ) {
t . SkipNow ( )
}
2019-02-19 19:50:11 +05:30
2019-02-15 10:05:29 -04:00
t . Run ( "active configuration no longer exists" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
truncateTables ( t )
err = ds . Load ( )
require . NoError ( t , err )
assertDatabaseNotEqualsConfig ( t , emptyConfig )
} )
t . Run ( "honour environment" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2019-03-26 16:28:41 -04:00
assert . Equal ( t , "http://minimal" , * ds . Get ( ) . ServiceSettings . SiteURL )
2019-02-15 10:05:29 -04:00
os . Setenv ( "MM_SERVICESETTINGS_SITEURL" , "http://override" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SERVICESETTINGS_SITEURL" )
2019-02-15 10:05:29 -04:00
err = ds . Load ( )
require . NoError ( t , err )
assert . Equal ( t , "http://override" , * ds . Get ( ) . ServiceSettings . SiteURL )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "SiteURL" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-02-15 10:05:29 -04:00
} )
2019-07-05 18:10:48 -04:00
t . Run ( "do not persist environment variables - string" , func ( t * testing . T ) {
2019-03-26 16:28:41 -04:00
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_SERVICESETTINGS_SITEURL" , "http://overridePersistEnvVariables" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SERVICESETTINGS_SITEURL" )
2019-03-26 16:28:41 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-26 16:28:41 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-03-26 16:28:41 -04:00
require . NoError ( t , err )
assert . Equal ( t , "http://overridePersistEnvVariables" , * ds . Get ( ) . ServiceSettings . SiteURL )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "SiteURL" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-03-26 16:28:41 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
assert . Equal ( t , "http://minimal" , * actualConfig . ServiceSettings . SiteURL )
} )
2019-07-05 18:10:48 -04:00
t . Run ( "do not persist environment variables - boolean" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_PLUGINSETTINGS_ENABLEUPLOADS" , "true" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_PLUGINSETTINGS_ENABLEUPLOADS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , true , * ds . Get ( ) . PluginSettings . EnableUploads )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
assert . Equal ( t , true , * ds . Get ( ) . PluginSettings . EnableUploads )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "PluginSettings" : map [ string ] any { "EnableUploads" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
assert . Equal ( t , false , * actualConfig . PluginSettings . EnableUploads )
} )
t . Run ( "do not persist environment variables - int" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_TEAMSETTINGS_MAXUSERSPERTEAM" , "3000" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_TEAMSETTINGS_MAXUSERSPERTEAM" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , 3000 , * ds . Get ( ) . TeamSettings . MaxUsersPerTeam )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
assert . Equal ( t , 3000 , * ds . Get ( ) . TeamSettings . MaxUsersPerTeam )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "TeamSettings" : map [ string ] any { "MaxUsersPerTeam" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
2021-07-12 20:05:36 +02:00
assert . Equal ( t , model . TeamSettingsDefaultMaxUsersPerTeam , * actualConfig . TeamSettings . MaxUsersPerTeam )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "do not persist environment variables - int64" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE" , "123456" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SERVICESETTINGS_TLSSTRICTTRANSPORTMAXAGE" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , int64 ( 123456 ) , * ds . Get ( ) . ServiceSettings . TLSStrictTransportMaxAge )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
assert . Equal ( t , int64 ( 123456 ) , * ds . Get ( ) . ServiceSettings . TLSStrictTransportMaxAge )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "ServiceSettings" : map [ string ] any { "TLSStrictTransportMaxAge" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
assert . Equal ( t , int64 ( 63072000 ) , * actualConfig . ServiceSettings . TLSStrictTransportMaxAge )
} )
t . Run ( "do not persist environment variables - string slice beginning with default" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" , "user:pwd@db:5432/test-db" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , [ ] string { "user:pwd@db:5432/test-db" } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
assert . Equal ( t , [ ] string { "user:pwd@db:5432/test-db" } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "SqlSettings" : map [ string ] any { "DataSourceReplicas" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
2020-04-30 02:36:09 +05:30
assert . Equal ( t , [ ] string { } , actualConfig . SqlSettings . DataSourceReplicas )
2019-07-05 18:10:48 -04:00
} )
t . Run ( "do not persist environment variables - string slice beginning with slice of three" , func ( t * testing . T ) {
modifiedMinimalConfig := minimalConfig . Clone ( )
modifiedMinimalConfig . SqlSettings . DataSourceReplicas = [ ] string { "user:pwd@db:5432/test-db" , "user:pwd@db2:5433/test-db2" , "user:pwd@db3:5434/test-db3" }
_ , tearDown := setupConfigDatabase ( t , modifiedMinimalConfig , nil )
defer tearDown ( )
os . Setenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" , "user:pwd@db:5432/test-db" )
2019-08-09 11:33:59 -04:00
defer os . Unsetenv ( "MM_SQLSETTINGS_DATASOURCEREPLICAS" )
2019-07-05 18:10:48 -04:00
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
defer ds . Close ( )
assert . Equal ( t , [ ] string { "user:pwd@db:5432/test-db" } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
2021-05-21 09:04:39 +02:00
_ , _ , err = ds . Set ( ds . Get ( ) )
2019-07-05 18:10:48 -04:00
require . NoError ( t , err )
assert . Equal ( t , [ ] string { "user:pwd@db:5432/test-db" } , ds . Get ( ) . SqlSettings . DataSourceReplicas )
2022-07-05 09:46:50 +03:00
assert . Equal ( t , map [ string ] any { "SqlSettings" : map [ string ] any { "DataSourceReplicas" : true } } , ds . GetEnvironmentOverrides ( ) )
2019-07-05 18:10:48 -04:00
// check that in DB config does not include overwritten variable
_ , actualConfig := getActualDatabaseConfig ( t )
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 )
} )
2019-02-15 10:05:29 -04:00
t . Run ( "invalid" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
2021-05-19 13:30:26 +02:00
cfgData , err := marshalConfig ( invalidConfig )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
truncateTables ( t )
id := model . NewId ( )
2022-07-05 09:46:50 +03:00
_ , err = mainHelper . GetSQLStore ( ) . GetMasterX ( ) . NamedExec ( "INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:id, :value, :createat, TRUE)" , map [ string ] any {
2022-03-15 19:49:19 +05:30
"id" : id ,
"value" : cfgData ,
"createat" : model . GetMillis ( ) ,
2019-02-15 10:05:29 -04:00
} )
2022-03-15 19:49:19 +05:30
t . Logf ( "%v\n" , err )
require . NoErrorf ( t , err , "what is - %v" , err )
2019-02-15 10:05:29 -04:00
err = ds . Load ( )
if assert . Error ( t , err ) {
2022-06-14 14:58:15 +05:30
var appErr * model . AppError
require . True ( t , errors . As ( err , & appErr ) )
assert . Equal ( t , appErr . Id , "model.config.is_valid.site_url.app_error" )
2019-02-15 10:05:29 -04:00
}
} )
t . Run ( "fixes required" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , fixesRequiredConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
err = ds . Load ( )
require . NoError ( t , err )
assertDatabaseNotEqualsConfig ( t , fixesRequiredConfig )
assert . Equal ( t , "http://trailingslash" , * ds . Get ( ) . ServiceSettings . SiteURL )
} )
2022-02-28 04:31:00 -05:00
t . Run ( "listeners notified on change" , func ( t * testing . T ) {
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
defer ds . Close ( )
called := make ( chan bool , 1 )
callback := func ( oldfg , newCfg * model . Config ) {
called <- true
}
ds . AddListener ( callback )
2021-05-19 13:30:26 +02:00
newCfg := minimalConfig . Clone ( )
dbStore , ok := ds . backingStore . ( * DatabaseStore )
require . True ( t , ok )
err = dbStore . persist ( newCfg )
require . NoError ( t , err )
2019-02-15 10:05:29 -04:00
err = ds . Load ( )
require . NoError ( t , err )
2021-05-19 13:30:26 +02:00
require . True ( t , wasCalled ( called , 5 * time . Second ) , "callback should have been called when config changed on load" )
2019-02-15 10:05:29 -04:00
} )
}
2019-03-06 15:06:45 -05:00
func TestDatabaseGetFile ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , map [ string ] [ ] byte {
2019-10-28 14:08:08 +01:00
"empty-file" : { } ,
2019-03-06 15:06:45 -05:00
"test-file" : [ ] byte ( "test" ) ,
} )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
t . Run ( "get empty filename" , func ( t * testing . T ) {
_ , err := ds . GetFile ( "" )
require . Error ( t , err )
} )
t . Run ( "get non-existent file" , func ( t * testing . T ) {
_ , err := ds . GetFile ( "unknown" )
require . Error ( t , err )
} )
t . Run ( "get empty file" , func ( t * testing . T ) {
data , err := ds . GetFile ( "empty-file" )
require . NoError ( t , err )
require . Empty ( t , data )
} )
t . Run ( "get non-empty file" , func ( t * testing . T ) {
data , err := ds . GetFile ( "test-file" )
require . NoError ( t , err )
require . Equal ( t , [ ] byte ( "test" ) , data )
} )
}
func TestDatabaseSetFile ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
t . Run ( "set new file" , func ( t * testing . T ) {
err := ds . SetFile ( "new" , [ ] byte ( "new file" ) )
require . NoError ( t , err )
data , err := ds . GetFile ( "new" )
require . NoError ( t , err )
require . Equal ( t , [ ] byte ( "new file" ) , data )
} )
t . Run ( "overwrite existing file" , func ( t * testing . T ) {
err := ds . SetFile ( "existing" , [ ] byte ( "existing file" ) )
require . NoError ( t , err )
err = ds . SetFile ( "existing" , [ ] byte ( "overwritten file" ) )
require . NoError ( t , err )
data , err := ds . GetFile ( "existing" )
require . NoError ( t , err )
require . Equal ( t , [ ] byte ( "overwritten file" ) , data )
} )
2019-09-27 09:10:38 -03:00
t . Run ( "max length" , func ( t * testing . T ) {
2020-02-06 15:15:18 +01:00
if * mainHelper . Settings . DriverName == "postgres" {
t . Skip ( "No limit for postgres" )
}
2021-05-19 13:30:26 +02:00
longFile := bytes . Repeat ( [ ] byte ( "a" ) , MaxWriteLength )
2019-09-27 09:10:38 -03:00
err := ds . SetFile ( "toolong" , longFile )
require . NoError ( t , err )
} )
t . Run ( "too long" , func ( t * testing . T ) {
2020-02-06 15:15:18 +01:00
if * mainHelper . Settings . DriverName == "postgres" {
t . Skip ( "No limit for postgres" )
}
2021-05-19 13:30:26 +02:00
longFile := bytes . Repeat ( [ ] byte ( "a" ) , MaxWriteLength + 1 )
2019-09-27 09:10:38 -03:00
err := ds . SetFile ( "toolong" , longFile )
if assert . Error ( t , err ) {
assert . True ( t , strings . HasPrefix ( err . Error ( ) , "file data failed length check: value is too long" ) )
}
} )
2019-03-06 15:06:45 -05:00
}
func TestDatabaseHasFile ( t * testing . T ) {
t . Run ( "has non-existent" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
has , err := ds . HasFile ( "non-existent" )
require . NoError ( t , err )
require . False ( t , has )
} )
t . Run ( "has existing" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
err = ds . SetFile ( "existing" , [ ] byte ( "existing file" ) )
require . NoError ( t , err )
has , err := ds . HasFile ( "existing" )
require . NoError ( t , err )
require . True ( t , has )
} )
t . Run ( "has manually created file" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , map [ string ] [ ] byte {
"manual" : [ ] byte ( "manual file" ) ,
} )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
has , err := ds . HasFile ( "manual" )
require . NoError ( t , err )
require . True ( t , has )
} )
2019-06-05 17:51:59 -04:00
t . Run ( "has non-existent empty string" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-06-05 17:51:59 -04:00
require . NoError ( t , err )
defer ds . Close ( )
has , err := ds . HasFile ( "" )
require . NoError ( t , err )
require . False ( t , has )
} )
2019-03-06 15:06:45 -05:00
}
func TestDatabaseRemoveFile ( t * testing . T ) {
t . Run ( "remove non-existent" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
err = ds . RemoveFile ( "non-existent" )
require . NoError ( t , err )
} )
t . Run ( "remove existing" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , nil )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
err = ds . SetFile ( "existing" , [ ] byte ( "existing file" ) )
require . NoError ( t , err )
err = ds . RemoveFile ( "existing" )
require . NoError ( t , err )
has , err := ds . HasFile ( "existing" )
require . NoError ( t , err )
require . False ( t , has )
_ , err = ds . GetFile ( "existing" )
require . Error ( t , err )
} )
t . Run ( "remove manually created file" , func ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , minimalConfig , map [ string ] [ ] byte {
"manual" : [ ] byte ( "manual file" ) ,
} )
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-03-06 15:06:45 -05:00
require . NoError ( t , err )
defer ds . Close ( )
err = ds . RemoveFile ( "manual" )
require . NoError ( t , err )
has , err := ds . HasFile ( "manual" )
require . NoError ( t , err )
require . False ( t , has )
_ , err = ds . GetFile ( "manual" )
require . Error ( t , err )
} )
}
2019-02-15 10:05:29 -04:00
func TestDatabaseStoreString ( t * testing . T ) {
2020-03-02 17:13:39 +01:00
if testing . Short ( ) {
t . SkipNow ( )
}
2019-03-06 15:06:45 -05:00
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
2019-02-15 10:05:29 -04:00
defer tearDown ( )
2021-02-09 23:52:27 +06:00
ds , err := newTestDatabaseStore ( nil )
2019-02-15 10:05:29 -04:00
require . NoError ( t , err )
2019-09-20 06:22:40 +02:00
require . NotNil ( t , ds )
2019-02-15 10:05:29 -04:00
defer ds . Close ( )
2020-02-06 15:15:18 +01:00
if * mainHelper . GetSQLSettings ( ) . DriverName == "postgres" {
maskedDSN := ds . String ( )
assert . True ( t , strings . HasPrefix ( maskedDSN , "postgres://" ) )
2023-04-03 23:41:51 +05:30
assert . False ( t , strings . Contains ( maskedDSN , "mmuser" ) )
2020-02-06 15:15:18 +01:00
assert . False ( t , strings . Contains ( maskedDSN , "mostest" ) )
} else {
maskedDSN := ds . String ( )
2023-04-03 23:41:51 +05:30
assert . False ( t , strings . HasPrefix ( maskedDSN , "mysql://" ) )
assert . False ( t , strings . Contains ( maskedDSN , "mmuser" ) )
2020-02-06 15:15:18 +01:00
assert . False ( t , strings . Contains ( maskedDSN , "mostest" ) )
}
2019-02-15 10:05:29 -04:00
}
2022-04-15 10:31:10 +03:00
func TestCleanUp ( t * testing . T ) {
_ , tearDown := setupConfigDatabase ( t , emptyConfig , nil )
defer tearDown ( )
ds , err := newTestDatabaseStore ( nil )
require . NoError ( t , err )
require . NotNil ( t , ds )
defer ds . Close ( )
dbs , ok := ds . backingStore . ( * DatabaseStore )
require . True ( t , ok , "should be a DatabaseStore instance" )
b , err := marshalConfig ( ds . config )
require . NoError ( t , err )
ds . config . JobSettings . CleanupConfigThresholdDays = model . NewInt ( 30 ) // we set 30 days as threshold
now := time . Now ( )
for i := 0 ; i < 5 ; i ++ {
// 20 days, we expect to remove at least 3 configuration values from the store
// first 2 (0 and 1) will be within a month constraint, others will be older than
// a month hence we expect 3 configurations to be removed from the database.
m := - 1 * i * 24 * 20
2022-07-05 09:46:50 +03:00
params := map [ string ] any {
2022-04-15 10:31:10 +03:00
"id" : model . NewId ( ) ,
"value" : string ( b ) ,
"create_at" : model . GetMillisForTime ( now . Add ( time . Duration ( m ) * time . Hour ) ) ,
}
_ , err = dbs . db . NamedExec ( "INSERT INTO Configurations (Id, Value, CreateAt) VALUES (:id, :value, :create_at)" , params )
require . NoError ( t , err )
}
var initialCount int
row := dbs . db . QueryRow ( "SELECT COUNT(*) FROM Configurations" )
err = row . Scan ( & initialCount )
require . NoError ( t , err )
err = ds . CleanUp ( )
require . NoError ( t , err )
var count int
row = dbs . db . QueryRow ( "SELECT COUNT(*) FROM Configurations" )
err = row . Scan ( & count )
require . NoError ( t , err )
require . True ( t , count + 3 == initialCount )
}