@@ -20,6 +20,7 @@ import (
2020 "crypto/rand"
2121 "encoding/hex"
2222 "fmt"
23+ "regexp"
2324 "strings"
2425 "testing"
2526
@@ -38,11 +39,11 @@ func TestRunBuildOnce(t *testing.T) {
3839 _ = c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once.yaml" , "down" , "--rmi" , "local" , "--remove-orphans" , "-v" )
3940 res := c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once.yaml" , "--verbose" , "run" , "--build" , "--rm" , "curl" )
4041
41- // Count how many times nginx was built by looking for its unique RUN command output
42- nginxBuilds := strings .Count (res .Stdout (), "Building nginx at" )
42+ output := res .Stdout ()
43+
44+ nginxBuilds := countServiceBuilds (output , projectName , "nginx" )
4345
44- // nginx should build exactly once, not twice
45- assert .Equal (t , nginxBuilds , 1 , "nginx dependency should build once, but built %d times" , nginxBuilds )
46+ assert .Equal (t , nginxBuilds , 1 , "nginx should build once, built %d times\n Output:\n %s" , nginxBuilds , output )
4647 assert .Assert (t , strings .Contains (res .Stdout (), "curl service" ))
4748
4849 c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once.yaml" , "down" , "--remove-orphans" )
@@ -55,13 +56,9 @@ func TestRunBuildOnce(t *testing.T) {
5556
5657 output := res .Stdout ()
5758
58- dbBuildMarker := fmt .Sprintf ("naming to docker.io/library/%s-db" , projectName )
59- apiBuildMarker := fmt .Sprintf ("naming to docker.io/library/%s-api" , projectName )
60- appBuildMarker := fmt .Sprintf ("naming to docker.io/library/%s-app" , projectName )
61-
62- dbBuilds := strings .Count (output , dbBuildMarker )
63- apiBuilds := strings .Count (output , apiBuildMarker )
64- appBuilds := strings .Count (output , appBuildMarker )
59+ dbBuilds := countServiceBuilds (output , projectName , "db" )
60+ apiBuilds := countServiceBuilds (output , projectName , "api" )
61+ appBuilds := countServiceBuilds (output , projectName , "app" )
6562
6663 assert .Equal (t , dbBuilds , 1 , "db should build once, built %d times\n Output:\n %s" , dbBuilds , output )
6764 assert .Equal (t , apiBuilds , 1 , "api should build once, built %d times\n Output:\n %s" , apiBuilds , output )
@@ -76,15 +73,24 @@ func TestRunBuildOnce(t *testing.T) {
7673 _ = c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once-no-deps.yaml" , "down" , "--rmi" , "local" , "--remove-orphans" )
7774 res := c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once-no-deps.yaml" , "run" , "--build" , "--rm" , "simple" )
7875
79- // Should build exactly once
80- simpleBuilds := strings .Count (res .Stdout (), "Simple service built at" )
81- assert .Equal (t , simpleBuilds , 1 , "simple should build once, built %d times" , simpleBuilds )
76+ output := res .Stdout ()
77+
78+ simpleBuilds := countServiceBuilds (output , projectName , "simple" )
79+
80+ assert .Equal (t , simpleBuilds , 1 , "simple should build once, built %d times\n Output:\n %s" , simpleBuilds , output )
8281 assert .Assert (t , strings .Contains (res .Stdout (), "Simple service" ))
8382
8483 c .RunDockerComposeCmd (t , "-p" , projectName , "-f" , "./fixtures/run-test/build-once-no-deps.yaml" , "down" , "--remove-orphans" )
8584 })
8685}
8786
87+ // countServiceBuilds counts how many times a service was built by matching
88+ // the "naming to *{projectName}-{serviceName}* done" pattern in the output
89+ func countServiceBuilds (output , projectName , serviceName string ) int {
90+ pattern := regexp .MustCompile (`naming to .*` + regexp .QuoteMeta (projectName ) + `-` + regexp .QuoteMeta (serviceName ) + `.* done` )
91+ return len (pattern .FindAllString (output , - 1 ))
92+ }
93+
8894// randomProjectName generates a unique project name for parallel test execution
8995// Format: prefix-<8 random hex chars> (e.g., "build-once-3f4a9b2c")
9096func randomProjectName (prefix string ) string {
0 commit comments