Skip to content

Commit

Permalink
feat: setup mock db env
Browse files Browse the repository at this point in the history
  • Loading branch information
Yatanvesh committed Aug 27, 2023
1 parent bd75ba6 commit 80023db
Show file tree
Hide file tree
Showing 5 changed files with 325 additions and 18 deletions.
4 changes: 2 additions & 2 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ tasks:
migrations:apply:
desc: Apply the migrations to the local database
cmds:
- task: db-up
- task: db:up
- sleep 2
- atlas migrate apply --dir "file://sql/migrations" --url "postgresql://basemind:basemind@localhost:5432/basemind?search_path=public&sslmode=disable"
migrations:create:
desc: Create a new migration
cmds:
- task: db-up
- task: db:up
- sleep 2
- atlas migrate diff {{.CLI_ARGS}} --dir "file://sql/migrations" --to "file://sql/schema.sql" --dev-url "postgresql://basemind:basemind@localhost:5432/basemind?search_path=public&sslmode=disable"
70 changes: 70 additions & 0 deletions go-services/dashboard-backend/api/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package api

import (
"encoding/json"
"github.com/basemind-ai/monorepo/go-services/dashboard-backend/constants"
dbTestutils "github.com/basemind-ai/monorepo/go-shared/db/testutils"
"github.com/basemind-ai/monorepo/go-shared/firebaseutils/testutils"
"github.com/stretchr/testify/assert"
"io"
"net/http"
"net/http/httptest"
"testing"
)

func TestMain(m *testing.M) {
dbTestutils.TestMainWrapper(m)
}

func TestHandleDashboardUserPostLogin(t *testing.T) {

t.Run("Creates a new user", func(t *testing.T) {
rr := httptest.NewRecorder()

req, err := http.NewRequestWithContext(testutils.MockFirebaseContext(), http.MethodGet, constants.DashboardLoginEndpoint, nil)
assert.Nil(t, err)

HandleDashboardUserPostLogin(rr, req)

res := rr.Result()
assert.Equal(t, http.StatusCreated, res.StatusCode)

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
assert.Nil(t, err)

var responseUser HandleDashboardUserPostLoginDTO
_ = json.Unmarshal(body, &responseUser)

assert.Equal(t, "1", responseUser.User.FirebaseID)
assert.Equal(t, "Default Project", responseUser.Projects[0].Name)
assert.Equal(t, "Default Project", responseUser.Projects[0].Description)
})

t.Run("Retrieves an existing user", func(t *testing.T) {
// Create a new user first
req, err := http.NewRequestWithContext(testutils.MockFirebaseContext(), http.MethodGet, constants.DashboardLoginEndpoint, nil)
assert.Nil(t, err)
HandleDashboardUserPostLogin(httptest.NewRecorder(), req)

req, err = http.NewRequestWithContext(testutils.MockFirebaseContext(), http.MethodGet, constants.DashboardLoginEndpoint, nil)
assert.Nil(t, err)

rr := httptest.NewRecorder()
HandleDashboardUserPostLogin(rr, req)

res := rr.Result()
assert.Equal(t, http.StatusOK, res.StatusCode)

defer res.Body.Close()
body, err := io.ReadAll(res.Body)
assert.Nil(t, err)

var responseUser HandleDashboardUserPostLoginDTO
_ = json.Unmarshal(body, &responseUser)

assert.Equal(t, "1", responseUser.User.FirebaseID)
assert.Equal(t, "Default Project", responseUser.Projects[0].Name)
assert.Equal(t, "Default Project", responseUser.Projects[0].Description)
})
}
111 changes: 111 additions & 0 deletions go-shared/db/testutils/connection_testutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package testutils

import (
"context"
"database/sql"
"errors"
"fmt"
"github.com/basemind-ai/monorepo/go-shared/db"
"os/exec"

"github.com/rs/zerolog/log"
"os"
"testing"
"time"

_ "github.com/lib/pq"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)

func TestMainWrapper(m *testing.M) {
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
pool, err := dockertest.NewPool("")
if err != nil {
log.Fatal().Err(err).Msgf("Could not construct pool: %s", err)
}

err = pool.Client.Ping()
if err != nil {
log.Fatal().Err(err).Msgf("Could not connect to Docker: %s", err)
}

// pulls an image, creates a container based on it and runs it
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "postgres",
Tag: "latest",
Env: []string{
"POSTGRES_PASSWORD=secret",
"POSTGRES_USER=user_name",
"POSTGRES_DB=dbname",
"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.Fatal().Err(err).Msgf("Could not start resource: %s", err)
}

hostAndPort := resource.GetHostPort("5432/tcp")
databaseUrl := fmt.Sprintf("postgresql://user_name:secret@%s/dbname?sslmode=disable", hostAndPort)

log.Info().Msgf("Connecting to database on url: %s", databaseUrl)

resource.Expire(120) // Tell docker to hard kill the container in 120 seconds

// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
pool.MaxWait = 120 * time.Second
if err = pool.Retry(func() error {

tmpDb, err := sql.Open("postgres", databaseUrl)
if err != nil {
return err
}
return tmpDb.Ping()
}); err != nil {
log.Fatal().Err(err).Msgf("Could not connect to docker: %s", err)
}

localContext := context.TODO()
conn := db.CreateConnection(localContext, databaseUrl)
err = conn.Ping(localContext)
if err != nil {
log.Fatal().Err(err).Msgf("Could not connect to docker: %s", err)
}

// Migrating DB
if err := runMigrations("../../../sql/migrations", databaseUrl); err != nil {
log.Fatal().Err(err).Msgf("Could not migrate db: %s", err)
}

//Run tests
code := m.Run()

// You can't defer this because os.Exit doesn't care for defer
if err := pool.Purge(resource); err != nil {
log.Fatal().Err(err).Msgf("Could not purge resource: %s", err)
}

os.Exit(code)
}

func runMigrations(migrationsPath string, connUrl string) error {
if migrationsPath == "" {
return errors.New("missing migrations path")
}

out, err := exec.Command("atlas", "migrate", "apply", "--dir", "file://"+migrationsPath, "--url", connUrl).Output()

log.Info().Msg(string(out))
if err != nil {
return err
}
if err := m.Up(); err != nil {

Check failure on line 106 in go-shared/db/testutils/connection_testutils.go

View workflow job for this annotation

GitHub Actions / test

undefined: m
return err
}

return nil
}
28 changes: 28 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ require (
github.com/go-chi/httplog v0.3.1
github.com/go-redis/redismock/v9 v9.0.3
github.com/jackc/pgx/v5 v5.4.3
github.com/lib/pq v1.10.9
github.com/ory/dockertest/v3 v3.10.0
github.com/redis/go-redis/v9 v9.1.0
github.com/rs/zerolog v1.30.0
github.com/sethvargo/go-envconfig v0.9.0
Expand All @@ -23,33 +25,58 @@ require (
cloud.google.com/go/iam v1.1.2 // indirect
cloud.google.com/go/longrunning v0.5.1 // indirect
cloud.google.com/go/storage v1.32.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/MicahParks/keyfunc v1.9.0 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/docker v20.10.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-migrate/migrate v3.5.4+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/s2a-go v0.1.5 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/stretchr/objx v0.5.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.11.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.138.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand All @@ -59,5 +86,6 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.57.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 80023db

Please sign in to comment.