Jelajahi Sumber

compile unit tests in parallel with GNU parallel

Docker-DCO-1.1-Signed-off-by: Tibor Vass <teabee89@gmail.com> (github: tiborvass)
Tibor Vass 11 tahun lalu
induk
melakukan
158e3068bd
2 mengubah file dengan 67 tambahan dan 23 penghapusan
  1. 19 0
      hack/make.sh
  2. 48 23
      hack/make/test-unit

+ 19 - 0
hack/make.sh

@@ -156,6 +156,25 @@ go_test_dir() {
 	)
 }
 
+# Compile phase run by parallel in test-unit. No support for coverpkg
+go_compile_test_dir() {
+	dir=$1
+	testcover=()
+	if [ "$HAVE_GO_TEST_COVER" ]; then
+		# if our current go install has -cover, we want to use it :)
+		mkdir -p "$DEST/coverprofiles"
+		coverprofile="docker${dir#.}"
+		coverprofile="$DEST/coverprofiles/${coverprofile//\//-}"
+		testcover=( -cover -coverprofile "$coverprofile" ) # missing $coverpkg
+	fi
+	(
+		readarray -t BUILDFLAGS < "$BUILDFLAGS_FILE"
+		cd "$dir"
+		go test "${testcover[@]}" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS -c
+		echo "$dir"
+	)
+}
+
 # This helper function walks the current directory looking for directories
 # holding certain files ($1 parameter), and prints their paths on standard
 # output, one per line.

+ 48 - 23
hack/make/test-unit

@@ -6,6 +6,7 @@ DEST=$1
 RED=$'\033[31m'
 GREEN=$'\033[32m'
 TEXTRESET=$'\033[0m' # reset the foreground colour
+: ${PARALLEL_JOBS:=0}
 
 # Run Docker's test suite, including sub-packages, and store their output as a bundle
 # If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
@@ -22,34 +23,58 @@ bundle_test_unit() {
 			TESTDIRS=$(find_dirs '*_test.go')
 		fi
 
-		TESTS_FAILED=()
-		for test_dir in $TESTDIRS; do
-			echo
+		(
+			# accomodate parallel to be able to access variables
+			export SHELL=/bin/bash 
+			export HOME=/tmp
+			mkdir -p "$HOME/.parallel"
+			touch "$HOME/.parallel/ignored_vars"
+			export -f go_compile_test_dir
+			export LDFLAGS="$LDFLAGS $LDFLAGS_STATIC_DOCKER"
+			export TESTFLAGS
+			export HAVE_GO_TEST_COVER
+			export DEST
+			# some hack to export array variables
+			export BUILDFLAGS_FILE="$HOME/buildflags_file"
+			( IFS=$'\n'; echo "${BUILDFLAGS[*]}" ) > "$BUILDFLAGS_FILE"
 
-			if ! LDFLAGS="$LDFLAGS $LDFLAGS_STATIC_DOCKER" go_test_dir "$test_dir"; then
-				TESTS_FAILED+=("$test_dir")
-				echo
-				echo "${RED}Tests failed: $test_dir${TEXTRESET}"
-				sleep 1 # give it a second, so observers watching can take note
-			fi
-		done
+			echo "$TESTDIRS" | parallel --jobs "$PARALLEL_JOBS" --env _ go_compile_test_dir | go_run_test_dir
+		)
+	}
+}
 
+go_run_test_dir() {
+	TESTS_FAILED=()
+	while read dir; do
 		echo
-		echo
-		echo
-
-		# if some tests fail, we want the bundlescript to fail, but we want to
-		# try running ALL the tests first, hence TESTS_FAILED
-		if [ "${#TESTS_FAILED[@]}" -gt 0 ]; then
-			echo "${RED}Test failures in: ${TESTS_FAILED[@]}${TEXTRESET}"
+		echo '+ go test' $TESTFLAGS "github.com/dotcloud/docker${dir#.}"
+		pushd "$dir" > /dev/null
+		t=$(basename "$dir").test
+		if ! ./$t; then
+			TESTS_FAILED+=("$dir")
 			echo
-			false
-		else
-			echo "${GREEN}Test success${TEXTRESET}"
-			echo
-			true
+			echo "${RED}Tests failed: $dir${TEXTRESET}"
+			sleep 1 # give it a second, so observers watching can take note
 		fi
-	}
+		rm ./$t || true
+		popd > /dev/null
+	done
+
+	echo
+	echo
+	echo
+
+	# if some tests fail, we want the bundlescript to fail, but we want to
+	# try running ALL the tests first, hence TESTS_FAILED
+	if [ "${#TESTS_FAILED[@]}" -gt 0 ]; then
+		echo "${RED}Test failures in: ${TESTS_FAILED[@]}${TEXTRESET}"
+		echo
+		false
+	else
+		echo "${GREEN}Test success${TEXTRESET}"
+		echo
+		true
+	fi
 }
 
 exec > >(tee -a $DEST/test.log) 2>&1