Skip to content

Commit 08b8020

Browse files
jonathanspwcopybara-github
authored andcommitted
Copybara import of the project:
-- 4eb3f49 by Jonathan Wright <jonathan@almalinux.org>: Build test_suites concurrently in local_build.sh with a capped pool Default cap is (nproc-1)/3 (floor 1), matching the ~3 hot worker processes each `go test -c` spawns (compile, vet, link). Pass -j N to override; -j 0 restores the auto formula. A FIFO semaphore throttles to $jobs concurrent suites; each suite still builds its 4 GOOS/GOARCH variants serially inside the slot. On a 32-core host this cuts a cold all-suites build from ~5m29s to ~2m30s (-54%) and self-throttles cleanly on smaller hardware (4 cores → K=1, effectively serial). FUTURE_COPYBARA_INTEGRATE_REVIEW=#510 from jonathanspw:local_build_parallel 4eb3f49 PiperOrigin-RevId: 926948257
1 parent 8ebe3c1 commit 08b8020

1 file changed

Lines changed: 67 additions & 18 deletions

File tree

local_build.sh

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,33 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
# usage: local_build.sh -o $outspath -i $imagetestroot -s $suites_to_build
16+
# usage: local_build.sh -o $outspath -i $imagetestroot -s $suites_to_build -j $jobs
1717
# the output path of the test files
1818
outpath=.
1919
# the suites to build, space separated. all suites are built by default
2020
suites=*
2121
# the path to the imagetest folder, default value assumes this script is run from the imagetest folder. If set, the commands cd $imagetestroot/cmd and cd $imagetestroot/test_suites should succeed.
2222
imagetestroot=.
23+
# max suites to build concurrently. 0 means auto: max(1, (nproc-1)/3),
24+
# on the theory that each `go test -c` invocation spawns ~3 hot worker
25+
# processes (compile, vet, link), so K*3 <= cores-1. Pass -j N to override.
26+
jobs=0
2327

2428

25-
while getopts "o:s:i:" arg; do
26-
case $arg in
29+
while getopts "o:s:i:j:" arg; do
30+
case $arg in
2731
o) outpath=$OPTARG;;
2832
s) suites=$OPTARG;;
2933
i) imagetestroot=$OPTARG;;
34+
j) jobs=$OPTARG;;
3035
*) echo "unknown arg"
3136
esac
32-
done
37+
done
38+
39+
if [ "$jobs" -eq 0 ]; then
40+
jobs=$(( ($(nproc) - 1) / 3 ))
41+
[ $jobs -lt 1 ] && jobs=1
42+
fi
3343

3444

3545
export CGO_ENABLED=0
@@ -46,19 +56,58 @@ GOOS=windows GOARCH=386 go build -o $outpath/wrapp32.exe ./cmd/wrapper/main.go |
4656
go build -o $outpath/manager ./cmd/manager/main.go || exit 1
4757

4858

49-
cd test_suites
50-
for suite in $suites; do
51-
[[ -d $suite ]] || continue
52-
cd $suite
59+
# Build one suite (all four arch variants). Run in its own subshell so cd
60+
# stays scoped and so multiple suites can run concurrently.
61+
build_suite() {
62+
local suite=$1
63+
local outpath=$2
64+
local root=$3
65+
cd "$root/test_suites/$suite" || return 1
5366
echo "building suite $suite"
54-
go test -c -tags cit || exit 1
55-
./"${suite}.test" -test.list '.*' > $outpath/"${suite}_tests.txt" || exit 1
56-
mv "${suite}.test" $outpath/"${suite}.amd64.test" || exit 1
57-
GOARCH=arm64 go test -c -tags cit || exit 1
58-
mv "${suite}.test" "$outpath/${suite}.arm64.test" || exit 1
59-
GOOS=windows GOARCH=amd64 go test -c -tags cit || exit 1
60-
if [ -f "${suite}.test.exe" ]; then mv "${suite}.test.exe" "$outpath/${suite}64.exe" || exit 1; fi;
61-
GOOS=windows GOARCH=386 go test -c -tags cit || exit 1
62-
if [ -f "${suite}.test.exe" ]; then mv "${suite}.test.exe" "$outpath/${suite}32.exe" || exit 1; fi;
63-
cd ..
67+
go test -c -tags cit || return 1
68+
./"${suite}.test" -test.list '.*' > "$outpath/${suite}_tests.txt" || return 1
69+
mv "${suite}.test" "$outpath/${suite}.amd64.test" || return 1
70+
GOARCH=arm64 go test -c -tags cit || return 1
71+
mv "${suite}.test" "$outpath/${suite}.arm64.test" || return 1
72+
GOOS=windows GOARCH=amd64 go test -c -tags cit || return 1
73+
if [ -f "${suite}.test.exe" ]; then mv "${suite}.test.exe" "$outpath/${suite}64.exe" || return 1; fi
74+
GOOS=windows GOARCH=386 go test -c -tags cit || return 1
75+
if [ -f "${suite}.test.exe" ]; then mv "${suite}.test.exe" "$outpath/${suite}32.exe" || return 1; fi
76+
}
77+
78+
abs_outpath=$(cd "$outpath" && pwd)
79+
abs_root=$(cd "$imagetestroot" && pwd)
80+
81+
# FIFO semaphore: $jobs slots in a named pipe. Each suite reads a token
82+
# before starting and writes one back when done.
83+
slotfifo=$(mktemp -u)
84+
mkfifo "$slotfifo"
85+
exec 9<>"$slotfifo"
86+
rm "$slotfifo"
87+
for i in $(seq 1 $jobs); do echo >&9; done
88+
89+
cd "$abs_root/test_suites"
90+
pids=()
91+
names=()
92+
for suite in $suites; do
93+
[[ -d "$suite" ]] || continue
94+
read -u 9 # wait for a slot
95+
(
96+
build_suite "$suite" "$abs_outpath" "$abs_root"
97+
rc=$?
98+
echo >&9 # release slot regardless of outcome
99+
exit $rc
100+
) &
101+
pids+=($!)
102+
names+=("$suite")
103+
done
104+
105+
fail=0
106+
for i in "${!pids[@]}"; do
107+
if ! wait "${pids[$i]}"; then
108+
echo "[!] suite ${names[$i]} failed"
109+
fail=1
110+
fi
64111
done
112+
exec 9>&-
113+
[[ $fail -eq 0 ]] || exit 1

0 commit comments

Comments
 (0)