mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
chore: Initial database scaffolding (#2)
* chore: Initial database scaffolding This implements migrations and code generation for interfacing with a PostgreSQL database. A dependency is added for the "postgres" binary on the host, but that seems like an acceptable requirement considering it's our primary database. An in-memory database object can be created for simple cross-OS and fast testing. * Run tests in CI * Use Docker instead of binaries on the host * Skip database tests on non-Linux operating systems * chore: Add golangci-lint and codecov * Use consistent file names
This commit is contained in:
59
database/postgres/postgres.go
Normal file
59
database/postgres/postgres.go
Normal file
@ -0,0 +1,59 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// Open creates a new PostgreSQL server using a Docker container.
|
||||
func Open() (string, func(), error) {
|
||||
pool, err := dockertest.NewPool("")
|
||||
if err != nil {
|
||||
return "", nil, xerrors.Errorf("create pool: %w", err)
|
||||
}
|
||||
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
|
||||
Repository: "postgres",
|
||||
Tag: "11",
|
||||
Env: []string{
|
||||
"POSTGRES_PASSWORD=postgres",
|
||||
"POSTGRES_USER=postgres",
|
||||
"POSTGRES_DB=postgres",
|
||||
"listen_addresses = '*'",
|
||||
},
|
||||
}, func(config *docker.HostConfig) {
|
||||
// set AutoRemove to true so that stopped container goes away by itself
|
||||
config.AutoRemove = true
|
||||
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Could not start resource: %s", err)
|
||||
}
|
||||
hostAndPort := resource.GetHostPort("5432/tcp")
|
||||
dbURL := fmt.Sprintf("postgres://postgres:postgres@%s/postgres?sslmode=disable", hostAndPort)
|
||||
|
||||
// Docker should hard-kill the container after 120 seconds.
|
||||
resource.Expire(120)
|
||||
|
||||
pool.MaxWait = 120 * time.Second
|
||||
err = pool.Retry(func() error {
|
||||
db, err := sql.Open("postgres", dbURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = db.Ping()
|
||||
_ = db.Close()
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return dbURL, func() {
|
||||
_ = pool.Purge(resource)
|
||||
}, nil
|
||||
}
|
32
database/postgres/postgres_test.go
Normal file
32
database/postgres/postgres_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
//go:build linux
|
||||
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/coder/coder/database/postgres"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m)
|
||||
}
|
||||
|
||||
func TestPostgres(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
connect, close, err := postgres.Open()
|
||||
require.NoError(t, err)
|
||||
defer close()
|
||||
db, err := sql.Open("postgres", connect)
|
||||
require.NoError(t, err)
|
||||
err = db.Ping()
|
||||
require.NoError(t, err)
|
||||
err = db.Close()
|
||||
require.NoError(t, err)
|
||||
}
|
Reference in New Issue
Block a user