Add a test target with sharding support to the CMake build.
Two major things going on here:
- One target is created for each file in test-data.sha1 (testdata_N),
and the testdata target now depends on all testdata_N targets. The
testdata build rule can now run with as many jobs as there are
input files to speed up test data download.
- GTest sharding support has been added to the tests via a runtests
custom build target. First, the number of processors is detected,
and then a custom target is created for each processor (test_N).
Once each test_N target is created, the runtests custom target
is created, and then made to depend on each test_N target. When
CMake is unable to detect the number of processors 10 test targets
are created. Each custom target then sets the GTEST_SHARD_INDEX and
GTEST_TOTAL_SHARDS environment variables, allowing GTest to handle
sharding internally.
BUG=aomedia:76,aomedia:469
Change-Id: Ib6b7974932396fbf44b735d37155fa57561027ab
diff --git a/test/test.cmake b/test/test.cmake
index 361d9f7..e4fc861 100644
--- a/test/test.cmake
+++ b/test/test.cmake
@@ -8,8 +8,12 @@
## Media Patent License 1.0 was not distributed with this source code in the
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
##
+include(ProcessorCount)
+
include("${AOM_ROOT}/test/test_data_util.cmake")
+set(AOM_UNIT_TEST_DATA_LIST_FILE "${AOM_ROOT}/test/test-data.sha1")
+
set(AOM_UNIT_TEST_WRAPPER_SOURCES
"${AOM_CONFIG_DIR}/usage_exit.c"
"${AOM_ROOT}/test/test_libaom.cc")
@@ -316,10 +320,52 @@
"AOM_UNIT_TEST_COMMON_INTRIN_NEON")
endif ()
- add_custom_target(testdata
- COMMAND ${CMAKE_COMMAND}
+ make_test_data_lists("${AOM_UNIT_TEST_DATA_LIST_FILE}"
+ test_files test_file_checksums)
+ list(LENGTH test_files num_test_files)
+ list(LENGTH test_file_checksums num_test_file_checksums)
+
+ math(EXPR max_file_index "${num_test_files} - 1")
+ foreach (test_index RANGE ${max_file_index})
+ list(GET test_files ${test_index} test_file)
+ list(GET test_file_checksums ${test_index} test_file_checksum)
+ add_custom_target(testdata_${test_index}
+ COMMAND ${CMAKE_COMMAND}
+ -DAOM_CONFIG_DIR="${AOM_CONFIG_DIR}"
+ -DAOM_ROOT="${AOM_ROOT}"
+ -DAOM_TEST_FILE="${test_file}"
+ -DAOM_TEST_CHECKSUM=${test_file_checksum}
+ -P "${AOM_ROOT}/test/test_data_download_worker.cmake")
+ set(testdata_targets ${testdata_targets} testdata_${test_index})
+ endforeach ()
+
+ # Create a custom build target for running each test data download target.
+ add_custom_target(testdata)
+ add_dependencies(testdata ${testdata_targets})
+
+ # Pick a reasonable number of targets (this controls parallelization).
+ ProcessorCount(num_test_targets)
+ if (num_test_targets EQUAL 0)
+ # Just default to 10 targets when there's no processor count available.
+ set(num_test_targets 10)
+ endif ()
+
+ # TODO(tomfinegan): This needs some work for MSVC and Xcode. Executable suffix
+ # and config based executable output paths are the obvious issues.
+ math(EXPR max_shard_index "${num_test_targets} - 1")
+ foreach (shard_index RANGE ${max_shard_index})
+ set(test_name "test_${shard_index}")
+ add_custom_target(${test_name}
+ COMMAND ${CMAKE_COMMAND}
-DAOM_CONFIG_DIR="${AOM_CONFIG_DIR}"
-DAOM_ROOT="${AOM_ROOT}"
- -P "${AOM_ROOT}/test/test_worker.cmake"
- SOURCES ${AOM_TEST_DATA_LIST})
+ -DAOM_TEST_TARGET=test_libaom
+ -DGTEST_SHARD_INDEX=${shard_index}
+ -DGTEST_TOTAL_SHARDS=${num_test_targets}
+ -P "${AOM_ROOT}/test/test_runner.cmake"
+ DEPENDS testdata test_libaom)
+ set(test_targets ${test_targets} ${test_name})
+ endforeach ()
+ add_custom_target(runtests)
+ add_dependencies(runtests ${test_targets})
endfunction ()
diff --git a/test/test_data_download_worker.cmake b/test/test_data_download_worker.cmake
new file mode 100644
index 0000000..d7bf99e
--- /dev/null
+++ b/test/test_data_download_worker.cmake
@@ -0,0 +1,40 @@
+##
+## Copyright (c) 2017, Alliance for Open Media. All rights reserved
+##
+## This source code is subject to the terms of the BSD 2 Clause License and
+## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+## was not distributed with this source code in the LICENSE file, you can
+## obtain it at www.aomedia.org/license/software. If the Alliance for Open
+## Media Patent License 1.0 was not distributed with this source code in the
+## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+##
+include("${AOM_ROOT}/test/test_data_util.cmake")
+
+if (NOT AOM_ROOT OR NOT AOM_CONFIG_DIR OR NOT AOM_TEST_FILE
+ OR NOT AOM_TEST_CHECKSUM)
+ message(FATAL_ERROR
+ "AOM_ROOT, AOM_CONFIG_DIR, AOM_TEST_FILE and AOM_TEST_CHECKSUM must be
+ defined.")
+endif ()
+
+set(AOM_TEST_DATA_URL
+ "https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx")
+set(AOM_TEST_DATA_PATH "$ENV{LIBAOM_TEST_DATA_PATH}")
+
+if ("${AOM_TEST_DATA_PATH}" STREQUAL "")
+ message(WARNING "Writing test data to ${AOM_CONFIG_DIR}, set "
+ "$LIBAOM_TEST_DATA_PATH in your environment to avoid this warning.")
+ set(AOM_TEST_DATA_PATH "${AOM_CONFIG_DIR}")
+endif ()
+
+if (NOT EXISTS "${AOM_TEST_DATA_PATH}")
+ file(MAKE_DIRECTORY "${AOM_TEST_DATA_PATH}")
+endif ()
+
+expand_test_file_paths("AOM_TEST_FILE" "${AOM_TEST_DATA_PATH}" "filepath")
+expand_test_file_paths("AOM_TEST_FILE" "${AOM_TEST_DATA_URL}" "url")
+
+check_file("${filepath}" "${AOM_TEST_CHECKSUM}" "needs_download")
+if (needs_download)
+ download_test_file("${url}" "${AOM_TEST_CHECKSUM}" "${filepath}")
+endif ()
diff --git a/test/test_data_util.cmake b/test/test_data_util.cmake
index f096e4e..e464104 100644
--- a/test/test_data_util.cmake
+++ b/test/test_data_util.cmake
@@ -11,15 +11,14 @@
# Parses test/test-data.sha1 and writes captured file names and checksums to
# $out_files and $out_checksums as lists.
-function (make_test_data_lists out_files out_checksums)
- if (NOT AOM_TEST_DATA_LIST OR NOT EXISTS "${AOM_TEST_DATA_LIST}")
- message(FATAL_ERROR "AOM_TEST_DATA_LIST (${AOM_TEST_DATA_LIST}) missing or "
- "variable empty.")
+function (make_test_data_lists test_data_file out_files out_checksums)
+ if (NOT test_data_file OR NOT EXISTS "${test_data_file}")
+ message(FATAL_ERROR "Test info file missing or empty (${test_data_file})")
endif ()
- # Read test-data.sha1 into $files_and_checksums. $files_and_checksums becomes
- # a list with an entry for each line from $AOM_TEST_DATA_LIST.
- file(STRINGS "${AOM_TEST_DATA_LIST}" files_and_checksums)
+ # Read $test_data_file into $files_and_checksums. $files_and_checksums becomes
+ # a list with an entry for each line from $test_data_file.
+ file(STRINGS "${test_data_file}" files_and_checksums)
# Iterate over the list of lines and split it into $checksums and $filenames.
foreach (line ${files_and_checksums})
@@ -33,8 +32,10 @@
set(filenames ${filenames} ${filename})
endforeach ()
- if (NOT checksums OR NOT filenames)
- message(FATAL_ERROR "Parsing of ${AOM_TEST_DATA_LIST} failed.")
+ list(LENGTH filenames num_files)
+ list(LENGTH checksums num_checksums)
+ if (NOT checksums OR NOT filenames OR NOT num_files EQUAL num_checksums)
+ message(FATAL_ERROR "Parsing of ${test_data_file} failed.")
endif ()
set(${out_checksums} ${checksums} PARENT_SCOPE)
@@ -62,7 +63,9 @@
unset(${out_needs_update} PARENT_SCOPE)
else ()
set(${out_needs_update} 1 PARENT_SCOPE)
+ return ()
endif ()
+ message("${local_path} up to date.")
endfunction ()
# Downloads data from $file_url, confirms that $file_checksum matches, and
diff --git a/test/test_runner.cmake b/test/test_runner.cmake
new file mode 100644
index 0000000..b8176d7
--- /dev/null
+++ b/test/test_runner.cmake
@@ -0,0 +1,20 @@
+##
+## Copyright (c) 2017, Alliance for Open Media. All rights reserved
+##
+## This source code is subject to the terms of the BSD 2 Clause License and
+## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+## was not distributed with this source code in the LICENSE file, you can
+## obtain it at www.aomedia.org/license/software. If the Alliance for Open
+## Media Patent License 1.0 was not distributed with this source code in the
+## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+##
+if (NOT AOM_ROOT OR NOT AOM_CONFIG_DIR OR NOT AOM_TEST_TARGET
+ OR NOT GTEST_TOTAL_SHARDS OR "${GTEST_SHARD_INDEX}" STREQUAL "")
+ message(FATAL_ERROR
+ "The variables AOM_ROOT AOM_CONFIG_DIR AOM_TEST_TARGET
+ GTEST_SHARD_INDEX and GTEST_TOTAL_SHARDS must be defined.")
+endif ()
+
+set($ENV{GTEST_SHARD_INDEX} ${GTEST_SHARD_INDEX})
+set($ENV{GTEST_TOTAL_SHARDS} ${GTEST_TOTAL_SHARDS})
+execute_process(COMMAND ${AOM_CONFIG_DIR}/${AOM_TEST_TARGET})
diff --git a/test/test_worker.cmake b/test/test_worker.cmake
deleted file mode 100644
index a57cf1a..0000000
--- a/test/test_worker.cmake
+++ /dev/null
@@ -1,49 +0,0 @@
-##
-## Copyright (c) 2017, Alliance for Open Media. All rights reserved
-##
-## This source code is subject to the terms of the BSD 2 Clause License and
-## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
-## was not distributed with this source code in the LICENSE file, you can
-## obtain it at www.aomedia.org/license/software. If the Alliance for Open
-## Media Patent License 1.0 was not distributed with this source code in the
-## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
-##
-if (NOT AOM_ROOT OR NOT AOM_CONFIG_DIR)
- message(FATAL_ERROR "AOM_ROOT AND AOM_CONFIG_DIR must be defined.")
-endif ()
-
-set(AOM_TEST_DATA_LIST "${AOM_ROOT}/test/test-data.sha1")
-set(AOM_TEST_DATA_URL "http://downloads.webmproject.org/test_data/libvpx")
-set(AOM_TEST_DATA_PATH "$ENV{LIBAOM_TEST_DATA_PATH}")
-
-include("${AOM_ROOT}/test/test_data_util.cmake")
-
-if ("${AOM_TEST_DATA_PATH}" STREQUAL "")
- message(WARNING "Writing test data to ${AOM_CONFIG_DIR}, set "
- "$LIBAOM_TEST_DATA_PATH in your environment to avoid this warning.")
- set(AOM_TEST_DATA_PATH "${AOM_CONFIG_DIR}")
-endif ()
-
-if (NOT EXISTS "${AOM_TEST_DATA_PATH}")
- file(MAKE_DIRECTORY "${AOM_TEST_DATA_PATH}")
-endif ()
-
-make_test_data_lists("AOM_TEST_DATA_FILES" "AOM_TEST_DATA_CHECKSUMS")
-expand_test_file_paths("AOM_TEST_DATA_FILES" "${AOM_TEST_DATA_PATH}"
- "AOM_TEST_DATA_FILE_PATHS")
-expand_test_file_paths("AOM_TEST_DATA_FILES" "${AOM_TEST_DATA_URL}"
- "AOM_TEST_DATA_URLS")
-list(LENGTH AOM_TEST_DATA_FILES num_files)
-math(EXPR num_files "${num_files} - 1")
-
-foreach (file_num RANGE ${num_files})
- list(GET AOM_TEST_DATA_FILES ${file_num} filename)
- list(GET AOM_TEST_DATA_CHECKSUMS ${file_num} checksum)
- list(GET AOM_TEST_DATA_FILE_PATHS ${file_num} filepath)
- list(GET AOM_TEST_DATA_URLS ${file_num} url)
-
- check_file("${filepath}" "${checksum}" "needs_download")
- if (needs_download)
- download_test_file("${url}" "${checksum}" "${filepath}")
- endif ()
-endforeach ()