From dac6c457d39a101149078c52a383f1f36f1fb82d Mon Sep 17 00:00:00 2001
From: Levente Polyak <anthraxx@archlinux.org>
Date: Thu, 12 Oct 2023 20:50:06 +0200
Subject: [PATCH] feat(test): support and enable parallelized test execution by
 default

Use nproc to determine the default job counter.
---
 Makefile                    |  3 ++-
 test/Dockerfile             |  4 ++++
 test/Makefile               |  3 ++-
 test/cases/setup_suite.bash |  6 ++++++
 test/lib/common.bash        | 39 +++++++++++++++++++++++++++++--------
 5 files changed, 45 insertions(+), 10 deletions(-)
 create mode 100644 test/cases/setup_suite.bash

diff --git a/Makefile b/Makefile
index 45737b5..45fb85a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
 IMAGE:=dbscripts/test
 RUN_OPTIONS:=--rm --network=none -v $(PWD):/dbscripts:ro --tmpfs=/tmp:exec -w /dbscripts/test
 CASES ?= cases
-BATS_ARGS ?=
+JOBS ?= $(shell nproc)
+BATS_ARGS ?= --jobs $(JOBS) --verbose-run
 DOCKER ?= docker
 
 test-image:
diff --git a/test/Dockerfile b/test/Dockerfile
index f54c87d..ec54236 100644
--- a/test/Dockerfile
+++ b/test/Dockerfile
@@ -54,6 +54,10 @@ RUN pacman-key --init && \
 		/srv/ftp/{{core,extra,multilib}{,-testing,-staging},gnome-unstable}/os/x86_64/ && \
 	echo -e "[safe]\n\tdirectory = *\n" > /etc/gitconfig
 
+# TODO: temporary hack to work around bats packaging bug
+RUN sed 's/libexec/lib/g' -i /usr/lib/bats/* && \
+	sed 's/bats-core/bats/g' -i /usr/lib/bats/*
+
 USER tester
 
 RUN echo -e "\
diff --git a/test/Makefile b/test/Makefile
index 556afa5..0a53c6a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,5 +1,6 @@
 CASES ?= cases
-BATS_ARGS ?=
+JOBS ?= $(shell nproc)
+BATS_ARGS ?= --jobs $(JOBS) --verbose-run
 
 test:
 	BUILDDIR=/build PATH=$(CURDIR)/../:$(CURDIR)/../cron-jobs/:$(PATH) bats $(BATS_ARGS) $(CASES)
diff --git a/test/cases/setup_suite.bash b/test/cases/setup_suite.bash
new file mode 100644
index 0000000..ea7f400
--- /dev/null
+++ b/test/cases/setup_suite.bash
@@ -0,0 +1,6 @@
+setup_suite() {
+	git config --global user.email "tester@localhost"
+	git config --global user.name "Bob Tester"
+	git config --global init.defaultBranch main
+	git config --global advice.detachedHead false
+}
diff --git a/test/lib/common.bash b/test/lib/common.bash
index 57e0bd3..aa5552e 100644
--- a/test/lib/common.bash
+++ b/test/lib/common.bash
@@ -70,6 +70,32 @@ __isGlobfile() {
 	[[ -f $1 ]]
 }
 
+##
+#  usage : lock( $fd, $file )
+##
+lock() {
+	# Only reopen the FD if it wasn't handed to us
+	if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
+		mkdir -p -- "$(dirname -- "$2")"
+		eval "exec $1>"'"$2"'
+	fi
+
+	if ! flock --wait 600 "$1"; then
+		error "Failed to acquire lock on %s" "$2"
+		exit 1
+	fi
+}
+
+##
+#  usage : lock_close( $fd )
+##
+lock_close() {
+	local fd=$1
+	# https://github.com/koalaman/shellcheck/issues/862
+	# shellcheck disable=2034
+	exec {fd}>&-
+}
+
 __buildPackage() {
 	local pkgdest=${1:-.}
 	local p
@@ -80,10 +106,12 @@ __buildPackage() {
 
 	if [[ -n ${BUILDDIR} ]]; then
 		cache=${BUILDDIR}/$(__getCheckSum PKGBUILD)
+		mkdir -p "${cache}"
+		lock 9 "${cache}/.lock"
+
 		if cp -Lv ${cache}/*${PKGEXT}{,.sig} ${pkgdest} 2>/dev/null; then
+			lock_close 9
 			return 0
-		else
-			mkdir -p ${cache}
 		fi
 	fi
 
@@ -110,6 +138,7 @@ __buildPackage() {
 			cp -Lv ${p}{,.sig} ${cache}/
 		fi
 	done
+	lock_close 9
 }
 
 __archrelease() {
@@ -195,12 +224,6 @@ eot
 
 	. config
 
-	git config --global user.email "tester@localhost"
-	git config --global user.name "Bob Tester"
-	git config --global init.defaultBranch main
-	git config --global advice.detachedHead false
-
-
 	# This is for our git clones when initializing bare repos
 	TMP_WORKDIR_GIT=${TMP}/git-clones
 
-- 
GitLab