Skip to content

Commit 748f9f4

Browse files
authored
Merge branch 'main' into k6-cache-auto-cleanup
2 parents 4fd6985 + d43fae3 commit 748f9f4

File tree

10 files changed

+135
-22
lines changed

10 files changed

+135
-22
lines changed

Pipfile.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docker.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type DockerContainer struct {
6767
consumers []LogConsumer
6868
raw *types.ContainerJSON
6969
stopProducer chan bool
70+
producerDone chan bool
7071
logger Logging
7172
lifecycleHooks []ContainerLifecycleHooks
7273
}
@@ -616,8 +617,12 @@ func (c *DockerContainer) StartLogProducer(ctx context.Context) error {
616617
}
617618

618619
c.stopProducer = make(chan bool)
620+
c.producerDone = make(chan bool)
621+
622+
go func(stop <-chan bool, done chan<- bool) {
623+
// signal the producer is done once go routine exits, this prevents race conditions around start/stop
624+
defer close(done)
619625

620-
go func(stop <-chan bool) {
621626
since := ""
622627
// if the socket is closed we will make additional logs request with updated Since timestamp
623628
BEGIN:
@@ -702,7 +707,7 @@ func (c *DockerContainer) StartLogProducer(ctx context.Context) error {
702707
}
703708
}
704709
}
705-
}(c.stopProducer)
710+
}(c.stopProducer, c.producerDone)
706711

707712
return nil
708713
}
@@ -712,7 +717,10 @@ func (c *DockerContainer) StartLogProducer(ctx context.Context) error {
712717
func (c *DockerContainer) StopLogProducer() error {
713718
if c.stopProducer != nil {
714719
c.stopProducer <- true
720+
// block until the producer is actually done in order to avoid strange races
721+
<-c.producerDone
715722
c.stopProducer = nil
723+
c.producerDone = nil
716724
}
717725
return nil
718726
}

generic.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"github.com/docker/docker/api/types/container"
1212
"github.com/docker/docker/api/types/network"
1313

14+
"github.com/testcontainers/testcontainers-go/internal/testcontainersdocker"
15+
"github.com/testcontainers/testcontainers-go/internal/testcontainerssession"
1416
"github.com/testcontainers/testcontainers-go/wait"
1517
)
1618

@@ -204,3 +206,8 @@ type GenericProvider interface {
204206
NetworkProvider
205207
ImageProvider
206208
}
209+
210+
// GenericLabels returns a map of labels that can be used to identify containers created by this library
211+
func GenericLabels() map[string]string {
212+
return testcontainersdocker.DefaultLabels(testcontainerssession.SessionID())
213+
}

modules/localstack/examples_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ package localstack_test
33
import (
44
"context"
55
"fmt"
6+
"io"
7+
"path/filepath"
68
"time"
79

810
"github.com/testcontainers/testcontainers-go"
11+
"github.com/testcontainers/testcontainers-go/exec"
912
"github.com/testcontainers/testcontainers-go/modules/localstack"
1013
"github.com/testcontainers/testcontainers-go/wait"
1114
)
@@ -113,3 +116,86 @@ func ExampleRunContainer_legacyMode() {
113116
// Output:
114117
// version=localstack/localstack:0.10.0. Testcontainers for Go does not support running LocalStack in legacy mode. Please use a version >= 0.11.0
115118
}
119+
120+
func ExampleRunContainer_usingLambdas() {
121+
ctx := context.Background()
122+
123+
flagsFn := func() string {
124+
labels := testcontainers.GenericLabels()
125+
126+
flags := ""
127+
for k, v := range labels {
128+
flags = fmt.Sprintf("%s -l %s=%s", flags, k, v)
129+
}
130+
131+
return flags
132+
}
133+
134+
lambdaName := "localstack-lambda-url-example"
135+
136+
container, err := localstack.RunContainer(ctx,
137+
testcontainers.WithImage("localstack/localstack:2.3.0"),
138+
testcontainers.CustomizeRequest(testcontainers.GenericContainerRequest{
139+
ContainerRequest: testcontainers.ContainerRequest{
140+
Env: map[string]string{
141+
"SERVICES": "lambda",
142+
"LAMBDA_DOCKER_FLAGS": flagsFn(),
143+
},
144+
Files: []testcontainers.ContainerFile{
145+
{
146+
HostFilePath: filepath.Join("testdata", "function.zip"),
147+
ContainerFilePath: "/tmp/function.zip",
148+
},
149+
},
150+
},
151+
}),
152+
)
153+
if err != nil {
154+
panic(err)
155+
}
156+
defer func() {
157+
err := container.Terminate(ctx)
158+
if err != nil {
159+
panic(err)
160+
}
161+
}()
162+
163+
// the three commands below are doing the following:
164+
// 1. create a lambda function
165+
// 2. wait for the lambda function to be active
166+
// 3. invoke the lambda function with a payload, writing the result to the output.txt file
167+
lambdaCommands := [][]string{
168+
{
169+
"awslocal", "lambda",
170+
"create-function", "--function-name", lambdaName,
171+
"--runtime", "nodejs18.x",
172+
"--zip-file",
173+
"fileb:///tmp/function.zip",
174+
"--handler", "index.handler",
175+
"--role", "arn:aws:iam::000000000000:role/lambda-role",
176+
},
177+
{"awslocal", "lambda", "wait", "function-active-v2", "--function-name", lambdaName},
178+
{"awslocal", "lambda", "invoke", "--function-name", lambdaName, "--payload", `{"body": "{\"num1\": \"10\", \"num2\": \"10\"}" }`, "output.txt"},
179+
}
180+
for _, cmd := range lambdaCommands {
181+
_, _, err = container.Exec(ctx, cmd)
182+
if err != nil {
183+
panic(err)
184+
}
185+
}
186+
187+
// the output.txt file lives in the WORKDIR of the localstack container
188+
_, reader, err := container.Exec(ctx, []string{"cat", "output.txt"}, exec.Multiplexed())
189+
if err != nil {
190+
panic(err)
191+
}
192+
193+
content, err := io.ReadAll(reader)
194+
if err != nil {
195+
panic(err)
196+
}
197+
fmt.Println(string(content))
198+
199+
// Output:
200+
// {"statusCode":200,"body":"The product of 10 and 10 is 100"}
201+
}

