diff --git a/cmake/templates/ntccfg_config.h b/cmake/templates/ntccfg_config.h index d44d7088c..47ed4ce9e 100644 --- a/cmake/templates/ntccfg_config.h +++ b/cmake/templates/ntccfg_config.h @@ -160,6 +160,9 @@ namespace ntccfg { // Build with compiler instrumentation for code coverage. #define NTC_BUILD_WITH_COVERAGE @NTF_BUILD_WITH_COVERAGE@ +// Build with the expectation that executables are run under valgrind. +#define NTC_BUILD_WITH_VALGRIND @NTF_BUILD_WITH_VALGRIND@ + // Build from a packaging environment. #define NTC_BUILD_FROM_PACKAGING @NTF_BUILD_FROM_PACKAGING@ diff --git a/cmake/templates/ntscfg_config.h b/cmake/templates/ntscfg_config.h index edeecbf9d..a279395ab 100644 --- a/cmake/templates/ntscfg_config.h +++ b/cmake/templates/ntscfg_config.h @@ -136,6 +136,9 @@ namespace ntscfg { // Build with compiler instrumentation for code coverage. #define NTS_BUILD_WITH_COVERAGE @NTF_BUILD_WITH_COVERAGE@ +// Build with the expectation that executables are run under valgrind. +#define NTS_BUILD_WITH_VALGRIND @NTF_BUILD_WITH_VALGRIND@ + // Build from a packaging environment. #define NTS_BUILD_FROM_PACKAGING @NTF_BUILD_FROM_PACKAGING@ diff --git a/configure b/configure index d000e9259..5d81c6c7c 100755 --- a/configure +++ b/configure @@ -407,6 +407,10 @@ if [[ -z "${NTF_CONFIGURE_WITH_COVERAGE}" ]]; then NTF_CONFIGURE_WITH_COVERAGE=0 fi +if [[ -z "${NTF_CONFIGURE_WITH_VALGRIND}" ]]; then + NTF_CONFIGURE_WITH_VALGRIND=0 +fi + if [[ -z "${NTF_CONFIGURE_WITH_DOCUMENTATION}" ]]; then NTF_CONFIGURE_WITH_DOCUMENTATION=0 fi @@ -499,6 +503,7 @@ usage() echo " --with-time-trace Build with time traces enabled [${NTF_CONFIGURE_WITH_TIME_TRACE}]" echo " --with-time-report Build with time reports enabled [${NTF_CONFIGURE_WITH_TIME_REPORT}]" echo " --with-coverage Build with code coverage enabled [${NTF_CONFIGURE_WITH_COVERAGE}]" + echo " --with-valgrind Build with tests running under valgrind [${NTF_CONFIGURE_WITH_VALGRIND}]" echo " --with-applications Build applications [${NTF_CONFIGURE_WITH_APPLICATIONS}]" echo " --with-usage-examples Build usage examples [${NTF_CONFIGURE_WITH_USAGE_EXAMPLES}]" @@ -592,6 +597,8 @@ while true ; do NTF_CONFIGURE_WITH_TIME_REPORT=1 ; shift ;; --with-coverage) NTF_CONFIGURE_WITH_COVERAGE=1 ; shift ;; + --with-valgrind) + NTF_CONFIGURE_WITH_VALGRIND=1 ; shift ;; --with-bsl) NTF_CONFIGURE_WITH_BSL=1 ; shift ;; @@ -699,6 +706,8 @@ while true ; do NTF_CONFIGURE_WITH_TIME_REPORT=0 ; shift ;; --without-coverage) NTF_CONFIGURE_WITH_COVERAGE=0 ; shift ;; + --without-valgrind) + NTF_CONFIGURE_WITH_VALGRIND=0 ; shift ;; --without-bsl) NTF_CONFIGURE_WITH_BSL=0 ; shift ;; @@ -844,6 +853,7 @@ export NTF_CONFIGURE_WITH_WARNINGS_AS_ERRORS export NTF_CONFIGURE_WITH_TIME_TRACE export NTF_CONFIGURE_WITH_TIME_REPORT export NTF_CONFIGURE_WITH_COVERAGE +export NTF_CONFIGURE_WITH_VALGRIND export NTF_CONFIGURE_WITH_BSL export NTF_CONFIGURE_WITH_BDL diff --git a/configure.cmd b/configure.cmd index f1088fa6b..be6d4e3ab 100644 --- a/configure.cmd +++ b/configure.cmd @@ -177,6 +177,22 @@ IF NOT DEFINED NTF_CONFIGURE_WITH_WARNINGS_AS_ERRORS ( set NTF_CONFIGURE_WITH_WARNINGS_AS_ERRORS=1 ) +IF NOT DEFINED NTF_CONFIGURE_WITH_TIME_TRACE ( + set NTF_CONFIGURE_WITH_TIME_TRACE=0 +) + +IF NOT DEFINED NTF_CONFIGURE_WITH_TIME_REPORT ( + set NTF_CONFIGURE_WITH_TIME_REPORT=0 +) + +IF NOT DEFINED NTF_CONFIGURE_WITH_COVERAGE ( + set NTF_CONFIGURE_WITH_COVERAGE=0 +) + +IF NOT DEFINED NTF_CONFIGURE_WITH_VALGRIND ( + set NTF_CONFIGURE_WITH_VALGRIND=0 +) + IF NOT DEFINED NTF_CONFIGURE_WITH_DOCUMENTATION ( set NTF_CONFIGURE_WITH_DOCUMENTATION=0 ) @@ -245,6 +261,18 @@ if not "%1"=="" ( if "%1"=="--with-warnings-as-errors" ( set NTF_CONFIGURE_WITH_WARNINGS_AS_ERRORS=1 ) + if "%1"=="--with-time-trace" ( + set NTF_CONFIGURE_WITH_TIME_TRACE=1 + ) + if "%1"=="--with-time-reports" ( + set NTF_CONFIGURE_WITH_TIME_REPORTS=1 + ) + if "%1"=="--with-coverage" ( + set NTF_CONFIGURE_WITH_COVERAGE=1 + ) + if "%1"=="--with-valgrind" ( + set NTF_CONFIGURE_WITH_VALGRIND=1 + ) if "%1"=="--with-bsl" ( set NTF_CONFIGURE_WITH_BSL=1 @@ -361,6 +389,18 @@ if not "%1"=="" ( if "%1"=="--without-warnings-as-errors" ( set NTF_CONFIGURE_WITH_WARNINGS_AS_ERRORS=0 ) + if "%1"=="--without-time-trace" ( + set NTF_CONFIGURE_WITH_TIME_TRACE=0 + ) + if "%1"=="--without-time-report" ( + set NTF_CONFIGURE_WITH_TIME_REPORT=0 + ) + if "%1"=="--without-coverage" ( + set NTF_CONFIGURE_WITH_COVERAGE=0 + ) + if "%1"=="--without-valgrind" ( + set NTF_CONFIGURE_WITH_VALGRIND=0 + ) if "%1"=="--without-bsl" ( set NTF_CONFIGURE_WITH_BSL=0 @@ -810,6 +850,10 @@ echo --with-spin-locks Build with mutually-exclusive locks im echo --with-recursive-mutexes Build with mutually-exclusive locks implemented as recursive mutexes echo --with-warnings Build with warnings enabled echo --with-warnings-as-errors Build with warnings as errors +echo --with-time-trace Build with time traces enabled +echo --with-time-report Build with time reports enabled +echo --with-coverage Build with code coverage enabled +echo --with-valgrind Build with tests running under valgrind echo --with-documentation Build documentation echo --with-documentation-internal Build documentation of internals diff --git a/groups/ntc/ntca/ntca_interfaceconfig.h b/groups/ntc/ntca/ntca_interfaceconfig.h index afe79ca3c..c519afa46 100644 --- a/groups/ntc/ntca/ntca_interfaceconfig.h +++ b/groups/ntc/ntca/ntca_interfaceconfig.h @@ -780,6 +780,11 @@ class InterfaceConfig bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; + + /// Defines the traits of this type. These traits can be used to select, + /// at compile-time, the most efficient algorithm to manipulate objects + /// of this type. + NTCCFG_DECLARE_NESTED_USES_ALLOCATOR_TRAITS(InterfaceConfig); }; /// Format the specified 'object' to the specified output 'stream' and diff --git a/groups/ntc/ntcf/ntcf_system.t.cpp b/groups/ntc/ntcf/ntcf_system.t.cpp index e6b5bbd39..6e42351a6 100644 --- a/groups/ntc/ntcf/ntcf_system.t.cpp +++ b/groups/ntc/ntcf/ntcf_system.t.cpp @@ -7129,7 +7129,12 @@ void concernConnectAndShutdown( // even if connection is not refused or shutdown is called not during // socket detachment process +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif + const int k_TIMEOUT_MICROSEC = 100; const char* address = "127.0.0.1:51"; @@ -7167,7 +7172,11 @@ void concernConnectEndpoint1(const bsl::shared_ptr& scheduler, // Concern: Connect to endpoint periodically fails but eventually succeeds // Testing: ECONNREFUSED, connection established +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -7572,7 +7581,11 @@ void concernConnectEndpoint4(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ECONNREFUSED (x4), ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -7729,7 +7742,11 @@ void concernConnectEndpoint5(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ETIMEDOUT (x4), ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -7889,7 +7906,11 @@ void concernConnectEndpoint6(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ECONNREFUSED (x4), ETIMEDOUT/ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8015,7 +8036,11 @@ void concernConnectEndpoint7(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ETIMEDOUT (x4), ETIMEDOUT/ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8145,7 +8170,11 @@ void concernConnectEndpoint8(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN( "ETIMEDOUT/ECONNREFUSED/ECONNABORTED (x100) (instantaneous)"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8244,7 +8273,11 @@ void concernConnectName1(const bsl::shared_ptr& scheduler, // Concern: Connect to name periodically fails but eventually succeeds // Testing: ECONNREFUSED, connection established +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8662,7 +8695,11 @@ void concernConnectName4(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ECONNREFUSED (x4), ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8819,7 +8856,11 @@ void concernConnectName5(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ETIMEDOUT (x4), ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -8991,7 +9032,11 @@ void concernConnectName6(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ECONNREFUSED (x4), ETIMEDOUT/ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -9116,7 +9161,11 @@ void concernConnectName7(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN("ETIMEDOUT (x4), ETIMEDOUT/ECANCELED"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -9260,7 +9309,11 @@ void concernConnectName8(const bsl::shared_ptr& scheduler, BSLS_LOG_WARN( "ETIMEDOUT/ECONNREFUSED/ECONNABORTED (x100) (instantaneous)"); +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 10; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 100; +#endif const double k_RETRY_INTERVAL_SECONDS = 0.1; @@ -12355,7 +12408,12 @@ void concernStreamSocketConnectDeadlineTimerClose( // Concern: validate that connect deadline timer is automatically closed // when the socket is closed and then destroyed +#if NTC_BUILD_WITH_VALGRIND + const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 6; +#else const bsl::size_t k_MAX_CONNECTION_ATTEMPTS = 60; +#endif + const int k_DEADLINE_INTERVAL_HOURS = 1; const int k_RETRY_INTERVAL_MINUTES = 1; diff --git a/groups/ntc/ntci/ntci_log.cpp b/groups/ntc/ntci/ntci_log.cpp index c4b651274..06caa9c44 100644 --- a/groups/ntc/ntci/ntci_log.cpp +++ b/groups/ntc/ntci/ntci_log.cpp @@ -19,6 +19,7 @@ BSLS_IDENT_RCSID(ntci_log_cpp, "$Id$ $CSID$") #include +#include #include #include #include @@ -34,6 +35,10 @@ BSLS_IDENT_RCSID(ntci_log_cpp, "$Id$ $CSID$") #include #include +#if defined(BSLS_PLATFORM_OS_LINUX) +#include +#endif + #define NTCI_LOG_UNSET_CONTEXT 0 // Define to 1 to use 'vsprintf'. Uncomment, undefine or set to zero to use @@ -106,38 +111,104 @@ void flushLogJournalLocked() s_journal_p->d_position = 0; } -void destroyKey(void* key) +// Provide process-wide initialization. +struct Initializer { + // Perform process-wide initialization for this component. + Initializer(); + + // Perform process-wide cleanup for this component. + ~Initializer(); + + // Allocate memory for a new log context. + static void* allocateLogContext(); + + // Free the memory for a log context at the specified 'address'. + static void freeLogContext(void* address); + + // Destroy the log context at the specified 'key'. + static void destroyKey(void* key); + +#if defined(BSLS_PLATFORM_OS_LINUX) + // The memory for the main thread's log context. + alignas(16) char d_mainThreadContext[sizeof(ntci::LogContext)]; +#endif + +} s_initializer; + +Initializer::Initializer() { - if (key) { - typedef ntci::LogContext Type; + int rc = bslmt::ThreadUtil::createKey(&s_key, &destroyKey); + BSLS_ASSERT_OPT(rc == 0); - Type* logContext = reinterpret_cast(key); - logContext->~Type(); + bool journal; + if (ntccfg::Tune::configure(&journal, "NTC_LOG_JOURNAL")) { + ntci::Log::initialize(journal); + } +} + +Initializer::~Initializer() +{ + ntci::Log::exit(); + + // int rc = bslmt::ThreadUtil::deleteKey(s_key); + // BSLS_ASSERT_OPT(rc == 0); +} - bsl::free(key); +void* Initializer::allocateLogContext() +{ +#if defined(BSLS_PLATFORM_OS_LINUX) + + const pid_t tid = (pid_t) syscall(SYS_gettid); + const pid_t pid = (pid_t) getpid(); + + if (tid == pid) { + BSLS_ASSERT_OPT( + (bsl::size_t)(bsl::uintptr_t)(s_initializer.d_mainThreadContext) + % 16 == 0); + + return (void*) s_initializer.d_mainThreadContext; + } + else { + return bsl::malloc(sizeof(ntci::LogContext)); } + +#else + + return bsl::malloc(sizeof(ntci::LogContext)); + +#endif } -struct Initializer { - Initializer() - { - int rc = bslmt::ThreadUtil::createKey(&s_key, &destroyKey); - BSLS_ASSERT_OPT(rc == 0); +void Initializer::freeLogContext(void* address) +{ +#if defined(BSLS_PLATFORM_OS_LINUX) - bool journal; - if (ntccfg::Tune::configure(&journal, "NTC_LOG_JOURNAL")) { - ntci::Log::initialize(journal); + if (address != 0) { + if (address != (void*) s_initializer.d_mainThreadContext) { + bsl::free(address); } } - ~Initializer() - { - ntci::Log::exit(); +#else - // int rc = bslmt::ThreadUtil::deleteKey(s_key); - // BSLS_ASSERT_OPT(rc == 0); + if (address != 0) { + bsl::free(address); } -} s_initializer; + +#endif +} + +void Initializer::destroyKey(void* key) +{ + if (key != 0) { + typedef ntci::LogContext Type; + + Type* logContext = reinterpret_cast(key); + logContext->~Type(); + + Initializer::freeLogContext(key); + } +} // enum PrintFieldType @@ -3001,7 +3072,7 @@ ntci::LogContext* LogContext::getThreadLocal() bslmt::ThreadUtil::getSpecific(s_key)); if (current == 0) { - void* arena = bsl::malloc(sizeof(ntci::LogContext)); + void* arena = Initializer::allocateLogContext(); current = new (arena) ntci::LogContext(); int rc = bslmt::ThreadUtil::setSpecific( s_key, @@ -3361,11 +3432,15 @@ bsl::size_t LogUtil::formatContext(char* destination, bsl::size_t n = static_cast(osb.length()); - if (n == destinationCapacity) { - --n; + if (n != 0) { + if (n == destinationCapacity) { + --n; + } + + destination[0] = + static_cast(bdlb::CharType::toUpper(destination[0])); } - destination[0] = static_cast(toupper(destination[0])); destination[n] = 0; return n; diff --git a/groups/ntc/ntcs/ntcs_blobbufferfactory.t.cpp b/groups/ntc/ntcs/ntcs_blobbufferfactory.t.cpp index 50a83e156..3a610661e 100644 --- a/groups/ntc/ntcs/ntcs_blobbufferfactory.t.cpp +++ b/groups/ntc/ntcs/ntcs_blobbufferfactory.t.cpp @@ -776,10 +776,17 @@ NTCCFG_TEST_CASE(7) bsl::size_t d_numIterations; } DATA[] = { +#if NTC_BUILD_WITH_VALGRIND + { 1, 100000 }, + { 2, 50000 }, + { 4, 25000 }, + { 10, 10000 } +#else { 1, 10000000 }, { 2, 5000000 }, { 4, 2500000 }, { 10, 1000000 } +#endif }; // clang-format on @@ -850,10 +857,17 @@ NTCCFG_TEST_CASE(8) bsl::size_t d_numIterations; } DATA[] = { +#if NTC_BUILD_WITH_VALGRIND + { 1, 100000 }, + { 2, 50000 }, + { 4, 25000 }, + { 10, 10000 } +#else { 1, 10000000 }, { 2, 5000000 }, { 4, 2500000 }, { 10, 1000000 } +#endif }; // clang-format on @@ -934,10 +948,17 @@ NTCCFG_TEST_CASE(9) bsl::size_t d_numIterations; } DATA[] = { +#if NTC_BUILD_WITH_VALGRIND + { 1, 100000 }, + { 2, 50000 }, + { 4, 25000 }, + { 10, 10000 } +#else { 1, 10000000 }, { 2, 5000000 }, { 4, 2500000 }, { 10, 1000000 } +#endif }; // clang-format on diff --git a/groups/nts/ntsa/ntsa_domainname.h b/groups/nts/ntsa/ntsa_domainname.h index e56e78587..fca790853 100644 --- a/groups/nts/ntsa/ntsa_domainname.h +++ b/groups/nts/ntsa/ntsa_domainname.h @@ -215,6 +215,11 @@ class DomainName /// the specified 'text', otherwise return false. bool less(const bslstl::StringRef& text) const; + /// Contribute the values of the salient attributes of this object to the + /// specified hash 'algorithm'. + template + void hash(HASH_ALGORITHM& algorithm) const; + /// Format this object to the specified output 'stream' at the /// optionally specified indentation 'level' and return a reference to /// the modifiable 'stream'. If 'level' is specified, optionally @@ -298,6 +303,14 @@ bsl::string DomainName::text() const return result; } +template +NTSCFG_INLINE +void DomainName::hash(HASH_ALGORITHM& algorithm) const +{ + using bslh::hashAppend; + algorithm(d_buffer, d_size); +} + NTSCFG_INLINE bsl::ostream& operator<<(bsl::ostream& stream, const DomainName& object) { @@ -323,10 +336,10 @@ bool operator<(const DomainName& lhs, const DomainName& rhs) } template +NTSCFG_INLINE void hashAppend(HASH_ALGORITHM& algorithm, const DomainName& value) { - using bslh::hashAppend; - algorithm(reinterpret_cast(&value), sizeof value); + value.hash(algorithm); } } // close package namespace diff --git a/groups/nts/ntsf/ntsf_system.cpp b/groups/nts/ntsf/ntsf_system.cpp index 100839157..c7b0ace58 100644 --- a/groups/nts/ntsf/ntsf_system.cpp +++ b/groups/nts/ntsf/ntsf_system.cpp @@ -1225,8 +1225,6 @@ void System::setDefault(const bsl::shared_ptr& resolver) error = ntsf::System::initialize(); BSLS_ASSERT_OPT(!error); - bsl::shared_ptr result; - ntscfg::LockGuard lock(s_globalMutex_p); if (s_globalResolver_p != 0) { @@ -1251,8 +1249,6 @@ void System::setDefault(const bsl::shared_ptr& resolver) BSLS_ASSERT_OPT(s_globalResolver_p); BSLS_ASSERT_OPT(s_globalResolverRep_p); - - s_globalResolverRep_p->acquireRef(); } void System::getDefault(bsl::shared_ptr* result) diff --git a/groups/nts/ntsf/ntsf_system.t.cpp b/groups/nts/ntsf/ntsf_system.t.cpp index 3dc451a60..5d6d0ab6c 100644 --- a/groups/nts/ntsf/ntsf_system.t.cpp +++ b/groups/nts/ntsf/ntsf_system.t.cpp @@ -587,11 +587,17 @@ NTSCFG_TEST_CASE(5) resolverConfig, bslma::Default::globalAllocator()); + NTSCFG_TEST_EQ(resolver.use_count(), 1); + ntsf::System::setDefault(resolver); + NTSCFG_TEST_EQ(resolver.use_count(), 2); + bsl::shared_ptr resolverDefault; ntsf::System::getDefault(&resolverDefault); + NTSCFG_TEST_EQ(resolver.use_count(), 3); + NTSCFG_TEST_EQ(resolverDefault, resolver); } diff --git a/repository.cmake b/repository.cmake index 6482aecf3..439da8052 100644 --- a/repository.cmake +++ b/repository.cmake @@ -1646,10 +1646,22 @@ function (ntf_executable) test_usage_executable ${runtime_output_path} ${target}) - add_test( - NAME ${executable_test_build_target} - COMMAND ${test_usage_executable} - ) + if (${NTF_BUILD_WITH_VALGRIND}) + if (NOT DEFINED VALGRIND_PATH) + message(FATAL_ERROR "Valgrind is not found") + endif() + + add_test( + NAME ${executable_test_build_target} + COMMAND ${VALGRIND_PATH} --tool=memcheck --leak-check=full --show-leak-kinds=all --error-exitcode=1 ${test_usage_executable} + ) + + else() + add_test( + NAME ${executable_test_build_target} + COMMAND ${test_usage_executable} + ) + endif() set_tests_properties(${executable_test_build_target} PROPERTIES TIMEOUT 600) @@ -1718,7 +1730,7 @@ function (ntf_executable) if (NOT TARGET test_${target}) add_custom_target( test_${target} - COMMAND ${CMAKE_CTEST_COMMAND} -R ${target}) + COMMAND ${CMAKE_CTEST_COMMAND} --stop-on-failure --output-on-failure -R ${target}) endif() if (NOT TARGET format_${target}) @@ -2457,7 +2469,7 @@ function (ntf_adapter) if (NOT TARGET test_${target}) add_custom_target( test_${target} - COMMAND ${CMAKE_CTEST_COMMAND} -R ${target}) + COMMAND ${CMAKE_CTEST_COMMAND} --stop-on-failure --output-on-failure -R ${target}) endif() if (NOT TARGET format_${target}) @@ -3183,7 +3195,7 @@ function (ntf_group) if (NOT TARGET test_${target}) add_custom_target( test_${target} - COMMAND ${CMAKE_CTEST_COMMAND} -R ${target}) + COMMAND ${CMAKE_CTEST_COMMAND} --stop-on-failure --output-on-failure -R ${target}) endif() if (NOT TARGET format_${target}) @@ -3840,7 +3852,7 @@ function (ntf_package) if (NOT TARGET test_${target}) add_custom_target( test_${target} - COMMAND ${CMAKE_CTEST_COMMAND} -R ${target}) + COMMAND ${CMAKE_CTEST_COMMAND} --stop-on-failure --output-on-failure -R ${target}) endif() if (NOT TARGET format_${target}) @@ -4361,16 +4373,29 @@ function (ntf_component) ntf_target_options_common_epilog(${target}) - add_test( - NAME ${component_test_build_target} - COMMAND ${component_test_build_target} - ) + cmake_path( + APPEND + component_test_build_target_path + ${runtime_output_path} ${component_test_build_target}) + + if (${NTF_BUILD_WITH_VALGRIND}) + add_test( + NAME ${component_test_build_target} + COMMAND ${VALGRIND_PATH} --tool=memcheck --leak-check=full --show-leak-kinds=all --error-exitcode=1 ${component_test_build_target_path} + ) + + else() + add_test( + NAME ${component_test_build_target} + COMMAND ${component_test_build_target} + ) + endif() set_tests_properties(${component_test_build_target} PROPERTIES TIMEOUT 600) add_custom_target( test_${component} - COMMAND ${CMAKE_CTEST_COMMAND} -R ${component}) + COMMAND ${CMAKE_CTEST_COMMAND} --stop-on-failure --output-on-failure -R ${component}) ntf_ide_vs_code_tasks_add_target(${component_test_build_target}) ntf_ide_vs_code_launch_add_target(${component_test_build_target}) @@ -6060,6 +6085,15 @@ function (ntf_repository) /opt/bb/bin ) + find_program( + VALGRIND_PATH + NAMES + valgrind + PATHS + ${install_refroot}/${install_prefix}/bin + /opt/bb/bin + ) + find_program( NTF_SDLC_FORMAT NAMES diff --git a/variables.cmake b/variables.cmake index 015401f20..d0d691e21 100644 --- a/variables.cmake +++ b/variables.cmake @@ -202,6 +202,17 @@ if (NOT DEFINED NTF_BUILD_WITH_COVERAGE) endif() endif() +if (NOT DEFINED NTF_BUILD_WITH_VALGRIND) + if (DEFINED NTF_CONFIGURE_WITH_VALGRIND) + set(NTF_BUILD_WITH_VALGRIND + ${NTF_CONFIGURE_WITH_VALGRIND} CACHE INTERNAL "") + elseif (DEFINED ENV{NTF_CONFIGURE_WITH_VALGRIND}) + set(NTF_BUILD_WITH_VALGRIND + $ENV{NTF_CONFIGURE_WITH_VALGRIND} CACHE INTERNAL "") + else() + set(NTF_BUILD_WITH_VALGRIND FALSE CACHE INTERNAL "") + endif() +endif() if (NOT DEFINED NTF_BUILD_WITH_TIME_TRACE) if (DEFINED NTF_CONFIGURE_WITH_TIME_TRACE) @@ -1084,3 +1095,10 @@ if (${NTF_BUILD_WITH_COVERAGE}) else() message(STATUS "NTF: Building with coverage: no") endif() + +if (${NTF_BUILD_WITH_VALGRIND}) + message(STATUS "NTF: Building with valgrind: yes") +else() + message(STATUS "NTF: Building with valgrind: no") +endif() +