From d6f45909b8a596733c63aec31e8494041b5b3d22 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:01:17 +0000 Subject: [PATCH 01/35] [core/cyclicbuffer] : Cherry pick from 'db117dcbe2ef7d01e80b8aacaff2adb64c7da8ed' Assert on overflow in 'GetCompleteTail'. --- Source/core/CyclicBuffer.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/core/CyclicBuffer.h b/Source/core/CyclicBuffer.h index 724f32957..11d199949 100644 --- a/Source/core/CyclicBuffer.h +++ b/Source/core/CyclicBuffer.h @@ -30,6 +30,8 @@ #include #endif +#include + // ---- Referenced classes and types ---- // ---- Helper types and constants ---- @@ -94,6 +96,8 @@ namespace Core { uint32_t GetCompleteTail(uint32_t offset) const { + ASSERT(_Parent._administration->_tailIndexMask < std::numeric_limits::max()); + uint32_t oldTail = _Tail; uint32_t roundCount = oldTail / (1 + _Parent._administration->_tailIndexMask); oldTail &= _Parent._administration->_tailIndexMask; From a3f09b65943e0799516be37e4df51265a62572ab Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:53:16 +0000 Subject: [PATCH 02/35] [core/DataElement] : prevent undefined behavior 'memcpy' and 'memmove' may experience undefined behavior under certain conditions --- Source/core/DataElement.cpp | 15 ++++++++++++--- Source/core/DataElement.h | 21 ++++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Source/core/DataElement.cpp b/Source/core/DataElement.cpp index 70acfc8b4..ab6244b61 100644 --- a/Source/core/DataElement.cpp +++ b/Source/core/DataElement.cpp @@ -91,8 +91,11 @@ namespace Core { void LinkedDataElement::GetBuffer(uint64_t offset, uint32_t size, uint8_t* buffer) const { + ASSERT(IsValid()); + ASSERT(buffer != nullptr); + // Check if we cross a boundary for the read.. - if ((offset + size) <= Size()) { + if (((offset + size) <= Size()) && (buffer != Buffer())) { // Nope, one plain copy !!! ::memcpy(buffer, &(Buffer()[offset]), size); } else { @@ -113,8 +116,11 @@ namespace Core { void LinkedDataElement::SetBuffer(uint64_t offset, uint32_t size, const uint8_t* buffer) { + ASSERT(IsValid()); + ASSERT(buffer != nullptr); + // Check if we cross a boundary for the write.. - if ((offset + size) <= Size()) { + if (((offset + size) <= Size()) && (buffer != Buffer())) { // Nope, one plain copy !!! ::memcpy(&(Buffer()[offset]), buffer, size); } else { @@ -135,6 +141,9 @@ namespace Core { uint64_t LinkedDataElement::Copy(const uint64_t offset, const LinkedDataElement& copy) { + ASSERT(IsValid()); + ASSERT(copy.IsValid()); + const LinkedDataElement* source = © LinkedDataElement* destination = this; uint64_t sourceOffset = 0; @@ -142,7 +151,7 @@ namespace Core { uint64_t copiedSize = 0; do { - if ((source->Size() - sourceOffset) > (destination->Size() - destinationOffset)) { + if ((source->Size() - sourceOffset) > (destination->Size() - destinationOffset) && (source != destination)) { // The destination is the limiting factor, fill the destination up.. ::memcpy(&(destination->Buffer()[destinationOffset]), &(source->Buffer()[sourceOffset]), static_cast(destination->Size() - destinationOffset)); diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 0db0074b6..bf69a80ee 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -75,6 +75,8 @@ namespace Core { public: inline void Copy(const uint8_t data[], const uint16_t length, const uint16_t offset = 0) { + ASSERT(_buffer != nullptr); + ASSERT(offset < _size); if (offset < _size) { ASSERT(static_cast(offset + length) <= _size); @@ -345,6 +347,8 @@ namespace Core { bool Expand(const uint64_t offset, const uint32_t size) { + ASSERT(IsValid()); + bool expanded = false; // Make sure we are not shrinking beyond the size boundary @@ -362,7 +366,9 @@ namespace Core { } bool Shrink(const uint64_t offset, const uint32_t size) - { + { + ASSERT(IsValid()); + // Make sure we are not shrinking beyond the size boundary ASSERT(m_Size >= (offset + size)); @@ -370,18 +376,21 @@ namespace Core { m_Size -= size; // Shift all data back the beginning in.. - ::memcpy(&m_Buffer[static_cast(offset)], &m_Buffer[static_cast(offset) + size], static_cast(m_Size - offset)); + ::memmove(&m_Buffer[static_cast(offset)], &m_Buffer[static_cast(offset) + size], static_cast(m_Size - offset)); return (true); } bool Copy(const DataElement& RHS, const uint64_t offset = 0) { + ASSERT(IsValid()); + ASSERT(RHS.IsValid()); + bool copied = false; // see if we need to resize if ((RHS.Size() + offset) > m_Size) { - if (Size(offset + RHS.m_Size) == true) { + if ((Size(offset + RHS.m_Size) == true) && (this != &RHS)) { ::memcpy(&(m_Buffer[offset]), RHS.m_Buffer, static_cast(RHS.m_Size)); m_Size = offset + RHS.m_Size; copied = true; @@ -577,6 +586,9 @@ namespace Core { inline void GetBuffer(const uint64_t offset, const uint32_t size, uint8_t* buffer) const { + ASSERT(IsValid()); + ASSERT(buffer != nullptr); + // Check if we cross a boundary for the read.. ASSERT((offset + size) <= m_Size); @@ -694,6 +706,9 @@ namespace Core { void SetBuffer(const uint64_t offset, const uint32_t size, const uint8_t* buffer) { + ASSERT(IsValid()); + ASSERT(buffer != nullptr); + // Check if we cross a boundary for the write.. ASSERT((offset + size) <= m_Size); From 7a27e2c4af564b53c743b9fac6de55ff664b0aee Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:58:29 +0000 Subject: [PATCH 03/35] [core/DataElement] : Add extra ASSERTS and checks --- Source/core/DataElement.cpp | 1 + Source/core/DataElement.h | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Source/core/DataElement.cpp b/Source/core/DataElement.cpp index ab6244b61..f4e5d8864 100644 --- a/Source/core/DataElement.cpp +++ b/Source/core/DataElement.cpp @@ -79,6 +79,7 @@ namespace Core { /// Calculated CRC value uint32_t DataElement::CRC32(const uint64_t offset, const uint64_t size) const { + ASSERT(IsValid()); ASSERT(offset + size <= m_Size); uint32_t crc = 0xffffffff; diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index bf69a80ee..176b3de7e 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -118,6 +118,8 @@ namespace Core { protected: void UpdateCache(const uint64_t offset, uint8_t* buffer, const uint64_t size, const uint64_t maxSize) { + ASSERT(buffer != nullptr); + // Update the cache... m_Offset = offset; m_Size = size; @@ -126,6 +128,7 @@ namespace Core { } void UpdateCache(const Core::DataElement& data, const uint64_t offset, const uint64_t size) { + ASSERT(data.IsValid()); ASSERT((offset + size) <= data.Size()); // Update the cache... @@ -193,6 +196,8 @@ namespace Core { , m_Size(move.m_Size) , m_MaxSize(move.m_MaxSize) { + ASSERT(this != &move); + move.m_Buffer = nullptr; move.m_Offset = 0; move.m_Size = 0; @@ -219,6 +224,8 @@ namespace Core { , m_Size(move.m_Size - offset) , m_MaxSize(move.m_MaxSize) { + ASSERT(this != &move); + if (size != 0) { m_Size = size; } From 3f596402c911414e72becad4e6315727cefda292 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Tue, 11 Jun 2024 08:32:50 +0000 Subject: [PATCH 04/35] [core/DataElement / Tests/unit/core] : Do not continue writing data if the chain of destinations has insufficient (total) free space Also partially revert 'a3f09b65943e0799516be37e4df51265a62572ab' --- Source/core/DataElement.cpp | 10 ++++++---- Tests/unit/core/test_dataelement.cpp | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/core/DataElement.cpp b/Source/core/DataElement.cpp index f4e5d8864..bc484f562 100644 --- a/Source/core/DataElement.cpp +++ b/Source/core/DataElement.cpp @@ -152,9 +152,9 @@ namespace Core { uint64_t copiedSize = 0; do { - if ((source->Size() - sourceOffset) > (destination->Size() - destinationOffset) && (source != destination)) { + if ((source->Size() - sourceOffset) > (destination->Size() - destinationOffset)) { // The destination is the limiting factor, fill the destination up.. - ::memcpy(&(destination->Buffer()[destinationOffset]), &(source->Buffer()[sourceOffset]), static_cast(destination->Size() - destinationOffset)); + ::memmove(&(destination->Buffer()[destinationOffset]), &(source->Buffer()[sourceOffset]), static_cast(destination->Size() - destinationOffset)); sourceOffset += (destination->Size() - destinationOffset); copiedSize += (destination->Size() - destinationOffset); @@ -169,8 +169,10 @@ namespace Core { source = source->m_Next; sourceOffset = 0; } - - } while ((destination != nullptr) && (source != nullptr)); + } while ( (destination != nullptr) + && (source != nullptr) + && !((copiedSize >= destination->Size()) && (destination->m_Next == nullptr)) + ); return (copiedSize); } diff --git a/Tests/unit/core/test_dataelement.cpp b/Tests/unit/core/test_dataelement.cpp index 0c950cd82..88dc1c5d9 100644 --- a/Tests/unit/core/test_dataelement.cpp +++ b/Tests/unit/core/test_dataelement.cpp @@ -91,6 +91,7 @@ TEST(test_linkeddata, simple_linkeddata) LinkedDataElement ob2(objt1); LinkedDataElement ob3(ob2); ob3.Enclosed(&ob2); + EXPECT_EQ(ob3.Enclosed(), &ob2); ob3.SetBuffer(2,9,arr); ob3.GetBuffer(2,9,arr1); LinkedDataElement ob4; From 1f045d92161080d4ba3921710b5931f0bbfb9170 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:48:54 +0000 Subject: [PATCH 05/35] [core/DataElement] : partially revert 'a3f09b65943e0799516be37e4df51265a62572ab' Replace 'memcpy' by 'memmove' which allows 'buffer' equal 'Buffer()' --- Source/core/DataElement.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/core/DataElement.cpp b/Source/core/DataElement.cpp index bc484f562..f7bfd1544 100644 --- a/Source/core/DataElement.cpp +++ b/Source/core/DataElement.cpp @@ -96,9 +96,9 @@ namespace Core { ASSERT(buffer != nullptr); // Check if we cross a boundary for the read.. - if (((offset + size) <= Size()) && (buffer != Buffer())) { + if ((offset + size) <= Size()) { // Nope, one plain copy !!! - ::memcpy(buffer, &(Buffer()[offset]), size); + ::memmove(buffer, &(Buffer()[offset]), size); } else { // If we want to read more than 4Gb ASSERT !! ASSERT(Size() - offset < 0xFFFFFFFF); @@ -121,9 +121,9 @@ namespace Core { ASSERT(buffer != nullptr); // Check if we cross a boundary for the write.. - if (((offset + size) <= Size()) && (buffer != Buffer())) { + if ((offset + size) <= Size()) { // Nope, one plain copy !!! - ::memcpy(&(Buffer()[offset]), buffer, size); + ::memmove(&(Buffer()[offset]), buffer, size); } else { // If we want to write more than 4Gb ASSERT !! ASSERT(Size() - offset < 0xFFFFFFFF); From fbec3d347f3dcca5820890b120feda4a697571f3 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:07:11 +0000 Subject: [PATCH 06/35] [core/DataElement] : Early stop without modification --- Source/core/DataElement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 176b3de7e..776f0fdd0 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -397,7 +397,7 @@ namespace Core { // see if we need to resize if ((RHS.Size() + offset) > m_Size) { - if ((Size(offset + RHS.m_Size) == true) && (this != &RHS)) { + if ((this != &RHS) && (Size(offset + RHS.m_Size) == true)) { ::memcpy(&(m_Buffer[offset]), RHS.m_Buffer, static_cast(RHS.m_Size)); m_Size = offset + RHS.m_Size; copied = true; From bacb506da9f6ad0e342f6421cabb329a0c0b7b4a Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:03:09 +0000 Subject: [PATCH 07/35] [core/DataElement] : Additional checks --- Source/core/DataElement.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 776f0fdd0..8d5e0b984 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -307,6 +307,9 @@ namespace Core { } inline bool operator==(const DataElement& RHS) const { + ASSERT(IsValid()); + ASSERT(RHS.IsValid()); + return ((m_Size == RHS.m_Size) && (::memcmp(m_Buffer, RHS.m_Buffer, static_cast(m_Size)) == 0)); } inline bool operator!=(const DataElement& RHS) const @@ -334,16 +337,24 @@ namespace Core { inline uint8_t& operator[](const uint32_t index) { + ASSERT(IsValid()); + ASSERT(index < m_Size); + return (m_Buffer[index]); } inline const uint8_t& operator[](const uint32_t index) const { + ASSERT(IsValid()); + ASSERT(index < m_Size); + return (m_Buffer[index]); } void Set(const uint8_t value, const uint64_t offset = 0, const uint64_t size = NUMBER_MAX_UNSIGNED(uint64_t)) { + ASSERT(IsValid()); + ASSERT((size == NUMBER_MAX_UNSIGNED(uint64_t)) || ((offset + size) < m_Size)); if (size == NUMBER_MAX_UNSIGNED(uint64_t)) { ::memset(&m_Buffer[offset], value, static_cast(m_Size - offset)); @@ -417,6 +428,8 @@ namespace Core { uint64_t Search(const uint64_t offset, const uint8_t pattern[], const uint32_t size) const { + ASSERT(IsValid()); + bool found = false; uint64_t index = offset; @@ -451,6 +464,8 @@ namespace Core { template uint64_t SearchNumber(const uint64_t offset, const TYPENAME info) const { + ASSERT(IsValid()); + // Make sure we do not pass the boundaries !!! ASSERT(offset < m_Size); From 24194746e7b0ccbd1477631545c8d89938d05954 Mon Sep 17 00:00:00 2001 From: HaseenaSainul <41037131+HaseenaSainul@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:31:54 +0530 Subject: [PATCH 08/35] Thunder::SetConfiguration jsonrpc: validate json config before setting (#1615) * Thunder::SetConfiguration jsonrpc: validate json config before setting * JSON:Variant: parsing updates --------- Co-authored-by: Pierre Wielders --- Source/Thunder/Controller.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Source/Thunder/Controller.cpp b/Source/Thunder/Controller.cpp index db9fb0b32..ac5c85635 100644 --- a/Source/Thunder/Controller.cpp +++ b/Source/Thunder/Controller.cpp @@ -309,11 +309,21 @@ namespace Plugin { ASSERT(_pluginServer != nullptr); if (_pluginServer->Services().FromIdentifier(callsign, service) == Core::ERROR_NONE) { - result = service->ConfigLine(configuration); + Core::JSON::Variant config; + Core::OptionalType error; + config.FromString(configuration, error); + result = Core::ERROR_INCOMPLETE_CONFIG; + if (error.IsSet() == true) { + SYSLOG(Logging::ParsingError, (_T("Parsing failed with %s"), ErrorDisplayMessage(error.Value()).c_str())); + } else if (config.IsValid() != true) { + SYSLOG(Logging::ParsingError, (_T("Given configuration is not valid"))); + } else { + result = service->ConfigLine(configuration); - // Normalise return code - if (result != Core::ERROR_NONE) { - result = Core::ERROR_GENERAL; + // Normalise return code + if (result != Core::ERROR_NONE) { + result = Core::ERROR_GENERAL; + } } } From be5d9c199820fcbfd9145edfa3d60af886d2703a Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Wed, 12 Jun 2024 16:32:01 +0200 Subject: [PATCH 09/35] Development/cmake enhancements (#1636) * cmake: set minimum required cmake to 3.15 * cmake: group binaries to components * cmake: fix typo * cmake: Introduce project metadata * cmake: Export versions * Core: Generate and use a version header * Thunder: Generate and use a version header * cmake: Use project version in binaries * cmake: remove old versioning * scripts: simplify init script generation * cmake: introduce new build options * COM: Prepare for versioned proxystub loading * Plugin: Prepare for versioned proxystub loading * cmake: Add Thunder config to runtime component * cmake make human versioned libs optional * cmake: remove arbitrary endif --------- Co-authored-by: Pierre Wielders --- CMakeLists.txt | 27 +++++++---- Source/Thunder/CMakeLists.txt | 29 +++++------ Source/Thunder/GenericConfig.cmake | 4 +- Source/Thunder/Module.h | 8 +--- Source/Thunder/Thunder.conf.in | 2 +- Source/Thunder/Version.h.in | 14 ++++++ Source/Thunder/scripts/CMakeLists.txt | 41 ++++++++-------- Source/Thunder/scripts/thunder.in | 10 ++-- Source/Thunder/scripts/thunder.service.in | 2 +- Source/ThunderPlugin/CMakeLists.txt | 19 +++++--- Source/ThunderPlugin/Process.cpp | 8 +++- Source/com/CMakeLists.txt | 22 +++++---- Source/com/Communicator.cpp | 8 +++- Source/core/CMakeLists.txt | 30 +++++++----- Source/core/Portability.h | 2 +- Source/core/Version.h.in | 7 +++ Source/cryptalgo/CMakeLists.txt | 23 +++++---- Source/extensions/hibernate/CMakeLists.txt | 23 +++++---- Source/extensions/localtracer/CMakeLists.txt | 8 ++-- .../localtracer/example/CMakeLists.txt | 2 +- .../privilegedrequest/CMakeLists.txt | 8 ++-- .../privilegedrequest/example/CMakeLists.txt | 2 +- .../processcontainers/CMakeLists.txt | 23 +++++---- .../warningreporting/CMakeLists.txt | 23 +++++---- Source/messaging/CMakeLists.txt | 25 ++++++---- Source/plugins/CMakeLists.txt | 48 +++++++++++-------- Source/websocket/CMakeLists.txt | 29 ++++++----- Tests/comrpctester/CMakeLists.txt | 2 +- Tests/file-unlink/CMakeLists.txt | 4 +- Tests/httpsclient/CMakeLists.txt | 2 +- Tests/loader/CMakeLists.txt | 2 +- Tests/message-buffer/CMakeLists.txt | 2 +- Tests/redirect/CMakeLists.txt | 2 +- Tests/unit/core/CMakeLists.txt | 4 +- Tests/unit/tests/CMakeLists.txt | 2 +- Tests/workerpool-test/CMakeLists.txt | 2 +- cmake/common/CmakeHelperFunctions.cmake | 6 +-- cmake/config.cmake | 2 +- cmake/modules/FindGBM.cmake | 2 +- cmake/modules/FindLibCRUN.cmake | 2 +- cmake/modules/FindMemcr.cmake | 2 +- cmake/project.cmake.in | 17 +++++++ docs/plugin/interfaces/interfaces.md | 8 ++-- 43 files changed, 309 insertions(+), 199 deletions(-) create mode 100644 Source/Thunder/Version.h.in create mode 100644 Source/core/Version.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index a5eac124c..fa3fe667e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,17 +15,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.15) -project(Thunder) +project(Thunder + VERSION 5.0.0 + DESCRIPTION "Thunder framework" + HOMEPAGE_URL "https://rdkcentral.github.io/Thunder/") -set(VERSION_MAJOR 1) -set(VERSION_MINOR 0) -set(VERSION_PATCH 0) +string(TIMESTAMP BUILD_TIMESTAMP UTC) -set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) - -message(STATUS "Setting up ${PROJECT_NAME} v${VERSION}") +message(STATUS "Setting up ${PROJECT_NAME} v${Thunder_VERSION}") option(HIDE_NON_EXTERNAL_SYMBOLS "Hide all non EXTERNAL tagged symbols" ON) @@ -33,12 +32,21 @@ option(ENABLE_STRICT_COMPILER_SETTINGS "Enable compiler flags to get the warnings/errors due to improper condition in the code" OFF) option(LEGACY_CONFIG_GENERATOR "Use the legacy config generator and all its needed CMake sub-components. - If switched OFF, plugins need to use the new python-based templates. (*.conf.in)" OFF) + If switched OFF, plugins need to use the new python-based templates. (*.conf.in)" OFF) +option(HUMAN_VERSIONED_BINARIES + "Create binaries with a human readeable version suffix" ON) +option(VERSIONED_LIBRARY_LOADING + "Uses the major version (*.so.) to load libraries rather then *.so" OFF) + if (BUILD_REFERENCE) add_definitions (-DBUILD_REFERENCE=${BUILD_REFERENCE}) endif() +if(VERSIONED_LIBRARY_LOADING) + add_definitions(-DVERSIONED_LIBRARY_LOADING) +endif() + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common" @@ -138,4 +146,3 @@ endif() add_subdirectory(Source) add_subdirectory(Tests) - diff --git a/Source/Thunder/CMakeLists.txt b/Source/Thunder/CMakeLists.txt index a327e1c5a..6ed4a9a4d 100644 --- a/Source/Thunder/CMakeLists.txt +++ b/Source/Thunder/CMakeLists.txt @@ -20,7 +20,6 @@ find_package(Threads REQUIRED) get_filename_component(TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME) set(THREADPOOL_COUNT "4" CACHE STRING "The number of threads in the thread pool") -set(ENABLE_INITSCRIPT_SUPPORT ON CACHE STRING "Enable init script(systemd/initd) install support from the thunder source tree") set(ENABLE_TRACING_MODULES "" CACHE STRING "A space separated list of specific tracing modules to be enabled at start.") add_executable(${TARGET} @@ -41,19 +40,23 @@ target_compile_definitions(${TARGET} target_compile_options (${TARGET} PRIVATE -Wno-psabi) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/version/version.h" @ONLY) +message(STATUS "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/version/version.h") + if (TREE_REFERENCE) target_compile_definitions(${TARGET} - PRIVATE + PRIVATE -DTREE_REFERENCE=${TREE_REFERENCE} ) endif() -target_include_directories( ${TARGET} +target_include_directories(${TARGET} PUBLIC $ + PRIVATE + $ ) - if (EXCEPTION_CATCHING) set_source_files_properties( PluginServer.cpp PROPERTIES COMPILE_FLAGS "-fexceptions" ) endif() @@ -95,24 +98,22 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - VERSION ${VERSION} + VERSION ${Thunder_VERSION} ) install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime ) install(DIRECTORY - DESTINATION ${CMAKE_INSTALL_PREFIX}/../${PERSISTENT_PATH/${NAMESPACE}} + DESTINATION ${CMAKE_INSTALL_PREFIX}/../${PERSISTENT_PATH}/${NAMESPACE}} DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE ) -if (ENABLE_INITSCRIPT_SUPPORT) - add_subdirectory(scripts) -endif() +add_subdirectory(scripts) include(GenericConfig.cmake) diff --git a/Source/Thunder/GenericConfig.cmake b/Source/Thunder/GenericConfig.cmake index e0c1daa29..c7714bb5a 100644 --- a/Source/Thunder/GenericConfig.cmake +++ b/Source/Thunder/GenericConfig.cmake @@ -65,7 +65,7 @@ map() key(tracing) endif() key(version) - val(${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}) + val(${Thunder_VERSION_MAJOR}.${Thunder_VERSION_MINOR}.${Thunder_VERSION_PATCH}) end() ans(CONFIG) @@ -286,7 +286,7 @@ install( FILES ${CMAKE_BINARY_DIR}/Config.json DESTINATION ../${CMAKE_INSTALL_SYSCONFDIR}/${NAMESPACE}/ RENAME config.json - COMPONENT ${MODULE_NAME}) + COMPONENT ${NAMESPACE}_Runtime) else() find_package(ConfigGenerator REQUIRED) diff --git a/Source/Thunder/Module.h b/Source/Thunder/Module.h index 883c1412d..7f397cab5 100644 --- a/Source/Thunder/Module.h +++ b/Source/Thunder/Module.h @@ -37,13 +37,7 @@ #define TREE_REFERENCE engineering_build_for_debug_purpose_only #endif -namespace Thunder { - namespace PluginHost { - static constexpr uint8_t Major = 4; - static constexpr uint8_t Minor = 0; - static constexpr uint8_t Patch = 0; - } -} +#include #undef EXTERNAL #define EXTERNAL diff --git a/Source/Thunder/Thunder.conf.in b/Source/Thunder/Thunder.conf.in index 260913aca..b408621d5 100644 --- a/Source/Thunder/Thunder.conf.in +++ b/Source/Thunder/Thunder.conf.in @@ -1,4 +1,4 @@ -version = '@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_REVISION@' +version = '@Thunder_VERSION_MAJOR@.@Thunder_VERSION_MINOR@.@Thunder_VERSION_PATCH@' port = '@PORT@' binding = '@BINDING@' ipv6 = '@IPV6_SUPPORT@' diff --git a/Source/Thunder/Version.h.in b/Source/Thunder/Version.h.in new file mode 100644 index 000000000..a5ad9d527 --- /dev/null +++ b/Source/Thunder/Version.h.in @@ -0,0 +1,14 @@ +/*** + * DO NOT EDIT, THIS FILE IS GENERATED @ @BUILD_TIMESTAMP@ + */ + +#pragma once + +namespace Thunder +{ + namespace PluginHost { + static constexpr uint8_t Major = @Thunder_VERSION_MAJOR@; + static constexpr uint8_t Minor = @Thunder_VERSION_MINOR@; + static constexpr uint8_t Patch = @Thunder_VERSION_PATCH@; + } +} diff --git a/Source/Thunder/scripts/CMakeLists.txt b/Source/Thunder/scripts/CMakeLists.txt index b43457529..3a1fc61c5 100644 --- a/Source/Thunder/scripts/CMakeLists.txt +++ b/Source/Thunder/scripts/CMakeLists.txt @@ -15,35 +15,36 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(SYSTEMD_SERVICE "false" CACHE STRING "Select systemd service scripts, by default it install initv scripts") -set(SYSTEM_ROOT_PATH "root" CACHE STRING "System root directory location") +option(SYSTEMD_SERVICE "Install the systemd service" OFF) +option(INITV_SCRIPT "Install the initv script" ON) if (SYSTEMD_SERVICE) - file(READ thunder.service.in THUNDER_SYSTEMD_SERVICE) - string( - REGEX REPLACE "EXTRA_DEPENDS" "${SYSTEMD_EXTRA_DEPENDS}" - MOD_THUNDER_SYSTEMD_SERVICE "${THUNDER_SYSTEMD_SERVICE}" - ) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/thunder.service "${MOD_THUNDER_SYSTEMD_SERVICE}") + set(SYSTEMD_EXTRA_DEPENDS "" CACHE STRING "Adds extra dependecies to the systemd service") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/thunder.service.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/thunder.service" @ONLY) - install(DIRECTORY DESTINATION ${CMAKE_INSTALL_PREFIX}/../${CMAKE_INSTALL_LIBDIR}) install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/thunder.service + FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/thunder.service PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - DESTINATION ${CMAKE_INSTALL_PREFIX}/../${SYSTEMD_INSTALL_PATH}/system/ - ) -else() - file(READ thunder.in THUNDER_INITD) - string( - REGEX REPLACE "ROOT_PATH" "${SYSTEM_ROOT_PATH}/${NAMESPACE}" - MOD_THUNDER_INITD "${THUNDER_INITD}" + DESTINATION ${CMAKE_INSTALL_PREFIX}/../${SYSTEMD_INSTALL_PATH}/system/ + COMPONENT ${NAMESPACE}_Runtime ) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/thunder "${MOD_THUNDER_INITD}") + +endif() + +if (INITV_SCRIPT) + set(SYSV_INIT_LEVEL "80" CACHE STRING "Level of the initv start script") + set(SYSTEM_ROOT_PATH "/root" CACHE STRING "System root directory location") + set(ROOT_PATH "${SYSTEM_ROOT_PATH}/${NAMESPACE}" CACHE STRING "Thunders root path") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/thunder.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/thunder" @ONLY) install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/thunder + FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/thunder PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - DESTINATION ../${CMAKE_INSTALL_SYSCONFDIR}/init.d/ + RENAME S${SYSV_INIT_LEVEL}thunder + DESTINATION ../${CMAKE_INSTALL_SYSCONFDIR}/init.d/ + COMPONENT ${NAMESPACE}_Runtime ) endif() diff --git a/Source/Thunder/scripts/thunder.in b/Source/Thunder/scripts/thunder.in index c596f5a8c..2f3531c86 100755 --- a/Source/Thunder/scripts/thunder.in +++ b/Source/Thunder/scripts/thunder.in @@ -4,13 +4,13 @@ start() { # Core dumps #echo 1 > /proc/sys/kernel/core_uses_pid #echo 2 > /proc/sys/fs/suid_dumpable - #echo "/ROOT_PATH/cores/core-pid_%p--process%E" > /proc/sys/kernel/core_pattern - #mkdir -p /ROOT_PATH/cores + #echo "@ROOT_PATH@/cores/core-pid_%p--process%E" > /proc/sys/kernel/core_pattern + #mkdir -p @ROOT_PATH@/cores #ulimit -c unlimited - if [ ! -d /ROOT_PATH/Netflix/dpi ]; then - mkdir -p /ROOT_PATH/Netflix/dpi - ln -sfn /etc/playready /ROOT_PATH/Netflix/dpi/playready + if [ ! -d @ROOT_PATH@/Netflix/dpi ]; then + mkdir -p @ROOT_PATH@/Netflix/dpi + ln -sfn /etc/playready @ROOT_PATH@/Netflix/dpi/playready fi # needed for wayland/westeros/weston diff --git a/Source/Thunder/scripts/thunder.service.in b/Source/Thunder/scripts/thunder.service.in index 3ac3fa423..1ac92dc3a 100755 --- a/Source/Thunder/scripts/thunder.service.in +++ b/Source/Thunder/scripts/thunder.service.in @@ -1,7 +1,7 @@ [Unit] Description=thunder Wants=multi-user.target -After=multi-user.target EXTRA_DEPENDS +After=multi-user.target @EXTRA_DEPENDS@ [Service] PIDFile=/var/run/Thunder.pid diff --git a/Source/ThunderPlugin/CMakeLists.txt b/Source/ThunderPlugin/CMakeLists.txt index 77b08c4c1..1b3dbc86b 100644 --- a/Source/ThunderPlugin/CMakeLists.txt +++ b/Source/ThunderPlugin/CMakeLists.txt @@ -63,14 +63,19 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + install( - TARGETS COMProcess ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac + TARGETS COMProcess ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime ) diff --git a/Source/ThunderPlugin/Process.cpp b/Source/ThunderPlugin/Process.cpp index 3bff387ab..ed14342d7 100644 --- a/Source/ThunderPlugin/Process.cpp +++ b/Source/ThunderPlugin/Process.cpp @@ -476,10 +476,16 @@ class ProcessFlow { uint32_t result; uint32_t waitTime (RPC::CommunicationTimeOut != Core::infinite ? 2 * RPC::CommunicationTimeOut : RPC::CommunicationTimeOut); +#ifdef VERSIONED_LIBRARY_LOADING + static const std::string suffixFilter = "*.so." + std::to_string(THUNDER_VERSION); +#else + static const std::string suffixFilter = ".so"; +#endif + TRACE_L1("Loading ProxyStubs from %s", (pathName.empty() == false ? pathName.c_str() : _T("<< No Proxy Stubs Loaded >>"))); if (pathName.empty() == false) { - Core::Directory index(pathName.c_str(), _T("*.so")); + Core::Directory index(pathName.c_str(), _T(suffixFilter.c_str())); while (index.Next() == true) { Core::Library library(index.Current().c_str()); diff --git a/Source/com/CMakeLists.txt b/Source/com/CMakeLists.txt index 1ab21951e..fd3cacf1b 100644 --- a/Source/com/CMakeLists.txt +++ b/Source/com/CMakeLists.txt @@ -86,19 +86,23 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/com COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/com COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) InstallCMakeConfig(TARGETS ${TARGET}) diff --git a/Source/com/Communicator.cpp b/Source/com/Communicator.cpp index 1429d7f62..e8642ead2 100644 --- a/Source/com/Communicator.cpp +++ b/Source/com/Communicator.cpp @@ -251,8 +251,14 @@ namespace RPC { Core::TextSegmentIterator places(Core::TextFragment(pathName), false, '|'); +#ifdef VERSIONED_LIBRARY_LOADING + static const std::string suffixFilter = "*.so." + std::to_string(THUNDER_VERSION); +#else + static const std::string suffixFilter = ".so"; +#endif + while (places.Next() == true) { - Core::Directory index(places.Current().Text().c_str(), _T("*.so")); + Core::Directory index(places.Current().Text().c_str(), _T(suffixFilter.c_str())); while (index.Next() == true) { // Check if this ProxySTub file is already loaded in this process space.. diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index b00656d8a..08985df25 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -22,6 +22,9 @@ find_package(Threads REQUIRED) find_package(ExecInfo) find_package(LIBRT) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h" @ONLY) +message(STATUS "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h") + add_library(${TARGET} Module.cpp DoorBell.cpp @@ -58,7 +61,6 @@ add_library(${TARGET} ResourceMonitor.cpp ) - #TODO: Remove all non public headers from this list, # All the interface headers are here, these will be installed to staging set(PUBLIC_HEADERS @@ -146,6 +148,7 @@ set(PUBLIC_HEADERS CallsignTLS.h TokenizedStringList.h MessageStore.h + ${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h ) target_compile_options (${TARGET} PRIVATE -Wno-psabi) @@ -227,19 +230,24 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + if (NOT BUILD_SHARED_LIBS) set_property(TARGET ${TARGET} APPEND PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON ) endif() - target_include_directories( ${TARGET} PUBLIC + $ $ #core.h $) @@ -270,13 +278,13 @@ endif() # Install ARTIFACTS: # =========================================================================================== install( - TARGETS CompileSettings ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/core COMPONENT devel # for mac - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS CompileSettings ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/core COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) # =========================================================================================== diff --git a/Source/core/Portability.h b/Source/core/Portability.h index 8085e69aa..263ba3f07 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -991,6 +991,6 @@ namespace std { #endif #endif -#define THUNDER_VERSION 5 +#include "Version.h" #endif // __PORTABILITY_H diff --git a/Source/core/Version.h.in b/Source/core/Version.h.in new file mode 100644 index 000000000..f81def4d3 --- /dev/null +++ b/Source/core/Version.h.in @@ -0,0 +1,7 @@ +/*** + * DO NOT EDIT, THIS FILE IS GENERATED @ @BUILD_TIMESTAMP@ + */ + +#pragma once + +#define THUNDER_VERSION @Thunder_VERSION_MAJOR@ diff --git a/Source/cryptalgo/CMakeLists.txt b/Source/cryptalgo/CMakeLists.txt index 424a9e1c3..c636d3ff4 100644 --- a/Source/cryptalgo/CMakeLists.txt +++ b/Source/cryptalgo/CMakeLists.txt @@ -68,10 +68,15 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + target_include_directories( ${TARGET} PUBLIC $ @@ -80,13 +85,13 @@ target_include_directories( ${TARGET} ) install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/cryptalgo COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/cryptalgo COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) InstallCMakeConfig(TARGETS ${TARGET}) diff --git a/Source/extensions/hibernate/CMakeLists.txt b/Source/extensions/hibernate/CMakeLists.txt index 42698598e..000380f39 100644 --- a/Source/extensions/hibernate/CMakeLists.txt +++ b/Source/extensions/hibernate/CMakeLists.txt @@ -38,10 +38,15 @@ set(PUBLIC_HEADERS set_target_properties(${TARGET} PROPERTIES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + if(HIBERNATE_CHECKPOINTLIB) find_package(Memcr REQUIRED) target_link_libraries(${TARGET} PRIVATE MEMCR::MEMCR) @@ -51,13 +56,13 @@ elseif(HIBERNATE_CHECKPOINTSERVER) endif() install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/hibernate COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/hibernate # headers + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/hibernate COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/hibernate ) InstallCMakeConfig( diff --git a/Source/extensions/localtracer/CMakeLists.txt b/Source/extensions/localtracer/CMakeLists.txt index 7dbdafb0e..3a2a7c838 100644 --- a/Source/extensions/localtracer/CMakeLists.txt +++ b/Source/extensions/localtracer/CMakeLists.txt @@ -1,5 +1,5 @@ project(LocalTracer LANGUAGES CXX) -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.15) set(MODULE_NAME ${NAMESPACE}LocalTracer) @@ -15,14 +15,14 @@ target_link_libraries(${MODULE_NAME} INTERFACE target_include_directories(${MODULE_NAME} INTERFACE $ - $) + $) target_compile_features(${MODULE_NAME} INTERFACE cxx_std_11) install(TARGETS ${MODULE_NAME} EXPORT ${MODULE_NAME}Targets) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/localtracer/localtracer.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/localtracer) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/localtracer/localtracer.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/localtracer COMPONENT ${NAMESPACE}_Development) include(HeaderOnlyInstall) diff --git a/Source/extensions/localtracer/example/CMakeLists.txt b/Source/extensions/localtracer/example/CMakeLists.txt index 09262ddad..b0d068dd8 100644 --- a/Source/extensions/localtracer/example/CMakeLists.txt +++ b/Source/extensions/localtracer/example/CMakeLists.txt @@ -8,5 +8,5 @@ target_link_libraries(local_trace_test PRIVATE ${NAMESPACE}LocalTracer::${NAMESPACE}LocalTracer) if(EXAMPLE_LOCALTRACER) - install(TARGETS local_trace_test DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(TARGETS local_trace_test DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) endif() diff --git a/Source/extensions/privilegedrequest/CMakeLists.txt b/Source/extensions/privilegedrequest/CMakeLists.txt index a6969a552..0bfbb22da 100644 --- a/Source/extensions/privilegedrequest/CMakeLists.txt +++ b/Source/extensions/privilegedrequest/CMakeLists.txt @@ -17,7 +17,7 @@ project(PrivilegedRequest LANGUAGES CXX) -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.15) set(MODULE_NAME ${NAMESPACE}${PROJECT_NAME}) @@ -30,15 +30,15 @@ add_library(${MODULE_NAME}::${MODULE_NAME} ALIAS ${MODULE_NAME}) target_include_directories(${MODULE_NAME} INTERFACE $ - $) + $) target_compile_features(${MODULE_NAME} INTERFACE cxx_std_11) install(TARGETS ${MODULE_NAME} EXPORT ${MODULE_NAME}Targets) install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/privilegedrequest/PrivilegedRequest.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/privilegedrequest) + ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/privilegedrequest/PrivilegedRequest.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/privilegedrequest COMPONENT ${NAMESPACE}_Development) include(HeaderOnlyInstall) diff --git a/Source/extensions/privilegedrequest/example/CMakeLists.txt b/Source/extensions/privilegedrequest/example/CMakeLists.txt index d4f7f8aac..92717190b 100644 --- a/Source/extensions/privilegedrequest/example/CMakeLists.txt +++ b/Source/extensions/privilegedrequest/example/CMakeLists.txt @@ -24,5 +24,5 @@ target_link_libraries(fdpassing PRIVATE ) if(EXAMPLE_PRIVILEGEDREQUEST) -install(TARGETS fdpassing DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS fdpassing DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) endif() diff --git a/Source/extensions/processcontainers/CMakeLists.txt b/Source/extensions/processcontainers/CMakeLists.txt index 15b33f348..513b4bb66 100644 --- a/Source/extensions/processcontainers/CMakeLists.txt +++ b/Source/extensions/processcontainers/CMakeLists.txt @@ -76,10 +76,15 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + target_include_directories( ${TARGET} PUBLIC $ @@ -149,13 +154,13 @@ elseif (PROCESSCONTAINERS_AWC) endif() install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/processcontainers COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/processcontainers # headers + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/processcontainers COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/processcontainers ) InstallCMakeConfig( diff --git a/Source/extensions/warningreporting/CMakeLists.txt b/Source/extensions/warningreporting/CMakeLists.txt index 65d18bdf0..fd2900c9d 100644 --- a/Source/extensions/warningreporting/CMakeLists.txt +++ b/Source/extensions/warningreporting/CMakeLists.txt @@ -44,10 +44,15 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + target_include_directories( ${TARGET} PUBLIC $ @@ -56,13 +61,13 @@ target_include_directories( ${TARGET} ) install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/warningreporting COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/warningreporting COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) InstallCMakeConfig(TARGETS ${TARGET}) diff --git a/Source/messaging/CMakeLists.txt b/Source/messaging/CMakeLists.txt index 35085c5e9..bfc53b3d2 100644 --- a/Source/messaging/CMakeLists.txt +++ b/Source/messaging/CMakeLists.txt @@ -59,10 +59,15 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + target_include_directories( ${TARGET} PUBLIC $ @@ -71,13 +76,13 @@ target_include_directories( ${TARGET} ) install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/messaging COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/messaging COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) InstallCMakeConfig(TARGETS ${TARGET}) @@ -99,6 +104,6 @@ createlink( ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/tracing.h - DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${NAMESPACE}/tracing/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/tracing/ ) endif() diff --git a/Source/plugins/CMakeLists.txt b/Source/plugins/CMakeLists.txt index a04db58a8..767c4cbcc 100644 --- a/Source/plugins/CMakeLists.txt +++ b/Source/plugins/CMakeLists.txt @@ -125,43 +125,53 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + set_target_properties(${TARGET_PROXYSTUBS} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + # =========================================================================================== # Install ARTIFACTS: # =========================================================================================== install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/plugins COMPONENT devel # for mac - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/plugins COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) install( - FILES ${JSON_DATA_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/plugins/json COMPONENT devel # for mac + FILES ${JSON_DATA_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/plugins/json COMPONENT ${NAMESPACE}_Development ) install( - TARGETS ${TARGET_PROXYSTUBS} EXPORT ${TARGET_PROXYSTUBS}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/proxystubs COMPONENT devel # for mac - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/proxystubs # headers + TARGETS ${TARGET_PROXYSTUBS} EXPORT ${TARGET_PROXYSTUBS}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/proxystubs COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/proxystubs ) # =========================================================================================== diff --git a/Source/websocket/CMakeLists.txt b/Source/websocket/CMakeLists.txt index 739ef702a..694d37a8e 100644 --- a/Source/websocket/CMakeLists.txt +++ b/Source/websocket/CMakeLists.txt @@ -58,10 +58,15 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR} + SOVERSION ${Thunder_VERSION_MAJOR} ) +if(HUMAN_VERSIONED_BINARIES) +set_target_properties(${TARGET} PROPERTIES + VERSION ${Thunder_VERSION} + ) +endif() + target_include_directories( ${TARGET} PUBLIC $ @@ -70,22 +75,22 @@ target_include_directories( ${TARGET} ) install( - TARGETS ${TARGET} EXPORT ${TARGET}Targets # for downstream dependencies - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries - FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # for mac - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/websocket COMPONENT devel # headers for mac (note the different component -> different package) - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} # default include path + TARGETS ${TARGET} EXPORT ${TARGET}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${NAMESPACE}_Runtime NAMELINK_COMPONENT ${NAMESPACE}_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Runtime + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/websocket COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE} ) -install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink websocket ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/include/${NAMESPACE}/jsonrpc)") -install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink websocket.h ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/include/${NAMESPACE}/websocket/jsonrpc.h)") +#FIXME: check if this goes OK with bitbake +install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink websocket ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/jsonrpc)") +install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink websocket.h ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/websocket/jsonrpc.h)") InstallPackageConfig( TARGETS ${TARGET} DESCRIPTION "library containing HTTP protocol (RFC2616), WebSocket (RFC6455) and JSONRPC functionality.") - InstallCMakeConfig(TARGETS ${TARGET}) diff --git a/Tests/comrpctester/CMakeLists.txt b/Tests/comrpctester/CMakeLists.txt index e6b7b9b39..e5ffd436c 100644 --- a/Tests/comrpctester/CMakeLists.txt +++ b/Tests/comrpctester/CMakeLists.txt @@ -28,5 +28,5 @@ set_target_properties(comrpctester PROPERTIES CXX_STANDARD_REQUIRED YES ) -install(TARGETS comrpctester DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS comrpctester DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/file-unlink/CMakeLists.txt b/Tests/file-unlink/CMakeLists.txt index c3b53a425..f69a34c27 100644 --- a/Tests/file-unlink/CMakeLists.txt +++ b/Tests/file-unlink/CMakeLists.txt @@ -29,6 +29,6 @@ set_target_properties(FileClient PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES ) -install(TARGETS FileClient DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(TARGETS FileMaster DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS FileClient DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) +install(TARGETS FileMaster DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/httpsclient/CMakeLists.txt b/Tests/httpsclient/CMakeLists.txt index d3f02a892..92f0485b8 100644 --- a/Tests/httpsclient/CMakeLists.txt +++ b/Tests/httpsclient/CMakeLists.txt @@ -16,4 +16,4 @@ target_link_libraries(httpsclient_test ${NAMESPACE}WebSocket ) -install(TARGETS httpsclient_test DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS httpsclient_test DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/loader/CMakeLists.txt b/Tests/loader/CMakeLists.txt index 1d9c450e9..ae1de7f01 100644 --- a/Tests/loader/CMakeLists.txt +++ b/Tests/loader/CMakeLists.txt @@ -31,5 +31,5 @@ set_target_properties(WPELibraryTestLoader PROPERTIES CXX_STANDARD_REQUIRED YES ) -install(TARGETS WPELibraryTestLoader DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS WPELibraryTestLoader DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/message-buffer/CMakeLists.txt b/Tests/message-buffer/CMakeLists.txt index df4e3ab7e..b33a86b12 100644 --- a/Tests/message-buffer/CMakeLists.txt +++ b/Tests/message-buffer/CMakeLists.txt @@ -31,4 +31,4 @@ set_target_properties(MessageBufferTest PROPERTIES CXX_STANDARD_REQUIRED YES ) -install(TARGETS MessageBufferTest DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS MessageBufferTest DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/redirect/CMakeLists.txt b/Tests/redirect/CMakeLists.txt index 9e3597d38..3bf47abd8 100644 --- a/Tests/redirect/CMakeLists.txt +++ b/Tests/redirect/CMakeLists.txt @@ -29,5 +29,5 @@ set_target_properties(redirect PROPERTIES SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") -install(TARGETS redirect DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS redirect DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index b95514eb4..6289a0ffc 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -116,14 +116,14 @@ target_link_libraries(${TEST_RUNNER_NAME} install( TARGETS ${TEST_RUNNER_NAME} - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) add_library(helloworld SHARED test_library_helloworld.cpp) install( TARGETS helloworld - DESTINATION ${CMAKE_INSTALL_LIBDIR}/testdata) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/testdata COMPONENT ${NAMESPACE}_Test) add_test(NAME ${TEST_RUNNER_NAME} COMMAND ${TEST_RUNNER_NAME}) diff --git a/Tests/unit/tests/CMakeLists.txt b/Tests/unit/tests/CMakeLists.txt index 2beab4a41..766c13346 100644 --- a/Tests/unit/tests/CMakeLists.txt +++ b/Tests/unit/tests/CMakeLists.txt @@ -33,6 +33,6 @@ target_link_libraries(${TEST_RUNNER_NAME} install( TARGETS ${TEST_RUNNER_NAME} - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) add_test(${TEST_RUNNER_NAME} ${TEST_RUNNER_NAME}) diff --git a/Tests/workerpool-test/CMakeLists.txt b/Tests/workerpool-test/CMakeLists.txt index 0e4346d8b..7c07f3360 100644 --- a/Tests/workerpool-test/CMakeLists.txt +++ b/Tests/workerpool-test/CMakeLists.txt @@ -10,4 +10,4 @@ target_link_libraries(WorkerPoolTest ${NAMESPACE}Core ) -install(TARGETS WorkerPoolTest DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS WorkerPoolTest DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${NAMESPACE}_Test) diff --git a/cmake/common/CmakeHelperFunctions.cmake b/cmake/common/CmakeHelperFunctions.cmake index d065de361..5490c8000 100644 --- a/cmake/common/CmakeHelperFunctions.cmake +++ b/cmake/common/CmakeHelperFunctions.cmake @@ -691,7 +691,7 @@ function(InstallCompatibleCMakeConfig) cmake_parse_arguments(Arg "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - if(Argument_UNPARSED_ARGUMENTS) + if(Arg_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown keywords given to InstallCMakeConfig(): \"${Arg_UNPARSED_ARGUMENTS}\".") endif() @@ -733,8 +733,8 @@ function(InstallCompatibleCMakeConfig) install( TARGETS ${Arg_LEGACY_TARGET} EXPORT ${Arg_LEGACY_TARGET}Targets - PUBLIC_HEADER DESTINATION ${Arg_LEGACY_PUBLIC_HEADER_LOCATION} COMPONENT devel - INCLUDES DESTINATION ${Arg_LEGACY_INCLUDE_DIR} # default include path + PUBLIC_HEADER DESTINATION ${Arg_LEGACY_PUBLIC_HEADER_LOCATION} COMPONENT ${NAMESPACE}_Development + INCLUDES DESTINATION ${Arg_LEGACY_INCLUDE_DIR} ) installcmakeconfig(TARGETS ${Arg_LEGACY_TARGET} EXTRA_DEPENDENCIES ${Arg_TARGET}) diff --git a/cmake/config.cmake b/cmake/config.cmake index 9c23ab604..1d33b66b3 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.7.0) +cmake_minimum_required(VERSION 3.15) get_property(is_included GLOBAL PROPERTY INCLUDE_GUARD) if(is_included) diff --git a/cmake/modules/FindGBM.cmake b/cmake/modules/FindGBM.cmake index c3d0ed650..7c12cd276 100644 --- a/cmake/modules/FindGBM.cmake +++ b/cmake/modules/FindGBM.cmake @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.15) # Be compatible even if a newer CMake version is available cmake_policy(VERSION 3.7...3.12) diff --git a/cmake/modules/FindLibCRUN.cmake b/cmake/modules/FindLibCRUN.cmake index 8c12bb630..16099a5a2 100644 --- a/cmake/modules/FindLibCRUN.cmake +++ b/cmake/modules/FindLibCRUN.cmake @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.15) # Be compatible even if a newer CMake version is available cmake_policy(VERSION 3.7...3.12) diff --git a/cmake/modules/FindMemcr.cmake b/cmake/modules/FindMemcr.cmake index 105c15706..39ec9e657 100644 --- a/cmake/modules/FindMemcr.cmake +++ b/cmake/modules/FindMemcr.cmake @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.15) # Be compatible even if a newer CMake version is available cmake_policy(VERSION 3.7...3.12) diff --git a/cmake/project.cmake.in b/cmake/project.cmake.in index 602111bc9..f567846da 100644 --- a/cmake/project.cmake.in +++ b/cmake/project.cmake.in @@ -35,6 +35,11 @@ macro(project_version) set(VERSION ${PROJECT_VERSION}) endmacro() +set(Thunder_VERSION_MAJOR @Thunder_VERSION_MAJOR@) +set(Thunder_VERSION_MINOR @Thunder_VERSION_MINOR@) +set(Thunder_VERSION_PATCH @Thunder_VERSION_PATCH@) +set(Thunder_VERSION @Thunder_VERSION@) + get_property(is_included GLOBAL PROPERTY INCLUDE_GUARD) if(is_included) return() @@ -78,6 +83,18 @@ if(NOT DEFINED LEGACY_CONFIG_GENERATOR) set(LEGACY_CONFIG_GENERATOR @LEGACY_CONFIG_GENERATOR@ CACHE INTERNAL "" FORCE) endif() +if(NOT DEFINED HUMAN_VERSIONED_BINARIES) + set(HUMAN_VERSIONED_BINARIES @HUMAN_VERSIONED_BINARIES@ CACHE INTERNAL "Create binaries with a human readable version suffix" FORCE) +endif() + +if(NOT DEFINED VERSIONED_LIBRARY_LOADING) + set(VERSIONED_LIBRARY_LOADING @VERSIONED_LIBRARY_LOADING@ CACHE INTERNAL "Uses the major version (*.so.) to load libraries rather then *.so" FORCE) +endif() + +if(VERSIONED_LIBRARY_LOADING) + add_definitions(-DVERSIONED_LIBRARY_LOADING) +endif() + set(CMAKE_BUILD_TYPE @CMAKE_BUILD_TYPE@ CACHE INTERNAL "" FORCE) # FIX_ME: Disable fortify source. diff --git a/docs/plugin/interfaces/interfaces.md b/docs/plugin/interfaces/interfaces.md index 5aa231b47..39af60faf 100644 --- a/docs/plugin/interfaces/interfaces.md +++ b/docs/plugin/interfaces/interfaces.md @@ -184,14 +184,14 @@ endif() # Install libs & headers string(TOLOWER ${NAMESPACE} NAMESPACE_LIB) install(TARGETS ExampleProxyStubs - EXPORT ExampleProxyStubsTargets # for downstream dependencies - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT libs # shared lib + EXPORT ExampleProxyStubsTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT ${NAMESPACE}_Runtime ) if(JSON_ENUM_SOURCES) install(TARGETS ExampleDefinitions - EXPORT ExampleDefinitionsTargets # for downstream dependencies - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ COMPONENT libs # shared lib + EXPORT ExampleDefinitionsTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ COMPONENT ${NAMESPACE}_Runtime ) endif() From 3274a16467c82d82a79a9aa9e89c1f09dcf35015 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:36:44 +0200 Subject: [PATCH 10/35] [core / Tests/unit/core] : Fix build 'test_valuerecorder'. (#1590) * [core / Tests/unit/core] : Fix build 'test_valuerecorder'. * [core / Tests/unit/core] : prepare 'test_value_recorder' for unpredictable failure. --------- Co-authored-by: Pierre Wielders --- Source/core/ValueRecorder.h | 2 +- Tests/unit/core/CMakeLists.txt | 2 +- Tests/unit/core/test_valuerecorder.cpp | 36 +++++++++++++++++--------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Source/core/ValueRecorder.h b/Source/core/ValueRecorder.h index 4b23708c4..ce7ef54e0 100644 --- a/Source/core/ValueRecorder.h +++ b/Source/core/ValueRecorder.h @@ -431,7 +431,7 @@ namespace Core { ASSERT((_storage[_index] & 0x80) == 0); // we need to loopback for another 0.. - while ((_storage[_index - 1] & 0x80) != 0) { + while (_index > 0 && (_storage[_index - 1] & 0x80) != 0) { result = (result << 7) | (_storage[_index] & 0x7F); _index--; stepBack++; diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index 6289a0ffc..3e4d1f3be 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -72,7 +72,7 @@ add_executable(${TEST_RUNNER_NAME} test_time.cpp test_timer.cpp test_tristate.cpp - #test_valuerecorder.cpp + test_valuerecorder.cpp test_weblinkjson.cpp test_weblinktext.cpp test_websocketjson.cpp diff --git a/Tests/unit/core/test_valuerecorder.cpp b/Tests/unit/core/test_valuerecorder.cpp index c0adeb507..ac939d8fe 100644 --- a/Tests/unit/core/test_valuerecorder.cpp +++ b/Tests/unit/core/test_valuerecorder.cpp @@ -47,11 +47,12 @@ class WriterClass : public RecorderType::Writer { uint8_t arr[] = {1,2,3}; SetBuffer(arr); - Create(_file); + auto object = Create(_file); Record(10); - Time(); - Source(); - Value(); + uint64_t TimeValue = Time(); + std::string storageName = Source(); + uint32_t value = Value(); + object.Release(); } private: @@ -82,14 +83,18 @@ class ReaderClass : public RecorderType::Reader public: void ReaderJob() { + Next(); + EXPECT_TRUE(IsValid()); + uint32_t time = 20; Core::Time curTime = Core::Time::Now(); curTime.Add(time); - Store(curTime.Ticks(), 1); + uint32_t index = Store(curTime.Ticks(), 1); StepForward(); StepBack(); ClearData(); + Reader obj1(_file, 1u); EXPECT_FALSE(obj1.Previous()); EXPECT_TRUE(obj1.Next()); @@ -101,8 +106,8 @@ class ReaderClass : public RecorderType::Reader else EXPECT_EQ(EndId(),2u); - EndId(); - Source(); + uint32_t id = EndId(); + std::string storageName = Source(); } private: @@ -112,12 +117,19 @@ class ReaderClass : public RecorderType::Reader TEST(test_valuerecorder, test_writer) { string filename = "baseRecorder.txt"; - WriterClass obj1(filename); - obj1.Copy(obj1,1); - obj1.Copy(obj1,100); - obj1.WriterJob(); + + auto obj1 = RecorderType::Writer::Create(filename); + + obj1->Copy(*(obj1),1); + obj1->Copy(*(obj1),100); + + static_cast(*obj1).WriterJob(); + ReaderClass obj2(filename); obj2.ReaderJob(); - ReaderClass obj3(ProxyType(obj1)); + + ReaderClass obj4(ProxyType(obj3)); + + obj1.Release(); } From 1f71a7236829f3b74a58016c854a2627b515d922 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:56:54 +0200 Subject: [PATCH 11/35] [Tests/unit/core] : Various improvements for 'test_dataelementfile' (#1641) --- Tests/unit/core/test_dataelementfile.cpp | 47 ++++++++++++++++++------ 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/Tests/unit/core/test_dataelementfile.cpp b/Tests/unit/core/test_dataelementfile.cpp index f4ec43e63..35a61980d 100644 --- a/Tests/unit/core/test_dataelementfile.cpp +++ b/Tests/unit/core/test_dataelementfile.cpp @@ -49,33 +49,58 @@ class DataFile: public Core::DataElementFile TEST(test_datafile, simple_test) { - char buffer[100]; const string fileName = "dataFile.txt"; - string message = ">echo 'DataElement file checking......'"; - snprintf(buffer,(message.size() + fileName.size()+1), "%s%s",message.c_str(),fileName.c_str()); - File file(fileName); + const string message = ">echo 'DataElement file checking......'"; + string buffer = message + fileName; - // Clear error no since it will be already set internally from - // the LoadInfo sequence with non existing file - EXPECT_EQ(file.ErrorCode(), unsigned(2)); +#ifdef __POSIX__ errno = 0; +#endif + + File file(fileName); + + ASSERT_FALSE(file.Exists()); - file.Create(true); + // Always for a non-existing file +#ifdef __WINDOWS__ + EXPECT_EQ(file.ErrorCode(), static_cast(ERROR_FILE_NOT_FOUND)); +#endif +#ifdef __POSIX__ + EXPECT_EQ(file.ErrorCode(), static_cast(ENOENT)); +#endif + + ASSERT_TRUE(file.Create(true)); EXPECT_EQ(file.IsOpen(), true); EXPECT_EQ(file.Name(), fileName); + +#ifdef __POSIX__ + errno = 0; +#endif + DataFile obj1(file); +#ifdef __WINDOWS__ + EXPECT_EQ(obj1.ErrorCode(), static_cast(ERROR_SUCCESS)); +#endif +#ifdef __POSIX__ + EXPECT_EQ(obj1.ErrorCode(), static_cast(0)); +#endif - EXPECT_EQ(obj1.ErrorCode(), unsigned(0)); DataFile object(fileName, 1, 10); DataFile obj2(fileName, 1, 50); + obj1.Sync(); obj2.MemoryMap(); const string& name = obj1.Name(); + EXPECT_EQ(name.c_str(), fileName); EXPECT_EQ(obj2.IsValid(), true); - obj1.Storage(); + + const File& obj1File = obj1.Storage(); + EXPECT_STREQ(obj1File.FileName().c_str(), file.FileName().c_str()); + obj1.ReloadFileInfo(); obj1.MemoryMap(); - file.Destroy(); + + EXPECT_TRUE(file.Destroy()); } From 3543989f7a9a817f668a008d55737afb491ee090 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Sat, 15 Jun 2024 09:18:18 +0200 Subject: [PATCH 12/35] Development/jsonparser (#1625) * [Tests/unit/core] : Fix build 'test_jsonparser'. * [core/JSON] : Opaque strings are opaque till the closing bracket. * Update JSON.h * Update JSON.h * Update CMakeLists.txt --------- Co-authored-by: Pierre Wielders --- Source/core/JSON.h | 15 +- Tests/unit/core/CMakeLists.txt | 4 +- Tests/unit/core/test_jsonparser.cpp | 538 ++++++++++++++++++++++++---- 3 files changed, 484 insertions(+), 73 deletions(-) diff --git a/Source/core/JSON.h b/Source/core/JSON.h index 4153a9f29..b91134e17 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -1973,7 +1973,7 @@ namespace Core { // We are assumed to be opaque, but all quoted string stuff is enclosed between quotes // and should be considered for scope counting. // Check if we are entering or leaving a quoted area in the opaque object - if ((current == '\"') && ((_value.empty() == true) || (_value[_value.length() - 2] != '\\'))) { + if ((current == '\"') && ((_value.empty() == true) || IsEscaped(_value))) { // This is not an "escaped" quote, so it should be considered a real quote. It means // we are now entering or leaving a quoted area within the opaque struct... _flagsAndCounters ^= QuotedAreaBit; @@ -2171,6 +2171,19 @@ namespace Core { } private: + bool IsEscaped(const string& value) const { + // This code determines if a lot of back slashes to esscape the backslash + // Is odd or even, so does it escape the last character.. + // e.g. 'Test \\\\\\\\\\"' is not the escaping of the quote (") + // 'Test \\\\\\\\\" continued"' is the escaping of th quote.. + // 'Test \" and \" and than \\\"' are all escaped quotes + uint32_t index = static_cast(value.length() - 1); + uint32_t start = index; + while ( (index != static_cast(~0)) && (value[index] == '\\') ) { + index--; + } + return (((start - index) % 2) == 0); + } bool InScope(const ScopeBracket mode) { bool added = false; uint8_t depth = (_flagsAndCounters & 0x1F); diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index 3e4d1f3be..34e548504 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -36,7 +36,7 @@ add_executable(${TEST_RUNNER_NAME} test_ipc.cpp test_iso639.cpp test_iterator.cpp - #test_jsonparser.cpp + test_jsonparser.cpp test_keyvalue.cpp test_library.cpp test_lockablecontainer.cpp @@ -72,7 +72,7 @@ add_executable(${TEST_RUNNER_NAME} test_time.cpp test_timer.cpp test_tristate.cpp - test_valuerecorder.cpp + # test_valuerecorder.cpp test_weblinkjson.cpp test_weblinktext.cpp test_websocketjson.cpp diff --git a/Tests/unit/core/test_jsonparser.cpp b/Tests/unit/core/test_jsonparser.cpp index fe00cc295..684a33090 100644 --- a/Tests/unit/core/test_jsonparser.cpp +++ b/Tests/unit/core/test_jsonparser.cpp @@ -24,7 +24,8 @@ #include "../IPTestAdministrator.h" #include -#include "JSON.h" + +#include namespace Thunder { enum class JSONTestEnum { @@ -625,9 +626,7 @@ namespace Tests { }); } - // FIXME: Disabled because JSON Parser does not support exponential notation - // yet is supports hex so 'E' or 'e' in number is interpreted as hex. - TEST(JSONParser, ExponentialNumber) + TEST(JSONParser, DISABLED_ExponentialNumber) { TestData data; data.key = "key"; @@ -651,7 +650,16 @@ namespace Tests { value << v.Value(); std::string res = value.str(); res += 'f'; - EXPECT_EQ(data.value, res.c_str()); + + float a = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float b = std::strtof(res.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(a, b); + EXPECT_FLOAT_EQ(c, b); }); } @@ -665,7 +673,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -679,7 +693,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -693,7 +713,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -707,7 +733,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -721,7 +753,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -735,7 +773,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -749,7 +793,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -763,7 +813,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -777,7 +833,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Float& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + float b = std::strtof(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + float c = std::strtof(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_FLOAT_EQ(b, c); }); } @@ -791,7 +853,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -805,7 +873,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -819,7 +893,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -833,7 +913,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -847,7 +933,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -861,7 +953,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -875,7 +973,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -889,7 +993,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -903,7 +1013,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -917,7 +1033,13 @@ namespace Tests { ExecutePrimitiveJsonTest(data, true, [data](const Core::JSON::Double& v) { std::ostringstream value; value << v.Value(); - EXPECT_EQ(data.value, value.str().c_str()); + + double b = std::strtod(value.str().c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + double c = std::strtod(data.value.c_str(), nullptr); + ASSERT_NE(errno, ERANGE); + + EXPECT_DOUBLE_EQ(b, c); }); } @@ -926,10 +1048,23 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference data.value = "\n solution \n for \n string \n serialization\n"; - data.valueToPutInJson = "\"" + data.value + "\""; - ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + + const string valueJSONFormatted("\\n solution \\n for \\n string \\n serialization\\n"); + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings + ExecutePrimitiveJsonTest(data, true, [&data, &valueJSONFormatted](const Core::JSON::String& v) { + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -938,10 +1073,24 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference data.value = "\' solution \n for \n string \n serialization\'\n"; - data.valueToPutInJson = "\"" + data.value + "\""; + + const string valueJSONFormatted = "\' solution \\n for \\n string \\n serialization\'\\n"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -950,10 +1099,24 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference data.value = "\" solution \n for \n string \n serialization\"\n"; - data.valueToPutInJson = "\"" + data.value + "\""; + + const string valueJSONFormatted = "\\\" solution \\n for \\n string \\n serialization\\\"\\n"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -962,10 +1125,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape, \? is equivalent to ? data.value = "Is this a solution \?"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \? equals 0x3F + const string valueJSONFormatted = "Is this a solution \?"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -974,10 +1152,24 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape, \\ to represent a single one data.value = "Checking backslash \\"; - data.valueToPutInJson = "\"" + data.value + "\""; + + const string valueJSONFormatted = "Checking backslash \\\\"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -986,10 +1178,26 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; - data.value = "Checking audible bell \a"; - data.valueToPutInJson = "\"" + data.value + "\""; - ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + + // Reference, with C-style escape; \a equals 0x07 and could be represented by a 2 character escape sequence, but non are defined in the specification; use unicode instead \u0007 +// data.value = "Checking audible bell \a"; + data.value = "Checking audible bell \\u0007"; + + const string valueExpected = "Checking audible bell \a"; + const string valueJSONFormatted = "Checking audible bell \\u0007"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings + ExecutePrimitiveJsonTest(data, true, [&data, &valueExpected](const Core::JSON::String& v) { + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(valueExpected.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -998,10 +1206,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "Checking backspace \b"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \b equals 0x08 and could be represented by a 2 character escape sequence defined in the specification; use \\b + const string valueJSONFormatted = "Checking backspace \\b"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1010,10 +1233,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "Checking form feed \f"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \f equals 0x0C and could be represented by a 2 character escape sequence defined in the specification; use \\c + const string valueJSONFormatted = "Checking form feed \\f"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1022,10 +1260,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "Checking line feed \n"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \n equals 0x0A and could be represented by a 2 character escape sequence defined in the specification; use \\n + const string valueJSONFormatted = "Checking line feed \\n"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1034,10 +1287,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "Checking carriage return \r"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \r equals 0x0C and could be represented by a 2 character escape sequence defined in the specification; use \\r + const string valueJSONFormatted = "Checking carriage return \\r"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1046,10 +1314,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "Checking horizontal tab \t"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \t equals 0x09 and could be represented by a 2 character escape sequence defined in the specification; use \\t + const string valueJSONFormatted = "Checking horizontal tab \\t"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1058,10 +1341,26 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; - data.value = "Checking vertical tab \v"; - data.valueToPutInJson = "\"" + data.value + "\""; - ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + + // Reference, with C-style escape; \v equals 0x0B and could be represented by a 2 character escape sequence, but non are defined in the specification; use unicode instead \u000B +// data.value = "Checking vertical tab \v"; + data.value = "Checking vertical tab \\u000B"; + + const string valueExpected = "Checking vertical tab \v"; + const string valueJSONFormatted = "Checking vertical tab \\u000B"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings + ExecutePrimitiveJsonTest(data, true, [&data, &valueExpected](const Core::JSON::String& v) { + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(valueExpected.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1070,13 +1369,17 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style raw string, no difference with regular string; invalid unicode character sequence data.value = R"(value\\uZZZZ)"; - data.valueToPutInJson = "\"" + data.value + "\""; - ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - Core::JSON::String value; - value.FromString(data.valueToPutInJson); - EXPECT_EQ(value.Value(), v.Value()); + const string valueJSONFormatted = "value\\uZZZZ"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings + ExecutePrimitiveJsonTest(data, false, [&data](const Core::JSON::String& v) { + EXPECT_EQ(string{}, v.Value()); }); } @@ -1085,10 +1388,24 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "\n solution \n for \n string \n serialization\n"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \n equals 0x0A and could be represented by a 2 character escape sequence defined in the specification; use \\n + const string valueJSONFormatted = "\\n solution \\n for \\n string \\n serialization\\n"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); }); } @@ -1097,10 +1414,25 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "\t solution \t for \t string \t serialization\t"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \t equals 0x09 and could be represented by a 2 character escape sequence defined in the specification; use \\t + const string valueJSONFormatted = "\\t solution \\t for \\t string \\t serialization\\t"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1109,10 +1441,26 @@ namespace Tests { TestData data; data.key = "teststring"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escape data.value = "\n solution \t for \r string \t serialization\n"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // \r equals 0x0C and could be represented by a 2 character escape sequence defined in the specification; use \\r + // \t equals 0x09 and could be represented by a 2 character escape sequence defined in the specification; use \\t + // \n equals 0x0A and could be represented by a 2 character escape sequence defined in the specification; use \\n + const string valueJSONFormatted = "\\n solution \\t for \\r string \\t serialization\\n"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { - EXPECT_EQ(data.value, v.Value()); + ASSERT_TRUE(v.IsQuoted()); + + string value; + v.ToString(value); + + // Value() returns the undecorated string! + ASSERT_STREQ(data.value.c_str(), v.Value().c_str()); + ASSERT_STREQ(data.valueToPutInJson.c_str(), value.c_str()); }); } @@ -1121,8 +1469,16 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference; JSON formatted style data.value = "value\\z"; - data.valueToPutInJson = "\"" + data.value + "\""; + + // Standard does not define 2-character escaped sequence + const string valueJSONFormatted = "value\\z"; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, false, [](const Core::JSON::String& v) { EXPECT_EQ(string{}, v.Value()); }); @@ -1133,8 +1489,16 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + + // Reference, with C-style escapes; unicode interpreted by C++-standard data.value = "value \"\b\n\f\r\u00b1/\""; - data.valueToPutInJson = "\"" + data.value + "\""; + + // Unescaped control characters, solidus, and, unicode + const string valueJSONFormatted = "value \"\b\n\f\r\u00b1/\""; + + data.valueToPutInJson = "\"" + valueJSONFormatted + "\""; + + // Key and value in container are both JSON strings ExecutePrimitiveJsonTest(data, false, [] (const Core::JSON::String& v) { EXPECT_EQ(string{}, v.Value()); }); @@ -1145,8 +1509,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "value"; + data.valueToPutInJson = "{\"" + data.key + "\":\"" + data.value + "\"}"; + ExecutePrimitiveJsonTest>(data, true, [&data](const PrimitiveJson& v) { EXPECT_TRUE(v.HasLabel(data.key)); EXPECT_EQ(data.value, v.Value().Value()); @@ -1158,7 +1525,9 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.valueToPutInJson = "{\"" + data.key + "\":\"" + data.value + "\"}"; + ExecutePrimitiveJsonTest>(data, true, [&data](const PrimitiveJson& v) { EXPECT_TRUE(v.HasLabel(data.key)); EXPECT_EQ(string{}, v.Value().Value()); @@ -1170,8 +1539,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "null"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest>(data, true, [](const PrimitiveJson& v) { EXPECT_TRUE(v.IsNull()); }); @@ -1182,8 +1554,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "nill"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest>(data, false, nullptr); } @@ -1192,8 +1567,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "\"" + data.key + "\":\"value\""; + data.valueToPutInJson = "[" + data.value + "}"; + ExecutePrimitiveJsonTest>(data, false, nullptr); } @@ -1213,8 +1591,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "nill"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest(data, false, nullptr); } @@ -1223,8 +1604,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "{\"" + data.key + "\":{\"key2\":[\"value\"]}}"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest(data, true, [&data](const Core::JSON::String& v) { EXPECT_EQ(data.value, v.Value()); }); @@ -1235,11 +1619,14 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "{\"" + data.key + "\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":" "{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":" "{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":{\"key2\":" "{\"key2\":{\"key2\":{\"key2\":{\"key2\":\"value\"}}}}}}}}}}}}}}}}}}}}}}}}}"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest(data, true, nullptr); } @@ -1248,8 +1635,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "{\"" + data.key + "\":{\"key2\":[\"value\"]"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest(data, false, [](const Core::JSON::String& v) { EXPECT_EQ(string{}, v.Value()); }); @@ -1260,8 +1650,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "{\"" + data.key + "\":{\"key2\":[\"value\"}}}"; + data.valueToPutInJson = data.value; + ExecutePrimitiveJsonTest(data, false, [](const Core::JSON::String& v) { EXPECT_EQ(string{}, v.Value()); }); @@ -1272,8 +1665,11 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "enum_2"; + data.valueToPutInJson = "\"" + data.value + "\""; + ExecutePrimitiveJsonTest>(data, true, [&data](const Core::JSON::EnumType& v) { EXPECT_EQ(JSONTestEnum::ENUM_2, v.Value()); }); @@ -1284,11 +1680,14 @@ namespace Tests { TestData data; data.key = "key"; data.keyToPutInJson = "\"" + data.key + "\""; + data.value = "enum_5"; + data.valueToPutInJson = "\"" + data.value + "\""; + ExecutePrimitiveJsonTest>(data, false, nullptr); } - +#ifdef _0 TEST(JSONParser, Variant) { Thunder::Core::JSON::Variant variant; @@ -1530,7 +1929,7 @@ namespace Tests { it.Reset(); EXPECT_FALSE(it.IsValid()); } - +#endif TEST(JSONParser, simpleSet) { { @@ -1586,7 +1985,7 @@ namespace Tests { json.FromString(input); json.ToString(received); - EXPECT_EQ(string{}, received.c_str()); + EXPECT_STREQ("\"\"", received.c_str()); } } @@ -1957,7 +2356,6 @@ namespace Tests { printf("input %zd --- = %s \n", input.length(), input.c_str()); printf("output %zd --- = %s \n", output.length(), output.c_str()); EXPECT_STREQ(input.c_str(), output.c_str()); - input = R"({"jsonrpc":"2.0","id":1234567890,"method":"hPho\\ne","params":{"ssid":"iPh\one"}})"; command.FromString(input); command.ToString(output); From e911ac43aa6fdf8a767cfbe5c04088116876b4c5 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Sat, 15 Jun 2024 10:37:19 +0200 Subject: [PATCH 13/35] Devopment/refine cmake (#1644) * scripts: Generate udev rules from cmake * scripts: Use more standard variables * cmake: Let cmake compute file paths --------- Co-authored-by: Pierre Wielders --- CMakeLists.txt | 2 +- Source/Thunder/CMakeLists.txt | 2 +- Source/Thunder/GenericConfig.cmake | 12 ++++---- Source/Thunder/scripts/CMakeLists.txt | 30 +++++++++++++++++-- .../scripts/set-subsystem-group-udev.rules.in | 1 + Source/Thunder/scripts/thunder.in | 12 ++++---- Source/Thunder/scripts/thunder.service.in | 8 ++--- 7 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 Source/Thunder/scripts/set-subsystem-group-udev.rules.in diff --git a/CMakeLists.txt b/CMakeLists.txt index fa3fe667e..60e03e706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ if(APPLE) set(CMAKE_MACOSX_RPATH ON) set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() diff --git a/Source/Thunder/CMakeLists.txt b/Source/Thunder/CMakeLists.txt index 6ed4a9a4d..f993a1b06 100644 --- a/Source/Thunder/CMakeLists.txt +++ b/Source/Thunder/CMakeLists.txt @@ -110,7 +110,7 @@ install( ) install(DIRECTORY - DESTINATION ${CMAKE_INSTALL_PREFIX}/../${PERSISTENT_PATH}/${NAMESPACE}} + DESTINATION ${PERSISTENT_PATH}/${NAMESPACE}} COMPONENT ${NAMESPACE}_Runtime DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE ) diff --git a/Source/Thunder/GenericConfig.cmake b/Source/Thunder/GenericConfig.cmake index c7714bb5a..8edc2783b 100644 --- a/Source/Thunder/GenericConfig.cmake +++ b/Source/Thunder/GenericConfig.cmake @@ -24,18 +24,18 @@ set(IDLE_TIME 180 CACHE STRING "Idle time") set(SOFT_KILL_CHECK_WAIT_TIME 10 CACHE STRING "Soft kill check waiting time") set(HARD_KILL_CHECK_WAIT_TIME 4 CACHE STRING "Hard kill check waiting time") set(PERSISTENT_PATH "/root" CACHE STRING "Persistent path") -set(DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/${NAMESPACE}" CACHE STRING "Data path") -set(SYSTEM_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/plugins" CACHE STRING "System path") +set(DATA_PATH "${CMAKE_INSTALL_FULL_DATAROOTDIR}/${NAMESPACE}" CACHE STRING "Data path") +set(SYSTEM_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/plugins" CACHE STRING "System path") set(WEBSERVER_PATH "/boot/www" CACHE STRING "Root path for the HTTP server") set(WEBSERVER_PORT 8080 CACHE STRING "Port for the HTTP server") -set(PROXYSTUB_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs" CACHE STRING "Proxy stub path") +set(PROXYSTUB_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/proxystubs" CACHE STRING "Proxy stub path") set(POSTMORTEM_PATH "/opt/minidumps" CACHE STRING "Core file path to do the postmortem of the crash") set(MESSAGECONTROL_PATH "MessageDispatcher" CACHE STRING "MessageControl base path to create message files") set(MESSAGING_PORT 0 CACHE STRING "The port for the messaging") set(MESSAGING_STDOUT false CACHE STRING "Enable message rederict from stdout") set(MESSAGING_STDERR false CACHE STRING "Enable message rederict from stderr") set(MESSAGING_DATASIZE 20480 CACHE STRING "Size of the data buffer in bytes [max 63KB]") -set(CONFIG_INSTALL_PATH "/etc/${NAMESPACE}" CACHE STRING "Install location of the configuration") +set(CONFIG_INSTALL_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${NAMESPACE}" CACHE STRING "Install location of the configuration") set(IPV6_SUPPORT false CACHE STRING "Controls if should application supports ipv6") set(LEGACY_INITIALZE false CACHE STRING "Enables legacy Plugin Initialize behaviour (Deinit not called on failed Init)") set(PRIORITY 0 CACHE STRING "Change the nice level [-20 - 20]") @@ -284,7 +284,7 @@ json_write("${CMAKE_BINARY_DIR}/Config.json" ${CONFIG}) install( FILES ${CMAKE_BINARY_DIR}/Config.json - DESTINATION ../${CMAKE_INSTALL_SYSCONFDIR}/${NAMESPACE}/ + DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/${NAMESPACE}/ RENAME config.json COMPONENT ${NAMESPACE}_Runtime) else() @@ -295,7 +295,7 @@ else() SKIP_CLASSNAME SKIP_LOCATOR CUSTOM_PARAMS_WHITELIST "${CMAKE_CURRENT_LIST_DIR}/params.config" - INSTALL_PATH "../${CMAKE_INSTALL_SYSCONFDIR}/${NAMESPACE}/" + INSTALL_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${NAMESPACE}/" INSTALL_NAME "config.json" PLUGINS "Thunder" ) diff --git a/Source/Thunder/scripts/CMakeLists.txt b/Source/Thunder/scripts/CMakeLists.txt index 3a1fc61c5..774463098 100644 --- a/Source/Thunder/scripts/CMakeLists.txt +++ b/Source/Thunder/scripts/CMakeLists.txt @@ -17,6 +17,7 @@ option(SYSTEMD_SERVICE "Install the systemd service" OFF) option(INITV_SCRIPT "Install the initv script" ON) +option(UDEV_VIDEO_RULE "Install the a thunder tailored udev rule to access the video device" OFF) if (SYSTEMD_SERVICE) set(SYSTEMD_EXTRA_DEPENDS "" CACHE STRING "Adds extra dependecies to the systemd service") @@ -26,7 +27,7 @@ if (SYSTEMD_SERVICE) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/thunder.service PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - DESTINATION ${CMAKE_INSTALL_PREFIX}/../${SYSTEMD_INSTALL_PATH}/system/ + DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/systemd/system/ COMPONENT ${NAMESPACE}_Runtime ) @@ -43,8 +44,33 @@ if (INITV_SCRIPT) FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/thunder PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ RENAME S${SYSV_INIT_LEVEL}thunder - DESTINATION ../${CMAKE_INSTALL_SYSCONFDIR}/init.d/ + DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/init.d/ COMPONENT ${NAMESPACE}_Runtime ) endif() +if (UDEV_VIDEO_RULE) + set(PLATFORM_UDEV_VIDEO_LEVEL "20" CACHE STRING "Level of the udev rule") + set(PLATFORM_VIDEO_SUBSYSTEM "" CACHE STRING "Subsystem to set the video group to be set on") + set(PLATFORM_VIDEO_DEVICE_GROUP "" CACHE STRING "Group name that needs access to the video device") + + if(NOT "${PLATFORM_VIDEO_SUBSYSTEM}" STREQUAL "" AND NOT "${PLATFORM_VIDEO_DEVICE_GROUP}" STREQUAL "") + set(UDEV_RULE_SUBSYSTEM "${PLATFORM_VIDEO_SUBSYSTEM}") + set(UDEV_RULE_GROUP "${PLATFORM_VIDEO_DEVICE_GROUP}") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/set-subsystem-group-udev.rules.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/video-device-udev.rules" @ONLY) + + unset(UDEV_RULE_SUBSYSTEM) + unset(UDEV_RULE_GROUP) + + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/video-device-udev.rules + PERMISSIONS OWNER_WRITE OWNER_READ + RENAME ${PLATFORM_UDEV_VIDEO_LEVEL}-thunder-video-device-udev.rules + DESTINATION ${CMAKE_INSTALL_LIBDIR}/udev/rules.d + COMPONENT ${NAMESPACE}_Runtime + ) + else() + message(SEND_ERROR "Udev video device rule is enabled, but there is missing information.") + endif() +endif() \ No newline at end of file diff --git a/Source/Thunder/scripts/set-subsystem-group-udev.rules.in b/Source/Thunder/scripts/set-subsystem-group-udev.rules.in new file mode 100644 index 000000000..a8d536a91 --- /dev/null +++ b/Source/Thunder/scripts/set-subsystem-group-udev.rules.in @@ -0,0 +1 @@ +SUBSYSTEM == "@UDEV_RULE_SUBSYSTEM@", GROUP = "@UDEV_RULE_GROUP@", MODE = "0660" diff --git a/Source/Thunder/scripts/thunder.in b/Source/Thunder/scripts/thunder.in index 2f3531c86..d6eaf25b4 100755 --- a/Source/Thunder/scripts/thunder.in +++ b/Source/Thunder/scripts/thunder.in @@ -10,21 +10,21 @@ start() { if [ ! -d @ROOT_PATH@/Netflix/dpi ]; then mkdir -p @ROOT_PATH@/Netflix/dpi - ln -sfn /etc/playready @ROOT_PATH@/Netflix/dpi/playready + ln -sfn @CMAKE_INSTALL_FULL_SYSCONFDIR@/playready @ROOT_PATH@/Netflix/dpi/playready fi - # needed for wayland/westeros/weston - export XDG_RUNTIME_DIR=/tmp +# needed for wayland/westeros/weston + export XDG_RUNTIME_DIR=@CMAKE_INSTALL_FULL_RUNSTATEDIR@ echo -n "Starting Thunder: " - start-stop-daemon -S -q -b -m -p /var/run/Thunder.pid --exec /usr/bin/Thunder -- -b /dev/null 2>&1 + start-stop-daemon -S -q -b -m -p @CMAKE_INSTALL_FULL_RUNSTATEDIR@/Thunder.pid --exec @CMAKE_INSTALL_FULL_BINDIR@/Thunder -- -b /dev/null 2>&1 [ $? == 0 ] && echo "OK" || echo "FAIL" } stop() { echo -n "Stopping Thunder: " - start-stop-daemon -K -q -p /var/run/Thunder.pid + start-stop-daemon -K -q -p @CMAKE_INSTALL_FULL_RUNSTATEDIR@/Thunder.pid [ $? == 0 ] && echo "OK" || echo "FAIL" - rm -rf /var/run/Thunder.pid + rm -rf @CMAKE_INSTALL_FULL_RUNSTATEDIR@/Thunder.pid } restart() { stop diff --git a/Source/Thunder/scripts/thunder.service.in b/Source/Thunder/scripts/thunder.service.in index 1ac92dc3a..aac75bfb4 100755 --- a/Source/Thunder/scripts/thunder.service.in +++ b/Source/Thunder/scripts/thunder.service.in @@ -4,11 +4,11 @@ Wants=multi-user.target After=multi-user.target @EXTRA_DEPENDS@ [Service] -PIDFile=/var/run/Thunder.pid -EnvironmentFile=-/etc/thunder/Thunder.env +PIDFile=@CMAKE_INSTALL_FULL_RUNSTATEDIR@/Thunder.pid +EnvironmentFile=-@CMAKE_INSTALL_FULL_SYSCONFDIR@/Thunder/Thunder.env Environment="WAYLAND_DISPLAY=wayland-0" -Environment="XDG_RUNTIME_DIR=/run" -ExecStart=-/usr/bin/Thunder -b +Environment="XDG_RUNTIME_DIR=@CMAKE_INSTALL_FULL_RUNSTATEDIR@" +ExecStart=-@CMAKE_INSTALL_FULL_BINDIR@/Thunder -b ExecStop=/bin/kill $MAINPID [Install] From 8a3fe02b8a9f3ff7c3672942d2ee906115420956 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Sun, 16 Jun 2024 11:24:10 +0200 Subject: [PATCH 14/35] Revert "[core / Tests/unit/core] : Fix build 'test_messageException'" (#1645) * Revert "[core / Tests/unit/core] : Fix build 'test_messageException' (#1589)" This reverts commit e1b416eee5b057a8ffe5acfd68dfda04ad4f30eb. * [WINDOWS] Try it to get it building on Windows again :-) * [CMAKE] Fun with CMake.... * [R5] Cleanup legacy stuff --- CMakeLists.txt | 5 +++ Source/Thunder/CMakeLists.txt | 5 +-- Source/Thunder/Module.h | 2 -- Source/Thunder/PluginHost.cpp | 2 +- Source/Thunder/PluginServer.h | 6 ++-- Source/Thunder/SystemInfo.cpp | 2 +- Source/Thunder/Version.h.in | 14 --------- Source/ThunderPlugin/CMakeLists.txt | 4 +-- Source/com/CMakeLists.txt | 4 +-- Source/core/CMakeLists.txt | 6 ++-- Source/core/MessageException.cpp | 4 +-- Source/core/MessageException.h | 6 ++-- Source/core/Version.h.in | 13 +++++++- Source/cryptalgo/CMakeLists.txt | 4 +-- Source/extensions/hibernate/CMakeLists.txt | 6 ++-- .../processcontainers/CMakeLists.txt | 4 +-- .../warningreporting/CMakeLists.txt | 4 +-- Source/messaging/CMakeLists.txt | 4 +-- Source/plugins/CMakeLists.txt | 8 ++--- Source/tracing/tracing.h | 20 ------------ Source/websocket/CMakeLists.txt | 4 +-- Tests/unit/core/CMakeLists.txt | 2 +- Tests/unit/core/test_messageException.cpp | 31 +++++++++++-------- 23 files changed, 71 insertions(+), 89 deletions(-) delete mode 100644 Source/Thunder/Version.h.in delete mode 100644 Source/tracing/tracing.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 60e03e706..26b00f485 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,11 @@ project(Thunder DESCRIPTION "Thunder framework" HOMEPAGE_URL "https://rdkcentral.github.io/Thunder/") +set(VERSION ${${PROJECT_NAME}_VERSION}) +set(VERSION_MAJOR ${${PROJECT_NAME}_VERSION_MAJOR}) +set(VERSION_MINOR ${${PROJECT_NAME}_VERSION_MINOR}) +set(VERSION_PATCH ${${PROJECT_NAME}_VERSION_PATCH}) + string(TIMESTAMP BUILD_TIMESTAMP UTC) message(STATUS "Setting up ${PROJECT_NAME} v${Thunder_VERSION}") diff --git a/Source/Thunder/CMakeLists.txt b/Source/Thunder/CMakeLists.txt index f993a1b06..e0be6eb13 100644 --- a/Source/Thunder/CMakeLists.txt +++ b/Source/Thunder/CMakeLists.txt @@ -40,9 +40,6 @@ target_compile_definitions(${TARGET} target_compile_options (${TARGET} PRIVATE -Wno-psabi) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/version/version.h" @ONLY) -message(STATUS "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/version/version.h") - if (TREE_REFERENCE) target_compile_definitions(${TARGET} PRIVATE @@ -98,7 +95,7 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) install( diff --git a/Source/Thunder/Module.h b/Source/Thunder/Module.h index 7f397cab5..f95bf5b3c 100644 --- a/Source/Thunder/Module.h +++ b/Source/Thunder/Module.h @@ -37,7 +37,5 @@ #define TREE_REFERENCE engineering_build_for_debug_purpose_only #endif -#include - #undef EXTERNAL #define EXTERNAL diff --git a/Source/Thunder/PluginHost.cpp b/Source/Thunder/PluginHost.cpp index 76e4666f8..0ddb48b89 100644 --- a/Source/Thunder/PluginHost.cpp +++ b/Source/Thunder/PluginHost.cpp @@ -651,7 +651,7 @@ POP_WARNING() SYSLOG(Logging::Startup, (_T("Process Id: %d"), Core::ProcessInfo().Id())); SYSLOG(Logging::Startup, (_T("Tree ref: " _T(EXPAND_AND_QUOTE(TREE_REFERENCE))))); SYSLOG(Logging::Startup, (_T("Build ref: " _T(EXPAND_AND_QUOTE(BUILD_REFERENCE))))); - SYSLOG(Logging::Startup, (_T("Version: %d:%d:%d"), PluginHost::Major, PluginHost::Minor, PluginHost::Minor)); + SYSLOG(Logging::Startup, (_T("Version: %d:%d:%d"), Versioning::Major, Versioning::Minor, Versioning::Minor)); if (_config->MessagingCategoriesFile() == false) { SYSLOG(Logging::Startup, (_T("Messages [INT]: %s"), options.configFile)); } diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 3f57027a3..6f92ea2d4 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -4415,9 +4415,9 @@ namespace PluginHost { } inline void Metadata(PluginHost::Metadata::Version& data) const { - data.Major = PluginHost::Major; - data.Minor = PluginHost::Minor; - data.Patch = PluginHost::Patch; + data.Major = Versioning::Major; + data.Minor = Versioning::Minor; + data.Patch = Versioning::Patch; data.Hash = string(Core::System::ModuleBuildRef()); } inline void Metadata(Core::JSON::ArrayType& data) const diff --git a/Source/Thunder/SystemInfo.cpp b/Source/Thunder/SystemInfo.cpp index 3541436d8..6a56272f9 100644 --- a/Source/Thunder/SystemInfo.cpp +++ b/Source/Thunder/SystemInfo.cpp @@ -271,7 +271,7 @@ POP_WARNING() string SystemInfo::Version() const /* override */ { - return (Core::Format(_T("%d.%d.%d"), PluginHost::Major, PluginHost::Minor, PluginHost::Patch)); + return (Core::Format(_T("%d.%d.%d"), Versioning::Major, Versioning::Minor, Versioning::Patch)); } } //namspace Plugin diff --git a/Source/Thunder/Version.h.in b/Source/Thunder/Version.h.in deleted file mode 100644 index a5ad9d527..000000000 --- a/Source/Thunder/Version.h.in +++ /dev/null @@ -1,14 +0,0 @@ -/*** - * DO NOT EDIT, THIS FILE IS GENERATED @ @BUILD_TIMESTAMP@ - */ - -#pragma once - -namespace Thunder -{ - namespace PluginHost { - static constexpr uint8_t Major = @Thunder_VERSION_MAJOR@; - static constexpr uint8_t Minor = @Thunder_VERSION_MINOR@; - static constexpr uint8_t Patch = @Thunder_VERSION_PATCH@; - } -} diff --git a/Source/ThunderPlugin/CMakeLists.txt b/Source/ThunderPlugin/CMakeLists.txt index 1b3dbc86b..269d4086d 100644 --- a/Source/ThunderPlugin/CMakeLists.txt +++ b/Source/ThunderPlugin/CMakeLists.txt @@ -63,12 +63,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/com/CMakeLists.txt b/Source/com/CMakeLists.txt index fd3cacf1b..7a12f2b73 100644 --- a/Source/com/CMakeLists.txt +++ b/Source/com/CMakeLists.txt @@ -86,12 +86,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index 08985df25..f31b83c0d 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -27,7 +27,7 @@ message(STATUS "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h") add_library(${TARGET} Module.cpp - DoorBell.cpp + DoorBell.cpp CyclicBuffer.cpp DataElement.cpp DataElementFile.cpp @@ -230,12 +230,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/core/MessageException.cpp b/Source/core/MessageException.cpp index c776cf59a..1be7b1420 100644 --- a/Source/core/MessageException.cpp +++ b/Source/core/MessageException.cpp @@ -36,11 +36,11 @@ PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) } POP_WARNING() - MessageException::~MessageException() noexcept(true) + MessageException::~MessageException() throw() { } - const TCHAR* MessageException::Message() const noexcept(true) + const TCHAR* MessageException::Message() const throw() { return m_Message.c_str(); } diff --git a/Source/core/MessageException.h b/Source/core/MessageException.h index 023adc368..ca5ff0997 100644 --- a/Source/core/MessageException.h +++ b/Source/core/MessageException.h @@ -29,15 +29,15 @@ namespace Thunder { namespace Core { - class EXTERNAL MessageException : public std::exception { + class MessageException : public std::exception { private: MessageException(); public: - MessageException(const string& message, bool inclSysMsg = false) noexcept(true); + MessageException(const string& message, bool inclSysMsg = false) throw(); ~MessageException() throw(); - const TCHAR* Message() const noexcept(true); + const TCHAR* Message() const throw(); private: string m_Message; // Exception message diff --git a/Source/core/Version.h.in b/Source/core/Version.h.in index f81def4d3..8543abb5c 100644 --- a/Source/core/Version.h.in +++ b/Source/core/Version.h.in @@ -4,4 +4,15 @@ #pragma once -#define THUNDER_VERSION @Thunder_VERSION_MAJOR@ +#include + +#define THUNDER_VERSION @VERSION_MAJOR@ + +namespace Thunder +{ + namespace Versioning { + static constexpr uint8_t Major = @VERSION_MAJOR@; + static constexpr uint8_t Minor = @VERSION_MINOR@; + static constexpr uint8_t Patch = @VERSION_PATCH@; + } +} diff --git a/Source/cryptalgo/CMakeLists.txt b/Source/cryptalgo/CMakeLists.txt index c636d3ff4..eb42f04f6 100644 --- a/Source/cryptalgo/CMakeLists.txt +++ b/Source/cryptalgo/CMakeLists.txt @@ -68,12 +68,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/extensions/hibernate/CMakeLists.txt b/Source/extensions/hibernate/CMakeLists.txt index 000380f39..1b9d441d2 100644 --- a/Source/extensions/hibernate/CMakeLists.txt +++ b/Source/extensions/hibernate/CMakeLists.txt @@ -38,12 +38,12 @@ set(PUBLIC_HEADERS set_target_properties(${TARGET} PROPERTIES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() @@ -70,4 +70,4 @@ InstallCMakeConfig( InstallPackageConfig( TARGETS ${TARGET} - DESCRIPTION "Enable ease of development for Hibernate support." ) \ No newline at end of file + DESCRIPTION "Enable ease of development for Hibernate support." ) diff --git a/Source/extensions/processcontainers/CMakeLists.txt b/Source/extensions/processcontainers/CMakeLists.txt index 513b4bb66..3dda39751 100644 --- a/Source/extensions/processcontainers/CMakeLists.txt +++ b/Source/extensions/processcontainers/CMakeLists.txt @@ -76,12 +76,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/extensions/warningreporting/CMakeLists.txt b/Source/extensions/warningreporting/CMakeLists.txt index fd2900c9d..4e751ac72 100644 --- a/Source/extensions/warningreporting/CMakeLists.txt +++ b/Source/extensions/warningreporting/CMakeLists.txt @@ -44,12 +44,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/messaging/CMakeLists.txt b/Source/messaging/CMakeLists.txt index bfc53b3d2..d8125bc44 100644 --- a/Source/messaging/CMakeLists.txt +++ b/Source/messaging/CMakeLists.txt @@ -59,12 +59,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/plugins/CMakeLists.txt b/Source/plugins/CMakeLists.txt index 767c4cbcc..01e5721df 100644 --- a/Source/plugins/CMakeLists.txt +++ b/Source/plugins/CMakeLists.txt @@ -125,12 +125,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() @@ -138,12 +138,12 @@ set_target_properties(${TARGET_PROXYSTUBS} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Source/tracing/tracing.h b/Source/tracing/tracing.h deleted file mode 100644 index b73494e94..000000000 --- a/Source/tracing/tracing.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2020 Metrological - * - * Licensed 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 \ No newline at end of file diff --git a/Source/websocket/CMakeLists.txt b/Source/websocket/CMakeLists.txt index 694d37a8e..2f39a23b1 100644 --- a/Source/websocket/CMakeLists.txt +++ b/Source/websocket/CMakeLists.txt @@ -58,12 +58,12 @@ set_target_properties(${TARGET} PROPERTIES CXX_STANDARD_REQUIRED YES FRAMEWORK FALSE PUBLIC_HEADER "${PUBLIC_HEADERS}" # specify the public headers - SOVERSION ${Thunder_VERSION_MAJOR} + SOVERSION ${VERSION_MAJOR} ) if(HUMAN_VERSIONED_BINARIES) set_target_properties(${TARGET} PROPERTIES - VERSION ${Thunder_VERSION} + VERSION ${VERSION} ) endif() diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index 34e548504..eafc39959 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -42,7 +42,7 @@ add_executable(${TEST_RUNNER_NAME} test_lockablecontainer.cpp test_measurementtype.cpp test_memberavailability.cpp - test_messageException.cpp + #test_messageException.cpp test_networkinfo.cpp test_nodeid.cpp test_numbertype.cpp diff --git a/Tests/unit/core/test_messageException.cpp b/Tests/unit/core/test_messageException.cpp index 377d17d2f..df07f1439 100644 --- a/Tests/unit/core/test_messageException.cpp +++ b/Tests/unit/core/test_messageException.cpp @@ -27,17 +27,22 @@ using namespace Thunder::Core; TEST(test_messageException, simple_messageException) { - const std::string msg = "Testing the message exception."; - - // No 'error' concatenated - MessageException exception(msg, false); - - EXPECT_STREQ(exception.Message(), msg.c_str()); - - // 'error' concatenated - MessageException exception1(msg, true); - - const string result = msg + ": No such file or directory"; - - EXPECT_STREQ(exception1.Message(), result.c_str()); + std::string msg = "Testing the message exception."; + MessageException exception(msg.c_str(),false); + EXPECT_STREQ(exception.Message(),msg.c_str()); + + MessageException exception1(msg.c_str(),true); + char buffer[50]; + string status = ": File exists"; + snprintf(buffer, msg.size()+status.size()+1, "%s%s",msg.c_str(),status.c_str()); +#ifdef BUILD_ARM + if (strcmp(exception1.Message(), buffer) != 0) { +#else + if (strcmp(exception1.Message(), buffer) != 0) { +#endif + memset(buffer, 0, sizeof buffer); + status = ": No such file or directory"; + snprintf(buffer, msg.size()+status.size()+1, "%s%s",msg.c_str(),status.c_str()); + } + EXPECT_STREQ(exception1.Message(),buffer); } From bec26edc896bb62702ed0695a6decded969fb18a Mon Sep 17 00:00:00 2001 From: DineshkumarJP <99791803+DineshkumarJP@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:58:11 +0530 Subject: [PATCH 15/35] RDKVREFPLT-1728 [BCM] [memcr] Thunder hibernate configuration (#1642) * RDKSEC-71 Build failure in wpeframework recipe while adding distro feature for DOBBY_CONTAINERS (| Source/processcontainers/libWPEFrameworkProcessContainers.so.2.1.11: error: undefined reference to 'sd_bus_message_read_array' | Source/processcontainers/libWPEFrameworkProcessContainers.so.2.1.11: error: undefined reference to 'sd_bus_message_skip' | Source/processcontainers/libWPEFrameworkProcessContainers.so.2.1.11: error: undefined reference to 'sd_bus_message_peek_type' | Source/processcontainers/libWPEFrameworkProcessContainers.so.2.1.11: error: undefined reference to 'sd_bus_message_at_end' | Source/processcontainers/libWPEFrameworkProcessContainers.so.2.1.11: error: undefined reference to 'sd_bus_message_append_array) Reason for change: Stable build Test Procedure: None. Risks: None. * Hibernate thunder configuration * Hibernate thunder configuration * Hibernate thunder configuration --------- Co-authored-by: Pierre Wielders --- Source/Thunder/GenericConfig.cmake | 7 +++++++ Source/Thunder/Thunder.conf.in | 3 +++ Source/Thunder/params.config | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/Thunder/GenericConfig.cmake b/Source/Thunder/GenericConfig.cmake index 8edc2783b..2cb0243c4 100644 --- a/Source/Thunder/GenericConfig.cmake +++ b/Source/Thunder/GenericConfig.cmake @@ -48,6 +48,7 @@ set(ETHERNETCARD_NAME "eth0" CACHE STRING "Ethernet Card name which has to be as set(GROUP "" CACHE STRING "Define which system group will be used") set(UMASK "" CACHE STRING "Set the permission mask for the creation of new files. e.g. 0760") set(COMMUNICATOR "" CACHE STRING "Define the ComRPC socket e.g. 127.0.0.1:62000 or /tmp/communicator|750") +set(LOCATOR "/tmp/memcrcom" CACHE STRING "Default Memecr Socket path") # Controller Plugin Settings. set(PLUGIN_CONTROLLER_UI_ENABLED "true" CACHE STRING "Enable the Controller's UI") @@ -90,6 +91,12 @@ if(NOT COMMUNICATOR STREQUAL "") map_set(${CONFIG} communicator ${COMMUNICATOR}) endif() +map() +kv(locator ${LOCATOR}) +end() +ans(HIBERNATE_CONFIG) +map_append(${CONFIG} hibernate ${HIBERNATE_CONFIG}) + map() kv(priority ${PRIORITY}) kv(policy ${POLICY}) diff --git a/Source/Thunder/Thunder.conf.in b/Source/Thunder/Thunder.conf.in index b408621d5..748082a40 100644 --- a/Source/Thunder/Thunder.conf.in +++ b/Source/Thunder/Thunder.conf.in @@ -15,6 +15,9 @@ redirect = '/Service/Controller/UI' ethernetcard = '@ETHERNETCARD_NAME@' communicator = '@COMMUNICATOR@' +hibernate = JSON() +hibernate.add("locator", '@LOCATOR@') + process = JSON() process.add("priority", '@PRIORITY@') process.add("policy", '@POLICY@') diff --git a/Source/Thunder/params.config b/Source/Thunder/params.config index e00ddb22a..e0fd44524 100644 --- a/Source/Thunder/params.config +++ b/Source/Thunder/params.config @@ -15,6 +15,7 @@ postmortempath redirect ethernetcard communicator +hibernate exitreasons messaging -plugins \ No newline at end of file +plugins From f0122a36a449e7942fcc51b372844923fdb1880e Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Mon, 17 Jun 2024 08:33:12 +0200 Subject: [PATCH 16/35] Hot Fixes. Running build is broken with the CMake changes (#1648) * Update Communicator.cpp * Update Process.cpp --- Source/ThunderPlugin/Process.cpp | 2 +- Source/com/Communicator.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ThunderPlugin/Process.cpp b/Source/ThunderPlugin/Process.cpp index ed14342d7..078c328d0 100644 --- a/Source/ThunderPlugin/Process.cpp +++ b/Source/ThunderPlugin/Process.cpp @@ -479,7 +479,7 @@ class ProcessFlow { #ifdef VERSIONED_LIBRARY_LOADING static const std::string suffixFilter = "*.so." + std::to_string(THUNDER_VERSION); #else - static const std::string suffixFilter = ".so"; + static const std::string suffixFilter = "*.so"; #endif TRACE_L1("Loading ProxyStubs from %s", (pathName.empty() == false ? pathName.c_str() : _T("<< No Proxy Stubs Loaded >>"))); diff --git a/Source/com/Communicator.cpp b/Source/com/Communicator.cpp index e8642ead2..ac6172b6b 100644 --- a/Source/com/Communicator.cpp +++ b/Source/com/Communicator.cpp @@ -254,7 +254,7 @@ namespace RPC { #ifdef VERSIONED_LIBRARY_LOADING static const std::string suffixFilter = "*.so." + std::to_string(THUNDER_VERSION); #else - static const std::string suffixFilter = ".so"; + static const std::string suffixFilter = "*.so"; #endif while (places.Next() == true) { From 431ba5a7d627833f38c499797786c99f5a7e61fa Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Mon, 17 Jun 2024 09:12:37 +0200 Subject: [PATCH 17/35] =?UTF-8?q?[WINDOWS]=20Windows=20compiler=20does=20g?= =?UTF-8?q?ive=20different=20warnings,=20lets=20fix=20tho=E2=80=A6=20(#164?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [WINDOWS] Windows compiler does give different warnings, lets fix those as well.. * Update Config.h * Update Configuration.h --------- Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- Source/Thunder/Config.h | 22 +++++++++++----------- Source/com/Communicator.h | 6 +++--- Source/core/ASN1.h | 16 ++++++++-------- Source/core/DataElement.h | 8 ++++---- Source/core/FileSystem.h | 4 ++-- Source/core/IPCMessage.h | 4 ++-- Source/core/ISO639.h | 4 ++-- Source/core/JSON.h | 8 ++++---- Source/core/JSONRPC.h | 20 ++++++++++---------- Source/core/NetworkInfo.h | 16 ++++++++-------- Source/core/NodeId.h | 2 +- Source/core/Optional.h | 4 ++-- Source/core/Process.h | 8 +++----- Source/core/ProcessInfo.h | 4 ++-- Source/core/TextFragment.h | 12 ++++++------ Source/core/TextReader.h | 4 ++-- Source/core/Time.h | 4 ++-- Source/core/TriState.h | 8 +++----- Source/core/WorkerPool.h | 6 ++---- Source/messaging/MessageUnit.h | 4 ++-- Source/plugins/Configuration.h | 4 ++-- Source/plugins/JSONRPC.h | 4 ++-- Source/plugins/Metadata.h | 6 +++--- Source/plugins/VirtualInput.h | 10 +++++----- Source/websocket/URL.h | 6 +++--- Source/websocket/WebRequest.h | 8 ++++---- 26 files changed, 98 insertions(+), 104 deletions(-) diff --git a/Source/Thunder/Config.h b/Source/Thunder/Config.h index f23d3706c..1bd497273 100644 --- a/Source/Thunder/Config.h +++ b/Source/Thunder/Config.h @@ -136,7 +136,7 @@ namespace PluginHost { Add(_T("value"), &Value); Add(_T("override"), &Override); } - Environment(Environment&& move) + Environment(Environment&& move) noexcept : Core::JSON::Container() , Key(std::move(move.Key)) , Value(std::move(move.Value)) @@ -155,7 +155,7 @@ namespace PluginHost { return (*this); } - Environment& operator=(Environment&& move) + Environment& operator=(Environment&& move) noexcept { if (this != &move) { Key = std::move(move.Key); @@ -210,7 +210,7 @@ namespace PluginHost { Add(_T("stacksize"), &StackSize); Add(_T("umask"), &Umask); } - ProcessSet(ProcessSet&& move) + ProcessSet(ProcessSet&& move) noexcept : Core::JSON::Container() , User(std::move(move.User)) , Group(std::move(move.Group)) @@ -244,7 +244,7 @@ namespace PluginHost { return (*this); } - ProcessSet& operator=(ProcessSet&& move) + ProcessSet& operator=(ProcessSet&& move) noexcept { if (this != &move) { User = std::move(move.User); @@ -295,7 +295,7 @@ namespace PluginHost { Add(_T("type"), &Type); Add(_T("output"), &OutputEnabled); } - InputConfig(InputConfig&& move) + InputConfig(InputConfig&& move) noexcept : Core::JSON::Container() , Locator(std::move(move.Locator)) , Type(std::move(move.Type)) @@ -316,7 +316,7 @@ namespace PluginHost { return (*this); } - InputConfig& operator=(InputConfig&& move) + InputConfig& operator=(InputConfig&& move) noexcept { if (this != &move) { Locator = std::move(move.Locator); @@ -349,7 +349,7 @@ namespace PluginHost { Add(_T("proxystubpath"), &ProxyStubPath); Add(_T("configpath"), &PluginConfigPath); } - Observables(Observables&& move) + Observables(Observables&& move) noexcept : Core::JSON::Container() , ProxyStubPath(std::move(move.ProxyStubPath)) , PluginConfigPath(std::move(move.PluginConfigPath)) { @@ -377,7 +377,7 @@ namespace PluginHost { { Add(_T("logging"), &Logging); } - ProcessContainerConfig(ProcessContainerConfig&& move) + ProcessContainerConfig(ProcessContainerConfig&& move) noexcept : Logging(std::move(move.Logging)) { Add(_T("logging"), &Logging); @@ -389,7 +389,7 @@ namespace PluginHost { Logging = RHS.Logging; return (*this); } - ProcessContainerConfig& operator=(ProcessContainerConfig&& move) + ProcessContainerConfig& operator=(ProcessContainerConfig&& move) noexcept { if (this != &move) { Logging = std::move(move.Logging; @@ -416,7 +416,7 @@ namespace PluginHost { { Add(_T("locator"), &Locator); } - HibernateConfig(HibernateConfig&& move) + HibernateConfig(HibernateConfig&& move) noexcept : Locator(std::move(move.Locator)) { Add(_T("locator"), &Locator); @@ -428,7 +428,7 @@ namespace PluginHost { Locator = RHS.Locator; return (*this); } - HibernateConfig& operator=(HibernateConfig&& move) + HibernateConfig& operator=(HibernateConfig&& move) noexcept { if (this != &move) { Locator = std::move(move.Locator); diff --git a/Source/com/Communicator.h b/Source/com/Communicator.h index d8f9ceae8..dcaa13715 100644 --- a/Source/com/Communicator.h +++ b/Source/com/Communicator.h @@ -83,7 +83,7 @@ namespace RPC { , _configuration(copy._configuration) { } - Object(Object&& move) + Object(Object&& move) noexcept : _locator(std::move(move._locator)) , _className(std::move(move._className)) , _callsign(std::move(move._callsign)) @@ -151,7 +151,7 @@ namespace RPC { } - Object& operator=(Object&& move) + Object& operator=(Object&& move) noexcept { if (this != &move) { _locator = std::move(move._locator); @@ -297,7 +297,7 @@ namespace RPC { , _postMortem(copy._postMortem) { } - Config(Config&& move) + Config(Config&& move) noexcept : _connector(std::move(move._connector)) , _hostApplication(std::move(move._hostApplication)) , _persistent(std::move(move._persistent)) diff --git a/Source/core/ASN1.h b/Source/core/ASN1.h index c78bf7331..7bebd2fb8 100644 --- a/Source/core/ASN1.h +++ b/Source/core/ASN1.h @@ -63,7 +63,7 @@ namespace Core { { AddRef(); } - Buffer(Buffer&& move) + Buffer(Buffer&& move) noexcept : _buffer(move._buffer) { move._buffer = nullptr; @@ -82,7 +82,7 @@ namespace Core { } return (*this); } - Buffer& operator=(Buffer&& move) + Buffer& operator=(Buffer&& move) noexcept { if (&move != this) { Release(); @@ -163,7 +163,7 @@ namespace Core { , _buffer(copy._buffer) { } - Iterator(Iterator&& move) + Iterator(Iterator&& move) noexcept : _length(move._length) , _index(move._index) , _buffer(move._buffer) @@ -183,7 +183,7 @@ namespace Core { _buffer = RHS._buffer; return (*this); } - Iterator& operator=(Iterator&& move) + Iterator& operator=(Iterator&& move) noexcept { if (this != &move) { _length = move._length; @@ -319,7 +319,7 @@ namespace Core { ::memcpy(_buffer, copy._buffer, copy._length); _length = copy._length; } - OID(OID&& move) + OID(OID&& move) noexcept { ::memcpy(_buffer, move._buffer, move._length); _length = move._length; @@ -337,7 +337,7 @@ namespace Core { return (*this); } - OID& operator=(OID&& move) + OID& operator=(OID&& move) noexcept { if (this != &move) { ::memcpy(_buffer, move._buffer, move._length); @@ -465,7 +465,7 @@ namespace Core { , _length(copy._length) { } - Sequence(Sequence&& move) + Sequence(Sequence&& move) noexcept : _buffer(std::move(move._buffer)) , _index(move._index) , _length(move._length) @@ -486,7 +486,7 @@ namespace Core { return (*this); } - Sequence& operator=(Sequence&& move) + Sequence& operator=(Sequence&& move) noexcept { if (this != &move) { _buffer = std::move(move._buffer); diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 8d5e0b984..41251319b 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -189,7 +189,7 @@ namespace Core { , m_MaxSize(RHS.m_MaxSize) { } - inline DataElement(DataElement&& move) + inline DataElement(DataElement&& move) noexcept : m_Storage(std::move(move.m_Storage)) , m_Buffer(move.m_Buffer) , m_Offset(move.m_Offset) @@ -248,7 +248,7 @@ namespace Core { return (*this); } - inline DataElement& operator=(DataElement&& move) + inline DataElement& operator=(DataElement&& move) noexcept { if (this != &move) { m_Size = move.m_Size; @@ -800,7 +800,7 @@ namespace Core { // Don't set the size bigger than the cummulated one!!! ASSERT(offset + size < RHS.LinkedSize()); } - inline LinkedDataElement(LinkedDataElement&& move, const uint64_t offset = 0, const uint64_t size = 0) + inline LinkedDataElement(LinkedDataElement&& move, const uint64_t offset = 0, const uint64_t size = 0) noexcept : DataElement(move, offset, (offset + size > move.Size() ? 0 : size)) , m_Next(move.m_Next) { @@ -824,7 +824,7 @@ namespace Core { return (*this); } - inline LinkedDataElement& operator=(LinkedDataElement&& move) + inline LinkedDataElement& operator=(LinkedDataElement&& move) noexcept { if (this != &move) { DataElement::operator=(move); diff --git a/Source/core/FileSystem.h b/Source/core/FileSystem.h index 0ca1fcbdc..a3d56dbf2 100644 --- a/Source/core/FileSystem.h +++ b/Source/core/FileSystem.h @@ -173,7 +173,7 @@ namespace Core { return (*this); } - File& operator=(File&& move) + File& operator=(File&& move) noexcept { if (this != &move) { _name = std::move(move._name); @@ -803,7 +803,7 @@ POP_WARNING() return (*this); } - Directory& operator=(Directory&& move) + Directory& operator=(Directory&& move) noexcept { if (this != &move) { _name = std::move(move._name); diff --git a/Source/core/IPCMessage.h b/Source/core/IPCMessage.h index 3c656c160..a9645ffaa 100644 --- a/Source/core/IPCMessage.h +++ b/Source/core/IPCMessage.h @@ -104,7 +104,7 @@ namespace Core { : _data(copy._data) { } - ScalarType(ScalarType&& move) + ScalarType(ScalarType&& move) noexcept : _data(std::move(move._data)) { } @@ -118,7 +118,7 @@ namespace Core { return (*this); } - ScalarType& operator=(ScalarType&& move) + ScalarType& operator=(ScalarType&& move) noexcept { if (this != &move) { _data = std::move(move._data); diff --git a/Source/core/ISO639.h b/Source/core/ISO639.h index cf632119e..cc96404bf 100644 --- a/Source/core/ISO639.h +++ b/Source/core/ISO639.h @@ -57,7 +57,7 @@ namespace Core { , m_Index(copy.m_Index) { } - Language(Language&& move) + Language(Language&& move) noexcept : m_SelectedLanguage(std::move(move.m_SelectedLanguage)) , m_Index(std::move(move.m_Index)) { @@ -74,7 +74,7 @@ namespace Core { return (*this); } - Language& operator=(Language&& move) + Language& operator=(Language&& move) noexcept { if (this != &move) { m_SelectedLanguage = std::move(move.m_SelectedLanguage); diff --git a/Source/core/JSON.h b/Source/core/JSON.h index b91134e17..a9a082e2b 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -506,7 +506,7 @@ namespace Core { } ~NumberType() override = default; - NumberType& operator=(NumberType&& move) + NumberType& operator=(NumberType&& move) noexcept { _value = std::move(move._value); _set = std::move(move._set); @@ -2650,7 +2650,7 @@ namespace Core { ~EnumType() override = default; - EnumType& operator=(EnumType&& move) + EnumType& operator=(EnumType&& move) noexcept { _value = std::move(move._value); _state = std::move(move._state); @@ -3135,7 +3135,7 @@ namespace Core { ~ArrayType() override = default; - ArrayType& operator=(ArrayType&& move) + ArrayType& operator=(ArrayType&& move) noexcept { _state = std::move(move._state); _data = std::move(move._data); @@ -4656,7 +4656,7 @@ namespace Core { return (*this); } - VariantContainer& operator=(VariantContainer&& move) + VariantContainer& operator=(VariantContainer&& move) noexcept { if (this != &move) { _elements = std::move(move._elements); diff --git a/Source/core/JSONRPC.h b/Source/core/JSONRPC.h index 3423afece..d98e30d01 100644 --- a/Source/core/JSONRPC.h +++ b/Source/core/JSONRPC.h @@ -65,7 +65,7 @@ namespace Core { Add(_T("message"), &Text); Add(_T("data"), &Data); } - Info(Info&& move) + Info(Info&& move) noexcept : Core::JSON::Container() , Code(std::move(move.Code)) , Text(std::move(move.Text)) @@ -85,7 +85,7 @@ namespace Core { return (*this); } - Info& operator=(Info&& move) + Info& operator=(Info&& move) noexcept { if (this != &move) { Code = std::move(move.Code); @@ -218,7 +218,7 @@ namespace Core { Add(_T("error"), &Error); } - Message(Message&& move) + Message(Message&& move) noexcept : Core::JSON::Container() , JSONRPC(std::move(move.JSONRPC)) , Id(std::move(move.Id)) @@ -438,7 +438,7 @@ namespace Core { , _sequence(copy._sequence) , _token(copy._token) { } - Context(Context&& move) + Context(Context&& move) noexcept : _channelId(move._channelId) , _sequence(move._sequence) , _token(std::move(move._token)) { @@ -464,9 +464,9 @@ namespace Core { } private: - const uint32_t _channelId; - const uint32_t _sequence; - const string _token; + uint32_t _channelId; + uint32_t _sequence; + string _token; }; typedef std::function&)> CallbackFunction; @@ -545,7 +545,7 @@ namespace Core { , _info(copy._info, copy._asynchronous) { } - Entry(Entry&& move) + Entry(Entry&& move) noexcept : _asynchronous(move._asynchronous) , _info(std::move(move._info), move._asynchronous) { @@ -621,7 +621,7 @@ namespace Core { , _position(copy._position) { } - EventIterator(EventIterator&& move) + EventIterator(EventIterator&& move) noexcept : _container(move._container) , _index(std::move(move._index)) , _position(move._position) @@ -639,7 +639,7 @@ namespace Core { return (*this); } - EventIterator& operator=(EventIterator&& move) + EventIterator& operator=(EventIterator&& move) noexcept { if (this != &move) { _container = move._container; diff --git a/Source/core/NetworkInfo.h b/Source/core/NetworkInfo.h index 977185a42..25dcef81e 100644 --- a/Source/core/NetworkInfo.h +++ b/Source/core/NetworkInfo.h @@ -60,7 +60,7 @@ namespace Core { , _protocol(copy._protocol) , _scope(copy._scope) { } - Route(Route&& move) + Route(Route&& move) noexcept : _source(std::move(move._source)) , _destination(std::move(move._destination)) , _preferred(std::move(move._preferred)) @@ -104,7 +104,7 @@ namespace Core { return (*this); } - Route& operator=(Route&& move) { + Route& operator=(Route&& move) noexcept { if (this != &move) { _source = std::move(move._source); _destination = std::move(move._destination); @@ -230,7 +230,7 @@ namespace Core { , _section3(copy._section3) { } - inline IPV4AddressIterator(IPV4AddressIterator&& move) + inline IPV4AddressIterator(IPV4AddressIterator&& move) noexcept : _adapter(move._adapter) , _index(move._index) , _section1(move._section1) @@ -259,7 +259,7 @@ namespace Core { return (*this); } - inline IPV4AddressIterator& operator=(IPV4AddressIterator&& move) + inline IPV4AddressIterator& operator=(IPV4AddressIterator&& move) noexcept { if (this != &move) { _adapter = move._adapter; @@ -329,7 +329,7 @@ namespace Core { , _section3(copy._section3) { } - inline IPV6AddressIterator(IPV6AddressIterator&& move) + inline IPV6AddressIterator(IPV6AddressIterator&& move) noexcept : _adapter(move._adapter) , _index(move._index) , _section1(move._section1) @@ -357,7 +357,7 @@ namespace Core { return (*this); } - inline IPV6AddressIterator& operator=(IPV6AddressIterator&& move) + inline IPV6AddressIterator& operator=(IPV6AddressIterator&& move) noexcept { if (this != &move) { _adapter = move._adapter; @@ -442,7 +442,7 @@ namespace Core { : _index(copy._index) { } - inline AdapterIterator(AdapterIterator&& move) + inline AdapterIterator(AdapterIterator&& move) noexcept : _index(move._index) { move._index = (static_cast(~0)); @@ -457,7 +457,7 @@ namespace Core { return (*this); } - inline AdapterIterator& operator=(AdapterIterator&& move) + inline AdapterIterator& operator=(AdapterIterator&& move) noexcept { if (this != &move) { _index = move._index; diff --git a/Source/core/NodeId.h b/Source/core/NodeId.h index 0066c5b56..210385809 100644 --- a/Source/core/NodeId.h +++ b/Source/core/NodeId.h @@ -418,7 +418,7 @@ namespace Core { , _mask(copy._mask) { } - IPNode(IPNode&& move) + IPNode(IPNode&& move) noexcept : Core::NodeId(move) , _mask(move._mask) { diff --git a/Source/core/Optional.h b/Source/core/Optional.h index 1e2b289de..36a99716e 100644 --- a/Source/core/Optional.h +++ b/Source/core/Optional.h @@ -45,7 +45,7 @@ namespace Core { { } - OptionalType(OptionalType&& value) + OptionalType(OptionalType&& value) noexcept : m_Value(std::move(value.m_Value)) , m_Set(value.m_Set) { @@ -65,7 +65,7 @@ namespace Core { return (*this); } - inline OptionalType& operator=(OptionalType&& move) + inline OptionalType& operator=(OptionalType&& move) noexcept { if (this != &move) { m_Value = std::move(move.m_Value); diff --git a/Source/core/Process.h b/Source/core/Process.h index 82f70a94f..f9e5f9776 100644 --- a/Source/core/Process.h +++ b/Source/core/Process.h @@ -55,14 +55,12 @@ namespace Core { , _options(copy._options) { } - Options(Options&& move) + Options(Options&& move) noexcept : _command(std::move(move._command)) , _options(std::move(move._options)) { } - ~Options() - { - } + ~Options() = default; public: inline const string& Command() const @@ -212,7 +210,7 @@ namespace Core { } private: - const string _command; + string _command; std::vector _options; }; diff --git a/Source/core/ProcessInfo.h b/Source/core/ProcessInfo.h index 56c5c0103..f87843907 100644 --- a/Source/core/ProcessInfo.h +++ b/Source/core/ProcessInfo.h @@ -120,7 +120,7 @@ namespace Core { , _index(copy._index) { } - Iterator(Iterator&& move) + Iterator(Iterator&& move) noexcept : _pids(std::move(move._pids)) , _current(std::move(move._current)) , _index(move._index) @@ -140,7 +140,7 @@ namespace Core { return (*this); } - Iterator& operator=(Iterator&& move) + Iterator& operator=(Iterator&& move) noexcept { if (this != &move) { _pids = std::move(move._pids); diff --git a/Source/core/TextFragment.h b/Source/core/TextFragment.h index 821f913d6..be259241f 100644 --- a/Source/core/TextFragment.h +++ b/Source/core/TextFragment.h @@ -54,7 +54,7 @@ namespace Core { , m_Length(copy.m_Length) { } - inline Index(Index&& move) + inline Index(Index&& move) noexcept : m_Begin(move.m_Begin) , m_Length(move.m_Length) { @@ -73,7 +73,7 @@ namespace Core { return (*this); } - inline Index& operator=(Index&& move) + inline Index& operator=(Index&& move) noexcept { if (this != &move) { m_Begin = move.m_Begin; @@ -196,7 +196,7 @@ namespace Core { , m_Buffer(copy.m_Buffer) { } - TextFragment(TextFragment&& move) + TextFragment(TextFragment&& move) noexcept : m_Index(std::move(move.m_Index)) , m_Start(move.m_Start) , m_Buffer(std::move(move.m_Buffer)) @@ -215,7 +215,7 @@ namespace Core { return (*this); } - TextFragment& operator=(TextFragment&& move) + TextFragment& operator=(TextFragment&& move) noexcept { if (this != &move) { m_Index = std::move(move.m_Index); @@ -615,7 +615,7 @@ namespace Core { , _suppressEmpty(copy._suppressEmpty) { } - TextSegmentIterator(TextSegmentIterator&& move, const bool fixatFromCurrentPosition = false) + TextSegmentIterator(TextSegmentIterator&& move, const bool fixatFromCurrentPosition = false) noexcept : _delimiter(move._delimiter) , _delimiters(std::move(move._delimiters)) , _index(fixatFromCurrentPosition ? (move._index < move._source.Length() ? 0 : 1) : move._index) @@ -645,7 +645,7 @@ namespace Core { return (*this); } - TextSegmentIterator& operator=(TextSegmentIterator&& move) + TextSegmentIterator& operator=(TextSegmentIterator&& move) noexcept { if (this != &move) { _delimiter = move._delimiter; diff --git a/Source/core/TextReader.h b/Source/core/TextReader.h index b0e4bb08b..324b52fba 100644 --- a/Source/core/TextReader.h +++ b/Source/core/TextReader.h @@ -51,7 +51,7 @@ namespace Core { , m_DataBlock(copy.m_DataBlock) { } - TextReader(TextReader&& move) + TextReader(TextReader&& move) noexcept : m_Index(move.m_Index) , m_DataBlock(std::move(move.m_DataBlock)) { @@ -66,7 +66,7 @@ namespace Core { return (*this); } - TextReader& operator=(TextReader&& move) + TextReader& operator=(TextReader&& move) noexcept { if (this != &move) { m_Index = move.m_Index; diff --git a/Source/core/Time.h b/Source/core/Time.h index 2eb7b095f..37c43202c 100644 --- a/Source/core/Time.h +++ b/Source/core/Time.h @@ -118,7 +118,7 @@ namespace Core { { } - Time(Time&& move) + Time(Time&& move) noexcept : _time(std::move(move._time)) { } @@ -132,7 +132,7 @@ namespace Core { return (*this); } - Time& operator=(Time&& move) + Time& operator=(Time&& move) noexcept { if (this != &move) { _time = std::move(move._time); diff --git a/Source/core/TriState.h b/Source/core/TriState.h index 366d4ce8e..010d8623d 100644 --- a/Source/core/TriState.h +++ b/Source/core/TriState.h @@ -82,13 +82,11 @@ namespace Core { : m_State(copy.m_State) { } - TriState(TriState&& move) + TriState(TriState&& move) noexcept : m_State(std::move(move.m_State)) { } - ~TriState() - { - } + ~TriState() = default; TriState& operator=(const TriState& rhs) { @@ -96,7 +94,7 @@ namespace Core { return (*this); } - TriState& operator=(TriState&& move) + TriState& operator=(TriState&& move) noexcept { if (this != &move) { m_State = std::move(move.m_State); diff --git a/Source/core/WorkerPool.h b/Source/core/WorkerPool.h index d522f4ecf..4f2e4895d 100644 --- a/Source/core/WorkerPool.h +++ b/Source/core/WorkerPool.h @@ -126,7 +126,7 @@ namespace Core { , _pool(copy._pool) { } - Timer(Timer&& move) + Timer(Timer&& move) noexcept : _job(std::move(move._job)) , _pool(move._pool) { @@ -137,9 +137,7 @@ namespace Core { , _pool(pool) { } - ~Timer() - { - } + ~Timer() = default; public: bool operator==(const Timer& RHS) const diff --git a/Source/messaging/MessageUnit.h b/Source/messaging/MessageUnit.h index b5a2cbd69..1af1b8423 100644 --- a/Source/messaging/MessageUnit.h +++ b/Source/messaging/MessageUnit.h @@ -288,7 +288,7 @@ namespace Thunder { Category = category; Enabled = enabled; } - Entry(Entry&& other) + Entry(Entry&& other) noexcept : Core::JSON::Container() , Module(std::move(other.Module)) , Category(std::move(other.Category)) @@ -309,7 +309,7 @@ namespace Thunder { Add(_T("enabled"), &Enabled); } - Entry& operator=(Entry&& other) + Entry& operator=(Entry&& other) noexcept { if (&other != this) { Module = std::move(other.Module); diff --git a/Source/plugins/Configuration.h b/Source/plugins/Configuration.h index acf153ce4..d89e810e2 100644 --- a/Source/plugins/Configuration.h +++ b/Source/plugins/Configuration.h @@ -149,7 +149,7 @@ namespace Plugin { Add(_T("remoteaddress"), &RemoteAddress); Add(_T("configuration"), &Configuration); } - RootConfig(RootConfig&& move) + RootConfig(RootConfig&& move) noexcept : Core::JSON::Container() , Locator(std::move(move.Locator)) , User(std::move(move.User)) @@ -189,7 +189,7 @@ namespace Plugin { return (*this); } - RootConfig& operator=(RootConfig&& move) + RootConfig& operator=(RootConfig&& move) noexcept { if (this != &move) { Locator = std::move(move.Locator); diff --git a/Source/plugins/JSONRPC.h b/Source/plugins/JSONRPC.h index 6e6cb0ab1..67f211188 100644 --- a/Source/plugins/JSONRPC.h +++ b/Source/plugins/JSONRPC.h @@ -305,7 +305,7 @@ namespace PluginHost { { Init(); } - VersionInfo(VersionInfo&& move) + VersionInfo(VersionInfo&& move) noexcept : Core::JSON::Container() , Name(std::move(move.Name)) , Major(std::move(move.Major)) @@ -330,7 +330,7 @@ namespace PluginHost { Patch = rhs.Patch; return (*this); } - VersionInfo& operator=(VersionInfo&& move) + VersionInfo& operator=(VersionInfo&& move) noexcept { if (this != &move) { Name = std::move(move.Name); diff --git a/Source/plugins/Metadata.h b/Source/plugins/Metadata.h index 569af6050..f14fbc044 100644 --- a/Source/plugins/Metadata.h +++ b/Source/plugins/Metadata.h @@ -46,7 +46,7 @@ namespace PluginHost { : Core::JSON::EnumType() { } - State(State&& move) + State(State&& move) noexcept : Core::JSON::EnumType(move) { } @@ -95,7 +95,7 @@ namespace PluginHost { class EXTERNAL State : public Core::JSON::EnumType { public: inline State() = default; - inline State(State&& move) + inline State(State&& move) noexcept : Core::JSON::EnumType(move) { } @@ -214,7 +214,7 @@ namespace PluginHost { Add(_T("link"), &Remote); Add(_T("proxies"), &Proxies); } - COMRPC(COMRPC&& move) + COMRPC(COMRPC&& move) noexcept : Core::JSON::Container() , Remote(std::move(move.Remote)) , Proxies(std::move(move.Proxies)) { diff --git a/Source/plugins/VirtualInput.h b/Source/plugins/VirtualInput.h index eba33d145..d16a3db87 100644 --- a/Source/plugins/VirtualInput.h +++ b/Source/plugins/VirtualInput.h @@ -176,7 +176,7 @@ POP_WARNING() Add(_T("key"), &Key); Add(_T("modifiers"), &Modifiers); } - inline KeyMapEntry(KeyMapEntry&& move) + inline KeyMapEntry(KeyMapEntry&& move) noexcept : Core::JSON::Container() , Code(std::move(move.Code)) , Key(std::move(move.Key)) @@ -322,7 +322,7 @@ POP_WARNING() , _position(copy._position) { } - Iterator(Iterator&& move) + Iterator(Iterator&& move) noexcept : _consumers(std::move(move._consumers)) , _index(std::move(move._index)) , _position(move._position) @@ -341,7 +341,7 @@ POP_WARNING() return (*this); } - Iterator& operator=(Iterator&& move) + Iterator& operator=(Iterator&& move) noexcept { if (this != &move) { _consumers = std::move(move._consumers); @@ -427,7 +427,7 @@ POP_WARNING() Add(_T("code"), &Code); Add(_T("mods"), &Mods); } - KeyCode(KeyCode&& move) + KeyCode(KeyCode&& move) noexcept : Core::JSON::Container() , Code(std::move(move.Code)) , Mods(std::move(move.Mods)) @@ -459,7 +459,7 @@ POP_WARNING() Add(_T("in"), &In); Add(_T("out"), &Out); } - Conversion(Conversion&& move) + Conversion(Conversion&& move) noexcept : Core::JSON::Container() , In(std::move(move.In)) , Out(std::move(move.Out)) diff --git a/Source/websocket/URL.h b/Source/websocket/URL.h index 54193fed6..e73ae9267 100644 --- a/Source/websocket/URL.h +++ b/Source/websocket/URL.h @@ -72,7 +72,7 @@ namespace Core { return (*this); } - KeyValue& operator=(KeyValue&& move) { + KeyValue& operator=(KeyValue&& move) noexcept { if (this != &move) { _data = std::move(move._data); } @@ -245,7 +245,7 @@ namespace Core { , _ref(copy._ref) { } - URL(URL&& move) + URL(URL&& move) noexcept : _scheme(std::move(move._scheme)) , _username(std::move(move._username)) , _password(std::move(move._password)) @@ -290,7 +290,7 @@ namespace Core { return (*this); } - inline URL& operator=(URL&& move) + inline URL& operator=(URL&& move) noexcept { if (this != &move) { _scheme = std::move(move._scheme); diff --git a/Source/websocket/WebRequest.h b/Source/websocket/WebRequest.h index d8057216f..9de9160c8 100644 --- a/Source/websocket/WebRequest.h +++ b/Source/websocket/WebRequest.h @@ -118,7 +118,7 @@ namespace Web { ASSERT(_type <= sizeof(_hashValue)); ::memcpy(_hashValue, copy._hashValue, _type); } - Signature(Signature&& move) + Signature(Signature&& move) noexcept : _type(std::move(move._type)) { ASSERT(_type <= sizeof(_hashValue)); @@ -137,7 +137,7 @@ namespace Web { return (*this); } - Signature& operator=(Signature&& move) + Signature& operator=(Signature&& move) noexcept { if (this != &move) { _type = std::move(move._type); @@ -198,7 +198,7 @@ namespace Web { , _token(copy._token) { } - Authorization(Authorization&& move) + Authorization(Authorization&& move) noexcept : _type(std::move(move._type)) , _token(std::move(move._token)) { @@ -215,7 +215,7 @@ namespace Web { return (*this); } - Authorization& operator=(Authorization&& move) + Authorization& operator=(Authorization&& move) noexcept { if (this != &move) { _type = std::move(move._type); From 2d91420c4948b8fb987512ef4eb0f014edbbf845 Mon Sep 17 00:00:00 2001 From: sebaszm <45654185+sebaszm@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:46:56 +0200 Subject: [PATCH 18/35] Fix process container build (#1650) Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- Source/Thunder/Config.h | 2 +- Source/com/Communicator.cpp | 4 --- Source/com/Communicator.h | 2 +- .../extensions/processcontainers/Messaging.h | 1 - Source/extensions/processcontainers/Module.h | 1 + .../implementations/AWCImplementation/AWC.cpp | 2 +- .../AWCImplementation/AWCContainerBase.cpp | 2 +- .../AWCImplementation/AWCProxyContainer.cpp | 2 +- .../CRunImplementation/CRunImplementation.cpp | 10 +++--- .../CRunImplementation/CRunImplementation.h | 5 +++ .../DobbyImplementation.cpp | 9 +++-- .../LXCImplementation/LXCImplementation.cpp | 22 ++---------- .../LXCImplementation/LXCImplementation.h | 36 ++++++++++++++++--- 13 files changed, 54 insertions(+), 44 deletions(-) diff --git a/Source/Thunder/Config.h b/Source/Thunder/Config.h index 1bd497273..2daebd2d6 100644 --- a/Source/Thunder/Config.h +++ b/Source/Thunder/Config.h @@ -392,7 +392,7 @@ namespace PluginHost { ProcessContainerConfig& operator=(ProcessContainerConfig&& move) noexcept { if (this != &move) { - Logging = std::move(move.Logging; + Logging = std::move(move.Logging); } return (*this); } diff --git a/Source/com/Communicator.cpp b/Source/com/Communicator.cpp index ac6172b6b..40addf41f 100644 --- a/Source/com/Communicator.cpp +++ b/Source/com/Communicator.cpp @@ -22,10 +22,6 @@ #include #include -#ifdef PROCESSCONTAINERS_ENABLED -#include "ProcessInfo.h" -#endif - namespace Thunder { namespace RPC { diff --git a/Source/com/Communicator.h b/Source/com/Communicator.h index dcaa13715..249899d35 100644 --- a/Source/com/Communicator.h +++ b/Source/com/Communicator.h @@ -32,7 +32,7 @@ #ifdef PROCESSCONTAINERS_ENABLED -#include "../processcontainers/ProcessContainer.h" +#include #endif diff --git a/Source/extensions/processcontainers/Messaging.h b/Source/extensions/processcontainers/Messaging.h index 6ce158898..60695121a 100644 --- a/Source/extensions/processcontainers/Messaging.h +++ b/Source/extensions/processcontainers/Messaging.h @@ -21,7 +21,6 @@ #include "Module.h" -#include "../messaging/messaging.h" namespace Thunder { namespace ProcessContainers { diff --git a/Source/extensions/processcontainers/Module.h b/Source/extensions/processcontainers/Module.h index b717687e2..2c7e9035f 100644 --- a/Source/extensions/processcontainers/Module.h +++ b/Source/extensions/processcontainers/Module.h @@ -24,6 +24,7 @@ #endif #include +#include #if defined(__WINDOWS__) && defined(CONTAINERS_EXPORTS) #undef EXTERNAL diff --git a/Source/extensions/processcontainers/implementations/AWCImplementation/AWC.cpp b/Source/extensions/processcontainers/implementations/AWCImplementation/AWC.cpp index be27629a8..a80435b38 100644 --- a/Source/extensions/processcontainers/implementations/AWCImplementation/AWC.cpp +++ b/Source/extensions/processcontainers/implementations/AWCImplementation/AWC.cpp @@ -43,7 +43,7 @@ AWCListener::AWCListener(AWCStateChangeNotifier * notifier) : _notifier(notifier) {} -void AWCListener::notifyWindowChange(int window_id, awc::AWCClient::awc_window_state_t window_state, unsigned int pid) +void AWCListener::notifyWindowChange(int window_id VARIABLE_IS_NOT_USED, awc::AWCClient::awc_window_state_t window_state VARIABLE_IS_NOT_USED, unsigned int pid VARIABLE_IS_NOT_USED) { // intentionally left empty } diff --git a/Source/extensions/processcontainers/implementations/AWCImplementation/AWCContainerBase.cpp b/Source/extensions/processcontainers/implementations/AWCImplementation/AWCContainerBase.cpp index 42f39bd01..b0b2ca54b 100644 --- a/Source/extensions/processcontainers/implementations/AWCImplementation/AWCContainerBase.cpp +++ b/Source/extensions/processcontainers/implementations/AWCImplementation/AWCContainerBase.cpp @@ -33,7 +33,7 @@ struct AWCProcessorInfo : public BaseRefCount { return 0; } - uint64_t CoreUsage(uint32_t coreNum) const + uint64_t CoreUsage(uint32_t coreNum VARIABLE_IS_NOT_USED) const { return 0; } diff --git a/Source/extensions/processcontainers/implementations/AWCImplementation/AWCProxyContainer.cpp b/Source/extensions/processcontainers/implementations/AWCImplementation/AWCProxyContainer.cpp index a2676cbb3..7486091e4 100644 --- a/Source/extensions/processcontainers/implementations/AWCImplementation/AWCProxyContainer.cpp +++ b/Source/extensions/processcontainers/implementations/AWCImplementation/AWCProxyContainer.cpp @@ -151,7 +151,7 @@ bool AWCProxyContainer::Start(const string &command, IStringIterator ¶ms) /* provided timeout is not used. Thunder provides 0ms timeout by default * and if this function returns false next Stop() will be retried after 10s */ -bool AWCProxyContainer::Stop(const uint32_t timeout /*ms*/) +bool AWCProxyContainer::Stop(const uint32_t timeout /*ms*/ VARIABLE_IS_NOT_USED) { if(!IsRunning()) { diff --git a/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.cpp b/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.cpp index c726c86b4..829a2218c 100644 --- a/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.cpp +++ b/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.cpp @@ -16,8 +16,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "CRunImplementation.h" -#include "JSON.h" #include namespace Thunder { @@ -31,7 +31,7 @@ namespace ProcessContainers { return cRunContainerAdministrator; } - IContainer* CRunContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& configuration) + IContainer* CRunContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& configuration VARIABLE_IS_NOT_USED) { searchpaths.Reset(0); while (searchpaths.Next()) { @@ -61,7 +61,7 @@ namespace ProcessContainers { { } - void CRunContainerAdministrator::Logging(const string& logPath, const string& loggingOptions) + void CRunContainerAdministrator::Logging(const string& logPath VARIABLE_IS_NOT_USED, const string& loggingOptions VARIABLE_IS_NOT_USED) { // Only container-scope logging } @@ -101,7 +101,7 @@ namespace ProcessContainers { Core::Directory(logPath.c_str()).CreatePath(); libcrun_error_t error = nullptr; - int ret = init_logging(&_context.output_handler, &_context.output_handler_arg, _name.c_str(), (logPath + "/container.log").c_str(), &error); + int ret = libcrun_init_logging(&_context.output_handler, &_context.output_handler_arg, _name.c_str(), (logPath + "/container.log").c_str(), &error); if (ret != 0) { TRACE_L1("Cannot initialize logging of container \"%s\" in directory %s\n. Error %d: %s", _name.c_str(), logPath.c_str(), error->status, error->msg); } @@ -225,7 +225,7 @@ namespace ProcessContainers { return result; } - bool CRunContainer::Stop(const uint32_t timeout /*ms*/) + bool CRunContainer::Stop(const uint32_t timeout /*ms*/ VARIABLE_IS_NOT_USED) { bool result = true; libcrun_error_t error = nullptr; diff --git a/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.h b/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.h index 23e651223..f6b82a453 100644 --- a/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.h +++ b/Source/extensions/processcontainers/implementations/CRunImplementation/CRunImplementation.h @@ -24,6 +24,9 @@ #include "processcontainers/common/BaseRefCount.h" #include "processcontainers/common/CGroupContainerInfo.h" + +PUSH_WARNING(DISABLE_WARNING_PEDANTIC) + extern "C" { #include #include @@ -31,6 +34,8 @@ extern "C" { #include } +POP_WARNING() + namespace Thunder { namespace ProcessContainers { diff --git a/Source/extensions/processcontainers/implementations/DobbyImplementation/DobbyImplementation.cpp b/Source/extensions/processcontainers/implementations/DobbyImplementation/DobbyImplementation.cpp index fafbda1f0..ac624c18b 100644 --- a/Source/extensions/processcontainers/implementations/DobbyImplementation/DobbyImplementation.cpp +++ b/Source/extensions/processcontainers/implementations/DobbyImplementation/DobbyImplementation.cpp @@ -22,7 +22,6 @@ #include #include #include -#include namespace Thunder { @@ -36,7 +35,7 @@ namespace ProcessContainers { return dobbyContainerAdministrator; } - IContainer* DobbyContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& configuration) + IContainer* DobbyContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& configuration VARIABLE_IS_NOT_USED) { searchpaths.Reset(0); while (searchpaths.Next()) { @@ -97,7 +96,7 @@ namespace ProcessContainers { { } - void DobbyContainerAdministrator::Logging(const string& logPath, const string& loggingOptions) + void DobbyContainerAdministrator::Logging(const string& logPath VARIABLE_IS_NOT_USED, const string& loggingOptions VARIABLE_IS_NOT_USED) { // Only container-scope logging } @@ -173,7 +172,7 @@ namespace ProcessContainers { return result; } - void DobbyContainerAdministrator::containerStopCallback(int32_t cd, const std::string& containerId, + void DobbyContainerAdministrator::containerStopCallback(int32_t cd VARIABLE_IS_NOT_USED, const std::string& containerId, IDobbyProxyEvents::ContainerState state, const void* params) { @@ -390,7 +389,7 @@ namespace ProcessContainers { return result; } - bool DobbyContainer::Stop(const uint32_t timeout /*ms*/) + bool DobbyContainer::Stop(const uint32_t timeout /*ms*/ VARIABLE_IS_NOT_USED) { // TODO: add timeout support bool result = false; diff --git a/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.cpp b/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.cpp index 74b6fde45..5730a6c0b 100644 --- a/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.cpp +++ b/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.cpp @@ -132,24 +132,6 @@ namespace ProcessContainers { return _interfaces.at(_current).addresses[id]; } - LXCContainer::Config::ConfigItem::ConfigItem(const ConfigItem& copy) - : Core::JSON::Container() - , Key(copy.Key) - , Value(copy.Value) - { - Add(_T("key"), &Key); - Add(_T("value"), &Value); - } - - LXCContainer::Config::ConfigItem::ConfigItem(ConfigItem&& move) - : Core::JSON::Container() - , Key(std::move(move.Key)) - , Value(std::move(move.Value)) - { - Add(_T("key"), &Key); - Add(_T("value"), &Value); - } - LXCContainer::Config::Config() : Core::JSON::Container() , ConsoleLogging("0") @@ -369,7 +351,7 @@ namespace ProcessContainers { return result; } - bool LXCContainer::Stop(const uint32_t timeout /*ms*/) + bool LXCContainer::Stop(const uint32_t timeout VARIABLE_IS_NOT_USED /*ms*/) { bool result = true; @@ -410,7 +392,7 @@ namespace ProcessContainers { uint32_t LXCContainer::Release() const { uint32_t lxcresult = lxc_container_put(_lxcContainer); - uint32_t retVal = BaseRefCount::Release(); + uint32_t retval = BaseRefCount::Release(); ASSERT((retval != Thunder::Core::ERROR_DESTRUCTION_SUCCEEDED) || (lxcresult == 1)); // if 1 is returned, lxc also released the container return retval; diff --git a/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.h b/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.h index b30f84cad..dc5d43b6a 100644 --- a/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.h +++ b/Source/extensions/processcontainers/implementations/LXCImplementation/LXCImplementation.h @@ -69,12 +69,40 @@ namespace ProcessContainers { ConfigItem& operator=(ConfigItem&&) = delete; ConfigItem& operator=(const ConfigItem&) = delete; - ConfigItem(ConfigItem&& move); - ConfigItem(const ConfigItem& copy); - ConfigItem(); - ~ConfigItem() override = default; + ConfigItem() + : Core::JSON::Container() + , Key() + , Value() + { + Init(); + } + + ConfigItem(const ConfigItem& copy) + : Core::JSON::Container() + , Key(copy.Key) + , Value(copy.Value) + { + Init(); + } + + ConfigItem(ConfigItem&& move) + : Core::JSON::Container() + , Key(std::move(move.Key)) + , Value(std::move(move.Value)) + { + Init(); + } + + private: + void Init() + { + Add(_T("key"), &Key); + Add(_T("value"), &Value); + } + + public: Core::JSON::String Key; Core::JSON::String Value; }; From d673eba184b8fa4e6d108ca8ba25c1ae9ae76457 Mon Sep 17 00:00:00 2001 From: Mateusz Daniluk <121170681+VeithMetro@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:22:20 +0200 Subject: [PATCH 19/35] [Docs] Architecture overview documentation (#1651) * Adding an initial version of the architecture overview documentation * Formatting changes * Turns out GitHub text editor changes tabs for spaces * Final improvements before the review * Using capital letter for section names * Removing unnecessary tabs in the coding example --------- Co-authored-by: Pierre Wielders --- docs/introduction/architecture/overview.md | 245 +++++++++++++++++++++ 1 file changed, 245 insertions(+) diff --git a/docs/introduction/architecture/overview.md b/docs/introduction/architecture/overview.md index e69de29bb..297d2f945 100644 --- a/docs/introduction/architecture/overview.md +++ b/docs/introduction/architecture/overview.md @@ -0,0 +1,245 @@ +The architecture of Thunder is designed to provide a modular, scalable, and efficient framework for building and managing software services and applications. At its core, Thunder employs a plugin-based architecture, where each functionality is encapsulated within a plugin that can be dynamically loaded, activated, and managed at runtime. This modularity ensures ease of maintenance, flexibility, and scalability, allowing developers to extend and customize the framework with minimal impact on existing components. + +Thunder leverages robust communication mechanisms, including JSON-RPC and COM-RPC protocols, to facilitate seamless interaction between plugins and external clients. The framework also emphasizes secure service management, with mechanisms for authentication, authorization, and secure communication. + +!!! note + Overall, Thunder's architecture is geared towards providing a high-performance, reliable platform that can adapt to various use cases and deployment environments. + + + +## Resource-Constrained Focus + +Thunder is meticulously designed with resource constraints in mind, making it exceptionally suitable for embedded systems and environments where memory and processing power are limited. The architecture prioritizes efficiency and optimization to ensure that the framework operates smoothly even under severe resource limitations. + +This focus on resource constraints drives several key design decisions, including the use of lightweight communication protocols, modular plugin systems, and efficient resource management strategies. + +### Execution Architecture + +The execution architecture of Thunder is a critical aspect that ensures optimal performance and resource utilization. Execution architecture refers to the structural organization of computational elements and their interactions within a system. In the context of Thunder, this architecture is geared towards maximizing efficiency and maintaining stability in resource-constrained environments. + +!!! note + A core component of Thunder’s execution architecture is the `ResourceMonitor`, and a more detailed documentation about it can be found [here](https://rdkcentral.github.io/Thunder/utils/sockets/#resource-monitor). + +In the nutshell, the `ResourceMonitor` operates as a separate thread dedicated to the aggregation, allocation, and management of resources. It plays a pivotal role in monitoring system resources, ensuring that each component receives the necessary resources while preventing over-allocation that could lead to system instability. Providing a centralized management system helps in identifying potential issues early and taking corrective actions before they escalate. The `ResourceMonitor`'s responsibilities include: + +- **Resource Aggregation**: Collecting data on resource usage from various components and plugins. +- **Resource Allocation**: Dynamically allocating resources to plugins and services based on current demands and availability. +- **Communication Handling**: Managing the sending and receiving of data between components, optimizing communication paths to reduce latency and overhead. + +This resource-centric approach is complemented by Thunder’s use of efficient communication protocols, such as COM-RPC, which minimizes overhead and maximizes throughput. By employing COM-RPC within the execution architecture, Thunder ensures that inter-component communication is both fast and resource-efficient, which is crucial for maintaining performance in embedded systems. + +### Benefits of Execution Architecture in Thunder + +- **Efficiency**: The architecture is optimized for minimal resource usage, ensuring that the framework can run on devices with limited processing power and memory. +- **Stability**: By isolating components and managing resources dynamically, Thunder can prevent the failure of one component from affecting the entire system. +- **Scalability**: The modular design allows for easy addition and management of plugins without significant reconfiguration, making it scalable for various applications. + +To sum up, Thunder’s focus on resource constraints and its robust execution architecture make it a powerful framework for embedded systems. The role of `ResourceMonitor` in dynamically managing resources and optimizing communication ensures that Thunder remains lean, mean, and highly efficient, catering to the needs of modern embedded devices. + + + +## Interface-Based Development + +Interface-based development is a software design principle that emphasizes defining clear, stable interfaces between components. This approach decouples the implementation details from the interface, allowing for greater flexibility, maintainability, and scalability. + +!!! warning + Interfaces serve as contracts that define the methods and properties a component must implement, enabling different components to interact seamlessly without being tightly coupled to each other's implementations. + +### Main Benefits + +1. **Modularity:** Interfaces allow different parts of the system to be developed, tested, and maintained independently. This modularity simplifies updates and improvements without disrupting the entire system. +2. **Interchangeability:** Implementations can be changed with minimal changes to the system. This is particularly useful for testing and upgrading components. +3. **Scalability:** As the system grows, new functionalities can be added through new interfaces, ensuring that existing components remain unaffected. +4. **Maintainability:** Clear interfaces make the codebase easier to understand and maintain, as they provide a clear contract for what a component should do. + +### Implementation in Thunder + +In Thunder, interfaces are typically named with a capital `I` prefix, and the actual classes implementing these interfaces follow a consistent naming convention. The `IPlugin` interface can be a good example of that principle. This interface defines methods that any plugin must implement. Below you can see only a part of this interface and its methods with a detailed explanation. This code can be found [here](https://github.com/rdkcentral/Thunder/blob/e1b416eee5b057a8ffe5acfd68dfda04ad4f30eb/Source/plugins/IPlugin.h) in the Thunder repository. + +```c++ +struct EXTERNAL IPlugin : public virtual Core::IUnknown { + + enum { ID = RPC::ID_PLUGIN }; + + struct INotification : virtual public Core::IUnknown { + + enum { ID = RPC::ID_PLUGIN_NOTIFICATION }; + + ~INotification() override = default; + + //! @{ + //! ================================== CALLED ON THREADPOOL THREAD ===================================== + //! Whenever a plugin changes state, this is reported to an observer so proper actions could be taken + //! on this state change. + //! @} + virtual void Activated(const string& callsign, IShell* plugin) = 0; + virtual void Deactivated(const string& callsign, IShell* plugin) = 0; + virtual void Unavailable(const string& callsign, IShell* plugin) = 0; + }; + +... + + //! @{ + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + //! First time initialization. Whenever a plugin is loaded, it is offered a Service object with relevant + //! information and services for this particular plugin. The Service object contains configuration information that + //! can be used to initialize the plugin correctly. If Initialization succeeds, return nothing (empty string) + //! If there is an error, return a string describing the issue why the initialisation failed. + //! The Service object is *NOT* reference counted, lifetime ends if the plugin is deactivated. + //! The lifetime of the Service object is guaranteed till the deinitialize method is called. + //! @} + virtual const string Initialize(PluginHost::IShell* shell) = 0; + + //! @{ + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + //! The plugin is unloaded from framework. This is call allows the module to notify clients + //! or to persist information if needed. After this call the plugin will unlink from the service path + //! and be deactivated. The Service object is the same as passed in during the Initialize. + //! After theis call, the lifetime of the Service object ends. + //! @} + virtual void Deinitialize(PluginHost::IShell* shell) = 0; + + //! @{ + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + //! Returns an interface to a JSON struct that can be used to return specific metadata information with respect + //! to this plugin. This Metadata can be used by the MetData plugin to publish this information to the ouside world. + //! @} + virtual string Information() const = 0; +}; + +... +``` + +!!! note + A class implementing this interface, for example, `MyPlugin`, must define all methods declared in `IPlugin`, which allows Thunder to manage plugins uniformly, relying on the interface rather than the specific implementation. + +In the end, by adhering to an interface-based architecture, Thunder ensures that its components remain decoupled and maintainable. This approach not only benefits the framework’s development but also encourages developers using Thunder to adopt best practices in their own projects. The clear separation of interface and implementation simplifies upgrades, enhances flexibility, and makes the system easier to understand and extend. + +Overall, interface-based development is a cornerstone of Thunder’s design philosophy, promoting a clean, modular, and scalable architecture. This ensures that Thunder remains robust and adaptable, capable of evolving alongside the ever-changing demands of embedded systems and the wider software development landscape. + + + +## Abstraction and Portability + +In the development journey, it's crucial for plugin developers to understand the breadth and depth of functionalities already integrated into the framework. While it may be tempting to implement custom features targeting specific operating systems, it's probably almost always more efficient to leverage the extensive capabilities already provided by Thunder. This not only aligns with the principles of portability and scalability but also ensures optimized performance of the plugin. + +One of the core principles guiding the design of Thunder is portability. The framework is engineered to be platform-agnostic, allowing it to seamlessly run across various operating systems and hardware environments. Plugin developers are encouraged to embrace this portability by utilizing Thunder's abstraction layers for interacting with the underlying OS functionalities. + +!!! note + By leveraging Thunder's abstraction, developers can write platform-independent code that remains consistent across different environments, eliminating the need to manage OS-specific implementations and dependencies. + +Thunder can be deployed on numerous platforms, including Linux, Windows, and macOS, with potential support for additional platforms in the future. The key benefit of using the features implemented within the framework rather than developing them locally within your plugin is that you don't have to worry about portability — the framework handles that for you. This is particularly advantageous as it allows developers to focus on the functionality of their plugins rather than the intricacies of different operating systems. + +Moreover, if there are changes in the specifications or functionalities of any operating system, maintaining the system becomes much simpler. Instead of modifying each component (plugin) separately, changes need to be made only within the framework. This centralized approach significantly reduces the maintenance burden and ensures consistency across all plugins. + +!!! warning + As a general rule of thumb, in order to avoid reinventing the wheel, always do the research to make sure that the feature you want to implement is not already available in Thunder. + +### Scalability and Efficient Resource Management + +Thunder is designed to support the concurrent execution of multiple plugins, each with its own set of functionalities and resources. Utilizing Thunder's built-in capabilities ensures that plugins can seamlessly coexist and interact within the framework, without introducing unnecessary overhead or resource contention. This optimized approach not only improves the overall responsiveness of the system but also simplifies the management and deployment of plugins in large-scale environments. + +A prime example of this is the usage of Thunder's `WorkerPool` to handle specific jobs on separate threads instead of creating threads within individual plugins. More detail information about this feature can be found [here](https://rdkcentral.github.io/Thunder/utils/threading/worker-pool/). In the nutshell, the main advantage of this approach is that there are a few threads that wait for a job, execute it, and then return to the waiting state for the next job. This eliminates the overhead associated with creating and destroying threads each time a task needs to be performed. + +!!! note + This is particularly beneficial both for smaller tasks where the time taken to create and destroy a thread could exceed the time required to execute the task itself, as well as for avoiding a scenario when each plugin spawns multiple threads which could lead to serious stability issues. + +Simply put, thanks to the principles of abstraction and portability, Thunder ensures that plugins are robust, maintainable, and scalable. Developers are encouraged to utilize the framework's extensive capabilities, which not only simplifies development but also enhances the overall efficiency and performance of the system. + + + +## Isolation: Out-of-process Plugins + +Besides the fact that in-process plugins in Thunder offer significant advantages in terms of communication efficiency and simplicity, they also consume less memory due to the absence of extra processes. These plugins run within the same memory space as the core framework, allowing for direct function calls and reducing the overhead associated with inter-process communication. + +However, despite these benefits, the use of out-of-process plugins remains crucial for maintaining the overall stability and resilience of the system. + +!!! note + By isolating each plugin in its own process, the framework ensures that any failure or crash within a plugin does not impact the core framework or other plugins. + +This isolation is vital in preventing a single point of failure from cascading through the system, thereby enhancing the robustness and reliability of the entire environment. + +### Ensuring Stability with Out-of-process Plugins + +Out-of-process plugins provide an extra layer of security by running in a separate memory space. This separation means that if a plugin encounters a fatal error, the failure is contained within that process, allowing the core system to continue running uninterrupted. + +!!! warning + This architectural decision is especially important in complex systems with multiple plugins, as it prevents a single faulty plugin from compromising the entire system. + +### Strategic Use of In-process Plugins + +While the primary advantage of out-of-process plugins is their isolation, there are scenarios where in-process plugins are preferable due to their efficiency. An example within Thunder is the `MessageControl` plugin, which aggregates and handles all communication within the framework. Running such a plugin in-process minimizes latency and maximizes performance, which is crucial for high-throughput communication tasks. + +However, incorporating in-process plugins requires meticulous attention to detail to ensure they are robust and free of bugs. This involves rigorous testing, code reviews, and adherence to best practices in software development to minimize the risk of crashes. The benefits of in-process plugins, such as reduced memory footprint and faster communication, justify this additional effort for components that are central to the framework’s operation. + +### Balancing Efficiency and Stability + +The architecture of Thunder exemplifies a balanced approach to plugin management, leveraging both in-process and out-of-process plugins as needed. + +!!! note + In-process plugins are used sensibly for tasks that benefit from close integration and high efficiency, while out-of-process plugins are employed to safeguard the system’s stability. This strategic use of different plugin architectures ensures that Thunder remains both performant and resilient. + +In conclusion, Thunder’s hybrid approach to plugin architecture, combining the strengths of both in-process and out-of-process plugins, ensures that the system remains efficient, stable, and flexible. This thoughtful design underscores Thunder's commitment to delivering a robust platform capable of handling the complexities and demands of modern embedded systems. By isolating potentially unstable components while optimizing critical ones, Thunder achieves a balance that maximizes performance without compromising reliability. + + + +## Minimizing Layers + +In any embedded systems, it's critical to minimize the addition of extra layers to maintain optimal performance and efficiency. Adding unnecessary layers can significantly impact both processing speed and resource utilization. For instance, when a plugin runs within the same process as Thunder, all interactions are handled through local virtual function calls, which are highly efficient. This approach avoids the overhead associated with Remote Procedure Calls (RPC), such as JSON-RPC, which introduce additional latency and processing requirements. + +However, when plugins operate out-of-process, using proxies and inter-process communication becomes unavoidable. In these scenarios, choosing the most efficient communication method is paramount. COM-RPC, for example, offers lower latency and overhead compared to JSON-RPC, making it a preferable choice. + +!!! danger + While both in-process and out-of-process plugins have their own set of benefits and trade-offs, it is universally true that introducing unnecessary communication layers is going to degrade performance. + +Therefore, developers should strive to use the most direct and efficient communication methods available without introducing additional unnecessary steps. + +### Main Advantages + +* **Reduced latency** - minimizing additional communication layers can significantly reduce latency in the system. Each additional layer introduces a delay, which can accumulate and become noticeable, especially in real-time applications. In Thunder, using direct virtual function calls within the same process ensures that interactions are swift and efficient, crucial for maintaining responsiveness. + +* **Lower resource utilization** - extra layers often require additional resources to manage and process communications. By keeping the communication path as direct as possible, systems can avoid unnecessary consumption of CPU cycles and memory. This is particularly important in embedded systems where resources are limited. Thunder's architecture prioritizes this efficiency, ensuring that plugins can interact directly with the framework whenever feasible. + +* **Simplified debugging and maintenance** - fewer layers mean simpler system architecture, making it easier to debug and maintain. When issues arise, having a straightforward communication path allows developers to trace problems more efficiently. In Thunder, minimizing layers means fewer points of potential failure, simplifying the process of identifying and resolving issues. + +* **Enhanced security** - each layer added to the communication path can potentially introduce new security vulnerabilities. By minimizing these layers, the attack surface is reduced, enhancing the overall security of the system. Thunder's design philosophy embraces this principle, ensuring that communication paths are as direct and secure as possible. + +In summary, minimizing unnecessary communication layers is a fundamental principle in Thunder’s architecture, critical for maintaining optimal performance, resource efficiency, and system simplicity. By leveraging Thunder’s direct function calls for in-process plugins and efficient RPC methods for out-of-process scenarios, developers can ensure that their applications are both robust and performant. + + + +## Different RPC Protocols + +Thunder offers two primary communication protocols: *JSON-RPC* and *COM-RPC*, each catering to different needs and use cases. + +### JSON-RPC + +On one hand we have JSON-RPC, which is a lightweight, remote procedure call protocol encoded in JSON. It is particularly useful for external communication with Thunder, as it provides a simple and easy-to-use interface for developers. JSON-RPC is ideal for scenarios where interoperability and ease of integration are paramount, enabling seamless communication with a wide range of clients and services. The use of JSON makes it human-readable and straightforward to debug, making it an excellent choice for development and testing environments. + +In JSON-RPC, communication typically occurs over HTTP or another transport protocol. The client sends a request in the form of a JSON object to the server, specifying the method to be called and any parameters required for the method. The server processes the request, executes the specified method, and returns a JSON response containing the result or an error message if applicable. + +In the context of Thunder, JSON-RPC serves as a fundamental communication protocol between the plugins developed by users and the outside world. Plugins can expose methods and functionalities through JSON-RPC interfaces, allowing to invoke these methods as needed. + +### COM-RPC + +On the other hand, COM-RPC is the cornerstone of Thunder's communication strategy, offering superior performance and efficiency, which are crucial for embedded devices where resources are limited. + +!!! note + COM-RPC is designed to be much faster and more efficient than JSON-RPC, as it involves less overhead and is optimized for high-speed, low-latency communication. + +This efficiency is vital for embedded systems, where memory usage and processing power must be carefully managed. The lean and mean nature of COM-RPC allows Thunder to maintain high performance while running on devices with constrained resources. By leveraging COM-RPC, Thunder can ensure that its services are not only reliable but also capable of meeting the strict demands of embedded environments, making it a robust framework for a wide range of applications. + +Despite the clear advantages of COM-RPC in terms of efficiency and performance, many developers working with Thunder still prefer using JSON-RPC due to its simplicity and ease of use. JSON-RPC's straightforward, human-readable format makes it an attractive choice for quick integrations and debugging, especially during the initial stages of development or when interoperability with various clients is required. + +However, it's important to emphasize that for production environments, particularly in embedded systems where resources are limited, the performance benefits of COM-RPC cannot be overlooked. COM-RPC's optimized, low-overhead communication significantly enhances the framework's efficiency, leading to lower memory usage and faster response times. + +!!! warning + Therefore, we strongly urge developers to invest the effort in utilizing COM-RPC wherever feasible. + +By doing so, they can achieve a much more optimized and performant system, ensuring that Thunder runs at its full potential even on resource-constrained devices. Adopting COM-RPC will ultimately lead to a more robust and scalable application, fully leveraging Thunder's architectural strengths. + + + +### Conclusion + +Thunder's architecture is designed with a strong emphasis on efficiency, stability, and modularity. By leveraging principles like interfaced-based development, efficient communication methods, and minimizing unnecessary layers, Thunder ensures a robust and performant framework for managing plugins in embedded systems. Developers are encouraged to fully utilize Thunder's built-in capabilities to create scalable, maintainable, and high-performance applications. From b61a83f2e6a90f9061e6b6a005cc99fef3578eca Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Thu, 20 Jun 2024 10:51:26 +0200 Subject: [PATCH 20/35] [DOC] Singletons section (#1540) * singleton section added * singletons documentation section added * singletons.md added to mkdocs.yml * warning fixed * formating fix * singletons description addded * [doc] description of singletons added * Update singletons.md --------- Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- docs/utils/singletons.md | 62 ++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 63 insertions(+) create mode 100644 docs/utils/singletons.md diff --git a/docs/utils/singletons.md b/docs/utils/singletons.md new file mode 100644 index 000000000..19240d936 --- /dev/null +++ b/docs/utils/singletons.md @@ -0,0 +1,62 @@ +## What is singleton and why it is used +The Singleton pattern is a design pattern that restricts the instantiation of a class to a single instance. It ensures that only one instance of the class exists throughout the runtime of the program and provides a global point of access to that instance. In addition, they allow for lazy allocation and initialization, whereas global variables will always consume resources. Examples of using singletons can be found in ThunderClientLibraries repository. + +## Singleton and SingletonType +The `SingletonType` class can be used to make a class a singleton get access to an instance (which creates one if that was not done before): +```cpp +Core::SingletonType::Instance() +``` +If a parameter is required for the construction of the class that should be a singleton, Create can be used (and after that access to the singleton instance can be done using the Instance method): +```cpp +Core::SingletonType::Create(connector.c_str()); +``` +`SingletonType` is a templated class designed to streamline the implementation of singleton objects in Thunder. It is intended to be used as a base class for concrete singleton classes and implements constructors and destructors to handle registration and unregistration of singleton instances within a `SingletonList`. + +## disposing singletons + +In general a singleton can be disposed using the Dispose method. Please note was will be highlighted below that calling Instance after Dispose might create a new instance of the Singleton. +All created Singletons cann be disposed at once with: +```cpp +Thunder::Core::Singleton::Dispose(); +``` +This should typically done at the end of an application fully based on the Thunder framework to cleanup all Singletons. As will be highlighted below if it is in a Library based on the Thunder framework you need to be more careful and not call the general Dispose but only cleanup what you created. + +Singletons that use sockets should connect to them before they are registered in the singletons list. This is therefore best done in their constructor. If the connection occurs too late, the singleton may not be cleaned up before the Resource Monitor destructor is called. +Here is an example of making sure a socket connection is opened in the OpenCDMAccessor singleton constructor. +```cpp +OpenCDMAccessor(const TCHAR domainName[]) + : _refCount(1) + , _domain(domainName) + , _engine(Core::ProxyType>::Create()) + , _client() + , _remote(nullptr) + , _adminLock() + , _signal(false, true) + , _interested(0) + , _sessionKeys() +{ + TRACE_L1("Trying to open an OCDM connection @ %s\n", domainName); + Reconnect(); // make sure ResourceMonitor singleton is created before OpenCDMAccessor so the destruction order is correct +} +``` + +When a singleton uses itself (via the instance method) or any other singleton during destruction be very careful to make sure it does not create a new singleton by accident. + +A client library dispose method should not call `Core::Singleton::Dispose()` but only clean up its own internal singletons. +!!!warning + `Core::Singleton::Dispose()` dispose of all singletons in the singletons list. + +Calling this method on a particular singleton will dispose of them all. Instead, we should use `Core::SingletonType<>::Dispose()` with the appropriate type of singleton we want to dispose of specified, or write our own `Dispose()` which will not dispose of all remaining singletons. + +Below is an example of how you SHOULD NOT dispose of a singleton! +```cpp +void opencdm_dispose() { + Core::Singleton::Dispose(); +} +``` +And here an example of the RIGHT way to dispose of a singleton. +```cpp +void opencdm_dispose() { + Core::SingletonType::Dispose(); +} +``` diff --git a/mkdocs.yml b/mkdocs.yml index 30b1ee3ad..d66fb8513 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -50,6 +50,7 @@ nav: - Timers: utils/timers.md - Web Requests: utils/web.md - Sockets: utils/sockets.md + - Singletons: utils/singletons.md - Processes: utils/processes.md - Client Development: - Introduction: client/intro.md From dbfcb83692efb58aa5d4cd5091be1972faa48a10 Mon Sep 17 00:00:00 2001 From: Mateusz Daniluk <121170681+VeithMetro@users.noreply.github.com> Date: Thu, 20 Jun 2024 11:28:14 +0200 Subject: [PATCH 21/35] [Actions] Adding process containers with runC backend to be built in the Linux workflow (#1655) * Fixing warnings in RunC process containers * Adding containers to Actions * Removing PROCESSCONTAINERS_CLIB option as it was the same as RunC * Temporarily using a template from development to test the changes * Using sizeof to get the size of a buffer instead of a fixed value which did not match the buffer size on top of that * Changing back to use template from master --- .github/workflows/Linux build template.yml | 2 ++ Source/extensions/processcontainers/CMakeLists.txt | 4 ---- .../RunCImplementation/RunCImplementation.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Linux build template.yml b/.github/workflows/Linux build template.yml index f10e103f2..8e23e559b 100644 --- a/.github/workflows/Linux build template.yml +++ b/.github/workflows/Linux build template.yml @@ -113,6 +113,8 @@ jobs: -DVOLATILE_PATH="tmp" \ -DLOCALTRACER=ON \ -DWARNING_REPORTING=ON \ + -DPROCESSCONTAINERS=ON \ + -DPROCESSCONTAINERS_RUNC=ON \ ${{steps.regexthunder.outputs.first_match}} cmake --build ${{matrix.build_type}}/build/Thunder --target install diff --git a/Source/extensions/processcontainers/CMakeLists.txt b/Source/extensions/processcontainers/CMakeLists.txt index 3dda39751..996b13834 100644 --- a/Source/extensions/processcontainers/CMakeLists.txt +++ b/Source/extensions/processcontainers/CMakeLists.txt @@ -24,8 +24,6 @@ option(PROCESSCONTAINERS_RUNC "Use RunC backend." OFF) option(PROCESSCONTAINERS_CRUN "Use CRun backend." OFF) -option(PROCESSCONTAINERS_CLIB - "Use c-library backend." OFF) option(PROCESSCONTAINERS_DOBBY "Use Dobby backend." OFF) option(PROCESSCONTAINERS_AWC @@ -45,8 +43,6 @@ elseif(PROCESSCONTAINERS_RUNC) elseif(PROCESSCONTAINERS_CRUN) target_sources(${TARGET} PRIVATE implementations/CRunImplementation/CRunImplementation.cpp ) -elseif(PROCESSCONTAINERS_CLIB) - target_sources(${TARGET} PRIVATE implementations/RunCImplementation/RunCImplementation.cpp) elseif(PROCESSCONTAINERS_DOBBY) target_sources(${TARGET} PRIVATE implementations/DobbyImplementation/DobbyImplementation.cpp) elseif(PROCESSCONTAINERS_AWC) diff --git a/Source/extensions/processcontainers/implementations/RunCImplementation/RunCImplementation.cpp b/Source/extensions/processcontainers/implementations/RunCImplementation/RunCImplementation.cpp index 6cb9782c6..e7c384f35 100644 --- a/Source/extensions/processcontainers/implementations/RunCImplementation/RunCImplementation.cpp +++ b/Source/extensions/processcontainers/implementations/RunCImplementation/RunCImplementation.cpp @@ -18,7 +18,7 @@ */ #include "RunCImplementation.h" -#include "JSON.h" +#include #include namespace Thunder { @@ -108,7 +108,7 @@ namespace ProcessContainers { return runCContainerAdministrator; } - IContainer* RunCContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& configuration) + IContainer* RunCContainerAdministrator::Container(const string& id, IStringIterator& searchpaths, const string& logpath, const string& /* configuration */) { searchpaths.Reset(0); while (searchpaths.Next()) { @@ -142,7 +142,7 @@ namespace ProcessContainers { { } - void RunCContainerAdministrator::Logging(const string& logPath, const string& loggingOptions) + void RunCContainerAdministrator::Logging(const string& /* logPath */, const string& /* loggingOptions */) { // Only container-scope logging } @@ -219,7 +219,7 @@ namespace ProcessContainers { } else { char data[1024]; - process.Output((uint8_t*)data, 2048); + process.Output((uint8_t*)data, sizeof(data)); RunCStatus info; info.FromString(string(data)); From 0c08fe1c9b59ec07e0805209e84f4022575f0bae Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:03:35 +0000 Subject: [PATCH 22/35] [Tests/unit/core] : Remove 'const_cast' in 'test_cyclicbuffer' --- Tests/unit/core/test_cyclicbuffer.cpp | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Tests/unit/core/test_cyclicbuffer.cpp b/Tests/unit/core/test_cyclicbuffer.cpp index f0caa777e..181beb786 100644 --- a/Tests/unit/core/test_cyclicbuffer.cpp +++ b/Tests/unit/core/test_cyclicbuffer.cpp @@ -231,7 +231,7 @@ namespace Tests { EXPECT_EQ(FileSize(bufferName.c_str()), (cyclicBufferSize + sizeof(CyclicBuffer::control))); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); // Check File Exist EXPECT_EQ(IsFileExist(bufferName.c_str()), false); @@ -260,7 +260,7 @@ namespace Tests { EXPECT_EQ(buffer2.Open(), true); // Remove after usage before destruction - const_cast(buffer2.Storage()).Destroy(); + buffer2.Close(); EXPECT_EQ(IsFileExist(bufferName.c_str()), false); } } @@ -286,7 +286,7 @@ namespace Tests { buffer.Storage().Close(); EXPECT_EQ(buffer.Storage().IsOpen(), false); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Create_WithDifferentPermissions) @@ -308,7 +308,7 @@ namespace Tests { EXPECT_EQ(IsValidFilePermissions(bufferName.c_str(), mode), true); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); RestoreFileMask(mask); } { @@ -329,7 +329,7 @@ namespace Tests { EXPECT_EQ(CheckBufferIsSharable(&buffer), true); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); RestoreFileMask(mask); } { @@ -349,7 +349,7 @@ namespace Tests { EXPECT_EQ(IsValidFilePermissions(bufferName.c_str(), mode), true); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); RestoreFileMask(mask); } { @@ -371,7 +371,7 @@ namespace Tests { EXPECT_EQ(buffer.Used(), sizeof(SampleData)); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); RestoreFileMask(mask); } } @@ -396,7 +396,7 @@ namespace Tests { EXPECT_EQ(buffer.Free(), cyclicBufferSize - (sizeof(SampleData) * 3)); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Write_BasedOnFreeSpaceAvailable) { @@ -437,7 +437,7 @@ namespace Tests { EXPECT_EQ(buffer.Free(), static_cast(cyclicBufferSize - previousFreeSpace)); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Read) @@ -483,7 +483,7 @@ namespace Tests { EXPECT_EQ(buffer.Used(), 0u); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Peek) { @@ -535,7 +535,7 @@ namespace Tests { EXPECT_EQ(buffer.Used(), sizeof(test1) + sizeof(test2) + sizeof(test3)); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Flush) { @@ -567,7 +567,7 @@ namespace Tests { EXPECT_EQ(buffer.Free(), cyclicBufferSize); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Reserve) { @@ -589,7 +589,7 @@ namespace Tests { EXPECT_EQ(buffer.Reserve(0), 0u); EXPECT_EQ(buffer.Reserve(51), Core::ERROR_INVALID_INPUT_LENGTH); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Using_DataElementFile) { @@ -615,7 +615,7 @@ namespace Tests { EXPECT_EQ(FileSize(fileName.c_str()), cyclicBufferWithControlDataSize); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); // Check File Exist EXPECT_EQ(IsFileExist(fileName.c_str()), false); @@ -646,7 +646,7 @@ namespace Tests { EXPECT_EQ(FileSize(fileName.c_str()), cyclicBufferWithControlDataSize + offset); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); // Check File Exist EXPECT_EQ(IsFileExist(fileName.c_str()), false); @@ -675,7 +675,7 @@ namespace Tests { EXPECT_EQ(FileSize(fileName.c_str()), cyclicBufferWithControlDataSize + offset); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); // Check File Exist EXPECT_EQ(IsFileExist(fileName.c_str()), false); @@ -722,7 +722,7 @@ namespace Tests { } // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, Write_Overflow_WithOverWrite) { @@ -824,7 +824,7 @@ namespace Tests { EXPECT_EQ(buffer.Free(), static_cast(cyclicBufferSize - size)); // Remove after usage before destruction - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } static int ClonedProcessFunc(void* arg) { Data* data = static_cast(arg); @@ -892,7 +892,7 @@ namespace Tests { EXPECT_EQ(buffer.Size(), 0u); } - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, CheckSharePermissionsFromClonedProcess) { @@ -1032,7 +1032,7 @@ namespace Tests { testAdmin.Sync("server read"); EXPECT_EQ(buffer->Used(), 0u); } - const_cast(buffer->Storage()).Destroy(); + buffer->Close(); delete buffer; if (dataElementFile) { delete dataElementFile; @@ -1146,7 +1146,7 @@ namespace Tests { EXPECT_EQ(buffer.Used(), 0u); testAdmin.Sync("client read"); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } @@ -1229,7 +1229,7 @@ namespace Tests { testAdmin.Sync("server peek"); testAdmin.Sync("server read"); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } @@ -1343,7 +1343,7 @@ namespace Tests { testAdmin.Sync("client flush"); EXPECT_EQ(buffer.Free(), cyclicBufferSize); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } @@ -1361,7 +1361,7 @@ namespace Tests { EXPECT_EQ(buffer.IsLocked(), true); buffer.Unlock(); EXPECT_EQ(buffer.IsLocked(), false); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, LockAlert_WithoutDataPresent) { @@ -1379,7 +1379,7 @@ namespace Tests { EXPECT_EQ(buffer.IsLocked(), true); buffer.Unlock(); EXPECT_EQ(buffer.IsLocked(), false); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, DISABLED_LockUnLock_FromParentAndForks) @@ -1483,7 +1483,7 @@ namespace Tests { testAdmin.Sync("client read"); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } @@ -1644,7 +1644,7 @@ namespace Tests { buffer.Unlock(); EXPECT_EQ(buffer.LockPid(), 0u); testAdmin.Sync("client exit"); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } @@ -1678,7 +1678,7 @@ namespace Tests { event.ResetEvent(); EXPECT_EQ(buffer.IsLocked(), false); threadLock.Stop(); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } TEST(Core_CyclicBuffer, DISABLED_LockUnlock_FromParentAndForks_UsingAlert) { @@ -1773,7 +1773,7 @@ namespace Tests { EXPECT_EQ(buffer.LockPid(), 0u); testAdmin.Sync("client alerted"); - const_cast(buffer.Storage()).Destroy(); + buffer.Close(); } Singleton::Dispose(); } From d3a1d452f261fe2f1c59e4ed7669d6c45fe2625c Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:06:55 +0000 Subject: [PATCH 23/35] [core/CyclicBuffer] : assert on buffer destruction --- Source/core/CyclicBuffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/core/CyclicBuffer.cpp b/Source/core/CyclicBuffer.cpp index 9ba5c58d7..5a3e8c873 100644 --- a/Source/core/CyclicBuffer.cpp +++ b/Source/core/CyclicBuffer.cpp @@ -224,7 +224,8 @@ namespace Core { void CyclicBuffer::Close() { - _buffer.Destroy(); + VARIABLE_IS_NOT_USED bool result = _buffer.Destroy(); + ASSERT(result); _realBuffer = nullptr; _administration = nullptr; } From 8dad5d6826d7ad094cf0c0cae290879fed7bfc32 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:16:58 +0000 Subject: [PATCH 24/35] [Tests/unit/core] : Amend '0c08fe1c9b59ec07e0805209e84f4022575f0bae' --- Tests/unit/core/test_cyclicbuffer.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Tests/unit/core/test_cyclicbuffer.cpp b/Tests/unit/core/test_cyclicbuffer.cpp index 181beb786..33ba8c42e 100644 --- a/Tests/unit/core/test_cyclicbuffer.cpp +++ b/Tests/unit/core/test_cyclicbuffer.cpp @@ -283,11 +283,8 @@ namespace Tests { EXPECT_EQ(buffer.Open(), true); EXPECT_EQ(buffer.Storage().IsOpen(), true); - buffer.Storage().Close(); - EXPECT_EQ(buffer.Storage().IsOpen(), false); - // Remove after usage before destruction buffer.Close(); - + EXPECT_EQ(buffer.Storage().IsOpen(), false); } TEST(Core_CyclicBuffer, Create_WithDifferentPermissions) { From d55a0134822fecc698f5c3b2f59ce84a0ceabd53 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:21:06 +0200 Subject: [PATCH 25/35] Development/library (#1656) * [core/Library] : No 'error' if no error is found. * [Tests/unit/core] : Improve 'test_library' - Avoid name mangling - Add checks on errors --- Source/core/Library.cpp | 2 ++ Tests/unit/core/test_library.cpp | 21 ++++++++++++++------- Tests/unit/core/test_library_helloworld.cpp | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Source/core/Library.cpp b/Source/core/Library.cpp index a4412d150..04575b3c7 100644 --- a/Source/core/Library.cpp +++ b/Source/core/Library.cpp @@ -180,6 +180,8 @@ namespace Core { ASSERT(_refCountedHandle != nullptr); + _error.clear(); + #ifdef __LINUX__ ASSERT(_refCountedHandle->_handle != nullptr); diff --git a/Tests/unit/core/test_library.cpp b/Tests/unit/core/test_library.cpp index f8d81d2e2..dc2aa207c 100644 --- a/Tests/unit/core/test_library.cpp +++ b/Tests/unit/core/test_library.cpp @@ -27,23 +27,30 @@ using namespace Thunder::Core; TEST(Core_Library, simpleSet) { - Library libObj; #ifdef BUILD_ARM const string file = _T("/usr/lib/testdata/libhelloworld.so"); // For QEMU #else const string file = string(BUILD_DIR) + _T("/libhelloworld.so"); // For PC //const string file = _T("/usr/lib/libwpe-0.2.so"); //For box. #endif - const TCHAR* function = _T("Test::HelloWorld()"); + const TCHAR* function = _T("HelloWorld"); const string file1 = _T("libThunder.so"); + Library LibObj1(file.c_str()); + EXPECT_TRUE(LibObj1.Error().empty()); + LibObj1.LoadFunction(function); - Library LibObjTest(file1.c_str()); - Library LibObj2(LibObj1); + EXPECT_TRUE(LibObj1.IsLoaded()); + EXPECT_TRUE(LibObj1.Error().empty()); + + Library LibObj2(LibObj1); // Copy constructor + EXPECT_TRUE(LibObj1.Error().empty()); + EXPECT_TRUE(LibObj2.Error().empty()); + Library LibObj3; - LibObj3 = LibObj2; + LibObj3 = LibObj2; // Copy assignment - EXPECT_TRUE(LibObj1.IsLoaded()); - EXPECT_EQ(LibObj3.Error(), ""); + EXPECT_TRUE(LibObj2.Error().empty()); + EXPECT_TRUE(LibObj3.Error().empty()); // Same as LibObj2 EXPECT_EQ(LibObj3.Name(), file); } diff --git a/Tests/unit/core/test_library_helloworld.cpp b/Tests/unit/core/test_library_helloworld.cpp index ef0554811..aa1f6f3ea 100644 --- a/Tests/unit/core/test_library_helloworld.cpp +++ b/Tests/unit/core/test_library_helloworld.cpp @@ -2,8 +2,8 @@ namespace Thunder{ namespace Test{ - std::string HelloWorld(){ + extern "C" std::string HelloWorld(){ return "Hello World!"; } } -} \ No newline at end of file +} From d88ec1ab666c13e87e1e6004bb4d64571e36f3b9 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Thu, 20 Jun 2024 20:01:17 +0200 Subject: [PATCH 26/35] Development/more cmake (#1657) --- CMakeLists.txt | 21 +++++---- Source/Thunder/CMakeLists.txt | 2 +- Source/Thunder/GenericConfig.cmake | 16 +++---- Source/Thunder/Thunder.conf.in | 2 +- Source/core/CMakeLists.txt | 4 +- Source/extensions/localtracer/CMakeLists.txt | 6 ++- .../privilegedrequest/CMakeLists.txt | 5 ++- cmake/common/CmakeHelperFunctions.cmake | 4 +- cmake/common/CreateLink.cmake | 2 +- cmake/common/HeaderOnlyInstall.cmake | 4 +- docs/introduction/build_linux.md | 44 ++++++------------- docs/introduction/intro.md | 2 +- 12 files changed, 52 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 26b00f485..886d31f6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,8 @@ project(Thunder DESCRIPTION "Thunder framework" HOMEPAGE_URL "https://rdkcentral.github.io/Thunder/") +include(GNUInstallDirs) + set(VERSION ${${PROJECT_NAME}_VERSION}) set(VERSION_MAJOR ${${PROJECT_NAME}_VERSION_MAJOR}) set(VERSION_MINOR ${${PROJECT_NAME}_VERSION_MINOR}) @@ -42,7 +44,6 @@ option(HUMAN_VERSIONED_BINARIES "Create binaries with a human readeable version suffix" ON) option(VERSIONED_LIBRARY_LOADING "Uses the major version (*.so.) to load libraries rather then *.so" OFF) - if (BUILD_REFERENCE) add_definitions (-DBUILD_REFERENCE=${BUILD_REFERENCE}) @@ -56,16 +57,15 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" - "${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/Modules") + "${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/Modules") if (TOOLS_SYSROOT) list(APPEND CMAKE_MODULE_PATH - "${TOOLS_SYSROOT}${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/Modules") + "${TOOLS_SYSROOT}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/Modules") endif() include(platform) include(CmakeHelperFunctions) -include(GNUInstallDirs) set(PLATFORM "PC_UNIX" CACHE STRING "Defines on what platform the application will run") @@ -78,7 +78,7 @@ find_package(ConfigGenerator REQUIRED) if(NOT DEFINED BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS ON CACHE INTERNAL "Enable shared objects by default") - message(STATUS "BUILD_SHARED_LIBS was not set, assuming ${BUILD_SHARED_LIBS}") + message(VERBOSE "Building shared libs") endif() # @@ -89,7 +89,7 @@ if(NOT CMAKE_BUILD_TYPE) message(AUTHOR_WARNING "CMAKE_BUILD_TYPE not set, assuming '${CMAKE_BUILD_TYPE}'") endif() -message(STATUS "CMake build type: '${CMAKE_BUILD_TYPE}'") +message(VERBOSE "CMake build type: '${CMAKE_BUILD_TYPE}'") # Remove optimization flags added by the build system string(REGEX REPLACE "(-g[0123])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -110,18 +110,21 @@ configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/project.cmake.in" install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${NAMESPACE}.cmake" RENAME "${NAMESPACE}Config.cmake" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE} + COMPONENT ${NAMESPACE}_Development) if(CMAKE_VERSION VERSION_LESS 3.20.0 AND LEGACY_CONFIG_GENERATOR) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/config" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE} + COMPONENT ${NAMESPACE}_Development) endif(CMAKE_VERSION VERSION_LESS 3.20.0 AND LEGACY_CONFIG_GENERATOR) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE} + COMPONENT ${NAMESPACE}_Development) if(APPLE) # Mac needed variables diff --git a/Source/Thunder/CMakeLists.txt b/Source/Thunder/CMakeLists.txt index e0be6eb13..fb3c0cdf8 100644 --- a/Source/Thunder/CMakeLists.txt +++ b/Source/Thunder/CMakeLists.txt @@ -107,7 +107,7 @@ install( ) install(DIRECTORY - DESTINATION ${PERSISTENT_PATH}/${NAMESPACE}} COMPONENT ${NAMESPACE}_Runtime + DESTINATION ${PERSISTENT_PATH} COMPONENT ${NAMESPACE}_Runtime DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE ) diff --git a/Source/Thunder/GenericConfig.cmake b/Source/Thunder/GenericConfig.cmake index 2cb0243c4..db6094bb3 100644 --- a/Source/Thunder/GenericConfig.cmake +++ b/Source/Thunder/GenericConfig.cmake @@ -23,19 +23,19 @@ set(BINDING "0.0.0.0" CACHE STRING "The binding interface") set(IDLE_TIME 180 CACHE STRING "Idle time") set(SOFT_KILL_CHECK_WAIT_TIME 10 CACHE STRING "Soft kill check waiting time") set(HARD_KILL_CHECK_WAIT_TIME 4 CACHE STRING "Hard kill check waiting time") -set(PERSISTENT_PATH "/root" CACHE STRING "Persistent path") -set(DATA_PATH "${CMAKE_INSTALL_FULL_DATAROOTDIR}/${NAMESPACE}" CACHE STRING "Data path") -set(SYSTEM_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/plugins" CACHE STRING "System path") -set(WEBSERVER_PATH "/boot/www" CACHE STRING "Root path for the HTTP server") +set(PERSISTENT_PATH "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/${NAMESPACE}" CACHE PATH "Persistent path") +set(DATA_PATH "${CMAKE_INSTALL_FULL_DATAROOTDIR}/${NAMESPACE}" CACHE PATH "Data path") +set(SYSTEM_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/plugins" CACHE PATH "System path") +set(WEBSERVER_PATH "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/www/html" CACHE PATH "Root path for the HTTP server") set(WEBSERVER_PORT 8080 CACHE STRING "Port for the HTTP server") -set(PROXYSTUB_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/proxystubs" CACHE STRING "Proxy stub path") -set(POSTMORTEM_PATH "/opt/minidumps" CACHE STRING "Core file path to do the postmortem of the crash") +set(PROXYSTUB_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/${NAMESPACE_LIB}/proxystubs" CACHE PATH "Proxy stub path") +set(POSTMORTEM_PATH "/opt/minidumps" CACHE PATH "Core file path to do the postmortem of the crash") set(MESSAGECONTROL_PATH "MessageDispatcher" CACHE STRING "MessageControl base path to create message files") set(MESSAGING_PORT 0 CACHE STRING "The port for the messaging") set(MESSAGING_STDOUT false CACHE STRING "Enable message rederict from stdout") set(MESSAGING_STDERR false CACHE STRING "Enable message rederict from stderr") set(MESSAGING_DATASIZE 20480 CACHE STRING "Size of the data buffer in bytes [max 63KB]") -set(CONFIG_INSTALL_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${NAMESPACE}" CACHE STRING "Install location of the configuration") +set(CONFIG_INSTALL_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${NAMESPACE}" CACHE PATH "Install location of the configuration") set(IPV6_SUPPORT false CACHE STRING "Controls if should application supports ipv6") set(LEGACY_INITIALZE false CACHE STRING "Enables legacy Plugin Initialize behaviour (Deinit not called on failed Init)") set(PRIORITY 0 CACHE STRING "Change the nice level [-20 - 20]") @@ -79,7 +79,7 @@ endif() map_set(${CONFIG} idletime ${IDLE_TIME}) map_set(${CONFIG} softkillcheckwaittime ${SOFT_KILL_CHECK_WAIT_TIME}) map_set(${CONFIG} hardkillcheckwaittime ${HARD_KILL_CHECK_WAIT_TIME}) -map_set(${CONFIG} persistentpath ${PERSISTENT_PATH}/${NAMESPACE}) +map_set(${CONFIG} persistentpath ${PERSISTENT_PATH}) map_set(${CONFIG} volatilepath ${VOLATILE_PATH}) map_set(${CONFIG} datapath ${DATA_PATH}) map_set(${CONFIG} systempath ${SYSTEM_PATH}) diff --git a/Source/Thunder/Thunder.conf.in b/Source/Thunder/Thunder.conf.in index 748082a40..48c939727 100644 --- a/Source/Thunder/Thunder.conf.in +++ b/Source/Thunder/Thunder.conf.in @@ -5,7 +5,7 @@ ipv6 = '@IPV6_SUPPORT@' idletime = '@IDLE_TIME@' softkillcheckwaittime = '@SOFT_KILL_CHECK_WAIT_TIME@' hardkillcheckwaittime = '@HARD_KILL_CHECK_WAIT_TIME@' -persistentpath = '@PERSISTENT_PATH@/@NAMESPACE@' +persistentpath = '@PERSISTENT_PATH@' volatilepath = '@VOLATILE_PATH@' datapath = '@DATA_PATH@' systempath = '@SYSTEM_PATH@' diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index f31b83c0d..c234636bd 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -23,7 +23,7 @@ find_package(ExecInfo) find_package(LIBRT) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h" @ONLY) -message(STATUS "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h") +message(VERBOSE "Generated ${CMAKE_CURRENT_BINARY_DIR}/generated/core/Version.h") add_library(${TARGET} Module.cpp @@ -157,7 +157,7 @@ target_compile_options (${TARGET} PRIVATE -Wno-psabi) # All build flags that are applicable to the whole system should be set here in the # core since the core is included everywhere so if they are set here, they are # picked up everywhere! -if(DISABLE_TRACING) +if(DISABLE_TRACING OR NOT ENABLED_TRACING_LEVEL) target_compile_definitions(${TARGET} PUBLIC _TRACE_LEVEL=0) message(STATUS "Force trace level to 0") else() diff --git a/Source/extensions/localtracer/CMakeLists.txt b/Source/extensions/localtracer/CMakeLists.txt index 3a2a7c838..a978c7e84 100644 --- a/Source/extensions/localtracer/CMakeLists.txt +++ b/Source/extensions/localtracer/CMakeLists.txt @@ -1,4 +1,8 @@ -project(LocalTracer LANGUAGES CXX) +project(LocalTracer + VERSION 0.0.1 + DESCRIPTION "Library to get tracing locally from e.g. your test code on the stdout." + LANGUAGES CXX) + cmake_minimum_required(VERSION 3.15) set(MODULE_NAME ${NAMESPACE}LocalTracer) diff --git a/Source/extensions/privilegedrequest/CMakeLists.txt b/Source/extensions/privilegedrequest/CMakeLists.txt index 0bfbb22da..a64eb7e6d 100644 --- a/Source/extensions/privilegedrequest/CMakeLists.txt +++ b/Source/extensions/privilegedrequest/CMakeLists.txt @@ -15,7 +15,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -project(PrivilegedRequest LANGUAGES CXX) +project(PrivilegedRequest + VERSION 1.0.0 + DESCRIPTION "With PrivilegedRequest you can make a file descriptor available to other processes." + LANGUAGES CXX) cmake_minimum_required(VERSION 3.15) diff --git a/cmake/common/CmakeHelperFunctions.cmake b/cmake/common/CmakeHelperFunctions.cmake index 5490c8000..78fd3b245 100644 --- a/cmake/common/CmakeHelperFunctions.cmake +++ b/cmake/common/CmakeHelperFunctions.cmake @@ -376,7 +376,7 @@ function(InstallCMakeConfig) VERSION ${_version} COMPATIBILITY SameMajorVersion) - message(STATUS "${_target} added support for cmake consumers via '${_name}Config.cmake'") + message(VERBOSE "${_target} added support for cmake consumers via '${_name}Config.cmake'") if(NOT "${_type}" STREQUAL "INTERFACE_LIBRARY") # The alias is used by local targets project @@ -608,7 +608,7 @@ function(InstallPackageConfig) endif() endforeach() - message(STATUS "${_target} added support for generic consumers via ${_pc_filename}") + message(VERBOSE "${_target} added support for generic consumers via ${_pc_filename}") configure_file( "${_pc_template}" "${CMAKE_CURRENT_BINARY_DIR}/${_pc_filename}" diff --git a/cmake/common/CreateLink.cmake b/cmake/common/CreateLink.cmake index 0a7018cea..ae8d5be2f 100644 --- a/cmake/common/CreateLink.cmake +++ b/cmake/common/CreateLink.cmake @@ -13,7 +13,7 @@ function(CreateLink) cmake_parse_arguments(Argument "${optionsArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - message(STATUS "Creating symlink ${Argument_LINK} -> ${Argument_TARGET}") + message(VERBOSE "Creating symlink ${Argument_LINK} -> ${Argument_TARGET}") get_filename_component(LINK_DIR ${Argument_LINK} DIRECTORY) file(MAKE_DIRECTORY "${LINK_DIR}") diff --git a/cmake/common/HeaderOnlyInstall.cmake b/cmake/common/HeaderOnlyInstall.cmake index 93ca517b6..e2f569682 100644 --- a/cmake/common/HeaderOnlyInstall.cmake +++ b/cmake/common/HeaderOnlyInstall.cmake @@ -82,7 +82,7 @@ function(HeaderOnlyInstallCMakeConfig) VERSION ${_version} COMPATIBILITY SameMajorVersion) - message(STATUS "${TARGET} added support for cmake consumers via '${_name}Config.cmake'") + message(VERBOSE "${TARGET} added support for cmake consumers via '${_name}Config.cmake'") if(NOT "${_type}" STREQUAL "INTERFACE_LIBRARY" OR Argument_TREAT_AS_NORMAL) # The alias is used by local targets project @@ -294,7 +294,7 @@ function(HeaderOnlyInstallPackageConfig) endif() endforeach() - message(STATUS "${TARGET} added support for generic consumers via ${_pc_filename}") + message(VERBOSE "${TARGET} added support for generic consumers via ${_pc_filename}") configure_file( "${_pc_template}" "${CMAKE_CURRENT_BINARY_DIR}/${_pc_filename}" diff --git a/docs/introduction/build_linux.md b/docs/introduction/build_linux.md index 15ebaa4fd..c8ccb5373 100644 --- a/docs/introduction/build_linux.md +++ b/docs/introduction/build_linux.md @@ -37,7 +37,7 @@ git clone https://github.com/rdkcentral/ThunderTools.git ``` Next, we need to run the following commands to build and then install the code generators inside ThunderTools: ```shell -cmake -G Ninja -S ThunderTools -B build/ThunderTools -DCMAKE_INSTALL_PREFIX="install/usr" +cmake -G Ninja -S ThunderTools -B build/ThunderTools -DCMAKE_INSTALL_PREFIX="install" cmake --build build/ThunderTools --target install ``` @@ -54,17 +54,12 @@ Run the following commands to build and then install Thunder. The available `-DC ```shell cmake -G Ninja -S Thunder -B build/Thunder \ --DBUILD_SHARED_LIBS=ON \ -DBINDING="127.0.0.1" \ -DCMAKE_BUILD_TYPE="Debug" \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" \ --DDATA_PATH="${PWD}/install/usr/share/Thunder" \ --DPERSISTENT_PATH="${PWD}/install/var/thunder" \ +-DCMAKE_INSTALL_PREFIX="install" \ -DPORT="55555" \ --DPROXYSTUB_PATH="${PWD}/install/usr/lib/thunder/proxystubs" \ --DSYSTEM_PATH="${PWD}/install/usr/lib/thunder/plugins" \ --DVOLATILE_PATH="tmp" +-DTOOLS_SYSROOT="${PWD}" \ +-DINITV_SCRIPT=OFF cmake --build build/Thunder --target install ``` @@ -84,8 +79,7 @@ Run the following commands to build and then install ThunderInterfaces: ```shell cmake -G Ninja -S ThunderInterfaces -B build/ThunderInterfaces \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" +-DCMAKE_INSTALL_PREFIX="install" cmake --build build/ThunderInterfaces --target install ``` @@ -107,24 +101,18 @@ In the command below, there is a complete list of plugins that do not require an ```shell cmake -G Ninja -S ThunderNanoServices -B build/ThunderNanoServices \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" \ +-DCMAKE_INSTALL_PREFIX="install" \ -DPLUGIN_COMMANDER=ON \ --DPLUGIN_DHCPSERVER=ON \ -DPLUGIN_DIALSERVER=ON \ -DPLUGIN_DICTIONARY=ON \ -DPLUGIN_FILETRANSFER=ON \ --DPLUGIN_IOCONNECTOR=ON \ -DPLUGIN_INPUTSWITCH=ON \ --DPLUGIN_NETWORKCONTROL=ON \ -DPLUGIN_PROCESSMONITOR=ON \ -DPLUGIN_RESOURCEMONITOR=ON \ -DPLUGIN_SYSTEMCOMMANDS=ON \ -DPLUGIN_SWITCHBOARD=ON \ -DPLUGIN_WEBPROXY=ON \ --DPLUGIN_WEBSERVER=ON \ --DPLUGIN_WEBSHELL=ON \ --DPLUGIN_WIFICONTROL=ON +-DPLUGIN_WEBSHELL=ON cmake --build build/ThunderNanoServices --target install ``` @@ -143,11 +131,8 @@ In the command below, there is a complete list of plugins that do not require an ```shell cmake -G Ninja -S ThunderNanoServicesRDK -B build/ThunderNanoServicesRDK \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" \ --DPLUGIN_DEVICEIDENTIFICATION=ON \ +-DCMAKE_INSTALL_PREFIX="install" \ -DPLUGIN_DEVICEINFO=ON \ --DPLUGIN_LOCATIONSYNC=ON \ -DPLUGIN_MESSAGECONTROL=ON \ -DPLUGIN_MESSENGER=ON \ -DPLUGIN_MONITOR=ON \ @@ -173,12 +158,10 @@ In the command below, there is a complete list of client libraries that do not r ```shell cmake -G Ninja -S ThunderClientLibraries -B build/ThunderClientLibraries \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" \ +-DCMAKE_INSTALL_PREFIX="install" \ -DBLUETOOTHAUDIOSINK=ON \ -DDEVICEINFO=ON \ -DDISPLAYINFO=ON \ --DLOCALTRACER=ON \ -DSECURITYAGENT=ON \ -DPLAYERINFO=ON \ -DPROTOCOLS=ON \ @@ -205,8 +188,7 @@ Run the following commands to build and then install ThunderUI: ```shell cmake -G Ninja -S ThunderUI -B build/ThunderUI \ --DCMAKE_INSTALL_PREFIX="install/usr" \ --DCMAKE_MODULE_PATH="${PWD}/install/usr/include/Thunder/Modules" +-DCMAKE_INSTALL_PREFIX="install" cmake --build build/ThunderUI --target install ``` @@ -219,10 +201,10 @@ After everything has been built and installed correctly, we can run Thunder. Since we installed Thunder in a custom installation directory, we need to provide an `LD_LIBRARY_PATH` to that location and set `PATH` to include the `bin` directory. If the libraries are installed in system-wide locations (e.g. `/usr/lib` and `/usr/bin`) then those environment variables are not required ```shell -export LD_LIBRARY_PATH=${PWD}/install/usr/lib:${LD_LIBRARY_PATH} -export PATH=${PWD}/install/usr/bin:${PATH} +export LD_LIBRARY_PATH=${PWD}/install/lib:${LD_LIBRARY_PATH} +export PATH=${PWD}/install/bin:${PATH} -$ Thunder -f -c ${PWD}/install/etc/Thunder/config.json +Thunder -f -c ${PWD}/install/etc/Thunder/config.json ``` The following arguments should be specified to the Thunder binary: diff --git a/docs/introduction/intro.md b/docs/introduction/intro.md index 20e766218..3e2ed0d8e 100644 --- a/docs/introduction/intro.md +++ b/docs/introduction/intro.md @@ -4,7 +4,7 @@ ## Introduction -Thunder (aka Thunder) is developed by [Metrological](https://www.metrological.com/) (a Comcast company), and provides a way for STB operators to implement business-logic in a modular way using plugins, and a consistent way for applications to control and query those plugins. By using a plugin-based architecture, it is possible to build a device with only the specific features that are required for that particular device. +Thunder is developed by [Metrological](https://www.metrological.com/) (a Comcast company), and provides a way for STB operators to implement business-logic in a modular way using plugins, and a consistent way for applications to control and query those plugins. By using a plugin-based architecture, it is possible to build a device with only the specific features that are required for that particular device. !!! tip Do not confuse Thunder and [WPEWebKit](https://github.com/WebPlatformForEmbedded/WPEWebKit/). Whilst both are maintained by the Metrological/WPE team, they are not related. [WPEWebKit](https://github.com/WebPlatformForEmbedded/WPEWebKit/) is a fork of the WebKit browser for embedded devices, and shares no code with Thunder From b1705a34a5a7116e229a56ed19367125d45cef1d Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Thu, 20 Jun 2024 22:42:45 +0200 Subject: [PATCH 27/35] Move operator issue (#1660) --- Source/core/JSON.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/core/JSON.h b/Source/core/JSON.h index a9a082e2b..bc93bd1bd 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -3121,7 +3121,7 @@ namespace Core { : _state(std::move(move._state)) , _count(std::move(move._count)) , _data(std::move(move._data)) - , _iterator(std::move(move._iterator)) + , _iterator(_data) { } @@ -3139,8 +3139,8 @@ namespace Core { { _state = std::move(move._state); _data = std::move(move._data); - _iterator = IteratorType(_data); _count = std::move(move._count); + _iterator.Reset(); return (*this); } @@ -3149,8 +3149,8 @@ namespace Core { { _state = RHS._state; _data = RHS._data; - _iterator = IteratorType(_data); _count = RHS._count; + _iterator.Reset(); return (*this); } From f1083e86ef39c1c4eb2caca4966d22679d87b7b0 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Thu, 20 Jun 2024 23:05:43 +0200 Subject: [PATCH 28/35] Re-enable message exception (#1653) * [core / Tests/unit/core] : Fix build 'test_messagException' Add missing 'EXTERNAL' to make the API visible outside the core library. * [core//MessageException] : Replace deprecated 'throw' by 'noexcept'. * [Tests/unit/core] : disable 'test_library' to investigate stack smashing * [Tests/unit/core] : disable 'test_memberavailability' to investigate buffer overflow * [Tests/unit/core] : disable 'test_ipc' to investigate buffer overflow * [Tests/unit/core] : disable 'test_ipcclient' to investigate stack smashing. * Changing the buffer size to fit everything and avoid stack overflow * [Tests/unit/core] : Remove use of char-array and re-enable disabled tests * [core/MessageException] : replace 'throw()' by 'noexcept(true)' * [core/MessageException] : make 'MessageException' inline * [core] : purge VS projects files to deleted references to 'MessageException.cpp' * [core/MessageException] : delete copy / move constuctors / assignment operators. * [core/MessageException] : Incorporate feedback. - Restore default value for the second parameter - Make the constructor expplicit * [core/MessageException] : Use delegating constructors --------- Co-authored-by: Pierre Wielders Co-authored-by: Mateusz Daniluk <121170681+VeithMetro@users.noreply.github.com> --- Source/core/CMakeLists.txt | 1 - Source/core/MessageException.cpp | 48 ----------------------- Source/core/MessageException.h | 38 ++++++++++++++---- Source/core/core.vcxproj | 3 +- Source/core/core.vcxproj.filters | 5 +-- Tests/unit/core/CMakeLists.txt | 2 +- Tests/unit/core/test_messageException.cpp | 31 ++++++--------- 7 files changed, 47 insertions(+), 81 deletions(-) delete mode 100644 Source/core/MessageException.cpp diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index c234636bd..ddacb09c8 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -36,7 +36,6 @@ add_library(${TARGET} JSON.cpp JSONRPC.cpp Library.cpp - MessageException.cpp Netlink.cpp NetworkInfo.cpp NodeId.cpp diff --git a/Source/core/MessageException.cpp b/Source/core/MessageException.cpp deleted file mode 100644 index 1be7b1420..000000000 --- a/Source/core/MessageException.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2020 Metrological - * - * Licensed 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 - -#include "MessageException.h" -#include "Serialization.h" - -namespace Thunder { -namespace Core { - -PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) - MessageException::MessageException(const string& message, bool inclSysMsg) throw() - : m_Message(message) - { - if (inclSysMsg) { - m_Message.append(_T(": ")); - m_Message.append(Core::ToString(strerror(errno))); - } - } -POP_WARNING() - - MessageException::~MessageException() throw() - { - } - - const TCHAR* MessageException::Message() const throw() - { - return m_Message.c_str(); - } -} -} // namespace Solution::Core diff --git a/Source/core/MessageException.h b/Source/core/MessageException.h index ca5ff0997..5dfa5e9f3 100644 --- a/Source/core/MessageException.h +++ b/Source/core/MessageException.h @@ -21,23 +21,47 @@ #define EXCEPTION_H #include // For exception class +#include #include "Module.h" #include "Portability.h" #include "TextFragment.h" +#include "Serialization.h" namespace Thunder { namespace Core { - class MessageException : public std::exception { - private: - MessageException(); - + class MessageException : public std::exception { public: - MessageException(const string& message, bool inclSysMsg = false) throw(); - ~MessageException() throw(); + MessageException() = delete; + MessageException(const MessageException&) = delete; + MessageException(MessageException&&) = delete; + MessageException& operator=(const MessageException&) = delete; + MessageException& operator=(MessageException&&) = delete; + +PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) + inline explicit MessageException(const string& message) noexcept(true) : MessageException(message, false) + { + } + + inline explicit MessageException(const string& message, bool inclSysMsg) noexcept(true) + : m_Message(message) + { + if (inclSysMsg) { + m_Message.append(_T(": ")); + m_Message.append(Core::ToString(strerror(errno))); + } + } +POP_WARNING() + + inline ~MessageException() noexcept(true) + { + } - const TCHAR* Message() const throw(); + inline const TCHAR* Message() const noexcept(true) + { + return m_Message.c_str(); + } private: string m_Message; // Exception message diff --git a/Source/core/core.vcxproj b/Source/core/core.vcxproj index 9c78f3883..c41950e92 100644 --- a/Source/core/core.vcxproj +++ b/Source/core/core.vcxproj @@ -113,7 +113,6 @@ - @@ -306,4 +305,4 @@ - \ No newline at end of file + diff --git a/Source/core/core.vcxproj.filters b/Source/core/core.vcxproj.filters index caa7b0e2f..cde148793 100644 --- a/Source/core/core.vcxproj.filters +++ b/Source/core/core.vcxproj.filters @@ -287,9 +287,6 @@ Source Files - - Source Files - Source Files @@ -372,4 +369,4 @@ Source Files - \ No newline at end of file + diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index eafc39959..34e548504 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -42,7 +42,7 @@ add_executable(${TEST_RUNNER_NAME} test_lockablecontainer.cpp test_measurementtype.cpp test_memberavailability.cpp - #test_messageException.cpp + test_messageException.cpp test_networkinfo.cpp test_nodeid.cpp test_numbertype.cpp diff --git a/Tests/unit/core/test_messageException.cpp b/Tests/unit/core/test_messageException.cpp index df07f1439..377d17d2f 100644 --- a/Tests/unit/core/test_messageException.cpp +++ b/Tests/unit/core/test_messageException.cpp @@ -27,22 +27,17 @@ using namespace Thunder::Core; TEST(test_messageException, simple_messageException) { - std::string msg = "Testing the message exception."; - MessageException exception(msg.c_str(),false); - EXPECT_STREQ(exception.Message(),msg.c_str()); - - MessageException exception1(msg.c_str(),true); - char buffer[50]; - string status = ": File exists"; - snprintf(buffer, msg.size()+status.size()+1, "%s%s",msg.c_str(),status.c_str()); -#ifdef BUILD_ARM - if (strcmp(exception1.Message(), buffer) != 0) { -#else - if (strcmp(exception1.Message(), buffer) != 0) { -#endif - memset(buffer, 0, sizeof buffer); - status = ": No such file or directory"; - snprintf(buffer, msg.size()+status.size()+1, "%s%s",msg.c_str(),status.c_str()); - } - EXPECT_STREQ(exception1.Message(),buffer); + const std::string msg = "Testing the message exception."; + + // No 'error' concatenated + MessageException exception(msg, false); + + EXPECT_STREQ(exception.Message(), msg.c_str()); + + // 'error' concatenated + MessageException exception1(msg, true); + + const string result = msg + ": No such file or directory"; + + EXPECT_STREQ(exception1.Message(), result.c_str()); } From 865eb751bf5c86d7d83741447d536da04f738429 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Fri, 21 Jun 2024 10:08:18 +0200 Subject: [PATCH 29/35] [TRACKING] Make sure leaking proxies can be tracked and reported... (#1661) * [TRACKING] Make sure leaking proxies can be tracked and reported... Now it is also tested :-) And as a bonus we pass the name of the interface as well :-) * Update Controller.cpp * Update Controller.cpp --- Source/Thunder/Controller.cpp | 7 ++++-- Source/Thunder/ExampleConfigWindows.json | 3 ++- Source/com/Administrator.cpp | 29 ++++++++++++++---------- Source/com/IUnknown.h | 11 +++++++-- Source/plugins/IController.h | 1 + 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/Source/Thunder/Controller.cpp b/Source/Thunder/Controller.cpp index ac5c85635..61a2c3498 100644 --- a/Source/Thunder/Controller.cpp +++ b/Source/Thunder/Controller.cpp @@ -727,7 +727,10 @@ namespace Plugin { PluginHost::Metadata::COMRPC::Proxy& info(entry.Proxies.Add()); info.Instance = proxy->Implementation(); info.Interface = proxy->InterfaceId(); - info.Count = proxy->ReferenceCount(); + info.Name = Core::ClassName(proxy->Name()).Text(); + // Subtract one for the Thunder syatem that keeps track of this + //proxy for leakage reporting! + info.Count = proxy->ReferenceCount() - 1; } } ); @@ -1252,7 +1255,7 @@ namespace Plugin { while (it2.Next() == true) { auto const& entry = it2.Current(); - proxies.push_back({ entry.Interface.Value(), entry.Instance.Value(), entry.Count.Value() }); + proxies.push_back({ entry.Interface.Value(), entry.Name.Value(), entry.Instance.Value(), entry.Count.Value() }); } break; diff --git a/Source/Thunder/ExampleConfigWindows.json b/Source/Thunder/ExampleConfigWindows.json index b9f4af26a..7e0a91af3 100644 --- a/Source/Thunder/ExampleConfigWindows.json +++ b/Source/Thunder/ExampleConfigWindows.json @@ -400,7 +400,8 @@ "url": "http://netflix.com/tv", "sleep": "5", "single": false, - "crash": false, + "crash": true, + "leak": true, "root": { "mode": "Local" } diff --git a/Source/com/Administrator.cpp b/Source/com/Administrator.cpp index df630928e..df62df452 100644 --- a/Source/com/Administrator.cpp +++ b/Source/com/Administrator.cpp @@ -126,26 +126,27 @@ namespace RPC { while ((entry != index->second.end()) && ((*entry) != &proxy)) { entry++; } + + ASSERT(entry != index->second.end()); + if (entry != index->second.end()) { index->second.erase(entry); removed = true; if (index->second.size() == 0) { _channelProxyMap.erase(index); } - else { - // If it is not found, check the dangling map - Proxies::iterator index = std::find(_danglingProxies.begin(), _danglingProxies.end(), &proxy); - - if (index != _danglingProxies.end()) { - _danglingProxies.erase(index); - } - else { - TRACE_L1("Could not find the Proxy entry to be unregistered from a channel perspective."); - } - } } } else { - TRACE_L1("Could not find the Proxy entry to be unregistered from a channel perspective."); + // If the channel nolonger exists, check the dangling map + Proxies::iterator index = std::find(_danglingProxies.begin(), _danglingProxies.end(), &proxy); + + if (index != _danglingProxies.end()) { + _danglingProxies.erase(index); + removed = true; + } + else { + TRACE_L1("Could not find the Proxy entry to be unregistered from a channel perspective."); + } } _adminLock.Unlock(); @@ -432,6 +433,10 @@ namespace RPC { for (auto entry : index->second) { entry->Invalidate(); _danglingProxies.emplace_back(entry); + + // This is actually for the pendingProxies to be reported + // dangling!! + entry->AddRef(); } // The _channelProxyMap does have a reference for each Proxy it // holds, so it is safe to just move the vector from the map to diff --git a/Source/com/IUnknown.h b/Source/com/IUnknown.h index 89fc25d31..522b8af85 100644 --- a/Source/com/IUnknown.h +++ b/Source/com/IUnknown.h @@ -138,7 +138,7 @@ namespace ProxyStub { UnknownProxy& operator=(UnknownProxy&&) = delete; UnknownProxy& operator=(const UnknownProxy&) = delete; - UnknownProxy(const Core::ProxyType& channel, const Core::instance_id& implementation, const uint32_t interfaceId, const bool outbound, Core::IUnknown& parent) + UnknownProxy(const Core::ProxyType& channel, const Core::instance_id& implementation, const uint32_t interfaceId, const bool outbound, Core::IUnknown& parent, const char* name) : _adminLock() , _refCount(1) , _mode(outbound ? 0 : CACHING_ADDREF) @@ -147,6 +147,7 @@ namespace ProxyStub { , _parent(parent) , _channel(channel) , _remoteReferences(1) + , _name(name) { } virtual ~UnknownProxy() = default; @@ -395,6 +396,9 @@ namespace ProxyStub { return (result); } + inline const char* Name() const { + return (_name); + } private: friend RPC::Administrator; @@ -442,6 +446,7 @@ namespace ProxyStub { Core::IUnknown& _parent; mutable Core::ProxyType _channel; uint32_t _remoteReferences; + const char* _name; }; template @@ -451,12 +456,14 @@ namespace ProxyStub { using IPCMessage = Core::ProxyType; public: + UnknownProxyType(UnknownProxyType&&) = delete; UnknownProxyType(const UnknownProxyType&) = delete; + UnknownProxyType& operator=(UnknownProxyType&&) = delete; UnknownProxyType& operator=(const UnknownProxyType&) = delete; PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) UnknownProxyType(const Core::ProxyType& channel, const Core::instance_id& implementation, const bool outbound) - : _unknown(channel, implementation, INTERFACE::ID, outbound, *this) + : _unknown(channel, implementation, INTERFACE::ID, outbound, *this, typeid(INTERFACE).name()) { } POP_WARNING() diff --git a/Source/plugins/IController.h b/Source/plugins/IController.h index 0075ece19..7d845bc24 100644 --- a/Source/plugins/IController.h +++ b/Source/plugins/IController.h @@ -245,6 +245,7 @@ namespace Controller { struct Proxy { uint32_t Interface /* @brief Interface ID */; + string Name /* @brief The fully qualified name of the interface */; Core::instance_id Instance /* @brief Instance ID */; uint32_t Count /* @brief Reference count */; }; From d36af0827d1ea1f9d0f433a935ab6ae47e5e4844 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Mon, 24 Jun 2024 09:30:57 +0200 Subject: [PATCH 30/35] [INTERFACE] Prepare for the upcoming IDispatcher Interface changes for R5! (#1664) --- Source/Thunder/PluginServer.cpp | 31 +++++++++++++++++++++---------- Source/Thunder/PluginServer.h | 8 +++----- Source/plugins/CMakeLists.txt | 2 +- Source/plugins/IDispatcher.h | 25 +++++++++++++------------ Source/plugins/JSONRPC.h | 33 +++++++++++---------------------- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/Source/Thunder/PluginServer.cpp b/Source/Thunder/PluginServer.cpp index 8a82aa43a..51ffe48fd 100644 --- a/Source/Thunder/PluginServer.cpp +++ b/Source/Thunder/PluginServer.cpp @@ -416,17 +416,18 @@ namespace PluginHost { SYSLOG(Logging::Startup, (_T("Activation of plugin [%s]:[%s], failed. Error [%s]"), className.c_str(), callSign.c_str(), ErrorMessage().c_str())); + _reason = reason::INITIALIZATION_FAILED; + _administrator.Deinitialized(callSign, this); + if( _administrator.Configuration().LegacyInitialize() == false ) { - Deactivate(reason::INITIALIZATION_FAILED); - } else { - _reason = reason::INITIALIZATION_FAILED; - _administrator.Deinitialized(callSign, this); - Lock(); - ReleaseInterfaces(); - State(DEACTIVATED); - Unlock(); + REPORT_DURATION_WARNING({ _handler->Deinitialize(this); }, WarningReporting::TooLongPluginState, WarningReporting::TooLongPluginState::StateChange::DEACTIVATION, callSign.c_str()); } + Lock(); + ReleaseInterfaces(); + State(DEACTIVATED); + Unlock(); + } else { const Core::EnumerateType textReason(why); const string webUI(PluginHost::Service::Configuration().WebUI.Value()); @@ -435,7 +436,12 @@ namespace PluginHost { } if (_jsonrpc != nullptr) { - _jsonrpc->Activate(this); + PluginHost::IShell::IConnectionServer::INotification* sink = nullptr; + _jsonrpc->Attach(sink, this); + if (sink != nullptr) { + Register(sink); + sink->Release(); + } } if (_external.Connector().empty() == false) { @@ -579,7 +585,12 @@ namespace PluginHost { Lock(); if (_jsonrpc != nullptr) { - _jsonrpc->Deactivate(); + PluginHost::IShell::IConnectionServer::INotification* sink = nullptr; + _jsonrpc->Detach(sink); + if (sink != nullptr) { + Unregister(sink); + sink->Release(); + } } if (_external.Connector().empty() == false) { diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 6f92ea2d4..f0c7786f7 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -1439,10 +1439,8 @@ namespace PluginHost { _textSocket = newIF->QueryInterface(); _rawSocket = newIF->QueryInterface(); _webSecurity = newIF->QueryInterface(); - IDispatcher* jsonrpc = newIF->QueryInterface(); - if (jsonrpc != nullptr) { - _jsonrpc = jsonrpc->Local(); - } + _jsonrpc = newIF->QueryInterface(); + _composit.AquireInterfaces(newIF); if (_webSecurity == nullptr) { _webSecurity = _administrator.Configuration().Security(); @@ -1540,7 +1538,7 @@ namespace PluginHost { ITextSocket* _textSocket; IChannel* _rawSocket; ISecurity* _webSecurity; - ILocalDispatcher* _jsonrpc; + IDispatcher* _jsonrpc; reason _reason; Condition _precondition; Condition _termination; diff --git a/Source/plugins/CMakeLists.txt b/Source/plugins/CMakeLists.txt index 01e5721df..d97383671 100644 --- a/Source/plugins/CMakeLists.txt +++ b/Source/plugins/CMakeLists.txt @@ -26,7 +26,7 @@ ProxyStubGenerator(NAMESPACE "Thunder::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE ProxyStubGenerator(NAMESPACE "Thunder::Exchange" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/IController.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated" INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/..") ProxyStubGenerator(NAMESPACE "Thunder::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/IStateControl.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated") ProxyStubGenerator(NAMESPACE "Thunder::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/ISubSystem.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated") -ProxyStubGenerator(NAMESPACE "Thunder::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/IDispatcher.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated") +ProxyStubGenerator(NAMESPACE "Thunder::PluginHost" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/IDispatcher.h" OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated" INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/..") JsonGenerator(CODE NAMESPACE Thunder::Exchange::Controller INPUT ${CMAKE_CURRENT_SOURCE_DIR}/IController.h OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/json" INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/.." NO_INCLUDES) diff --git a/Source/plugins/IDispatcher.h b/Source/plugins/IDispatcher.h index 8bb58b51f..139069ccb 100644 --- a/Source/plugins/IDispatcher.h +++ b/Source/plugins/IDispatcher.h @@ -17,17 +17,17 @@ * limitations under the License. */ -#ifndef __IDISPATCHER_H__ -#define __IDISPATCHER_H__ +#pragma once #include +#include "IShell.h" + +// @stubgen:include namespace Thunder { namespace PluginHost { - struct EXTERNAL ILocalDispatcher; - struct EXTERNAL IDispatcher : public virtual Core::IUnknown { ~IDispatcher() override = default; @@ -46,14 +46,15 @@ namespace Thunder { virtual Core::hresult Subscribe(ICallback* callback, const string& event, const string& designator) = 0; virtual Core::hresult Unsubscribe(ICallback* callback, const string& event, const string& designator) = 0; - // If this is a local instance of this interface, we get access to the IShell - // of this service which in turn allows access to the channels and thus the - // possibility to return responses on the right JSONRPC channels. - /* @stubgen:stub */ - virtual ILocalDispatcher* Local() = 0; + // Lifetime managment of the IDispatcher. + // Attach is to be called prior to receiving JSONRPC requests! + // Detach is to be called if the service is nolonger required! + virtual Core::hresult Attach(IShell::IConnectionServer::INotification*& sink /* @out */, IShell* service) = 0; + virtual Core::hresult Detach(IShell::IConnectionServer::INotification*& sink /* @out */) = 0; + + // If a callback is unexpectedly dropepd (non-happy day scenarios) it is reported through this + // method that all subscribtions for a certain callback can be dropped.. + virtual void Dropped(const ICallback* callback) = 0; }; } - } - -#endif diff --git a/Source/plugins/JSONRPC.h b/Source/plugins/JSONRPC.h index 67f211188..81094f5c5 100644 --- a/Source/plugins/JSONRPC.h +++ b/Source/plugins/JSONRPC.h @@ -29,15 +29,7 @@ namespace Thunder { namespace PluginHost { - struct EXTERNAL ILocalDispatcher : public IDispatcher { - virtual ~ILocalDispatcher() = default; - - virtual void Activate(IShell* service) = 0; - virtual void Deactivate() = 0; - virtual void Dropped(const IDispatcher::ICallback* callback) = 0; - }; - - class EXTERNAL JSONRPC : public ILocalDispatcher { + class EXTERNAL JSONRPC : public IDispatcher { public: using SendIfMethod = std::function; @@ -710,13 +702,8 @@ namespace PluginHost { return (result); } - ILocalDispatcher* Local() override { - return (this); - } - // Inherited via ILocalDispatcher - // --------------------------------------------------------------------------------- - void Activate(IShell* service) override + Core::hresult Attach(IShell::IConnectionServer::INotification*& sink /* @out */, IShell* service) override { ASSERT(_service == nullptr); ASSERT(service != nullptr); @@ -727,24 +714,26 @@ namespace PluginHost { _service->AddRef(); _callsign = _service->Callsign(); - _service->Register(&_notification); + sink = &_notification; + sink->AddRef(); _adminLock.Unlock(); + + return (Core::ERROR_NONE); } - void Deactivate() override + Core::hresult Detach(IShell::IConnectionServer::INotification*& sink /* @out */) override { _adminLock.Lock(); - if (_service != nullptr) { - _service->Unregister(&_notification); - _service->Release(); - _service = nullptr; - } + sink = &_notification; + sink->AddRef(); _callsign.clear(); _observers.clear(); _adminLock.Unlock(); + + return (Core::ERROR_NONE); } // Inherited via IDispatcher::ICallback From 087dcae1c563a41a13a71e3cce67f08e10ed19a4 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Mon, 24 Jun 2024 20:32:06 +0200 Subject: [PATCH 31/35] [PRUNING] Cleanup of the "all" event mechanism sending out RESTFULL notifications and JSONRPC events. (#1667) --- Source/Thunder/Controller.cpp | 14 +---- Source/Thunder/Controller.h | 17 ------ Source/Thunder/PluginHost.cpp | 3 -- Source/Thunder/PluginServer.cpp | 96 ++++++++++++--------------------- Source/Thunder/PluginServer.h | 31 ++--------- Source/plugins/IShell.h | 10 ++-- Source/plugins/Metadata.cpp | 6 --- Source/plugins/Service.cpp | 9 +--- Source/plugins/Service.h | 21 +++----- 9 files changed, 55 insertions(+), 152 deletions(-) diff --git a/Source/Thunder/Controller.cpp b/Source/Thunder/Controller.cpp index 61a2c3498..bc4dc8b6a 100644 --- a/Source/Thunder/Controller.cpp +++ b/Source/Thunder/Controller.cpp @@ -738,9 +738,7 @@ namespace Plugin { void Controller::SubSystems() { -#if THUNDER_RESTFULL_API || defined(__DEBUG__) PluginHost::Metadata response; -#endif Core::JSON::ArrayType responseJsonRpc; PluginHost::ISubSystem* subSystem = _service->SubSystems(); @@ -763,10 +761,7 @@ namespace Plugin { status.Subsystem = current; status.Active = ((reportMask & bit) != 0); responseJsonRpc.Add(status); - -#if THUNDER_RESTFULL_API || defined(__DEBUG__) response.SubSystems.Add(current, ((reportMask & bit) != 0)); -#endif sendReport = true; } @@ -781,15 +776,11 @@ namespace Plugin { if (sendReport == true) { -#if THUNDER_RESTFULL_API || defined(__DEBUG__) string message; response.ToString(message); TRACE_L1("Sending out a SubSystem change notification. %s", message.c_str()); -#endif -#if THUNDER_RESTFULL_API - _pluginServer->_controller->Notification(message); -#endif + _service->Notify(EMPTY_STRING, message); Exchange::Controller::JSubsystems::Event::SubsystemChange(*this, responseJsonRpc); } @@ -1110,10 +1101,7 @@ namespace Plugin { service.Configuration = meta.Configuration; service.Precondition = meta.Precondition; service.Termination = meta.Termination; - - #if THUNDER_RESTFULL_API service.Observers = meta.Observers; - #endif #if THUNDER_RUNTIME_STATISTICS service.ProcessedRequests = meta.ProcessedRequests; diff --git a/Source/Thunder/Controller.h b/Source/Thunder/Controller.h index f6c19bf7e..40cfa8faa 100644 --- a/Source/Thunder/Controller.h +++ b/Source/Thunder/Controller.h @@ -210,23 +210,6 @@ namespace Plugin { } } - void Notification(const string& callsign, const string& message) - { - ASSERT(callsign.empty() == false); - ASSERT(message.empty() == false); - - Exchange::Controller::JEvents::Event::ForwardMessage(*this, callsign, message); - } - - void Notification(const string& callsign, const string& event, const string& params) - { - ASSERT(callsign.empty() == false); - ASSERT(event.empty() == false); - - Exchange::Controller::IEvents::INotification::Event data{event, params}; - Exchange::Controller::JEvents::Event::ForwardEvent(*this, callsign, data); - } - inline void SetServer(PluginHost::Server* pluginServer, const std::vector& externalSubsystems) { ASSERT((_pluginServer == nullptr) && (pluginServer != nullptr)); diff --git a/Source/Thunder/PluginHost.cpp b/Source/Thunder/PluginHost.cpp index 0ddb48b89..d53baa1bb 100644 --- a/Source/Thunder/PluginHost.cpp +++ b/Source/Thunder/PluginHost.cpp @@ -774,10 +774,7 @@ POP_WARNING() printf("Locator: %s\n", index.Current().Locator.Value().c_str()); printf("Classname: %s\n", index.Current().ClassName.Value().c_str()); printf("StartMode: %s\n", index.Current().StartMode.Data()); -#if THUNDER_RESTFULL_API - printf("Observers: %d\n", index.Current().Observers.Value()); -#endif #if THUNDER_RUNTIME_STATISTICS printf("Requests: %d\n", index.Current().ProcessedRequests.Value()); diff --git a/Source/Thunder/PluginServer.cpp b/Source/Thunder/PluginServer.cpp index 51ffe48fd..5264732eb 100644 --- a/Source/Thunder/PluginServer.cpp +++ b/Source/Thunder/PluginServer.cpp @@ -298,6 +298,14 @@ namespace PluginHost { AddRef(); result = static_cast(this); } + else if (id == PluginHost::IDispatcher::ID) { + _pluginHandling.Lock(); + if (_jsonrpc != nullptr) { + _jsonrpc->AddRef(); + result = _jsonrpc; + } + _pluginHandling.Unlock(); + } else { _pluginHandling.Lock(); @@ -456,12 +464,6 @@ namespace PluginHost { State(ACTIVATED); _administrator.Activated(callSign, this); -#if THUNDER_RESTFULL_API - _administrator.Notification(_T("{\"callsign\":\"") + callSign + _T("\",\"state\":\"deactivated\",\"reason\":\"") + textReason.Data() + _T("\"}")); -#endif - - _administrator.Notification(callSign, string(_T("{\"state\":\"activated\",\"reason\":\"")) + textReason.Data() + _T("\"}")); - IStateControl* stateControl = nullptr; if ((Resumed() == true) && ((stateControl = _handler->QueryInterface()) != nullptr)) { @@ -469,6 +471,8 @@ namespace PluginHost { stateControl->Release(); } + Notify(EMPTY_STRING, string(_T("{\"state\":\"activated\",\"reason\":\"")) + textReason.Data() + _T("\"}")); + Unlock(); } } @@ -600,12 +604,7 @@ namespace PluginHost { if (currentState != IShell::state::ACTIVATION) { SYSLOG(Logging::Shutdown, (_T("Deactivated plugin [%s]:[%s]"), className.c_str(), callSign.c_str())); - #if THUNDER_RESTFULL_API - _administrator.Notification(_T("{\"callsign\":\"") + callSign + _T("\",\"state\":\"deactivated\",\"reason\":\"") + textReason.Data() + _T("\"}")); - #endif - - _administrator.Notification(callSign, string(_T("{\"state\":\"deactivated\",\"reason\":\"")) + textReason.Data() + _T("\"}")); - + Notify(EMPTY_STRING, string(_T("{\"state\":\"deactivated\",\"reason\":\"")) + textReason.Data() + _T("\"}")); } } @@ -691,11 +690,7 @@ namespace PluginHost { State(UNAVAILABLE); _administrator.Unavailable(callSign, this); -#if THUNDER_RESTFULL_API - _administrator.Notification(_T("{\"callsign\":\"") + callSign + _T("\",\"state\":\"unavailable\",\"reason\":\"") + textReason.Data() + _T("\"}")); -#endif - - _administrator.Notification(callSign, string(_T("{\"state\":\"unavailable\",\"reason\":\"")) + textReason.Data() + _T("\"}")); + Notify(EMPTY_STRING, string(_T("{\"state\":\"unavailable\",\"reason\":\"")) + textReason.Data() + _T("\"}")); } Unlock(); @@ -899,19 +894,15 @@ namespace PluginHost { return (_administrator.SubSystemsInterface(this)); } - void Server::Service::Notify(const string& message) /* override */ + void Server::Service::Notify(const string& jsonrpcEvent, const string& message) /* override */ { -#if THUNDER_RESTFULL_API - // Notify the base class and the subscribers - PluginHost::Service::Notification(message); -#endif - - _administrator.Notification(PluginHost::Service::Callsign(), message); - } + // JSONRPC has been send by now, lets send it to the "notification" + // observers.. + if (jsonrpcEvent.empty() == true) { + BaseClass::Notification(message); + } - void Server::Service::Notify(const string& event, const string& parameters) /* override */ - { - _administrator.Notification(PluginHost::Service::Callsign(), event, parameters); + _administrator.Notification(PluginHost::Service::Callsign(), jsonrpcEvent, message); } // @@ -1193,46 +1184,27 @@ namespace PluginHost { IFactories::Assign(nullptr); } - void Server::Notification(const string& callsign, const string& data) + void Server::Notification(const string& callsign, const string& jsonrpc_event, const string& parameters) { - Plugin::Controller* controller; - if ((_controller.IsValid() == true) && ((controller = (_controller->ClassType())) != nullptr)) { - - controller->Notification(callsign, data); - -#if THUNDER_RESTFULL_API - JsonData::Events::ForwardMessageParamsData message; - message.Callsign = callsign; - message.Data = data; - string messageString; - message.ToString(messageString); - _controller->Notification(messageString); -#endif - } - } + ASSERT((_controller.IsValid() == true) && (_controller->ClassType() != nullptr)); - void Server::Notification(const string& callsign, const string& event, const string& parameters) - { - if (_controller.IsValid() == true) { - Plugin::Controller* controller = _controller->ClassType(); + Plugin::Controller* controller = _controller->ClassType(); - if (controller != nullptr) { - static const TCHAR allEvent[] = _T("all"); + // Break a recursive loop, if it tries to arise ;-) + if ( (controller != nullptr) && (callsign != controller->Callsign()) ) { - if ((callsign != controller->Callsign()) || (event != allEvent)) { + ASSERT(callsign.empty() == false); - controller->Notification(callsign, event, parameters); + if (jsonrpc_event.empty() == false) { + JsonData::Events::ForwardEventParamsData message; + message.Data = Exchange::Controller::IEvents::INotification::Event({ jsonrpc_event, parameters }); + message.Callsign = callsign; + Exchange::Controller::JEvents::Event::ForwardEvent(*controller, message); + } + else { + string messageString = string(_T("{\"callsign\":\"")) + callsign + _T("\", {\"data\":\"") + parameters + _T("\"}}"); -#if THUNDER_RESTFULL_API - JsonData::Events::ForwardEventParamsData message; - message.Callsign = callsign; - message.Data.Event = event; - message.Data.Params = parameters; - string messageString; - message.ToString(messageString); - _controller->Notification(messageString); -#endif - } + _controller->Notify(EMPTY_STRING, messageString); } } } diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index f0c7786f7..49c5eb917 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -320,6 +320,7 @@ namespace PluginHost { }; private: + using BaseClass = PluginHost::Service; class Composit : public PluginHost::ICompositPlugin::ICallback { public: Composit() = delete; @@ -811,7 +812,6 @@ namespace PluginHost { } inline bool Subscribe(Channel& channel) { - #if THUNDER_RESTFULL_API bool result = PluginHost::Service::Subscribe(channel); if ((result == true) && (_extended != nullptr)) { @@ -819,19 +819,10 @@ namespace PluginHost { } return (result); - #else - if (_extended != nullptr) { - _extended->Attach(channel); - } - - return (_extended != nullptr); - #endif } inline void Unsubscribe(Channel& channel) { - #if THUNDER_RESTFULL_API PluginHost::Service::Unsubscribe(channel); - #endif if (_extended != nullptr) { _extended->Detach(channel); @@ -1156,8 +1147,7 @@ namespace PluginHost { uint32_t Submit(const uint32_t id, const Core::ProxyType& response) override; ISubSystem* SubSystems() override; - void Notify(const string& message) override; - void Notify(const string& event, const string& parameters) override; + void Notify(const string& event, const string& message) override; void* QueryInterface(const uint32_t id) override; void* QueryInterfaceByCallsign(const uint32_t id, const string& name) override; template @@ -2981,20 +2971,10 @@ namespace PluginHost { return (Iterator(std::move(workingList))); } - inline void Notification(const string& callsign, const string& message) + inline void Notification(const string& callsign, const string& jsonrpc_event, const string& message) { - _server.Notification(callsign, message); + _server.Notification(callsign, jsonrpc_event, message); } - inline void Notification(const string& callsign, const string& event, const string& message) - { - _server.Notification(callsign, event, message); - } - #if THUNDER_RESTFULL_API - inline void Notification(const string& message) - { - _server.Controller()->Notification(message); - } - #endif void GetMetadata(Core::JSON::ArrayType& metaData) const { std::vector> workingList; @@ -4451,8 +4431,7 @@ namespace PluginHost { return (_config); } - void Notification(const string& callsign, const string& message); - void Notification(const string& callsign, const string& event, const string& message); + void Notification(const string& callsign, const string& jsonrpc_event, const string& message); void Open(); void Close(); diff --git a/Source/plugins/IShell.h b/Source/plugins/IShell.h index d8c9e5a18..d0411d746 100644 --- a/Source/plugins/IShell.h +++ b/Source/plugins/IShell.h @@ -252,10 +252,12 @@ namespace PluginHost { virtual ISubSystem* SubSystems() = 0; // Notify all subscribers of this service with the given string. - // It is expected to be JSON formatted strings as it is assumed that this is for reaching websockets clients living in - // the web world that have build in functionality to parse JSON structs. - virtual void Notify(const string& message) = 0; - virtual void Notify(const string& event, const string& parameters) = 0; + // It is expected to be JSON formatted strings (message) as it is assumed that this is for reaching websockets clients + // living in the web world that have build in functionality to parse JSON structs. + void Notify(const string& message) { + Notify(EMPTY_STRING, message); + } + virtual void Notify(const string& event, const string& message) = 0; // Allow access to the Shells, configured for the different Plugins found in the configuration. // Calling the QueryInterfaceByCallsign with an empty callsign will query for interfaces located diff --git a/Source/plugins/Metadata.cpp b/Source/plugins/Metadata.cpp index f116b861d..718e67b87 100644 --- a/Source/plugins/Metadata.cpp +++ b/Source/plugins/Metadata.cpp @@ -112,9 +112,7 @@ namespace PluginHost , ProcessedRequests(0) , ProcessedObjects(0) #endif -#if THUNDER_RESTFULL_API , Observers(0) -#endif , ServiceVersion() , Module() , InterfaceVersion() @@ -124,9 +122,7 @@ namespace PluginHost Add(_T("processedrequests"), &ProcessedRequests); Add(_T("processedobjects"), &ProcessedObjects); #endif -#if THUNDER_RESTFULL_API Add(_T("observers"), &Observers); -#endif Add(_T("module"), &Module); Add(_T("version"), &ServiceVersion); Add(_T("interface"), &InterfaceVersion); @@ -138,9 +134,7 @@ namespace PluginHost , ProcessedRequests(std::move(move.ProcessedRequests)) , ProcessedObjects(std::move(move.ProcessedObjects)) #endif -#if THUNDER_RESTFULL_API , Observers(std::move(move.Observers)) -#endif , ServiceVersion(std::move(move.ServiceVersion)) , Module(std::move(move.Module)) , InterfaceVersion(std::move(move.InterfaceVersion)) diff --git a/Source/plugins/Service.cpp b/Source/plugins/Service.cpp index c2cfa59fb..580bb98e6 100644 --- a/Source/plugins/Service.cpp +++ b/Source/plugins/Service.cpp @@ -67,24 +67,19 @@ namespace PluginHost { return (Core::ProxyType(Core::ProxyType::Create(shell, toState, why))); } -#if THUNDER_RESTFULL_API void Service::Notification(const string& message) { _notifierLock.Lock(); ASSERT(message.empty() != true); { - std::list::iterator index(_notifiers.begin()); - - while (index != _notifiers.end()) { - (*index)->Submit(message); - index++; + for (auto entry : _notifiers) { + entry->Submit(message); } } _notifierLock.Unlock(); } -#endif void Service::FileToServe(const string& webServiceRequest, Web::Response& response, bool allowUnsafePath) { diff --git a/Source/plugins/Service.h b/Source/plugins/Service.h index fd559447a..c31f60c6e 100644 --- a/Source/plugins/Service.h +++ b/Source/plugins/Service.h @@ -32,6 +32,8 @@ namespace PluginHost { class EXTERNAL Service : public IShell { private: + using Channels = std::vector; + class EXTERNAL Config { public: Config() = delete; @@ -162,9 +164,7 @@ namespace PluginHost { #endif , _state(DEACTIVATED) , _config(plugin, webPrefix, persistentPath, dataPath, volatilePath) - #if THUNDER_RESTFULL_API , _notifiers() - #endif { if ( (plugin.StartMode.IsSet() == true) && (plugin.StartMode.Value() == PluginHost::IShell::startmode::UNAVAILABLE) ) { _state = UNAVAILABLE; @@ -325,9 +325,7 @@ namespace PluginHost { inline void GetMetadata(Metadata::Service& metaData) const { metaData = _config.Configuration(); - #if THUNDER_RESTFULL_API metaData.Observers = static_cast(_notifiers.size()); - #endif // When we do this, we need to make sure that the Service does not change state, otherwise it might // be that the the plugin is deinitializing and the IStateControl becomes invalid during our run. @@ -346,9 +344,7 @@ namespace PluginHost { bool IsWebServerRequest(const string& segment) const; - #if THUNDER_RESTFULL_API void Notification(const string& message); - #endif virtual Core::ProxyType Inbound(const string& identifier) = 0; @@ -369,7 +365,6 @@ namespace PluginHost { { _errorMessage = message; } - #if THUNDER_RESTFULL_API inline bool Subscribe(Channel& channel) { _notifierLock.Lock(); @@ -380,6 +375,9 @@ namespace PluginHost { if (channel.IsNotified() == true) { _notifiers.push_back(&channel); } + else { + result = false; + } } _notifierLock.Unlock(); @@ -391,7 +389,7 @@ namespace PluginHost { _notifierLock.Lock(); - std::list::iterator index(std::find(_notifiers.begin(), _notifiers.end(), &channel)); + Channels::iterator index(std::find(_notifiers.begin(), _notifiers.end(), &channel)); if (index != _notifiers.end()) { _notifiers.erase(index); @@ -399,7 +397,6 @@ namespace PluginHost { _notifierLock.Unlock(); } - #endif #if THUNDER_RUNTIME_STATISTICS inline void IncrementProcessedRequests() { @@ -416,9 +413,7 @@ namespace PluginHost { private: mutable Core::CriticalSection _adminLock; - #if THUNDER_RESTFULL_API Core::CriticalSection _notifierLock; - #endif #if THUNDER_RUNTIME_STATISTICS uint32_t _processedRequests; @@ -434,10 +429,8 @@ namespace PluginHost { string _webURLPath; string _webServerFilePath; - #if THUNDER_RESTFULL_API // Keep track of people who want to be notified of changes. - std::list _notifiers; - #endif + Channels _notifiers; }; } } From e84f07c8e6299de672e2f6c1fbe8d005bbcdeb4c Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Tue, 25 Jun 2024 10:18:12 +0200 Subject: [PATCH 32/35] Development/notification pruning (#1668) * [PRUNING] Cleanup of the "all" event mechanism sending out RESTFULL notifications and JSONRPC events. * [SYNC] Update after testing.. --- Source/Thunder/PluginServer.cpp | 10 ++- Source/Thunder/PluginServer.h | 121 ++++++++++++++------------------ Source/plugins/Channel.h | 15 ++-- Source/plugins/Request.h | 33 +++++---- Source/plugins/Service.cpp | 19 ++--- Source/plugins/Service.h | 36 +++++----- 6 files changed, 116 insertions(+), 118 deletions(-) diff --git a/Source/Thunder/PluginServer.cpp b/Source/Thunder/PluginServer.cpp index 5264732eb..19221114a 100644 --- a/Source/Thunder/PluginServer.cpp +++ b/Source/Thunder/PluginServer.cpp @@ -972,16 +972,17 @@ namespace PluginHost { _processAdministrator.Destroy(); } - uint32_t Server::ServiceMap::FromLocator(const string& identifier, Core::ProxyType& service, bool& serviceCall) + uint32_t Server::ServiceMap::FromLocator(const string& identifier, Core::ProxyType& service, PluginHost::Request::mode& callType) { uint32_t result = Core::ERROR_BAD_REQUEST; const string& serviceHeader(Configuration().WebPrefix()); const string& JSONRPCHeader(Configuration().JSONRPCPrefix()); + // Check the header (prefix part) if (identifier.compare(0, serviceHeader.length(), serviceHeader.c_str()) == 0) { - serviceCall = true; + callType = PluginHost::Request::mode::RESTFULL; if (identifier.length() <= (serviceHeader.length() + 1)) { service = _server.Controller(); @@ -1002,7 +1003,7 @@ namespace PluginHost { } } else if (identifier.compare(0, JSONRPCHeader.length(), JSONRPCHeader.c_str()) == 0) { - serviceCall = false; + callType = PluginHost::Request::mode::JSONRPC; if (identifier.length() <= (JSONRPCHeader.length() + 1)) { service = _server.Controller(); @@ -1022,6 +1023,9 @@ namespace PluginHost { } } } + else { + callType = PluginHost::Request::mode::PROPRIETARY; + } return (result); } diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 49c5eb917..104d0dec6 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -810,20 +810,15 @@ namespace PluginHost { { return (_rawSocket != nullptr); } - inline bool Subscribe(Channel& channel) - { - bool result = PluginHost::Service::Subscribe(channel); + inline bool Attach(PluginHost::Channel& channel) { + bool attached = true; - if ((result == true) && (_extended != nullptr)) { - _extended->Attach(channel); + if (_extended != nullptr) { + attached = _extended->Attach(channel); } - - return (result); + return (attached); } - inline void Unsubscribe(Channel& channel) - { - PluginHost::Service::Unsubscribe(channel); - + inline void Detach(PluginHost::Channel& channel) { if (_extended != nullptr) { _extended->Detach(channel); } @@ -3105,7 +3100,7 @@ namespace PluginHost { RecursiveNotification(index); } - uint32_t FromLocator(const string& identifier, Core::ProxyType& service, bool& serviceCall); + uint32_t FromLocator(const string& identifier, Core::ProxyType& service, PluginHost::Request::mode& callType); void Open(std::vector& externallyControlled); void Startup(); @@ -3843,11 +3838,11 @@ namespace PluginHost { // Remember the path and options.. Core::ProxyType service; - bool serviceCall; + PluginHost::Request::mode callType; - uint32_t status = _parent.Services().FromLocator(request->Path, service, serviceCall); + uint32_t status = _parent.Services().FromLocator(request->Path, service, callType); - request->Service(status, Core::ProxyType(service), serviceCall); + request->Set(status, Core::ProxyType(service), callType); ASSERT(request->State() != Request::INCOMPLETE); @@ -3855,9 +3850,9 @@ namespace PluginHost { ASSERT(service.IsValid() == true); - if (serviceCall == true) { + if (callType == PluginHost::Request::mode::RESTFULL) { service->Inbound(*request); - } else { + } else if (callType == PluginHost::Request::mode::JSONRPC) { request->Body(IFactories::Instance().JSONRPC()); } } @@ -3901,10 +3896,10 @@ namespace PluginHost { if (request->State() == Request::INCOMPLETE) { Core::ProxyType service; - bool serviceCall; - uint32_t status = _parent.Services().FromLocator(request->Path, service, serviceCall); + PluginHost::Request::mode callType; + uint32_t status = _parent.Services().FromLocator(request->Path, service, callType); - request->Service(status, Core::ProxyType(service), serviceCall); + request->Set(status, Core::ProxyType(service), callType); } else if ((request->State() == Request::COMPLETE) && (request->HasBody() == true)) { Core::ProxyType message(request->Body()); if (message.IsValid() == true) { @@ -3960,7 +3955,7 @@ namespace PluginHost { Core::ProxyType response; - if (request->ServiceCall() == true) { + if (request->RestfulCall() == true) { response = service->Evaluate(*request); } @@ -3976,7 +3971,7 @@ namespace PluginHost { if (job.IsValid() == true) { Core::ProxyType baseRequest(request); - job->Set(Id(), &_parent, service, baseRequest, _security->Token(), !request->ServiceCall()); + job->Set(Id(), &_parent, service, baseRequest, _security->Token(), !request->RestfulCall()); Push(Core::ProxyType(job)); } } @@ -4111,7 +4106,7 @@ namespace PluginHost { // If we are closing (or closed) do the clean up if (IsOpen() == false) { if (_service.IsValid() == true) { - _service->Unsubscribe(*this); + _service->Detach(*this); _service.Release(); } @@ -4123,38 +4118,55 @@ namespace PluginHost { } else if (IsUpgrading() == true) { ASSERT(_service.IsValid() == false); - bool serviceCall; + PluginHost::Request::mode callType; // see if we need to subscribe... - _parent.Services().FromLocator(Path(), _service, serviceCall); + _parent.Services().FromLocator(Path(), _service, callType); if (_service.IsValid() == false) { AbortUpgrade(Web::STATUS_SERVICE_UNAVAILABLE, _T("Could not find a correct service for this socket.")); } else if (Allowed(Path(), Query()) == false) { AbortUpgrade(Web::STATUS_FORBIDDEN, _T("Security prohibites this connection.")); } else { - //select supported protocol and let know which one was choosen - auto protocol = SelectSupportedProtocol(Protocols()); - if (protocol.empty() == false) { + bool notification = false; + Channel::ChannelState mode = Channel::ChannelState::JSONRPC; + + const Web::ProtocolsArray& protocols(Protocols()); + + if (protocols.Empty() == true) { // if protocol header is not set sending an empty protocol header is not allowed (at least by chrome) - Protocols(Web::ProtocolsArray(protocol)); + Protocols(Web::ProtocolsArray(protocols)); } - - if (serviceCall == false) { - const string& JSONRPCHeader(_parent._config.JSONRPCPrefix()); - if (Name().length() > (JSONRPCHeader.length() + 1)) { - Properties(static_cast(JSONRPCHeader.length()) + 1); + else for (const auto& protocol : protocols) { + if (protocol == _T("notification")) { + notification = true; } - State(JSONRPC, false); - } else { - const string& serviceHeader(_parent._config.WebPrefix()); - if (Name().length() > (serviceHeader.length() + 1)) { - Properties(static_cast(serviceHeader.length()) + 1); + else if ( (protocol == _T("json")) || (protocol == _T("jsonrpc"))) { + mode = Channel::ChannelState::JSON; + break; + } + else if (protocol == _T("text")) { + mode = Channel::ChannelState::TEXT; + } + else if (protocol == _T("raw")) { + mode = Channel::ChannelState::RAW; + } + } + + if (callType == PluginHost::Request::JSONRPC) { + Properties(static_cast(_parent._config.JSONRPCPrefix().length()) + 1); + State(static_cast(mode | ChannelState::JSONRPC), notification); + if (_service->Attach(*this) == false) { + AbortUpgrade(Web::STATUS_FORBIDDEN, _T("Subscription rejected by the destination plugin.")); } } - if (_service->Subscribe(*this) == false) { - State(WEB, false); - AbortUpgrade(Web::STATUS_FORBIDDEN, _T("Subscription rejected by the destination plugin.")); + else if (callType == PluginHost::Request::RESTFULL) { + Properties(static_cast(_parent._config.WebPrefix().length()) + 1); + State(static_cast(mode | ChannelState::WEB), notification); + if (((IsNotified() == true) && (_service->Subscribe(*this) == false)) || (_service->Attach(*this) == false)) { + AbortUpgrade(Web::STATUS_FORBIDDEN, _T("Subscription rejected by the destination plugin.")); + } } + } } else if ((IsOpen() == true) && (IsWebSocket() == false)) { @@ -4169,31 +4181,6 @@ namespace PluginHost { SetId(id); } - inline string SelectSupportedProtocol(const Web::ProtocolsArray& protocols) - { - for (const auto& protocol : protocols) { - if (protocol == _T("notification")) { - State(TEXT, true); - return protocol; - } else if (protocol == _T("json")) { - State(JSON, false); - return protocol; - } else if (protocol == _T("text")) { - State(TEXT, false); - return protocol; - } else if (protocol == _T("jsonrpc")) { - State(JSONRPC, false); - return protocol; - } else if (protocol == _T("raw")) { - State(RAW, false); - return protocol; - } - } - - State(RAW, false); - return _T(""); - } - Server& _parent; Core::CriticalSection _adminLock; PluginHost::ISecurity* _security; diff --git a/Source/plugins/Channel.h b/Source/plugins/Channel.h index 3aa2c295f..bc3e6895c 100644 --- a/Source/plugins/Channel.h +++ b/Source/plugins/Channel.h @@ -192,13 +192,14 @@ namespace PluginHost { public: enum ChannelState : uint16_t { - CLOSED = 0x01, - WEB = 0x02, - JSON = 0x04, - RAW = 0x08, - TEXT = 0x10, - JSONRPC = 0x20, - PINGED = 0x4000, + CLOSED = 0x01, + WEB = 0x02, + JSON = 0x04, + RAW = 0x08, + TEXT = 0x10, + JSONRPC = 0x20, + + PINGED = 0x4000, NOTIFIED = 0x8000 }; diff --git a/Source/plugins/Request.h b/Source/plugins/Request.h index 72f9df83f..15ecf7b13 100644 --- a/Source/plugins/Request.h +++ b/Source/plugins/Request.h @@ -36,46 +36,55 @@ namespace PluginHost { // used but are not actively used. class EXTERNAL Request : public Web::Request { public: - enum enumState : uint8_t { + enum state : uint8_t { INCOMPLETE = 0x01, OBLIVIOUS, MISSING_CALLSIGN, INVALID_VERSION, COMPLETE, - UNAUTHORIZED, - SERVICE_CALL = 0x80 + UNAUTHORIZED + }; + enum mode : uint8_t { + RESTFULL = 0x10, + JSONRPC = 0x20, + PROPRIETARY = 0x30 }; - private: + public: + Request(Request&&) = delete; Request(const Request&) = delete; + Request& operator=(Request&&) = delete; Request& operator=(const Request&) = delete; - public: Request(); - virtual ~Request(); + ~Request() = default; public: // This method tells us if this call was received over the // Service prefix path or (if it is false) over the JSONRPC // prefix path. - inline bool ServiceCall() const + inline bool RestfulCall() const + { + return ((_state & 0xF0) == RESTFULL); + } + inline bool JSONRPCCall() const { - return ((_state & SERVICE_CALL) != 0); + return ((_state & 0xF0) == JSONRPC); } - inline enumState State() const + inline state State() const { - return (static_cast(_state & 0x7F)); + return (static_cast(_state & 0x0F)); } inline Core::ProxyType& Service() { return (_service); } inline void Unauthorized() { - _state = ((_state & 0x80) | UNAUTHORIZED); + _state = ((_state & 0xF0) | UNAUTHORIZED); } void Clear(); - void Service(const uint32_t errorCode, const Core::ProxyType& service, const bool serviceCall); + void Set(const uint32_t errorCode, const Core::ProxyType& service, const mode type); private: uint8_t _state; diff --git a/Source/plugins/Service.cpp b/Source/plugins/Service.cpp index 580bb98e6..2ddb8b1f3 100644 --- a/Source/plugins/Service.cpp +++ b/Source/plugins/Service.cpp @@ -26,39 +26,34 @@ namespace PluginHost { PluginHost::Request::Request() : Web::Request() - , _state(INCOMPLETE | SERVICE_CALL) + , _state(INCOMPLETE | mode::RESTFULL) , _service() { } - /* virtual */ PluginHost::Request::~Request() - { - } void PluginHost::Request::Clear() { Web::Request::Clear(); - _state = INCOMPLETE | SERVICE_CALL; + _state = INCOMPLETE | mode::RESTFULL; if (_service.IsValid()) { _service.Release(); } } - void PluginHost::Request::Service(const uint32_t errorCode, const Core::ProxyType& service, const bool serviceCall) + void PluginHost::Request::Set(const uint32_t errorCode, const Core::ProxyType& service, const mode type) { ASSERT(_service.IsValid() == false); ASSERT(State() == INCOMPLETE); - uint8_t value = (serviceCall ? SERVICE_CALL : 0); - if (service.IsValid() == true) { - _state = COMPLETE | value; + _state = COMPLETE | (type & 0xF0); _service = service; } else if (errorCode == Core::ERROR_BAD_REQUEST) { - _state = OBLIVIOUS | value; + _state = OBLIVIOUS | (type & 0xF0); } else if (errorCode == Core::ERROR_INVALID_SIGNATURE) { - _state = INVALID_VERSION | value; + _state = INVALID_VERSION | (type & 0xF0); } else if (errorCode == Core::ERROR_UNAVAILABLE) { - _state = MISSING_CALLSIGN | value; + _state = MISSING_CALLSIGN | (type & 0xF0); } } diff --git a/Source/plugins/Service.h b/Source/plugins/Service.h index c31f60c6e..3fde6e148 100644 --- a/Source/plugins/Service.h +++ b/Source/plugins/Service.h @@ -348,23 +348,6 @@ namespace PluginHost { virtual Core::ProxyType Inbound(const string& identifier) = 0; - protected: - inline void Lock() const - { - _adminLock.Lock(); - } - inline void Unlock() const - { - _adminLock.Unlock(); - } - inline void State(const state value) - { - _state = value; - } - inline void ErrorMessage(const string& message) - { - _errorMessage = message; - } inline bool Subscribe(Channel& channel) { _notifierLock.Lock(); @@ -397,6 +380,25 @@ namespace PluginHost { _notifierLock.Unlock(); } + + protected: + inline void Lock() const + { + _adminLock.Lock(); + } + inline void Unlock() const + { + _adminLock.Unlock(); + } + inline void State(const state value) + { + _state = value; + } + inline void ErrorMessage(const string& message) + { + _errorMessage = message; + } + #if THUNDER_RUNTIME_STATISTICS inline void IncrementProcessedRequests() { From 2817e300d466883fe8b6f0aa364dd88299a1239f Mon Sep 17 00:00:00 2001 From: Mateusz Daniluk <121170681+VeithMetro@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:18:50 +0200 Subject: [PATCH 33/35] Updating the Worker Pool docs to match the documentation style on our wiki (#1665) Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- docs/utils/threading/worker-pool.md | 129 +++++++++++++++++++++------- 1 file changed, 99 insertions(+), 30 deletions(-) diff --git a/docs/utils/threading/worker-pool.md b/docs/utils/threading/worker-pool.md index 483612275..32d602e41 100644 --- a/docs/utils/threading/worker-pool.md +++ b/docs/utils/threading/worker-pool.md @@ -1,46 +1,88 @@ -# Worker Pool - -One of the most underused functionalities in Thunder that we believe needs to be addressed as soon as possible is Worker Pool. Multiple examples can be found across many repositories where it is, in fact, properly utilized, but there are also plenty of plugins that do not apply this feature, while in the meantime using other ways to create threads, which are far less efficient on many fronts. The goal of creating this document is to spread the knowledge about features that are not used enough just like Worker Pool, because the main reason why it is not utilized to its fullest extent is probably the fact that many developers do not know about such a feature being already implemented in Thunder. Before we jump into explaining the details, it is probably a good idea to briefly describe multithreading and simple ways to create threads, so that later it will be possible to show the advantages of using the Worker Pool. +The purpose of this document is to illuminate the underutilized potential of the Worker Pool. Even though multiple examples can be found across many repositories where Worker Pool is, in fact, properly utilized, many developers possibly unaware of this feature within Thunder still resort to alternative, less optimal thread creation methods. By delving into the nuances of multithreading and basic thread creation, we aim to pave the way for demonstrating the unparalleled advantages of embracing the Worker Pool. ## Multithreading -As most of us know, multithreading is a feature that enables multiple parts of a program to be executed simultaneously for the maximum CPU usage. With this definition, it can be said that every part of such a program is called a thread, so essentially threads are tiny processes within a process. If we think about this concept, it certainly has many advantages. The most important one which comes to mind is that we could execute multiple instructions concurrently, and thus make our plugin faster. This is of course true, but such an approach comes with its own drawbacks that can be pretty significant, especially in an embedded environment, such as, for example, increased memory usage. +Multithreading, a well-known programming paradigm, empowers a program to execute multiple tasks simultaneously, optimizing CPU usage to its fullest potential. In the realm of multithreading, each independently executing section of a program is referred to as a thread. Considered through this lens, multithreading offers a multitude of advantages. + +Most significant among them is the ability to concurrently execute multiple instructions, a potential game-changer for plugins aiming for elevated performance. The appeal of faster execution is undeniable, but, as with any approach, it brings its own set of considerations and challenges, particularly in embedded environments. + +!!! note + In the context of embedded systems, where resources are often constrained, embracing multithreading may lead to noteworthy drawbacks. One prominent concern is the increased memory usage, a critical factor necessary to consider when optimizing the performance in such environments. ## Ways to create threads -There are of course many ways to create a thread - before C++11 the main way was to use `pthreads`, which stands for `POSIX` threads. As we can imagine, `pthreads` are not natively supported in Windows because this is a solution purely for Unix/Linux operating systems. This approach is most effective in multiprocessor or multicore systems, where threads can be implemented at the kernel level to achieve execution speed. Although this solution has been working well, the lack of standard language support for creating threads has caused serious portability problems. +### Prior to C++11 + +In the pre-C++11 era, a prominent method for thread creation involved the use of `pthreads` - an acronym denoting `POSIX` threads. Notably, `pthreads` proved highly effective in Unix/Linux operating systems, leveraging their capabilities in multiprocessor or multicore environments to achieve optimal execution speed. However, this approach encounters a significant roadblock when transitioning to Windows, where native support for `pthreads` is lacking. + +While successful in its own right, the reliance on `pthreads` highlighted a critical issue: the absence of standardized language support for thread creation. This deficiency resulted in substantial portability challenges, limiting the seamless transition of threaded code across different platforms. + +### Post C++11 + +With C++11, `std::thread` was released. It is an improvement upon `boost::thread` but offers the advantage of cross-platform compatibility without relying on additional dependencies. + +The natural thought might be to use `std::thread` universally to avoid compatibility issues. While this holds true for standard computers and modern mobile devices, the scenario changes when dealing with resource-constrained embedded systems. + +Nevertheless, there is no need to worry - there are already ways to deal with all this and more in Thunder. -With C++11, `std::thread` was released. It is based on `boost::thread`, but is now cross-platform and does not require any dependencies. Therefore, you might now think that this is the way to go; simply use std::thread, and at least we will not need to worry about portability issues. This could potentially be true if we were creating applications for a PC or these days even a mobile device, but not for embedded systems. Nevertheless, there is no need to worry; there are already ways to deal with all this and more in Thunder. +!!! warning + Simply using `std::thread` or other standard ways of creating threads in your plugins is not the optimal approach when it comes to embedded systems. ## Thread Pool concept -Thread pools are software design patterns that help achieve concurrency in the execution of the computer application. The thread pool provides multiple threads that wait for tasks to be allocated for simultaneous execution by a supervising program. We could say that a thread pool is a collection of *worker threads* that effectively perform asynchronous callbacks for the application and that it is mainly used to decrease the number of application threads, but at the same time to provide management of the worker threads. Additionally, the threads are not terminated immediately - when one of the threads completes its task, it becomes idle and ready to be sent off to another assignment. If there is no task, the thread will wait. +Thread pools are software design patterns that help achieve concurrency in the execution of the computer application. The thread pool provides multiple threads that wait for tasks to be allocated for simultaneous execution by a supervising program. + +!!! note + We could say that a thread pool is a collection of *worker threads* that effectively perform asynchronous callbacks for the application and that it is mainly used to decrease the number of application threads, but also at the same time to provide management of the worker threads. + +Additionally, the threads are not terminated immediately - when one of the threads completes its task, it becomes idle and ready to be sent off to another assignment. If there is no task, the thread will simply wait. ## Advantages of using Thread Pool -To truly understand why it is much more efficient to use something like a thread pool instead of simply creating your own threads, we need to look at it from various points of view. There are three main ways to approach this issue, namely from the perspective of memory usage, scalability, and portability, each of which is equally important and will be discussed in the following subsections. +To truly understand why it is much more efficient to use something like a thread pool instead of simply creating your own threads, we need to look at it from various points of view. There are three main perspectives to this issue: + +* memory usage, + +* scalability, + +* portability. ### Memory usage -Comprehending the problem of memory usage might not be easy for everyone, especially people who are simply used to coding applications for PC or mobile devices, which nowadays basically have unlimited memory, in particular compared to embedded systems. It may not seem like a huge deal to create a few additional threads now and again on the PC with many GB of RAM, but it can be very noticeable when done on an embedded device with, for example, 512 MB. You could be asking yourself now why does it have to be like that, would it not be easier for embedded devices to have at least a little bit more memory, so that we as developers would not have to worry about it that much? +Comprehending the problem of memory usage might not be easy for everyone, especially people who are used to coding applications for PC or mobile devices, which nowadays basically have unlimited memory, in particular compared to embedded systems. -Unfortunately, the answer is no, and there is a very good reason for that. These embedded devices must be as cost-efficient as possible, because saving even a tiny percentage of their cost makes a huge difference when millions of them are being produced. With that in mind, it is very profitable in the long run to spend quite a bit of money to improve the software as much as possible, so it is feasible to reduce the production cost and save much more. +!!! warning + Higher memory usage may not seem like a huge deal when creating a few additional threads now and again on the PC with many GBs of RAM, but it definitely can be very noticeable when done on an embedded device with, for example, 512 MB. + +You could be asking yourself now - why does it have to be like that, would it not be easier for embedded devices to have at least a little bit more memory, so that we as developers would not have to worry about it that much? + +Unfortunately, the answer is no, and there is a very good reason for that. These embedded devices have to be as cost-efficient as possible, because saving even a tiny percentage of their production cost makes a huge difference when millions of them are being manufactured. With that in mind, it is very profitable in the long run to spend quite a bit of money to improve the software as much as possible, so it is feasible to reduce the production cost and save much more. ### Scalability -Imagine now that we are not only in an embedded environment but also in a system in which dozens of plugins are running concurrently. Now, if every one of these plugins were creating new threads whenever it would like, we would for sure quickly run into a memory shortage problem. This is a serious scalability issue, and we can all agree that from an architectural point of view, it is a terrible approach. Once again, it can be noticed that issues like that usually do not happen, for example, when we are building a relatively small PC application, but it is a significant concern in our system that we as developers need to consider. +Imagine now that we are not only in an embedded environment but also in a system where dozens of plugins are running concurrently. Now, if every one of these plugins were creating new threads whenever it would like, we would for sure quickly run into a memory shortage problem. This is a serious scalability issue, and we can all agree that from an architectural point of view, it is a terrible approach. + +Once again, it can be noticed that issues like that usually do not happen, for example, when we are building a relatively small PC application, but in the embedded system it is a significant concern that we as developers need to consider. + +On top of that, it is worth mentioning that the very process of creating a new thread is sometimes much more resource-consuming than the actual operations which are performed by this thread. To avoid that, we need to use a thread pool design pattern, and luckily for us, that is already implemented. -On top of that, it is worth mentioning that the very process of creating a new thread is sometimes much more resource-consuming than the actual operations that are performed by this thread. To avoid that, we need to use a thread pool design pattern, and luckily for us, that is already implemented. In summary, more threads use more memory, whereas a thread pool can be configured to split the work among existing threads and not to use too much memory, which could substantially slow our system or even cause a crash. +!!! note + In summary, more threads use more memory, whereas a thread pool can be configured to split the work among existing threads and not to use too much memory, which could substantially slow down our system or even cause a crash. ### Portability -One of the main reasons for using the functionalities available in Thunder is to make the system as portable as possible. But how is that exactly achieved and what does it mean? Well, a system is considered portable if it requires very little effort to run on different platforms. Furthermore, a generalized abstraction between application logic and system interfaces is a prerequisite for portability. That is exactly one of the main goals of Thunder, namely, providing an abstraction layer between plugins and the OS. The general rule of thumb is: do not do something that directly targets the OS in a plugin, since we most likely have an abstraction for that in Thunder; use these abstractions. +One of the main reasons for using the functionalities available in Thunder is to make the system as portable as possible. But how is that exactly achieved and what does it mean? Well, a system is considered portable if it requires very little effort to run on different platforms. Furthermore, a generalized abstraction between application logic and system interfaces is a prerequisite for portability. -You may be wondering now why it is so important. Imagine that in the future, we would like to enable our system to work on a new platform, maybe even one that has not been developed yet. Of course, it would be a huge task anyhow, but think about how much easier it would be if abstractions were used in every plugin instead of each one of them directly targeting the OS on their own. From an architectural point of view, the difference is enormous. If each plugin uses the same abstraction layer, we only need to make changes to this functionality, and we are good to go. On the other hand, if everyone targets the OS on their own, we would literally have to rewrite each and every plugin to be portable to this new environment, which obviously scales really badly with the size of the system. +!!! note + That is exactly one of the main goals of Thunder, namely, providing an abstraction layer between plugins and the OS. The general rule of thumb is: do not do something that directly targets the OS in a plugin, since we most likely have an abstraction for that in Thunder; use these abstractions. + +You may be wondering now why it is so important. Imagine that in the future, we would like to enable our system to work on a new platform, maybe even one that has not been developed yet. Of course, it would be a huge task anyhow, but think about how much easier it would be if abstractions were used in every plugin instead of each one of them directly targeting the OS on their own. + +From an architectural point of view, the difference is enormous. If each plugin uses the same abstraction layer, we only need to make changes to this functionality, and we are good to go. On the other hand, if everyone targets the OS on their own, we would literally have to rewrite each and every plugin to be portable to this new environment, which obviously scales really badly with the size of the system. ## How to use Worker Pool -The whole time up to this point the concept of a thread pool has been discussed as a design pattern. As was mentioned, we have such functionality inside the Thunder core, that is, in `ThreadPool.h`. But the title of this document is Worker Pool and it is time to introduce its main features. First, it can be located in `Thunder/Source/core/ WorkerPool.h`. We could say that it is an interface of sorts that simplifies the usage of a thread pool concept. It actually makes that quite easy, which will be shown later with some examples. So, no worries, it is not like you will have to learn to use something much more complex than, for example, `std::thread`. +The whole time up to this point the concept of a thread pool has been discussed as a design pattern. As was mentioned, we have such functionality inside the Thunder core, that is, in `ThreadPool.h`. But the title of this document is Worker Pool and it is time to introduce its main features. First, it can be located in `Thunder/Source/core/WorkerPool.h`. We could say that it is an interface of sorts that simplifies the usage of a thread pool concept. It actually makes that quite easy, which will be shown later with some examples. So, no worries, it is not like you will have to learn to use something much more complex than, for example, `std::thread`. ### Most important features and methods @@ -64,7 +106,12 @@ public: } ``` -The first thing worth discussing is the class template `JobType<>`, which can be seen in the above listing. Without going into too many details, this class template will allow us to create *jobs*. The concept of a job could be described as follows: inside the plugin, we implement a piece of code that should be executed in a separate thread; afterwards, we submit our job to Thunder (a piece of code responsible for that is in the listing below), and it takes care of it for us. In a bit more detail, the Worker Pool will first try to find a worker (simply a thread inside the thread pool) who is currently not doing anything and +The first thing worth discussing is a class template `JobType<>`, which can be seen in the above listing. Without going into too many details, this class template will allow us to create *jobs*. + +!!! tip + The concept of a job could be described as follows: inside the plugin, we implement a piece of code that should be executed in a separate thread; afterwards, we submit our job to Thunder (a piece of code responsible for that is in the listing below), and it takes care of it for us. + +In a bit more detail, the Worker Pool will first try to find a worker (simply a thread inside the thread pool) who is currently not doing anything and will wait until such a worker is found. Next, it will assign the job to a worker, and that is about it. ``` c++ @@ -81,7 +128,7 @@ bool Submit() ``` So now you know how to create a job and what that means. You have yet to find out how to do that in the code, but that is going to be covered in -the next section. Additionally, it was mentioned that the job can be submitted, but that is not the only thing you can do with a job. It is also possible to reschedule or revoke a job. All of this can be done with the use of very simple methods, namely `Submit()`, `Reschedule()` and `Revoke()`, which can be found in the following listing. +the next section. Additionally, it was mentioned that the job can be submitted, but that is not the only thing you can do with a job. It is also possible to reschedule or revoke a job. All of this can be done with the use of very simple methods, namely `Submit()`, `Reschedule()` and `Revoke()`, which can be found in the following listing. On top of that, scheduling jobs will be described further in the following section. ``` c++ void Revoke() @@ -94,17 +141,20 @@ void Revoke() } ``` -You might be wondering what exactly stands behind a job, that is, what actually happens, for example, when the job is submitted. As mentioned above, the job is an object of a class template `JobType<>`. The key word here is template. When creating a job, you should include a class reference in this template. Then, you need to create a method called `Dispatch()` inside this class, and in this method you put everything that should be executed - about as difficult as using `std::thread`, but infinitely more efficient. +You might be wondering what exactly stands behind a job, that is, what actually happens, for example, when the job is submitted. As mentioned above, the job is an object of a class template `JobType<>`. The key word here is template. + +!!! tip + When creating a job, you should include a class reference in its template. Then, you need to create a method called `Dispatch()` inside this class, and in this method you put everything that should be executed - about as difficult as using `std::thread`, but infinitely more efficient. ### Coding examples -In this subsection, we show what steps to take to code an explanatory job. First, we need to create it as a private member of a class, which can be seen below: +In this section, we show what steps to take to code an explanatory job. First, we need to create it as a private member of a class, which can be seen below: ``` c++ Core::WorkerPool::JobType _job; ``` -As you could have guessed, you simply substitute `className` with the name of a class that will be used inside a plugin to submit a job, and that is almost it. After declaring the member variable `_job`, we have yet to initialize it with some value. If you predicated that the value was simply going to be a pointer to our class, you were right. The easiest way to do that would be inside every constructor of the class, and an example of this can be found below: +As you could have guessed, you simply substitute `className` with the name of a class that will be used inside a plugin to submit a job, and that is almost it. After declaring the member variable `_job`, we have yet to initialize it with some value. If you predicated that the value was simply going to be a *pointer to our class*, you were right. The easiest way to do that would be inside every constructor of the class, and an example of this can be found below: ``` c++ FileObserver() @@ -116,19 +166,34 @@ FileObserver() } ``` -After that, it is only necessary to create the `Dispatch()` method, and we will be able to submit our job with `_job.Submit()`. Furthermore, it is important not to forget about the `Revoke()` method and to know when to call it. Consider a situation where the job is submitted and the class is destructed afterwards. It is essential to remember what happens after a job submission inside the Worker Pool, namely, it is waiting for any worker to be available. If the class is destroyed, either before a worker is assigned or before an actual job is finished, you will surely run into some problems. Because of that, it is worth to keep in mind the lifetime of the object you pass into the `JobType<>` template as a parameter, meaning that you must make sure it is kept alive as long as the job is submitted and/or running. Depending on the situation, the `Revoke()` method will either synchronously stop the potential run or wait for the run to complete. +After that, it is only necessary to create the `Dispatch()` method, and we will be able to submit our job with `_job.Submit()`. Here is a `Dispatch() ` method from `FileObserver` class, but keep in mind that this can be virtually anything that you want to be done for your plugin in a separate thread: -``` c++ -FileObserver() - : _callback(nullptr) - , _position(0) - , _path() - , _job(*this) +```c++ +void Dispatch() { + TRACE(Trace::Information, (_T("FileObserver: job is dispatched"))); + std::ifstream file(_path); + if (file) { + file.seekg(_position, file.beg); + std::string str; + while ((std::getline(file, str)) && (str.size() > 0)) { + ASSERT(_callback != nullptr); + _callback->NewLine(str); + } + } + _position = GetCurrentPosition(_path); } ``` -If, for example, we did not pass a class to the template as a reference, the class would become a composite of the `JobType<>` object and its lifetime would then always be equal to the `JobType<>` object, which is, of course, not intended. The fact that we pass a reference to a class makes it mandatory to call `Revoke()` in its destructor, and the same applies to the `Unregister()` method when callbacks are used, as you can see in the following listing. +!!! warning + It is important not to forget about the `Revoke()` method and to know when to call it. + +Consider a situation where the job is submitted and the class is destructed afterwards. It is essential to remember what happens after a job submission inside the Worker Pool, namely, it is waiting for any worker to be available. If the class is destroyed, either before a worker is assigned or before an actual job is finished, you will surely run into some problems. Because of that, it is worth to keep in mind the lifetime of the object you pass into the `JobType<>` template as a parameter, meaning that you must make sure it is kept alive as long as the job is submitted and/or running. Depending on the situation, the `Revoke()` method will either synchronously stop the potential run or wait for the run to complete. + +If, for example, we did not pass a class to the template as a reference, the class would become a composite of the `JobType<>` object and its lifetime would then always be equal to the `JobType<>` object, which is, of course, not intended. + +!!! warning + The fact that we pass a reference to a class makes it mandatory to call `Revoke()` in its destructor, and the same applies to the `Unregister()` method when callbacks are used, as you can see in the following listing. ``` c++ ~FileObserver() @@ -143,8 +208,12 @@ If, for example, we did not pass a class to the template as a reference, the cla ``` A basic example of properly using the Worker Pool to perform a relatively easy task can be found inside `rdkcentral/ThunderNanoServices/FileTransfer/FileTransfer.h` in the `FileObserver` class, which by the way is another useful and underused -functionality in Thunder, which will be further described in a different document. +functionality in Thunder. ## Conclusions -To sum up, the main idea is not to reinvent the wheel. When creating plugins, developers should keep in mind they are working on a large system in an embedded environment. Because of that from an architectural point of view, a different set of rules applies than when working on developing PC or even mobile applications. We all have to be aware of limitations like the low amount of memory available, the difficulty of keeping a system with dozens of plugins scalable, or even the necessity to use abstractions to achieve portability. These are the main reasons why it is essential to use functionalities that are already given, instead of making things suboptimally on your own. +To sum up, the main idea is not to reinvent the wheel. When creating plugins, developers should keep in mind they are working on a large system in an embedded environment. + +Because of that, from an architectural point of view, a different set of rules applies than when working on developing PC or even mobile applications. We all have to be aware of limitations like the low amount of memory available, the difficulty of keeping a system with dozens of plugins scalable, or even the necessity to use abstractions to achieve portability. + +These are the main reasons why it is essential to use functionalities that are already given, instead of making things suboptimally on your own. From ccd0415b5e6bb8e3a3c506f19b9391a170f2f0b4 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Tue, 25 Jun 2024 16:50:41 +0200 Subject: [PATCH 34/35] Development/workerpool (#1669) * [Tests/unit/core] : Fix build 'test_workerpool'. 'ThreadPool' and 'WorkerPool' changes were not (fully) integrated. * [Tests/unit/core] : Amend 'a65dbb2adf2e9622aae8825c0d88c599a4a252e6'. - Add 1 to occupation to compensate for the 'internal' timer. - Reverse the boolean test for calculating occupation. * [Tests/unit/core] : test for less or equal on timings in 'test_workerpool'. Clock timings are never exact due to resolution, rounding and scheduling. Assume a Job executed earlier is allowed and preferred. * [Tests/unit/core] : Disable instant job completion for 'test_workerpool'. Time resolution and scheduling may prevent instant completion. --------- Co-authored-by: Pierre Wielders --- Tests/unit/core/test_workerpool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/unit/core/test_workerpool.cpp b/Tests/unit/core/test_workerpool.cpp index 5a6a9dd33..e1820c4aa 100644 --- a/Tests/unit/core/test_workerpool.cpp +++ b/Tests/unit/core/test_workerpool.cpp @@ -669,7 +669,7 @@ TEST(Core_WorkerPool, Check_ScheduleJobs_SinglePool_SingleJob) const uint16_t scheduledTimes[] = {2000}; //In milliseconds CheckWorkerPool_ScheduleJobs(1, 1, 0, 0, nullptr, scheduledTimes); } -TEST(Core_WorkerPool, Check_ScheduleJobs_SinglePool_SingleJob_ZeroTime) +TEST(Core_WorkerPool, DISABLED_Check_ScheduleJobs_SinglePool_SingleJob_ZeroTime) { const uint16_t scheduledTimes[] = {0}; CheckWorkerPool_ScheduleJobs(1, 1, 0, 0, nullptr, scheduledTimes); @@ -697,7 +697,7 @@ TEST(Core_WorkerPool, Check_ScheduleJobs_SinglePool_MultipleJobs) const uint16_t scheduledTimes[] = {2000, 3000, 1000, 2000, 3000}; CheckWorkerPool_ScheduleJobs(1, maxJobs, 0, 0, nullptr, scheduledTimes); } -TEST(Core_WorkerPool, Check_ScheduleJobs_SinglePool_MultipleJobs_ZeroTime) +TEST(Core_WorkerPool, DISABLED_Check_ScheduleJobs_SinglePool_MultipleJobs_ZeroTime) { uint8_t maxJobs = 5; const uint16_t scheduledTimes[5] = {0}; From 0392ba8bdc9868dbf96b05cb2c3b7e26f313b084 Mon Sep 17 00:00:00 2001 From: msieben <4319079+msieben@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:13:26 +0200 Subject: [PATCH 35/35] [Tests/unit] : Do not depend on 'IPTestAdministrator' if not used (#1662) Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- Tests/unit/IPTestAdministrator.h | 4 +--- Tests/unit/Module.h | 24 +++++++++++++++++++ Tests/unit/core/test_cyclicbuffer.cpp | 12 ++++++---- Tests/unit/core/test_databuffer.cpp | 7 ++++-- Tests/unit/core/test_dataelement.cpp | 7 ++++-- Tests/unit/core/test_dataelementfile.cpp | 7 ++++-- Tests/unit/core/test_doorbell.cpp | 8 ++++++- Tests/unit/core/test_enumerate.cpp | 8 +++++-- Tests/unit/core/test_event.cpp | 8 +++++-- Tests/unit/core/test_filesystem.cpp | 7 ++++-- Tests/unit/core/test_frametype.cpp | 7 ++++-- Tests/unit/core/test_hash.cpp | 8 +++++-- Tests/unit/core/test_hex2strserialization.cpp | 7 +++++- Tests/unit/core/test_ipc.cpp | 9 +++++-- Tests/unit/core/test_ipcclient.cpp | 9 +++++-- Tests/unit/core/test_iso639.cpp | 7 ++++-- Tests/unit/core/test_iterator.cpp | 7 ++++-- Tests/unit/core/test_jsonparser.cpp | 8 ++++--- Tests/unit/core/test_keyvalue.cpp | 7 ++++-- Tests/unit/core/test_library.cpp | 7 ++++-- Tests/unit/core/test_lockablecontainer.cpp | 7 ++++-- Tests/unit/core/test_measurementtype.cpp | 7 ++++-- Tests/unit/core/test_memberavailability.cpp | 8 +++++-- Tests/unit/core/test_messageException.cpp | 7 ++++-- Tests/unit/core/test_message_dispatcher.cpp | 12 ++++++---- Tests/unit/core/test_message_unit.cpp | 11 ++++++--- Tests/unit/core/test_networkinfo.cpp | 7 ++++-- Tests/unit/core/test_nodeid.cpp | 7 ++++-- Tests/unit/core/test_numbertype.cpp | 7 ++++-- Tests/unit/core/test_optional.cpp | 7 ++++-- Tests/unit/core/test_parser.cpp | 7 ++++-- Tests/unit/core/test_portability.cpp | 8 +++++-- Tests/unit/core/test_processinfo.cpp | 7 ++++-- Tests/unit/core/test_queue.cpp | 7 ++++-- Tests/unit/core/test_rangetype.cpp | 7 ++++-- Tests/unit/core/test_readwritelock.cpp | 7 ++++-- Tests/unit/core/test_rectangle.cpp | 7 ++++-- Tests/unit/core/test_rpc.cpp | 9 ++++--- Tests/unit/core/test_semaphore.cpp | 8 +++++-- Tests/unit/core/test_sharedbuffer.cpp | 9 +++++-- Tests/unit/core/test_singleton.cpp | 7 ++++-- Tests/unit/core/test_socketstreamjson.cpp | 15 ++++++++---- Tests/unit/core/test_socketstreamtext.cpp | 13 ++++++---- Tests/unit/core/test_statetrigger.cpp | 6 ++++- Tests/unit/core/test_stopwatch.cpp | 7 ++++-- Tests/unit/core/test_synchronize.cpp | 7 ++++-- Tests/unit/core/test_synchronous.cpp | 9 +++++-- Tests/unit/core/test_systeminfo.cpp | 13 ++++++---- Tests/unit/core/test_textfragment.cpp | 7 ++++-- Tests/unit/core/test_textreader.cpp | 7 ++++-- Tests/unit/core/test_thread.cpp | 10 +++++--- Tests/unit/core/test_threadpool.cpp | 8 +++++-- Tests/unit/core/test_time.cpp | 8 +++++-- Tests/unit/core/test_timer.cpp | 10 +++++--- Tests/unit/core/test_tracing.cpp | 15 +++++++----- Tests/unit/core/test_tristate.cpp | 7 ++++-- Tests/unit/core/test_valuerecorder.cpp | 7 ++++-- Tests/unit/core/test_weblinkjson.cpp | 9 +++++-- Tests/unit/core/test_weblinktext.cpp | 9 +++++-- Tests/unit/core/test_websocketjson.cpp | 12 +++++++--- Tests/unit/core/test_websockettext.cpp | 12 +++++++--- Tests/unit/core/test_workerpool.cpp | 8 +++++-- Tests/unit/core/test_xgetopt.cpp | 9 ++++--- 63 files changed, 392 insertions(+), 147 deletions(-) create mode 100644 Tests/unit/Module.h diff --git a/Tests/unit/IPTestAdministrator.h b/Tests/unit/IPTestAdministrator.h index 270442e23..ef749723f 100644 --- a/Tests/unit/IPTestAdministrator.h +++ b/Tests/unit/IPTestAdministrator.h @@ -19,12 +19,10 @@ #pragma once -#define MODULE_NAME ThunderUnitTests - #include #include -class IPTestAdministrator; +#include "Module.h" class IPTestAdministrator { diff --git a/Tests/unit/Module.h b/Tests/unit/Module.h new file mode 100644 index 000000000..cb547a8ea --- /dev/null +++ b/Tests/unit/Module.h @@ -0,0 +1,24 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed 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. + */ + +#pragma once + +#ifndef MODULE_NAME +#define MODULE_NAME ThunderUnitTests +#endif diff --git a/Tests/unit/core/test_cyclicbuffer.cpp b/Tests/unit/core/test_cyclicbuffer.cpp index 33ba8c42e..91f16ca5f 100644 --- a/Tests/unit/core/test_cyclicbuffer.cpp +++ b/Tests/unit/core/test_cyclicbuffer.cpp @@ -17,13 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include -#include -#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Core { diff --git a/Tests/unit/core/test_databuffer.cpp b/Tests/unit/core/test_databuffer.cpp index 01542ecbf..cf8daf999 100644 --- a/Tests/unit/core/test_databuffer.cpp +++ b/Tests/unit/core/test_databuffer.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_dataelement.cpp b/Tests/unit/core/test_dataelement.cpp index 88dc1c5d9..358527739 100644 --- a/Tests/unit/core/test_dataelement.cpp +++ b/Tests/unit/core/test_dataelement.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_dataelementfile.cpp b/Tests/unit/core/test_dataelementfile.cpp index 35a61980d..1dffb9607 100644 --- a/Tests/unit/core/test_dataelementfile.cpp +++ b/Tests/unit/core/test_dataelementfile.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_doorbell.cpp b/Tests/unit/core/test_doorbell.cpp index 56990a424..ecc6cca21 100644 --- a/Tests/unit/core/test_doorbell.cpp +++ b/Tests/unit/core/test_doorbell.cpp @@ -16,11 +16,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "../IPTestAdministrator.h" #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_enumerate.cpp b/Tests/unit/core/test_enumerate.cpp index aacec7d66..8b53bd78f 100644 --- a/Tests/unit/core/test_enumerate.cpp +++ b/Tests/unit/core/test_enumerate.cpp @@ -17,9 +17,13 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME + +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_event.cpp b/Tests/unit/core/test_event.cpp index 06fe9e25f..26c75096d 100644 --- a/Tests/unit/core/test_event.cpp +++ b/Tests/unit/core/test_event.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_filesystem.cpp b/Tests/unit/core/test_filesystem.cpp index 2dea5b4e5..b51eb51d1 100644 --- a/Tests/unit/core/test_filesystem.cpp +++ b/Tests/unit/core/test_filesystem.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_frametype.cpp b/Tests/unit/core/test_frametype.cpp index 22252e01e..d79c8a358 100644 --- a/Tests/unit/core/test_frametype.cpp +++ b/Tests/unit/core/test_frametype.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_hash.cpp b/Tests/unit/core/test_hash.cpp index 58c588c65..0ff9d7db8 100644 --- a/Tests/unit/core/test_hash.cpp +++ b/Tests/unit/core/test_hash.cpp @@ -17,12 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include -#include namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_hex2strserialization.cpp b/Tests/unit/core/test_hex2strserialization.cpp index 03d5dc45a..6b9075a01 100644 --- a/Tests/unit/core/test_hex2strserialization.cpp +++ b/Tests/unit/core/test_hex2strserialization.cpp @@ -16,11 +16,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "../IPTestAdministrator.h" + #include #include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include "core/core.h" namespace Thunder { diff --git a/Tests/unit/core/test_ipc.cpp b/Tests/unit/core/test_ipc.cpp index 4a8217ce3..4bfea2226 100644 --- a/Tests/unit/core/test_ipc.cpp +++ b/Tests/unit/core/test_ipc.cpp @@ -17,11 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_ipcclient.cpp b/Tests/unit/core/test_ipcclient.cpp index 016dfdc96..9edd7ae49 100644 --- a/Tests/unit/core/test_ipcclient.cpp +++ b/Tests/unit/core/test_ipcclient.cpp @@ -17,11 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_iso639.cpp b/Tests/unit/core/test_iso639.cpp index 2d38cd393..71f1446a1 100644 --- a/Tests/unit/core/test_iso639.cpp +++ b/Tests/unit/core/test_iso639.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_iterator.cpp b/Tests/unit/core/test_iterator.cpp index be26042cf..8d656ecd7 100644 --- a/Tests/unit/core/test_iterator.cpp +++ b/Tests/unit/core/test_iterator.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_jsonparser.cpp b/Tests/unit/core/test_jsonparser.cpp index 684a33090..8cccbf459 100644 --- a/Tests/unit/core/test_jsonparser.cpp +++ b/Tests/unit/core/test_jsonparser.cpp @@ -19,14 +19,16 @@ #include #include +#include #include -#include "../IPTestAdministrator.h" +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include - namespace Thunder { enum class JSONTestEnum { ENUM_1, diff --git a/Tests/unit/core/test_keyvalue.cpp b/Tests/unit/core/test_keyvalue.cpp index 12089ab7f..e60b8ac6b 100644 --- a/Tests/unit/core/test_keyvalue.cpp +++ b/Tests/unit/core/test_keyvalue.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_library.cpp b/Tests/unit/core/test_library.cpp index dc2aa207c..b6aa99ae5 100644 --- a/Tests/unit/core/test_library.cpp +++ b/Tests/unit/core/test_library.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_lockablecontainer.cpp b/Tests/unit/core/test_lockablecontainer.cpp index 76a42faa7..634d19757 100644 --- a/Tests/unit/core/test_lockablecontainer.cpp +++ b/Tests/unit/core/test_lockablecontainer.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_measurementtype.cpp b/Tests/unit/core/test_measurementtype.cpp index bcd96f2f1..fed7764b6 100644 --- a/Tests/unit/core/test_measurementtype.cpp +++ b/Tests/unit/core/test_measurementtype.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_memberavailability.cpp b/Tests/unit/core/test_memberavailability.cpp index df8306414..0b437afd8 100644 --- a/Tests/unit/core/test_memberavailability.cpp +++ b/Tests/unit/core/test_memberavailability.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_messageException.cpp b/Tests/unit/core/test_messageException.cpp index 377d17d2f..86180ddbd 100644 --- a/Tests/unit/core/test_messageException.cpp +++ b/Tests/unit/core/test_messageException.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_message_dispatcher.cpp b/Tests/unit/core/test_message_dispatcher.cpp index e3419552d..c741e4844 100644 --- a/Tests/unit/core/test_message_dispatcher.cpp +++ b/Tests/unit/core/test_message_dispatcher.cpp @@ -17,13 +17,17 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include -#include #include -#include -#include +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_message_unit.cpp b/Tests/unit/core/test_message_unit.cpp index 7610a8cc4..ff3e3bfda 100644 --- a/Tests/unit/core/test_message_unit.cpp +++ b/Tests/unit/core/test_message_unit.cpp @@ -17,11 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include -#include +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include + +#include "../IPTestAdministrator.h" + using namespace Thunder; class Control : public Core::Messaging::IControl { diff --git a/Tests/unit/core/test_networkinfo.cpp b/Tests/unit/core/test_networkinfo.cpp index 96892dfb4..b09b5d70c 100644 --- a/Tests/unit/core/test_networkinfo.cpp +++ b/Tests/unit/core/test_networkinfo.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_nodeid.cpp b/Tests/unit/core/test_nodeid.cpp index 026264e4f..7ff22fccc 100644 --- a/Tests/unit/core/test_nodeid.cpp +++ b/Tests/unit/core/test_nodeid.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_numbertype.cpp b/Tests/unit/core/test_numbertype.cpp index 05d3f4682..5bc5a658b 100644 --- a/Tests/unit/core/test_numbertype.cpp +++ b/Tests/unit/core/test_numbertype.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_optional.cpp b/Tests/unit/core/test_optional.cpp index ba0961cc0..c802dbeea 100644 --- a/Tests/unit/core/test_optional.cpp +++ b/Tests/unit/core/test_optional.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_parser.cpp b/Tests/unit/core/test_parser.cpp index e0d367269..9ba705362 100644 --- a/Tests/unit/core/test_parser.cpp +++ b/Tests/unit/core/test_parser.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_portability.cpp b/Tests/unit/core/test_portability.cpp index a4c706522..24e448615 100644 --- a/Tests/unit/core/test_portability.cpp +++ b/Tests/unit/core/test_portability.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_processinfo.cpp b/Tests/unit/core/test_processinfo.cpp index a3b10e97d..5ab22f4a9 100644 --- a/Tests/unit/core/test_processinfo.cpp +++ b/Tests/unit/core/test_processinfo.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_queue.cpp b/Tests/unit/core/test_queue.cpp index 80a765e3a..80c5e237a 100644 --- a/Tests/unit/core/test_queue.cpp +++ b/Tests/unit/core/test_queue.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_rangetype.cpp b/Tests/unit/core/test_rangetype.cpp index 0da321e63..d5aa74709 100644 --- a/Tests/unit/core/test_rangetype.cpp +++ b/Tests/unit/core/test_rangetype.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include namespace Thunder { diff --git a/Tests/unit/core/test_readwritelock.cpp b/Tests/unit/core/test_readwritelock.cpp index 80725dd85..18c72583b 100644 --- a/Tests/unit/core/test_readwritelock.cpp +++ b/Tests/unit/core/test_readwritelock.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_rectangle.cpp b/Tests/unit/core/test_rectangle.cpp index 27faeef08..2900036b8 100644 --- a/Tests/unit/core/test_rectangle.cpp +++ b/Tests/unit/core/test_rectangle.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_rpc.cpp b/Tests/unit/core/test_rpc.cpp index de3ce2a1f..bac4cd4d6 100644 --- a/Tests/unit/core/test_rpc.cpp +++ b/Tests/unit/core/test_rpc.cpp @@ -17,13 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include -#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Exchange { diff --git a/Tests/unit/core/test_semaphore.cpp b/Tests/unit/core/test_semaphore.cpp index 556fba1bc..356aaf710 100644 --- a/Tests/unit/core/test_semaphore.cpp +++ b/Tests/unit/core/test_semaphore.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_sharedbuffer.cpp b/Tests/unit/core/test_sharedbuffer.cpp index df4650ca9..c3577700f 100644 --- a/Tests/unit/core/test_sharedbuffer.cpp +++ b/Tests/unit/core/test_sharedbuffer.cpp @@ -17,11 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_singleton.cpp b/Tests/unit/core/test_singleton.cpp index b9d42e74e..26a1acf18 100644 --- a/Tests/unit/core/test_singleton.cpp +++ b/Tests/unit/core/test_singleton.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_socketstreamjson.cpp b/Tests/unit/core/test_socketstreamjson.cpp index 23afc4ab3..337491e46 100644 --- a/Tests/unit/core/test_socketstreamjson.cpp +++ b/Tests/unit/core/test_socketstreamjson.cpp @@ -17,13 +17,18 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - -#include -#include -#include #include #include + +#include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_socketstreamtext.cpp b/Tests/unit/core/test_socketstreamtext.cpp index 7272f421a..6a613e876 100644 --- a/Tests/unit/core/test_socketstreamtext.cpp +++ b/Tests/unit/core/test_socketstreamtext.cpp @@ -17,13 +17,18 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include -#include -#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_statetrigger.cpp b/Tests/unit/core/test_statetrigger.cpp index 6c92bf06d..48d514df3 100644 --- a/Tests/unit/core/test_statetrigger.cpp +++ b/Tests/unit/core/test_statetrigger.cpp @@ -16,9 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "../IPTestAdministrator.h" #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_stopwatch.cpp b/Tests/unit/core/test_stopwatch.cpp index 48a6b9479..97b11a508 100644 --- a/Tests/unit/core/test_stopwatch.cpp +++ b/Tests/unit/core/test_stopwatch.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_synchronize.cpp b/Tests/unit/core/test_synchronize.cpp index 2cb5f57d6..8fcec033f 100644 --- a/Tests/unit/core/test_synchronize.cpp +++ b/Tests/unit/core/test_synchronize.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_synchronous.cpp b/Tests/unit/core/test_synchronous.cpp index 70083770f..700aab9aa 100644 --- a/Tests/unit/core/test_synchronous.cpp +++ b/Tests/unit/core/test_synchronous.cpp @@ -17,11 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include +#include "../IPTestAdministrator.h" + using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_systeminfo.cpp b/Tests/unit/core/test_systeminfo.cpp index 56e517e96..b1784f72d 100644 --- a/Tests/unit/core/test_systeminfo.cpp +++ b/Tests/unit/core/test_systeminfo.cpp @@ -17,17 +17,20 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include - -#include -#include #include #include #include #include +#include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_textfragment.cpp b/Tests/unit/core/test_textfragment.cpp index fde006b6c..ff2e979ef 100644 --- a/Tests/unit/core/test_textfragment.cpp +++ b/Tests/unit/core/test_textfragment.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_textreader.cpp b/Tests/unit/core/test_textreader.cpp index 864c000ee..f075fb3cc 100644 --- a/Tests/unit/core/test_textreader.cpp +++ b/Tests/unit/core/test_textreader.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_thread.cpp b/Tests/unit/core/test_thread.cpp index defbf2502..2ef0e2aaf 100644 --- a/Tests/unit/core/test_thread.cpp +++ b/Tests/unit/core/test_thread.cpp @@ -17,12 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include -#include namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_threadpool.cpp b/Tests/unit/core/test_threadpool.cpp index 42443a27b..29295cf00 100644 --- a/Tests/unit/core/test_threadpool.cpp +++ b/Tests/unit/core/test_threadpool.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_time.cpp b/Tests/unit/core/test_time.cpp index 0e193ba55..3a3ca588e 100644 --- a/Tests/unit/core/test_time.cpp +++ b/Tests/unit/core/test_time.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_timer.cpp b/Tests/unit/core/test_timer.cpp index a919d792d..0e91402e2 100644 --- a/Tests/unit/core/test_timer.cpp +++ b/Tests/unit/core/test_timer.cpp @@ -17,12 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include -#include namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_tracing.cpp b/Tests/unit/core/test_tracing.cpp index 0d32cb406..b85ff04c7 100644 --- a/Tests/unit/core/test_tracing.cpp +++ b/Tests/unit/core/test_tracing.cpp @@ -17,13 +17,16 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include -#include -#include -#include +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include + +#include "../IPTestAdministrator.h" + using namespace Thunder; using namespace Thunder::Core; @@ -348,4 +351,4 @@ TEST(Core_tracing, simpleTracingReversed) testAdmin.WaitForChildCompletion(); Singleton::Dispose(); -} \ No newline at end of file +} diff --git a/Tests/unit/core/test_tristate.cpp b/Tests/unit/core/test_tristate.cpp index 2d71c0c52..7067c5591 100644 --- a/Tests/unit/core/test_tristate.cpp +++ b/Tests/unit/core/test_tristate.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include using namespace Thunder; diff --git a/Tests/unit/core/test_valuerecorder.cpp b/Tests/unit/core/test_valuerecorder.cpp index ac939d8fe..f7e8446fb 100644 --- a/Tests/unit/core/test_valuerecorder.cpp +++ b/Tests/unit/core/test_valuerecorder.cpp @@ -17,9 +17,12 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include "gtest/gtest.h" + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include "core/core.h" using namespace Thunder; diff --git a/Tests/unit/core/test_weblinkjson.cpp b/Tests/unit/core/test_weblinkjson.cpp index f811a24ab..a9821292c 100644 --- a/Tests/unit/core/test_weblinkjson.cpp +++ b/Tests/unit/core/test_weblinkjson.cpp @@ -17,12 +17,17 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_weblinktext.cpp b/Tests/unit/core/test_weblinktext.cpp index 49d135c0a..fcf37dcca 100644 --- a/Tests/unit/core/test_weblinktext.cpp +++ b/Tests/unit/core/test_weblinktext.cpp @@ -17,12 +17,17 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include +#include "../IPTestAdministrator.h" + namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_websocketjson.cpp b/Tests/unit/core/test_websocketjson.cpp index 4f9e19c19..54809313e 100644 --- a/Tests/unit/core/test_websocketjson.cpp +++ b/Tests/unit/core/test_websocketjson.cpp @@ -17,13 +17,19 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include -#include -#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_websockettext.cpp b/Tests/unit/core/test_websockettext.cpp index 6753e9ab5..c118e7e53 100644 --- a/Tests/unit/core/test_websockettext.cpp +++ b/Tests/unit/core/test_websockettext.cpp @@ -17,13 +17,19 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include #include -#include -#include + +#include "../IPTestAdministrator.h" namespace Thunder { namespace Tests { diff --git a/Tests/unit/core/test_workerpool.cpp b/Tests/unit/core/test_workerpool.cpp index e1820c4aa..a9bbae498 100644 --- a/Tests/unit/core/test_workerpool.cpp +++ b/Tests/unit/core/test_workerpool.cpp @@ -17,11 +17,15 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" +#include #include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + #include -#include using namespace Thunder; using namespace Thunder::Core; diff --git a/Tests/unit/core/test_xgetopt.cpp b/Tests/unit/core/test_xgetopt.cpp index 27feec7c8..320411080 100644 --- a/Tests/unit/core/test_xgetopt.cpp +++ b/Tests/unit/core/test_xgetopt.cpp @@ -17,10 +17,13 @@ * limitations under the License. */ -#include "../IPTestAdministrator.h" - #include -#include + +#ifndef MODULE_NAME +#include "../Module.h" +#endif + +#include int argumentCount = 3; char* arguments[]= {(char*)"-c", (char*)"-h", (char*)"-b"};