Skip to content

Commit ef4a62e

Browse files
committed
Create dockerpool for testing
1 parent 7526c80 commit ef4a62e

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed
2+
// under the Apache License Version 2.0.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
// Copyright 2016-present Datadog, Inc.
5+
6+
package dockerpool
7+
8+
import (
9+
"github.com/ory/dockertest"
10+
"github.com/ory/dockertest/docker"
11+
"github.com/sirupsen/logrus"
12+
)
13+
14+
type TeardownFunc func()
15+
16+
// PoolConfig is used to define a basic container and the pool.
17+
//
18+
// Public fields define the required values to create a pool.
19+
// Private fields are optional and can be applied with `func Option...()`
20+
type PoolConfig struct {
21+
// Repository represents the image repository.
22+
Repository string
23+
// ImageTag represents the image tag.
24+
ImageTag string
25+
// Expiration sets the max amount of time to try and create a pool before exiting.
26+
Expiration uint
27+
// DockerHostConfig contains the container options related to starting a container.
28+
DockerHostConfig *docker.HostConfig
29+
30+
// endpoint represents the docker endpoint. By default, this is an empty string which sets the pool's
31+
// default behavior to take the endpoint from the environment variable DOCKER_HOST and DOCKER_URL, or from
32+
// docker-machine if the environment variable DOCKER_MACHINE_NAME is set, or if neither is defined a
33+
// sensible default for the operating system you are on.
34+
endpoint string
35+
// env defines the image's environment variables
36+
env []string
37+
// exposedPorts defines ports to be exposed from the pool container.
38+
exposedPorts []string
39+
}
40+
41+
// PoolOption defines an option for a docker pool.
42+
type PoolOption func(*PoolConfig)
43+
44+
// OptionEndpoint sets the docker endpoint.
45+
func OptionEndpoint(endpoint string) PoolOption {
46+
return func(pc *PoolConfig) {
47+
pc.endpoint = endpoint
48+
}
49+
}
50+
51+
// OptionalEnvs applies a list of the image's environment variables.
52+
func OptionEnvs(envs ...string) PoolOption {
53+
return func(pc *PoolConfig) {
54+
pc.env = envs
55+
}
56+
}
57+
58+
// OptionalExposedPort applies a list of ports to be exposed from the container.
59+
func OptionalExposedPorts(ports ...string) PoolOption {
60+
return func(pc *PoolConfig) {
61+
pc.exposedPorts = ports
62+
}
63+
}
64+
65+
// CreatePool creates a new docker pool.
66+
func CreatePool(pc *PoolConfig, options ...PoolOption) (*dockertest.Pool, *dockertest.Resource, TeardownFunc) {
67+
pc.endpoint = ""
68+
pc.env = nil
69+
pc.exposedPorts = nil
70+
71+
for _, apply := range options {
72+
apply(pc)
73+
}
74+
75+
pool, err := dockertest.NewPool(pc.endpoint)
76+
if err != nil {
77+
logrus.Fatalf("Failed to construct pool: %s", err)
78+
}
79+
if err := pool.Client.Ping(); err != nil {
80+
logrus.Fatalf("Failed to connect to docker: %s", err)
81+
}
82+
83+
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
84+
Repository: pc.Repository,
85+
Tag: pc.ImageTag,
86+
Env: pc.env,
87+
ExposedPorts: pc.exposedPorts,
88+
}, func(config *docker.HostConfig) {
89+
config.AutoRemove = pc.DockerHostConfig.AutoRemove
90+
config.RestartPolicy = pc.DockerHostConfig.RestartPolicy
91+
// extensible, update as needed
92+
})
93+
if err != nil {
94+
logrus.Fatalf("Failed to start resource: %s", err)
95+
}
96+
97+
teardown := func() {
98+
logrus.Infof("Tearing down docker pool id=[%s]", resource.Container.ID)
99+
if err := pool.Purge(resource); err != nil {
100+
logrus.Errorf("Failed to purge pool resource: %s", err)
101+
}
102+
}
103+
104+
return pool, resource, teardown
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed
2+
// under the Apache License Version 2.0.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
// Copyright 2016-present Datadog, Inc.
5+
6+
package testutil
7+
8+
import (
9+
"fmt"
10+
"time"
11+
12+
_ "github.com/godror/godror"
13+
"github.com/jmoiron/sqlx"
14+
"github.com/ory/dockertest/docker"
15+
"github.com/sirupsen/logrus"
16+
17+
"github.com/DataDog/datadog-agent/pkg/collector/corechecks/oracle/testutil/dockerpool"
18+
)
19+
20+
// CreateOraclePool creates an Oracle docker pool used for testing.
21+
// TODO: Make configuratable, using hardcoded values for now...
22+
func CreateOraclePool(dbName string, port int, attemptWait uint) (*sqlx.DB, dockerpool.TeardownFunc) {
23+
portStr := fmt.Sprintf("%d/tcp", port)
24+
25+
pool, resource, teardown := dockerpool.CreatePool(&dockerpool.PoolConfig{
26+
Repository: "gvenzl/oracle-xe",
27+
ImageTag: "latest",
28+
DockerHostConfig: &docker.HostConfig{
29+
AutoRemove: true,
30+
RestartPolicy: docker.RestartPolicy{Name: "no"},
31+
},
32+
}, dockerpool.OptionEnvs("ORACLE_PASSWORD=password"), dockerpool.OptionalExposedPorts(portStr))
33+
34+
databaseUrl := fmt.Sprintf("%s/%s@localhost:%s/%s", "system", "password", resource.GetPort(portStr), dbName)
35+
36+
// Hard kill the container after defined time
37+
if err := resource.Expire(180); err != nil {
38+
logrus.Fatalf("Failed to set resource expiration: %s", err)
39+
}
40+
41+
var db *sqlx.DB
42+
43+
// Exponential backoff-retry, our app in the container might not be ready to accept connections yet
44+
pool.MaxWait = time.Duration(attemptWait) * time.Second
45+
if err := pool.Retry(func() error {
46+
oracleDB, err := sqlx.Open("godror", databaseUrl)
47+
if err != nil {
48+
return err
49+
}
50+
db = oracleDB
51+
return oracleDB.Ping()
52+
}); err != nil {
53+
logrus.Fatalf("Failed to connect to docker after %d seconds | err=[%s]", attemptWait, err)
54+
}
55+
56+
// TODO: Setup migrations to allow setup scripts
57+
58+
return db, teardown
59+
}

0 commit comments

Comments
 (0)