Chore: Add CloudWatch HTTP API tests (#29691)
* CloudWatch: Add HTTP API tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
@@ -44,17 +44,7 @@ const InitPriority = registry.High
|
||||
|
||||
func init() {
|
||||
ss := &SQLStore{}
|
||||
|
||||
// This change will make xorm use an empty default schema for postgres and
|
||||
// by that mimic the functionality of how it was functioning before
|
||||
// xorm's changes above.
|
||||
xorm.DefaultPostgresSchema = ""
|
||||
|
||||
registry.Register(®istry.Descriptor{
|
||||
Name: ServiceName,
|
||||
Instance: ss,
|
||||
InitPriority: InitPriority,
|
||||
})
|
||||
ss.Register()
|
||||
}
|
||||
|
||||
type SQLStore struct {
|
||||
@@ -69,23 +59,35 @@ type SQLStore struct {
|
||||
skipEnsureDefaultOrgAndUser bool
|
||||
}
|
||||
|
||||
// Register registers the SQLStore service with the DI system.
|
||||
func (ss *SQLStore) Register() {
|
||||
// This change will make xorm use an empty default schema for postgres and
|
||||
// by that mimic the functionality of how it was functioning before
|
||||
// xorm's changes above.
|
||||
xorm.DefaultPostgresSchema = ""
|
||||
|
||||
registry.Register(®istry.Descriptor{
|
||||
Name: ServiceName,
|
||||
Instance: ss,
|
||||
InitPriority: InitPriority,
|
||||
})
|
||||
}
|
||||
|
||||
func (ss *SQLStore) Init() error {
|
||||
ss.log = log.New("sqlstore")
|
||||
ss.readConfig()
|
||||
|
||||
engine, err := ss.getEngine()
|
||||
if err != nil {
|
||||
if err := ss.initEngine(); err != nil {
|
||||
return errutil.Wrap("failed to connect to database", err)
|
||||
}
|
||||
|
||||
ss.engine = engine
|
||||
ss.Dialect = migrator.NewDialect(ss.engine)
|
||||
|
||||
// temporarily still set global var
|
||||
x = engine
|
||||
x = ss.engine
|
||||
dialect = ss.Dialect
|
||||
|
||||
migrator := migrator.NewMigrator(engine)
|
||||
migrator := migrator.NewMigrator(ss.engine)
|
||||
migrations.AddMigrations(migrator)
|
||||
|
||||
for _, descriptor := range registry.GetServices() {
|
||||
@@ -96,7 +98,7 @@ func (ss *SQLStore) Init() error {
|
||||
}
|
||||
|
||||
if err := migrator.Start(); err != nil {
|
||||
return errutil.Wrap("migration failed", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Init repo instances
|
||||
@@ -109,6 +111,25 @@ func (ss *SQLStore) Init() error {
|
||||
ss.addAlertNotificationUidByIdHandler()
|
||||
ss.addPreferencesQueryAndCommandHandlers()
|
||||
|
||||
if err := ss.Reset(); err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure the changes are synced, so they get shared with eventual other DB connections
|
||||
if err := ss.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sync syncs changes to the database.
|
||||
func (ss *SQLStore) Sync() error {
|
||||
return ss.engine.Sync2()
|
||||
}
|
||||
|
||||
// Reset resets database state.
|
||||
// If default org and user creation is enabled, it will be ensured they exist in the database.
|
||||
func (ss *SQLStore) Reset() error {
|
||||
if ss.skipEnsureDefaultOrgAndUser {
|
||||
return nil
|
||||
}
|
||||
@@ -141,25 +162,27 @@ func (ss *SQLStore) ensureMainOrgAndAdminUser() error {
|
||||
// ensure admin user
|
||||
if !ss.Cfg.DisableInitAdminCreation {
|
||||
ss.log.Debug("Creating default admin user")
|
||||
cmd := models.CreateUserCommand{
|
||||
ss.log.Debug("Creating default admin user")
|
||||
if _, err := ss.createUser(ctx, userCreationArgs{
|
||||
Login: ss.Cfg.AdminUser,
|
||||
Email: ss.Cfg.AdminUser + "@localhost",
|
||||
Password: ss.Cfg.AdminPassword,
|
||||
IsAdmin: true,
|
||||
}
|
||||
if err := bus.DispatchCtx(ctx, &cmd); err != nil {
|
||||
}, false); err != nil {
|
||||
return fmt.Errorf("failed to create admin user: %s", err)
|
||||
}
|
||||
|
||||
ss.log.Info("Created default admin", "user", ss.Cfg.AdminUser)
|
||||
return nil
|
||||
// Why should we return and not create the default org in this case?
|
||||
// Returning here breaks tests using anonymous access
|
||||
// return nil
|
||||
}
|
||||
|
||||
// ensure default org even if default admin user is disabled
|
||||
if err := inTransactionCtx(ctx, func(sess *DBSession) error {
|
||||
_, err := getOrCreateOrg(sess, mainOrgName)
|
||||
if err := inTransactionWithRetryCtx(ctx, ss.engine, func(sess *DBSession) error {
|
||||
ss.log.Debug("Creating default org", "name", MainOrgName)
|
||||
_, err := ss.getOrCreateOrg(sess, MainOrgName)
|
||||
return err
|
||||
}); err != nil {
|
||||
}, 0); err != nil {
|
||||
return fmt.Errorf("failed to create default organization: %w", err)
|
||||
}
|
||||
|
||||
@@ -253,10 +276,16 @@ func (ss *SQLStore) buildConnectionString() (string, error) {
|
||||
return cnnstr, nil
|
||||
}
|
||||
|
||||
func (ss *SQLStore) getEngine() (*xorm.Engine, error) {
|
||||
// initEngine initializes ss.engine.
|
||||
func (ss *SQLStore) initEngine() error {
|
||||
if ss.engine != nil {
|
||||
sqlog.Debug("Already connected to database")
|
||||
return nil
|
||||
}
|
||||
|
||||
connectionString, err := ss.buildConnectionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if ss.Cfg.IsDatabaseMetricsEnabled() {
|
||||
@@ -264,10 +293,11 @@ func (ss *SQLStore) getEngine() (*xorm.Engine, error) {
|
||||
}
|
||||
|
||||
sqlog.Info("Connecting to DB", "dbtype", ss.dbCfg.Type)
|
||||
if ss.dbCfg.Type == migrator.SQLite && strings.HasPrefix(connectionString, "file:") {
|
||||
if ss.dbCfg.Type == migrator.SQLite && strings.HasPrefix(connectionString, "file:") &&
|
||||
!strings.HasPrefix(connectionString, "file::memory:") {
|
||||
exists, err := fs.Exists(ss.dbCfg.Path)
|
||||
if err != nil {
|
||||
return nil, errutil.Wrapf(err, "can't check for existence of %q", ss.dbCfg.Path)
|
||||
return errutil.Wrapf(err, "can't check for existence of %q", ss.dbCfg.Path)
|
||||
}
|
||||
|
||||
const perms = 0640
|
||||
@@ -275,15 +305,15 @@ func (ss *SQLStore) getEngine() (*xorm.Engine, error) {
|
||||
ss.log.Info("Creating SQLite database file", "path", ss.dbCfg.Path)
|
||||
f, err := os.OpenFile(ss.dbCfg.Path, os.O_CREATE|os.O_RDWR, perms)
|
||||
if err != nil {
|
||||
return nil, errutil.Wrapf(err, "failed to create SQLite database file %q", ss.dbCfg.Path)
|
||||
return errutil.Wrapf(err, "failed to create SQLite database file %q", ss.dbCfg.Path)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return nil, errutil.Wrapf(err, "failed to create SQLite database file %q", ss.dbCfg.Path)
|
||||
return errutil.Wrapf(err, "failed to create SQLite database file %q", ss.dbCfg.Path)
|
||||
}
|
||||
} else {
|
||||
fi, err := os.Lstat(ss.dbCfg.Path)
|
||||
if err != nil {
|
||||
return nil, errutil.Wrapf(err, "failed to stat SQLite database file %q", ss.dbCfg.Path)
|
||||
return errutil.Wrapf(err, "failed to stat SQLite database file %q", ss.dbCfg.Path)
|
||||
}
|
||||
m := fi.Mode() & os.ModePerm
|
||||
if m|perms != perms {
|
||||
@@ -294,7 +324,7 @@ func (ss *SQLStore) getEngine() (*xorm.Engine, error) {
|
||||
}
|
||||
engine, err := xorm.NewEngine(ss.dbCfg.Type, connectionString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
engine.SetMaxOpenConns(ss.dbCfg.MaxOpenConn)
|
||||
@@ -311,9 +341,11 @@ func (ss *SQLStore) getEngine() (*xorm.Engine, error) {
|
||||
engine.ShowExecTime(true)
|
||||
}
|
||||
|
||||
return engine, nil
|
||||
ss.engine = engine
|
||||
return nil
|
||||
}
|
||||
|
||||
// readConfig initializes the SQLStore from its configuration.
|
||||
func (ss *SQLStore) readConfig() {
|
||||
sec := ss.Cfg.Raw.Section("database")
|
||||
|
||||
@@ -363,18 +395,29 @@ type ITestDB interface {
|
||||
Helper()
|
||||
Fatalf(format string, args ...interface{})
|
||||
Logf(format string, args ...interface{})
|
||||
Log(args ...interface{})
|
||||
}
|
||||
|
||||
var testSQLStore *SQLStore
|
||||
|
||||
// InitTestDBOpt contains options for InitTestDB.
|
||||
type InitTestDBOpt struct {
|
||||
// EnsureDefaultOrgAndUser flags whether to ensure that default org and user exist.
|
||||
EnsureDefaultOrgAndUser bool
|
||||
}
|
||||
|
||||
// InitTestDB initializes the test DB.
|
||||
func InitTestDB(t ITestDB) *SQLStore {
|
||||
func InitTestDB(t ITestDB, opts ...InitTestDBOpt) *SQLStore {
|
||||
t.Helper()
|
||||
if testSQLStore == nil {
|
||||
testSQLStore = &SQLStore{}
|
||||
testSQLStore.Bus = bus.New()
|
||||
testSQLStore.CacheService = localcache.New(5*time.Minute, 10*time.Minute)
|
||||
testSQLStore.skipEnsureDefaultOrgAndUser = false
|
||||
testSQLStore.skipEnsureDefaultOrgAndUser = true
|
||||
|
||||
for _, opt := range opts {
|
||||
testSQLStore.skipEnsureDefaultOrgAndUser = !opt.EnsureDefaultOrgAndUser
|
||||
}
|
||||
|
||||
dbType := migrator.SQLite
|
||||
|
||||
@@ -423,19 +466,26 @@ func InitTestDB(t ITestDB) *SQLStore {
|
||||
|
||||
t.Logf("Cleaning DB")
|
||||
if err := dialect.CleanDB(); err != nil {
|
||||
t.Fatalf("Failed to clean test db %v", err)
|
||||
t.Fatalf("Failed to clean test db: %s", err)
|
||||
}
|
||||
|
||||
if err := testSQLStore.Init(); err != nil {
|
||||
t.Fatalf("Failed to init test database: %v", err)
|
||||
t.Fatalf("Failed to init test database: %s", err)
|
||||
}
|
||||
t.Log("Successfully initialized test database")
|
||||
|
||||
testSQLStore.engine.DatabaseTZ = time.UTC
|
||||
testSQLStore.engine.TZLocation = time.UTC
|
||||
|
||||
return testSQLStore
|
||||
}
|
||||
|
||||
t.Log("Truncating DB tables")
|
||||
if err := dialect.TruncateDBTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate test db %v", err)
|
||||
t.Fatalf("Failed to truncate test db: %s", err)
|
||||
}
|
||||
if err := testSQLStore.Reset(); err != nil {
|
||||
t.Fatalf("Failed to reset SQLStore: %s", err)
|
||||
}
|
||||
|
||||
return testSQLStore
|
||||
|
||||
Reference in New Issue
Block a user