Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit f2fd52c

Browse files
authored
Merge pull request #2 from amirhnajafiz/1-redesign
1 redesign
2 parents 3f86de4 + 0813751 commit f2fd52c

File tree

7 files changed

+252
-183
lines changed

7 files changed

+252
-183
lines changed

README.md

Lines changed: 85 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,110 @@
22
Test Containers
33
</h1>
44

5-
Example of using Test containers in Golang. Creating a **redis** cluster with
6-
containers and test redis cluster with Golang SDK while running unit tests.
5+
Example of using Test containers in Golang. Creating a **Nats** cluster with
6+
containers and test nats cluster with Golang SDK while running unit tests.
7+
8+
## What are test-containers?
9+
10+
Test-containers is a package that makes it simple to create and clean up container-based
11+
dependencies for automated _integration/smoke_ tests.
712

813
We use _test-containers_ to run our dependent services like databases in a container
9-
hense we won't need to mock them or use real external services. This makes our uint tests more
10-
efficient and more reliable. Let's see an example.
14+
hence we won't need to mock them or use real external services. This makes our uint tests more
15+
efficient and more reliable.
1116

12-
## Redis container
17+
The clean, easy-to-use API enables developers
18+
to programmatically define containers that should
19+
be run as part of a test and clean up those
20+
resources when the test is done.
1321

14-
All we need for running a redis container with ```docker-compose``` is
15-
an image name and image version.
22+
## Example
1623

17-
These data are all in ```pkg/storage/redis/container.go```.
24+
In the following example, we are going to create a **Nats**
25+
container and test it.
1826

1927
```go
20-
const (
21-
// redis image information
22-
imageName = "redis"
23-
imageTag = "latest"
24-
)
28+
// container build request
29+
req := testcontainers.ContainerRequest{
30+
Image: "nats:latest",
31+
ExposedPorts: []string{"4222/tcp", "8222/tcp"},
32+
Cmd: []string{
33+
"--http_port 8222",
34+
"--cluster nats://0.0.0.0:6222",
35+
"--cluster_name NATS",
36+
},
37+
WaitingFor: wait.ForLog("Listening for client connections"),
38+
}
2539
```
2640

27-
Now we build our container with a request.
41+
The ```testcontainers.ContainerRequest``` describes how the Docker container will look.
42+
43+
- ```Image``` is the Docker image the container starts from.
44+
- ```ExposedPorts``` lists the ports to be exposed from the container.
45+
- ```Cmd``` is the commands that will be executed when container is set.
46+
- ```WaitingFor``` is a field you can use to validate when a container is ready. It is important to get this set because it helps to know when the container is ready to receive any traffic. In this case, we check for the logs we know come from Redis, telling us that it is ready to accept requests.
47+
48+
When you use ExposedPorts you have to imagine
49+
yourself using ```docker run -p <port>```.
50+
When you do so, dockerd maps the selected ```<port>``` from
51+
inside the container to a random one available on your host.
2852

2953
```go
30-
// container request
31-
req := testcontainers.ContainerRequest{
32-
Image: imageName + ":" + imageTag,
33-
ExposedPorts: []string{"6379/tcp"},
34-
WaitingFor: wait.ForLog("Ready to accept connections"),
35-
}
54+
// building a generic container
55+
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
56+
ContainerRequest: req,
57+
Started: true,
58+
})
3659
```
3760

38-
Now you can access container in your source codes.
61+
```testcontainers.GenericContainer``` creates the
62+
container.
63+
In this example we are using ```Started: true```.
64+
It means that the container function will wait for
65+
the container to be up and running.
66+
If you set the Start value to false it won't start,
67+
leaving to you the decision about when to start it.
3968

4069
```go
41-
ctx := context.Background()
70+
// cleaning container after test is complete
71+
t.Cleanup(func() {
72+
t.Log("terminating container")
73+
74+
if er := container.Terminate(ctx); er != nil {
75+
t.Errorf("failed to terminate container: :%v", er)
76+
}
77+
})
78+
```
4279

