Prepare a sqlite or postgres connection string for testing. Returns the connection string to use and a close function which must be called when the test finishes. Calling this function twice will return the same database, which will have data from previous tests unless close() is called. TODO: names
(t *testing.T, dbType DBType)
| 102 | // unless close() is called. |
| 103 | // TODO: namespace for concurrent package tests |
| 104 | func PrepareDBConnectionString(t *testing.T, dbType DBType) (connStr string, close func()) { |
| 105 | if dbType == DBTypeSQLite { |
| 106 | // this will be made in the current working directory which namespaces concurrent package runs correctly |
| 107 | dbname := "dendrite_test.db" |
| 108 | return fmt.Sprintf("file:%s", dbname), func() { |
| 109 | err := os.Remove(dbname) |
| 110 | if err != nil { |
| 111 | t.Fatalf("failed to cleanup sqlite db '%s': %s", dbname, err) |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | // Required vars: user and db |
| 117 | // We'll try to infer from the local env if they are missing |
| 118 | user := os.Getenv("POSTGRES_USER") |
| 119 | if user == "" { |
| 120 | user = currentUser() |
| 121 | } |
| 122 | connStr = fmt.Sprintf( |
| 123 | "user=%s sslmode=disable", |
| 124 | user, |
| 125 | ) |
| 126 | // optional vars, used in CI |
| 127 | password := os.Getenv("POSTGRES_PASSWORD") |
| 128 | if password != "" { |
| 129 | connStr += fmt.Sprintf(" password=%s", password) |
| 130 | } |
| 131 | host := os.Getenv("POSTGRES_HOST") |
| 132 | if host != "" { |
| 133 | connStr += fmt.Sprintf(" host=%s", host) |
| 134 | } |
| 135 | |
| 136 | // superuser database |
| 137 | postgresDB := os.Getenv("POSTGRES_DB") |
| 138 | // we cannot use 'dendrite_test' here else 2x concurrently running packages will try to use the same db. |
| 139 | // instead, hash the current working directory, snaffle the first 16 bytes and append that to dendrite_test |
| 140 | // and use that as the unique db name. We do this because packages are per-directory hence by hashing the |
| 141 | // working (test) directory we ensure we get a consistent hash and don't hash against concurrent packages. |
| 142 | wd, err := os.Getwd() |
| 143 | if err != nil { |
| 144 | t.Fatalf("cannot get working directory: %s", err) |
| 145 | } |
| 146 | hash := sha256.Sum256([]byte(wd)) |
| 147 | dbName := fmt.Sprintf("dendrite_test_%s", hex.EncodeToString(hash[:16])) |
| 148 | if postgresDB == "" { // local server, use createdb |
| 149 | createLocalDB(t, dbName) |
| 150 | } else { // remote server, shell into the postgres user and CREATE DATABASE |
| 151 | createRemoteDB(t, dbName, user, connStr) |
| 152 | } |
| 153 | connStr += fmt.Sprintf(" dbname=%s", dbName) |
| 154 | |
| 155 | return connStr, func() { |
| 156 | // Drop all tables on the database to get a fresh instance |
| 157 | db, err := sql.Open("postgres", connStr) |
| 158 | if err != nil { |
| 159 | t.Fatalf("failed to connect to postgres db '%s': %s", connStr, err) |
| 160 | } |
| 161 | _, err = db.Exec(`DROP SCHEMA public CASCADE; |
nothing calls this directly
no test coverage detected