Skip to content

Commit

Permalink
chore: expose SessionID (#1793)
Browse files Browse the repository at this point in the history
* chore: expose session ID

* chore: add tests for session ID

* fix: use MustCompile
  • Loading branch information
mdelapenya authored Oct 25, 2023
1 parent b90800d commit febb04c
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
27 changes: 27 additions & 0 deletions testcontainer.go
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
package testcontainers

import "github.com/testcontainers/testcontainers-go/internal/testcontainerssession"

// 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.
// By test session, we mean:
// - a single "go test" invocation (including flags)
// - a single "go test ./..." invocation (including flags)
// - the execution of a single test or a set of tests using the IDE
//
// As a consequence, with the sole goal of aggregating test execution across multiple
// packages, this variable will contain the value of the parent process ID (pid) of the current process
// and its creation date, to use it to generate a unique session ID. We are using the parent pid because
// the current process will be a child process of:
// - the process that is running the tests, e.g.: "go test";
// - the process that is running the application in development mode, e.g. "go run main.go -tags dev";
// - the process that is running the tests in the IDE, e.g.: "go test ./...".
//
// Finally, we will hash the combination of the "testcontainers-go:" string with the parent pid
// and the creation date of that parent process to generate a unique session ID.
//
// This sessionID will be used to:
// - 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()
}
85 changes: 85 additions & 0 deletions testcontainers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package testcontainers

import (
"fmt"
"os"
"os/exec"
"regexp"
"testing"
)

func TestSessionID(t *testing.T) {
t.Run("SessionID() returns a non-empty string", func(t *testing.T) {
sessionID := SessionID()
if sessionID == "" {
t.Error("SessionID() returned an empty string")
}
})

t.Run("Multiple calls to SessionID() return the same value", func(t *testing.T) {
sessionID1 := SessionID()
sessionID2 := SessionID()
if sessionID1 != sessionID2 {
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
}
})

t.Run("Multiple calls to SessionID() in multiple goroutines return the same value", func(t *testing.T) {
sessionID1 := ""
sessionID2 := ""

done := make(chan bool)
go func() {
sessionID1 = SessionID()
done <- true
}()

go func() {
sessionID2 = SessionID()
done <- true
}()

<-done
<-done

if sessionID1 != sessionID2 {
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
}
})

t.Run("SessionID() from different child processes returns the same value", func(t *testing.T) {
args := []string{"test", "./...", "-v", "-run", "TestSessionIDHelper"}
env := append(os.Environ(), "TESTCONTAINERS_SESSION_ID_HELPER=1")

re := regexp.MustCompile(">>>(.*)<<<")

cmd1 := exec.Command("go", args...)
cmd1.Env = env
stdoutStderr1, err := cmd1.CombinedOutput()
if err != nil {
t.Errorf("cmd1.Run() failed with %s", err)
}
sessionID1 := re.FindString(string(stdoutStderr1))

cmd2 := exec.Command("go", args...)
cmd2.Env = env
stdoutStderr2, err := cmd2.CombinedOutput()
if err != nil {
t.Errorf("cmd2.Run() failed with %s", err)
}
sessionID2 := re.FindString(string(stdoutStderr2))

if sessionID1 != sessionID2 {
t.Errorf("SessionID() returned different values: %s != %s", sessionID1, sessionID2)
}
})
}

// Not a real test, used to print out the session ID
func TestSessionIDHelper(t *testing.T) {
if os.Getenv("TESTCONTAINERS_SESSION_ID_HELPER") == "" {
t.Skip("Not a real test, used as a test helper")
}

fmt.Printf(">>>%s<<<\n", SessionID())
}

0 comments on commit febb04c

Please sign in to comment.