Skip to content

Commit

Permalink
Merge pull request #198 from dvulpe/fix_192
Browse files Browse the repository at this point in the history
fixes #192 - guard access to reaper with a mutex
  • Loading branch information
gianarb authored May 24, 2020
2 parents dfa4f8f + 6d72535 commit 50c8baf
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
41 changes: 41 additions & 0 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"archive/tar"
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"strings"
Expand Down Expand Up @@ -303,3 +304,43 @@ func Test_GetLogsFromFailedContainer(t *testing.T) {
t.Fatalf("could not find expected log in %s", log)
}
}

func TestShouldStartContainersInParallel(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
t.Cleanup(cancel)

for i := 0; i < 3; i++ {
t.Run(fmt.Sprintf("iteration_%d", i), func(t *testing.T) {
t.Parallel()
createTestContainer(t, ctx)
})
}
}

func createTestContainer(t *testing.T, ctx context.Context) int {
req := ContainerRequest{
Image: "localstack/localstack:latest",
ExposedPorts: []string{"4584/tcp", "8080/tcp"},
Env: map[string]string{
"SERVICES": "secretsmanager",
},
WaitingFor: wait.ForListeningPort("4584/tcp"),
}
container, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
t.Fatalf("could not start container: %v", err)
}
port, err := container.MappedPort(ctx, "4584")
if err != nil {
t.Fatalf("could not get mapped port: %v", err)
}

t.Cleanup(func() {
container.Terminate(context.Background())
})

return port.Int()
}
4 changes: 4 additions & 0 deletions reaper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/testcontainers/testcontainers-go/wait"
"net"
"strings"
"sync"
"time"

"github.com/pkg/errors"
Expand All @@ -22,6 +23,7 @@ const (
)

var reaper *Reaper // We would like to create reaper only once
var mutex sync.Mutex

// ReaperProvider represents a provider for the reaper to run itself with
// The ContainerProvider interface should usually satisfy this as well, so it is pluggable
Expand All @@ -38,6 +40,8 @@ type Reaper struct {

// NewReaper creates a Reaper with a sessionID to identify containers and a provider to use
func NewReaper(ctx context.Context, sessionID string, provider ReaperProvider, reaperImageName string) (*Reaper, error) {
mutex.Lock()
defer mutex.Unlock()
// If reaper already exists re-use it
if reaper != nil {
return reaper, nil
Expand Down

0 comments on commit 50c8baf

Please sign in to comment.