Skip to content

Commit

Permalink
tests: Enable running parallel unit tests for Windows.
Browse files Browse the repository at this point in the history
testsuite uses mkfifo in its job dispatcher that manages
parallel unit tests. MinGW does not have a mkfifo. This
results in unit tests running serially on Windows. Right
now it takes up to approximately 40 minutes to run all the
unit tests on Windows.

This commit provides a job dispatcher for MinGW that uses
temporary files instead of mkfifo to manage parallel jobs.
With this commit, on a Windows machine with 4 cores and with
8 parallel unit test sessions, it takes approximately 8
minutes to finish a unit test run.

Signed-off-by: Gurucharan Shetty <[email protected]>
Acked-by: Eitan Eliahu <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
shettyg committed Feb 13, 2015
1 parent d8a5ced commit ddd347c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
2 changes: 2 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ you will need the following software:

- Python 2.x, for x >= 4.

- patch (The utility that is used to patch files).

On Linux, you may choose to compile the kernel module that comes with
the Open vSwitch distribution or to use the kernel module built into
the Linux kernel (version 3.3 or later). See the [FAQ.md] question
Expand Down
7 changes: 5 additions & 2 deletions tests/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ EXTRA_DIST += \
$(KMOD_TESTSUITE) \
tests/atlocal.in \
$(srcdir)/package.m4 \
$(srcdir)/tests/testsuite
$(srcdir)/tests/testsuite \
$(srcdir)/tests/testsuite.patch

COMMON_MACROS_AT = \
tests/ovsdb-macros.at \
Expand Down Expand Up @@ -87,6 +88,7 @@ KMOD_TESTSUITE_AT = \
tests/kmod-traffic.at

TESTSUITE = $(srcdir)/tests/testsuite
TESTSUITE_PATCH = $(srcdir)/tests/testsuite.patch
KMOD_TESTSUITE = $(srcdir)/tests/kmod-testsuite
DISTCLEANFILES += tests/atconfig tests/atlocal

Expand Down Expand Up @@ -196,8 +198,9 @@ clean-local:
test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' -C tests --clean

AUTOTEST = $(AUTOM4TE) --language=autotest
$(TESTSUITE): package.m4 $(TESTSUITE_AT) $(COMMON_MACROS_AT)
$(TESTSUITE): package.m4 $(TESTSUITE_AT) $(COMMON_MACROS_AT) $(TESTSUITE_PATCH)
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
patch -p0 $@.tmp $(TESTSUITE_PATCH)
$(AM_V_at)mv $@.tmp $@

$(KMOD_TESTSUITE): package.m4 $(KMOD_TESTSUITE_AT) $(COMMON_MACROS_AT)
Expand Down
76 changes: 76 additions & 0 deletions tests/testsuite.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
--- testsuite 2015-02-11 17:19:21.654646439 -0800
+++ testsuite 2015-02-11 17:15:03.810653032 -0800
@@ -4669,6 +4669,73 @@
fi
exec 6<&-
wait
+elif test $at_jobs -ne 1 &&
+ test "$IS_WIN32" = "yes"; then
+ # FIFO job dispatcher.
+ trap 'at_pids=
+ for at_pid in `jobs -p`; do
+ at_pids="$at_pids $at_job_group$at_pid"
+ done
+ if test -n "$at_pids"; then
+ at_sig=TSTP
+ test "${TMOUT+set}" = set && at_sig=STOP
+ kill -$at_sig $at_pids 2>/dev/null
+ fi
+ kill -STOP $$
+ test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
+
+ echo
+ # Turn jobs into a list of numbers, starting from 1.
+ running_jobs="`pwd`/tests/jobdispatcher"
+ mkdir -p $running_jobs
+ at_joblist=`$as_echo "$at_groups" | sed -n 1,${at_jobs}p`
+
+ set X $at_joblist
+ shift
+ for at_group in $at_groups; do
+ $at_job_control_on 2>/dev/null
+ (
+ # Start one test group.
+ $at_job_control_off
+ touch $running_jobs/$at_group
+ trap 'set +x; set +e
+ trap "" PIPE
+ echo stop > "$at_stop_file"
+ rm -f $running_jobs/$at_group
+ as_fn_exit 141' PIPE
+ at_fn_group_prepare
+ if cd "$at_group_dir" &&
+ at_fn_test $at_group &&
+ . "$at_test_source"
+ then :; else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+ at_failed=:
+ fi
+ rm -f $running_jobs/$at_group
+ at_fn_group_postprocess
+ ) &
+ $at_job_control_off
+ shift # Consume one token.
+ if test $# -gt 0; then :; else
+ while [ "`ls -l $running_jobs 2>/dev/null | wc -l`" -gt "$at_jobs" ]; do
+ sleep 0.1
+ done
+ set x $*
+ fi
+ test -f "$at_stop_file" && break
+ done
+ # Read back the remaining ($at_jobs - 1) tokens.
+ set X $at_joblist
+ shift
+ if test $# -gt 0; then
+ shift
+ while [ "`ls -l $running_jobs | wc -l`" -gt 1 ]; do
+ sleep 0.1
+ done
+ fi
+ rmdir $running_jobs
+ wait
else
# Run serially, avoid forks and other potential surprises.
for at_group in $at_groups; do

0 comments on commit ddd347c

Please sign in to comment.