Make more tests run in parallel
Summary: Generate t/run-* scripts to run tests in $PARALLEL_TEST separately, then make check_0 rule execute all of them. Run `time make check` after running `make all`. master: 71 sec with this diff: 63 sec. It seems moving more tests to $PARALLEL_TEST doesn't help improve test time though. Test Plan: Run the following make check J=16 make check J=1 make check make valgrind_check J=1 make valgrind_check J=16 make_valgrind_check Reviewers: IslamAbdelRahman, sdong Reviewed By: sdong Subscribers: leveldb, kradhakrishnan, dhruba, andrewkr, yhchiang Differential Revision: https://reviews.facebook.net/D56805
This commit is contained in:
parent
47833e0ab9
commit
6affd45d84
139
Makefile
139
Makefile
@ -356,6 +356,18 @@ TESTS = \
|
|||||||
ldb_cmd_test \
|
ldb_cmd_test \
|
||||||
iostats_context_test
|
iostats_context_test
|
||||||
|
|
||||||
|
PARALLEL_TEST = \
|
||||||
|
backupable_db_test \
|
||||||
|
compact_on_deletion_collector_test \
|
||||||
|
db_compaction_filter_test \
|
||||||
|
db_compaction_test \
|
||||||
|
db_test \
|
||||||
|
db_universal_compaction_test \
|
||||||
|
fault_injection_test \
|
||||||
|
inlineskiplist_test \
|
||||||
|
manual_compaction_test \
|
||||||
|
table_test
|
||||||
|
|
||||||
SUBSET := $(TESTS)
|
SUBSET := $(TESTS)
|
||||||
ifdef ROCKSDBTESTS_START
|
ifdef ROCKSDBTESTS_START
|
||||||
SUBSET := $(shell echo $(SUBSET) | sed 's/^.*$(ROCKSDBTESTS_START)/$(ROCKSDBTESTS_START)/')
|
SUBSET := $(shell echo $(SUBSET) | sed 's/^.*$(ROCKSDBTESTS_START)/$(ROCKSDBTESTS_START)/')
|
||||||
@ -464,7 +476,26 @@ coverage:
|
|||||||
# Delete intermediate files
|
# Delete intermediate files
|
||||||
find . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \;
|
find . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \;
|
||||||
|
|
||||||
# Extract the names of its tests by running db_test with --gtest_list_tests.
|
ifneq (,$(filter check parallel_check,$(MAKECMDGOALS)),)
|
||||||
|
# Use /dev/shm if it has the sticky bit set (otherwise, /tmp),
|
||||||
|
# and create a randomly-named rocksdb.XXXX directory therein.
|
||||||
|
# We'll use that directory in the "make check" rules.
|
||||||
|
ifeq ($(TMPD),)
|
||||||
|
TMPD := $(shell f=/dev/shm; test -k $$f || f=/tmp; \
|
||||||
|
perl -le 'use File::Temp "tempdir";' \
|
||||||
|
-e 'print tempdir("'$$f'/rocksdb.XXXX", CLEANUP => 0)')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Run all tests in parallel, accumulating per-test logs in t/log-*.
|
||||||
|
#
|
||||||
|
# Each t/run-* file is a tiny generated bourne shell script that invokes one of
|
||||||
|
# sub-tests. Why use a file for this? Because that makes the invocation of
|
||||||
|
# parallel below simpler, which in turn makes the parsing of parallel's
|
||||||
|
# LOG simpler (the latter is for live monitoring as parallel
|
||||||
|
# tests run).
|
||||||
|
#
|
||||||
|
# Test names are extracted by running tests with --gtest_list_tests.
|
||||||
# This filter removes the "#"-introduced comments, and expands to
|
# This filter removes the "#"-introduced comments, and expands to
|
||||||
# fully-qualified names by changing input like this:
|
# fully-qualified names by changing input like this:
|
||||||
#
|
#
|
||||||
@ -482,52 +513,33 @@ coverage:
|
|||||||
# MultiThreaded/MultiThreadedDBTest.MultiThreaded/0
|
# MultiThreaded/MultiThreadedDBTest.MultiThreaded/0
|
||||||
# MultiThreaded/MultiThreadedDBTest.MultiThreaded/1
|
# MultiThreaded/MultiThreadedDBTest.MultiThreaded/1
|
||||||
#
|
#
|
||||||
test_names = \
|
|
||||||
./db_test --gtest_list_tests \
|
|
||||||
| perl -n \
|
|
||||||
-e 's/ *\#.*//;' \
|
|
||||||
-e '/^(\s*)(\S+)/; !$$1 and do {$$p=$$2; break};' \
|
|
||||||
-e 'print qq! $$p$$2!'
|
|
||||||
|
|
||||||
ifneq (,$(filter check parallel_check,$(MAKECMDGOALS)),)
|
parallel_tests = $(patsubst %,parallel_%,$(PARALLEL_TEST))
|
||||||
# Use /dev/shm if it has the sticky bit set (otherwise, /tmp),
|
.PHONY: gen_parallel_tests $(parallel_tests)
|
||||||
# and create a randomly-named rocksdb.XXXX directory therein.
|
$(parallel_tests): $(PARALLEL_TEST)
|
||||||
# We'll use that directory in the "make check" rules.
|
$(AM_V_at)TEST_BINARY=$(patsubst parallel_%,%,$@); \
|
||||||
ifeq ($(TMPD),)
|
TEST_NAMES=` \
|
||||||
TMPD := $(shell f=/dev/shm; test -k $$f || f=/tmp; \
|
./$$TEST_BINARY --gtest_list_tests \
|
||||||
perl -le 'use File::Temp "tempdir";' \
|
| perl -n \
|
||||||
-e 'print tempdir("'$$f'/rocksdb.XXXX", CLEANUP => 0)')
|
-e 's/ *\#.*//;' \
|
||||||
endif
|
-e '/^(\s*)(\S+)/; !$$1 and do {$$p=$$2; break};' \
|
||||||
endif
|
-e 'print qq! $$p$$2!'`; \
|
||||||
|
for TEST_NAME in $$TEST_NAMES; do \
|
||||||
|
TEST_SCRIPT=t/run-$$TEST_BINARY-$${TEST_NAME//\//-}; \
|
||||||
|
echo " GEN " $$TEST_SCRIPT; \
|
||||||
|
printf '%s\n' \
|
||||||
|
'#!/bin/sh' \
|
||||||
|
"d=\$(TMPD)$$TEST_SCRIPT" \
|
||||||
|
'mkdir -p $$d' \
|
||||||
|
"TEST_TMPDIR=\$$d ./$$TEST_BINARY --gtest_filter=$$TEST_NAME" \
|
||||||
|
> $$TEST_SCRIPT; \
|
||||||
|
chmod a=rx $$TEST_SCRIPT; \
|
||||||
|
done
|
||||||
|
|
||||||
ifneq ($(T),)
|
gen_parallel_tests:
|
||||||
|
$(AM_V_at)mkdir -p t
|
||||||
# Run all tests in parallel, accumulating per-test logs in t/log-*.
|
$(AM_V_at)rm -f t/run-*
|
||||||
|
$(MAKE) $(parallel_tests)
|
||||||
# t_sanitized is each $(T) with "-" in place of each "/".
|
|
||||||
t_sanitized = $(subst /,-,$(T))
|
|
||||||
|
|
||||||
# t_run is each sanitized name with a leading "t/".
|
|
||||||
t_run = $(patsubst %,t/%,$(t_sanitized))
|
|
||||||
|
|
||||||
# Each t_run file is a tiny generated bourne shell script
|
|
||||||
# that invokes one of db_tests's sub-tests. Why use a file
|
|
||||||
# for this? Because that makes the invocation of parallel
|
|
||||||
# below simpler, which in turn makes the parsing of parallel's
|
|
||||||
# LOG simpler (the latter is for live monitoring as parallel
|
|
||||||
# tests run).
|
|
||||||
filter = --gtest_filter=$(subst -,/,$(@F))
|
|
||||||
$(t_run): Makefile db_test
|
|
||||||
$(AM_V_GEN)mkdir -p t
|
|
||||||
$(AM_V_at)rm -f $@ $@-t
|
|
||||||
$(AM_V_at)printf '%s\n' \
|
|
||||||
'#!/bin/sh' \
|
|
||||||
'd=$(TMPD)/$(@F)' \
|
|
||||||
'mkdir -p $$d' \
|
|
||||||
'TEST_TMPDIR=$$d $(DRIVER) ./db_test $(filter)' \
|
|
||||||
> $@-t
|
|
||||||
$(AM_V_at)chmod a=rx $@-t
|
|
||||||
$(AM_V_at)mv $@-t $@
|
|
||||||
|
|
||||||
# Reorder input lines (which are one per test) so that the
|
# Reorder input lines (which are one per test) so that the
|
||||||
# longest-running tests appear first in the output.
|
# longest-running tests appear first in the output.
|
||||||
@ -546,7 +558,7 @@ $(t_run): Makefile db_test
|
|||||||
# 107.816 PASS t/DBTest.EncodeDecompressedBlockSizeTest
|
# 107.816 PASS t/DBTest.EncodeDecompressedBlockSizeTest
|
||||||
#
|
#
|
||||||
slow_test_regexp = \
|
slow_test_regexp = \
|
||||||
^t/DBTest\.(?:FileCreationRandomFailure|EncodeDecompressedBlockSizeTest)$$
|
^t/run-table_test-HarnessTest.Randomized$$|^t/run-db_test-.*(?:FileCreationRandomFailure|EncodeDecompressedBlockSizeTest)$$
|
||||||
prioritize_long_running_tests = \
|
prioritize_long_running_tests = \
|
||||||
perl -pe 's,($(slow_test_regexp)),100 $$1,' \
|
perl -pe 's,($(slow_test_regexp)),100 $$1,' \
|
||||||
| sort -k1,1gr \
|
| sort -k1,1gr \
|
||||||
@ -557,35 +569,36 @@ prioritize_long_running_tests = \
|
|||||||
# Run with "make J=200% check" to run two parallel jobs per core.
|
# Run with "make J=200% check" to run two parallel jobs per core.
|
||||||
# The default is to run one job per core (J=100%).
|
# The default is to run one job per core (J=100%).
|
||||||
# See "man parallel" for its "-j ..." option.
|
# See "man parallel" for its "-j ..." option.
|
||||||
J = 100%
|
J ?= 100%
|
||||||
|
|
||||||
# Use this regexp to select the subset of tests whose names match.
|
# Use this regexp to select the subset of tests whose names match.
|
||||||
tests-regexp = .
|
tests-regexp = .
|
||||||
|
|
||||||
|
t_run = $(wildcard t/run-*)
|
||||||
.PHONY: check_0
|
.PHONY: check_0
|
||||||
check_0: $(t_run)
|
check_0:
|
||||||
$(AM_V_GEN)export TEST_TMPDIR=$(TMPD); \
|
$(AM_V_GEN)export TEST_TMPDIR=$(TMPD); \
|
||||||
printf '%s\n' '' \
|
printf '%s\n' '' \
|
||||||
'To monitor subtest <duration,pass/fail,name>,' \
|
'To monitor subtest <duration,pass/fail,name>,' \
|
||||||
' run "make watch-log" in a separate window' ''; \
|
' run "make watch-log" in a separate window' ''; \
|
||||||
test -t 1 && eta=--eta || eta=; \
|
test -t 1 && eta=--eta || eta=; \
|
||||||
{ \
|
{ \
|
||||||
printf './%s\n' $(filter-out db_test, $(TESTS)); \
|
printf './%s\n' $(filter-out $(PARALLEL_TEST),$(TESTS)); \
|
||||||
printf '%s\n' $(t_run); \
|
printf '%s\n' $(t_run); \
|
||||||
} \
|
} \
|
||||||
| $(prioritize_long_running_tests) \
|
| $(prioritize_long_running_tests) \
|
||||||
| grep -E '$(tests-regexp)' \
|
| grep -E '$(tests-regexp)' \
|
||||||
| parallel -j$(J) --joblog=LOG $$eta --gnu '{} >& t/log-{/}'
|
| parallel -j$(J) --joblog=LOG $$eta --gnu '{} >& t/log-{/}'
|
||||||
|
|
||||||
.PHONY: valgrind_check_0
|
.PHONY: valgrind_check_0
|
||||||
valgrind_check_0: $(t_run)
|
valgrind_check_0:
|
||||||
$(AM_V_GEN)export TEST_TMPDIR=$(TMPD); \
|
$(AM_V_GEN)export TEST_TMPDIR=$(TMPD); \
|
||||||
printf '%s\n' '' \
|
printf '%s\n' '' \
|
||||||
'To monitor subtest <duration,pass/fail,name>,' \
|
'To monitor subtest <duration,pass/fail,name>,' \
|
||||||
' run "make watch-log" in a separate window' ''; \
|
' run "make watch-log" in a separate window' ''; \
|
||||||
test -t 1 && eta=--eta || eta=; \
|
test -t 1 && eta=--eta || eta=; \
|
||||||
{ \
|
{ \
|
||||||
printf './%s\n' $(filter-out db_test %skiplist_test options_settable_test, $(TESTS)); \
|
printf './%s\n' $(filter-out $(PARALLEL_TEST) %skiplist_test options_settable_test, $(TESTS)); \
|
||||||
printf '%s\n' $(t_run); \
|
printf '%s\n' $(t_run); \
|
||||||
} \
|
} \
|
||||||
| $(prioritize_long_running_tests) \
|
| $(prioritize_long_running_tests) \
|
||||||
@ -593,7 +606,6 @@ valgrind_check_0: $(t_run)
|
|||||||
| parallel -j$(J) --joblog=LOG $$eta --gnu \
|
| parallel -j$(J) --joblog=LOG $$eta --gnu \
|
||||||
'if [[ "{}" == "./"* ]] ; then $(DRIVER) {} >& t/valgrind_log-{/}; ' \
|
'if [[ "{}" == "./"* ]] ; then $(DRIVER) {} >& t/valgrind_log-{/}; ' \
|
||||||
'else {} >& t/valgrind_log-{/}; fi'
|
'else {} >& t/valgrind_log-{/}; fi'
|
||||||
endif
|
|
||||||
|
|
||||||
CLEAN_FILES += t LOG $(TMPD)
|
CLEAN_FILES += t LOG $(TMPD)
|
||||||
|
|
||||||
@ -610,11 +622,11 @@ watch-log:
|
|||||||
# If J != 1 and GNU parallel is installed, run the tests in parallel,
|
# If J != 1 and GNU parallel is installed, run the tests in parallel,
|
||||||
# via the check_0 rule above. Otherwise, run them sequentially.
|
# via the check_0 rule above. Otherwise, run them sequentially.
|
||||||
check: all
|
check: all
|
||||||
|
$(MAKE) gen_parallel_tests
|
||||||
$(AM_V_GEN)if test "$(J)" != 1 \
|
$(AM_V_GEN)if test "$(J)" != 1 \
|
||||||
&& (parallel --gnu --help 2>/dev/null) | \
|
&& (parallel --gnu --help 2>/dev/null) | \
|
||||||
grep -q 'GNU Parallel'; \
|
grep -q 'GNU Parallel'; \
|
||||||
then \
|
then \
|
||||||
t=$$($(test_names)); \
|
|
||||||
$(MAKE) T="$$t" TMPD=$(TMPD) check_0; \
|
$(MAKE) T="$$t" TMPD=$(TMPD) check_0; \
|
||||||
else \
|
else \
|
||||||
for t in $(TESTS); do \
|
for t in $(TESTS); do \
|
||||||
@ -664,12 +676,12 @@ ubsan_crash_test:
|
|||||||
$(MAKE) clean
|
$(MAKE) clean
|
||||||
|
|
||||||
valgrind_check: $(TESTS)
|
valgrind_check: $(TESTS)
|
||||||
|
$(MAKE) gen_parallel_tests
|
||||||
$(AM_V_GEN)if test "$(J)" != 1 \
|
$(AM_V_GEN)if test "$(J)" != 1 \
|
||||||
&& (parallel --gnu --help 2>/dev/null) | \
|
&& (parallel --gnu --help 2>/dev/null) | \
|
||||||
grep -q 'GNU Parallel'; \
|
grep -q 'GNU Parallel'; \
|
||||||
then \
|
then \
|
||||||
t=$$($(test_names)); \
|
$(MAKE) TMPD=$(TMPD) \
|
||||||
$(MAKE) T="$$t" TMPD=$(TMPD) \
|
|
||||||
DRIVER="$(VALGRIND_VER) $(VALGRIND_OPTS)" valgrind_check_0; \
|
DRIVER="$(VALGRIND_VER) $(VALGRIND_OPTS)" valgrind_check_0; \
|
||||||
else \
|
else \
|
||||||
for t in $(filter-out %skiplist_test options_settable_test,$(TESTS)); do \
|
for t in $(filter-out %skiplist_test options_settable_test,$(TESTS)); do \
|
||||||
@ -703,6 +715,13 @@ parloop:
|
|||||||
exit $$ret_bad;
|
exit $$ret_bad;
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
test_names = \
|
||||||
|
./db_test --gtest_list_tests \
|
||||||
|
| perl -n \
|
||||||
|
-e 's/ *\#.*//;' \
|
||||||
|
-e '/^(\s*)(\S+)/; !$$1 and do {$$p=$$2; break};' \
|
||||||
|
-e 'print qq! $$p$$2!'
|
||||||
|
|
||||||
parallel_check: $(TESTS)
|
parallel_check: $(TESTS)
|
||||||
$(AM_V_GEN)if test "$(J)" > 1 \
|
$(AM_V_GEN)if test "$(J)" > 1 \
|
||||||
&& (parallel --gnu --help 2>/dev/null) | \
|
&& (parallel --gnu --help 2>/dev/null) | \
|
||||||
|
Loading…
Reference in New Issue
Block a user