Skip to content

Commit 607c474

Browse files
committed
fix: avoid breaking changes
1 parent e837788 commit 607c474

File tree

1 file changed

+50
-3
lines changed

1 file changed

+50
-3
lines changed

internal/core/bootstrap.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
11
package core
22

33
import (
4+
"crypto/sha256"
5+
"encoding/hex"
6+
"fmt"
47
"os"
58

69
"github.com/google/uuid"
710
"github.com/shirou/gopsutil/v4/process"
811
"github.com/testcontainers/testcontainers-go/internal/config"
912
)
1013

11-
// sessionID returns a unique session ID for the current test session.
14+
// sessionID returns a unique session ID for the current test session. Because each Go package
15+
// will be run in a separate process, we need a way to identify the current test session.
16+
// By test session, we mean:
17+
// - a single "go test" invocation (including flags)
18+
// - a single "go test ./..." invocation (including flags)
19+
// - the execution of a single test or a set of tests using the IDE
20+
//
21+
// As a consequence, with the sole goal of aggregating test execution across multiple
22+
// packages, this function will use the parent process ID (pid) of the current process
23+
// and its creation date, to use it to generate a unique session ID. We are using the parent pid because
24+
// the current process will be a child process of:
25+
// - the process that is running the tests, e.g.: "go test";
26+
// - the process that is running the application in development mode, e.g. "go run main.go -tags dev";
27+
// - the process that is running the tests in the IDE, e.g.: "go test ./...".
28+
//
29+
// Finally, we will hash the combination of the "testcontainers-go:" string with the parent pid
30+
// and the creation date of that parent process to generate a unique session ID.
31+
//
32+
// This sessionID will be used to:
33+
// - identify the test session, aggregating the test execution of multiple packages in the same test session.
34+
// - tag the containers created by testcontainers-go, adding a label to the container with the session ID.
1235
var sessionID string
1336

1437
// projectPath returns the current working directory of the parent test process running Testcontainers for Go.
@@ -20,17 +43,18 @@ var projectPath string
2043
// we need a way to identify the current test process, in the form of a UUID
2144
var processID string
2245

46+
const sessionIDPlaceholder = "testcontainers-go:%d:%d"
47+
2348
func init() {
2449
cfg := config.Read()
2550
if cfg.SessionID != "" {
2651
sessionID = cfg.SessionID
27-
} else {
28-
sessionID = uuid.New().String()
2952
}
3053

3154
processID = uuid.New().String()
3255

3356
parentPid := os.Getppid()
57+
var createTime int64
3458
fallbackCwd, err := os.Getwd()
3559
if err != nil {
3660
// very unlikely to fail, but if it does, we will use a temp dir
@@ -39,6 +63,9 @@ func init() {
3963

4064
processes, err := process.Processes()
4165
if err != nil {
66+
if sessionID == "" {
67+
sessionID = uuid.New().String()
68+
}
4269
projectPath = fallbackCwd
4370
return
4471
}
@@ -54,8 +81,28 @@ func init() {
5481
}
5582
projectPath = cwd
5683

84+
t, err := p.CreateTime()
85+
if err != nil {
86+
if sessionID == "" {
87+
sessionID = uuid.New().String()
88+
}
89+
return
90+
}
91+
92+
createTime = t
5793
break
5894
}
95+
96+
if sessionID == "" {
97+
hasher := sha256.New()
98+
_, err = fmt.Fprintf(hasher, sessionIDPlaceholder, parentPid, createTime)
99+
if err != nil {
100+
sessionID = uuid.New().String()
101+
return
102+
}
103+
104+
sessionID = hex.EncodeToString(hasher.Sum(nil))
105+
}
59106
}
60107

61108
func ProcessID() string {

0 commit comments

Comments
 (0)