Dockertest + postgres + golang. relation "url_uuid" does not exist
Для своего микросервиса (сервис общается с postgres без ошибок) решил сделать тест с использованием dockertest. Пример использование взял отсюда - https://github.com/ory/dockertest/blob/v3/examples/PostgreSQL.md В postgres на данный момент существует BD с таблицей url_uuid, но при запуске Test_1 в err получаю ошибку - pq: relation "url_uuid" does not exist
Что я делаю не так? -_-
package postgres
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
log "github.com/sirupsen/logrus"
"os"
"testing"
"time"
)
var db *sql.DB
func TestMain(m *testing.M) {
// uses a sensible default on windows (tcp/http) and linux/osx (socket)
pool, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("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=test",
"POSTGRES_USER=test",
"POSTGRES_DB=DB",
"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")
databaseUrl := fmt.Sprintf("postgres://test:test@%s/DB?sslmode=disable", hostAndPort)
log.Println("Connecting to database on url: ", 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 {
db, err = sql.Open("postgres", databaseUrl)
if err != nil {
return err
}
return db.Ping()
}); err != nil {
log.Fatalf("Could not connect to docker: %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.Fatalf("Could not purge resource: %s", err)
}
os.Exit(code)
}
func Test_1(t *testing.T) {
_, err := db.Exec("select * from url_uuid")
if err != nil {
fmt.Println(err)
}
}
Ответы (1 шт):
Автор решения: Nikolay Tuzov
→ Ссылка
Вы не создаете таблицу в базе данных. Вы ведь поднимаете новый контейнер с postgres, а не подключаетесь к уже существующей БД.
То есть, можно сделать так:
if _, err := db.Exec(`CREATE TABLE url_uuid (
id SERIAL PRIMARY KEY,
url VARCHAR(255) NOT NULL,
uuid VARCHAR(255) NOT NULL
);`); err != nil {
log.Fatalf("Could not create table: %s", err)
}
Но лучше вынести создание схемы в отдельный файл и применять его перед запуском тестов:
// schema.sql
CREATE TABLE url_uuid (
id SERIAL PRIMARY KEY,
url VARCHAR(255) NOT NULL,
uuid VARCHAR(255) NOT NULL
);
func TestMain(m *testing.M) {
// ...
// apply schema
schema, err := ioutil.ReadFile("schema.sql")
if err != nil {
log.Fatalf("Could not read schema: %s", err)
}
if _, err := db.Exec(string(schema)); err != nil {
log.Fatalf("Could not apply schema: %s", err)
}
// ...
}