Skip to content

Commit

Permalink
testcontainers#98 canned postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolay Kuznetsov committed Nov 21, 2019
1 parent 2b46560 commit 118fd09
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 1 deletion.
107 changes: 107 additions & 0 deletions canned/postgres/postgres.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package postgres

import (
"context"
"fmt"
"github.com/docker/go-connections/nat"
"github.com/pkg/errors"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)

const (
image = "postgres"
tag = "9.6.15"
port nat.Port = "5432/tcp"
user = "user"
password = "password"
database = "database"
logEntry = "database system is ready to accept connections"
)

type ContainerRequest struct {
testcontainers.GenericContainerRequest
User string
Password string
Database string
}

// should always be created via NewContainer
type Container struct {
Container testcontainers.Container
req ContainerRequest
}

func (cont Container) ConnectURL(ctx context.Context) (string, error) {
template := "postgres://%s:%s@localhost:%s/%s"

mappedPort, err := cont.Container.MappedPort(ctx, port)
if err != nil {
return "", errors.Wrapf(err, "failed to get mapper port for %s", port.Port())
}

return fmt.Sprintf(template, cont.req.User, cont.req.Password,
mappedPort.Port(), cont.req.Database), nil
}

func NewContainer(ctx context.Context, req ContainerRequest) (*Container, error) {
req.ExposedPorts = []string{string(port)}

// Set the default values if none were provided in the request
if req.Image == "" && req.FromDockerfile.Context == "" {
req.Image = fmt.Sprintf("%s:%s", image, tag)
}

if req.User == "" {
req.User = user
}

if req.Password == "" {
req.Password = password
}

if req.Database == "" {
req.Database = database
}

if req.Env == nil {
req.Env = map[string]string{}
}
req.Env["POSTGRES_USER"] = req.User
req.Env["POSTGRES_PASSWORD"] = req.Password
req.Env["POSTGRES_DB"] = req.Database

if req.WaitingFor == nil {
req.WaitingFor = wait.ForAll(
wait.NewHostPortStrategy(port),
wait.ForLog(logEntry).WithOccurrence(2),
)
}

if req.Cmd == nil {
req.Cmd = []string{"postgres", "-c", "fsync=off"}
}

provider, err := req.ProviderType.GetProvider()
if err != nil {
return nil, err
}

c, err := provider.CreateContainer(ctx, req.ContainerRequest)
if err != nil {
return nil, errors.Wrap(err, "failed to create container")
}

res := &Container{
Container: c,
req: req,
}

if req.Started {
if err := c.Start(ctx); err != nil {
return res, errors.Wrap(err, "failed to start container")
}
}

return res, nil
}
83 changes: 83 additions & 0 deletions canned/postgres/postgres_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package postgres

import (
"context"
"database/sql"
"testing"

_ "github.com/lib/pq"
"github.com/testcontainers/testcontainers-go"
)

func TestWriteIntoAPostgreSQLContainerViaDriver(t *testing.T) {

ctx := context.Background()

c, err := NewContainer(ctx, ContainerRequest{
Database: "hello",
GenericContainerRequest: testcontainers.GenericContainerRequest{
Started: true,
},
})
if err != nil {
t.Fatal(err.Error())
}
defer c.Container.Terminate(ctx)

connectURL, err := c.ConnectURL(ctx)
if err != nil {
t.Fatal(err.Error())
}

connectURL += "?sslmode=disable"

sqlC, err := sql.Open("postgres", connectURL)
if err != nil {
t.Fatal(err.Error())
}
defer sqlC.Close()

_, err = sqlC.ExecContext(ctx, "CREATE TABLE example ( id integer, data varchar(32) )")
if err != nil {
t.Fatal(err.Error())
}
}

func ExamplePostgreSQLContainerRequest() {

// Optional
containerRequest := testcontainers.ContainerRequest{
Image: "docker.io/library/postgres:11.5",
}

genericContainerRequest := testcontainers.GenericContainerRequest{
Started: true,
ContainerRequest: containerRequest,
}

// Database, User, and Password are optional,
// the driver will use default ones if not provided
pgContainerRequest := ContainerRequest{
Database: "mycustomdatabase",
User: "anyuser",
Password: "yoursecurepassword",
GenericContainerRequest: genericContainerRequest,
}

pgContainerRequest.Validate()
}

func ExampleNewPostgreSQLContainer() {
ctx := context.Background()

// Create your PostgreSQL database,
// by setting Started this function will not return
// until a test connection has been established
c, _ := NewContainer(ctx, ContainerRequest{
Database: "hello",
GenericContainerRequest: testcontainers.GenericContainerRequest{
Started: true,
},
})
defer c.Container.Terminate(ctx)
}
2 changes: 1 addition & 1 deletion container.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (t ProviderType) GetProvider() (GenericProvider, error) {
return nil, errors.New("unknown provider")
}

// Validate ensures that the ContainerRequest does not have invalid paramters configured to it
// Validate ensures that the ContainerRequest does not have invalid parameters configured to it
// ex. make sure you are not specifying both an image as well as a context
func (c *ContainerRequest) Validate() error {

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/mux v1.6.2 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/lib/pq v1.2.0
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down

0 comments on commit 118fd09

Please sign in to comment.