From 3ce34a81b2189dcaf182c078484a570fbde08ce6 Mon Sep 17 00:00:00 2001 From: Joe McDonnell Date: Fri, 21 Dec 2018 14:58:23 -0800 Subject: [PATCH] IMPALA-8071: Initial unified backend test framework There are 100+ backend tests and each requires 400+ MB of disk space when statically linked (the default). This requires a large amount of disk space and adds considerable link time. This introduces a framework to link multiple backend tests into a single executable. Currently it does this for several tests in be/src/util. It saves about 10GB of space. It maintains several of the same properties that the current tests have: 1. "make " rebuilds that test. 2. It generates an executable shell script with the same name as the original backend test that runs the same subset of tests. 3. It generates JUnitXML and log files with names that match the test name. 4. One can run the shell script with "--gtest_filter" and run a subset of the tests. 5. ctest commands such as ctest -R continue to function. It validates at build time that every test linked into the unified executable is covered by an equivalent test filter pattern. This means that every test in the unified executable will run as part of normal testing. Introducing the framework along with a limited number of trial backend tests gives us a chance to evaluate this change before continuing to convert tests. Change-Id: Ia03ef38719b1fbc0fe2025e16b7b3d3dd4488842 Reviewed-on: http://gerrit.cloudera.org:8080/12124 Reviewed-by: Tim Armstrong Tested-by: Impala Public Jenkins --- be/CMakeLists.txt | 106 +++++++++++++++- be/src/service/CMakeLists.txt | 8 ++ be/src/service/unified-betest-main.cc | 49 ++++++++ be/src/util/CMakeLists.txt | 119 ++++++++++++------ be/src/util/benchmark-test.cc | 1 - be/src/util/bit-packing-test.cc | 1 - be/src/util/bit-stream-utils-test.cc | 1 - be/src/util/bit-util-test.cc | 1 - be/src/util/bitmap-test.cc | 2 - be/src/util/blocking-queue-test.cc | 1 - be/src/util/bloom-filter-test.cc | 6 - be/src/util/coding-util-test.cc | 1 - be/src/util/debug-util-test.cc | 1 - be/src/util/dict-test.cc | 1 - be/src/util/error-util-test.cc | 1 - be/src/util/filesystem-util-test.cc | 1 - be/src/util/fixed-size-hash-table-test.cc | 1 - be/src/util/hdfs-util-test.cc | 7 -- be/src/util/logging-support-test.cc | 1 - be/src/util/lru-cache-test.cc | 1 - be/src/util/metrics-test.cc | 5 - be/src/util/min-max-filter-test.cc | 7 -- be/src/util/openssl-util-test.cc | 1 - be/src/util/os-util-test.cc | 1 - be/src/util/parse-util-test.cc | 1 - be/src/util/pretty-printer-test.cc | 1 - be/src/util/proc-info-test.cc | 6 - be/src/util/redactor-config-parser-test.cc | 1 - be/src/util/redactor-test-utils.cc | 110 ++++++++++++++++ be/src/util/redactor-test-utils.h | 93 +++----------- be/src/util/redactor-test.cc | 2 - be/src/util/redactor-unconfigured-test.cc | 4 +- be/src/util/rle-test.cc | 1 - be/src/util/runtime-profile-test.cc | 1 - be/src/util/string-parser-test.cc | 1 - be/src/util/string-util-test.cc | 1 - be/src/util/symbols-util-test.cc | 1 - be/src/util/sys-info-test.cc | 1 - be/src/util/system-state-info-test.cc | 1 - be/src/util/thread-pool-test.cc | 1 - be/src/util/time-test.cc | 1 - be/src/util/uid-util-test.cc | 1 - be/src/util/zip-util-test.cc | 6 - bin/gen-backend-test-script.sh | 48 +++++++ bin/junitxml_prune_notrun.py | 1 + bin/rat_exclude_files.txt | 1 + bin/validate-unified-backend-test-filters.py | 67 ++++++++++ .../jenkins/junitxml_prune_notrun.py | 65 ++++++++++ 48 files changed, 548 insertions(+), 192 deletions(-) create mode 100644 be/src/service/unified-betest-main.cc create mode 100644 be/src/util/redactor-test-utils.cc create mode 100755 bin/gen-backend-test-script.sh create mode 120000 bin/junitxml_prune_notrun.py create mode 100755 bin/validate-unified-backend-test-filters.py create mode 100755 lib/python/impala_py_lib/jenkins/junitxml_prune_notrun.py diff --git a/be/CMakeLists.txt b/be/CMakeLists.txt index 2cec3dd44..ad163f286 100644 --- a/be/CMakeLists.txt +++ b/be/CMakeLists.txt @@ -380,8 +380,7 @@ if (NOT APPLE) set(WL_START_GROUP "-Wl,--start-group") set(WL_END_GROUP "-Wl,--end-group") endif() -set (IMPALA_LINK_LIBS - ${WL_START_GROUP} +set (IMPALA_LIBS BufferPool Catalog CodeGen @@ -409,6 +408,38 @@ set (IMPALA_LINK_LIBS token_proto Udf Util +) + +set (IMPALA_LINK_LIBS + ${WL_START_GROUP} + ${IMPALA_LIBS} + ${WL_END_GROUP} +) + +# Backend tests originally produced a single executable for each backend c++ test file. +# Since these executables linked in all of the libraries, each test is very large +# (100s of MB) and requires considerable link time. To address this, tests can now +# be linked into a unified test executable that contains tests from many backend +# c++ test files. See the ADD_UNIFIED_BE_TEST and ADD_UNIFIED_LSAN_BE_TEST +# macros below. The original mode of producing a standalone executable is still +# available via the ADD_BE_TEST and ADD_LSAN_BE_TEST macros. +# +# To make a unified test executable, the backend tests need to be in their own libraries. +# The main function is provided by the unified main c++ file. None of the test c++ files +# has a main function. Normal dependency resolution would not include any of the tests +# in any executable, as no function references them. Force the unified test executable +# to include the tests by using "--whole-archive". +set(WL_WHOLE_ARCHIVE "-Wl,--whole-archive") +set(WL_NO_WHOLE_ARCHIVE "-Wl,--no-whole-archive") +set (UNIFIED_TEST_LIBS + UtilTests +) +set (UNIFIED_TEST_LINK_LIBS + ${WL_START_GROUP} + ${WL_WHOLE_ARCHIVE} + ${UNIFIED_TEST_LIBS} + ${WL_NO_WHOLE_ARCHIVE} + ${IMPALA_LIBS} ${WL_END_GROUP} ) @@ -475,6 +506,13 @@ set (IMPALA_LINK_LIBS ${IMPALA_LINK_LIBS} -ldl # Needed for LLVM ) +# Add external dependencies for backend tests +set (UNIFIED_TEST_LINK_LIBS ${UNIFIED_TEST_LINK_LIBS} + ${IMPALA_DEPENDENCIES} + -lrt + -ldl # Needed for LLVM +) + # The above link list does not include tcmalloc. This is because the Impala JVM support # libraries (libfesupport, libloggingsupport) cannot use tcmalloc in all cases. When they # are started up by the FE (for tests) the jvm has already made allocations before @@ -485,6 +523,7 @@ set (IMPALA_LINK_LIBS_NO_TCMALLOC ${IMPALA_LINK_LIBS}) if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN") set (IMPALA_LINK_LIBS ${IMPALA_LINK_LIBS} tcmallocstatic) + set (UNIFIED_TEST_LINK_LIBS ${UNIFIED_TEST_LINK_LIBS} tcmallocstatic) endif() # When we link statically, we need to replace the static libhdfs.a with the dynamic @@ -501,6 +540,7 @@ set(IMPALA_LINK_LIBS_DYNAMIC_TARGETS ${IMPALA_LINK_LIBS_DYNAMIC_TARGETS} # TODO: build time for tests is no longer small, but our dependencies are now very # complicated and hard to isolate set (IMPALA_TEST_LINK_LIBS ${IMPALA_LINK_LIBS} gtest) +set (UNIFIED_TEST_LINK_LIBS ${UNIFIED_TEST_LINK_LIBS} gtest) MESSAGE(STATUS "Compiler Flags: ${CMAKE_CXX_FLAGS}") @@ -512,9 +552,24 @@ set(LLVM_IR_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/llvm-ir") file(MAKE_DIRECTORY ${LLVM_IR_OUTPUT_DIRECTORY}) # Add custom target to only build the backend tests -add_custom_target(be-test) +# Note: this specifies "ALL" so it builds if running "make" with no arguments. This is +# necessary due to the non-executable targets (i.e. generating backend test scripts) +# that run for the unified backend tests. +add_custom_target(be-test ALL) -# Utility CMake function to make specifying tests and benchmarks less verbose +# Add custom target to build unified backend tests +add_custom_target(unified-be-test) + +# Add custom target to build the unified backend test executable +add_custom_target(unified-be-test-executable) + +# Variable to use to aggregate all of the filter patterns, joined by ":" +set_property(GLOBAL PROPERTY AGG_UNIFIED_FILTER_PATTERN) + +# Utility CMake functions for specifying tests and benchmarks + +# ADD_BE_TEST: This function adds a backend test with its own executable. The associated +# c++ file must have its own main() function. FUNCTION(ADD_BE_TEST TEST_NAME) # This gets the directory where the test is from (e.g. 'exprs' or 'runtime') file(RELATIVE_PATH DIR_NAME "${CMAKE_SOURCE_DIR}/be/src/" ${CMAKE_CURRENT_SOURCE_DIR}) @@ -526,6 +581,27 @@ FUNCTION(ADD_BE_TEST TEST_NAME) ADD_DEPENDENCIES(be-test ${TEST_NAME}) ENDFUNCTION() +# ADD_UNIFIED_BE_TEST: This function adds a backend test that is part of the unified +# backend executable. This creates an executable script that runs the unified executable +# with appropriate args to run the subset of tests identified by "TEST_FILTER_PATTERN". +# See the documentation for --gtest_filter for examples of filter patterns. +FUNCTION(ADD_UNIFIED_BE_TEST TEST_NAME TEST_FILTER_PATTERN) + # This gets the directory where the test is from (e.g. 'exprs' or 'runtime') + file(RELATIVE_PATH DIR_NAME "${CMAKE_SOURCE_DIR}/be/src/" ${CMAKE_CURRENT_SOURCE_DIR}) + add_custom_target(${TEST_NAME} "${CMAKE_SOURCE_DIR}/bin/gen-backend-test-script.sh" + "${BUILD_OUTPUT_ROOT_DIRECTORY}/${DIR_NAME}/${TEST_NAME}" + ${TEST_FILTER_PATTERN}) + # Incorporate this TEST_FILTER_PATTERN into the aggregate list of filter patterns + get_property(tmp GLOBAL PROPERTY AGG_UNIFIED_FILTER_PATTERN) + set(tmp "${TEST_FILTER_PATTERN}:${tmp}") + set_property(GLOBAL PROPERTY AGG_UNIFIED_FILTER_PATTERN "${tmp}") + ADD_TEST(NAME ${TEST_NAME} + COMMAND "${BUILD_OUTPUT_ROOT_DIRECTORY}/${DIR_NAME}/${TEST_NAME}" + -log_dir=$ENV{IMPALA_BE_TEST_LOGS_DIR}) + ADD_DEPENDENCIES(unified-be-test ${TEST_NAME}) + ADD_DEPENDENCIES(${TEST_NAME} unified-be-test-executable) +ENDFUNCTION() + FUNCTION(ENABLE_LSAN_FOR_TEST TEST_NAME) SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES ENVIRONMENT "ASAN_OPTIONS=handle_segv=0 detect_leaks=1 allocator_may_return_null=1") @@ -533,13 +609,20 @@ FUNCTION(ENABLE_LSAN_FOR_TEST TEST_NAME) "LSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/bin/lsan-suppressions.txt") ENDFUNCTION() -# Same as ADD_BE_TEST, but also enable LeakSanitizer. +# ADD_BE_LSAN_TEST: Same as ADD_BE_TEST, but also enable LeakSanitizer. # TODO: IMPALA-2746: we should make this the default. FUNCTION(ADD_BE_LSAN_TEST TEST_NAME) ADD_BE_TEST(${TEST_NAME}) ENABLE_LSAN_FOR_TEST(${TEST_NAME}) ENDFUNCTION() +# ADD_UNIFIED_BE_LSAN_TEST: Same as ADD_UNIFIED_BE_TEST, but also enable LeakSanitizer. +# TODO: IMPALA_2746: we should make this the default. +FUNCTION(ADD_UNIFIED_BE_LSAN_TEST TEST_NAME TEST_FILTER_PATTERN) + ADD_UNIFIED_BE_TEST(${TEST_NAME} ${TEST_FILTER_PATTERN}) + ENABLE_LSAN_FOR_TEST(${TEST_NAME}) +ENDFUNCTION() + # Similar utility function for tests that use the UDF SDK FUNCTION(ADD_UDF_TEST TEST_NAME) # This gets the directory where the test is from (e.g. 'exprs' or 'runtime') @@ -618,6 +701,19 @@ link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/build/transport ) +# Add custom target to validate the unified backend test executable and test match +# patterns. At this point, all filter patterns have been aggregated from the individual +# ADD_UNIFIED_BE_TEST calls into AGG_UNIFIED_FILTER_PATTERN. +get_property(TOTAL_UNIFIED_FILTER_PATTERN GLOBAL PROPERTY AGG_UNIFIED_FILTER_PATTERN) +add_custom_target(unified-be-test-validate + "${CMAKE_CURRENT_SOURCE_DIR}/../bin/validate-unified-backend-test-filters.py" + "-f" "${TOTAL_UNIFIED_FILTER_PATTERN}" + "-b" "${BUILD_OUTPUT_ROOT_DIRECTORY}/service/unifiedbetests") + +ADD_DEPENDENCIES(be-test unified-be-test) +ADD_DEPENDENCIES(unified-be-test unified-be-test-executable unified-be-test-validate) +ADD_DEPENDENCIES(unified-be-test-validate unified-be-test-executable) + # only generate statically linked libs and executables set(BUILD_SHARED_LIBS OFF) diff --git a/be/src/service/CMakeLists.txt b/be/src/service/CMakeLists.txt index 701c7f4fd..515ee3beb 100644 --- a/be/src/service/CMakeLists.txt +++ b/be/src/service/CMakeLists.txt @@ -58,6 +58,10 @@ add_executable(impalad daemon-main.cc ) +add_executable(unifiedbetests + unified-betest-main.cc +) + # All Impala daemons run from the same binary. The code that is run is determined by the # name (i.e. argv[0]) of the command that executes the binary, so we create symlinks for # statestored and catalogd. The symlinks are relative so they can be installed along with @@ -86,6 +90,10 @@ target_link_libraries(impalad ${IMPALA_LINK_LIBS} ) +target_link_libraries(unifiedbetests + ${JAVA_JSIG_LIBRARY} ${UNIFIED_TEST_LINK_LIBS}) +ADD_DEPENDENCIES(unified-be-test-executable unifiedbetests) + ADD_BE_TEST(session-expiry-test session-expiry-test.cc) # TODO: this leaks thrift server ADD_BE_LSAN_TEST(hs2-util-test hs2-util-test.cc) ADD_BE_LSAN_TEST(query-options-test query-options-test.cc) diff --git a/be/src/service/unified-betest-main.cc b/be/src/service/unified-betest-main.cc new file mode 100644 index 000000000..645d699d6 --- /dev/null +++ b/be/src/service/unified-betest-main.cc @@ -0,0 +1,49 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + +#include "service/fe-support.h" +#include "testutil/gtest-util.h" +#include "common/names.h" + +// Main function for the unified backend tests. This incorporates multiple common +// initializations (e.g. setting a random seed) that are not necessary for every test, +// but allows unifying more tests into a single executable. The tests are incorporated +// by linking test libraries into this executable. +int main(int argc, char** argv) { + // If running with --gtest_list_tests, avoid the Impala-specific initialization code. + // This is particularly useful for the InitFeSupport() call, as that requires an + // appropriate CLASSPATH set in the environment. It is useful to be able to list the + // tests without that environment in place. + // Note: This needs to happen before InitGoogleTest(), because that removes its flags. + bool list_tests_only = false; + for (int i = 0; i < argc; i++) { + if (string(argv[i]) == "--gtest_list_tests") { + list_tests_only = true; + break; + } + } + ::testing::InitGoogleTest(&argc, argv); + if (!list_tests_only) { + impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST); + impala::InitFeSupport(); + uint32_t seed = time(NULL); + cout << "seed = " << seed << endl; + srand(seed); + } + return RUN_ALL_TESTS(); +} diff --git a/be/src/util/CMakeLists.txt b/be/src/util/CMakeLists.txt index 63bb0bafa..08d311160 100644 --- a/be/src/util/CMakeLists.txt +++ b/be/src/util/CMakeLists.txt @@ -96,6 +96,46 @@ add_library(Util ) add_dependencies(Util gen-deps gen_ir_descriptions) +add_library(UtilTests + benchmark-test.cc + bitmap-test.cc + bit-packing-test.cc + bit-util-test.cc + blocking-queue-test.cc + bloom-filter-test.cc + coding-util-test.cc + debug-util-test.cc + dict-test.cc + error-util-test.cc + filesystem-util-test.cc + fixed-size-hash-table-test.cc + hdfs-util-test.cc + logging-support-test.cc + lru-cache-test.cc + metrics-test.cc + min-max-filter-test.cc + openssl-util-test.cc + os-util-test.cc + parse-util-test.cc + pretty-printer-test.cc + proc-info-test.cc + redactor-config-parser-test.cc + redactor-test.cc + redactor-test-utils.cc + redactor-unconfigured-test.cc + rle-test.cc + runtime-profile-test.cc + string-parser-test.cc + string-util-test.cc + symbols-util-test.cc + sys-info-test.cc + thread-pool-test.cc + time-test.cc + uid-util-test.cc + zip-util-test.cc +) +add_dependencies(UtilTests gen-deps gen_ir_descriptions) + # Squeasel requires C99 compatibility to build. SET_SOURCE_FILES_PROPERTIES(${SQUEASEL_SRC_DIR}/squeasel.c PROPERTIES COMPILE_FLAGS -std=c99) @@ -111,44 +151,49 @@ target_link_libraries(parquet-reader ${IMPALA_LINK_LIBS}) target_link_libraries(loggingsupport ${IMPALA_LINK_LIBS_DYNAMIC_TARGETS}) -ADD_BE_LSAN_TEST(benchmark-test) -ADD_BE_LSAN_TEST(bitmap-test) -ADD_BE_LSAN_TEST(bit-packing-test) -ADD_BE_LSAN_TEST(bit-stream-utils-test) -ADD_BE_LSAN_TEST(bit-util-test) -ADD_BE_LSAN_TEST(blocking-queue-test) -ADD_BE_LSAN_TEST(bloom-filter-test) -ADD_BE_LSAN_TEST(coding-util-test) -ADD_BE_LSAN_TEST(debug-util-test) +ADD_UNIFIED_BE_LSAN_TEST(benchmark-test "BenchmarkTest.*") +ADD_UNIFIED_BE_LSAN_TEST(bitmap-test "Bitmap.*") +ADD_UNIFIED_BE_LSAN_TEST(bit-packing-test "BitPackingTest.*") +ADD_UNIFIED_BE_LSAN_TEST(bit-stream-utils-test "BitArray.*") +ADD_UNIFIED_BE_LSAN_TEST(bit-util-test "BitUtil.*") +ADD_UNIFIED_BE_LSAN_TEST(blocking-queue-test "BlockingQueueTest.*") +ADD_UNIFIED_BE_LSAN_TEST(bloom-filter-test "BloomFilter.*:BloomFilterTest.*") +ADD_UNIFIED_BE_LSAN_TEST(coding-util-test "UrlCodingTest.*:Base64Test.*:HtmlEscapingTest.*") +ADD_UNIFIED_BE_LSAN_TEST(debug-util-test "DebugUtil.*") +# Decompress-test fails in unified mode (possibly due to missing libs) ADD_BE_LSAN_TEST(decompress-test) -ADD_BE_LSAN_TEST(dict-test) -ADD_BE_LSAN_TEST(error-util-test) -ADD_BE_LSAN_TEST(filesystem-util-test) -ADD_BE_LSAN_TEST(fixed-size-hash-table-test) -ADD_BE_LSAN_TEST(hdfs-util-test) +ADD_UNIFIED_BE_LSAN_TEST(dict-test "DictTest.*") +ADD_UNIFIED_BE_LSAN_TEST(error-util-test "ErrorMsg.*") +ADD_UNIFIED_BE_LSAN_TEST(filesystem-util-test "FilesystemUtil.*") +ADD_UNIFIED_BE_LSAN_TEST(fixed-size-hash-table-test "FixedSizeHash.*") +ADD_UNIFIED_BE_LSAN_TEST(hdfs-util-test HdfsUtilTest.*) +# internal-queue-test has a non-standard main(), so it needs a small amount of thought +# to use a unified executable ADD_BE_LSAN_TEST(internal-queue-test) -ADD_BE_LSAN_TEST(logging-support-test) -ADD_BE_LSAN_TEST(lru-cache-test) -ADD_BE_LSAN_TEST(metrics-test) -ADD_BE_LSAN_TEST(min-max-filter-test) -ADD_BE_LSAN_TEST(openssl-util-test) -ADD_BE_LSAN_TEST(os-util-test) -ADD_BE_LSAN_TEST(parse-util-test) -ADD_BE_LSAN_TEST(pretty-printer-test) -ADD_BE_LSAN_TEST(proc-info-test) +ADD_UNIFIED_BE_LSAN_TEST(logging-support-test "LoggingSupport.*") +ADD_UNIFIED_BE_LSAN_TEST(lru-cache-test "FifoMultimap.*") +ADD_UNIFIED_BE_LSAN_TEST(metrics-test "MetricsTest.*") +ADD_UNIFIED_BE_LSAN_TEST(min-max-filter-test "MinMaxFilterTest.*") +ADD_UNIFIED_BE_LSAN_TEST(openssl-util-test "OpenSSLUtilTest.*") +ADD_UNIFIED_BE_LSAN_TEST(os-util-test "OsUtil.*") +ADD_UNIFIED_BE_LSAN_TEST(parse-util-test "ParseMemSpecs.*") +ADD_UNIFIED_BE_LSAN_TEST(pretty-printer-test "PrettyPrinterTest.*") +ADD_UNIFIED_BE_LSAN_TEST(proc-info-test "MemInfo.*:ProcessStateInfo.*:MappedMapInfo.*:CGroupInfo.*") +# IMPALA-4128: promise-test has a non-standard main(), so it can't be unified yet ADD_BE_LSAN_TEST(promise-test) -ADD_BE_LSAN_TEST(redactor-config-parser-test) -ADD_BE_LSAN_TEST(redactor-test) -ADD_BE_LSAN_TEST(redactor-unconfigured-test) -ADD_BE_LSAN_TEST(rle-test) -ADD_BE_LSAN_TEST(runtime-profile-test) -ADD_BE_LSAN_TEST(string-parser-test) -ADD_BE_LSAN_TEST(string-util-test) -ADD_BE_LSAN_TEST(symbols-util-test) -ADD_BE_LSAN_TEST(system-state-info-test) -ADD_BE_LSAN_TEST(sys-info-test) -ADD_BE_LSAN_TEST(thread-pool-test) -ADD_BE_LSAN_TEST(time-test) -ADD_BE_LSAN_TEST(uid-util-test) +ADD_UNIFIED_BE_LSAN_TEST(redactor-config-parser-test ParserTest.*) +ADD_UNIFIED_BE_LSAN_TEST(redactor-test "RedactorTest.*") +ADD_UNIFIED_BE_LSAN_TEST(redactor-unconfigured-test "RedactorUnconfigTest.*") +ADD_UNIFIED_BE_LSAN_TEST(rle-test "BitArray.*:RleTest.*") +ADD_UNIFIED_BE_LSAN_TEST(runtime-profile-test "CountersTest.*:TimerCounterTest.*:TimeSeriesCounterTest.*:VariousNumbers/TimeSeriesCounterResampleTest.*") +ADD_UNIFIED_BE_LSAN_TEST(string-parser-test "StringToInt.*:StringToIntWithBase.*:StringToFloat.*:StringToBool.*") +ADD_UNIFIED_BE_LSAN_TEST(string-util-test "TruncateDownTest.*:TruncateUpTest.*:CommandSeparatedContainsTest.*:CommaSeparatedContainsTest.*") +ADD_UNIFIED_BE_LSAN_TEST(symbols-util-test "SymbolsUtil.*") +ADD_UNIFIED_BE_LSAN_TEST(system-state-info-test "SystemStateInfoTest.*") +ADD_UNIFIED_BE_LSAN_TEST(sys-info-test "CpuInfoTest.*:DiskInfoTest.*") +ADD_UNIFIED_BE_LSAN_TEST(thread-pool-test "ThreadPoolTest.*") +ADD_UNIFIED_BE_LSAN_TEST(time-test "TimeTest.*") +ADD_UNIFIED_BE_LSAN_TEST(uid-util-test "UidUtil.*") +# Using standalone webserver-test for now, nonstandard main() passes in a port. ADD_BE_LSAN_TEST(webserver-test) -ADD_BE_LSAN_TEST(zip-util-test) +ADD_UNIFIED_BE_LSAN_TEST(zip-util-test "ZipUtilTest.*") diff --git a/be/src/util/benchmark-test.cc b/be/src/util/benchmark-test.cc index d069d46c3..355f6e00e 100644 --- a/be/src/util/benchmark-test.cc +++ b/be/src/util/benchmark-test.cc @@ -72,4 +72,3 @@ TEST(BenchmarkTest, DISABLED_Basic) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/bit-packing-test.cc b/be/src/util/bit-packing-test.cc index d65bb388c..2cf86bad4 100644 --- a/be/src/util/bit-packing-test.cc +++ b/be/src/util/bit-packing-test.cc @@ -156,4 +156,3 @@ TEST(BitPackingTest, RandomUnpack) { } } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/bit-stream-utils-test.cc b/be/src/util/bit-stream-utils-test.cc index 56879e71f..e02e3c3a9 100644 --- a/be/src/util/bit-stream-utils-test.cc +++ b/be/src/util/bit-stream-utils-test.cc @@ -204,4 +204,3 @@ TEST(BitArray, TestValues) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/bit-util-test.cc b/be/src/util/bit-util-test.cc index 7c70e6eff..ae3fa6284 100644 --- a/be/src/util/bit-util-test.cc +++ b/be/src/util/bit-util-test.cc @@ -329,4 +329,3 @@ TEST(BitUtil, CpuInfoIsSupportedHoist) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/bitmap-test.cc b/be/src/util/bitmap-test.cc index c0a389961..61efa2333 100644 --- a/be/src/util/bitmap-test.cc +++ b/be/src/util/bitmap-test.cc @@ -120,5 +120,3 @@ TEST(Bitmap, MemUsage) { } } - -IMPALA_TEST_MAIN(); diff --git a/be/src/util/blocking-queue-test.cc b/be/src/util/blocking-queue-test.cc index 8a91275b9..c807054ec 100644 --- a/be/src/util/blocking-queue-test.cc +++ b/be/src/util/blocking-queue-test.cc @@ -204,4 +204,3 @@ TEST(BlockingQueueTest, TestMultipleThreadsWithBytesLimit) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/bloom-filter-test.cc b/be/src/util/bloom-filter-test.cc index 6fcfc9222..e8e7e2e8b 100644 --- a/be/src/util/bloom-filter-test.cc +++ b/be/src/util/bloom-filter-test.cc @@ -358,9 +358,3 @@ TEST_F(BloomFilterTest, ThriftOr) { } // namespace impala -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST); - impala::InitFeSupport(); - return RUN_ALL_TESTS(); -} diff --git a/be/src/util/coding-util-test.cc b/be/src/util/coding-util-test.cc index 402f0fcc4..4222d9c01 100644 --- a/be/src/util/coding-util-test.cc +++ b/be/src/util/coding-util-test.cc @@ -121,4 +121,3 @@ TEST(HtmlEscapingTest, Basic) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/debug-util-test.cc b/be/src/util/debug-util-test.cc index 636d9d459..bf430c750 100644 --- a/be/src/util/debug-util-test.cc +++ b/be/src/util/debug-util-test.cc @@ -102,4 +102,3 @@ TEST(DebugUtil, PreCDH5QueryIdParsing) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/dict-test.cc b/be/src/util/dict-test.cc index ebfba11e4..4f46cf2ed 100644 --- a/be/src/util/dict-test.cc +++ b/be/src/util/dict-test.cc @@ -398,4 +398,3 @@ TEST(DictTest, TestSkippingValues) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/error-util-test.cc b/be/src/util/error-util-test.cc index baba5ad38..deec5d427 100644 --- a/be/src/util/error-util-test.cc +++ b/be/src/util/error-util-test.cc @@ -139,4 +139,3 @@ TEST(ErrorMsg, PrintMap) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/filesystem-util-test.cc b/be/src/util/filesystem-util-test.cc index be5f5eb67..cd081a927 100644 --- a/be/src/util/filesystem-util-test.cc +++ b/be/src/util/filesystem-util-test.cc @@ -118,4 +118,3 @@ TEST(FilesystemUtil, Paths) { EXPECT_EQ(string("def"), relpath); } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/fixed-size-hash-table-test.cc b/be/src/util/fixed-size-hash-table-test.cc index 211693f3e..f0501d427 100644 --- a/be/src/util/fixed-size-hash-table-test.cc +++ b/be/src/util/fixed-size-hash-table-test.cc @@ -79,4 +79,3 @@ TEST(FixedSizeHash, TestAllOperations) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/hdfs-util-test.cc b/be/src/util/hdfs-util-test.cc index 7ed364689..cbeac1664 100644 --- a/be/src/util/hdfs-util-test.cc +++ b/be/src/util/hdfs-util-test.cc @@ -111,10 +111,3 @@ TEST(HdfsUtilTest, CheckGetBaseName) { EXPECT_EQ("c", GetBaseName("/c")); EXPECT_EQ("c", GetBaseName("/a//b/c/")); } - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - InitCommonRuntime(argc, argv, true, TestInfo::BE_TEST); - InitFeSupport(); - return RUN_ALL_TESTS(); -} diff --git a/be/src/util/logging-support-test.cc b/be/src/util/logging-support-test.cc index 96da51963..a4d0edcb3 100644 --- a/be/src/util/logging-support-test.cc +++ b/be/src/util/logging-support-test.cc @@ -93,4 +93,3 @@ TEST(LoggingSupport, DeleteOldLogs) { filesystem::remove_all(dir); } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/lru-cache-test.cc b/be/src/util/lru-cache-test.cc index 993d9df0e..96a9b284a 100644 --- a/be/src/util/lru-cache-test.cc +++ b/be/src/util/lru-cache-test.cc @@ -151,4 +151,3 @@ TEST(FifoMultimap, PopShouldPopMostRecent) { ASSERT_EQ(0, c.size()); } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/metrics-test.cc b/be/src/util/metrics-test.cc index a7ccd8647..d61b70d30 100644 --- a/be/src/util/metrics-test.cc +++ b/be/src/util/metrics-test.cc @@ -435,8 +435,3 @@ TEST_F(MetricsTest, MetricGroupJson) { } -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST); - return RUN_ALL_TESTS(); -} diff --git a/be/src/util/min-max-filter-test.cc b/be/src/util/min-max-filter-test.cc index c6704fc91..8ae20b7eb 100644 --- a/be/src/util/min-max-filter-test.cc +++ b/be/src/util/min-max-filter-test.cc @@ -505,10 +505,3 @@ TEST(MinMaxFilterTest, TestDecimalMinMaxFilter) { filter8->Close(); filter16->Close(); } - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - InitCommonRuntime(argc, argv, true, TestInfo::BE_TEST); - InitFeSupport(); - return RUN_ALL_TESTS(); -} diff --git a/be/src/util/openssl-util-test.cc b/be/src/util/openssl-util-test.cc index 77cb25564..9700cfe27 100644 --- a/be/src/util/openssl-util-test.cc +++ b/be/src/util/openssl-util-test.cc @@ -210,4 +210,3 @@ TEST_F(OpenSSLUtilTest, RandSeeding) { } } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/os-util-test.cc b/be/src/util/os-util-test.cc index 1491c9f31..5d383c116 100644 --- a/be/src/util/os-util-test.cc +++ b/be/src/util/os-util-test.cc @@ -62,4 +62,3 @@ TEST(OsUtil, RunShellProcess) { }); } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/parse-util-test.cc b/be/src/util/parse-util-test.cc index 971e11891..6b8e7a588 100644 --- a/be/src/util/parse-util-test.cc +++ b/be/src/util/parse-util-test.cc @@ -115,4 +115,3 @@ TEST(ParseMemSpecs, Basic) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/pretty-printer-test.cc b/be/src/util/pretty-printer-test.cc index 6daa131dd..5045e3ca3 100644 --- a/be/src/util/pretty-printer-test.cc +++ b/be/src/util/pretty-printer-test.cc @@ -140,4 +140,3 @@ TEST(PrettyPrinterTest, StringList) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/proc-info-test.cc b/be/src/util/proc-info-test.cc index 3c7c30c13..d9793e3a3 100644 --- a/be/src/util/proc-info-test.cc +++ b/be/src/util/proc-info-test.cc @@ -78,9 +78,3 @@ TEST(MappedMapInfo, Basic) { } -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST); - impala::InitFeSupport(); - return RUN_ALL_TESTS(); -} diff --git a/be/src/util/redactor-config-parser-test.cc b/be/src/util/redactor-config-parser-test.cc index c12683fdd..bedd55a3e 100644 --- a/be/src/util/redactor-config-parser-test.cc +++ b/be/src/util/redactor-config-parser-test.cc @@ -182,4 +182,3 @@ TEST(ParserTest, RuleNumberInErrorMessage) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/redactor-test-utils.cc b/be/src/util/redactor-test-utils.cc new file mode 100644 index 000000000..0a90eedd0 --- /dev/null +++ b/be/src/util/redactor-test-utils.cc @@ -0,0 +1,110 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include // file stuff +#include // rand +#include +#include +#include + +#include "util/redactor.h" +#include "util/redactor-test-utils.h" + +namespace impala { + +TempRulesFile::TempRulesFile(const std::string& contents) + : name_("/tmp/rules_XXXXXX"), + deleted_(false) { + int fd = mkstemp(&name_[0]); + if (fd == -1) { + std::cout << "Error creating temp file; " << strerror(errno) << std::endl; + abort(); + } + if (close(fd) != 0) { + std::cout << "Error closing temp file; " << strerror(errno) << std::endl; + abort(); + } + OverwriteContents(contents); +} + +void TempRulesFile::Delete() { + if (deleted_) return; + deleted_ = true; + if (remove(name()) != 0) { + std::cout << "Error deleting temp file; " << strerror(errno) << std::endl; + abort(); + } +} + +void TempRulesFile::OverwriteContents(const std::string& contents) { + FILE* handle = fopen(name(), "w"); + if (handle == NULL) { + std::cout << "Error creating temp file; " << strerror(errno) << std::endl; + abort(); + } + int status = fputs(contents.c_str(), handle); + if (status < 0) { + std::cout << "Error writing to temp file; " << strerror(errno) << std::endl; + abort(); + } + status = fclose(handle); + if (status != 0) { + std::cout << "Error closing temp file; " << strerror(errno) << std::endl; + abort(); + } +} + +unsigned int RandSeed() { + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + return now.tv_nsec + pthread_self(); +} + +/// Randomly fills the contents of 'string' up to the given length. +void RandomlyFillString(char* string, const int length) { + ASSERT_GT(length, 0); + unsigned int rand_seed = RandSeed(); + int char_count = static_cast('~') - static_cast(' ') + 1; + for (int i = 0; i < length - 1; ++i) { + string[i] = ' ' + rand_r(&rand_seed) % char_count; + } + string[length - 1] = '\0'; +} + +void AssertErrorMessageContains(const std::string& message, const char* expected) { + ASSERT_TRUE(message.find(expected) != std::string::npos) + << "Expected substring <<" << expected << ">> is not in <<" << message << ">>"; +} + +void AssertRedactedEquals(const char* message, const char* expected) { + std::string temp(message); + Redact(&temp); + ASSERT_EQ(expected, temp); + + /// Test the signature with the 'changed' argument. + temp = std::string(message); + bool changed = false; + Redact(&temp, &changed); + ASSERT_EQ(expected, temp); + ASSERT_EQ(temp == message, !changed); +} + +void AssertUnredacted(const char* message) { + AssertRedactedEquals(message, message); +} + +} diff --git a/be/src/util/redactor-test-utils.h b/be/src/util/redactor-test-utils.h index 3ee92d0a1..5f156bed1 100644 --- a/be/src/util/redactor-test-utils.h +++ b/be/src/util/redactor-test-utils.h @@ -17,17 +17,11 @@ #ifndef IMPALA_REDACTOR_TEST_UTILS_H #define IMPALA_REDACTOR_TEST_UTILS_H -#include // rand -#include // file stuff -#include -#include -#include #include #include #include "gutil/strings/substitute.h" -#include "util/redactor.h" namespace impala { @@ -35,49 +29,16 @@ namespace impala { /// upon test completion. class TempRulesFile { public: - TempRulesFile(const std::string& contents) - : name_("/tmp/rules_XXXXXX"), - deleted_(false) { - int fd = mkstemp(&name_[0]); - if (fd == -1) { - std::cout << "Error creating temp file; " << strerror(errno) << std::endl; - abort(); - } - if (close(fd) != 0) { - std::cout << "Error closing temp file; " << strerror(errno) << std::endl; - abort(); - } - OverwriteContents(contents); - } + // Creates a temporary file with the specified contents. + TempRulesFile(const std::string& contents); ~TempRulesFile() { Delete(); } - void Delete() { - if (deleted_) return; - deleted_ = true; - if (remove(name()) != 0) { - std::cout << "Error deleting temp file; " << strerror(errno) << std::endl; - abort(); - } - } + // Delete this temporary file + void Delete(); - void OverwriteContents(const std::string& contents) { - FILE* handle = fopen(name(), "w"); - if (handle == NULL) { - std::cout << "Error creating temp file; " << strerror(errno) << std::endl; - abort(); - } - int status = fputs(contents.c_str(), handle); - if (status < 0) { - std::cout << "Error writing to temp file; " << strerror(errno) << std::endl; - abort(); - } - status = fclose(handle); - if (status != 0) { - std::cout << "Error closing temp file; " << strerror(errno) << std::endl; - abort(); - } - } + // Overwrite the temporary file with the specified contents. + void OverwriteContents(const std::string& contents); /// Returns the absolute path to the file. const char* name() const { return name_.c_str(); } @@ -87,44 +48,20 @@ class TempRulesFile { bool deleted_; }; -unsigned int RandSeed() { - struct timespec now; - clock_gettime(CLOCK_REALTIME, &now); - return now.tv_nsec + pthread_self(); -} +// Produces a random seed based on the current time and the thread id. +unsigned int RandSeed(); /// Randomly fills the contents of 'string' up to the given length. -void RandomlyFillString(char* string, const int length) { - ASSERT_GT(length, 0); - unsigned int rand_seed = RandSeed(); - int char_count = static_cast('~') - static_cast(' ') + 1; - for (int i = 0; i < length - 1; ++i) { - string[i] = ' ' + rand_r(&rand_seed) % char_count; - } - string[length - 1] = '\0'; -} +void RandomlyFillString(char* string, const int length); -void AssertErrorMessageContains(const std::string& message, const char* expected) { - ASSERT_TRUE(message.find(expected) != std::string::npos) - << "Expected substring <<" << expected << ">> is not in <<" << message << ">>"; -} +/// Assert 'message' contains 'expected' +void AssertErrorMessageContains(const std::string& message, const char* expected); -void AssertRedactedEquals(const char* message, const char* expected) { - std::string temp(message); - Redact(&temp); - ASSERT_EQ(expected, temp); +/// Redact the 'message' and assert that it matches 'expected' +void AssertRedactedEquals(const char* message, const char* expected); - /// Test the signature with the 'changed' argument. - temp = std::string(message); - bool changed = false; - Redact(&temp, &changed); - ASSERT_EQ(expected, temp); - ASSERT_EQ(temp == message, !changed); -} - -void AssertUnredacted(const char* message) { - AssertRedactedEquals(message, message); -} +/// Assert that redaction does nothing for the specified message +void AssertUnredacted(const char* message); /// Putting these assertion utilities above into functions messes up failure messages /// such that failures appear to be coming from this file instead of from the file diff --git a/be/src/util/redactor-test.cc b/be/src/util/redactor-test.cc index 24f8bc0e2..553464974 100644 --- a/be/src/util/redactor-test.cc +++ b/be/src/util/redactor-test.cc @@ -328,5 +328,3 @@ TEST(RedactorTest, MultiThreaded) { } } - -IMPALA_TEST_MAIN(); diff --git a/be/src/util/redactor-unconfigured-test.cc b/be/src/util/redactor-unconfigured-test.cc index e8e46e2af..8485777b8 100644 --- a/be/src/util/redactor-unconfigured-test.cc +++ b/be/src/util/redactor-unconfigured-test.cc @@ -25,11 +25,9 @@ namespace impala { extern std::vector* g_rules; // If the rules were never set, nothing should be redacted. -TEST(RedactorTest, Unconfigured) { +TEST(RedactorUnconfigTest, Unconfigured) { ASSERT_EQ(NULL, g_rules); ASSERT_UNREDACTED("foo33"); } } - -IMPALA_TEST_MAIN(); diff --git a/be/src/util/rle-test.cc b/be/src/util/rle-test.cc index 939fe19a6..826c8da15 100644 --- a/be/src/util/rle-test.cc +++ b/be/src/util/rle-test.cc @@ -827,4 +827,3 @@ TEST_F(RleTest, MeasureOutputLengths) { } } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/runtime-profile-test.cc b/be/src/util/runtime-profile-test.cc index 87acb6932..e07994e34 100644 --- a/be/src/util/runtime-profile-test.cc +++ b/be/src/util/runtime-profile-test.cc @@ -1143,4 +1143,3 @@ INSTANTIATE_TEST_CASE_P(VariousNumbers, TimeSeriesCounterResampleTest, } // namespace impala -IMPALA_TEST_MAIN(); diff --git a/be/src/util/string-parser-test.cc b/be/src/util/string-parser-test.cc index f3133eb30..52f8fd22d 100644 --- a/be/src/util/string-parser-test.cc +++ b/be/src/util/string-parser-test.cc @@ -505,4 +505,3 @@ TEST(StringToBool, Basic) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/string-util-test.cc b/be/src/util/string-util-test.cc index 2c268dde0..a84ca667b 100644 --- a/be/src/util/string-util-test.cc +++ b/be/src/util/string-util-test.cc @@ -112,4 +112,3 @@ TEST(CommaSeparatedContainsTest, Basic) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/symbols-util-test.cc b/be/src/util/symbols-util-test.cc index a00fc94f9..f9af6b5cb 100644 --- a/be/src/util/symbols-util-test.cc +++ b/be/src/util/symbols-util-test.cc @@ -324,4 +324,3 @@ TEST(SymbolsUtil, ManglingPrepareOrClose) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/sys-info-test.cc b/be/src/util/sys-info-test.cc index dab8f92d2..7fe9da115 100644 --- a/be/src/util/sys-info-test.cc +++ b/be/src/util/sys-info-test.cc @@ -71,4 +71,3 @@ TEST(DiskInfoTest, Basic) { } } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/system-state-info-test.cc b/be/src/util/system-state-info-test.cc index 561b2d63a..f1b976b87 100644 --- a/be/src/util/system-state-info-test.cc +++ b/be/src/util/system-state-info-test.cc @@ -88,4 +88,3 @@ TEST_F(SystemStateInfoTest, ComputeCpuRatios) { } // namespace impala -IMPALA_TEST_MAIN(); diff --git a/be/src/util/thread-pool-test.cc b/be/src/util/thread-pool-test.cc index d0e9287ab..e02c5a22e 100644 --- a/be/src/util/thread-pool-test.cc +++ b/be/src/util/thread-pool-test.cc @@ -157,4 +157,3 @@ TEST(ThreadPoolTest, SynchronousThreadPoolTest) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/time-test.cc b/be/src/util/time-test.cc index 78b795802..98f8823cf 100644 --- a/be/src/util/time-test.cc +++ b/be/src/util/time-test.cc @@ -135,4 +135,3 @@ TEST(TimeTest, Basic) { } // TEST } // namespace impala -IMPALA_TEST_MAIN(); diff --git a/be/src/util/uid-util-test.cc b/be/src/util/uid-util-test.cc index 997cc0ade..4015bd51b 100644 --- a/be/src/util/uid-util-test.cc +++ b/be/src/util/uid-util-test.cc @@ -38,4 +38,3 @@ TEST(UidUtil, FragmentInstanceId) { } -IMPALA_TEST_MAIN(); diff --git a/be/src/util/zip-util-test.cc b/be/src/util/zip-util-test.cc index c3379f655..98bd4dc58 100644 --- a/be/src/util/zip-util-test.cc +++ b/be/src/util/zip-util-test.cc @@ -79,9 +79,3 @@ TEST(ZipUtilTest, Basic) { // Cleanup filesystem::remove_all(uniq_dir); } - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - InitCommonRuntime(argc, argv, true, TestInfo::BE_TEST); - return RUN_ALL_TESTS(); -} diff --git a/bin/gen-backend-test-script.sh b/bin/gen-backend-test-script.sh new file mode 100755 index 000000000..32322b7f9 --- /dev/null +++ b/bin/gen-backend-test-script.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# This script generates a bash script to run a certain set of backend tests +# using the unified backend test executable. It take two positional arguments: +# 1: The file location to write the generated script +# 2: The test filter pattern that describes which tests to run (following gtest's +# --gtest_filter) +# This script is used by the build system and is not intended to be run directly. +TEST_EXEC_LOCATION=${1} +GTEST_FILTER=${2} +TEST_EXEC_NAME=$(basename "${TEST_EXEC_LOCATION}") + +cat > "${TEST_EXEC_LOCATION}" << EOF +#!/bin/bash +${IMPALA_HOME}/be/build/latest/service/unifiedbetests \ + --gtest_filter=${GTEST_FILTER} \ + --gtest_output=xml:${IMPALA_BE_TEST_LOGS_DIR}/${TEST_EXEC_NAME}.xml \ + -log_filename="${TEST_EXEC_NAME}" \ + "\$@" +# Running a gtest executable using the -gtest_filter flag produces a JUnitXML that +# contains all the tests whether they ran or not. The tests that ran are populated +# normally. The tests that didn't run have status="notrun". This is a problem for the +# unified binary, because every JUnitXML would contain every test, with a large portion +# of them marked as notrun. Various consumers of JUnitXML (such as Jenkins) may not +# understand this distinction, so it is useful to prune the notrun entries. The +# junitxml_prune_notrun.py walks through the JUnitXML file and drops the entries that +# did not run, producing a new JUnitXML file of the same name. +${IMPALA_HOME}/bin/junitxml_prune_notrun.py \ + -f "${IMPALA_BE_TEST_LOGS_DIR}/${TEST_EXEC_NAME}.xml" +EOF + +chmod +x "${TEST_EXEC_LOCATION}" diff --git a/bin/junitxml_prune_notrun.py b/bin/junitxml_prune_notrun.py new file mode 120000 index 000000000..e7c2a6179 --- /dev/null +++ b/bin/junitxml_prune_notrun.py @@ -0,0 +1 @@ +../lib/python/impala_py_lib/jenkins/junitxml_prune_notrun.py \ No newline at end of file diff --git a/bin/rat_exclude_files.txt b/bin/rat_exclude_files.txt index bbc95bfeb..5809da2b3 100644 --- a/bin/rat_exclude_files.txt +++ b/bin/rat_exclude_files.txt @@ -12,6 +12,7 @@ be/src/testutil/htpasswd be/src/testutil/*.key bin/generate_junitxml.py +bin/junitxml_prune_notrun.py tests/*/__init__.py testdata/common/__init__.py fe/src/test/resources/regionservers diff --git a/bin/validate-unified-backend-test-filters.py b/bin/validate-unified-backend-test-filters.py new file mode 100755 index 000000000..c8729382d --- /dev/null +++ b/bin/validate-unified-backend-test-filters.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import subprocess +import sys +from optparse import OptionParser + + +def get_set_of_tests(unified_binary, filters): + # Run the unified_binary with the specified filters. If filters is None, run + # without filters. Process the output to get fully qualified tests. + command = [unified_binary, "--gtest_list_tests"] + if filters is not None: + command.append("--gtest_filter={0}".format(filters)) + p = subprocess.Popen(command, stdout=subprocess.PIPE) + out, err = p.communicate() + test_list = set() + cur_test_suite = None + for line in out.split("\n"): + if line.find("seed = ") != -1: continue + if len(line) == 0: continue + if line[-1] == ".": + cur_test_suite = line + else: + testcase = line.strip() + test_list.add("{0}{1}".format(cur_test_suite, testcase)) + return test_list + + +def main(): + parser = OptionParser() + parser.add_option("-f", "--filters", dest="filters", + help="Aggregation of all gtest filters") + parser.add_option("-b", "--unified_binary", dest="unified_binary", + help="Filename for the unified test binary") + options, args = parser.parse_args() + without_filter = get_set_of_tests(options.unified_binary, None) + with_filter = get_set_of_tests(options.unified_binary, options.filters) + + assert with_filter.issubset(without_filter) + if without_filter != with_filter: + print("FAILED: The unified backend test executable contains tests that are\n" + "missing from the CMake test filters:") + for tests in without_filter - with_filter: + print(tests) + print("Unified test executable: {0}\nFilters: {1}".format( + options.unified_binary, options.filters)) + sys.exit(1) + + +if __name__ == "__main__": main() diff --git a/lib/python/impala_py_lib/jenkins/junitxml_prune_notrun.py b/lib/python/impala_py_lib/jenkins/junitxml_prune_notrun.py new file mode 100755 index 000000000..9d9d92107 --- /dev/null +++ b/lib/python/impala_py_lib/jenkins/junitxml_prune_notrun.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Some tests that produce JUnitXML include tests that did not run (i.e. status="notrun"). +This script walks through the JUnitXML and removes these elements. +""" +from optparse import OptionParser +from xml.etree.ElementTree import ElementTree + + +def junitxml_prune_notrun(junitxml_filename): + tree = ElementTree() + root = tree.parse(junitxml_filename) + + for testsuite in root.findall("testsuite"): + # Get the list of notrun tests + notrun_testcases = [] + for testcase in testsuite: + status = testcase.attrib["status"] + if status == 'notrun': + notrun_testcases.append(testcase) + # Get the total number of tests + num_tests = int(testsuite.attrib["tests"]) + + # There are two cases. + # 1. No test from the testsuite ran. The whole testsuite can be pruned. + # 2. Some test from the testsuite ran. The individual testcases can be pruned. + if len(notrun_testcases) == num_tests: + # Remove whole testsuite + root.remove(testsuite) + else: + # Remote individual testcases. + for testcase in notrun_testcases: + testsuite.remove(testcase) + # Fixup the total number of tests + testsuite.attrib["tests"] = str(num_tests - len(notrun_testcases)) + # Write out the pruned JUnitXML + tree.write(junitxml_filename, encoding="utf-8", xml_declaration=True) + + +def main(): + parser = OptionParser() + parser.add_option("-f", "--file", dest="filename", help="JUnitXML file to prune") + options, args = parser.parse_args() + junitxml_prune_notrun(options.filename) + + +if __name__ == "__main__": main()