Skip to content

Commit febb04c

Browse files
authored
chore: expose SessionID (#1793)
* chore: expose session ID * chore: add tests for session ID * fix: use MustCompile
1 parent b90800d commit febb04c

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

testcontainer.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,28 @@
11
package testcontainers
2+
3+
import "github.com/testcontainers/testcontainers-go/internal/testcontainerssession"
4+
5+
// SessionID returns a unique session ID for the current test session. Because each Go package
6+
// will be run in a separate process, we need a way to identify the current test session.
7+
// By test session, we mean:
8+
// - a single "go test" invocation (including flags)
9+
// - a single "go test ./..." invocation (including flags)
10+
// - the execution of a single test or a set of tests using the IDE
11+
//
12+
// As a consequence, with the sole goal of aggregating test execution across multiple
13+
// packages, this variable will contain the value of the parent process ID (pid) of the current process
14+
// and its creation date, to use it to generate a unique session ID. We are using the parent pid because
15+
// the current process will be a child process of:
16+
// - the process that is running the tests, e.g.: "go test";
17+
// - the process that is running the application in development mode, e.g. "go run main.go -tags dev";
18+
// - the process that is running the tests in the IDE, e.g.: "go test ./...".
19+
//
20+
// Finally, we will hash the combination of the "testcontainers-go:" string with the parent pid
21+
// and the creation date of that parent process to generate a unique session ID.
22+
//
23+
// This sessionID will be used to:
24+
// - identify the test session, aggregating the test execution of multiple packages in the same test session.
25+
// - tag the containers created by testcontainers-go, adding a label to the container with the session ID.
26+
func SessionID() string {
27+
return testcontainerssession.SessionID()
28+
}

testcontainers_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package testcontainers
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"regexp"
8+
"testing"
9+
)
10+
11+
func TestSessionID(t *testing.T) {
12+
t.Run("SessionID() returns a non-empty string", func(t *testing.T) {
13+
sessionID := SessionID()
14+
if sessionID == "" {
15+
t.Error("SessionID() returned an empty string")
16+
}
17+
})
18+
19+
t.Run("Multiple calls to SessionID() return the same value", func(t *testing.T) {
20+
sessionID1 := SessionID()
21+
sessionID2 := SessionID()
22+
if sessionID1 != sessionID2 {
23+
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
24+
}
25+
})
26+
27+
t.Run("Multiple calls to SessionID() in multiple goroutines return the same value", func(t *testing.T) {
28+
sessionID1 := ""
29+
sessionID2 := ""
30+
31+
done := make(chan bool)
32+
go func() {
33+
sessionID1 = SessionID()
34+
done <- true
35+
}()
36+
37+
go func() {
38+
sessionID2 = SessionID()
39+
done <- true
40+
}()
41+
42+
<-done
43+
<-done
44+
45+
if sessionID1 != sessionID2 {
46+
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
47+
}
48+
})
49+
50+
t.Run("SessionID() from different child processes returns the same value", func(t *testing.T) {
51+
args := []string{"test", "./...", "-v", "-run", "TestSessionIDHelper"}
52+
env := append(os.Environ(), "TESTCONTAINERS_SESSION_ID_HELPER=1")
53+
54+
re := regexp.MustCompile(">>>(.*)<<<")
55+
56+
cmd1 := exec.Command("go", args...)
57+
cmd1.Env = env
58+
stdoutStderr1, err := cmd1.CombinedOutput()
59+
if err != nil {
60+
t.Errorf("cmd1.Run() failed with %s", err)
61+
}
62+
sessionID1 := re.FindString(string(stdoutStderr1))
63+
64+
cmd2 := exec.Command("go", args...)
65+
cmd2.Env = env
66+
stdoutStderr2, err := cmd2.CombinedOutput()
67+
if err != nil {
68+
t.Errorf("cmd2.Run() failed with %s", err)
69+
}
70+
sessionID2 := re.FindString(string(stdoutStderr2))
71+
72+
if sessionID1 != sessionID2 {
73+
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
74+
}
75+
})
76+
}
77+
78+
// Not a real test, used to print out the session ID
79+
func TestSessionIDHelper(t *testing.T) {
80+
if os.Getenv("TESTCONTAINERS_SESSION_ID_HELPER") == "" {
81+
t.Skip("Not a real test, used as a test helper")
82+
}
83+
84+
fmt.Printf(">>>%s<<<\n", SessionID())
85+
}

0 commit comments

Comments
 (0)