git » chasquid » commit 7a4a4e4

tests: Fix "text file busy" race condition in go-build-cached

author Alberto Bertogli
2025-10-18 15:21:29 UTC
committer Alberto Bertogli
2025-10-18 15:26:51 UTC
parent 08273ea90128d08e9a52504a7aaff388642faf68

tests: Fix "text file busy" race condition in go-build-cached

There are a couple of places in the tests when we attempt to build and
run simultaneously. Here, if the build is slow, there is a race where
"text file busy" can appear.

To fix this, build to a temporary file with a random name, then
atomically rename it to the final binary name.

test/util/lib.sh +14 -1

diff --git a/test/util/lib.sh b/test/util/lib.sh
index 14239e7..dcb4265 100644
--- a/test/util/lib.sh
+++ b/test/util/lib.sh
@@ -53,8 +53,21 @@ function go-build-cached() { (
 		! cmp -s .flags-new .flags >/dev/null 2>&1 ||
 		[ "$(basename "$PWD")" -ot ".reference" ] ;
 	then
+		# Build to a temporary file first, then atomically rename it.
+		# This prevents "text file busy" errors when the binary is
+		# executed while being written to.
+		BINARY="$(basename "$PWD")"
+		TMPFILE=".${BINARY}.tmp.${RANDOM}"
+
 		# shellcheck disable=SC2086
-		go build -tags="$GOTAGS" $GOFLAGS
+		if go build -tags="$GOTAGS" $GOFLAGS -o "$TMPFILE"; then
+			# Atomically replace the binary.
+			mv "$TMPFILE" "$BINARY"
+		else
+			# Clean up the temp file if the build failed.
+			rm -f "$TMPFILE"
+			exit 1
+		fi
 
 		# Write to .flags instead of renaming, to prevent races where
 		# was .flags-new is already renamed by the time we get here.