diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4ddfb11 --- /dev/null +++ b/.clang-format @@ -0,0 +1,62 @@ +--- +BasedOnStyle: Chromium +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +#AllowAllArgumentsOnNextLine: 'false' +#AlignConsecutiveAssignments: None +#AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: true +AllowAllParametersOfDeclarationOnNextLine: true +#AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +#AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +ColumnLimit: 140 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +IndentCaseLabels: true +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +ObjCBlockIndentWidth: 4 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +#SortIncludes: Never +SpaceAfterCStyleCast: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpacesBeforeTrailingComments: 2 +Standard: Auto +TabWidth: 4 +UseTab: Never +#NamespaceMacros: +# - DECLARE_TEMPLATED_OPENDAQ_INTERFACE_T +# - DECLARE_TEMPLATED_OPENDAQ_INTERFACE_T_U +# - DECLARE_OPENDAQ_INTERFACE_EX +# - DECLARE_OPENDAQ_INTERFACE +FixNamespaceComments: false +#MacroBlockBegin: "^BEGIN_NAMESPACE_OPENDAQ$" +#MacroBlockEnd: "^END_NAMESPACE_OPENDAQ" +#IndentPPDirectives: BeforeHash +#SeparateDefinitionBlocks: Always +... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..72081c9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[{*.{cpp,h},CMakeLists.txt,*.rtclass,*.cmake,*.json}] +indent_style = space +indent_size = 4 +tab_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.yml] +ident_style = space +ident_size = 2 +tab_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8884b5b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto +*.[tT][xX][tT] text +*.[sS][hH] text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..67a4fdd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,101 @@ +name: Build and Test + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +jobs: + build-and-test: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + generator: Ninja + - os: windows-latest + generator: "Visual Studio 17 2022" + + runs-on: ${{ matrix.os }} + + steps: + - name: Install additional dependencies + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install -y --no-install-recommends mono-runtime libmono-system-json-microsoft4.0-cil libmono-system-data4.0-cil + + - name: Checkout project repo + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch || github.event.client_payload.branch || github.ref }} + + - name: Configure project with CMake + run: cmake -B build/output -S . -G "${{ matrix.generator }}" -DDAQMODULES_LT_STREAMING_ENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug + + - name: Build project with CMake + run: cmake --build build/output --config Debug + + - name: Run project tests with CMake + run: ctest --test-dir build/output --output-on-failure -C Debug + + install-build-and-test: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + generator: Ninja + - os: windows-latest + generator: "Visual Studio 17 2022" + + runs-on: ${{ matrix.os }} + env: + INSTALL_PREFIX: ${{ github.workspace }}/opendaq_install + + steps: + - name: Install additional dependencies + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get install -y --no-install-recommends mono-runtime libmono-system-json-microsoft4.0-cil libmono-system-data4.0-cil + + - name: Checkout module + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch || github.event.client_payload.branch || github.ref }} + path: module + + - name: Read openDAQ version + shell: bash + working-directory: module + run: | + opendaq_ref=$(cat external/opendaq_ref) + echo "OPENDAQ_REF=$opendaq_ref" >> $GITHUB_ENV + + - name: Checkout openDAQ + uses: actions/checkout@v4 + with: + repository: openDAQ/openDAQ + ref: ${{ env.OPENDAQ_REF }} + path: opendaq + + - name: Configure, build and install openDAQ + working-directory: opendaq + run: | + cmake -B build/output -S . -G "${{ matrix.generator }}" -DOPENDAQ_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${{ env.INSTALL_PREFIX }}" + cmake --build build/output --config Release + cmake --install build/output --config Release + + - name: Add DLL path (Windows only) + if: matrix.os == 'windows-latest' + run: echo "${{ env.INSTALL_PREFIX }}/lib" >> $env:GITHUB_PATH + + - name: Configure project with CMake + working-directory: module + run: cmake -B build/output -S . -G "${{ matrix.generator }}" -DDAQMODULES_LT_STREAMING_ENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DopenDAQ_DIR="${{ env.INSTALL_PREFIX }}/lib/cmake/opendaq/" + + - name: Build project with CMake + working-directory: module + run: cmake --build build/output --config Release + + - name: Run project tests with CMake + working-directory: module + run: ctest --test-dir build/output --output-on-failure -C Release diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..295355a --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# file types +*.bin +*.bak +*.cache +*.check_cache +*.db +*.dcu +*.depend +*.exp +*.filters +*.idb +*.ilk +*.list +*.log +*.obj +*.orig +*.pdb +*.pyc +*.rule +*.rsm +*.stamp +*.stat +*.suo +*.tlog +*.user + +# IDE files +.idea/ +.idea_/ +.vs/ +.vscode/ +__history/ +__recovery/ +__pycache__/ + +# build and backup folders +/_build* +/build* +/build_win +/cmake-build* +/out* +bckp + +# cmake +CMakeUserPresets.json +CMakeSettings.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..415f006 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +set(CMAKE_POLICY_VERSION_MINIMUM 3.5) +cmake_minimum_required(VERSION 3.25) + +set(REPO_NAME LtStreamingModulesModern) +set(REPO_OPTION_PREFIX DAQMODULES_LT_STREAMING) + +add_subdirectory(cmake) + +opendaq_setup_repo_version("${REPO_OPTION_PREFIX}" ${REPO_NAME} "module_version") + +if(NOT DEFINED ${REPO_OPTION_PREFIX}_VERSION) + message(FATAL_ERROR "Module project version is not specified - specify module version using -D${${REPO_OPTION_PREFIX}_VERSION} or via module_version file in module project root dir") +endif() + +project(${REPO_NAME} VERSION ${${REPO_OPTION_PREFIX}_VERSION} LANGUAGES CXX) + +opendaq_module_common_setup(${REPO_OPTION_PREFIX} ${REPO_NAME}) + +add_subdirectory(external) + +add_subdirectory(shared) +add_subdirectory(modules) + diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..99c8a24 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,222 @@ +{ + "version": 4, + "configurePresets": [ + { + "name": "debug", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "binaryDir": "build/${presetName}" + }, + { + "name": "release", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + }, + "binaryDir": "build/${presetName}" + }, + { + "name": "gcc", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++" + } + }, + { + "name": "clang", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + } + }, + { + "name": "intel-llvm", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "icx", + "CMAKE_CXX_COMPILER": "icpx" + } + }, + { + "name": "ninja", + "hidden": true, + "generator": "Ninja" + }, + { + "name": "msvc-17", + "hidden": true, + "generator": "Visual Studio 15 2017", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Windows" ] + } + } + }, + { + "name": "msvc-22", + "hidden": true, + "generator": "Visual Studio 17 2022", + "inherits": [ + "msvc-17" + ] + }, + { + "name": "msvc-x86", + "hidden": true, + "architecture": "Win32", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Windows" ] + } + } + }, + { + "name": "msvc-x64", + "hidden": true, + "architecture": "x64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Windows" ] + } + } + }, + { + "name": "full", + "hidden": true + }, + { + "name": "ci", + "hidden": false, + "inherits": [ + "full" + ] + }, + { + "name": "full/release", + "hidden": true, + "displayName": "Full - Release", + "inherits": [ + "release", + "full" + ] + }, + { + "name": "full/debug", + "hidden": true, + "displayName": "Full - Release", + "inherits": [ + "debug", + "full" + ] + }, + { + "name": "x86/msvc-17/full", + "displayName": "[MSVC 17] Full - x86", + "inherits": [ + "full/release", + "msvc-17", + "msvc-x86" + ] + }, + { + "name": "x64/msvc-17/full", + "displayName": "[MSVC 17] Full - x64", + "inherits": [ + "full/release", + "msvc-17", + "msvc-x64" + ] + }, + { + "name": "x86/msvc-22/full", + "displayName": "[MSVC 22] Full - x86", + "inherits": [ + "full/release", + "msvc-22", + "msvc-x86" + ] + }, + { + "name": "x64/msvc-22/full", + "displayName": "[MSVC 22] Full - x64", + "inherits": [ + "full/release", + "msvc-22", + "msvc-x64" + ] + }, + { + "name": "x64/gcc/full/debug", + "displayName": "[GCC] Full - Debug", + "inherits": [ + "full/debug", + "gcc", + "ninja" + ] + }, + { + "name": "x64/gcc/full/release", + "displayName": "[GCC] Full - Release", + "inherits": [ + "full/release", + "gcc", + "ninja" + ] + }, + { + "name": "x64/clang/full/debug", + "displayName": "[Clang] Full - Debug", + "inherits": [ + "full/debug", + "clang", + "ninja" + ] + }, + { + "name": "x64/clang/full/release", + "displayName": "[Clang] Full - Release", + "inherits": [ + "full/release", + "clang", + "ninja" + ] + }, + { + "name": "x64/intel-llvm/full/debug", + "displayName": "[IntelLLVM] Full - Debug", + "inherits": [ + "full/debug", + "intel-llvm", + "ninja" + ] + }, + { + "name": "x64/intel-llvm/full/release", + "displayName": "[IntelLLVM] Full - Release", + "inherits": [ + "full/release", + "intel-llvm", + "ninja" + ] + } + ] +} diff --git a/LICENSE b/LICENSE index 261eeb9..1c17a0a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -174,28 +174,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 0000000..de859f0 --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CMAKE_FOLDER "cmake") + +list(APPEND CMAKE_MESSAGE_CONTEXT cmake) +set(CURR_MESSAGE_CONTEXT ${CMAKE_MESSAGE_CONTEXT}) + +message(STATUS "Import functions and macro from opendaq-cmake-utils repo") +include(FetchContent) +FetchContent_Declare( + opendaq-cmake-utils + GIT_REPOSITORY https://github.com/openDAQ/opendaq-cmake-utils.git + GIT_TAG main + GIT_PROGRESS ON +) +FetchContent_MakeAvailable(opendaq-cmake-utils) diff --git a/external/Boost.cmake b/external/Boost.cmake new file mode 100644 index 0000000..64c262b --- /dev/null +++ b/external/Boost.cmake @@ -0,0 +1,10 @@ +opendaq_add_required_boost_libs( + algorithm + asio + beast + program_options + uuid + signals2 + serialization + multiprecision +) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 0000000..834f167 --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,5 @@ +set(CMAKE_FOLDER external) +list(APPEND CMAKE_MESSAGE_CONTEXT external) + +opendaq_setup_module_default_dependencies(${REPO_OPTION_PREFIX}) +add_subdirectory(ws-streaming) diff --git a/external/opendaq_ref b/external/opendaq_ref new file mode 100644 index 0000000..e5aef74 --- /dev/null +++ b/external/opendaq_ref @@ -0,0 +1 @@ +other/module-deps-refactoring \ No newline at end of file diff --git a/module_version b/module_version new file mode 100644 index 0000000..c06dab4 --- /dev/null +++ b/module_version @@ -0,0 +1 @@ +3.31.0dev \ No newline at end of file diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 0000000..214be03 --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,12 @@ +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME) + +if (MSVC) + add_compile_options(/wd4100) +endif() + +if (POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) +endif() + +add_subdirectory(websocket_streaming_client_module) +add_subdirectory(websocket_streaming_server_module) diff --git a/modules/websocket_streaming_client_module/CMakeLists.txt b/modules/websocket_streaming_client_module/CMakeLists.txt index dd07a83..1d79140 100644 --- a/modules/websocket_streaming_client_module/CMakeLists.txt +++ b/modules/websocket_streaming_client_module/CMakeLists.txt @@ -1,10 +1,6 @@ -set_cmake_folder_context(TARGET_FOLDER_NAME) - -project( - WebsocketStreamingClientModule - VERSION ${OPENDAQ_PACKAGE_VERSION} - LANGUAGES C CXX -) +cmake_minimum_required(VERSION 3.10) +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME) +project(WebsocketStreamingClientModule VERSION ${${REPO_OPTION_PREFIX}_VERSION} LANGUAGES C CXX) if (MSVC) # loss of data / precision, unsigned <--> signed @@ -20,6 +16,6 @@ endif() add_subdirectory(src) -if (OPENDAQ_ENABLE_TESTS) +if (${REPO_OPTION_PREFIX}_BUILDING_AS_SUBMODULE AND OPENDAQ_ENABLE_TESTS OR ${REPO_OPTION_PREFIX}_ENABLE_TESTS) add_subdirectory(tests) -endif() +endif() \ No newline at end of file diff --git a/modules/websocket_streaming_client_module/src/CMakeLists.txt b/modules/websocket_streaming_client_module/src/CMakeLists.txt index de1417d..8e549e4 100644 --- a/modules/websocket_streaming_client_module/src/CMakeLists.txt +++ b/modules/websocket_streaming_client_module/src/CMakeLists.txt @@ -11,7 +11,7 @@ set(SRC_Srcs websocket_streaming_client_module_impl.cpp ) -prepend_include(${TARGET_FOLDER_NAME} SRC_Include) +opendaq_prepend_include(${TARGET_FOLDER_NAME} SRC_Include) source_group(module FILES ../include/${TARGET_FOLDER_NAME}/websocket_streaming_client_module_impl.h @@ -24,7 +24,7 @@ source_group(module FILES ) add_library(${LIB_NAME} SHARED ${SRC_Include} ${SRC_Srcs}) -add_library(${SDK_TARGET_NAMESPACE}::${LIB_NAME} ALIAS ${LIB_NAME}) +add_library(${OPENDAQ_SDK_TARGET_NAMESPACE}::${LIB_NAME} ALIAS ${LIB_NAME}) if (MSVC) target_compile_options(${LIB_NAME} PRIVATE /bigobj) @@ -47,4 +47,4 @@ target_include_directories(${LIB_NAME} opendaq_set_module_properties(${LIB_NAME} ${PROJECT_VERSION_MAJOR}) -create_version_header(${LIB_NAME}) +opendaq_create_version_header(${LIB_NAME}) diff --git a/modules/websocket_streaming_client_module/src/websocket_streaming_client_module_impl.cpp b/modules/websocket_streaming_client_module/src/websocket_streaming_client_module_impl.cpp index 5d5eb53..db65658 100644 --- a/modules/websocket_streaming_client_module/src/websocket_streaming_client_module_impl.cpp +++ b/modules/websocket_streaming_client_module/src/websocket_streaming_client_module_impl.cpp @@ -110,7 +110,9 @@ DevicePtr WebsocketStreamingClientModule::onCreateDevice(const StringPtr& connec std::scoped_lock lock(sync); std::string localId = fmt::format("websocket_pseudo_device{}", deviceIndex++); - auto device = createWithImplementation(context, parent, localId, strPtr); + auto deviceType = WsStreamingDevice::createNewType(); + checkErrorInfo(deviceType.asPtr()->setModuleInfo(moduleInfo)); + auto device = createWithImplementation(context, parent, localId, strPtr, deviceType); // Set the connection info for the device auto host = String(""); diff --git a/modules/websocket_streaming_client_module/tests/CMakeLists.txt b/modules/websocket_streaming_client_module/tests/CMakeLists.txt index a251317..4588d2b 100644 --- a/modules/websocket_streaming_client_module/tests/CMakeLists.txt +++ b/modules/websocket_streaming_client_module/tests/CMakeLists.txt @@ -8,8 +8,8 @@ set(TEST_SOURCES test_websocket_streaming_client_module.cpp add_executable(${TEST_APP} ${TEST_SOURCES} ) -target_link_libraries(${TEST_APP} PRIVATE daq::test_utils - ${SDK_TARGET_NAMESPACE}::${MODULE_NAME} +target_link_libraries(${TEST_APP} PRIVATE daq::opendaq_test_utils gtest + ${OPENDAQ_SDK_TARGET_NAMESPACE}::${MODULE_NAME} ) add_test(NAME ${TEST_APP} diff --git a/modules/websocket_streaming_client_module/tests/test_app.cpp b/modules/websocket_streaming_client_module/tests/test_app.cpp index d92f41f..2d76abc 100644 --- a/modules/websocket_streaming_client_module/tests/test_app.cpp +++ b/modules/websocket_streaming_client_module/tests/test_app.cpp @@ -1,15 +1,10 @@ #include -#include +#include -#include -#include #include int main(int argc, char** args) { - daq::daqInitializeCoreObjectsTesting(); - daqInitModuleManagerLibrary(); - testing::InitGoogleTest(&argc, args); testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); diff --git a/modules/websocket_streaming_client_module/tests/test_websocket_streaming_client_module.cpp b/modules/websocket_streaming_client_module/tests/test_websocket_streaming_client_module.cpp index aff83f6..673815e 100644 --- a/modules/websocket_streaming_client_module/tests/test_websocket_streaming_client_module.cpp +++ b/modules/websocket_streaming_client_module/tests/test_websocket_streaming_client_module.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -90,33 +89,6 @@ TEST_F(WebsocketStreamingClientModuleTest, CreateDeviceConnectionStringInvalidId ASSERT_THROW(module.createDevice("daq.opcua://devicett3axxr1", nullptr), InvalidParameterException); } -//TEST_F(WebsocketStreamingClientModuleTest, CreateConnectionString) -//{ -// auto context = NullContext(); -// ModulePtr module; -// createModule(&module, context); -// -// StringPtr connectionString; -// -// ServerCapabilityConfigPtr serverCapabilityIgnored = ServerCapability("test", "test", ProtocolType::Unknown); -// ASSERT_NO_THROW(connectionString = module.createConnectionString(serverCapabilityIgnored)); -// ASSERT_FALSE(connectionString.assigned()); -// -// ServerCapabilityConfigPtr serverCapability = ServerCapability("OpenDAQLTStreaming", "OpenDAQLTStreaming", ProtocolType::Streaming); -// ASSERT_THROW(module.createConnectionString(serverCapability), InvalidParameterException); -// -// serverCapability.addAddress("123.123.123.123"); -// ASSERT_EQ(module.createConnectionString(serverCapability), "daq.lt://123.123.123.123:7414"); -// -// serverCapability.setPort(1234); -// ASSERT_NO_THROW(connectionString = module.createConnectionString(serverCapability)); -// ASSERT_EQ(connectionString, "daq.lt://123.123.123.123:1234"); -// -// serverCapability.addProperty(StringProperty("Path", "/path")); -// ASSERT_NO_THROW(connectionString = module.createConnectionString(serverCapability)); -// ASSERT_EQ(connectionString, "daq.lt://123.123.123.123:1234/path"); -//} - TEST_F(WebsocketStreamingClientModuleTest, CreateStreamingWithNullArguments) { auto module = CreateModule(); diff --git a/modules/websocket_streaming_server_module/CMakeLists.txt b/modules/websocket_streaming_server_module/CMakeLists.txt index 6225a37..12e32a4 100644 --- a/modules/websocket_streaming_server_module/CMakeLists.txt +++ b/modules/websocket_streaming_server_module/CMakeLists.txt @@ -1,13 +1,9 @@ -set_cmake_folder_context(TARGET_FOLDER_NAME) - -project( - WebsocketStreamingServerModule - VERSION ${OPENDAQ_PACKAGE_VERSION} - LANGUAGES CXX -) +cmake_minimum_required(VERSION 3.10) +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME) +project(WebsocketStreamingServerModule VERSION ${${REPO_OPTION_PREFIX}_VERSION} LANGUAGES CXX) add_subdirectory(src) -if (OPENDAQ_ENABLE_TESTS) +if (${REPO_OPTION_PREFIX}_BUILDING_AS_SUBMODULE AND OPENDAQ_ENABLE_TESTS OR ${REPO_OPTION_PREFIX}_ENABLE_TESTS) add_subdirectory(tests) endif() diff --git a/modules/websocket_streaming_server_module/src/CMakeLists.txt b/modules/websocket_streaming_server_module/src/CMakeLists.txt index d2a8121..b6fb7ae 100644 --- a/modules/websocket_streaming_server_module/src/CMakeLists.txt +++ b/modules/websocket_streaming_server_module/src/CMakeLists.txt @@ -15,7 +15,7 @@ set(SRC_Srcs ws_streaming_server_outlet_fb.cpp ) -prepend_include(${TARGET_FOLDER_NAME} SRC_Include) +opendaq_prepend_include(${TARGET_FOLDER_NAME} SRC_Include) source_group(module FILES ../include/${TARGET_FOLDER_NAME}/ws_streaming_server_module.h @@ -25,12 +25,16 @@ source_group(module FILES ) add_library(${LIB_NAME} SHARED ${SRC_Include} ${SRC_Srcs}) -add_library(${SDK_TARGET_NAMESPACE}::${LIB_NAME} ALIAS ${LIB_NAME}) +add_library(${OPENDAQ_SDK_TARGET_NAMESPACE}::${LIB_NAME} ALIAS ${LIB_NAME}) if (MSVC) target_compile_options(${LIB_NAME} PRIVATE /bigobj) endif() +if (MINGW) + target_link_libraries(${LIB_NAME} PRIVATE ws2_32 wsock32) +endif() + target_link_libraries(${LIB_NAME} PUBLIC daq::opendaq @@ -48,4 +52,4 @@ target_include_directories(${LIB_NAME} opendaq_set_module_properties(${LIB_NAME} ${PROJECT_VERSION_MAJOR}) -create_version_header(${LIB_NAME}) +opendaq_create_version_header(${LIB_NAME}) diff --git a/modules/websocket_streaming_server_module/tests/CMakeLists.txt b/modules/websocket_streaming_server_module/tests/CMakeLists.txt index 02df280..50edcd5 100644 --- a/modules/websocket_streaming_server_module/tests/CMakeLists.txt +++ b/modules/websocket_streaming_server_module/tests/CMakeLists.txt @@ -8,21 +8,11 @@ set(TEST_SOURCES test_websocket_streaming_server_module.cpp add_executable(${TEST_APP} ${TEST_SOURCES} ) -target_link_libraries(${TEST_APP} PRIVATE daq::test_utils - daq::opendaq_mocks - ${SDK_TARGET_NAMESPACE}::${MODULE_NAME} - Taskflow::Taskflow +target_link_libraries(${TEST_APP} PRIVATE daq::opendaq_test_utils gtest + ${OPENDAQ_SDK_TARGET_NAMESPACE}::${MODULE_NAME} ) add_test(NAME ${TEST_APP} COMMAND $ WORKING_DIRECTORY $ ) - -if (MSVC) # Ignoring warning for the Taskflow - target_compile_options(${TEST_APP} PRIVATE /wd4324) -endif() - -if (OPENDAQ_ENABLE_COVERAGE) - setup_target_for_coverage(${TEST_APP}coverage ${TEST_APP} ${TEST_APP}coverage) -endif() diff --git a/modules/websocket_streaming_server_module/tests/test_app.cpp b/modules/websocket_streaming_server_module/tests/test_app.cpp index 64dd0cc..29a34d8 100644 --- a/modules/websocket_streaming_server_module/tests/test_app.cpp +++ b/modules/websocket_streaming_server_module/tests/test_app.cpp @@ -1,16 +1,9 @@ -#include -#include -#include #include -#include +#include #include int main(int argc, char** args) { - daq::daqInitializeCoreObjectsTesting(); - daqInitModuleManagerLibrary(); - daqInitOpenDaqLibrary(); - testing::InitGoogleTest(&argc, args); testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); diff --git a/modules/websocket_streaming_server_module/tests/test_websocket_streaming_server_module.cpp b/modules/websocket_streaming_server_module/tests/test_websocket_streaming_server_module.cpp index 16c0038..ce3cbd4 100644 --- a/modules/websocket_streaming_server_module/tests/test_websocket_streaming_server_module.cpp +++ b/modules/websocket_streaming_server_module/tests/test_websocket_streaming_server_module.cpp @@ -7,11 +7,7 @@ #include #include #include -#include #include -#include -#include -#include class WsStreamingServerModuleTest : public testing::Test { diff --git a/shared/CMakeLists.txt b/shared/CMakeLists.txt new file mode 100644 index 0000000..704326b --- /dev/null +++ b/shared/CMakeLists.txt @@ -0,0 +1,17 @@ +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME) + +if (MSVC) + add_compile_options(/wd4100) + + # loss of data / precision, unsigned <--> signed + # + # 'argument' : conversion from 'type1' to 'type2', possible loss of data + # https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4244 + add_compile_options(/wd4244) + + # 'var' : conversion from 'size_t' to 'type', possible loss of data + # https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4267 + add_compile_options(/wd4267) +endif() + +add_subdirectory(libraries) diff --git a/shared/libraries/CMakeLists.txt b/shared/libraries/CMakeLists.txt new file mode 100644 index 0000000..1492fab --- /dev/null +++ b/shared/libraries/CMakeLists.txt @@ -0,0 +1,3 @@ +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME) + +add_subdirectory(websocket_streaming) diff --git a/shared/libraries/websocket_streaming/CMakeLists.txt b/shared/libraries/websocket_streaming/CMakeLists.txt index a89b800..4296bad 100644 --- a/shared/libraries/websocket_streaming/CMakeLists.txt +++ b/shared/libraries/websocket_streaming/CMakeLists.txt @@ -1,12 +1,8 @@ cmake_minimum_required(VERSION 3.10) -set_cmake_folder_context(TARGET_FOLDER_NAME ${SDK_TARGET_NAMESPACE}_websocket_streaming) +opendaq_set_cmake_folder_context(TARGET_FOLDER_NAME ${OPENDAQ_SDK_TARGET_NAMESPACE}_websocket_streaming) project(OpenDaqStreaming VERSION 4.0.0 LANGUAGES CXX ) add_subdirectory(src) - -if (OPENDAQ_ENABLE_TESTS) - add_subdirectory(tests) -endif() diff --git a/shared/libraries/websocket_streaming/include/websocket_streaming/ws_streaming_device.h b/shared/libraries/websocket_streaming/include/websocket_streaming/ws_streaming_device.h index dda1e0d..05db676 100644 --- a/shared/libraries/websocket_streaming/include/websocket_streaming/ws_streaming_device.h +++ b/shared/libraries/websocket_streaming/include/websocket_streaming/ws_streaming_device.h @@ -77,7 +77,8 @@ class WsStreamingDevice : public Device const ContextPtr& context, const ComponentPtr& parent, const StringPtr& localId, - const StringPtr& connectionString); + const StringPtr& connectionString, + const DeviceTypePtr& type); protected: @@ -96,6 +97,7 @@ class WsStreamingDevice : public Device wss::remote_signal_ptr signal); StringPtr connectionString; + DeviceTypePtr deviceType; StreamingPtr streaming; std::list streamingEvents; diff --git a/shared/libraries/websocket_streaming/src/CMakeLists.txt b/shared/libraries/websocket_streaming/src/CMakeLists.txt index a1491a9..5440df0 100644 --- a/shared/libraries/websocket_streaming/src/CMakeLists.txt +++ b/shared/libraries/websocket_streaming/src/CMakeLists.txt @@ -1,6 +1,6 @@ set(BASE_NAME websocket_streaming) -set(LIB_NAME ${SDK_TARGET_NAME}_${BASE_NAME}) +set(LIB_NAME ${OPENDAQ_SDK_TARGET_NAME}_${BASE_NAME}) set(SRC_Cpp descriptor_to_metadata.cpp @@ -27,10 +27,10 @@ set(SRC_PublicHeaders ) set(INCLUDE_DIR ../include/websocket_streaming) -prepend_include(${INCLUDE_DIR} SRC_PublicHeaders) +opendaq_prepend_include(${INCLUDE_DIR} SRC_PublicHeaders) add_library(${LIB_NAME} STATIC ${SRC_Cpp} ${SRC_PublicHeaders}) -add_library(${SDK_TARGET_NAMESPACE}::${BASE_NAME} ALIAS ${LIB_NAME}) +add_library(${OPENDAQ_SDK_TARGET_NAMESPACE}::${BASE_NAME} ALIAS ${LIB_NAME}) if(BUILD_64Bit OR BUILD_ARM) set_target_properties(${LIB_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/shared/libraries/websocket_streaming/src/ws_streaming_device.cpp b/shared/libraries/websocket_streaming/src/ws_streaming_device.cpp index 6d6a6a8..ef5060c 100644 --- a/shared/libraries/websocket_streaming/src/ws_streaming_device.cpp +++ b/shared/libraries/websocket_streaming/src/ws_streaming_device.cpp @@ -54,9 +54,11 @@ WsStreamingDevice::WsStreamingDevice( const ContextPtr& context, const ComponentPtr& parent, const StringPtr& localId, - const StringPtr& connectionString) + const StringPtr& connectionString, + const DeviceTypePtr& type) : Device(context, parent, localId) , connectionString(connectionString) + , deviceType(type) { if (!connectionString.assigned()) DAQ_THROW_EXCEPTION(ArgumentNullException, "connectionString cannot be null"); @@ -89,7 +91,9 @@ void WsStreamingDevice::removed() DeviceInfoPtr WsStreamingDevice::onGetInfo() { - return DeviceInfo(connectionString, "WebsocketClientPseudoDevice"); + auto info = DeviceInfo(connectionString, "WebsocketClientPseudoDevice"); + info.setDeviceType(deviceType); + return info; } void WsStreamingDevice::onSignalAvailable( diff --git a/shared/libraries/websocket_streaming/tests/CMakeLists.txt b/shared/libraries/websocket_streaming/tests/CMakeLists.txt deleted file mode 100644 index e0c18fa..0000000 --- a/shared/libraries/websocket_streaming/tests/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set(MODULE_NAME websocket_streaming) -set(TEST_APP test_${MODULE_NAME}) - -add_executable(${TEST_APP} - test_signal_generator.cpp - test_app.cpp -) - -if (MSVC) - target_compile_options(${TEST_APP} PRIVATE /bigobj) -endif() - -target_link_libraries(${TEST_APP} PRIVATE - ${SDK_TARGET_NAMESPACE}::${MODULE_NAME} - daq::opendaq - daq::opendaq_mocks - ${SDK_TARGET_NAMESPACE}::test_utils -) - -set_target_properties(${TEST_APP} PROPERTIES DEBUG_POSTFIX _debug) -target_include_directories(${TEST_APP} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") - -add_test(NAME ${TEST_APP} - COMMAND $ - WORKING_DIRECTORY $ -) - -if(OPENDAQ_ENABLE_COVERAGE) - setup_target_for_coverage(${MODULE_NAME}coverage ${TEST_APP} ${MODULE_NAME}coverage) -endif() diff --git a/shared/libraries/websocket_streaming/tests/test_app.cpp b/shared/libraries/websocket_streaming/tests/test_app.cpp deleted file mode 100644 index 608cd21..0000000 --- a/shared/libraries/websocket_streaming/tests/test_app.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -int main(int argc, char** args) -{ - testing::InitGoogleTest(&argc, args); - - testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); - listeners.Append(new BaseTestListener()); - - return RUN_ALL_TESTS(); -} diff --git a/shared/libraries/websocket_streaming/tests/test_signal_generator.cpp b/shared/libraries/websocket_streaming/tests/test_signal_generator.cpp deleted file mode 100644 index c0f6194..0000000 --- a/shared/libraries/websocket_streaming/tests/test_signal_generator.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -using namespace daq; - -class SignalGeneratorTest : public testing::Test -{ -public: - ContextPtr context; - SignalConfigPtr signal; - SignalGenerator::GenerateSampleFunc stepFunction10; - SignalGenerator::GenerateSampleFunc stepFunction100; - - void SetUp() override - { - context = NullContext(); - signal = createSignal(); - initFunctions(); - } - - void initFunctions() - { - stepFunction10 = [](uint64_t tick, void* sampleOut) - { - int* intOut = (int*) sampleOut; - *intOut = tick % 10; - }; - - stepFunction100 = [](uint64_t tick, void* sampleOut) - { - int* intOut = (int*) sampleOut; - *intOut = tick % 100; - }; - } - - std::vector calculateExpectedSamples(uint64_t startTick, size_t sampleCount, const SignalGenerator::GenerateSampleFunc& function) - { - auto samples = std::vector(sampleCount); - - for (size_t i = 0; i < sampleCount; i++) - function(startTick + i, samples.data() + i); - - return samples; - } - - bool compareSamples(int* expected, void* packetData, size_t sampleCount) - { - return std::memcmp(expected, packetData, sampleCount * sizeof(int)) == 0; - } - -private: - SignalConfigPtr createTimeSignal() - { - const size_t nanosecondsInSecond = 1000000000; - auto delta = nanosecondsInSecond / 1000; - - auto descriptor = DataDescriptorBuilder() - .setSampleType(SampleType::UInt64) - .setRule(LinearDataRule(delta, 0)) - .setTickResolution(Ratio(1, nanosecondsInSecond)) - .setOrigin("1970-01-01T00:00:00") - .setName("Time") - .build(); - - return SignalWithDescriptor(context, descriptor, nullptr, "Time"); - } - - SignalConfigPtr createSignal() - { - auto descriptor = DataDescriptorBuilder().setSampleType(SampleType::Int32).setName("Step").build(); - - auto domainSignal = createTimeSignal(); - auto signal = SignalWithDescriptor(context, descriptor, nullptr, "ByteStep"); - signal.setDomainSignal(domainSignal); - return signal; - } -}; - - -TEST_F(SignalGeneratorTest, CreateSignal) -{ - auto reader = PacketReader(signal); - auto packets = reader.readAll(); - ASSERT_EQ(packets.getCount(), 1u); - ASSERT_EQ(packets[0].getType(), PacketType::Event); - - EventPacketPtr eventPacket = packets[0]; - ASSERT_EQ(eventPacket.getEventId(), event_packet_id::DATA_DESCRIPTOR_CHANGED); -} - -TEST_F(SignalGeneratorTest, StepSignal) -{ - const size_t packetSize = 100; - - auto expectedSamples1 = calculateExpectedSamples(0, packetSize, stepFunction10); - auto expectedSamples2 = calculateExpectedSamples(packetSize, packetSize, stepFunction10); - - auto reader = PacketReader(signal); - - auto generator = SignalGenerator(signal, std::chrono::system_clock::now()); - generator.setFunction(stepFunction10); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize)); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize * 2)); - - auto packets = reader.readAll(); - ASSERT_EQ(packets.getCount(), 3u); - - auto packet1 = packets[1].asPtr(); - ASSERT_EQ(packet1.getSampleCount(), packetSize); - ASSERT_TRUE(compareSamples(expectedSamples1.data(), packet1.getData(), packetSize)); - - auto packet2 = packets[2].asPtr(); - ASSERT_EQ(packet2.getSampleCount(), packetSize); - ASSERT_TRUE(compareSamples(expectedSamples2.data(), packet2.getData(), packetSize)); -} - -TEST_F(SignalGeneratorTest, ChangeFunction) -{ - const size_t packetSize = 100; - - auto expectedSamples1 = calculateExpectedSamples(0, packetSize, stepFunction10); - auto expectedSamples2 = calculateExpectedSamples(packetSize, packetSize, stepFunction100); - - auto reader = PacketReader(signal); - - auto updateFunction = [this](SignalGenerator& generator, uint64_t packetOffset) - { - if (packetOffset > 0) - generator.setFunction(stepFunction100); - }; - - auto generator = SignalGenerator(signal, std::chrono::system_clock::now()); - generator.setFunction(stepFunction10); - generator.setUpdateFunction(updateFunction); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize)); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize * 2)); - - auto packets = reader.readAll(); - ASSERT_EQ(packets.getCount(), 3u); - - auto packet1 = packets[1].asPtr(); - ASSERT_EQ(packet1.getSampleCount(), packetSize); - ASSERT_TRUE(compareSamples(expectedSamples1.data(), packet1.getData(), packetSize)); - - auto packet2 = packets[2].asPtr(); - ASSERT_EQ(packet2.getSampleCount(), packetSize); - ASSERT_TRUE(compareSamples(expectedSamples2.data(), packet2.getData(), packetSize)); -} - -TEST_F(SignalGeneratorTest, SignalGeneratorCountCheck) -{ - const size_t packetSize= 100; - auto expectedSamples1 = calculateExpectedSamples(0, packetSize, stepFunction10); - - auto reader = PacketReader(signal); - - auto generator = SignalGenerator(signal, std::chrono::system_clock::now()); - generator.setFunction(stepFunction10); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize)); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize * 2)); - generator.generateSamplesTo(std::chrono::milliseconds(packetSize * 3)); - - auto packets = reader.readAll(); - ASSERT_EQ(packets.getCount(), 4u); - auto packet1 = packets[1].asPtr(); - ASSERT_EQ(packet1.getSampleCount(), packetSize); - auto packet2 = packets[2].asPtr(); - ASSERT_EQ(packet2.getSampleCount(), packetSize); -}