From c9f6816548700486e0f4bcd823e94011064c843b Mon Sep 17 00:00:00 2001 From: krehermann Date: Fri, 21 Jun 2024 09:55:24 -0600 Subject: [PATCH] Add forceful testdb creation (#13640) * Add forceful testdb creation * fix tests --- GNUmakefile | 6 ++++- README.md | 8 +++++++ core/cmd/shell_local.go | 22 +++++++++++++++---- core/scripts/setup_testdb.sh | 2 +- .../scripts/node/db/preparetest/help.txtar | 1 + testdata/scripts/node/db/reset/help.txtar | 1 + 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index b09e0ee3cc7..711a41840a9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -114,7 +114,11 @@ setup-testdb: ## Setup the test database. testdb: ## Prepares the test database. go run . local db preparetest -.PHONY: testdb +.PHONY: testdb-force +testdb-force: ## Prepares the test database, drops any pesky user connections that stand in the the way. + go run . local db preparetest --force + +.PHONY: testdb-user-only testdb-user-only: ## Prepares the test database with user only. go run . local db preparetest --user-only diff --git a/README.md b/README.md index 6d246a6c461..2f56c5c93a8 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,14 @@ source .dbenv make testdb ``` +If you encounter the error `database accessed by other users (SQLSTATE 55006) exit status 1` +and you want force the database creation then use +``` +source .dbenv +make testdb-force +``` + + 7. Run tests: ```bash diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 780105d9868..3ecd3eed402 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -173,6 +173,10 @@ func initLocalSubCmds(s *Shell, safe bool) []cli.Command { Name: "dangerWillRobinson", Usage: "set to true to enable dropping non-test databases", }, + cli.BoolFlag{ + Name: "force", + Usage: "set to true to force the reset by dropping any existing connections to the database", + }, }, }, { @@ -186,6 +190,10 @@ func initLocalSubCmds(s *Shell, safe bool) []cli.Command { Name: "user-only", Usage: "only include test user fixture", }, + cli.BoolFlag{ + Name: "force", + Usage: "set to true to force the reset by dropping any existing connections to the database", + }, }, }, { @@ -748,7 +756,7 @@ func (s *Shell) ResetDatabase(c *cli.Context) error { } dangerMode := c.Bool("dangerWillRobinson") - + force := c.Bool("force") dbname := parsed.Path[1:] if !dangerMode && !strings.HasSuffix(dbname, "_test") { return s.errorOut(fmt.Errorf("cannot reset database named `%s`. This command can only be run against databases with a name that ends in `_test`, to prevent accidental data loss. If you REALLY want to reset this database, pass in the -dangerWillRobinson option", dbname)) @@ -756,7 +764,7 @@ func (s *Shell) ResetDatabase(c *cli.Context) error { lggr := s.Logger lggr.Infof("Resetting database: %#v", parsed.String()) lggr.Debugf("Dropping and recreating database: %#v", parsed.String()) - if err := dropAndCreateDB(parsed); err != nil { + if err := dropAndCreateDB(parsed, force); err != nil { return s.errorOut(err) } lggr.Debugf("Migrating database: %#v", parsed.String()) @@ -1079,7 +1087,7 @@ func newConnection(cfg dbConfig) (*sqlx.DB, error) { return pg.NewConnection(parsed.String(), cfg.Dialect(), cfg) } -func dropAndCreateDB(parsed url.URL) (err error) { +func dropAndCreateDB(parsed url.URL, force bool) (err error) { // Cannot drop the database if we are connected to it, so we must connect // to a different one. template1 should be present on all postgres installations dbname := parsed.Path[1:] @@ -1093,7 +1101,13 @@ func dropAndCreateDB(parsed url.URL) (err error) { err = multierr.Append(err, cerr) } }() - + if force { + // supports pg < 13. https://stackoverflow.com/questions/17449420/postgresql-unable-to-drop-database-because-of-some-auto-connections-to-db + _, err = db.Exec(fmt.Sprintf("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '%s';", dbname)) + if err != nil { + return fmt.Errorf("unable to terminate connections to postgres database: %v", err) + } + } _, err = db.Exec(fmt.Sprintf(`DROP DATABASE IF EXISTS "%s"`, dbname)) if err != nil { return fmt.Errorf("unable to drop postgres database: %v", err) diff --git a/core/scripts/setup_testdb.sh b/core/scripts/setup_testdb.sh index 534c980feb9..85aa5812e23 100755 --- a/core/scripts/setup_testdb.sh +++ b/core/scripts/setup_testdb.sh @@ -57,7 +57,7 @@ echo $db_url repo=$(git rev-parse --show-toplevel) pushd $repo export $db_url -make testdb || exit_error "Failed to create test database" +make testdb-force || exit_error "Failed to create test database" popd # Set the database URL in the .dbenv file diff --git a/testdata/scripts/node/db/preparetest/help.txtar b/testdata/scripts/node/db/preparetest/help.txtar index 0173cd5b6cd..7ba7450a79d 100644 --- a/testdata/scripts/node/db/preparetest/help.txtar +++ b/testdata/scripts/node/db/preparetest/help.txtar @@ -11,4 +11,5 @@ USAGE: OPTIONS: --user-only only include test user fixture + --force set to true to force the reset by dropping any existing connections to the database diff --git a/testdata/scripts/node/db/reset/help.txtar b/testdata/scripts/node/db/reset/help.txtar index 2f03884be9c..d69a0624528 100644 --- a/testdata/scripts/node/db/reset/help.txtar +++ b/testdata/scripts/node/db/reset/help.txtar @@ -11,4 +11,5 @@ USAGE: OPTIONS: --dangerWillRobinson set to true to enable dropping non-test databases + --force set to true to force the reset by dropping any existing connections to the database