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:
Arve Knudsen
2021-01-07 11:36:13 +01:00
committed by GitHub
parent b6efebd92c
commit 25048ebdf8
33 changed files with 1286 additions and 191 deletions
+89 -39
View File
@@ -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(&registry.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(&registry.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