43-
// creating a new container.
44-
redisC, err := redis.CreateRedisContainer()
45-
if err != nil {
46-
t.Error(err)
80+
All the containers must be removed
81+
at some point, otherwise they will run until
82+
the host is overloaded.
83+
One of the ways we have to clean up is by deferring the terminated function:
84+
```defer container.Terminate(ctx)```.
4785

48-
return
49-
}
86+
## Talking to container
5087

51-
// get container connection.
52-
redisConnection, err := redisC.Endpoint(ctx, "")
53-
if err != nil {
54-
t.Error(err)
88+
```go
89+
// opening connection
90+
nc, er := nats.Connect(container.URI)
91+
if er != nil {
92+
t.Error(fmt.Errorf("connecting to nats container failed:\n\t%v\n", er))
5593

5694
return
5795
}
58-
```
5996

60-
## Test
61-
62-
Execute redis container test with following command:
63-
64-
```shell
65-
go test -v ./...
66-
```
97+
// async subscriber
98+
go func() {
99+
_, e := nc.Subscribe(natsTopic, func(m *nats.Msg) {
100+
log.Printf("Received a message:\n\t%s\n", string(m.Data))
101+
})
102+
if e != nil {
103+
t.Error(fmt.Errorf("subscribe over topic failed:\n\t%v\n", e))
104+
}
105+
}()
106+
107+
// publish over topic
108+
if e := nc.Publish(natsTopic, []byte(natsValue)); e != nil {
109+
t.Error(fmt.Errorf("publish over topic failed:\n\t%v\n", e))
110+
}
111+
```

go.mod

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@ module github.com/amirhnajafiz/testcontainers
22

33
go 1.19
44

5+
require (
6+
github.com/nats-io/nats.go v1.20.0
7+
github.com/testcontainers/testcontainers-go v0.15.0
8+
)
9+
510
require (
611
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
712
github.com/Microsoft/go-winio v0.5.2 // indirect
813
github.com/Microsoft/hcsshim v0.9.4 // indirect
914
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
10-
github.com/cespare/xxhash/v2 v2.1.2 // indirect
1115
github.com/containerd/cgroups v1.0.4 // indirect
1216
github.com/containerd/containerd v1.6.8 // indirect
13-
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
1417
github.com/docker/distribution v2.8.1+incompatible // indirect
1518
github.com/docker/docker v20.10.17+incompatible // indirect
1619
github.com/docker/go-connections v0.4.0 // indirect
1720
github.com/docker/go-units v0.5.0 // indirect
18-
github.com/go-redis/redis/v9 v9.0.0-rc.1 // indirect
1921
github.com/gogo/protobuf v1.3.2 // indirect
2022
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
2123
github.com/golang/protobuf v1.5.2 // indirect
@@ -25,15 +27,18 @@ require (
2527
github.com/moby/sys/mountinfo v0.6.2 // indirect
2628
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
2729
github.com/morikuni/aec v1.0.0 // indirect
30+
github.com/nats-io/nats-server/v2 v2.9.7 // indirect
31+
github.com/nats-io/nkeys v0.3.0 // indirect
32+
github.com/nats-io/nuid v1.0.1 // indirect
2833
github.com/opencontainers/go-digest v1.0.0 // indirect
2934
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
3035
github.com/opencontainers/runc v1.1.3 // indirect
3136
github.com/pkg/errors v0.9.1 // indirect
3237
github.com/sirupsen/logrus v1.8.1 // indirect
33-
github.com/testcontainers/testcontainers-go v0.15.0 // indirect
3438
go.opencensus.io v0.23.0 // indirect
39+
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
3540
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
36-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
41+
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
3742
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
3843
google.golang.org/grpc v1.47.0 // indirect
3944
google.golang.org/protobuf v1.28.0 // indirect

0 commit comments

Comments
 (0)