modules/localstack/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/aws/aws-sdk-go-v2/config v1.18.44
99
github.com/aws/aws-sdk-go-v2/credentials v1.13.42
1010
github.com/aws/aws-sdk-go-v2/service/s3 v1.40.1
11+
github.com/docker/docker v24.0.6+incompatible
1112
github.com/docker/go-connections v0.4.0
1213
github.com/stretchr/testify v1.8.4
1314
github.com/testcontainers/testcontainers-go v0.25.0
@@ -38,7 +39,6 @@ require (
3839
github.com/cpuguy83/dockercfg v0.3.1 // indirect
3940
github.com/davecgh/go-spew v1.1.1 // indirect
4041
github.com/docker/distribution v2.8.2+incompatible // indirect
41-
github.com/docker/docker v24.0.6+incompatible // indirect
4242
github.com/docker/go-units v0.5.0 // indirect
4343
github.com/go-ole/go-ole v1.2.6 // indirect
4444
github.com/gogo/protobuf v1.3.2 // indirect

modules/localstack/localstack.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77
"time"
88

9+
"github.com/docker/docker/api/types/container"
910
"golang.org/x/mod/semver"
1011

1112
"github.com/testcontainers/testcontainers-go"
@@ -92,10 +93,12 @@ func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomize
9293

9394
req := testcontainers.ContainerRequest{
9495
Image: fmt.Sprintf("localstack/localstack:%s", defaultVersion),
95-
Binds: []string{fmt.Sprintf("%s:/var/run/docker.sock", dockerHost)},
9696
WaitingFor: wait.ForHTTP("/_localstack/health").WithPort("4566/tcp").WithStartupTimeout(120 * time.Second),
9797
ExposedPorts: []string{fmt.Sprintf("%d/tcp", defaultPort)},
9898
Env: map[string]string{},
99+
HostConfigModifier: func(hostConfig *container.HostConfig) {
100+
hostConfig.Binds = []string{fmt.Sprintf("%s:/var/run/docker.sock", dockerHost)}
101+
},
99102
}
100103

101104
localStackReq := LocalStackContainerRequest{
337 Bytes
Binary file not shown.

modules/localstack/testdata/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
exports.handler = async (event) => {
2+
let body = JSON.parse(event.body)
3+
const product = body.num1 * body.num2;
4+
const response = {
5+
statusCode: 200,
6+
body: "The product of " + body.num1 + " and " + body.num2 + " is " + product,
7+
};
8+
return response;
9+
};

modules/nats/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/moby/sys/sequential v0.5.0 // indirect
3131
github.com/moby/term v0.5.0 // indirect
3232
github.com/morikuni/aec v1.0.0 // indirect
33-
github.com/nats-io/nats-server/v2 v2.9.21 // indirect
33+
github.com/nats-io/nats-server/v2 v2.9.23 // indirect
3434
github.com/nats-io/nkeys v0.4.5 // indirect
3535
github.com/nats-io/nuid v1.0.1 // indirect
3636
github.com/opencontainers/go-digest v1.0.0 // indirect

modules/nats/go.sum

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
5555
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
5656
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
5757
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
58-
github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
59-
github.com/nats-io/nats-server/v2 v2.9.21 h1:2TBTh0UDE74eNXQmV4HofsmRSCiVN0TH2Wgrp6BD6fk=
60-
github.com/nats-io/nats-server/v2 v2.9.21/go.mod h1:ozqMZc2vTHcNcblOiXMWIXkf8+0lDGAi5wQcG+O1mHU=
58+
github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak=
59+
github.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU=
60+
github.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0=
6161
github.com/nats-io/nats.go v1.30.2 h1:aloM0TGpPorZKQhbAkdCzYDj+ZmsJDyeo3Gkbr72NuY=
6262
github.com/nats-io/nats.go v1.30.2/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM=
6363
github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk=

0 commit comments

Comments
 (0)