IMPALA-6249: Expose several build flags via web UI Exposes a list of build flags via the impalad web UI. The build flags can be viewed on the root page under the "Version" section. They can be accessed via other tests through the debug version of the root page (e.g. adding &json to the URL). The build flags are listed in a JSON array so that they can be parsed easily. This should help run Impala tests against a remote Impala cluster.
The build flags are read in CMakeLists.txt and then stored in preprocessor variables. Three build flags are exposed as part of this commit: - Is_NDEBUG = [true, false] - Whether NDEBUG was true or false at compile time - CMake_Build_Type = [DEBUG, RELEASE, ADDRESS_SANITIZER, TIDY, UBSAN, UBSAN_FULL, TSAN, CODE_COVERAGE_RELEASE, CODE_COVERAGE_DEBUG] - The value of CMAKE_BUILD_TYPE at compile time - Library_Link_Type = [DYNAMIC, STATIC] - Derived from the compile time value of BUILD_SHARED_LIBS There are a few other minor changes that are apart of this commit: * The patch modifies environ.py so that it supports fetching build metadata for both local and remote clusters. * The tests under the tests/webserver directory were not being run because 'webserver' was not whitelisted in tests/run-tests.py. This patch fixes that and addresses several test failures in run-tests.py. * It reverts part of IMPALA-6947 so that their is no dependency from start-impala-cluster.py to environ.py. The timeout discussed IMPALA-6947 is now set at compile time. Testing: Added new tests to webserver/test_web_pages.py to ensure that the build flags are being set. Some tests are only run when run against a local cluster because we have no way of getting the build info from a remote cluster, whereas local clusters contain a .cmake_build_type file. Change-Id: I47e3ad4cbf844909bdaf22a6f9d7bd915dce3f19 Reviewed-on: http://gerrit.cloudera.org:8080/11410 Reviewed-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com> Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com> Project: http://git-wip-us.apache.org/repos/asf/impala/repo Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/9bdb73b1 Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/9bdb73b1 Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/9bdb73b1 Branch: refs/heads/branch-3.1.0 Commit: 9bdb73b188c4c87ee3a71e56aa10de0eba32b086 Parents: c73530d Author: Sahil Takiar <takiar.sa...@gmail.com> Authored: Wed Sep 5 10:52:49 2018 -0400 Committer: Zoltan Borok-Nagy <borokna...@cloudera.com> Committed: Tue Nov 13 12:50:23 2018 +0100 ---------------------------------------------------------------------- CMakeLists.txt | 20 +- be/src/common/config.h.in | 3 + be/src/common/global-flags.cc | 16 +- be/src/util/debug-util.h | 19 ++ be/src/util/default-path-handlers.cc | 27 +++ bin/start-impala-cluster.py | 4 +- tests/common/environ.py | 207 +++++++++++++++---- tests/common/skip.py | 8 +- tests/conftest.py | 4 +- .../custom_cluster/test_admission_controller.py | 6 +- .../test_automatic_invalidation.py | 5 +- tests/custom_cluster/test_exchange_delays.py | 4 +- tests/custom_cluster/test_metadata_replicas.py | 1 - tests/custom_cluster/test_restart_services.py | 4 +- tests/query_test/test_hdfs_caching.py | 4 +- tests/query_test/test_runtime_filters.py | 4 +- tests/run-tests.py | 19 +- tests/statestore/test_statestore.py | 8 +- tests/webserver/test_web_pages.py | 96 +++++++-- www/root.tmpl | 5 +- 20 files changed, 368 insertions(+), 96 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index 90b4df8..e248540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,9 @@ if (NOT DEFINED BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS OFF) endif() +# Store BUILD_SHARED_LIBS in a variable so it can be read in config.h.in +set(IMPALA_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) + # Build compile commands database set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -47,8 +50,14 @@ endif(NOT CMAKE_BUILD_TYPE) STRING (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) message(STATUS "Build type is ${CMAKE_BUILD_TYPE}") -# Write the build type to a file so that tests can determine the current build type. -file(WRITE "${CMAKE_SOURCE_DIR}/.cmake_build_type" ${CMAKE_BUILD_TYPE}) + +# Write build flags to a file so that they can be read by tests +file(WRITE "${CMAKE_SOURCE_DIR}/.cmake_build_type" ${CMAKE_BUILD_TYPE}\n) +file(APPEND "${CMAKE_SOURCE_DIR}/.cmake_build_type" ${BUILD_SHARED_LIBS}\n) + +# Store CMAKE_BUILD_TYPE in a variable so it can be read in config.h.in +string(REPLACE "_" "-" ESCAPED_CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}) +set(IMPALA_CMAKE_BUILD_TYPE ${ESCAPED_CMAKE_BUILD_TYPE}) set(ENABLE_CODE_COVERAGE false) if ("${CMAKE_BUILD_TYPE}" STREQUAL "CODE_COVERAGE_DEBUG") @@ -61,6 +70,13 @@ endif() message(STATUS "ENABLE_CODE_COVERAGE: ${ENABLE_CODE_COVERAGE}") +if (ENABLE_CODE_COVERAGE + OR "${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER" + OR "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN" + OR "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN") + set (SLOW_BUILD true) +endif() + # Helper function that given a package name constructs the package_ROOT variable based on # the version number extracted from the environment function(set_dep_root NAME) http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/be/src/common/config.h.in ---------------------------------------------------------------------- diff --git a/be/src/common/config.h.in b/be/src/common/config.h.in index f474a9f..43c7e65 100644 --- a/be/src/common/config.h.in +++ b/be/src/common/config.h.in @@ -28,5 +28,8 @@ #cmakedefine HAVE_PIPE2 #cmakedefine HAVE_MAGIC_H #cmakedefine HAVE_SYNC_FILE_RANGE +#cmakedefine SLOW_BUILD +#cmakedefine IMPALA_BUILD_SHARED_LIBS @IMPALA_BUILD_SHARED_LIBS@ +#cmakedefine IMPALA_CMAKE_BUILD_TYPE @IMPALA_CMAKE_BUILD_TYPE@ #endif http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/be/src/common/global-flags.cc ---------------------------------------------------------------------- diff --git a/be/src/common/global-flags.cc b/be/src/common/global-flags.cc index 0473352..3c73b56 100644 --- a/be/src/common/global-flags.cc +++ b/be/src/common/global-flags.cc @@ -161,12 +161,18 @@ DEFINE_int32(kudu_operation_timeout_ms, 3 * 60 * 1000, "Timeout (milliseconds) s "all Kudu operations. This must be a positive value, and there is no way to disable " "timeouts."); +#ifdef SLOW_BUILD +static const int32 default_kudu_client_rpc_timeout_ms = 60000; +#else +static const int32 default_kudu_client_rpc_timeout_ms = 0; +#endif + // Timeout (ms) for Kudu rpcs set in the BE on the KuduClient. -DEFINE_int32(kudu_client_rpc_timeout_ms, 0, "(Advanced) Timeout (milliseconds) set for " - "individual Kudu client rpcs. An operation may consist of several rpcs, so this is " - "expected to be less than kudu_operation_timeout_ms. This must be a positive value " - "or it will be ignored and Kudu's default of 10s will be used. There is no way to " - "disable timeouts."); +DEFINE_int32(kudu_client_rpc_timeout_ms, default_kudu_client_rpc_timeout_ms, + "(Advanced) Timeout (milliseconds) set for individual Kudu client rpcs. An operation " + "may consist of several rpcs, so this is expected to be less than " + "kudu_operation_timeout_ms. This must be a positive value or it will be ignored and " + "Kudu's default of 10s will be used. There is no way to disable timeouts."); DEFINE_int64(inc_stats_size_limit_bytes, 200 * (1LL<<20), "Maximum size of " "incremental stats the catalog is allowed to serialize per table. " http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/be/src/util/debug-util.h ---------------------------------------------------------------------- diff --git a/be/src/util/debug-util.h b/be/src/util/debug-util.h index 005cc23..240eab6 100644 --- a/be/src/util/debug-util.h +++ b/be/src/util/debug-util.h @@ -24,6 +24,7 @@ #include <thrift/protocol/TDebugProtocol.h> +#include "common/config.h" #include "gen-cpp/JniCatalog_types.h" #include "gen-cpp/Descriptors_types.h" #include "gen-cpp/Exprs_types.h" @@ -97,6 +98,24 @@ bool ParseId(const std::string& s, TUniqueId* id); /// This is used to set gflags build version std::string GetBuildVersion(bool compact = false); +#ifndef IMPALA_CMAKE_BUILD_TYPE +static_assert(false, "IMPALA_CMAKE_BUILD_TYPE is not defined"); +#endif + +/// Returns the value of CMAKE_BUILD_TYPE used to build the code +constexpr const char* GetCMakeBuildType() { + return AS_STRING(IMPALA_CMAKE_BUILD_TYPE); +} + +/// Returns whether the code was dynamically or statically linked, return +/// value is either STATIC or DYNAMIC. +constexpr const char* GetLibraryLinkType() { + return AS_STRING(IMPALA_BUILD_SHARED_LIBS)[0] == 'O' + && AS_STRING(IMPALA_BUILD_SHARED_LIBS)[1] == 'N' ? + "DYNAMIC" : + "STATIC"; +} + /// Returns "<program short name> version <GetBuildVersion(compact)>" std::string GetVersionString(bool compact = false); http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/be/src/util/default-path-handlers.cc ---------------------------------------------------------------------- diff --git a/be/src/util/default-path-handlers.cc b/be/src/util/default-path-handlers.cc index c492d06..df04d92 100644 --- a/be/src/util/default-path-handlers.cc +++ b/be/src/util/default-path-handlers.cc @@ -224,11 +224,38 @@ void JmxHandler(const Webserver::ArgumentMap& args, Document* document) { } } +// Helper function that creates a Value for a given build flag name, value and adds it to +// an array of build_flags +void AddBuildFlag(const std::string& flag_name, const std::string& flag_value, + Document* document, Value* build_flags) { + Value build_type(kObjectType); + Value build_type_name(flag_name.c_str(), document->GetAllocator()); + build_type.AddMember("flag_name", build_type_name, document->GetAllocator()); + Value build_type_value(flag_value.c_str(), document->GetAllocator()); + build_type.AddMember("flag_value", build_type_value, document->GetAllocator()); + build_flags->PushBack(build_type, document->GetAllocator()); +} + namespace impala { void RootHandler(const Webserver::ArgumentMap& args, Document* document) { Value version(GetVersionString().c_str(), document->GetAllocator()); document->AddMember("version", version, document->GetAllocator()); + +#ifdef NDEBUG + const char* is_ndebug = "true"; +#else + const char* is_ndebug = "false"; +#endif + + Value build_flags(kArrayType); + AddBuildFlag("is_ndebug", is_ndebug, document, &build_flags); + string cmake_build_type(GetCMakeBuildType()); + replace(cmake_build_type.begin(), cmake_build_type.end(), '-', '_'); + AddBuildFlag("cmake_build_type", cmake_build_type, document, &build_flags); + AddBuildFlag("library_link_type", GetLibraryLinkType(), document, &build_flags); + document->AddMember("build_flags", build_flags, document->GetAllocator()); + Value cpu_info(CpuInfo::DebugString().c_str(), document->GetAllocator()); document->AddMember("cpu_info", cpu_info, document->GetAllocator()); Value mem_info(MemInfo::DebugString().c_str(), document->GetAllocator()); http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/bin/start-impala-cluster.py ---------------------------------------------------------------------- diff --git a/bin/start-impala-cluster.py b/bin/start-impala-cluster.py index 7e22ca9..d052650 100755 --- a/bin/start-impala-cluster.py +++ b/bin/start-impala-cluster.py @@ -29,7 +29,7 @@ from getpass import getuser from time import sleep, time from optparse import OptionParser, SUPPRESS_HELP from testdata.common import cgroups -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout logging.basicConfig(level=logging.ERROR, format="%(asctime)s %(threadName)s: %(message)s", datefmt="%H:%M:%S") @@ -120,7 +120,7 @@ CLUSTER_WAIT_TIMEOUT_IN_SECONDS = 240 # It is set to a high value to avoid failing if processes are slow to shut down. KILL_TIMEOUT_IN_SECONDS = 240 # For build types like ASAN, modify the default Kudu rpc timeout. -KUDU_RPC_TIMEOUT = specific_build_type_timeout(0, slow_build_timeout=60000) +KUDU_RPC_TIMEOUT = build_flavor_timeout(0, slow_build_timeout=60000) def find_user_processes(binaries): """Returns an iterator over all processes owned by the current user with a matching http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/common/environ.py ---------------------------------------------------------------------- diff --git a/tests/common/environ.py b/tests/common/environ.py index 092c2e0..e20aa98 100644 --- a/tests/common/environ.py +++ b/tests/common/environ.py @@ -15,20 +15,23 @@ # specific language governing permissions and limitations # under the License. +import json import logging import os import re +import requests LOG = logging.getLogger('tests.common.environ') test_start_cluster_args = os.environ.get("TEST_START_CLUSTER_ARGS", "") IMPALA_HOME = os.environ.get("IMPALA_HOME", "") +IMPALA_REMOTE_URL = os.environ.get("IMPALA_REMOTE_URL", "") # Find the likely BuildType of the running Impala. Assume it's found through the path # $IMPALA_HOME/be/build/latest as a fallback. build_type_arg_regex = re.compile(r'--build_type=(\w+)', re.I) build_type_arg_search_result = re.search(build_type_arg_regex, test_start_cluster_args) if build_type_arg_search_result is not None: - build_type_dir = build_type_search_result.groups()[0].lower() + build_type_dir = build_type_arg_search_result.groups()[0].lower() else: build_type_dir = 'latest' @@ -36,9 +39,10 @@ else: impalad_basedir = \ os.path.realpath(os.path.join(IMPALA_HOME, 'be/build', build_type_dir)).rstrip('/') -class SpecificImpaladBuildTypes: + +class ImpalaBuildFlavors: """ - Represents the possible CMAKE_BUILD_TYPE values. These specific build types are needed + Represents the possible CMAKE_BUILD_TYPE values. These build flavors are needed by Python test code, e.g. to set different timeouts for different builds. All values are lower-cased to enable case-insensitive comparison. """ @@ -52,6 +56,8 @@ class SpecificImpaladBuildTypes: CODE_COVERAGE_DEBUG = 'code_coverage_debug' # ./buildall.sh -release -codecoverage CODE_COVERAGE_RELEASE = 'code_coverage_release' + # ./buildall.sh -tidy + TIDY = 'tidy' # ./buildall.sh -tsan TSAN = 'tsan' # ./buildall.sh -ubsan @@ -60,82 +66,168 @@ class SpecificImpaladBuildTypes: UBSAN_FULL = 'ubsan_full' VALID_BUILD_TYPES = [ADDRESS_SANITIZER, DEBUG, CODE_COVERAGE_DEBUG, RELEASE, - CODE_COVERAGE_RELEASE, TSAN, UBSAN, UBSAN_FULL] + CODE_COVERAGE_RELEASE, TIDY, TSAN, UBSAN, UBSAN_FULL] + + +class LinkTypes: + """ + Represents the possible library link type values, either "dynamic" or "static". This + value is derived from the cmake value of BUILD_SHARED_LIBS. All values are lower-cased + to enable case-insensitive comparison. + """ + # ./buildall.sh + STATIC = 'static' + # ./buildall.sh -build_shared_libs + DYNAMIC = 'dynamic' + + VALID_LINK_TYPES = [STATIC, DYNAMIC] + + +class ImpalaTestClusterFlagsDetector: + """ + Detects the build flags of different types of Impala clusters. Currently supports + detecting build flags from either a locally built Impala cluster using a file generated + by CMake, or from the Impala web ui, which is useful for detecting flags from a remote + Impala cluster. The supported list of build flags is: [CMAKE_BUILD_TYPE, + BUILD_SHARED_LIBS] + """ @classmethod - def detect(cls, impala_build_root): + def detect_using_build_root_or_web_ui(cls, impala_build_root): """ - Determine the build type based on the .cmake_build_type file created by + Determine the build flags based on the .cmake_build_type file created by ${IMPALA_HOME}/CMakeLists.txt. impala_build_root should be the path of the - Impala source checkout, i.e. ${IMPALA_HOME}. + Impala source checkout, i.e. ${IMPALA_HOME}. If .cmake_build_type is not present, + or cannot be read, attempt to detect the build flags from the local web UI using + detect_using_web_ui. """ - build_type_path = os.path.join(impala_build_root, ".cmake_build_type") + cmake_build_type_path = os.path.join(impala_build_root, ".cmake_build_type") try: - with open(build_type_path) as build_type_file: - build_type = build_type_file.read().strip().lower() + with open(cmake_build_type_path) as cmake_build_type_file: + build_flags = cmake_build_type_file.readlines() + build_type = build_flags[0].strip().lower() + build_shared_libs = build_flags[1].strip().lower() except IOError: - LOG.error("Could not open %s assuming DEBUG", build_type_path) - return cls.DEBUG + LOG.debug("Unable to read .cmake_build_type file, fetching build flags from " + + "web ui on localhost") + build_type, build_shared_libs = ImpalaTestClusterFlagsDetector.detect_using_web_ui( + "http://localhost:25000") - if build_type not in cls.VALID_BUILD_TYPES: + library_link_type = LinkTypes.STATIC if build_shared_libs == "off"\ + else LinkTypes.DYNAMIC + ImpalaTestClusterFlagsDetector.validate_build_flags(build_type, library_link_type) + return build_type, library_link_type + + @classmethod + def detect_using_web_ui(cls, impala_url): + """ + Determine the build type based on the Impala cluster's web UI by using + get_build_flags_from_web_ui. + """ + build_flags = ImpalaTestClusterFlagsDetector.get_build_flags_from_web_ui(impala_url) + build_type = build_flags['cmake_build_type'] + library_link_type = build_flags['library_link_type'] + ImpalaTestClusterFlagsDetector.validate_build_flags(build_type, library_link_type) + return build_type, library_link_type + + @classmethod + def validate_build_flags(cls, build_type, library_link_type): + """ + Validates that the build flags have valid values. + """ + if build_type not in ImpalaBuildFlavors.VALID_BUILD_TYPES: raise Exception("Unknown build type {0}".format(build_type)) + if library_link_type not in LinkTypes.VALID_LINK_TYPES: + raise Exception("Unknown library link type {0}".format(library_link_type)) LOG.debug("Build type detected: %s", build_type) - return build_type + LOG.debug("Library link type detected: %s", library_link_type) + + @classmethod + def get_build_flags_from_web_ui(cls, impala_url): + """ + Fetches the build flags from the given Impala cluster web UI by parsing the ?json + response of the root homepage and looking for the section on build flags. It returns + the flags as a dictionary where the key is the flag name. + """ + response = requests.get(impala_url + "/?json") + assert response.status_code == requests.codes.ok,\ + "Offending url: " + impala_url + assert "application/json" in response.headers['Content-Type'] + + build_flags_json = json.loads(response.text)["build_flags"] + build_flags = dict((flag['flag_name'].lower(), flag['flag_value'].lower()) + for flag in build_flags_json) + assert len(build_flags_json) == len(build_flags) # Ensure there are no collisions + return build_flags +""" +Indicates whether we are operating against a locally built Impala cluster or a remote one. +""" +( + LOCAL_BUILD, + REMOTE_BUILD, +) = xrange(2) -class ImpaladBuild(object): + +class ImpalaTestClusterProperties(object): """ Acquires and provides characteristics about the way the Impala under test was compiled - and its likely effects on its responsiveness to automated test timings. Currently - assumes that the Impala daemon under test was built in our current source checkout. - TODO: we could get this information for remote cluster tests if we exposed the build - type via a metric or the Impalad web UI. + and its likely effects on its responsiveness to automated test timings. """ - def __init__(self, impala_build_root): - self._specific_build_type = SpecificImpaladBuildTypes.detect(impala_build_root) + def __init__(self, build_flavor, library_link_type, local_or_remote_build): + self._build_flavor = build_flavor + self._library_link_type = library_link_type + self._local_or_remote_build = local_or_remote_build + + @property + def build_flavor(self): + """ + Return the correct ImpalaBuildFlavors for the Impala under test. + """ + return self._build_flavor @property - def specific_build_type(self): + def library_link_type(self): """ - Return the correct SpecificImpaladBuildTypes for the Impala under test. + Return the library link type (either static or dynamic) for the Impala under test. """ - return self._specific_build_type + return self._library_link_type def has_code_coverage(self): """ Return whether the Impala under test was compiled with code coverage enabled. """ - return self.specific_build_type in (SpecificImpaladBuildTypes.CODE_COVERAGE_DEBUG, - SpecificImpaladBuildTypes.CODE_COVERAGE_RELEASE) + return self.build_flavor in (ImpalaBuildFlavors.CODE_COVERAGE_DEBUG, + ImpalaBuildFlavors.CODE_COVERAGE_RELEASE) def is_asan(self): """ Return whether the Impala under test was compiled with ASAN. """ - return self.specific_build_type == SpecificImpaladBuildTypes.ADDRESS_SANITIZER + return self.build_flavor == ImpalaBuildFlavors.ADDRESS_SANITIZER def is_tsan(self): """ Return whether the Impala under test was compiled with TSAN. """ - return self.specific_build_type == SpecificImpaladBuildTypes.TSAN + return self.build_flavor == ImpalaBuildFlavors.TSAN def is_ubsan(self): """ Return whether the Impala under test was compiled with UBSAN. """ - return self.specific_build_type == SpecificImpaladBuildTypes.UBSAN + return self.build_flavor == ImpalaBuildFlavors.UBSAN def is_dev(self): """ Return whether the Impala under test is a development build (i.e., any debug or ASAN build). """ - return self.specific_build_type in ( - SpecificImpaladBuildTypes.ADDRESS_SANITIZER, SpecificImpaladBuildTypes.DEBUG, - SpecificImpaladBuildTypes.CODE_COVERAGE_DEBUG, - SpecificImpaladBuildTypes.TSAN, SpecificImpaladBuildTypes.UBSAN) + return self.build_flavor in ( + ImpalaBuildFlavors.ADDRESS_SANITIZER, ImpalaBuildFlavors.DEBUG, + ImpalaBuildFlavors.CODE_COVERAGE_DEBUG, ImpalaBuildFlavors.TSAN, + ImpalaBuildFlavors.UBSAN) def runs_slowly(self): """ @@ -144,15 +236,42 @@ class ImpaladBuild(object): """ return self.has_code_coverage() or self.is_asan() or self.is_tsan() or self.is_ubsan() + def is_statically_linked(self): + """ + Return whether the Impala under test was statically linked during compilation. + """ + return self.build_shared_libs == LinkTypes.STATIC + + def is_dynamically_linked(self): + """ + Return whether the Impala under test was dynamically linked during compilation. + """ + return self.build_shared_libs == LinkTypes.DYNAMIC + + def is_remote_cluster(self): + """ + Return true if the Impala test cluster is running remotely, false otherwise + """ + return self._local_or_remote_build == REMOTE_BUILD + -IMPALAD_BUILD = ImpaladBuild(IMPALA_HOME) +if IMPALA_REMOTE_URL: + build_flavor, link_type =\ + ImpalaTestClusterFlagsDetector.detect_using_web_ui(IMPALA_REMOTE_URL) + IMPALA_TEST_CLUSTER_PROPERTIES =\ + ImpalaTestClusterProperties(build_flavor, link_type, REMOTE_BUILD) +else: + build_flavor, link_type =\ + ImpalaTestClusterFlagsDetector.detect_using_build_root_or_web_ui(IMPALA_HOME) + IMPALA_TEST_CLUSTER_PROPERTIES =\ + ImpalaTestClusterProperties(build_flavor, link_type, LOCAL_BUILD) -def specific_build_type_timeout( - default_timeout, slow_build_timeout=None, asan_build_timeout=None, - code_coverage_build_timeout=None): + +def build_flavor_timeout(default_timeout, slow_build_timeout=None, + asan_build_timeout=None, code_coverage_build_timeout=None): """ - Return a test environment-specific timeout based on the sort of - SpecificImpalaBuildType under test. + Return a test environment-specific timeout based on the sort of ImpalaBuildFlavor under + test. Required parameter: default_timeout - default timeout value. This applies when Impala is a standard release or debug build, or if no other timeouts are specified. @@ -163,7 +282,7 @@ def specific_build_type_timeout( "slow". You can use this as a shorthand in lieu of specifying all of the following parameters. - The parameters below correspond to specific build types. These preempt both + The parameters below correspond to build flavors. These preempt both slow_build_timeout and default_timeout, if the Impala under test is a build of the applicable type: @@ -173,13 +292,13 @@ def specific_build_type_timeout( (both debug and release code coverage) """ - if IMPALAD_BUILD.is_asan() and asan_build_timeout is not None: + if IMPALA_TEST_CLUSTER_PROPERTIES.is_asan() and asan_build_timeout is not None: timeout_val = asan_build_timeout - elif IMPALAD_BUILD.has_code_coverage() and code_coverage_build_timeout is not None: + elif IMPALA_TEST_CLUSTER_PROPERTIES.has_code_coverage() and\ + code_coverage_build_timeout is not None: timeout_val = code_coverage_build_timeout - elif IMPALAD_BUILD.runs_slowly() and slow_build_timeout is not None: + elif IMPALA_TEST_CLUSTER_PROPERTIES.runs_slowly() and slow_build_timeout is not None: timeout_val = slow_build_timeout else: timeout_val = default_timeout return timeout_val - http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/common/skip.py ---------------------------------------------------------------------- diff --git a/tests/common/skip.py b/tests/common/skip.py index 2f19bf4..41e119a 100644 --- a/tests/common/skip.py +++ b/tests/common/skip.py @@ -24,7 +24,7 @@ import os import pytest from functools import partial -from tests.common.environ import IMPALAD_BUILD +from tests.common.environ import IMPALA_TEST_CLUSTER_PROPERTIES from tests.util.filesystem_utils import ( IS_ABFS, IS_ADLS, @@ -161,8 +161,10 @@ class SkipIfNotHdfsMinicluster: reason="Test is tuned for 3-node HDFS minicluster with no EC") class SkipIfBuildType: - not_dev_build = pytest.mark.skipif(not IMPALAD_BUILD.is_dev(), - reason="Tests depends on debug build startup option.") + not_dev_build = pytest.mark.skipif(not IMPALA_TEST_CLUSTER_PROPERTIES.is_dev(), + reason="Test depends on debug build startup option.") + remote = pytest.mark.skipif(IMPALA_TEST_CLUSTER_PROPERTIES.is_remote_cluster(), + reason="Test depends on running against a local Impala cluster") class SkipIfEC: remote_read = pytest.mark.skipif(IS_EC, reason="EC files are read remotely and " http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/conftest.py ---------------------------------------------------------------------- diff --git a/tests/conftest.py b/tests/conftest.py index 4e1c837..0fccc5d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,7 +27,7 @@ import logging import os import pytest -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout from common.test_result_verifier import QueryTestResult from tests.common.patterns import is_valid_impala_identifier from tests.comparison.db_connection import ImpalaConnection @@ -52,7 +52,7 @@ if FILESYSTEM == 'isilon': # Timeout each individual test case after 2 hours, or 4 hours for slow builds PYTEST_TIMEOUT_S = \ - specific_build_type_timeout(2 * 60 * 60, slow_build_timeout=4 * 60 * 60) + build_flavor_timeout(2 * 60 * 60, slow_build_timeout=4 * 60 * 60) def pytest_configure(config): """ Hook startup of pytest. Sets up log format and per-test timeout. """ http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/custom_cluster/test_admission_controller.py ---------------------------------------------------------------------- diff --git a/tests/custom_cluster/test_admission_controller.py b/tests/custom_cluster/test_admission_controller.py index 6b3100f..f716788 100644 --- a/tests/custom_cluster/test_admission_controller.py +++ b/tests/custom_cluster/test_admission_controller.py @@ -31,7 +31,7 @@ from time import sleep, time from beeswaxd.BeeswaxService import QueryState from tests.beeswax.impala_beeswax import ImpalaBeeswaxException from tests.common.custom_cluster_test_suite import CustomClusterTestSuite -from tests.common.environ import specific_build_type_timeout, IMPALAD_BUILD +from tests.common.environ import build_flavor_timeout, IMPALA_TEST_CLUSTER_PROPERTIES from tests.common.impala_test_suite import ImpalaTestSuite from tests.common.resource_pool_config import ResourcePoolConfig from tests.common.skip import ( @@ -119,7 +119,7 @@ POOL_NAME = "default-pool" # Stress test timeout (seconds). The timeout needs to be significantly higher for # slow builds like code coverage and ASAN (IMPALA-3790, IMPALA-6241). -STRESS_TIMEOUT = specific_build_type_timeout(60, slow_build_timeout=600) +STRESS_TIMEOUT = build_flavor_timeout(60, slow_build_timeout=600) # The number of queries that can execute concurrently in the pool POOL_NAME. MAX_NUM_CONCURRENT_QUERIES = 5 @@ -902,7 +902,7 @@ class TestAdmissionControllerStress(TestAdmissionControllerBase): # Additional constraints for code coverage jobs and core. num_queries = None - if IMPALAD_BUILD.has_code_coverage(): + if IMPALA_TEST_CLUSTER_PROPERTIES.has_code_coverage(): # Code coverage builds can't handle the increased concurrency. num_queries = 15 elif cls.exploration_strategy() == 'core': http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/custom_cluster/test_automatic_invalidation.py ---------------------------------------------------------------------- diff --git a/tests/custom_cluster/test_automatic_invalidation.py b/tests/custom_cluster/test_automatic_invalidation.py index 019712b..e82217b 100644 --- a/tests/custom_cluster/test_automatic_invalidation.py +++ b/tests/custom_cluster/test_automatic_invalidation.py @@ -19,7 +19,7 @@ import os import pytest import time from subprocess import call -from tests.common.environ import IMPALAD_BUILD +from tests.common.environ import IMPALA_TEST_CLUSTER_PROPERTIES from tests.util.filesystem_utils import IS_HDFS, IS_LOCAL @@ -37,7 +37,8 @@ class TestAutomaticCatalogInvalidation(CustomClusterTestSuite): # The test will run a query and assumes the table is loaded when the query finishes. # The timeout should be larger than the time of the query. - timeout = 20 if IMPALAD_BUILD.runs_slowly() or (not IS_HDFS and not IS_LOCAL) else 10 + timeout = 20 if IMPALA_TEST_CLUSTER_PROPERTIES.runs_slowly() or\ + (not IS_HDFS and not IS_LOCAL) else 10 timeout_flag = "--invalidate_tables_timeout_s=" + str(timeout) @classmethod http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/custom_cluster/test_exchange_delays.py ---------------------------------------------------------------------- diff --git a/tests/custom_cluster/test_exchange_delays.py b/tests/custom_cluster/test_exchange_delays.py index 1d7d14b..38dfde1 100644 --- a/tests/custom_cluster/test_exchange_delays.py +++ b/tests/custom_cluster/test_exchange_delays.py @@ -17,13 +17,13 @@ import pytest from tests.common.custom_cluster_test_suite import CustomClusterTestSuite -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout from tests.common.skip import SkipIfBuildType from tests.util.filesystem_utils import IS_S3, IS_ADLS, IS_ISILON # IMPALA-6100: add additional margin for error for slow build types. SLOW_BUILD_TIMEOUT=20000 -DELAY_MS = specific_build_type_timeout(10000, slow_build_timeout=SLOW_BUILD_TIMEOUT) +DELAY_MS = build_flavor_timeout(10000, slow_build_timeout=SLOW_BUILD_TIMEOUT) # IMPALA-6381: Isilon can behave as a slow build. if IS_ISILON: DELAY_MS = SLOW_BUILD_TIMEOUT http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/custom_cluster/test_metadata_replicas.py ---------------------------------------------------------------------- diff --git a/tests/custom_cluster/test_metadata_replicas.py b/tests/custom_cluster/test_metadata_replicas.py index 940f371..ff34cf2 100644 --- a/tests/custom_cluster/test_metadata_replicas.py +++ b/tests/custom_cluster/test_metadata_replicas.py @@ -18,7 +18,6 @@ import pytest import re from time import sleep -from tests.common.environ import specific_build_type_timeout from tests.common.custom_cluster_test_suite import CustomClusterTestSuite from tests.common.skip import ( SkipIfS3, http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/custom_cluster/test_restart_services.py ---------------------------------------------------------------------- diff --git a/tests/custom_cluster/test_restart_services.py b/tests/custom_cluster/test_restart_services.py index a24149f..e441cbc 100644 --- a/tests/custom_cluster/test_restart_services.py +++ b/tests/custom_cluster/test_restart_services.py @@ -22,7 +22,7 @@ import re import socket import time -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout from time import sleep from impala.error import HiveServer2Error @@ -50,7 +50,7 @@ class TestRestart(CustomClusterTestSuite): # We need to wait for the impalad to register to the new statestored and for a # non-empty catalog update from the new statestored. It cannot be expressed with the # existing metrics yet so we wait for some time here. - wait_time_s = specific_build_type_timeout(60, slow_build_timeout=100) + wait_time_s = build_flavor_timeout(60, slow_build_timeout=100) sleep(wait_time_s) for retry in xrange(wait_time_s): try: http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/query_test/test_hdfs_caching.py ---------------------------------------------------------------------- diff --git a/tests/query_test/test_hdfs_caching.py b/tests/query_test/test_hdfs_caching.py index 176fe09..64b36da 100644 --- a/tests/query_test/test_hdfs_caching.py +++ b/tests/query_test/test_hdfs_caching.py @@ -22,7 +22,7 @@ import re import time from subprocess import check_call -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout from tests.common.impala_cluster import ImpalaCluster from tests.common.impala_test_suite import ImpalaTestSuite, LOG from tests.common.skip import SkipIfS3, SkipIfABFS, SkipIfADLS, SkipIfIsilon, \ @@ -339,7 +339,7 @@ def get_num_cache_requests(): return len(stdout.split('\n')) # IMPALA-3040: This can take time, especially under slow builds like ASAN. - wait_time_in_sec = specific_build_type_timeout(5, slow_build_timeout=20) + wait_time_in_sec = build_flavor_timeout(5, slow_build_timeout=20) num_stabilization_attempts = 0 max_num_stabilization_attempts = 10 new_requests = None http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/query_test/test_runtime_filters.py ---------------------------------------------------------------------- diff --git a/tests/query_test/test_runtime_filters.py b/tests/query_test/test_runtime_filters.py index 547a1ee..f769224 100644 --- a/tests/query_test/test_runtime_filters.py +++ b/tests/query_test/test_runtime_filters.py @@ -20,11 +20,11 @@ import pytest import re import time -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout from tests.common.impala_test_suite import ImpalaTestSuite from tests.common.skip import SkipIfLocal, SkipIfIsilon -WAIT_TIME_MS = specific_build_type_timeout(60000, slow_build_timeout=100000) +WAIT_TIME_MS = build_flavor_timeout(60000, slow_build_timeout=100000) # Some of the queries in runtime_filters consume a lot of memory, leading to # significant memory reservations in parallel tests. http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/run-tests.py ---------------------------------------------------------------------- diff --git a/tests/run-tests.py b/tests/run-tests.py index 9aaeaa5..0de9ce9 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -37,7 +37,17 @@ from _pytest.config import FILE_OR_DIR # We whitelist valid test directories. If a new test directory is added, update this. VALID_TEST_DIRS = ['failure', 'query_test', 'stress', 'unittests', 'aux_query_tests', 'shell', 'hs2', 'catalog_service', 'metadata', 'data_errors', - 'statestore', 'infra', 'observability'] + 'statestore', 'infra', 'observability', 'webserver'] + +# A list of helper directories that do not contain any tests. The purpose of this +# additional list is to prevent devs from adding a new test dir, but not adding the +# new dir to the list of valid test dirs above. All dirs unders tests/ must be placed +# into one of these lists, otherwise the script will throw an error. This list can be +# removed once IMPALA-4417 has been resolved. +TEST_HELPER_DIRS = ['aux_parquet_data_load', 'test-hive-udfs', 'comparison', 'benchmark', + 'custom_cluster', 'util', 'experiments', 'verifiers', 'common', + 'performance', 'beeswax', 'aux_custom_cluster_tests', + 'authorization'] TEST_DIR = os.path.join(os.environ['IMPALA_HOME'], 'tests') RESULT_DIR = os.path.join(os.environ['IMPALA_EE_TEST_LOGS_DIR'], 'results') @@ -201,7 +211,12 @@ def build_ignore_dir_arg_list(valid_dirs): code as though it contained tests, resulting in misleading warnings or failures. (There is a JIRA filed to restructure this: IMPALA-4417.) """ - subdirs = [subdir for subdir in os.listdir(TEST_DIR) if os.path.isdir(subdir)] + subdirs = [subdir for subdir in os.listdir(TEST_DIR) + if os.path.isdir(subdir) and not subdir.startswith(".")] + for subdir in subdirs: + assert subdir in VALID_TEST_DIRS or subdir in TEST_HELPER_DIRS,\ + "Unexpected test dir '%s' is not in the list of valid or helper test dirs"\ + % subdir ignored_dir_list = [] for subdir in (set(subdirs) - set(valid_dirs)): ignored_dir_list += ['--ignore', subdir] http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/statestore/test_statestore.py ---------------------------------------------------------------------- diff --git a/tests/statestore/test_statestore.py b/tests/statestore/test_statestore.py index f6a6bb2..a951414 100644 --- a/tests/statestore/test_statestore.py +++ b/tests/statestore/test_statestore.py @@ -39,7 +39,7 @@ from StatestoreService.StatestoreSubscriber import TTopicRegistration from ErrorCodes.ttypes import TErrorCode from Status.ttypes import TStatus -from tests.common.environ import specific_build_type_timeout +from tests.common.environ import build_flavor_timeout LOG = logging.getLogger('test_statestore') @@ -69,10 +69,10 @@ DEFAULT_UPDATE_STATE_RESPONSE = TUpdateStateResponse(status=STATUS_OK, topic_upd skipped=False) # IMPALA-3501: the timeout needs to be higher in code coverage builds -WAIT_FOR_FAILURE_TIMEOUT = specific_build_type_timeout(40, code_coverage_build_timeout=60) -WAIT_FOR_HEARTBEAT_TIMEOUT = specific_build_type_timeout( +WAIT_FOR_FAILURE_TIMEOUT = build_flavor_timeout(40, code_coverage_build_timeout=60) +WAIT_FOR_HEARTBEAT_TIMEOUT = build_flavor_timeout( 40, code_coverage_build_timeout=60) -WAIT_FOR_UPDATE_TIMEOUT = specific_build_type_timeout(40, code_coverage_build_timeout=60) +WAIT_FOR_UPDATE_TIMEOUT = build_flavor_timeout(40, code_coverage_build_timeout=60) class WildcardServerSocket(TSocket.TSocketBase, TTransport.TServerTransportBase): """Specialised server socket that binds to a random port at construction""" http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/tests/webserver/test_web_pages.py ---------------------------------------------------------------------- diff --git a/tests/webserver/test_web_pages.py b/tests/webserver/test_web_pages.py index 15d4f8f..0c05546 100644 --- a/tests/webserver/test_web_pages.py +++ b/tests/webserver/test_web_pages.py @@ -15,14 +15,19 @@ # specific language governing permissions and limitations # under the License. -from tests.common.skip import SkipIf +from tests.common.environ import IMPALA_TEST_CLUSTER_PROPERTIES +from tests.common.environ import ImpalaTestClusterFlagsDetector +from tests.common.skip import SkipIfBuildType from tests.common.impala_cluster import ImpalaCluster from tests.common.impala_test_suite import ImpalaTestSuite import json import requests +import pytest + class TestWebPage(ImpalaTestSuite): + ROOT_URL = "http://localhost:{0}/" GET_JAVA_LOGLEVEL_URL = "http://localhost:{0}/get_java_loglevel" SET_JAVA_LOGLEVEL_URL = "http://localhost:{0}/set_java_loglevel" RESET_JAVA_LOGLEVEL_URL = "http://localhost:{0}/reset_java_loglevel" @@ -46,8 +51,55 @@ class TestWebPage(ImpalaTestSuite): TEST_PORTS_WITH_SS = ["25000", "25010", "25020"] CATALOG_TEST_PORT = ["25020"] + def test_get_root_url(self): + """Tests that the root URL is accessible and loads properly""" + self.get_and_check_status(self.ROOT_URL) + + def test_get_build_flags(self): + """Tests that the build flags on the root page contain valid values""" + for port in self.TEST_PORTS_WITH_SS: + build_flags = ImpalaTestClusterFlagsDetector.\ + get_build_flags_from_web_ui(self.ROOT_URL.format(port)) + + assert len(build_flags) == 3 + assert "is_ndebug" in build_flags + assert build_flags["is_ndebug"] in ["true", "false"] + assert "cmake_build_type" in build_flags + assert build_flags["cmake_build_type"] in ["debug", "release", "address_sanitizer", + "tidy", "ubsan", "ubsan_full", "tsan", "code_coverage_release", + "code_coverage_debug"] + assert "library_link_type" in build_flags + assert build_flags["library_link_type"] in ["dynamic", "static"] + + @SkipIfBuildType.remote + def test_root_correct_build_flags(self): + """Tests that the build flags on the root page contain correct values""" + assert not IMPALA_TEST_CLUSTER_PROPERTIES.is_remote_cluster() + for port in self.TEST_PORTS_WITH_SS: + build_flags = ImpalaTestClusterFlagsDetector.\ + get_build_flags_from_web_ui(self.ROOT_URL.format(port)) + + assert build_flags["cmake_build_type"] ==\ + IMPALA_TEST_CLUSTER_PROPERTIES.build_flavor + assert build_flags["library_link_type"] ==\ + IMPALA_TEST_CLUSTER_PROPERTIES.library_link_type + + def test_root_consistent_build_flags(self): + """Tests that the build flags on the root page contain consistent values""" + for port in self.TEST_PORTS_WITH_SS: + build_flags = ImpalaTestClusterFlagsDetector.\ + get_build_flags_from_web_ui(self.ROOT_URL.format(port)) + + is_ndebug = build_flags["is_ndebug"] == "true" + + if not is_ndebug: + assert not build_flags["cmake_build_type"] in ["release"] + + if build_flags["cmake_build_type"] in ["debug"]: + assert not is_ndebug + def test_memz(self): - """test /memz at impalad / statestored / catalogd""" + """Tests /memz at impalad / statestored / catalogd""" page = requests.get("http://localhost:25000/memz") assert page.status_code == requests.codes.ok @@ -79,26 +131,31 @@ class TestWebPage(ImpalaTestSuite): except ValueError: assert False, "Invalid JSON returned from /jmx endpoint: %s" % jmx_json - def get_and_check_status(self, url, string_to_search = "", ports_to_test = None): + def get_and_check_status(self, url, string_to_search="", ports_to_test=None): """Helper method that polls a given url and asserts the return code is ok and the response contains the input string.""" if ports_to_test is None: ports_to_test = self.TEST_PORTS_WITH_SS + + responses = [] for port in ports_to_test: input_url = url.format(port) response = requests.get(input_url) assert response.status_code == requests.codes.ok\ and string_to_search in response.text, "Offending url: " + input_url + responses.append(response) + return responses - def get_debug_page(self, page_url): + def get_debug_page(self, page_url, port=25000): """Returns the content of the debug page 'page_url' as json.""" - response = self.get_and_check_status(page_url + "?json", ports_to_test=[25000]) - assert "application/json" in response.headers['Content-Type'] - return json.loads(response) + responses = self.get_and_check_status(page_url + "?json", ports_to_test=[port]) + assert len(responses) == 1 + assert "application/json" in responses[0].headers['Content-Type'] + return json.loads(responses[0].text) - def get_and_check_status_jvm(self, url, string_to_search = ""): + def get_and_check_status_jvm(self, url, string_to_search=""): """Calls get_and_check_status() for impalad and catalogd only""" - self.get_and_check_status(url, string_to_search, + return self.get_and_check_status(url, string_to_search, ports_to_test=self.TEST_PORTS_WITHOUT_SS) def test_content_type(self): @@ -151,7 +208,7 @@ class TestWebPage(ImpalaTestSuite): self.get_and_check_status(set_glog_url, "v set to 3") # Try resetting the glog logging defaults again. - self.get_and_check_status( self.RESET_GLOG_LOGLEVEL_URL, "v set to ") + self.get_and_check_status(self.RESET_GLOG_LOGLEVEL_URL, "v set to ") # Try to get the log level of an empty class input get_loglevel_url = (self.GET_JAVA_LOGLEVEL_URL + "?class=") @@ -214,17 +271,19 @@ class TestWebPage(ImpalaTestSuite): cancels the query.""" if query_options: self.client.set_configuration(query_options) - query_handle = self.client.execute_async(query) + query_handle = self.client.execute_async(query) response_json = "" try: - response = self.get_and_check_status( + responses = self.get_and_check_status( page_url + "?query_id=%s&json" % query_handle.get_handle().id, ports_to_test=[25000]) - response_json = json.loads(response) + assert len(responses) == 1 + response_json = json.loads(responses[0].text) finally: self.client.cancel(query_handle) return response_json + @pytest.mark.skip(reason='IMPALA-7625') def test_backend_states(self, unique_database): """Test that /query_backends returns the list of backend states for DML or queries; nothing for DDL statements""" @@ -240,6 +299,7 @@ class TestWebPage(ImpalaTestSuite): else: assert 'backend_states' not in response_json + @pytest.mark.skip(reason='IMPALA-7625') def test_backend_instances(self, unique_database): """Test that /query_finstances returns the list of fragment instances for DML or queries; nothing for DDL statements""" @@ -255,6 +315,7 @@ class TestWebPage(ImpalaTestSuite): else: assert 'backend_instances' not in response_json + @pytest.mark.skip(reason='IMPALA-7625') def test_backend_instances_mt_dop(self, unique_database): """Test that accessing /query_finstances does not crash the backend when running with mt_dop.""" @@ -268,14 +329,15 @@ class TestWebPage(ImpalaTestSuite): def test_io_mgr_threads(self): """Test that IoMgr threads have readable names. This test assumed that all systems we support have a disk called 'sda'.""" - response = self.get_and_check_status( + responses = self.get_and_check_status( self.THREAD_GROUP_URL + "?group=disk-io-mgr&json", ports_to_test=[25000]) - response_json = json.loads(response) + assert len(responses) == 1 + response_json = json.loads(responses[0].text) thread_names = [t["name"] for t in response_json['threads']] - expected_name_patterns = ["ADLS remote", "S3 remote", "HDFS remote", "sda"] + expected_name_patterns = ["ADLS remote", "S3 remote", "HDFS remote"] for pattern in expected_name_patterns: assert any(pattern in t for t in thread_names), \ - "Could not find thread matching '%s'" % pattern + "Could not find thread matching '%s'" % pattern def test_krpc_rpcz(self): """Test that KRPC metrics are exposed in /rpcz and that they are updated when http://git-wip-us.apache.org/repos/asf/impala/blob/9bdb73b1/www/root.tmpl ---------------------------------------------------------------------- diff --git a/www/root.tmpl b/www/root.tmpl index 7d156c4..9d73c41 100644 --- a/www/root.tmpl +++ b/www/root.tmpl @@ -32,7 +32,10 @@ under the License. {{/impala_server_mode}} <h2>Vers<span id="v">i</span>on</h2> - <pre id="version_pre">{{version}}</pre> + <pre id="version_pre">{{version}} +Build Flags: {{#build_flags}}{{flag_name}}={{flag_value}} {{/build_flags}}</pre> +<!-- The space after {{flag_value}} is necessary to add a space between each flag when +this page is rendered --> <h2>Process Start Time</h2> <pre>{{process_start_time}}</pre>