github.com/isacikgoz/mattermost-server@v5.11.1+incompatible/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 "fmt" 9 "net/url" 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/config" 20 "github.com/mattermost/mattermost-server/model" 21 ) 22 23 func setupConfigDatabase(t *testing.T, cfg *model.Config, files map[string][]byte) (string, func()) { 24 t.Helper() 25 os.Clearenv() 26 truncateTables(t) 27 28 cfgData, err := config.MarshalConfig(cfg) 29 require.NoError(t, err) 30 31 db := sqlx.NewDb(mainHelper.GetSqlSupplier().GetMaster().Db, *mainHelper.GetSqlSettings().DriverName) 32 err = config.InitializeConfigurationsTable(db) 33 require.NoError(t, err) 34 35 id := model.NewId() 36 _, err = db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:Id, :Value, :CreateAt, TRUE)", map[string]interface{}{ 37 "Id": id, 38 "Value": cfgData, 39 "CreateAt": model.GetMillis(), 40 }) 41 require.NoError(t, err) 42 43 for name, data := range files { 44 params := map[string]interface{}{ 45 "name": name, 46 "data": data, 47 "create_at": model.GetMillis(), 48 "update_at": model.GetMillis(), 49 } 50 51 _, err = db.NamedExec("INSERT INTO ConfigurationFiles (Name, Data, CreateAt, UpdateAt) VALUES (:name, :data, :create_at, :update_at)", params) 52 require.NoError(t, err) 53 } 54 55 return id, func() { 56 truncateTables(t) 57 } 58 } 59 60 // getActualDatabaseConfig returns the active configuration in the database without relying on a config store. 61 func getActualDatabaseConfig(t *testing.T) (string, *model.Config) { 62 t.Helper() 63 64 var actual struct { 65 Id string `db:"Id"` 66 Value []byte `db:"Value"` 67 } 68 db := sqlx.NewDb(mainHelper.GetSqlSupplier().GetMaster().Db, *mainHelper.GetSqlSettings().DriverName) 69 err := db.Get(&actual, "SELECT Id, Value FROM Configurations WHERE Active") 70 require.NoError(t, err) 71 72 actualCfg, _, err := config.UnmarshalConfig(bytes.NewReader(actual.Value), false) 73 require.Nil(t, err) 74 75 return actual.Id, actualCfg 76 } 77 78 // assertDatabaseEqualsConfig verifies the active in-database configuration equals the given config. 79 func assertDatabaseEqualsConfig(t *testing.T, expectedCfg *model.Config) { 80 t.Helper() 81 82 expectedCfg = prepareExpectedConfig(t, expectedCfg) 83 _, actualCfg := getActualDatabaseConfig(t) 84 assert.Equal(t, expectedCfg, actualCfg) 85 } 86 87 // assertDatabaseNotEqualsConfig verifies the in-database configuration does not equal the given config. 88 func assertDatabaseNotEqualsConfig(t *testing.T, expectedCfg *model.Config) { 89 t.Helper() 90 91 expectedCfg = prepareExpectedConfig(t, expectedCfg) 92 _, actualCfg := getActualDatabaseConfig(t) 93 assert.NotEqual(t, expectedCfg, actualCfg) 94 } 95 96 func TestDatabaseStoreNew(t *testing.T) { 97 sqlSettings := mainHelper.GetSqlSettings() 98 99 t.Run("no existing configuration - initialization required", func(t *testing.T) { 100 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 101 require.NoError(t, err) 102 defer ds.Close() 103 104 assert.Equal(t, model.SERVICE_SETTINGS_DEFAULT_SITE_URL, *ds.Get().ServiceSettings.SiteURL) 105 }) 106 107 t.Run("existing config, initialization required", func(t *testing.T) { 108 _, tearDown := setupConfigDatabase(t, testConfig, nil) 109 defer tearDown() 110 111 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 112 require.NoError(t, err) 113 defer ds.Close() 114 115 assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL) 116 assertDatabaseNotEqualsConfig(t, testConfig) 117 }) 118 119 t.Run("already minimally configured", func(t *testing.T) { 120 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 121 defer tearDown() 122 123 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 124 require.NoError(t, err) 125 defer ds.Close() 126 127 assert.Equal(t, "http://minimal", *ds.Get().ServiceSettings.SiteURL) 128 assertDatabaseEqualsConfig(t, minimalConfig) 129 }) 130 131 t.Run("invalid url", func(t *testing.T) { 132 _, err := config.NewDatabaseStore("") 133 require.Error(t, err) 134 }) 135 136 t.Run("unsupported scheme", func(t *testing.T) { 137 _, err := config.NewDatabaseStore("invalid") 138 require.Error(t, err) 139 }) 140 } 141 142 func TestDatabaseStoreGet(t *testing.T) { 143 _, tearDown := setupConfigDatabase(t, testConfig, nil) 144 defer tearDown() 145 146 sqlSettings := mainHelper.GetSqlSettings() 147 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 148 require.NoError(t, err) 149 defer ds.Close() 150 151 cfg := ds.Get() 152 assert.Equal(t, "http://TestStoreNew", *cfg.ServiceSettings.SiteURL) 153 154 cfg2 := ds.Get() 155 assert.Equal(t, "http://TestStoreNew", *cfg.ServiceSettings.SiteURL) 156 157 assert.True(t, cfg == cfg2, "Get() returned different configuration instances") 158 159 newCfg := &model.Config{} 160 oldCfg, err := ds.Set(newCfg) 161 require.NoError(t, err) 162 163 assert.True(t, oldCfg == cfg, "returned config after set() changed original") 164 assert.False(t, newCfg == cfg, "returned config should have been different from original") 165 } 166 167 func TestDatabaseStoreGetEnivironmentOverrides(t *testing.T) { 168 _, tearDown := setupConfigDatabase(t, testConfig, nil) 169 defer tearDown() 170 171 sqlSettings := mainHelper.GetSqlSettings() 172 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 173 require.NoError(t, err) 174 defer ds.Close() 175 176 assert.Equal(t, "http://TestStoreNew", *ds.Get().ServiceSettings.SiteURL) 177 assert.Empty(t, ds.GetEnvironmentOverrides()) 178 179 os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://override") 180 181 ds, err = config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 182 require.NoError(t, err) 183 defer ds.Close() 184 185 assert.Equal(t, "http://override", *ds.Get().ServiceSettings.SiteURL) 186 assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides()) 187 } 188 189 func TestDatabaseStoreSet(t *testing.T) { 190 sqlSettings := mainHelper.GetSqlSettings() 191 192 t.Run("set same pointer value", func(t *testing.T) { 193 t.Skip("not yet implemented") 194 195 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 196 defer tearDown() 197 198 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 199 require.NoError(t, err) 200 defer ds.Close() 201 202 _, err = ds.Set(ds.Get()) 203 if assert.Error(t, err) { 204 assert.EqualError(t, err, "old configuration modified instead of cloning") 205 } 206 }) 207 208 t.Run("defaults required", func(t *testing.T) { 209 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 210 defer tearDown() 211 212 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 213 require.NoError(t, err) 214 defer ds.Close() 215 216 oldCfg := ds.Get() 217 218 newCfg := &model.Config{} 219 220 retCfg, err := ds.Set(newCfg) 221 require.NoError(t, err) 222 assert.Equal(t, oldCfg, retCfg) 223 224 assert.Equal(t, model.SERVICE_SETTINGS_DEFAULT_SITE_URL, *ds.Get().ServiceSettings.SiteURL) 225 }) 226 227 t.Run("desanitization required", func(t *testing.T) { 228 _, tearDown := setupConfigDatabase(t, ldapConfig, nil) 229 defer tearDown() 230 231 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 232 require.NoError(t, err) 233 defer ds.Close() 234 235 oldCfg := ds.Get() 236 237 newCfg := &model.Config{} 238 newCfg.LdapSettings.BindPassword = sToP(model.FAKE_SETTING) 239 240 retCfg, err := ds.Set(newCfg) 241 require.NoError(t, err) 242 assert.Equal(t, oldCfg, retCfg) 243 244 assert.Equal(t, "password", *ds.Get().LdapSettings.BindPassword) 245 }) 246 247 t.Run("invalid", func(t *testing.T) { 248 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 249 defer tearDown() 250 251 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 252 require.NoError(t, err) 253 defer ds.Close() 254 255 newCfg := &model.Config{} 256 newCfg.ServiceSettings.SiteURL = sToP("invalid") 257 258 _, err = ds.Set(newCfg) 259 if assert.Error(t, err) { 260 assert.EqualError(t, err, "new configuration is invalid: Config.IsValid: model.config.is_valid.site_url.app_error, ") 261 } 262 263 assert.Equal(t, model.SERVICE_SETTINGS_DEFAULT_SITE_URL, *ds.Get().ServiceSettings.SiteURL) 264 }) 265 266 t.Run("duplicate ignored", func(t *testing.T) { 267 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 268 defer tearDown() 269 270 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 271 require.NoError(t, err) 272 defer ds.Close() 273 274 _, err = ds.Set(ds.Get()) 275 require.NoError(t, err) 276 277 beforeId, _ := getActualDatabaseConfig(t) 278 _, err = ds.Set(ds.Get()) 279 require.NoError(t, err) 280 281 afterId, _ := getActualDatabaseConfig(t) 282 assert.Equal(t, beforeId, afterId, "new record should not have been written") 283 }) 284 285 t.Run("read-only ignored", func(t *testing.T) { 286 _, tearDown := setupConfigDatabase(t, readOnlyConfig, nil) 287 defer tearDown() 288 289 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 290 require.NoError(t, err) 291 defer ds.Close() 292 293 newCfg := &model.Config{ 294 ServiceSettings: model.ServiceSettings{ 295 SiteURL: sToP("http://new"), 296 }, 297 } 298 299 _, err = ds.Set(newCfg) 300 require.NoError(t, err) 301 302 assert.Equal(t, "http://new", *ds.Get().ServiceSettings.SiteURL) 303 }) 304 305 t.Run("set with automatic save", func(t *testing.T) { 306 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 307 defer tearDown() 308 309 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 310 require.NoError(t, err) 311 defer ds.Close() 312 313 newCfg := &model.Config{ 314 ServiceSettings: model.ServiceSettings{ 315 SiteURL: sToP("http://new"), 316 }, 317 } 318 319 _, err = ds.Set(newCfg) 320 require.NoError(t, err) 321 322 err = ds.Load() 323 require.NoError(t, err) 324 325 assert.Equal(t, "http://new", *ds.Get().ServiceSettings.SiteURL) 326 }) 327 328 t.Run("persist failed", func(t *testing.T) { 329 t.Skip("skipping persistence test inside Set") 330 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 331 defer tearDown() 332 333 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 334 require.NoError(t, err) 335 defer ds.Close() 336 337 db := sqlx.NewDb(mainHelper.GetSqlSupplier().GetMaster().Db, *sqlSettings.DriverName) 338 _, err = db.Exec("DROP TABLE Configurations") 339 require.NoError(t, err) 340 341 newCfg := &model.Config{} 342 343 _, err = ds.Set(newCfg) 344 if assert.Error(t, err) { 345 assert.True(t, strings.HasPrefix(err.Error(), "failed to persist: failed to write to database")) 346 } 347 348 assert.Equal(t, model.SERVICE_SETTINGS_DEFAULT_SITE_URL, *ds.Get().ServiceSettings.SiteURL) 349 }) 350 351 t.Run("listeners notified", func(t *testing.T) { 352 activeId, tearDown := setupConfigDatabase(t, emptyConfig, nil) 353 defer tearDown() 354 355 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 356 require.NoError(t, err) 357 defer ds.Close() 358 359 oldCfg := ds.Get() 360 361 called := make(chan bool, 1) 362 callback := func(oldfg, newCfg *model.Config) { 363 called <- true 364 } 365 ds.AddListener(callback) 366 367 newCfg := &model.Config{} 368 369 retCfg, err := ds.Set(newCfg) 370 require.NoError(t, err) 371 assert.Equal(t, oldCfg, retCfg) 372 373 id, _ := getActualDatabaseConfig(t) 374 assert.NotEqual(t, activeId, id, "new record should have been written") 375 376 select { 377 case <-called: 378 case <-time.After(5 * time.Second): 379 t.Fatal("callback should have been called when config written") 380 } 381 }) 382 } 383 384 func TestDatabaseStoreLoad(t *testing.T) { 385 sqlSettings := mainHelper.GetSqlSettings() 386 387 t.Run("active configuration no longer exists", func(t *testing.T) { 388 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 389 defer tearDown() 390 391 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 392 require.NoError(t, err) 393 defer ds.Close() 394 395 truncateTables(t) 396 397 err = ds.Load() 398 require.NoError(t, err) 399 assertDatabaseNotEqualsConfig(t, emptyConfig) 400 }) 401 402 t.Run("honour environment", func(t *testing.T) { 403 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 404 defer tearDown() 405 406 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 407 require.NoError(t, err) 408 defer ds.Close() 409 410 os.Setenv("MM_SERVICESETTINGS_SITEURL", "http://override") 411 412 err = ds.Load() 413 require.NoError(t, err) 414 assert.Equal(t, "http://override", *ds.Get().ServiceSettings.SiteURL) 415 assert.Equal(t, map[string]interface{}{"ServiceSettings": map[string]interface{}{"SiteURL": true}}, ds.GetEnvironmentOverrides()) 416 }) 417 418 t.Run("invalid", func(t *testing.T) { 419 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 420 defer tearDown() 421 422 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 423 require.NoError(t, err) 424 defer ds.Close() 425 426 cfgData, err := config.MarshalConfig(invalidConfig) 427 require.NoError(t, err) 428 429 db := sqlx.NewDb(mainHelper.GetSqlSupplier().GetMaster().Db, *sqlSettings.DriverName) 430 truncateTables(t) 431 id := model.NewId() 432 _, err = db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt, Active) VALUES(:Id, :Value, :CreateAt, TRUE)", map[string]interface{}{ 433 "Id": id, 434 "Value": cfgData, 435 "CreateAt": model.GetMillis(), 436 }) 437 require.NoError(t, err) 438 439 err = ds.Load() 440 if assert.Error(t, err) { 441 assert.EqualError(t, err, "invalid config: Config.IsValid: model.config.is_valid.site_url.app_error, ") 442 } 443 }) 444 445 t.Run("fixes required", func(t *testing.T) { 446 _, tearDown := setupConfigDatabase(t, fixesRequiredConfig, nil) 447 defer tearDown() 448 449 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 450 require.NoError(t, err) 451 defer ds.Close() 452 453 err = ds.Load() 454 require.NoError(t, err) 455 assertDatabaseNotEqualsConfig(t, fixesRequiredConfig) 456 assert.Equal(t, "http://trailingslash", *ds.Get().ServiceSettings.SiteURL) 457 }) 458 459 t.Run("listeners notifed", func(t *testing.T) { 460 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 461 defer tearDown() 462 463 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 464 require.NoError(t, err) 465 defer ds.Close() 466 467 called := make(chan bool, 1) 468 callback := func(oldfg, newCfg *model.Config) { 469 called <- true 470 } 471 ds.AddListener(callback) 472 473 err = ds.Load() 474 require.NoError(t, err) 475 476 select { 477 case <-called: 478 case <-time.After(5 * time.Second): 479 t.Fatal("callback should have been called when config loaded") 480 } 481 }) 482 } 483 484 func TestDatabaseGetFile(t *testing.T) { 485 _, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{ 486 "empty-file": []byte{}, 487 "test-file": []byte("test"), 488 }) 489 defer tearDown() 490 491 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 492 require.NoError(t, err) 493 defer ds.Close() 494 495 t.Run("get empty filename", func(t *testing.T) { 496 _, err := ds.GetFile("") 497 require.Error(t, err) 498 }) 499 500 t.Run("get non-existent file", func(t *testing.T) { 501 _, err := ds.GetFile("unknown") 502 require.Error(t, err) 503 }) 504 505 t.Run("get empty file", func(t *testing.T) { 506 data, err := ds.GetFile("empty-file") 507 require.NoError(t, err) 508 require.Empty(t, data) 509 }) 510 511 t.Run("get non-empty file", func(t *testing.T) { 512 data, err := ds.GetFile("test-file") 513 require.NoError(t, err) 514 require.Equal(t, []byte("test"), data) 515 }) 516 } 517 518 func TestDatabaseSetFile(t *testing.T) { 519 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 520 defer tearDown() 521 522 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 523 require.NoError(t, err) 524 defer ds.Close() 525 526 t.Run("set new file", func(t *testing.T) { 527 err := ds.SetFile("new", []byte("new file")) 528 require.NoError(t, err) 529 530 data, err := ds.GetFile("new") 531 require.NoError(t, err) 532 require.Equal(t, []byte("new file"), data) 533 }) 534 535 t.Run("overwrite existing file", func(t *testing.T) { 536 err := ds.SetFile("existing", []byte("existing file")) 537 require.NoError(t, err) 538 539 err = ds.SetFile("existing", []byte("overwritten file")) 540 require.NoError(t, err) 541 542 data, err := ds.GetFile("existing") 543 require.NoError(t, err) 544 require.Equal(t, []byte("overwritten file"), data) 545 }) 546 } 547 548 func TestDatabaseHasFile(t *testing.T) { 549 t.Run("has non-existent", func(t *testing.T) { 550 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 551 defer tearDown() 552 553 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 554 require.NoError(t, err) 555 defer ds.Close() 556 557 has, err := ds.HasFile("non-existent") 558 require.NoError(t, err) 559 require.False(t, has) 560 }) 561 562 t.Run("has existing", func(t *testing.T) { 563 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 564 defer tearDown() 565 566 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 567 require.NoError(t, err) 568 defer ds.Close() 569 570 err = ds.SetFile("existing", []byte("existing file")) 571 require.NoError(t, err) 572 573 has, err := ds.HasFile("existing") 574 require.NoError(t, err) 575 require.True(t, has) 576 }) 577 578 t.Run("has manually created file", func(t *testing.T) { 579 _, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{ 580 "manual": []byte("manual file"), 581 }) 582 defer tearDown() 583 584 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 585 require.NoError(t, err) 586 defer ds.Close() 587 588 has, err := ds.HasFile("manual") 589 require.NoError(t, err) 590 require.True(t, has) 591 }) 592 } 593 594 func TestDatabaseRemoveFile(t *testing.T) { 595 t.Run("remove non-existent", func(t *testing.T) { 596 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 597 defer tearDown() 598 599 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 600 require.NoError(t, err) 601 defer ds.Close() 602 603 err = ds.RemoveFile("non-existent") 604 require.NoError(t, err) 605 }) 606 607 t.Run("remove existing", func(t *testing.T) { 608 _, tearDown := setupConfigDatabase(t, minimalConfig, nil) 609 defer tearDown() 610 611 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 612 require.NoError(t, err) 613 defer ds.Close() 614 615 err = ds.SetFile("existing", []byte("existing file")) 616 require.NoError(t, err) 617 618 err = ds.RemoveFile("existing") 619 require.NoError(t, err) 620 621 has, err := ds.HasFile("existing") 622 require.NoError(t, err) 623 require.False(t, has) 624 625 _, err = ds.GetFile("existing") 626 require.Error(t, err) 627 }) 628 629 t.Run("remove manually created file", func(t *testing.T) { 630 _, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{ 631 "manual": []byte("manual file"), 632 }) 633 defer tearDown() 634 635 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *mainHelper.Settings.DriverName, *mainHelper.Settings.DataSource)) 636 require.NoError(t, err) 637 defer ds.Close() 638 639 err = ds.RemoveFile("manual") 640 require.NoError(t, err) 641 642 has, err := ds.HasFile("manual") 643 require.NoError(t, err) 644 require.False(t, has) 645 646 _, err = ds.GetFile("manual") 647 require.Error(t, err) 648 }) 649 } 650 651 func TestDatabaseStoreString(t *testing.T) { 652 _, tearDown := setupConfigDatabase(t, emptyConfig, nil) 653 defer tearDown() 654 655 sqlSettings := mainHelper.GetSqlSettings() 656 ds, err := config.NewDatabaseStore(fmt.Sprintf("%s://%s", *sqlSettings.DriverName, *sqlSettings.DataSource)) 657 require.NoError(t, err) 658 defer ds.Close() 659 660 actualStringURL, err := url.Parse(ds.String()) 661 require.NoError(t, err) 662 663 assert.Equal(t, *sqlSettings.DriverName, actualStringURL.Scheme) 664 actualUsername := actualStringURL.User.Username() 665 actualPassword, _ := actualStringURL.User.Password() 666 assert.NotEmpty(t, actualUsername) 667 assert.Empty(t, actualPassword, "should mask password") 668 }