diff --git a/docker.go b/docker.go index 252d94ec7c..2633408be6 100644 --- a/docker.go +++ b/docker.go @@ -32,8 +32,8 @@ import ( tcexec "github.com/testcontainers/testcontainers-go/exec" "github.com/testcontainers/testcontainers-go/internal/config" + "github.com/testcontainers/testcontainers-go/internal/core" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" - "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" "github.com/testcontainers/testcontainers-go/wait" ) @@ -877,7 +877,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque // the reaper does not need to start a reaper for itself isReaperContainer := strings.HasSuffix(imageName, config.ReaperDefaultImage) if !tcConfig.RyukDisabled && !isReaperContainer { - r, err := reuseOrCreateReaper(context.WithValue(ctx, testcontainersdocker.DockerHostContextKey, p.host), testcontainerssession.SessionID(), p) + r, err := reuseOrCreateReaper(context.WithValue(ctx, testcontainersdocker.DockerHostContextKey, p.host), core.SessionID(), p) if err != nil { return nil, fmt.Errorf("%w: creating reaper failed", err) } @@ -973,7 +973,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque if !isReaperContainer { // add the labels that the reaper will use to terminate the container to the request - for k, v := range testcontainersdocker.DefaultLabels(testcontainerssession.SessionID()) { + for k, v := range testcontainersdocker.DefaultLabels(core.SessionID()) { req.Labels[k] = v } } @@ -1080,7 +1080,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque Image: imageName, imageWasBuilt: req.ShouldBuildImage(), keepBuiltImage: req.ShouldKeepBuiltImage(), - sessionID: testcontainerssession.SessionID(), + sessionID: core.SessionID(), provider: p, terminationSignal: termSignal, stopProducer: nil, @@ -1127,7 +1127,7 @@ func (p *DockerProvider) ReuseOrCreateContainer(ctx context.Context, req Contain return p.CreateContainer(ctx, req) } - sessionID := testcontainerssession.SessionID() + sessionID := core.SessionID() tcConfig := p.Config().Config @@ -1298,7 +1298,7 @@ func (p *DockerProvider) CreateNetwork(ctx context.Context, req NetworkRequest) IPAM: req.IPAM, } - sessionID := testcontainerssession.SessionID() + sessionID := core.SessionID() var termSignal chan bool if !tcConfig.RyukDisabled { @@ -1409,7 +1409,7 @@ func (p *DockerProvider) getDefaultNetwork(ctx context.Context, cli client.APICl _, err = cli.NetworkCreate(ctx, reaperNetwork, types.NetworkCreate{ Driver: Bridge, Attachable: true, - Labels: testcontainersdocker.DefaultLabels(testcontainerssession.SessionID()), + Labels: testcontainersdocker.DefaultLabels(core.SessionID()), }) if err != nil { @@ -1440,7 +1440,7 @@ func containerFromDockerResponse(ctx context.Context, response types.Container) } container.provider = provider - container.sessionID = testcontainerssession.SessionID() + container.sessionID = core.SessionID() container.consumers = []LogConsumer{} container.stopProducer = nil container.isRunning = response.State == "running" diff --git a/docker_client.go b/docker_client.go index 87ea18192b..6523040ffb 100644 --- a/docker_client.go +++ b/docker_client.go @@ -10,8 +10,8 @@ import ( "github.com/docker/docker/api/types/registry" "github.com/docker/docker/client" + "github.com/testcontainers/testcontainers-go/internal/core" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" - "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" ) // DockerClient is a wrapper around the docker client that is used by testcontainers-go. @@ -68,8 +68,8 @@ func (c *DockerClient) Info(ctx context.Context) (types.Info, error) { dockerInfo.OperatingSystem, dockerInfo.MemTotal/1024/1024, testcontainersdocker.ExtractDockerHost(ctx), testcontainersdocker.ExtractDockerSocket(ctx), - testcontainerssession.SessionID(), - testcontainerssession.ProcessID(), + core.SessionID(), + core.ProcessID(), ) return dockerInfo, nil diff --git a/generic.go b/generic.go index 837d0191f7..bd5f34c8e7 100644 --- a/generic.go +++ b/generic.go @@ -6,8 +6,8 @@ import ( "fmt" "sync" + "github.com/testcontainers/testcontainers-go/internal/core" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" - "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" ) var ( @@ -94,5 +94,5 @@ type GenericProvider interface { // GenericLabels returns a map of labels that can be used to identify containers created by this library func GenericLabels() map[string]string { - return testcontainersdocker.DefaultLabels(testcontainerssession.SessionID()) + return testcontainersdocker.DefaultLabels(core.SessionID()) } diff --git a/internal/testcontainerssession/session.go b/internal/core/bootstrap.go similarity index 79% rename from internal/testcontainerssession/session.go rename to internal/core/bootstrap.go index 7ce57d6c27..cf06dde7e2 100644 --- a/internal/testcontainerssession/session.go +++ b/internal/core/bootstrap.go @@ -1,4 +1,4 @@ -package testcontainerssession +package core import ( "crypto/sha256" @@ -32,6 +32,11 @@ import ( // - tag the containers created by testcontainers-go, adding a label to the container with the session ID. var sessionID string +// projectPath returns the current working directory of the parent test process running Testcontainers for Go. +// If it's not possible to get that directory, the library will use the current working directory. If again +// it's not possible to get the current working directory, the library will use a temporary directory. +var projectPath string + // processID returns a unique ID for the current test process. Because each Go package will be run in a separate process, // we need a way to identify the current test process, in the form of an UUID var processID string @@ -43,10 +48,16 @@ func init() { parentPid := os.Getppid() var createTime int64 + fallbackCwd, err := os.Getwd() + if err != nil { + // very unlinke to fail, but if it does, we will use a temp dir + fallbackCwd = os.TempDir() + } processes, err := process.Processes() if err != nil { sessionID = uuid.New().String() + projectPath = fallbackCwd return } @@ -55,6 +66,12 @@ func init() { continue } + cwd, err := p.Cwd() + if err != nil { + cwd = fallbackCwd + } + projectPath = cwd + t, err := p.CreateTime() if err != nil { sessionID = uuid.New().String() @@ -79,6 +96,10 @@ func ProcessID() string { return processID } +func ProjectPath() string { + return projectPath +} + func SessionID() string { return sessionID } diff --git a/internal/testcontainersdocker/client.go b/internal/testcontainersdocker/client.go index e4b871400d..44f7f2c2f4 100644 --- a/internal/testcontainersdocker/client.go +++ b/internal/testcontainersdocker/client.go @@ -8,7 +8,7 @@ import ( "github.com/testcontainers/testcontainers-go/internal" "github.com/testcontainers/testcontainers-go/internal/config" - "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" + "github.com/testcontainers/testcontainers-go/internal/core" ) // NewClient returns a new docker client extracting the docker host from the different alternatives @@ -33,7 +33,8 @@ func NewClient(ctx context.Context, ops ...client.Opt) (*client.Client, error) { opts = append(opts, client.WithHTTPHeaders( map[string]string{ - "x-tc-sid": testcontainerssession.SessionID(), + "x-tc-pp": core.ProjectPath(), + "x-tc-sid": core.SessionID(), "User-Agent": "tc-go/" + internal.Version, }), ) diff --git a/reaper_test.go b/reaper_test.go index 4657e1ba09..1090afd181 100644 --- a/reaper_test.go +++ b/reaper_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go/internal/config" + "github.com/testcontainers/testcontainers-go/internal/core" "github.com/testcontainers/testcontainers-go/internal/testcontainersdocker" - "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" "github.com/testcontainers/testcontainers-go/wait" ) @@ -134,7 +134,7 @@ func TestContainerStartsWithoutTheReaper(t *testing.T) { require.NoError(t, err) terminateContainerOnEnd(t, ctx, container) - sessionID := testcontainerssession.SessionID() + sessionID := core.SessionID() reaperContainer, err := lookUpReaperContainer(ctx, sessionID) if err != nil { @@ -169,7 +169,7 @@ func TestContainerStartsWithTheReaper(t *testing.T) { } terminateContainerOnEnd(t, ctx, c) - sessionID := testcontainerssession.SessionID() + sessionID := core.SessionID() reaperContainer, err := lookUpReaperContainer(ctx, sessionID) if err != nil { diff --git a/testcontainer.go b/testcontainer.go index 3410e06b80..0b39231533 100644 --- a/testcontainer.go +++ b/testcontainer.go @@ -1,6 +1,6 @@ package testcontainers -import "github.com/testcontainers/testcontainers-go/internal/testcontainerssession" +import "github.com/testcontainers/testcontainers-go/internal/core" // SessionID returns a unique session ID for the current test session. Because each Go package // will be run in a separate process, we need a way to identify the current test session. @@ -24,5 +24,5 @@ import "github.com/testcontainers/testcontainers-go/internal/testcontainerssessi // - identify the test session, aggregating the test execution of multiple packages in the same test session. // - tag the containers created by testcontainers-go, adding a label to the container with the session ID. func SessionID() string { - return testcontainerssession.SessionID() + return core.SessionID() }