mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-02-05 15:18:45 +00:00
84
tests/CMakeLists.txt
Normal file
84
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
# Define project
|
||||
project(Tests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Enable testing for all subsequent projects
|
||||
enable_testing()
|
||||
|
||||
# Re-set target directories
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/tests/lib>)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/tests/bin>)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/tests/bin>)
|
||||
|
||||
# Include export into the include directory path
|
||||
include_directories(../export)
|
||||
|
||||
# Get Google Test from github
|
||||
include(FetchContent)
|
||||
# Fetch the Google Test library from GitHub.
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG v1.17.0
|
||||
)
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
add_library(GTest::GTest INTERFACE IMPORTED)
|
||||
add_library(GMock::GMock INTERFACE IMPORTED)
|
||||
target_link_libraries(GTest::GTest INTERFACE gtest_main)
|
||||
target_link_libraries(GMock::GMock INTERFACE gmock_main)
|
||||
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/sdv_core_reloc.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/sdv_core_reloc.toml DESTINATION ${CMAKE_BINARY_DIR}/examples/bin/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/sdv_core_reloc.toml DESTINATION ${CMAKE_BINARY_DIR}/framework_tests/bin/)
|
||||
|
||||
# Copy shell script to the build directory
|
||||
if(WIN32)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/run_tests_on_windows.ps1 DESTINATION ${CMAKE_BINARY_DIR}/tests/)
|
||||
else()
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/run_tests_on_linux.sh DESTINATION ${CMAKE_BINARY_DIR}/tests/)
|
||||
endif()
|
||||
|
||||
# Add test projects
|
||||
add_subdirectory(unit_tests/concurrency)
|
||||
add_subdirectory(unit_tests/flags_type)
|
||||
add_subdirectory(unit_tests/scheduler)
|
||||
add_subdirectory(unit_tests/idl_compiler)
|
||||
add_subdirectory(unit_tests/commandline_parser)
|
||||
add_subdirectory(unit_tests/dbc_parser)
|
||||
add_subdirectory(unit_tests/asc_format)
|
||||
add_subdirectory(unit_tests/basic_types)
|
||||
add_subdirectory(unit_tests/smart_ifc)
|
||||
add_subdirectory(unit_tests/toml_parser)
|
||||
add_subdirectory(unit_tests/module_control)
|
||||
add_subdirectory(unit_tests/repository)
|
||||
# add_subdirectory(unit_tests/shared_mem)
|
||||
add_subdirectory(unit_tests/memory_manager)
|
||||
add_subdirectory(unit_tests/core_loader)
|
||||
add_subdirectory(unit_tests/named_mutex)
|
||||
add_subdirectory(unit_tests/trace_fifo)
|
||||
add_subdirectory(unit_tests/socket_can_com_tests)
|
||||
add_subdirectory(unit_tests/app_connect)
|
||||
add_subdirectory(unit_tests/process_control)
|
||||
add_subdirectory(unit_tests/ipc_com)
|
||||
add_subdirectory(unit_tests/ipc_connect)
|
||||
add_subdirectory(unit_tests/sdv_control)
|
||||
add_subdirectory(unit_tests/sdv_macro_test)
|
||||
add_subdirectory(unit_tests/install_package_composer)
|
||||
add_subdirectory(unit_tests/path_match)
|
||||
add_subdirectory(component_tests/logger)
|
||||
add_subdirectory(component_tests/data_dispatch_service)
|
||||
add_subdirectory(component_tests/repository)
|
||||
add_subdirectory(component_tests/config_install)
|
||||
add_subdirectory(component_tests/dbc_util)
|
||||
add_subdirectory(component_tests/vss_util)
|
||||
add_subdirectory(component_tests/task_timer)
|
||||
add_subdirectory(component_tests/core_library)
|
||||
add_subdirectory(component_tests/config)
|
||||
add_subdirectory(manual_tests/silkit_can_com_tests)
|
||||
91
tests/README.md
Normal file
91
tests/README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Running tests
|
||||
|
||||
When the project is build the tests are executed with warning level.
|
||||
To run the test without warning level aou have to execute the test locally by executing the script files:
|
||||
|
||||
**On Windows PowerShell:** run_tests_on_windows.ps1
|
||||
or
|
||||
**On Linux:** run_tests_on_linux.sh
|
||||
|
||||
|
||||
|
||||
# SDV TEST MACRO
|
||||
## Overview
|
||||
There is set of macros in "export/support/sdv_test_macro.h" which are designed to extend the Google Test (GTEST) framework by incorporating a warning level mechanism. These macros allow developers to specify a warning level for each test assertion, providing more control over test outcomes and enabling better handling of test result conditions based on their warning level.
|
||||
|
||||
## Purpose
|
||||
The primary purpose of these macros is to enhance the flexibility and robustness of test assertions in the GTEST framework. By integrating a warning level, developers can decide whether to report failed tests as warning or error and handle them accordingly. This is particularly useful in where different test failures may have varying impacts on the overall build system.
|
||||
|
||||
## Macros
|
||||
### Equality Assertions:
|
||||
These macros check for equality or inequality between two values. The level parameter specifies the warning level to be handled by the HANDLE_WARNING_LEVEL function.
|
||||
- SDV_EXPECT_EQ(val1, val2, level)
|
||||
- SDV_ASSERT_EQ(val1, val2, level)
|
||||
- SDV_EXPECT_NE(val1, val2, level)
|
||||
- SDV_ASSERT_NE(val1, val2, level)
|
||||
|
||||
### Boolean Assertions:
|
||||
These macros check if a condition is true or false. The level parameter specifies the warning level to be handled by the HANDLE_WARNING_LEVEL function.
|
||||
- SDV_EXPECT_TRUE(condition, level)
|
||||
- SDV_ASSERT_TRUE(condition, level)
|
||||
- SDV_EXPECT_FALSE(condition, level)
|
||||
- SDV_ASSERT_FALSE(condition, level)
|
||||
|
||||
### Relational Assertions:
|
||||
These macros check for relational conditions (less than, less than or equal to, greater than, greater than or equal to) between two values. The level parameter specifies the warning level to be handled by the HANDLE_WARNING_LEVEL function.
|
||||
- SDV_EXPECT_LT(val1, val2, level)
|
||||
- SDV_ASSERT_LT(val1, val2, level)
|
||||
- SDV_EXPECT_LE(val1, val2, level)
|
||||
- SDV_ASSERT_LE(val1, val2, level)
|
||||
- SDV_EXPECT_GT(val1, val2, level)
|
||||
- SDV_ASSERT_GT(val1, val2, level)
|
||||
- SDV_EXPECT_GE(val1, val2, level)
|
||||
- SDV_ASSERT_GE(val1, val2, level)
|
||||
|
||||
### String Assertions:
|
||||
These macros check for string equality or inequality, both case-sensitive and case-insensitive. The level parameter specifies the warning level to be handled by the HANDLE_WARNING_LEVEL function.
|
||||
- SDV_EXPECT_STREQ(str1, str2, level)
|
||||
- SDV_ASSERT_STREQ(str1, str2, level)
|
||||
- SDV_EXPECT_STRNE(str1, str2, level)
|
||||
- SDV_ASSERT_STRNE(str1, str2, level)
|
||||
- SDV_EXPECT_STRCASEEQ(str1, str2, level)
|
||||
- SDV_ASSERT_STRCASEEQ(str1, str2, level)
|
||||
- SDV_EXPECT_STRCASENE(str1, str2, level)
|
||||
- SDV_ASSERT_STRCASENE(str1, str2, level)
|
||||
|
||||
## Warning Levels
|
||||
The WarningLevel enum defines three levels of warnings:
|
||||
- WARNING_ENABLED: With this warning level, failed tests are reported as errors, as is standard in GTEST.
|
||||
- WARNING_REDUCED: With warning this level, failed tests are reported as warnings.
|
||||
- WARNING_DISABLED: With this warning level, no action is implemented at this moment.
|
||||
|
||||
Additionally SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD is implemented to check if tests are running with CMake build or any other way. It returns true if they are running with CMake build.
|
||||
|
||||
## Usage
|
||||
To use these macros, include the header file '#include <support/sdv_test_macro.h>" in your test files. When writing test cases, use the SDV macros instead of the standard GTEST macros, and specify the appropriate warning level for each assertion.
|
||||
|
||||
```cpp
|
||||
#include <support/sdv_test_macro.h>
|
||||
|
||||
TEST(SDVTestMacros, TestExpectEq)
|
||||
{
|
||||
int val1 = 5;
|
||||
int val2 = 5;
|
||||
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
|
||||
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_REDUCED);
|
||||
else
|
||||
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_ENABLED);
|
||||
}
|
||||
|
||||
TEST(SDVTestMacros, TestExpectStreq)
|
||||
{
|
||||
std::string str1 = "test";
|
||||
std::string str2 = "test";
|
||||
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
|
||||
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_REDUCED);
|
||||
else
|
||||
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_ENABLED);
|
||||
}
|
||||
```
|
||||
In this example, the SDV_EXPECT_EQ macro checks if val1 and val2 are equal, while the SDV_EXPECT_STREQ macro checks if str1 and str2 are equal. In both test cases, it is checked whether it is running
|
||||
with the Cmake build. If it is running with the CMake build then report test failures as warning, otherwise report normally as GTEST does.
|
||||
19
tests/component_tests/config/CMakeLists.txt
Normal file
19
tests/component_tests/config/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
# Define project
|
||||
project(ConfigTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Define target
|
||||
add_executable(ComponentTest_Config config_tests.cpp)
|
||||
|
||||
target_link_libraries(ComponentTest_Config ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the test
|
||||
add_test(NAME ComponentTest_Config COMMAND ComponentTest_Config WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_Config POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_Config>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_Config.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_Config dependency_sdv_components)
|
||||
960
tests/component_tests/config/config_tests.cpp
Normal file
960
tests/component_tests/config/config_tests.cpp
Normal file
@@ -0,0 +1,960 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/toml.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4566)
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(Config, Instantiate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config;
|
||||
EXPECT_TRUE(config.Process(""));
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, Table)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
[newTable]
|
||||
[secondTable.nestedTable]
|
||||
)");
|
||||
EXPECT_TRUE(config.IsValid());
|
||||
|
||||
auto table1 = config.GetDirect("newTable");
|
||||
EXPECT_TRUE(table1);
|
||||
EXPECT_EQ(table1.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_EQ(table1.GetName(), "newTable");
|
||||
EXPECT_EQ(table1.GetValue(), sdv::any_t());
|
||||
sdv::toml::CNodeCollection collection = table1;
|
||||
EXPECT_TRUE(collection);
|
||||
|
||||
sdv::toml::CNodeCollection table2 = config.GetDirect("secondTable");
|
||||
EXPECT_TRUE(table2);
|
||||
EXPECT_EQ(table2.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_EQ(table2.GetName(), "secondTable");
|
||||
EXPECT_EQ(table2.GetValue(), sdv::any_t());
|
||||
|
||||
sdv::toml::CNodeCollection table3 = config.GetDirect("secondTable.nestedTable");
|
||||
EXPECT_TRUE(table3);
|
||||
EXPECT_EQ(table3.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_EQ(table3.GetName(), "nestedTable");
|
||||
EXPECT_EQ(table3.GetValue(), sdv::any_t());
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, Key_Value)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
name = "Hammer"
|
||||
id = 42
|
||||
pi = 3.1415926
|
||||
boolean = true
|
||||
array = []
|
||||
table = {}
|
||||
)");
|
||||
|
||||
|
||||
auto value_name = config.GetDirect("name");
|
||||
EXPECT_EQ(value_name.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(value_name.GetValue(), sdv::any_t("Hammer"));
|
||||
|
||||
auto value_id = config.GetDirect("id");
|
||||
EXPECT_EQ(value_id.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(value_id.GetValue(), 42);
|
||||
|
||||
auto value_pi = config.GetDirect("pi");
|
||||
EXPECT_EQ(value_pi.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(value_pi.GetValue(), 3.1415926);
|
||||
|
||||
auto value_boolean = config.GetDirect("boolean");
|
||||
EXPECT_EQ(value_boolean.GetType(), sdv::toml::ENodeType::node_boolean);
|
||||
EXPECT_EQ(value_boolean.GetValue(), true);
|
||||
|
||||
auto value_array = config.GetDirect("array");
|
||||
EXPECT_EQ(value_array.GetType(), sdv::toml::ENodeType::node_array);
|
||||
EXPECT_EQ(value_array.GetValue(), sdv::any_t());
|
||||
|
||||
auto value_table = config.GetDirect("table");
|
||||
EXPECT_EQ(value_table.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_EQ(value_table.GetValue(), sdv::any_t());
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, TableArray)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
[[newTableArray]]
|
||||
[[newTableArray]]
|
||||
[[table.nestedTableArray]]
|
||||
)");
|
||||
|
||||
sdv::toml::CNodeCollection tableArray1 = config.GetDirect("newTableArray");
|
||||
EXPECT_EQ(tableArray1.GetType(), sdv::toml::ENodeType::node_array);
|
||||
EXPECT_TRUE(tableArray1);
|
||||
EXPECT_EQ(tableArray1.GetName(), "newTableArray");
|
||||
EXPECT_EQ(tableArray1.GetCount(), 2u);
|
||||
auto tableNode0 = tableArray1[0];
|
||||
EXPECT_TRUE(tableNode0);
|
||||
auto tableNode0b = tableArray1.Get(0);
|
||||
EXPECT_TRUE(tableNode0b);
|
||||
auto tableNode1 = tableArray1[1];
|
||||
EXPECT_TRUE(tableNode1);
|
||||
auto tableNode1b = tableArray1.Get(1);
|
||||
EXPECT_TRUE(tableNode1b);
|
||||
EXPECT_FALSE(tableArray1[2]);
|
||||
EXPECT_FALSE(tableArray1.Get(2));
|
||||
|
||||
auto table1 = config.GetDirect("newTableArray[0]");
|
||||
EXPECT_EQ(table1.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_TRUE(table1.GetName().empty());
|
||||
|
||||
auto table2 = config.GetDirect("newTableArray[1]");
|
||||
EXPECT_EQ(table2.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_TRUE(table2.GetName().empty());
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(NestedContent, Array)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
arr_mixed = [ 1.0, 2, "test string", [ 1, 2, ], { pi = 3.14, e = 2.71828 }, true]
|
||||
arr_ints = [ 1, 2, 3, 4]
|
||||
arr_ints_trailing_comma = [ 1, 2, 3, 4, ]
|
||||
arr_multiline = [
|
||||
"first line",
|
||||
"second line",
|
||||
"third_line",
|
||||
]
|
||||
)");
|
||||
|
||||
{
|
||||
|
||||
sdv::toml::CNodeCollection array_ints = config.GetDirect("arr_ints");
|
||||
EXPECT_EQ(array_ints.GetType(), sdv::toml::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_ints);
|
||||
EXPECT_EQ(array_ints.GetCount(), 4u);
|
||||
EXPECT_TRUE(array_ints[0]);
|
||||
EXPECT_TRUE(array_ints[1]);
|
||||
EXPECT_TRUE(array_ints[2]);
|
||||
EXPECT_TRUE(array_ints[3]);
|
||||
EXPECT_FALSE(array_ints[4]);
|
||||
auto array_ints_0 = config.GetDirect("arr_ints[0]");
|
||||
ASSERT_TRUE(array_ints_0);
|
||||
EXPECT_EQ(array_ints_0.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_0.GetValue(), 1);
|
||||
auto array_ints_1 = config.GetDirect("arr_ints[1]");
|
||||
ASSERT_TRUE(array_ints_1);
|
||||
EXPECT_EQ(array_ints_1.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_1.GetValue(), 2);
|
||||
auto array_ints_2 = config.GetDirect("arr_ints[2]");
|
||||
ASSERT_TRUE(array_ints_2);
|
||||
EXPECT_EQ(array_ints_2.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_2.GetValue(), 3);
|
||||
auto array_ints_3 = config.GetDirect("arr_ints[3]");
|
||||
ASSERT_TRUE(array_ints_3);
|
||||
EXPECT_EQ(array_ints_3.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_3.GetValue(), 4);
|
||||
auto array_ints_4 = config.GetDirect("arr_ints[4]");
|
||||
EXPECT_FALSE(array_ints_4);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_ints_trailing_comma = config.GetDirect("arr_ints_trailing_comma");
|
||||
auto array_ints_trailing_comma_0 = config.GetDirect("arr_ints_trailing_comma[0]");
|
||||
auto array_ints_trailing_comma_1 = config.GetDirect("arr_ints_trailing_comma[1]");
|
||||
auto array_ints_trailing_comma_2 = config.GetDirect("arr_ints_trailing_comma[2]");
|
||||
auto array_ints_trailing_comma_3 = config.GetDirect("arr_ints_trailing_comma[3]");
|
||||
auto array_ints_trailing_comma_4 = config.GetDirect("arr_ints_trailing_comma[4]");
|
||||
|
||||
EXPECT_EQ(array_ints_trailing_comma.GetType(), sdv::toml::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_0);
|
||||
EXPECT_EQ(array_ints_trailing_comma_0.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_trailing_comma_0.GetValue(), 1);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_1);
|
||||
EXPECT_EQ(array_ints_trailing_comma_1.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_trailing_comma_1.GetValue(), 2);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_2);
|
||||
EXPECT_EQ(array_ints_trailing_comma_2.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_trailing_comma_2.GetValue(), 3);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_3);
|
||||
EXPECT_EQ(array_ints_trailing_comma_3.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_ints_trailing_comma_3.GetValue(), 4);
|
||||
EXPECT_FALSE(array_ints_trailing_comma_4);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_mixed = config.GetDirect("arr_mixed");
|
||||
auto array_mixed_0 = config.GetDirect("arr_mixed[0]");
|
||||
auto array_mixed_1 = config.GetDirect("arr_mixed[1]");
|
||||
auto array_mixed_2 = config.GetDirect("arr_mixed[2]");
|
||||
auto array_mixed_3 = config.GetDirect("arr_mixed[3]");
|
||||
auto array_mixed_3_2 = config.GetDirect("arr_mixed[3][1]");
|
||||
auto array_mixed_4 = config.GetDirect("arr_mixed[4]");
|
||||
auto array_mixed_4_pi = config.GetDirect("arr_mixed[4].pi");
|
||||
auto array_mixed_5 = config.GetDirect("arr_mixed[5]");
|
||||
auto array_mixed_6 = config.GetDirect("arr_mixed[6]");
|
||||
|
||||
EXPECT_EQ(array_mixed.GetType(), sdv::toml::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_mixed_0);
|
||||
EXPECT_EQ(array_mixed_0.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(array_mixed_0.GetValue(), 1.0);
|
||||
ASSERT_TRUE(array_mixed_1);
|
||||
EXPECT_EQ(array_mixed_1.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_mixed_1.GetValue(), 2);
|
||||
ASSERT_TRUE(array_mixed_2);
|
||||
EXPECT_EQ(array_mixed_2.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(array_mixed_2.GetValue()), "test string");
|
||||
ASSERT_TRUE(array_mixed_3);
|
||||
EXPECT_EQ(array_mixed_3.GetType(), sdv::toml::ENodeType::node_array);
|
||||
EXPECT_EQ(array_mixed_3_2.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(array_mixed_3_2.GetValue(), 2);
|
||||
ASSERT_TRUE(array_mixed_4);
|
||||
EXPECT_EQ(array_mixed_4.GetType(), sdv::toml::ENodeType::node_table);
|
||||
EXPECT_EQ(array_mixed_4_pi.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(array_mixed_4_pi.GetValue(), 3.14);
|
||||
ASSERT_TRUE(array_mixed_5);
|
||||
EXPECT_EQ(array_mixed_5.GetType(), sdv::toml::ENodeType::node_boolean);
|
||||
EXPECT_EQ(array_mixed_5.GetValue(), true);
|
||||
EXPECT_EQ(array_mixed_5.GetValue(), sdv::any_t());
|
||||
EXPECT_FALSE(array_mixed_6);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_multiline = config.GetDirect("arr_multiline");
|
||||
auto array_multiline_0 = config.GetDirect("arr_multiline[0]");
|
||||
auto array_multiline_1 = config.GetDirect("arr_multiline[1]");
|
||||
auto array_multiline_2 = config.GetDirect("arr_multiline[2]");
|
||||
auto array_multiline_3 = config.GetDirect("arr_multiline[3]");
|
||||
|
||||
EXPECT_EQ(array_multiline.GetType(), sdv::toml::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_multiline_0);
|
||||
EXPECT_EQ(array_multiline_0.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(array_multiline_0.GetValue()), "first line");
|
||||
ASSERT_TRUE(array_multiline_1);
|
||||
EXPECT_EQ(array_multiline_1.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(array_multiline_1.GetValue()), "second line");
|
||||
ASSERT_TRUE(array_multiline_2);
|
||||
EXPECT_EQ(array_multiline_2.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(array_multiline_2.GetValue()), "third_line");
|
||||
EXPECT_FALSE(array_multiline_3);
|
||||
}
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(NestedContent, Table)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
[table]
|
||||
a = 2
|
||||
b = 1.2
|
||||
[anotherTable]
|
||||
a = 4
|
||||
c = false
|
||||
[thirdTable.fourthTable]
|
||||
a = "five"
|
||||
d = []
|
||||
)");
|
||||
|
||||
auto table_a = config.GetDirect("table.a");
|
||||
auto table_b = config.GetDirect("table.b");
|
||||
auto anotherTable_a = config.GetDirect("anotherTable.a");
|
||||
auto anotherTable_c = config.GetDirect("anotherTable.c");
|
||||
auto fourthTable_a = config.GetDirect("thirdTable.fourthTable.a");
|
||||
auto fourthTable_d = config.GetDirect("thirdTable.fourthTable.d");
|
||||
|
||||
ASSERT_TRUE(table_a);
|
||||
EXPECT_EQ(table_a.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(table_a.GetValue(), 2);
|
||||
ASSERT_TRUE(table_b);
|
||||
EXPECT_EQ(table_b.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(table_b.GetValue(), 1.2);
|
||||
ASSERT_TRUE(anotherTable_a);
|
||||
EXPECT_EQ(anotherTable_a.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(anotherTable_a.GetValue(), 4);
|
||||
ASSERT_TRUE(anotherTable_c);
|
||||
EXPECT_EQ(anotherTable_c.GetType(), sdv::toml::ENodeType::node_boolean);
|
||||
EXPECT_EQ(anotherTable_c.GetValue(), false);
|
||||
ASSERT_TRUE(fourthTable_a);
|
||||
EXPECT_EQ(fourthTable_a.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(fourthTable_a.GetValue()), "five");
|
||||
ASSERT_TRUE(fourthTable_d);
|
||||
EXPECT_EQ(fourthTable_d.GetType(), sdv::toml::ENodeType::node_array);
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(NestedContent, TableArray)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
[[table.test]]
|
||||
a = 2
|
||||
b = 1.2
|
||||
[[table.test]]
|
||||
a = 4
|
||||
c = false
|
||||
[[table.test]]
|
||||
a = "five"
|
||||
d = []
|
||||
)");
|
||||
|
||||
auto table_test_1_a = config.GetDirect("table.test[0].a");
|
||||
auto table_test_1_b = config.GetDirect("table.test[0].b");
|
||||
auto table_test_2_a = config.GetDirect("table.test[1].a");
|
||||
auto table_test_2_c = config.GetDirect("table.test[1].c");
|
||||
auto table_test_3_a = config.GetDirect("table.test[2].a");
|
||||
auto table_test_3_d = config.GetDirect("table.test[2].d");
|
||||
|
||||
ASSERT_TRUE(table_test_1_a);
|
||||
EXPECT_EQ(table_test_1_a.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(table_test_1_a.GetValue(), 2);
|
||||
ASSERT_TRUE(table_test_1_b);
|
||||
EXPECT_EQ(table_test_1_b.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(table_test_1_b.GetValue(), 1.2);
|
||||
ASSERT_TRUE(table_test_2_a);
|
||||
EXPECT_EQ(table_test_2_a.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(table_test_2_a.GetValue(), 4);
|
||||
ASSERT_TRUE(table_test_2_c);
|
||||
EXPECT_EQ(table_test_2_c.GetType(), sdv::toml::ENodeType::node_boolean);
|
||||
EXPECT_EQ(table_test_2_c.GetValue(), false);
|
||||
ASSERT_TRUE(table_test_3_a);
|
||||
EXPECT_EQ(table_test_3_a.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table_test_3_a.GetValue()), "five");
|
||||
ASSERT_TRUE(table_test_3_d);
|
||||
EXPECT_EQ(table_test_3_d.GetType(), sdv::toml::ENodeType::node_array);
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(NestedContent, InlineTable)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
table1 = { a = 0, b = 1.2, c = "string" }
|
||||
table2 = { a = [], b = true, e = 2.71828 }
|
||||
table3 = { a = { a = "a", b = "A" }, b = {a = "b", b = "B"}, e = {a = "e", b = "E"} }
|
||||
)");
|
||||
|
||||
auto table1_a = config.GetDirect("table1.a");
|
||||
auto table1_b = config.GetDirect("table1.b");
|
||||
auto table1_c = config.GetDirect("table1.c");
|
||||
auto table2_a = config.GetDirect("table2.a");
|
||||
auto table2_b = config.GetDirect("table2.b");
|
||||
auto table2_e = config.GetDirect("table2.e");
|
||||
auto table3_a_a = config.GetDirect("table3.a.a");
|
||||
auto table3_a_b = config.GetDirect("table3.a.b");
|
||||
auto table3_b_a = config.GetDirect("table3.b.a");
|
||||
auto table3_b_b = config.GetDirect("table3.b.b");
|
||||
auto table3_e_a = config.GetDirect("table3.e.a");
|
||||
auto table3_e_b = config.GetDirect("table3.e.b");
|
||||
|
||||
ASSERT_TRUE(table1_a);
|
||||
EXPECT_EQ(table1_a.GetType(), sdv::toml::ENodeType::node_integer);
|
||||
EXPECT_EQ(table1_a.GetValue(), 0);
|
||||
ASSERT_TRUE(table1_b);
|
||||
EXPECT_EQ(table1_b.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(table1_b.GetValue(), 1.2);
|
||||
ASSERT_TRUE(table1_c);
|
||||
EXPECT_EQ(table1_c.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table1_c.GetValue()), "string");
|
||||
ASSERT_TRUE(table2_a);
|
||||
EXPECT_EQ(table2_a.GetType(), sdv::toml::ENodeType::node_array);
|
||||
ASSERT_TRUE(table2_b);
|
||||
EXPECT_EQ(table2_b.GetType(), sdv::toml::ENodeType::node_boolean);
|
||||
EXPECT_EQ(table2_b.GetValue(), true);
|
||||
ASSERT_TRUE(table2_e);
|
||||
EXPECT_EQ(table2_e.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(table2_e.GetValue(), 2.71828);
|
||||
ASSERT_TRUE(table3_a_a);
|
||||
EXPECT_EQ(table3_a_a.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_a_a.GetValue()), "a");
|
||||
ASSERT_TRUE(table3_a_b);
|
||||
EXPECT_EQ(table3_a_b.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_a_b.GetValue()), "A");
|
||||
ASSERT_TRUE(table3_b_a);
|
||||
EXPECT_EQ(table3_b_a.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_b_a.GetValue()), "b");
|
||||
ASSERT_TRUE(table3_b_b);
|
||||
EXPECT_EQ(table3_b_b.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_b_b.GetValue()), "B");
|
||||
ASSERT_TRUE(table3_e_a);
|
||||
EXPECT_EQ(table3_e_a.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_e_a.GetValue()), "e");
|
||||
ASSERT_TRUE(table3_e_b);
|
||||
EXPECT_EQ(table3_e_b.GetType(), sdv::toml::ENodeType::node_string);
|
||||
EXPECT_EQ(static_cast<std::string>(table3_e_b.GetValue()), "E");
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Keys)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(u8R"(
|
||||
"127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
"" = "blank" # VALID but discouraged
|
||||
)"));
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
'' = 'blank' # VALID but discouraged
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true
|
||||
)"));
|
||||
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
# This makes the key "fruit" into a table.
|
||||
fruit.apple.smooth = true
|
||||
# So then you can add to the table "fruit" like so:
|
||||
fruit.orange = 2
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
# VALID BUT DISCOURAGED
|
||||
apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
apple.color = "red"
|
||||
orange.color = "orange"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
3.1415 = 3.1415
|
||||
)"));
|
||||
{
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
3.1415 = 3.1415
|
||||
)");
|
||||
auto table = config.GetDirect("3");
|
||||
auto pi = config.GetDirect("3.1415");
|
||||
ASSERT_TRUE(table);
|
||||
EXPECT_EQ(table.GetType(), sdv::toml::ENodeType::node_table);
|
||||
ASSERT_TRUE(pi);
|
||||
EXPECT_EQ(pi.GetType(), sdv::toml::ENodeType::node_floating_point);
|
||||
EXPECT_EQ(pi.GetValue(), 3.1415);
|
||||
}
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Arrays)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
]
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
]
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Tables)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
[table-1]
|
||||
key1 = "some string"
|
||||
key2 = 123
|
||||
|
||||
[table-2]
|
||||
key1 = "another string"
|
||||
key2 = 456
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
[dog."tater.man"]
|
||||
type.name = "pug"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(u8R"(
|
||||
[a.b.c] # this is best practice
|
||||
[ d.e.f ] # same as [d.e.f]
|
||||
[ g . h . i ] # same as [g.h.i]
|
||||
[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
# [x] you
|
||||
# [x.y] don't
|
||||
# [x.y.z] need these
|
||||
[x.y.z.w] # for this to work
|
||||
[x] # defining a super-table afterward is ok
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
# VALID BUT DISCOURAGED
|
||||
[fruit.apple]
|
||||
[animal]
|
||||
[fruit.orange]
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
[fruit.apple.texture] # you can add sub-tables
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(SpecialCases, TableArrays)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
[[products]] # empty table within the array
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
color = "gray"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[fruits.physical] # subtable
|
||||
color = "red"
|
||||
shape = "round"
|
||||
[[fruits.varieties]] # nested array of tables
|
||||
name = "red delicious"
|
||||
[[fruits.varieties]]
|
||||
name = "granny smith"
|
||||
[[fruits]]
|
||||
name = "banana"
|
||||
[[fruits.varieties]]
|
||||
name = "plantain"
|
||||
)"));
|
||||
|
||||
EXPECT_TRUE(sdv::toml::CTOMLParser(R"(
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ]
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ErrorCases, KeyValue)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(key = # node_invalid)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(first = "Tom" last = "Preston-Werner" # node_invalid)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(= "no key name" # node_invalid)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
name = "Tom"
|
||||
name = "Pradyun"
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
fruit . flavor = "banana" # same as fruit.flavor
|
||||
fruit.flavor = "banana"
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
spelling = "favorite"
|
||||
"spelling" = "favourite"
|
||||
)"));
|
||||
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
# This defines the value of fruit.apple to be an integer.
|
||||
fruit.apple = 1
|
||||
# But then this treats fruit.apple like it's a table.
|
||||
# You can't turn an integer into a table.
|
||||
fruit.apple.smooth = true
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ErrorCases, Tables)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(u8R"(
|
||||
[ j . "ʞ" . 'l' ]
|
||||
[j."ʞ".'l']
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit]
|
||||
apple = "red"
|
||||
[fruit]
|
||||
orange = "orange"
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit]
|
||||
apple = "red"
|
||||
[fruit.apple]
|
||||
texture = "smooth"
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
[fruit.apple] # INVALID
|
||||
)"));
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
[fruit.apple.taste] # INVALID
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ErrorCases, InlineTables)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
type = { name = "Nail" }
|
||||
type.edible = false # INVALID
|
||||
)"));
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[product]
|
||||
type.name = "Nail"
|
||||
type = { edible = false } # INVALID
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ErrorCases, TableArrays)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[fruit.physical] # subtable, but to which parent element should it belong?
|
||||
color = "red"
|
||||
shape = "round"
|
||||
[[fruit]] # parser must throw an error upon discovering that "fruit" is
|
||||
# an array rather than a table
|
||||
name = "apple"
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
fruits = []
|
||||
[[fruits]] # Not allowed
|
||||
)"));
|
||||
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[[fruits.varieties]]
|
||||
name = "red delicious"
|
||||
# INVALID: This table conflicts with the previous array of tables
|
||||
[fruits.varieties]
|
||||
name = "granny smith"
|
||||
)"));
|
||||
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[fruits.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
# INVALID: This array of tables conflicts with the previous table
|
||||
[[fruits.physical]]
|
||||
color = "green"
|
||||
)"));
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(Ordering, Array)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
)");
|
||||
|
||||
auto two = config.GetDirect("array[2]");
|
||||
auto eleven = config.GetDirect("array[11]");
|
||||
const sdv::toml::CNodeCollection arr = config.GetDirect("array");
|
||||
|
||||
// with direct access
|
||||
ASSERT_TRUE(two);
|
||||
EXPECT_EQ(two.GetValue(), 2);
|
||||
ASSERT_TRUE(eleven);
|
||||
EXPECT_EQ(eleven.GetValue(), 11);
|
||||
|
||||
// with indirect access through iterating
|
||||
ASSERT_TRUE(arr);
|
||||
for (std::size_t i = 0; i < arr.GetCount(); ++i)
|
||||
{
|
||||
EXPECT_EQ(arr[i].GetValue(), (int64_t)i);
|
||||
}
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(Ordering, TableAray)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config");
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
sdv::toml::CTOMLParser config(R"(
|
||||
[[tableArray]]
|
||||
a = 0
|
||||
[[tableArray]]
|
||||
a = 1
|
||||
[[tableArray]]
|
||||
a = 2
|
||||
[[tableArray]]
|
||||
a = 3
|
||||
[[tableArray]]
|
||||
a = 4
|
||||
[[tableArray]]
|
||||
a = 5
|
||||
[[tableArray]]
|
||||
a = 6
|
||||
[[tableArray]]
|
||||
a = 7
|
||||
[[tableArray]]
|
||||
a = 8
|
||||
[[tableArray]]
|
||||
a = 9
|
||||
[[tableArray]]
|
||||
a = 10
|
||||
[[tableArray]]
|
||||
a = 11
|
||||
)");
|
||||
|
||||
sdv::toml::CNodeCollection tableArray = config.GetDirect("tableArray");
|
||||
|
||||
ASSERT_TRUE(tableArray);
|
||||
for (std::size_t i = 0; i < tableArray.GetCount(); ++i)
|
||||
{
|
||||
EXPECT_EQ(sdv::toml::CNodeCollection(tableArray[i])[0].GetValue(), (int64_t) i);
|
||||
}
|
||||
|
||||
config.Clear();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
69
tests/component_tests/config_install/CMakeLists.txt
Normal file
69
tests/component_tests/config_install/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
# Define project
|
||||
project (ModuleControlTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Get CRC++ from github
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
CRCpp
|
||||
GIT_REPOSITORY https://github.com/d-bahr/CRCpp
|
||||
GIT_TAG release-1.2.0.0
|
||||
)
|
||||
FetchContent_MakeAvailable(CRCpp)
|
||||
|
||||
# Add include directories
|
||||
include_directories(../export ${CRCpp_SOURCE_DIR})
|
||||
|
||||
# build module example for the test
|
||||
add_library(ComponentTest_ConfigInstall_Module SHARED
|
||||
"test_component.cpp"
|
||||
)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(ComponentTest_ConfigInstall_Module PUBLIC -fPIC)
|
||||
target_link_libraries(ComponentTest_ConfigInstall_Module GTest::GTest)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_ConfigInstall_Module Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_ConfigInstall_Module ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_ConfigInstall_Module GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
set_target_properties(ComponentTest_ConfigInstall_Module PROPERTIES PREFIX "")
|
||||
set_target_properties(ComponentTest_ConfigInstall_Module PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Execute the sdv_packager utility to install the component in instance #2006.
|
||||
add_custom_target(ComponentTest_ConfigInstall_install_manifest
|
||||
# TODO EVE
|
||||
# COMMAND "$<TARGET_FILE:sdv_packager>" -O. --instance2006 -NComponentTest_ConfigInstall "$<TARGET_FILE:ComponentTest_ConfigInstall_Module>" "-I$<TARGET_FILE_DIR:ComponentTest_ConfigInstall_Module>" --settings --create_configtest.toml
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_ConfigInstall --instance2006 "$<TARGET_FILE:ComponentTest_ConfigInstall_Module>" "-I$<TARGET_FILE_DIR:ComponentTest_ConfigInstall_Module>" --overwrite --user_config
|
||||
DEPENDS ComponentTest_ConfigInstall_Module
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
# Module control test executable
|
||||
add_executable(ComponentTest_ConfigInstall
|
||||
"main.cpp"
|
||||
"module_install_test.cpp"
|
||||
"manifest_helper_util_test.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(ComponentTest_ConfigInstall ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the Data Dispatch Service unittest
|
||||
add_test(NAME ComponentTest_ConfigInstall COMMAND ComponentTest_ConfigInstall WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_ConfigInstall POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_ConfigInstall>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_ConfigInstall.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_ConfigInstall_Module sdv_packager)
|
||||
add_dependencies(ComponentTest_ConfigInstall_Module dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_ConfigInstall dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_ConfigInstall ComponentTest_ConfigInstall_Module)
|
||||
add_dependencies(ComponentTest_ConfigInstall ComponentTest_ConfigInstall_install_manifest)
|
||||
|
||||
14
tests/component_tests/config_install/main.cpp
Normal file
14
tests/component_tests/config_install/main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include <filesystem>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
|
||||
TEST(ManifestHelperUtil, Instantiate)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
sdv::core::TModuleID tManifestModule = pModuleControl->Load("manifest_util.sdv");
|
||||
ASSERT_NE(tManifestModule, 0);
|
||||
|
||||
sdv::TObjectPtr ptrManifestUtil = sdv::core::CreateUtility("ManifestHelperUtility");
|
||||
EXPECT_TRUE(ptrManifestUtil);
|
||||
sdv::helper::IModuleManifestHelper* pManifestHelper = ptrManifestUtil.GetInterface<sdv::helper::IModuleManifestHelper>();
|
||||
EXPECT_NE(pManifestHelper, nullptr);
|
||||
ptrManifestUtil.Clear();
|
||||
|
||||
pModuleControl->Unload(tManifestModule);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ManifestHelperUtil, NonExistingComponent)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
sdv::core::TModuleID tManifestModule = pModuleControl->Load("manifest_util.sdv");
|
||||
ASSERT_NE(tManifestModule, 0);
|
||||
|
||||
sdv::TObjectPtr ptrManifestUtil = sdv::core::CreateUtility("ManifestHelperUtility");
|
||||
EXPECT_TRUE(ptrManifestUtil);
|
||||
sdv::helper::IModuleManifestHelper* pManifestHelper = ptrManifestUtil.GetInterface<sdv::helper::IModuleManifestHelper>();
|
||||
EXPECT_NE(pManifestHelper, nullptr);
|
||||
|
||||
sdv::u8string ssManifest = pManifestHelper->ReadModuleManifest("non_existing_component");
|
||||
EXPECT_TRUE(ssManifest.empty());
|
||||
|
||||
ptrManifestUtil.Clear();
|
||||
pModuleControl->Unload(tManifestModule);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(ManifestHelperUtil, ExistingComponent)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
sdv::core::TModuleID tManifestModule = pModuleControl->Load("manifest_util.sdv");
|
||||
ASSERT_NE(tManifestModule, 0);
|
||||
|
||||
sdv::TObjectPtr ptrManifestUtil = sdv::core::CreateUtility("ManifestHelperUtility");
|
||||
EXPECT_TRUE(ptrManifestUtil);
|
||||
sdv::helper::IModuleManifestHelper* pManifestHelper = ptrManifestUtil.GetInterface<sdv::helper::IModuleManifestHelper>();
|
||||
EXPECT_NE(pManifestHelper, nullptr);
|
||||
|
||||
sdv::u8string ssManifest = pManifestHelper->ReadModuleManifest((GetExecDirectory() /
|
||||
"ComponentTest_ConfigInstall_Module.sdv").generic_u8string());
|
||||
EXPECT_FALSE(ssManifest.empty());
|
||||
|
||||
ptrManifestUtil.Clear();
|
||||
pModuleControl->Unload(tManifestModule);
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
277
tests/component_tests/config_install/module_install_test.cpp
Normal file
277
tests/component_tests/config_install/module_install_test.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include <filesystem>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "../../../global/base64.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Shlobj.h>
|
||||
#endif
|
||||
|
||||
class CModuleControl_Install : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
virtual void SetUp()
|
||||
{
|
||||
DeleteTestDirs();
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
DeleteTestDirs();
|
||||
}
|
||||
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestSuite() {}
|
||||
|
||||
void DeleteTestDirs()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(GetExecDirectory() / "module_test1");
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error&)
|
||||
{}
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(GetExecDirectory() / "module_test2");
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error&)
|
||||
{}
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(GetDefaultInstallDir());
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error&)
|
||||
{}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default installation directory.
|
||||
* @return The default installation directory.
|
||||
*/
|
||||
std::filesystem::path GetDefaultInstallDir();
|
||||
};
|
||||
|
||||
inline std::filesystem::path CModuleControl_Install::GetDefaultInstallDir()
|
||||
{
|
||||
// // The default directory for Windows is located at $ProgramData/ and for Posix at the executable.
|
||||
std::filesystem::path pathInstallDir;
|
||||
//#ifdef _WIN32
|
||||
// wchar_t* szPath = nullptr;
|
||||
// HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, 0, &szPath);
|
||||
// if (SUCCEEDED(hr) && szPath)
|
||||
// pathInstallDir = szPath;
|
||||
// if (szPath) CoTaskMemFree(szPath);
|
||||
//#elif defined __unix__
|
||||
pathInstallDir = GetExecDirectory();
|
||||
//#else
|
||||
//#error OS is not supported!
|
||||
//#endif
|
||||
// Append the installation directory with /<instance_ID>/.
|
||||
pathInstallDir /= "2006";
|
||||
|
||||
return pathInstallDir;
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, MainApp_DefaultInstallDir)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2006");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_DefaultInstallDir)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
std::string ssConnectionString = Base64EncodePlainText("");
|
||||
std::string ssConfig = R"code([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2006
|
||||
Connection = ")code";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, OtherApp_DefaultInstallDir)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_FALSE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, MainApp_BlockDefaultInstallDir)
|
||||
{
|
||||
// Prevent error reporting on std::cerr - they will influence test outcome.
|
||||
auto* pCErr = std::cerr.rdbuf();
|
||||
std::ostringstream sstreamCErr;
|
||||
std::cerr.rdbuf(sstreamCErr.rdbuf());
|
||||
|
||||
// Create a blocking file... cannot create directory!
|
||||
std::ofstream fstream(GetDefaultInstallDir());
|
||||
ASSERT_TRUE(fstream.is_open());
|
||||
fstream << "Dummy string...";
|
||||
fstream.close();
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2006");
|
||||
EXPECT_FALSE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
std::cerr.rdbuf(pCErr);
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_BlockDefaultInstallDir)
|
||||
{
|
||||
// Prevent error reporting on std::cerr - they will influence test outcome.
|
||||
auto* pCErr = std::cerr.rdbuf();
|
||||
std::ostringstream sstreamCErr;
|
||||
std::cerr.rdbuf(sstreamCErr.rdbuf());
|
||||
|
||||
std::ofstream fstream(GetDefaultInstallDir());
|
||||
ASSERT_TRUE(fstream.is_open());
|
||||
fstream << "Dummy string...";
|
||||
fstream.close();
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Isolated\"\nInstance=2006");
|
||||
EXPECT_FALSE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
std::cerr.rdbuf(pCErr);
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, OtherApp_BlockDefaultInstallDir)
|
||||
{
|
||||
std::ofstream fstream(GetDefaultInstallDir());
|
||||
ASSERT_TRUE(fstream.is_open());
|
||||
fstream << "Dummy string...";
|
||||
fstream.close();
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetDefaultInstallDir()));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, MainApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(R"code(
|
||||
[Application]
|
||||
Mode="Main"
|
||||
Instance=2006
|
||||
InstallDir = "module_test1"
|
||||
)code");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetExecDirectory() / "module_test1"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
[Application]
|
||||
Mode="Isolated"
|
||||
Instance=2006
|
||||
InstallDir = "module_test1"
|
||||
Connection = ")code") + Base64EncodePlainText("test") + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetExecDirectory() / "module_test1"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, OtherApp_CustomInstallDirRelative)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(R"code([Application]
|
||||
Install.Dir = "module_test1"
|
||||
)code");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_FALSE(std::filesystem::exists(GetExecDirectory() / "module_test1"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, MainApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
[Application]
|
||||
Mode="Main"
|
||||
Instance=2006
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetExecDirectory() / "module_test2"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, IsolatedApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code(
|
||||
[Application]
|
||||
Mode="Isolated"
|
||||
Instance=2006
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"" + R"code(
|
||||
Connection = ")code" + Base64EncodePlainText("test") + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_TRUE(std::filesystem::exists(GetExecDirectory() / "module_test2"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CModuleControl_Install, OtherApp_CustomInstallDirAbsolute)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
bool bResult = control.Startup(std::string(R"code([Application]
|
||||
InstallDir = ")code") + (GetExecDirectory() / "module_test2").generic_u8string() + "\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
|
||||
// The default installation directory should be created.
|
||||
EXPECT_FALSE(std::filesystem::exists(GetExecDirectory() / "module_test2"));
|
||||
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
28
tests/component_tests/config_install/test_component.cpp
Normal file
28
tests/component_tests/config_install/test_component.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <support/component_impl.h>
|
||||
|
||||
class CModuleTestComponent1 : public sdv::CSdvObject
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Utility)
|
||||
DECLARE_OBJECT_CLASS_NAME("ModuleTestComponent1")
|
||||
private:
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CModuleTestComponent1)
|
||||
|
||||
class CModuleTestComponent2 : public sdv::CSdvObject
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Utility)
|
||||
DECLARE_OBJECT_CLASS_NAME("ModuleTestComponent2")
|
||||
private:
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CModuleTestComponent2)
|
||||
|
||||
31
tests/component_tests/core_library/CMakeLists.txt
Normal file
31
tests/component_tests/core_library/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# Define project
|
||||
project (ComponentTest_CoreLibrary VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Data maneger executable
|
||||
add_executable(ComponentTest_CoreLibrary
|
||||
"main.cpp"
|
||||
"app_control_test.cpp"
|
||||
"app_control_test_no_event_handler.cpp"
|
||||
"app_control_test_event_handler.cpp"
|
||||
"app_control_test_mgnt_class.cpp"
|
||||
"app_config.cpp")
|
||||
|
||||
target_link_libraries(ComponentTest_CoreLibrary ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the Data Dispatch Service unittest
|
||||
add_test(NAME ComponentTest_CoreLibrary COMMAND ComponentTest_CoreLibrary WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
# Currently disabled due to issues with MINGW causing the application to sporadically crash. A bug ticket has been filed:
|
||||
# https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608132
|
||||
#add_custom_command(TARGET ComponentTest_CoreLibrary POST_BUILD
|
||||
# COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_CoreLibrary>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_CoreLibrary.xml
|
||||
# VERBATIM
|
||||
#)
|
||||
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_CoreLibrary install_manifest)
|
||||
add_dependencies(ComponentTest_CoreLibrary dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_CoreLibrary data_dispatch_service)
|
||||
add_dependencies(ComponentTest_CoreLibrary ComponentTest_Repository) # Use the repository components for this test
|
||||
29
tests/component_tests/core_library/app_config.cpp
Normal file
29
tests/component_tests/core_library/app_config.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Application config tests
|
||||
// Load config file - Save config file - identical?
|
||||
// Load config file - add module - save config file - module added?
|
||||
// Load config file - add and delete module - identical?
|
||||
// Load config file - add component - save config file - module added?
|
||||
// Load config file - add and delete component - identical?
|
||||
// Load config file - load another config file - Save config file - identical to last config file?
|
||||
// Load config file - reset baseline - add module - save config file - only module in config?
|
||||
// Load config file - reset baseline - add component - save config file - only component in config?
|
||||
// Add module - save config - only module in config?
|
||||
// Add component - save config - only component in config?
|
||||
// Add config file in Startup - config loaded?
|
||||
// For main app: add system config file in settings - config loaded?
|
||||
// For main app: add multiple system config file in settings - config loaded?
|
||||
// For main app: add application config file in settings - config loaded?
|
||||
// For main app: add multiple system config files and an application config in settings - configs loaded?
|
||||
// For main app: add application config file in settings - config loaded? - add component - auto save config - config updated with additional compoment?
|
||||
// For main app: add multiple system config files and an application config file in settings - config loaded? - add component - auto save config - config updated with additional compoment?
|
||||
// For main app: add system config file in settings - add config in application startup - configs loaded?
|
||||
// For main app: add multiple system config file in settings - add config in application startup - configs loaded?
|
||||
// For main app: add application config file in settings - add config in application startup - startup config loaded (and otherone not)?
|
||||
// For main app: add application config file in settings - add config in application startup - add service - startup config not updated? Settings config also not?
|
||||
// Test search algorithm with multiple modules with similar name in different location for standalone and essential
|
||||
// Test search algorithm with multiple modules with similar name in different location for main and isolated
|
||||
// Test configuration saving of module path shoudl not change when module is found somewhere else.
|
||||
// Test not existing config
|
||||
// Test partially existing config (some modules/components do not exist)
|
||||
// Test multiple manifest for loading components
|
||||
|
||||
33
tests/component_tests/core_library/app_control_test.cpp
Normal file
33
tests/component_tests/core_library/app_control_test.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
|
||||
TEST(CoreLibrary_AppControl, SetModuleSearchPath)
|
||||
{
|
||||
sdv::core::IModuleControlConfig* pModuleConfig = sdv::core::GetCore<sdv::core::IModuleControlConfig>();
|
||||
ASSERT_NE(pModuleConfig, nullptr);
|
||||
bool bResult = pModuleConfig->AddModuleSearchDir("../../bin");
|
||||
EXPECT_TRUE(bResult);
|
||||
sdv::sequence<sdv::u8string> seqSearchDirs = pModuleConfig->GetModuleSearchDirs();
|
||||
std::filesystem::path pathModuleDir = (GetExecDirectory() / "../../bin").lexically_normal();
|
||||
auto itDir = std::find_if(seqSearchDirs.begin(), seqSearchDirs.end(),
|
||||
[&](const sdv::u8string& rssDir)
|
||||
{
|
||||
std::filesystem::path pathDir = static_cast<std::string>(rssDir);
|
||||
if (pathDir.is_relative())
|
||||
pathDir = (GetExecDirectory() / pathDir).lexically_normal();
|
||||
return pathDir == pathModuleDir;
|
||||
});
|
||||
EXPECT_NE(itDir, seqSearchDirs.end());
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl, SetModuleSearchPathMgntClass)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.AddModuleSearchDir("../../bin");
|
||||
EXPECT_TRUE(bResult);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,510 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../sdv_services/core/local_shutdown_request.h"
|
||||
#include "../../../global/base64.h"
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Invalid_ApplicationMode)
|
||||
{
|
||||
// Prevent error reporting on std::cerr - they will influence test outcome.
|
||||
auto* pCErr = std::cerr.rdbuf();
|
||||
std::ostringstream sstreamCErr;
|
||||
std::cerr.rdbuf(sstreamCErr.rdbuf());
|
||||
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Invalid\"");
|
||||
EXPECT_FALSE(bResult);
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
std::cerr.rdbuf(pCErr);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Default_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Standalone_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Standalone\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_External_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"External\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Isolated_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup(R"code(
|
||||
[Application]
|
||||
Mode = "Isolated"
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Main_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Essential_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Essential\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Maintenance_NoConfig)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Maintenance\"");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(control.GetInstanceID(), 1000u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Default_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Standalone_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Standalone\"\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_External_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"External\"\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Isolated_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2005
|
||||
Connection = ")code";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Main_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Essential_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Essential\"\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, Startup_Maintenance_DefineInstance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Maintenance\"\nInstance=2005");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2005u);
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Default)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Standalone)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Standalone\"\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_External)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"External\"\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Isolated)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2007
|
||||
Connection = ")code";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = control.Startup(ssConfig);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
pShutdownRequest->RequestShutdown();
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Main)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Main\"\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
pShutdownRequest->RequestShutdown();
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Essential)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Essential\"\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
EXPECT_TRUE(control.RunLoop());
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_MgntClass, RunLoop_Maintenance)
|
||||
{
|
||||
sdv::app::CAppControl control;
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = control.Startup("[Application]\nMode=\"Maintenance\"\nInstance=2007");
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_TRUE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(control.GetInstanceID(), 2007u);
|
||||
|
||||
// Loop not allowed...
|
||||
EXPECT_FALSE(control.RunLoop());
|
||||
|
||||
control.Shutdown();
|
||||
EXPECT_FALSE(control.IsRunning());
|
||||
EXPECT_EQ(control.GetAppContext(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(control.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,643 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include <support/mem_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../sdv_services/core/local_shutdown_request.h"
|
||||
#include "../../../global/base64.h"
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Invalid_ApplicationMode)
|
||||
{
|
||||
// Prevent error reporting on std::cerr - they will influence test outcome.
|
||||
auto* pCErr = std::cerr.rdbuf();
|
||||
std::ostringstream sstreamCErr;
|
||||
std::cerr.rdbuf(sstreamCErr.rdbuf());
|
||||
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Invalid\"", nullptr);
|
||||
EXPECT_FALSE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::cerr.rdbuf(pCErr);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Default_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Standalone_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_External_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Isolated_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup(R"code(
|
||||
[Application]
|
||||
Mode = "Isolated"
|
||||
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Main_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Essential_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Maintenance_NoConfig)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 1000u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Default_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Standalone_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_External_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Isolated_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2005
|
||||
Connection = ")code";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Main_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Essential_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, Startup_Maintenance_DefineInstance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2005", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2005u);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Default)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Standalone)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Standalone\"\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_External)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"External\"\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Isolated)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
std::string ssConfig = R"code([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2007
|
||||
Connection = ")code";
|
||||
ssConfig += Base64EncodePlainText("test") + "\"";
|
||||
bool bResult = pControl->Startup(ssConfig, nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
pShutdownRequest->RequestShutdown();
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Main)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Main\"\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
sdv::app::IAppShutdownRequest* pShutdownRequest = sdv::core::GetObject<sdv::app::IAppShutdownRequest>("AppControlService");
|
||||
ASSERT_NE(pShutdownRequest, nullptr);
|
||||
pShutdownRequest->RequestShutdown();
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Essential)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Essential\"\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
auto tpStart = std::chrono::high_resolution_clock::now();
|
||||
std::thread threadShutdownRequest([]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
RequestShutdown(2007u);
|
||||
});
|
||||
pControl->RunLoop();
|
||||
EXPECT_GT(std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - tpStart).count(), 0.100);
|
||||
threadShutdownRequest.join();
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(CoreLibrary_AppControl_NoEventHandler, RunLoop_Maintenance)
|
||||
{
|
||||
sdv::app::IAppControl* pControl = sdv::core::GetCore<sdv::app::IAppControl>();
|
||||
ASSERT_NE(pControl, nullptr);
|
||||
sdv::app::IAppContext* pContext = sdv::core::GetCore<sdv::app::IAppContext>();
|
||||
ASSERT_NE(pContext, nullptr);
|
||||
sdv::app::IAppOperation* pOperation = sdv::core::GetCore<sdv::app::IAppOperation>();
|
||||
ASSERT_NE(pOperation, nullptr);
|
||||
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
|
||||
bool bResult = pControl->Startup("[Application]\nMode=\"Maintenance\"\nInstance=2007", nullptr);
|
||||
EXPECT_TRUE(bResult);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::running);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 2007u);
|
||||
|
||||
// Loop not allowed...
|
||||
EXPECT_THROW(pControl->RunLoop(), sdv::XAccessDenied);
|
||||
|
||||
pControl->Shutdown(true);
|
||||
EXPECT_EQ(pOperation->GetOperationState(), sdv::app::EAppOperationState::not_started);
|
||||
EXPECT_EQ(pContext->GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_EQ(pContext->GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
14
tests/component_tests/core_library/main.cpp
Normal file
14
tests/component_tests/core_library/main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
32
tests/component_tests/data_dispatch_service/CMakeLists.txt
Normal file
32
tests/component_tests/data_dispatch_service/CMakeLists.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
# Define project
|
||||
project (DataDispatchServiceTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Data maneger executable
|
||||
add_executable(ComponentTest_DataDispatchService data_dispatch_service_test.cpp "transaction_test.cpp" "main.cpp" "trigger_test.cpp")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
target_link_libraries(ComponentTest_DataDispatchService ${CMAKE_THREAD_LIBS_INIT} GTest::GTest)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_DataDispatchService Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_DataDispatchService ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_DataDispatchService GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the Data Dispatch Service unittest
|
||||
add_test(NAME ComponentTest_DataDispatchService COMMAND ComponentTest_DataDispatchService WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_DataDispatchService POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_DataDispatchService>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_DataDispatchService.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_DataDispatchService dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_DataDispatchService data_dispatch_service)
|
||||
add_dependencies(ComponentTest_DataDispatchService task_timer)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_dds_config.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
File diff suppressed because it is too large
Load Diff
14
tests/component_tests/data_dispatch_service/main.cpp
Normal file
14
tests/component_tests/data_dispatch_service/main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
1676
tests/component_tests/data_dispatch_service/transaction_test.cpp
Normal file
1676
tests/component_tests/data_dispatch_service/transaction_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
814
tests/component_tests/data_dispatch_service/trigger_test.cpp
Normal file
814
tests/component_tests/data_dispatch_service/trigger_test.cpp
Normal file
@@ -0,0 +1,814 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
|
||||
#include <support/signal_support.h>
|
||||
#include <interfaces/dispatch.h>
|
||||
#include <support/app_control.h>
|
||||
|
||||
TEST(DataDispatchServiceTest, SingleSpontaneousTrigger)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; });
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, 7);
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(101);
|
||||
signal9.Write(111);
|
||||
signal10.Write(121);
|
||||
signal11.Write(131);
|
||||
signal12.Write(141);
|
||||
signal13.Write(151);
|
||||
signal14.Write(161);
|
||||
EXPECT_EQ(nTriggerCnt, 14);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, MultipleSpontaneousTrigger)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTrigger1Cnt = 0;
|
||||
sdv::core::CTrigger trigger1 = dispatch.CreateTxTrigger([&] { nTrigger1Cnt++; });
|
||||
EXPECT_TRUE(trigger1);
|
||||
trigger1.AddSignal(signal1);
|
||||
trigger1.AddSignal(signal2);
|
||||
trigger1.AddSignal(signal3);
|
||||
size_t nTrigger2Cnt = 0;
|
||||
sdv::core::CTrigger trigger2 = dispatch.CreateTxTrigger([&] { nTrigger2Cnt++; });
|
||||
EXPECT_TRUE(trigger2);
|
||||
trigger2.AddSignal(signal4);
|
||||
trigger2.AddSignal(signal5);
|
||||
trigger2.AddSignal(signal6);
|
||||
trigger2.AddSignal(signal7);
|
||||
EXPECT_EQ(nTrigger2Cnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTrigger1Cnt, 3);
|
||||
EXPECT_EQ(nTrigger2Cnt, 4);
|
||||
|
||||
trigger1.Reset();
|
||||
trigger2.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, TriggerRemoveSignals)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; });
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, 7);
|
||||
|
||||
// Remove signals from trigger
|
||||
trigger.RemoveSignal(signal4);
|
||||
trigger.RemoveSignal(signal4); // Check double removal
|
||||
trigger.RemoveSignal(signal5);
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, 12);
|
||||
|
||||
// Reset signal
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, 15);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, SpontaneousTransactionalTrigger)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Start read transaction
|
||||
sdv::core::CTransaction transaction = dispatch.CreateTransaction();
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; });
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100, transaction);
|
||||
signal9.Write(110, transaction);
|
||||
signal10.Write(120, transaction);
|
||||
signal11.Write(130, transaction);
|
||||
signal12.Write(140, transaction);
|
||||
signal13.Write(150, transaction);
|
||||
signal14.Write(160, transaction);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(200, transaction);
|
||||
signal9.Write(210, transaction);
|
||||
signal10.Write(220, transaction);
|
||||
signal11.Write(230, transaction);
|
||||
signal12.Write(240, transaction);
|
||||
signal13.Write(250, transaction);
|
||||
signal14.Write(260, transaction);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
EXPECT_EQ(nTriggerCnt, 1);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, PeriodicTrigger)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; }, false, 0, 100);
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
size_t nTriggerCntTemp = nTriggerCnt;
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp);
|
||||
|
||||
// Sleep for 750 ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(750));
|
||||
|
||||
// Check trigger count.
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp + 7);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, PeriodicTriggerOnlyActive)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; }, false, 0, 100, true);
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
size_t nTriggerCntTemp = nTriggerCnt;
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp);
|
||||
|
||||
// Sleep for 220 ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(220));
|
||||
|
||||
// Back to default value
|
||||
nTriggerCntTemp = nTriggerCnt;
|
||||
signal8.Write(10);
|
||||
signal9.Write(20);
|
||||
signal10.Write(30);
|
||||
signal11.Write(40);
|
||||
signal12.Write(50);
|
||||
signal13.Write(60);
|
||||
signal14.Write(70);
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp);
|
||||
|
||||
// Sleep for 700 ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(700));
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp + 1);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, SpontaneousAndPeriodicTrigger)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; }, true, 0, 100);
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
size_t nTriggerCntTemp = nTriggerCnt;
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp + 7);
|
||||
|
||||
// Sleep for 750 ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(750));
|
||||
|
||||
// Check trigger count.
|
||||
EXPECT_EQ(nTriggerCnt, nTriggerCntTemp + 14);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(DataDispatchServiceTest, SingleSpontaneousTriggerWithDelay)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_dds_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
// Register the signals
|
||||
sdv::core::CDispatchService dispatch;
|
||||
sdv::core::CSignal signal1 = dispatch.RegisterTxSignal("abc", 10);
|
||||
EXPECT_TRUE(signal1);
|
||||
sdv::core::CSignal signal2 = dispatch.RegisterTxSignal("def", 20);
|
||||
EXPECT_TRUE(signal2);
|
||||
sdv::core::CSignal signal3 = dispatch.RegisterTxSignal("ghi", 30);
|
||||
EXPECT_TRUE(signal3);
|
||||
sdv::core::CSignal signal4 = dispatch.RegisterTxSignal("jkl", 40);
|
||||
EXPECT_TRUE(signal4);
|
||||
sdv::core::CSignal signal5 = dispatch.RegisterTxSignal("mno", 50);
|
||||
EXPECT_TRUE(signal5);
|
||||
sdv::core::CSignal signal6 = dispatch.RegisterTxSignal("pqr", 60);
|
||||
EXPECT_TRUE(signal6);
|
||||
sdv::core::CSignal signal7 = dispatch.RegisterTxSignal("stu", 70);
|
||||
EXPECT_TRUE(signal7);
|
||||
|
||||
// Add publisher for the signals
|
||||
sdv::core::CSignal signal8 = dispatch.AddPublisher("abc");
|
||||
EXPECT_TRUE(signal8);
|
||||
sdv::core::CSignal signal9 = dispatch.AddPublisher("def");
|
||||
EXPECT_TRUE(signal9);
|
||||
sdv::core::CSignal signal10 = dispatch.AddPublisher("ghi");
|
||||
EXPECT_TRUE(signal10);
|
||||
sdv::core::CSignal signal11 = dispatch.AddPublisher("jkl");
|
||||
EXPECT_TRUE(signal11);
|
||||
sdv::core::CSignal signal12 = dispatch.AddPublisher("mno");
|
||||
EXPECT_TRUE(signal12);
|
||||
sdv::core::CSignal signal13 = dispatch.AddPublisher("pqr");
|
||||
EXPECT_TRUE(signal13);
|
||||
sdv::core::CSignal signal14 = dispatch.AddPublisher("stu");
|
||||
EXPECT_TRUE(signal14);
|
||||
|
||||
// Create a trigger
|
||||
size_t nTriggerCnt = 0;
|
||||
sdv::core::CTrigger trigger = dispatch.CreateTxTrigger([&] { nTriggerCnt++; }, true, 100);
|
||||
EXPECT_TRUE(trigger);
|
||||
trigger.AddSignal(signal1);
|
||||
trigger.AddSignal(signal2);
|
||||
trigger.AddSignal(signal3);
|
||||
trigger.AddSignal(signal4);
|
||||
trigger.AddSignal(signal5);
|
||||
trigger.AddSignal(signal6);
|
||||
trigger.AddSignal(signal7);
|
||||
EXPECT_EQ(nTriggerCnt, 0);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(100);
|
||||
signal9.Write(110);
|
||||
signal10.Write(120);
|
||||
signal11.Write(130);
|
||||
signal12.Write(140);
|
||||
signal13.Write(150);
|
||||
signal14.Write(160);
|
||||
EXPECT_EQ(nTriggerCnt, 1);
|
||||
|
||||
// Send data through the publisher
|
||||
signal8.Write(101);
|
||||
signal9.Write(111);
|
||||
signal10.Write(121);
|
||||
signal11.Write(131);
|
||||
signal12.Write(141);
|
||||
signal13.Write(151);
|
||||
signal14.Write(161);
|
||||
EXPECT_EQ(nTriggerCnt, 1);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
EXPECT_EQ(nTriggerCnt, 2);
|
||||
|
||||
appcontrol.SetConfigMode();
|
||||
trigger.Reset();
|
||||
|
||||
signal1.Reset();
|
||||
signal2.Reset();
|
||||
signal3.Reset();
|
||||
signal4.Reset();
|
||||
signal5.Reset();
|
||||
signal6.Reset();
|
||||
signal7.Reset();
|
||||
signal8.Reset();
|
||||
signal9.Reset();
|
||||
signal10.Reset();
|
||||
signal11.Reset();
|
||||
signal12.Reset();
|
||||
signal13.Reset();
|
||||
signal14.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
74
tests/component_tests/dbc_util/CMakeLists.txt
Normal file
74
tests/component_tests/dbc_util/CMakeLists.txt
Normal file
@@ -0,0 +1,74 @@
|
||||
# Define project
|
||||
project (DbcUtilTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Find the DBC utility
|
||||
# REMARKS The utility can only be found after it has build. Having both the utility and the unittest project build, causes an
|
||||
# error during the scanning phase of CMake.
|
||||
#find_program(DBCUTIL NAMES "sdv_dbc_util" PATHS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/" NO_CACHE)
|
||||
set (DBCUTIL "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/sdv_dbc_util")
|
||||
message("Use DBC utility: ${DBCUTIL}")
|
||||
|
||||
# Generate the datalink
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/generated/dbc_struct_test/can_dl/datalink.h ${PROJECT_SOURCE_DIR}/generated/dbc_struct_test/can_dl/datalink.cpp
|
||||
DEPENDS sdv_dbc_util
|
||||
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/dbc_struct_test.dbc
|
||||
COMMENT "Build dbc_struct_test.dbc"
|
||||
COMMAND ${DBCUTIL} ${PROJECT_SOURCE_DIR}/dbc_struct_test.dbc -O${PROJECT_SOURCE_DIR}/generated/dbc_struct_test/ --nodesTestECU_Tx,TestECU_Rx
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/generated/example_can_test/can_dl/datalink.h ${PROJECT_SOURCE_DIR}/generated/example_can_test/can_dl/datalink.cpp
|
||||
DEPENDS sdv_dbc_util
|
||||
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/example_can.dbc
|
||||
COMMENT "Build example_can.dbc"
|
||||
COMMAND ${DBCUTIL} ${PROJECT_SOURCE_DIR}/example_can.dbc -O${PROJECT_SOURCE_DIR}/generated/example_can_test/ --nodesDSC_ASC_ABS
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(PrecompileDBCUtilTest
|
||||
DEPENDS
|
||||
${PROJECT_SOURCE_DIR}/generated/dbc_struct_test/can_dl/datalink.cpp
|
||||
${PROJECT_SOURCE_DIR}/generated/example_can_test/can_dl/datalink.cpp
|
||||
${PROJECT_SOURCE_DIR}/generated/dbc_struct_test/can_dl/datalink.h
|
||||
${PROJECT_SOURCE_DIR}/generated/example_can_test/can_dl/datalink.h
|
||||
)
|
||||
|
||||
# DBC util component test executable
|
||||
add_executable(ComponentTest_DbcUtil dbc_util_test.cpp)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
target_link_libraries(ComponentTest_DbcUtil ${CMAKE_THREAD_LIBS_INIT} GTest::GTest)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_DbcUtil Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_DbcUtil ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_DbcUtil GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the DBC utility component test
|
||||
add_test(NAME ComponentTest_DbcUtil COMMAND ComponentTest_DbcUtil WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# copy the folder 'test_dbc_util_config.toml' to output folder 'config'
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_dbc_util_config_asc.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_dbc_util_config_rx.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_dbc_util_config_tx.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_DbcUtil POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_DbcUtil>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_DbcUtil.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_DbcUtil sdv_dbc_util)
|
||||
add_dependencies(ComponentTest_DbcUtil PrecompileDBCUtilTest)
|
||||
add_dependencies(ComponentTest_DbcUtil dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_DbcUtil task_timer)
|
||||
add_dependencies(ComponentTest_DbcUtil data_dispatch_service)
|
||||
add_dependencies(ComponentTest_DbcUtil can_com_sim)
|
||||
|
||||
3540
tests/component_tests/dbc_util/asc_reader_test.asc
Normal file
3540
tests/component_tests/dbc_util/asc_reader_test.asc
Normal file
File diff suppressed because it is too large
Load Diff
233
tests/component_tests/dbc_util/dbc_struct_test.dbc
Normal file
233
tests/component_tests/dbc_util/dbc_struct_test.dbc
Normal file
@@ -0,0 +1,233 @@
|
||||
VERSION ""
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
BU_: TestECU_Rx TestECU_Tx
|
||||
|
||||
|
||||
BO_ 39 TestLE_MinMax: 8 TestECU_Tx
|
||||
SG_ SignalLE6 : 32|32@1+ (-1.5,5000) [-5000|5000] "" TestECU_Rx
|
||||
SG_ SignalLE5 : 24|8@1- (12.34567,0) [-1000|1000] "" TestECU_Rx
|
||||
SG_ SignalLE4 : 18|6@1+ (0.5,-16) [-15|15] "" TestECU_Rx
|
||||
SG_ SignalLE3 : 12|6@1- (1,25) [0|50] "" TestECU_Rx
|
||||
SG_ SignalLE2 : 4|8@1+ (2,-100) [-100|300] "" TestECU_Rx
|
||||
SG_ SignalLE1 : 0|4@1- (1,0) [-6|6] "" TestECU_Rx
|
||||
|
||||
BO_ 38 TestBE_MinMax: 8 TestECU_Tx
|
||||
SG_ SignalBE1 : 7|4@0- (1,0) [-6|6] "" TestECU_Rx
|
||||
SG_ SignalBE2 : 3|8@0+ (2,-100) [-100|300] "" TestECU_Rx
|
||||
SG_ SignalBE3 : 11|6@0- (1,25) [0|50] "" TestECU_Rx
|
||||
SG_ SignalBE4 : 21|6@0+ (0.5,-16) [-15|15] "" TestECU_Rx
|
||||
SG_ SignalBE5 : 31|8@0- (12.34567,0) [-1000|1000] "" TestECU_Rx
|
||||
SG_ SignalBE6 : 39|32@0+ (-1.5,5000) [-5000|5000] "" TestECU_Rx
|
||||
|
||||
BO_ 8 TestCyclic: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 9 TestCyclicAndSpontaneous: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 10 TestCyclicIfActive: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 11 TestCyclicIfActiveAndSpontaneous: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 12 TestSpontaneousDelay: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 13 TestCyclicAndSpontaneousDelay: 1 TestECU_Tx
|
||||
SG_ Counter : 7|3@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 100 TestUintLE: 8 TestECU_Tx
|
||||
SG_ SignalUintLE6 : 34|30@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintLE5 : 16|18@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintLE4 : 9|7@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintLE3 : 3|6@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintLE2 : 1|2@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintLE1 : 0|1@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 101 TestUintBE: 8 TestECU_Tx
|
||||
SG_ SignalUintBE1 : 7|1@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintBE2 : 6|2@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintBE3 : 4|6@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintBE4 : 14|7@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintBE5 : 23|18@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalUintBE6 : 37|30@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 102 TestUint64LE: 8 TestECU_Tx
|
||||
SG_ SignalUint64LE : 0|64@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 103 TestUint64BE: 8 TestECU_Tx
|
||||
SG_ SignalUint64BE : 7|64@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 200 TestIntLE: 8 TestECU_Tx
|
||||
SG_ SignalIntLE6 : 34|30@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntLE5 : 16|18@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntLE4 : 13|3@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntLE3 : 7|6@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntLE2 : 2|5@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntLE1 : 0|2@1- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 201 TestIntBE: 8 TestECU_Tx
|
||||
SG_ SignalIntBE1 : 7|2@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntBE2 : 5|5@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntBE3 : 0|6@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntBE4 : 10|3@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntBE5 : 23|18@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalIntBE6 : 37|30@0- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 202 TestInt64LE: 8 TestECU_Tx
|
||||
SG_ SignalInt64LE : 0|64@1- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 203 TestInt64BE: 8 TestECU_Tx
|
||||
SG_ SignalInt64BE : 7|64@0- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 300 TestFloatLE: 8 TestECU_Tx
|
||||
SG_ SignalFloatLE2 : 32|32@1- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalFloatLE1 : 0|32@1- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 301 TestFloatBE: 8 TestECU_Tx
|
||||
SG_ SignalFloatBE1 : 7|32@0- (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalFloatBE2 : 39|32@0- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 400 TestDoubleLE: 8 TestECU_Tx
|
||||
SG_ SignalDoubleLE1 : 0|64@1- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 401 TestDoubleBE: 8 TestECU_Tx
|
||||
SG_ SignalDoubleBE1 : 7|64@0- (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 500 TestScaleLE: 7 TestECU_Tx
|
||||
SG_ SignalScaleFloatLE7 : 24|32@1- (0.001,100) [-1000|1000] "" TestECU_Rx
|
||||
SG_ SignalScaleIntLE6 : 20|4@1- (1,-3.5) [-14|15] "" TestECU_Rx
|
||||
SG_ SignalScaleIntLE5 : 16|4@1- (0.001,0.008) [0.002|0.012] "" TestECU_Rx
|
||||
SG_ SignalScaleUintLE4 : 12|4@1+ (1,-2) [-1|10.5] "" TestECU_Rx
|
||||
SG_ SignalScaleUintLE3 : 8|4@1+ (-1,0) [-14|-2] "" TestECU_Rx
|
||||
SG_ SignalScaleUintLE2 : 4|4@1+ (1,-3.5) [-2|11.5] "" TestECU_Rx
|
||||
SG_ SignalScaleUintLE1 : 0|4@1+ (0.001,0) [0.002|0.012] "" TestECU_Rx
|
||||
|
||||
BO_ 501 TestScaleBE: 7 TestECU_Tx
|
||||
SG_ SignalScaleUintBE1 : 7|4@0+ (0.001,0) [0.002|0.012] "" TestECU_Rx
|
||||
SG_ SignalScaleUintBE2 : 3|4@0+ (1,-3.5) [-2|11.5] "" TestECU_Rx
|
||||
SG_ SignalScaleUintBE3 : 15|4@0+ (-1,0) [-14|-2] "" TestECU_Rx
|
||||
SG_ SignalScaleUintBE4 : 11|4@0+ (1,-2) [-1|10.5] "" TestECU_Rx
|
||||
SG_ SignalScaleIntBE5 : 23|4@0- (0.001,0.008) [0.002|0.012] "" TestECU_Rx
|
||||
SG_ SignalScaleIntBE6 : 19|4@0- (1,-3.5) [-14|15] "" TestECU_Rx
|
||||
SG_ SignalScaleFloatBE7 : 31|32@0- (0.001,100) [-1000|1000] "" TestECU_Rx
|
||||
|
||||
BO_ 502 TestScale64LE: 8 TestECU_Tx
|
||||
SG_ SignalScaleInt64LE : 0|64@1- (1e-9,0) [-1000|1000] "" TestECU_Rx
|
||||
|
||||
BO_ 503 TestScale64BE: 8 TestECU_Tx
|
||||
SG_ SignalScaleInt64BE : 7|64@0- (1e-9,0) [-1000|1000] "" TestECU_Rx
|
||||
|
||||
BO_ 7 TestLE: 8 TestECU_Tx
|
||||
SG_ SignalLE6 : 32|32@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalLE5 : 24|8@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalLE4 : 18|6@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalLE3 : 12|6@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalLE2 : 4|8@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalLE1 : 0|4@1+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
BO_ 6 TestBE: 8 TestECU_Tx
|
||||
SG_ SignalBE1 : 7|4@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalBE2 : 3|8@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalBE3 : 11|6@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalBE4 : 21|6@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalBE5 : 31|8@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
SG_ SignalBE6 : 39|32@0+ (1,0) [0|0] "" TestECU_Rx
|
||||
|
||||
|
||||
|
||||
BA_DEF_ BO_ "GenMsgStartDelayTime" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgSendType" ENUM "cyclic","triggered","cyclicIfActive","cyclicAndTriggered","cyclicIfActiveAndTriggered","none";
|
||||
BA_DEF_ BO_ "GenMsgRequestable" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgNrOfRepetition" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgLSupport" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgFastOnStart" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgDelayTime" INT 0 0;
|
||||
BA_DEF_ BO_ "GenMsgCycleTimeFast" INT 0 1000;
|
||||
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 1000;
|
||||
BA_DEF_ SG_ "GenSigStartValue" FLOAT 0 0;
|
||||
BA_DEF_ "BusType" STRING ;
|
||||
BA_DEF_DEF_ "GenMsgStartDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgSendType" "triggered";
|
||||
BA_DEF_DEF_ "GenMsgRequestable" 0;
|
||||
BA_DEF_DEF_ "GenMsgNrOfRepetition" 0;
|
||||
BA_DEF_DEF_ "GenMsgLSupport" 0;
|
||||
BA_DEF_DEF_ "GenMsgFastOnStart" 0;
|
||||
BA_DEF_DEF_ "GenMsgDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgCycleTimeFast" 100;
|
||||
BA_DEF_DEF_ "GenMsgCycleTime" 100;
|
||||
BA_DEF_DEF_ "GenSigStartValue" 0;
|
||||
BA_DEF_DEF_ "BusType" "";
|
||||
BA_ "BusType" "CAN";
|
||||
BA_ "GenMsgCycleTime" BO_ 8 10;
|
||||
BA_ "GenMsgSendType" BO_ 8 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 9 50;
|
||||
BA_ "GenMsgSendType" BO_ 9 3;
|
||||
BA_ "GenMsgCycleTime" BO_ 10 10;
|
||||
BA_ "GenMsgSendType" BO_ 10 2;
|
||||
BA_ "GenMsgCycleTime" BO_ 11 50;
|
||||
BA_ "GenMsgSendType" BO_ 11 4;
|
||||
BA_ "GenMsgDelayTime" BO_ 12 20;
|
||||
BA_ "GenMsgSendType" BO_ 12 1;
|
||||
BA_ "GenMsgDelayTime" BO_ 13 25;
|
||||
BA_ "GenMsgCycleTime" BO_ 13 50;
|
||||
BA_ "GenMsgSendType" BO_ 13 3;
|
||||
BA_ "GenSigStartValue" SG_ 10 Counter 2;
|
||||
BA_ "GenSigStartValue" SG_ 11 Counter 2;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleFloatLE7 100;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleIntLE6 10;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleIntLE5 10;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleUintLE4 10;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleUintLE3 10;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleUintLE2 10;
|
||||
BA_ "GenSigStartValue" SG_ 500 SignalScaleUintLE1 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleUintBE1 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleUintBE2 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleUintBE3 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleUintBE4 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleIntBE5 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleIntBE6 10;
|
||||
BA_ "GenSigStartValue" SG_ 501 SignalScaleFloatBE7 100;
|
||||
SIG_VALTYPE_ 300 SignalFloatLE2 : 1;
|
||||
SIG_VALTYPE_ 300 SignalFloatLE1 : 1;
|
||||
SIG_VALTYPE_ 301 SignalFloatBE1 : 1;
|
||||
SIG_VALTYPE_ 301 SignalFloatBE2 : 1;
|
||||
SIG_VALTYPE_ 400 SignalDoubleLE1 : 2;
|
||||
SIG_VALTYPE_ 401 SignalDoubleBE1 : 2;
|
||||
SIG_VALTYPE_ 500 SignalScaleFloatLE7 : 1;
|
||||
SIG_VALTYPE_ 501 SignalScaleFloatBE7 : 1;
|
||||
|
||||
3524
tests/component_tests/dbc_util/dbc_util_test.cpp
Normal file
3524
tests/component_tests/dbc_util/dbc_util_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
375
tests/component_tests/dbc_util/example_can.dbc
Normal file
375
tests/component_tests/dbc_util/example_can.dbc
Normal file
@@ -0,0 +1,375 @@
|
||||
VERSION "PrivateCAN"
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
BU_: ExampleNode
|
||||
VAL_TABLE_ Fault_Codes 27 "UKWN" 26 "VEHSPDMAX_EXDD" 25 "STS_ALIVE" 24 "STEER_NOT_E2E_MODE" 23 "OTA_SPD" 22 "OTA_TIMER_DOWNLOAD_FAILED" 21 "OTA_MAX_TIME" 20 "CUBIXAD_STEERSTREQ_NOTACTV" 19 "CUBIXAD_DRVSTREQ_NOTACTV" 18 "SFTYDRV_INTV" 17 "LSDC_ALIVE" 16 "CUBIXAD_ALIVE" 15 "IBC_MAB_NO_PRIO" 14 "IBC_NOT_RDY" 13 "IBC_ALIVE" 12 "LSDC_GEAR" 11 "LSDC_SPD" 10 "LSDC_ACCL" 9 "IBC_NOT_MAB_MOD" 8 "GOLDBOX_ALIVE" 7 "CUBIXAD_GEAR" 6 "CUBIXAD_SPD_TESTTRACK" 5 "DRVREQCHG" 4 "RDY_TIMER" 3 "SFTY_CDN_FAILED" 2 "ACTVNCHK_SPD" 1 "ACTVNCHK_TIMR" 0 "NONE" ;
|
||||
VAL_TABLE_ TestMapID 6 "E_TESTMAPID_UNDEFINED" 5 "E_TESTMAPID_TEST_DRIVE" 4 "E_TESTMAPID_AD_AREA" 3 "E_TESTMAPID_STUTT_ARENA" 2 "E_TESTMAPID_ZF_LASTMILE" 1 "E_TESTMAPID_ZF_TESTTRACK_2" 0 "E_TESTMAPID_NONE" ;
|
||||
VAL_TABLE_ CtrlReqStates 7 "CtrlSts3b_RESERVED_4" 6 "CtrlSts3b_RESERVED_3" 5 "CtrlSts3b_RESERVED_2" 4 "CtrlSts3b_RESERVED_1" 3 "CtrlSts3b_ERROR" 2 "CtrlSts3b_CONTROL_REQUESTED" 1 "CtrlSts3b_CONTROL_NOT_REQUESTED" 0 "CtrlSts3b_INIT" ;
|
||||
VAL_TABLE_ SteerActrReSts 7 "Diag" 6 "Inactive" 5 "Ramping" 4 "Yellow" 3 "Red" 2 "Normal" 1 "Pending" 0 "Initialisation" ;
|
||||
VAL_TABLE_ SwtPark1 1 "SwtParkActv" 0 "SwtParkNotActv" ;
|
||||
VAL_TABLE_ PE_State 2 "ERROR" 1 "INIT" 0 "NO_ERROR" ;
|
||||
VAL_TABLE_ SSM_Req 7 "HMS_TAKEOVER" 6 "RESERVED" 5 "RELESE_VIA_RAMP" 4 "DRIVEOFF" 3 "HOLD_STANDBY" 2 "PARK" 1 "HOLD" 0 "NO_REQUEST" ;
|
||||
VAL_TABLE_ IBC_StandStillMode 12 "SSM_ERROR" 11 "SSM_INIT" 10 "SSM_DRIVEOFF_STANDBY_ACTIVE" 9 "SSM_HOLD_STANDBY_ACTIVE" 8 "SSM_HILL_SLIPPOFF_DETECTED" 7 "SSM_RELEASE_REQ_FROM_DRIVER" 6 "SSM_RELEASE_REQ_ACTIVE" 5 "SSM_DRIVEOFF_ACTIVE" 4 "SSM_PARK_RETAINED_ACTIVE" 3 "SSM_PARK_ACTIVE" 2 "SSM_PARK_REQUESTED" 1 "SSM_HOLD_ACTIVE" 0 "SSM_NO_ACTIVE_FUNCTION" ;
|
||||
VAL_TABLE_ AppTgtStDrv 3 "ACTIVE" 2 "READY" 1 "RESERVED" 0 "NOT_ACTIVE" ;
|
||||
VAL_TABLE_ IBC_Status 4 "IBC_MAB_ERR_COMM" 3 "IBC_MAB_NO_PRIO" 2 "IBC_IN_MAB_MODE" 1 "IBC_READY" 0 "IBC_NOT_READY_FAILED" ;
|
||||
VAL_TABLE_ GearLvrIndcn 7 "GearLvrIndcn2_Undefd" 6 "GearLvrIndcn2_Resd2" 5 "GearLvrIndcn2_Resd1" 4 "GearLvrIndcn2_ManModeIndcn" 3 "GearLvrIndcn2_DrvIndcn" 2 "GearLvrIndcn2_NeutIndcn" 1 "GearLvrIndcn2_RvsIndcn" 0 "GearLvrIndcn2_ParkIndcn" ;
|
||||
VAL_TABLE_ LvlgAdjReq 7 "LvlgAdjReq_Resd2" 6 "LvlgAdjReq_Resd1" 5 "LvlgAdjReq_Ll2" 4 "LvlgAdjReq_Ll1" 3 "LvlgAdjReq_Nrh" 2 "LvlgAdjReq_Hl1" 1 "LvlgAdjReq_Hl2" 0 "LvlgAdjReq_Ukwn" ;
|
||||
VAL_TABLE_ DrvModReq 15 "Err" 14 "Rock" 13 "Mud" 12 "Sand" 11 "Snow" 10 "Power" 9 "Hybrid" 8 "Pure_EV" 7 "Race" 6 "Adaptive" 5 "Offroad_CrossTerrain" 4 "Individual" 3 "Dynamic_Sport" 2 "Comfort_Normal" 1 "ECO" 0 "Undefd" ;
|
||||
VAL_TABLE_ MAB_Info_Message 4 "DRV_GEARLVR_TO_P" 3 "DRV_P_TO_D" 2 "LSDC_DI_NOT_PSBL" 1 "LSDC_ENA_NOT_POSSIBLE" 0 "NONE" ;
|
||||
VAL_TABLE_ MAB_OvrdTool_Sts 11 "HACKATHON" 10 "OTA" 9 "INIT" 8 "FINSHD" 7 "FLT" 6 "CUBIX_AD" 5 "SAVE_THE_SPOILER" 4 "LSDC" 3 "RDY" 2 "ACTVN_CHK" 1 "NO_MANIPULATION" 0 "NONE" ;
|
||||
VAL_TABLE_ HMI_Drvr_Req 9 "FCT_DEACTVN_REQ" 8 "FCT_ACTVN_OTA_CFMD" 7 "FCT_ACTVN_OTA_REQ" 6 "FCT_ACTVN_SAVETHESPOILER_CFMD" 5 "FCT_ACTVN_SAVETHESPOILER_REQ" 4 "FCT_ACTVN_LSDC_CFMD" 3 "FCT_ACTVN_LSDC_REQ" 2 "FCT_ACTVN_CUBIXAD_CFMD" 1 "FCT_ACTVN_CUBIXAD_REQ" 0 "FCT_ACTVN_NONE" ;
|
||||
VAL_TABLE_ Info_Message 4 "DRV_GEARLVR_TO_P" 3 "DRV_P_TO_D" 2 "LSDC_DI_NOT_PSBL" 1 "LSDC_ENA_NOT_POSSIBLE" 0 "NONE" ;
|
||||
VAL_TABLE_ HMI_Fct_Req 8 "FCT_DEACTVN_REQ" 7 "FCT_ACTVN_OTA_REQ" 6 "FCT_ACTVN_SAVETHESPOILER_CFMD" 5 "FCT_ACTVN_SAVETHESPOILER_REQ" 4 "FCT_ACTVN_LSDC_CFMD" 3 "FCT_ACTVN_LSDC_REQ" 2 "FCT_ACTVN_AI4MTN_CFMD" 1 "FCT_ACTVN_AI4MTN_REQ" 0 "FCT_ACTVN_NONE" ;
|
||||
VAL_TABLE_ SOVD_states 2 "SOVD_SHOWCASE_ACTIVE" 1 "SOVD_SHOWCASE_DEACTIVE" 0 "SOVD_NONE" ;
|
||||
VAL_TABLE_ OTA_states 7 "OTA_DOWNLOAD_FAILED" 6 "OTA_INSTALL_FAILED" 5 "OTA_INSTALL_FINISHED" 4 "OTA_INSTALL_START" 3 "OTA_DOWNLOAD_START" 2 "OTA_SCHEDULED" 1 "OTA_STANDBY" 0 "OTA_NONE" ;
|
||||
|
||||
|
||||
BO_ 21 Goldbox_Common: 1 ExampleNode
|
||||
SG_ Goldbox_RollgCntr : 7|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
|
||||
BO_ 20 MAB_Internal_Info: 1 Vector__XXX
|
||||
SG_ MAB_GPS_Map_ID : 7|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
|
||||
BO_ 257 MAB_Diagnosics_Response: 8 Vector__XXX
|
||||
SG_ MAB_Diag_IBC_Response : 7|64@0+ (1,0) [0|1.84467440737096E+019] "unitless" Vector__XXX
|
||||
|
||||
BO_ 256 ProConnect_Diagnostics_Request: 8 Vector__XXX
|
||||
SG_ ProConnect_Diag_IBC_Req : 7|64@0+ (1,0) [0|1.84467440737096E+019] "" Vector__XXX
|
||||
|
||||
BO_ 19 ProConnect_GPS_Lat_Long: 8 Vector__XXX
|
||||
SG_ ProConnect_GPS_PE_Long_LowAccry : 39|32@0+ (8.3819E-008,-180) [-180|179.999863699605] "deg" ExampleNode
|
||||
SG_ ProConnect_GPS_PE_Lat_LowAccry : 7|32@0+ (4.19095E-008,-90) [-90|89.9999318498025] "deg" ExampleNode
|
||||
|
||||
BO_ 18 ProConnect_GPS_IMU_Status: 5 Vector__XXX
|
||||
SG_ ProConnect_GPS_TimeStamp : 15|32@0+ (1,0) [0|4294967295] "" Vector__XXX
|
||||
SG_ ProConnect_IMU_PE_State : 7|3@0+ (1,0) [0|7] "" ExampleNode
|
||||
SG_ ProConnect_GPS_PE_State : 4|3@0+ (1,0) [0|7] "" ExampleNode
|
||||
|
||||
BO_ 17 Goldbox_Cubix_Ctrl_2: 3 ExampleNode
|
||||
SG_ Goldbox_TestMapId : 23|8@0+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ Goldbox_Freigabe_Radbremsmom : 8|1@0+ (1,0) [0|1] "bool" Vector__XXX
|
||||
SG_ Goldbox_AccrPedlRatAccrPedlRat : 7|15@0+ (0.00390625,0) [0|127.99609375] "%" Vector__XXX
|
||||
|
||||
BO_ 16 MAB_CubixAD_Ctrl_2: 6 Vector__XXX
|
||||
SG_ MAB_IBC_Status : 15|3@0+ (1,0) [0|7] "" ExampleNode
|
||||
SG_ MAB_GearLvrIndc : 3|3@0+ (1,0) [0|7] "" ExampleNode
|
||||
SG_ MAB_BrakeStandStillMode : 7|4@0+ (1,0) [0|15] "" ExampleNode
|
||||
SG_ MAB_VehMNom : 39|14@0+ (1,0) [0|10000] "Kg" ExampleNode
|
||||
SG_ MAB_DrvrGearShiftParkReq1 : 0|1@0+ (1,0) [0|1] "" ExampleNode
|
||||
SG_ MAB_PinionSteerAgAct : 23|15@0- (0.0009765625,0) [-14.5|14.5] "rad" ExampleNode
|
||||
|
||||
BO_ 15 MAB_CubixAD_Ctrl_1: 6 Vector__XXX
|
||||
SG_ MAB_f_cubiX_AD_Actvn : 24|1@0+ (1,0) [0|1] "bool" ExampleNode
|
||||
SG_ MAB_SteerActReGroupAgAct : 39|10@0- (0.01,0) [-5.12|5.11] "Deg" ExampleNode
|
||||
SG_ MAB_ADataRawSafeALat : 23|15@0- (0.0085,0) [-139.264|139.2555] "m/s^2" ExampleNode
|
||||
SG_ MAB_AgDataRawSafeYawRate : 7|16@0- (0.000244140625,0) [-8|7.999755859375] "rad/s" ExampleNode
|
||||
|
||||
BO_ 14 ProConnect_PE_Angle: 8 Vector__XXX
|
||||
SG_ ProConnect_GPS_PE_Yaw_Angle : 39|32@0+ (8.3819E-008,0) [0|359.999863699605] "deg" ExampleNode
|
||||
SG_ ProConnect_GPS_PE_Course_Angle : 7|32@0+ (8.3819E-008,0) [0|359.999863699605] "deg" ExampleNode
|
||||
|
||||
BO_ 13 ProConnect_GPS_Long: 5 Vector__XXX
|
||||
SG_ ProConnect_GPS_PE_Longitude : 7|40@0+ (3.27419E-010,-180) [-180|180.000997654463] "deg" ExampleNode
|
||||
|
||||
BO_ 12 ProConnect_GPS_Lat: 5 Vector__XXX
|
||||
SG_ ProConnect_GPS_PE_Latitude : 7|40@0+ (1.6371E-010,-90) [-90|90.0010485830452] "deg" ExampleNode
|
||||
|
||||
BO_ 11 ProConnect_STS_Ctrl: 1 Vector__XXX
|
||||
SG_ ProConnect_VehHeiTarReq : 2|3@0+ (1,0) [0|7] "Enum" Vector__XXX
|
||||
SG_ ProConnect_STS_AliveCounter : 6|4@0+ (1,0) [0|15] "Unitless" Vector__XXX
|
||||
SG_ ProConnect_f_VehInGeofence : 7|1@0+ (1,0) [0|1] "bool" Vector__XXX
|
||||
|
||||
BO_ 5 ProConnect_OTA_STS_Status: 1 Vector__XXX
|
||||
SG_ ProConnect_OTA_Sts : 7|8@0+ (1,0) [0|255] "enum" Vector__XXX
|
||||
|
||||
BO_ 10 MAB_STS_Input: 6 Vector__XXX
|
||||
SG_ MAB_WhlRotToothCntrReRi : 47|8@0+ (1,0) [0|255] "Unitless" Vector__XXX
|
||||
SG_ MAB_WhlRotToothCntrReLe : 39|8@0+ (1,0) [0|255] "Unitless" Vector__XXX
|
||||
SG_ MAB_WhlRotToothCntrFrntRi : 31|8@0+ (1,0) [0|255] "Unitless" Vector__XXX
|
||||
SG_ MAB_WhlRotToothCntrFrntLe : 23|8@0+ (1,0) [0|255] "Unitless" Vector__XXX
|
||||
SG_ MAB_VehBodyHei : 7|15@0- (6.2E-005,0) [-1.015808|1.015746] "m" Vector__XXX
|
||||
SG_ MAB_f_STS_Actvn : 8|1@0+ (1,0) [0|1] "bool" Vector__XXX
|
||||
|
||||
BO_ 6 MAB_LSDC_PROP_Input: 8 Vector__XXX
|
||||
SG_ MAB_BrkFricTqWhlReRiAct : 55|13@0+ (1,0) [0|8191] "Nm" ExampleNode
|
||||
SG_ MAB_BrkFricTqWhlReLeAct : 39|13@0+ (1,0) [0|8191] "Nm" ExampleNode
|
||||
SG_ MAB_BrkFricTqWhlFrntRiAct : 23|13@0+ (1,0) [0|8191] "Nm" ExampleNode
|
||||
SG_ MAB_BrkFricTqWhlFrntLeAct : 7|13@0+ (1,0) [0|8191] "Nm" ExampleNode
|
||||
|
||||
BO_ 2 MAB_LSDC_Ctrl: 1 Vector__XXX
|
||||
SG_ MAB_f_LSDC_Actvn : 7|1@0+ (1,0) [0|1] "bool" ExampleNode
|
||||
|
||||
BO_ 0 MAB_LSDC_CAN_Input: 8 Vector__XXX
|
||||
SG_ MAB_VehSpdLgtA : 55|15@0+ (0.00391,0) [0|128.11897] "m/s" ExampleNode
|
||||
SG_ MAB_SteerWhlSnsrAg : 39|15@0- (0.0009765625,0) [-16|15.9990234375] "rad" ExampleNode
|
||||
SG_ MAB_f_VehSpd_RvsDetd : 24|1@0+ (1,0) [0|1] "bool" ExampleNode
|
||||
SG_ MAB_DrvModReq : 15|8@0+ (1,0) [0|255] "" ExampleNode
|
||||
SG_ MAB_ADataRawSafeALgt : 23|15@0- (0.0085,0) [-139.264|139.2555] "m/s^2" ExampleNode
|
||||
SG_ MAB_act_wheel_angle_front : 7|8@0- (0.00781,0) [-0.99968|0.99187] "rad" ExampleNode
|
||||
|
||||
BO_ 7 MAB_HMI_Feedback_2: 8 Vector__XXX
|
||||
SG_ MAB_FourCornrReq_Act : 45|3@0+ (1,0) [0|7] "Enum" Vector__XXX
|
||||
SG_ MAB_Veh_A : 15|8@0- (0.2,0) [-25.6|25.4] "m/s^2" Vector__XXX
|
||||
SG_ MAB_SteerWhlAg_Deg : 23|11@0- (1,0) [-1024|1023] "deg" Vector__XXX
|
||||
SG_ MAB_ReSteerAgAct : 55|10@0- (0.01,0) [-5.12|5.11] "deg" Vector__XXX
|
||||
SG_ MAB_Goldbox_Alive : 25|1@0+ (1,0) [0|1] "bool" Vector__XXX
|
||||
SG_ MAB_CurSpd_kmph : 7|8@0+ (1,0) [0|255] "kmph" Vector__XXX
|
||||
SG_ MAB_AliveCounter : 28|3@0+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ MAB_act_wheel_angle_front_deg : 39|10@0- (0.2,0) [-102.4|102.2] "deg" Vector__XXX
|
||||
|
||||
BO_ 4 MAB_HMI_Feedback_1: 4 Vector__XXX
|
||||
SG_ voltage_AccrPedl_Out : 31|8@0+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ MAB_OvrdTool_Sts : 3|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ MAB_Info_Message : 7|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ MAB_Global_activation_status : 15|6@0+ (1,0) [0|63] "bit coded" Vector__XXX
|
||||
SG_ MAB_Fault_codes : 23|5@0+ (1,0) [0|31] "" Vector__XXX
|
||||
|
||||
BO_ 9 MAB_CubixAD_Ctrl_3: 6 Vector__XXX
|
||||
SG_ MAB_SteerActReGroupSts : 43|3@0+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ MAB_IsgTqAct800ActuTq : 39|12@0+ (5,-10235) [-10235|10240] "Nm" ExampleNode
|
||||
SG_ MAB_WhlMotSysTqEst800Tq2Act : 23|14@0+ (1,-8191) [-8191|8192] "Nm" ExampleNode
|
||||
SG_ MAB_VehMtnSt : 8|1@0+ (1,0) [0|1] "bool" ExampleNode
|
||||
SG_ MAB_BrkFricTqTotAtWhlsAct : 7|15@0+ (1,0) [0|20000] "Nm" ExampleNode
|
||||
|
||||
BO_ 1 HMI_Requests: 2 Vector__XXX
|
||||
SG_ HMI_f_ReSteerCtrlActvnReq : 15|1@0+ (1,0) [0|1] "bool" Vector__XXX
|
||||
SG_ HMI_Drvr_Req : 7|8@0+ (1,0) [0|255] "enum" Vector__XXX
|
||||
|
||||
BO_ 3 Goldbox_LSDC_Ctrl: 3 ExampleNode
|
||||
SG_ Goldbox_SteerReCtrlReqSts : 23|3@0+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ Goldbox_SteerReCtrlReqAgReq : 7|10@0- (0.01,0) [-5.12|5.11] "deg" Vector__XXX
|
||||
SG_ Goldbox_LSDC_RollgCntr : 13|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
|
||||
BO_ 8 Goldbox_Cubix_Ctrl_1: 7 ExampleNode
|
||||
SG_ Goldbox_DriveStateReq : 55|2@0+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ Goldbox_SteerStateReq : 42|3@0+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ Goldbox_SSM_Req : 45|3@0+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ Goldbox_Verz_Anf : 39|10@0+ (0.024,-20.016) [-20.016|4.536] "m/s^2" Vector__XXX
|
||||
SG_ Goldbox_Radbremsmom : 23|12@0+ (8,0) [0|32760] "Nm" Vector__XXX
|
||||
SG_ Goldbox_Verz_freigabe : 8|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ Goldbox_SteerWhlAgReq : 7|15@0- (0.0009765625,0) [-14.5|14.5] "rad" Vector__XXX
|
||||
SG_ Goldbox_Cubix_RollgCntr : 27|4@0+ (1,0) [0|15] "" Vector__XXX
|
||||
|
||||
|
||||
|
||||
CM_ SG_ 21 Goldbox_RollgCntr "A similar counter will be existing in MAB, Each cycle will the counter number be compared with the value from Goldbox. When these numbers have a deviation of more than 3, the MAB will switch to the series mode.";
|
||||
CM_ BO_ 20 "Internal signals for measurement and debugging";
|
||||
CM_ SG_ 257 MAB_Diag_IBC_Response "Response of IBC regarding diagnosis request read from Chassis can 1 ";
|
||||
CM_ SG_ 256 ProConnect_Diag_IBC_Req "Diagnosis request sent by ProConnect to MAB. MAB forwards it to IBC on chassis Can 1";
|
||||
CM_ SG_ 19 ProConnect_GPS_PE_Long_LowAccry "ProConnect GPS longitude signal with less accuracy. Instead of 40 bit is 32 bit. The accuracy will be in the 1-2 cm range.";
|
||||
CM_ SG_ 19 ProConnect_GPS_PE_Lat_LowAccry "ProConnect GPS lateral signal with less accuracy. Instead of 40 bit is 32 bit. The accuracy will be in the 1-2 cm range.";
|
||||
CM_ SG_ 17 Goldbox_TestMapId "Identifier CubixAD test map. ";
|
||||
CM_ SG_ 16 MAB_VehMNom "Estimated vehicle mass including trailer. Vehicle mass including trailer mass (if connected).";
|
||||
CM_ SG_ 16 MAB_DrvrGearShiftParkReq1 "Driver park request from gear shifter. Valid for Shift-By-Wire system.";
|
||||
CM_ SG_ 15 MAB_SteerActReGroupAgAct "AgAct (Actual angle at Rear axle)";
|
||||
CM_ SG_ 11 ProConnect_STS_AliveCounter "Save the spoiler alive rolling counter (0 -14 )";
|
||||
CM_ SG_ 11 ProConnect_f_VehInGeofence "Is vehicle in geofence area";
|
||||
CM_ SG_ 5 ProConnect_OTA_Sts "Current status of the ProConnect. ";
|
||||
CM_ SG_ 10 MAB_WhlRotToothCntrReRi "Wheel rotation ticks for each individual wheel. Wheel rotation impuls counter rear right. For one complete wheel revolution the counter will increase by 96 (with 48 magnetic pole-pairs).";
|
||||
CM_ SG_ 10 MAB_WhlRotToothCntrReLe "Wheel rotation ticks for each individual wheel. Wheel rotation impuls counter rear left. For one complete wheel revolution the counter will increase by 96 (with 48 magnetic pole-pairs).";
|
||||
CM_ SG_ 10 MAB_WhlRotToothCntrFrntRi "Wheel rotation ticks for each individual wheel. Wheel rotation impuls counter front right. For one complete wheel revolution the counter will increase by 96 (with 48 magnetic pole-pairs).";
|
||||
CM_ SG_ 10 MAB_WhlRotToothCntrFrntLe "Wheel rotation ticks for each individual wheel. Wheel rotation impuls counter front left. For one complete wheel revolution the counter will increase by 96 (with 48 magnetic pole-pairs).";
|
||||
CM_ SG_ 10 MAB_VehBodyHei "Signal forwareded from vehicle to ProConnect regarding Vehicle body height. Vehicle signal on Chassis CAN 2 is BodyHei. ";
|
||||
CM_ SG_ 10 MAB_f_STS_Actvn "Activation and deactivation flag from MAB to ProConnect regarding the activation and deactivation of save the spoiler";
|
||||
CM_ SG_ 6 MAB_BrkFricTqWhlReRiAct "Actual service brake torque. Brake torque acting on the rear right wheel.
|
||||
Based on nominal brake parameters (e.g. constant pads friction) and (estimated) brake pressures (clamp forces). Not incl.: parking brake torque or regenerative brake torque.";
|
||||
CM_ SG_ 6 MAB_BrkFricTqWhlReLeAct "Actual service brake torque. Brake torque acting on the rear left wheel.
|
||||
Based on nominal brake parameters (e.g. constant pads friction) and (estimated) brake pressures (clamp forces). Not incl.: parking brake torque or regenerative brake torque.";
|
||||
CM_ SG_ 6 MAB_BrkFricTqWhlFrntRiAct "Actual service brake torque. Brake torque acting on the front right wheel.
|
||||
Based on nominal brake parameters (e.g. constant pads friction) and (estimated) brake pressures (clamp forces). Not incl.: parking brake torque or regenerative brake torque.";
|
||||
CM_ SG_ 6 MAB_BrkFricTqWhlFrntLeAct "Actual service brake torque. Brake torque acting on the front left wheel.
|
||||
Based on nominal brake parameters (e.g. constant pads friction) and (estimated) brake pressures (clamp forces). Not incl.: parking brake torque or regenerative brake torque.";
|
||||
CM_ SG_ 2 MAB_f_LSDC_Actvn "This flag will be send via MAB in the ready state.This state is one step, before fully handover to the algorithm. It can be used to reset the rolling counter as well. ";
|
||||
CM_ SG_ 0 MAB_VehSpdLgtA "Vehicle speed longitudinal based on wheel speed sensors and longitudinal acceleration.";
|
||||
CM_ SG_ 0 MAB_SteerWhlSnsrAg "Actual steering wheel angle from the actual centre position of the steering wheel. ";
|
||||
CM_ SG_ 0 MAB_f_VehSpd_RvsDetd "VehicleVelocity.ReverseDetected. This signal should still be clarified, whether is needed or not?";
|
||||
CM_ SG_ 0 MAB_DrvModReq "driving mode request. This signal can be read on the CAN 1 and CAN 2 with different frame cyclicity. ";
|
||||
CM_ SG_ 0 MAB_ADataRawSafeALgt "Longitudinal acceleration over ground.
|
||||
end2endprotection=profile1A dataid= 12345 Longitudinal acceleration over ground";
|
||||
CM_ SG_ 0 MAB_act_wheel_angle_front "This signal is calculated by multiplying steering gear ratio with MAB_SteerWhlSnsrAg";
|
||||
CM_ SG_ 7 MAB_FourCornrReq_Act "Actual request of vehicle height adjustment from ProConnect during Save the spoiler";
|
||||
CM_ SG_ 7 MAB_Veh_A "vehicle acceleration OR deceleration ";
|
||||
CM_ SG_ 7 MAB_SteerWhlAg_Deg "actual steering wheel angle in degree";
|
||||
CM_ SG_ 7 MAB_ReSteerAgAct "Actual rear wheel steering angle in degree";
|
||||
CM_ SG_ 7 MAB_Goldbox_Alive "Status of Goldbox (alive or not)";
|
||||
CM_ SG_ 7 MAB_act_wheel_angle_front_deg "actua frontl wheel angle in degree";
|
||||
CM_ SG_ 4 MAB_OvrdTool_Sts "Current state of the MAB stateflow. ";
|
||||
CM_ SG_ 4 MAB_Info_Message "This signal can be used to show any messages to the safety driver. ";
|
||||
CM_ SG_ 4 MAB_Global_activation_status "Bit coded signal. Set true to below conditions. Value is 31 if all conditions true
|
||||
0 --> All Door closed
|
||||
1 --> Driver seat belt fastened
|
||||
2 --> AD main switch on
|
||||
3 --> Driver seat occupied ";
|
||||
CM_ SG_ 4 MAB_Fault_codes "0 = NONE,1 = Glb Actvn Cdn Failed,2 = Emergency Button,3 = Drvr Intv Detd,4 = MAB Watchdog Err Detd,5 = GoldBox Cntr Err Detd,6 = Spd Lim Excdd,7 = Acc Lim Excdd,8 = IBC not in Manip Mod,9 = Steer Grdt Excdd,10 = Phy Lim Excdd,11 = Re Steer Grdt Excdd
|
||||
";
|
||||
CM_ SG_ 9 MAB_IsgTqAct800ActuTq "Actual Torque (at Front Motor)";
|
||||
CM_ SG_ 9 MAB_WhlMotSysTqEst800Tq2Act "Actual Torque (at Rear Motor)";
|
||||
CM_ SG_ 9 MAB_VehMtnSt "Vehicle motion state information based on wheel speed sensors. Provides information about vehicle stand still and vehicle rolling direction. Vehicle motion state;";
|
||||
CM_ SG_ 9 MAB_BrkFricTqTotAtWhlsAct "Total actual friction brake toque at all four wheels.";
|
||||
CM_ SG_ 1 HMI_f_ReSteerCtrlActvnReq "LSDC: flag for rear steering control enabled or disabled.";
|
||||
CM_ SG_ 1 HMI_Drvr_Req "HMI sends the driver request and his confirmation. ";
|
||||
CM_ SG_ 3 Goldbox_SteerReCtrlReqSts "Control bits for angle request, corporate with steer angle request and Qf to realize rear axle angle control.
|
||||
SteerReCtrlReqSteerReCtrlSts";
|
||||
CM_ SG_ 3 Goldbox_SteerReCtrlReqAgReq "Rear Steering angle request";
|
||||
CM_ SG_ 3 Goldbox_LSDC_RollgCntr "A similar counter will be existing in MAB, Each cycle will the counter number be compared with the value from Goldbox. When these numbers have a deviation of more than 3, the MAB will switch to the series mode.";
|
||||
CM_ SG_ 8 Goldbox_SteerWhlAgReq "steering wheel angle from the actual centre position of the steering wheel requested from Cubix AD application on Goldbox ";
|
||||
CM_ SG_ 8 Goldbox_Cubix_RollgCntr "A similar counter will be existing in MAB, Each cycle will the counter number be compared with the value from Goldbox. When these numbers have a deviation of more than 3, the MAB will switch to the series mode.";
|
||||
BA_DEF_ "Baudrate" INT 1000 1000000;
|
||||
BA_DEF_ "BusType" STRING ;
|
||||
BA_DEF_ "DBName" STRING ;
|
||||
BA_DEF_ "ProtocolType" STRING ;
|
||||
BA_DEF_ BU_ "NmAsrNode" ENUM "No","Yes";
|
||||
BA_DEF_ BU_ "NmAsrNodeIdentifier" INT 0 255;
|
||||
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65536;
|
||||
BA_DEF_ BO_ "GenMsgCycleTimeFast" FLOAT 0 300000;
|
||||
BA_DEF_ BO_ "GenMsgDelayTime" INT 0 65536;
|
||||
BA_DEF_ BO_ "GenMsgNrOfRepetition" INT 0 100000;
|
||||
BA_DEF_ BO_ "GenMsgSendType" ENUM "cyclic","spontaneous","not-used","not-used","not-used","cyclicAndSpontaneous","not-used","cyclicIfActive","NoMsgSendType";
|
||||
BA_DEF_ BO_ "GenMsgStartDelayTime" INT 0 65536;
|
||||
BA_DEF_ SG_ "GenSigSendType" ENUM "Cyclic","OnWrite","OnWriteWithRepetition","OnChange","OnChangeWithRepetition","IfActive","IfActiveWithRepetition","NoSigSendType";
|
||||
BA_DEF_ SG_ "GenSigStartValue" HEX 0 80000000;
|
||||
BA_DEF_ BO_ "GenMsgILSupport" ENUM "No","Yes";
|
||||
BA_DEF_ BO_ "NmAsrMessage" ENUM "No","Yes";
|
||||
BA_DEF_ "NmAsrBaseAddress" HEX 0 536870911;
|
||||
BA_DEF_ "NmAsrMessageCount" INT 0 255;
|
||||
BA_DEF_ BU_ "NodeLayerModules" STRING ;
|
||||
BA_DEF_ BU_ "ILused" ENUM "No","Yes";
|
||||
BA_DEF_ SG_ "GenSigFuncType" ENUM "NoFunction","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","CHK","CNTR","n/a","n/a","n/a","CNTR_AR_01","CRC_AR_01_BOTH","CRC_AR_01_ALT","CRC_AR_01_LOW","CRC_AR_01_NIBBLE","CNTR_AR_04","CRC_AR_04A","CNTR_AR_05","CRC_AR_05";
|
||||
BA_DEF_ SG_ "GenSigDataID" STRING ;
|
||||
BA_DEF_ SG_ "SigGroup" STRING ;
|
||||
BA_DEF_DEF_ "Baudrate" 1000;
|
||||
BA_DEF_DEF_ "BusType" "";
|
||||
BA_DEF_DEF_ "DBName" "";
|
||||
BA_DEF_DEF_ "ProtocolType" "";
|
||||
BA_DEF_DEF_ "NmAsrNode" "No";
|
||||
BA_DEF_DEF_ "NmAsrNodeIdentifier" 0;
|
||||
BA_DEF_DEF_ "GenMsgCycleTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgCycleTimeFast" 0;
|
||||
BA_DEF_DEF_ "GenMsgDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgNrOfRepetition" 0;
|
||||
BA_DEF_DEF_ "GenMsgSendType" "NoMsgSendType";
|
||||
BA_DEF_DEF_ "GenMsgStartDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenSigSendType" "NoSigSendType";
|
||||
BA_DEF_DEF_ "GenSigStartValue" 0;
|
||||
BA_DEF_DEF_ "GenMsgILSupport" "Yes";
|
||||
BA_DEF_DEF_ "NmAsrMessage" "No";
|
||||
BA_DEF_DEF_ "NmAsrBaseAddress" 1280;
|
||||
BA_DEF_DEF_ "NmAsrMessageCount" 64;
|
||||
BA_DEF_DEF_ "NodeLayerModules" "CANoeILNLSPA.dll";
|
||||
BA_DEF_DEF_ "ILused" "Yes";
|
||||
BA_DEF_DEF_ "GenSigFuncType" "NoFunction";
|
||||
BA_DEF_DEF_ "GenSigDataID" "";
|
||||
BA_DEF_DEF_ "SigGroup" "";
|
||||
BA_ "Baudrate" 500000;
|
||||
BA_ "BusType" "CAN";
|
||||
BA_ "ProtocolType" "CAN";
|
||||
BA_ "DBName" "example_can";
|
||||
BA_ "GenMsgSendType" BO_ 21 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 21 10;
|
||||
BA_ "GenMsgCycleTime" BO_ 20 10;
|
||||
BA_ "GenMsgSendType" BO_ 20 0;
|
||||
BA_ "GenMsgSendType" BO_ 257 1;
|
||||
BA_ "GenMsgDelayTime" BO_ 257 5;
|
||||
BA_ "GenMsgSendType" BO_ 256 1;
|
||||
BA_ "GenMsgDelayTime" BO_ 256 5;
|
||||
BA_ "GenMsgSendType" BO_ 19 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 19 10;
|
||||
BA_ "GenMsgSendType" BO_ 18 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 18 10;
|
||||
BA_ "GenMsgCycleTime" BO_ 17 10;
|
||||
BA_ "GenMsgSendType" BO_ 17 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 16 10;
|
||||
BA_ "GenMsgSendType" BO_ 16 0;
|
||||
BA_ "GenMsgSendType" BO_ 15 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 15 10;
|
||||
BA_ "GenMsgSendType" BO_ 14 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 14 10;
|
||||
BA_ "GenMsgSendType" BO_ 13 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 13 10;
|
||||
BA_ "GenMsgSendType" BO_ 12 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 12 10;
|
||||
BA_ "GenMsgSendType" BO_ 11 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 11 10;
|
||||
BA_ "GenMsgCycleTime" BO_ 5 10;
|
||||
BA_ "GenMsgSendType" BO_ 5 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 10 10;
|
||||
BA_ "GenMsgSendType" BO_ 10 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 6 10;
|
||||
BA_ "GenMsgSendType" BO_ 6 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 2 10;
|
||||
BA_ "GenMsgSendType" BO_ 2 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 0 10;
|
||||
BA_ "GenMsgSendType" BO_ 0 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 7 10;
|
||||
BA_ "GenMsgSendType" BO_ 7 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 4 10;
|
||||
BA_ "GenMsgSendType" BO_ 4 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 9 10;
|
||||
BA_ "GenMsgSendType" BO_ 9 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 1 10;
|
||||
BA_ "GenMsgSendType" BO_ 1 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 3 10;
|
||||
BA_ "GenMsgSendType" BO_ 3 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 8 10;
|
||||
BA_ "GenMsgSendType" BO_ 8 0;
|
||||
BA_ "GenSigStartValue" SG_ 19 ProConnect_GPS_PE_Long_LowAccry 0;
|
||||
BA_ "GenSigStartValue" SG_ 19 ProConnect_GPS_PE_Lat_LowAccry 0;
|
||||
BA_ "GenSigStartValue" SG_ 13 ProConnect_GPS_PE_Longitude 0;
|
||||
BA_ "GenSigStartValue" SG_ 12 ProConnect_GPS_PE_Latitude 0;
|
||||
BA_ "GenSigStartValue" SG_ 9 MAB_IsgTqAct800ActuTq 2047;
|
||||
BA_ "GenSigStartValue" SG_ 9 MAB_WhlMotSysTqEst800Tq2Act 8191;
|
||||
BA_ "GenSigStartValue" SG_ 8 Goldbox_Verz_Anf 834;
|
||||
VAL_ 20 MAB_GPS_Map_ID 6 "E_TESTMAPID_UNDEFINED" 5 "E_TESTMAPID_TEST_DRIVE" 4 "E_TESTMAPID_AD_AREA" 3 "E_TESTMAPID_STUTT_ARENA" 2 "E_TESTMAPID_ZF_LASTMILE" 1 "E_TESTMAPID_ZF_TESTTRACK_2" 0 "E_TESTMAPID_NONE" ;
|
||||
VAL_ 18 ProConnect_IMU_PE_State 2 "ERROR" 1 "INIT" 0 "NO_ERROR" ;
|
||||
VAL_ 18 ProConnect_GPS_PE_State 2 "ERROR" 1 "INIT" 0 "NO_ERROR" ;
|
||||
VAL_ 17 Goldbox_TestMapId 6 "E_TESTMAPID_UNDEFINED" 5 "E_TESTMAPID_TEST_DRIVE" 4 "E_TESTMAPID_AD_AREA" 3 "E_TESTMAPID_STUTT_ARENA" 2 "E_TESTMAPID_ZF_LASTMILE" 1 "E_TESTMAPID_ZF_TESTTRACK_2" 0 "E_TESTMAPID_NONE" ;
|
||||
VAL_ 16 MAB_IBC_Status 4 "IBC_MAB_ERR_COMM" 3 "IBC_MAB_NO_PRIO" 2 "IBC_IN_MAB_MODE" 1 "IBC_READY" 0 "IBC_NOT_READY_FAILED" ;
|
||||
VAL_ 16 MAB_GearLvrIndc 7 "GearLvrIndcn2_Undefd" 6 "GearLvrIndcn2_Resd2" 5 "GearLvrIndcn2_Resd1" 4 "GearLvrIndcn2_ManModeIndcn" 3 "GearLvrIndcn2_DrvIndcn" 2 "GearLvrIndcn2_NeutIndcn" 1 "GearLvrIndcn2_RvsIndcn" 0 "GearLvrIndcn2_ParkIndcn" ;
|
||||
VAL_ 16 MAB_BrakeStandStillMode 12 "SSM_ERROR" 11 "SSM_INIT" 10 "SSM_DRIVEOFF_STANDBY_ACTIVE" 9 "SSM_HOLD_STANDBY_ACTIVE" 8 "SSM_HILL_SLIPPOFF_DETECTED" 7 "SSM_RELEASE_REQ_FROM_DRIVER" 6 "SSM_RELEASE_REQ_ACTIVE" 5 "SSM_DRIVEOFF_ACTIVE" 4 "SSM_PARK_RETAINED_ACTIVE" 3 "SSM_PARK_ACTIVE" 2 "SSM_PARK_REQUESTED" 1 "SSM_HOLD_ACTIVE" 0 "SSM_NO_ACTIVE_FUNCTION" ;
|
||||
VAL_ 16 MAB_DrvrGearShiftParkReq1 1 "SwtParkActv" 0 "SwtParkNotActv" ;
|
||||
VAL_ 11 ProConnect_VehHeiTarReq 7 "LvlgAdjReq_Resd2" 6 "LvlgAdjReq_Resd1" 5 "LvlgAdjReq_Ll2" 4 "LvlgAdjReq_Ll1" 3 "LvlgAdjReq_Nrh" 2 "LvlgAdjReq_Hl1" 1 "LvlgAdjReq_Hl2" 0 "LvlgAdjReq_Ukwn" ;
|
||||
VAL_ 5 ProConnect_OTA_Sts 7 "OTA_DOWNLOAD_FAILED" 6 "OTA_INSTALL_FAILED" 5 "OTA_INSTALL_FINISHED" 4 "OTA_INSTALL_START" 3 "OTA_DOWNLOAD_START" 2 "OTA_SCHEDULED" 1 "OTA_STANDBY" 0 "OTA_NONE" ;
|
||||
VAL_ 0 MAB_DrvModReq 15 "Err" 14 "Rock" 13 "Mud" 12 "Sand" 11 "Snow" 10 "Power" 9 "Hybrid" 8 "Pure_EV" 7 "Race" 6 "Adaptive" 5 "Offroad_CrossTerrain" 4 "Individual" 3 "Dynamic_Sport" 2 "Comfort_Normal" 1 "ECO" 0 "Undefd" ;
|
||||
VAL_ 7 MAB_FourCornrReq_Act 7 "LvlgAdjReq_Resd2" 6 "LvlgAdjReq_Resd1" 5 "LvlgAdjReq_Ll2" 4 "LvlgAdjReq_Ll1" 3 "LvlgAdjReq_Nrh" 2 "LvlgAdjReq_Hl1" 1 "LvlgAdjReq_Hl2" 0 "LvlgAdjReq_Ukwn" ;
|
||||
VAL_ 4 MAB_OvrdTool_Sts 11 "HACKATHON" 10 "OTA" 9 "INIT" 8 "FINSHD" 7 "FLT" 6 "CUBIX_AD" 5 "SAVE_THE_SPOILER" 4 "LSDC" 3 "RDY" 2 "ACTVN_CHK" 1 "NO_MANIPULATION" 0 "NONE" ;
|
||||
VAL_ 4 MAB_Info_Message 4 "DRV_GEARLVR_TO_P" 3 "DRV_P_TO_D" 2 "LSDC_DI_NOT_PSBL" 1 "LSDC_ENA_NOT_POSSIBLE" 0 "NONE" ;
|
||||
VAL_ 4 MAB_Fault_codes 27 "UKWN" 26 "VEHSPDMAX_EXDD" 25 "STS_ALIVE" 24 "STEER_NOT_E2E_MODE" 23 "OTA_SPD" 22 "OTA_TIMER_DOWNLOAD_FAILED" 21 "OTA_MAX_TIME" 20 "CUBIXAD_STEERSTREQ_NOTACTV" 19 "CUBIXAD_DRVSTREQ_NOTACTV" 18 "SFTYDRV_INTV" 17 "LSDC_ALIVE" 16 "CUBIXAD_ALIVE" 15 "IBC_MAB_NO_PRIO" 14 "IBC_NOT_RDY" 13 "IBC_ALIVE" 12 "LSDC_GEAR" 11 "LSDC_SPD" 10 "LSDC_ACCL" 9 "IBC_NOT_MAB_MOD" 8 "GOLDBOX_ALIVE" 7 "CUBIXAD_GEAR" 6 "CUBIXAD_SPD_TESTTRACK" 5 "DRVREQCHG" 4 "RDY_TIMER" 3 "SFTY_CDN_FAILED" 2 "ACTVNCHK_SPD" 1 "ACTVNCHK_TIMR" 0 "NONE" ;
|
||||
VAL_ 9 MAB_SteerActReGroupSts 7 "Diag" 6 "Inactive" 5 "Ramping" 4 "Yellow" 3 "Red" 2 "Normal" 1 "Pending" 0 "Initialisation" ;
|
||||
VAL_ 1 HMI_Drvr_Req 9 "FCT_DEACTVN_REQ" 8 "FCT_ACTVN_OTA_CFMD" 7 "FCT_ACTVN_OTA_REQ" 6 "FCT_ACTVN_SAVETHESPOILER_CFMD" 5 "FCT_ACTVN_SAVETHESPOILER_REQ" 4 "FCT_ACTVN_LSDC_CFMD" 3 "FCT_ACTVN_LSDC_REQ" 2 "FCT_ACTVN_CUBIXAD_CFMD" 1 "FCT_ACTVN_CUBIXAD_REQ" 0 "FCT_ACTVN_NONE" ;
|
||||
VAL_ 3 Goldbox_SteerReCtrlReqSts 7 "CtrlSts3b_RESERVED_4" 6 "CtrlSts3b_RESERVED_3" 5 "CtrlSts3b_RESERVED_2" 4 "CtrlSts3b_RESERVED_1" 3 "CtrlSts3b_ERROR" 2 "CtrlSts3b_CONTROL_REQUESTED" 1 "CtrlSts3b_CONTROL_NOT_REQUESTED" 0 "CtrlSts3b_INIT" ;
|
||||
VAL_ 8 Goldbox_DriveStateReq 3 "ACTIVE" 2 "READY" 1 "RESERVED" 0 "NOT_ACTIVE" ;
|
||||
VAL_ 8 Goldbox_SteerStateReq 3 "ACTIVE" 2 "READY" 1 "RESERVED" 0 "NOT_ACTIVE" ;
|
||||
VAL_ 8 Goldbox_SSM_Req 7 "HMS_TAKEOVER" 6 "RESERVED" 5 "RELESE_VIA_RAMP" 4 "DRIVEOFF" 3 "HOLD_STANDBY" 2 "PARK" 1 "HOLD" 0 "NO_REQUEST" ;
|
||||
|
||||
17
tests/component_tests/dbc_util/test_dbc_util_config_asc.toml
Normal file
17
tests/component_tests/dbc_util/test_dbc_util_config_asc.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_sim.sdv"
|
||||
Class = "CAN_Com_Sim"
|
||||
Source="asc_reader_test.asc"
|
||||
Target="asc_writer_test.asc"
|
||||
|
||||
16
tests/component_tests/dbc_util/test_dbc_util_config_rx.toml
Normal file
16
tests/component_tests/dbc_util/test_dbc_util_config_rx.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_sim.sdv"
|
||||
Class = "CAN_Com_Sim"
|
||||
Source="receiver_test.asc"
|
||||
|
||||
15
tests/component_tests/dbc_util/test_dbc_util_config_tx.toml
Normal file
15
tests/component_tests/dbc_util/test_dbc_util_config_tx.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_sim.sdv"
|
||||
Class = "CAN_Com_Sim"
|
||||
Target="transmitter_test.asc"
|
||||
53
tests/component_tests/logger/CMakeLists.txt
Normal file
53
tests/component_tests/logger/CMakeLists.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
project(LoggerTests)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Define target
|
||||
add_library(ComponentTest_Logger_Module SHARED "logger_test_service.h" "logger_test_service.cpp")
|
||||
target_link_options(ComponentTest_Logger_Module PRIVATE)
|
||||
target_include_directories(ComponentTest_Logger_Module PRIVATE ./include)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_Logger_Module Ws2_32 Winmm)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_Logger_Module)
|
||||
endif()
|
||||
set_target_properties(ComponentTest_Logger_Module PROPERTIES PREFIX "")
|
||||
set_target_properties(ComponentTest_Logger_Module PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Logger
|
||||
add_executable(ComponentTest_Logger
|
||||
"logger_test.cpp"
|
||||
)
|
||||
|
||||
target_include_directories(ComponentTest_Logger PRIVATE
|
||||
${GTEST_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(ComponentTest_Logger
|
||||
GTest::GTest
|
||||
#pthread
|
||||
#stdc++fs
|
||||
${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
||||
add_test(NAME ComponentTest_Logger COMMAND ComponentTest_Logger)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_Logger Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_Logger rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_Logger Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ComponentTest_Logger POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_Logger>" ${GTEST_ARGUMENTS}ComponentTest_Logger.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/test_logger_userconfig.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
|
||||
add_dependencies(ComponentTest_Logger_Module dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_Logger ComponentTest_Logger_Module)
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "ComponentTest_Logger_Module.sdv"
|
||||
Class = "LoggerTestService"
|
||||
60
tests/component_tests/logger/logger_test.cpp
Normal file
60
tests/component_tests/logger/logger_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../include/logger_test_helper.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <process.h>
|
||||
#elif defined __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(AppLoggerTest, CallbackMultiThread)
|
||||
{
|
||||
std::string prefix = "PA_LoggerTest_";
|
||||
|
||||
auto startCount = GetLoggerFilesCount(prefix);
|
||||
{
|
||||
SDV_LOG(sdv::core::ELogSeverity::warning, "Warning: trying to log before instantiation!");
|
||||
|
||||
sdv::app::CAppControl appcontrol;
|
||||
std::stringstream sstreamAppConfig;
|
||||
sstreamAppConfig << "[LogHandler]" << std::endl << "Tag=\"" << prefix << getpid() << "\"";
|
||||
bool bResult = appcontrol.Startup(sstreamAppConfig.str());
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
|
||||
SDV_LOG(sdv::core::ELogSeverity::warning, "Warning: trying to log before initialization!");
|
||||
|
||||
std::cout << "Logger test: Initialize Log" << std::endl;
|
||||
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_logger_userconfig.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
appcontrol.SetRunningMode();
|
||||
}
|
||||
|
||||
auto endCount = GetLoggerFilesCount(prefix);
|
||||
#if defined(_WIN32)
|
||||
EXPECT_TRUE(endCount > startCount);
|
||||
#else
|
||||
// just avoid unused variable warning
|
||||
std::cout << "start:" << std::to_string(startCount) << " end:" << std::to_string(endCount) << std::endl;
|
||||
#endif
|
||||
}
|
||||
11
tests/component_tests/logger/logger_test_service.cpp
Normal file
11
tests/component_tests/logger/logger_test_service.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "logger_test_service.h"
|
||||
|
||||
CLoggerTestService::CLoggerTestService()
|
||||
{
|
||||
// auto test = sdv::core::GetObject("DataDispatchService");
|
||||
// auto foo = test.GetInterface<sdv::core::IDataDispatchService>();
|
||||
// foo->HasSignal(0);
|
||||
|
||||
SDV_LOG(sdv::core::ELogSeverity::info, "Info: Logging from Dummy test service via macro!");
|
||||
|
||||
}
|
||||
23
tests/component_tests/logger/logger_test_service.h
Normal file
23
tests/component_tests/logger/logger_test_service.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef VAPI_DUMMY_TEST_SERVICE_H
|
||||
#define VAPI_DUMMY_TEST_SERVICE_H
|
||||
|
||||
#include <support/component_impl.h>
|
||||
|
||||
/**
|
||||
* @brief Class to create a dummy test service.
|
||||
*/
|
||||
class CLoggerTestService
|
||||
: public sdv::CSdvObject
|
||||
{
|
||||
public:
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("LoggerTestService")
|
||||
|
||||
CLoggerTestService();
|
||||
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CLoggerTestService)
|
||||
|
||||
|
||||
#endif // !define VAPI_DUMMY_TEST_SERVICE_H
|
||||
77
tests/component_tests/repository/CMakeLists.txt
Normal file
77
tests/component_tests/repository/CMakeLists.txt
Normal file
@@ -0,0 +1,77 @@
|
||||
# Define project
|
||||
project(RepositoryTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Find the IDL compiler
|
||||
# REMARKS The compiler can only be found after it has build. Having both the compiler and the unittest project build, causes an
|
||||
# error during the scanning phase of CMake.
|
||||
#find_program(SDVIDL NAMES "sdv_idl_compiler" PATHS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/" NO_CACHE)
|
||||
set (SDVIDL "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/sdv_idl_compiler")
|
||||
message("Use IDL compiler: ${SDVIDL}")
|
||||
|
||||
# Compile the IDL
|
||||
add_custom_command(
|
||||
OUTPUT ${PROJECT_SOURCE_DIR}/generated/test_component.h
|
||||
DEPENDS sdv_idl_compiler
|
||||
MAIN_DEPENDENCY test_component.idl
|
||||
COMMENT "Build test_component.idl"
|
||||
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/test_component.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set_source_files_properties(test_component_ps.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
set_source_files_properties(test_component.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test_component.h)
|
||||
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(ComponentTest_Repository_ps SHARED
|
||||
"test_component_ps.cpp"
|
||||
)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(ComponentTest_Repository_ps PROPERTIES PREFIX "")
|
||||
set_target_properties(ComponentTest_Repository_ps PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# build module example for the test
|
||||
add_library(ComponentTest_Repository_test_module SHARED
|
||||
test_component.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(ComponentTest_Repository_test_module ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
set_target_properties(ComponentTest_Repository_test_module PROPERTIES PREFIX "")
|
||||
set_target_properties(ComponentTest_Repository_test_module PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Execute the installation helper utility to create an installation manifest for the core files.
|
||||
add_custom_target(ComponentTest_Repository_install_manifest
|
||||
# TODO EVE
|
||||
# COMMAND "$<TARGET_FILE:sdv_packager>" -O. --instance2005 -NComponentTest_Repository "$<TARGET_FILE:ComponentTest_Repository_test_module>" "$<TARGET_FILE:ComponentTest_Repository_ps>" "-I$<TARGET_FILE_DIR:ComponentTest_Repository_test_module>" --settings --create_configtest.toml --exclude_config_class"TestObject_CreateChain" --exclude_config_class"TestObject_CreateChainLock" --exclude_config_class"TestObject_CreateChainLockThread" --exclude_config_class"TestObject_CreateDuringShutdown" --exclude_config_class"TestObject_IObjectControlFail"
|
||||
COMMAND "$<TARGET_FILE:sdv_packager>" DIRECT_INSTALL ComponentTest_Repository --instance2005 "$<TARGET_FILE:ComponentTest_Repository_test_module>" "$<TARGET_FILE:ComponentTest_Repository_ps>" "-I$<TARGET_FILE_DIR:ComponentTest_Repository_test_module>" --overwrite --user_config
|
||||
DEPENDS ComponentTest_Repository_test_module ComponentTest_Repository_ps
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
# Define target
|
||||
add_executable(ComponentTest_Repository
|
||||
"repository_test.cpp"
|
||||
"isolation_test.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(ComponentTest_Repository ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the test
|
||||
add_test(NAME ComponentTest_Repository COMMAND ComponentTest_Repository WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_Repository POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_Repository>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_Repository.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_Repository_test_module install_manifest)
|
||||
add_dependencies(ComponentTest_Repository_test_module dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_Repository dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_Repository_ps dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_Repository ComponentTest_Repository_test_module)
|
||||
add_dependencies(ComponentTest_Repository ComponentTest_Repository_ps)
|
||||
add_dependencies(ComponentTest_Repository ComponentTest_Repository_install_manifest)
|
||||
135
tests/component_tests/repository/isolation_test.cpp
Normal file
135
tests/component_tests/repository/isolation_test.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/sdv_core.h>
|
||||
#include <interfaces/app.h>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Automatically configure and start the system to do tests on the test component.
|
||||
*/
|
||||
class CIsolatedComponentTest : public ::testing::Test, public sdv::app::CAppControl
|
||||
{
|
||||
public:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestSuite() {}
|
||||
|
||||
/**
|
||||
* @brief Setup test case
|
||||
*/
|
||||
virtual void SetUp()
|
||||
{
|
||||
bool bRet = Startup(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
)code");
|
||||
|
||||
if (!bRet)
|
||||
std::cout << "Failed to start the application for instance 1234." << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tear down test case
|
||||
*/
|
||||
virtual void TearDown()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST_F(CIsolatedComponentTest, DISABLED_LoadNonIsolatedSystemService)
|
||||
{
|
||||
// Load the hello system service
|
||||
IHello* pHello = sdv::core::GetObject<IHello>("TestObject_SystemHelloService");
|
||||
ASSERT_NE(pHello, nullptr);
|
||||
|
||||
EXPECT_EQ(pHello->SayHello(), "Hello from system service");
|
||||
sdv::process::TProcessID tPID = pHello->GetPID();
|
||||
EXPECT_NE(tPID, 0u);
|
||||
EXPECT_EQ(tPID, GetProcessID()); // Runs in main process
|
||||
}
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST_F(CIsolatedComponentTest, DISABLED_LoadNonIsolatedDevice)
|
||||
{
|
||||
// Load the hello device
|
||||
IHello* pHello = sdv::core::GetObject<IHello>("TestObject_HelloDevice");
|
||||
ASSERT_NE(pHello, nullptr);
|
||||
|
||||
EXPECT_EQ(pHello->SayHello(), "Hello from device");
|
||||
sdv::process::TProcessID tPID = pHello->GetPID();
|
||||
EXPECT_NE(tPID, 0u);
|
||||
EXPECT_EQ(tPID, GetProcessID()); // Runs in main process
|
||||
}
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST_F(CIsolatedComponentTest, DISABLED_LoadNonIsolatedBasicService)
|
||||
{
|
||||
// Load the hello basic service
|
||||
IHello* pHello = sdv::core::GetObject<IHello>("TestObject_BasicHelloService");
|
||||
ASSERT_NE(pHello, nullptr);
|
||||
|
||||
EXPECT_EQ(pHello->SayHello(), "Hello from basic service");
|
||||
sdv::process::TProcessID tPID = pHello->GetPID();
|
||||
EXPECT_NE(tPID, 0u);
|
||||
EXPECT_EQ(tPID, GetProcessID()); // Runs in main process
|
||||
}
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST_F(CIsolatedComponentTest, DISABLED_LoadIsolatedComplexService)
|
||||
{
|
||||
// Load the hello basic service
|
||||
IHello* pHello = sdv::core::GetObject<IHello>("TestObject_ComplexHelloService");
|
||||
ASSERT_NE(pHello, nullptr);
|
||||
|
||||
EXPECT_EQ(pHello->SayHello(), "Hello from complex service");
|
||||
sdv::process::TProcessID tPID = pHello->GetPID();
|
||||
EXPECT_NE(tPID, 0u);
|
||||
EXPECT_NE(tPID, GetProcessID()); // Runs in isolated process
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
TEST the following:
|
||||
|
||||
- Main app crashes or ends... iso app also ends
|
||||
- Iso app crashes/ends, object in main app will be removed
|
||||
- iso and exetrnal apps are not allowed to create objects in main app
|
||||
- dependencies
|
||||
- on startup create objects the object is dependent on first
|
||||
- on shutdown shutdown dependent objects first
|
||||
|
||||
// TODO EVE
|
||||
// The following issues are still present:
|
||||
// Lifetime of remote object
|
||||
// Lifetime of iso process
|
||||
// Print information during verbose
|
||||
// Test when error occurs
|
||||
// Utilities during startup and when running (currently disabled: see CreateUtility)
|
||||
// Enabling the automatic test execution and compilation of repo tests: see CMakeLists in ComponentTest_Repository
|
||||
|
||||
|
||||
|
||||
*/
|
||||
646
tests/component_tests/repository/repository_test.cpp
Normal file
646
tests/component_tests/repository/repository_test.cpp
Normal file
@@ -0,0 +1,646 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <interfaces/repository.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../include/basic_test_helper.h"
|
||||
#include "generated/test_component.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
const uint32_t LoopCount = 100; //< amount of loops used for concurrency tests. more loops means more thorough deadlock check at the cost of increased runtime
|
||||
|
||||
// used to supply external objects for testing pruposes. Implements IObjectControl to make sure this is NOT called for externally supplied objects
|
||||
class TestExternalObject : public sdv::IInterfaceAccess, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
FAIL() << "Error: Initialize should not be called by Repo Service!";
|
||||
// m_eObjectStatus = sdv::EObjectStatus::initialization_failure;
|
||||
}
|
||||
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Shutdown()
|
||||
{
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
TEST(RepositoryTest, LoadNonexistentModule)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
EXPECT_FALSE(pModuleControl->Load((GetExecDirectory() / "TestFooBar.sdv").generic_u8string()));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, CreateNonexistantClass)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
EXPECT_FALSE(pRepositoryControl->CreateObject("TestFooBar", nullptr, nullptr));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, GetNonexistantObject)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("Example_Object", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("TestFooBar"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateAndGet)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("Example_Object", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("Example_Object"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("Example_Object"));
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateInitFail)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_IObjectControlFail", nullptr, nullptr);
|
||||
EXPECT_FALSE(bRes);
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("TestObject_IObjectControlFail"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateCreateObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
// Instantiating the same object twice is allowed (only one instance will be created).
|
||||
EXPECT_TRUE(pRepositoryControl->CreateObject("Example_Object", nullptr, nullptr));
|
||||
EXPECT_TRUE(pRepositoryControl->CreateObject("Example_Object", nullptr, nullptr));
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("Example_Object"));
|
||||
|
||||
// Instantiating a different object with the same name as the previous object is not allowed.
|
||||
EXPECT_FALSE(pRepositoryControl->CreateObject("Example_Object_2", "Example_Object", nullptr));
|
||||
|
||||
// Instantiating a different object with a completely different name is allowed
|
||||
EXPECT_TRUE(pRepositoryControl->CreateObject("Example_Object_2", "abracadabra", nullptr));
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("abracadabra"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateExternalObjectName)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
sdv::core::IRegisterForeignObject* pExternalObject = sdv::core::GetObject<sdv::core::IRegisterForeignObject>("RepositoryService");
|
||||
ASSERT_TRUE(pExternalObject);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
//no two objects of same name allowed! Second Register fails, Get returns instance of first Register
|
||||
TestExternalObject testObj1;
|
||||
EXPECT_TRUE(pExternalObject->RegisterObject(&testObj1, "Example_Object"));
|
||||
TestExternalObject testObj2;
|
||||
EXPECT_FALSE(pExternalObject->RegisterObject(&testObj2, "Example_Object"));
|
||||
EXPECT_EQ(&testObj1, pObjectAccess->GetObject("Example_Object"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuplicateObjectNameMixed)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
sdv::core::IRegisterForeignObject* pExternalObject = sdv::core::GetObject<sdv::core::IRegisterForeignObject>("RepositoryService");
|
||||
ASSERT_TRUE(pExternalObject);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
//no two objects of same name allowed! Register fails, Get returns instance previously created
|
||||
bool bRes = pRepositoryControl->CreateObject("Example_Object", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
|
||||
TestExternalObject testObj2;
|
||||
EXPECT_FALSE(pExternalObject->RegisterObject(&testObj2, "Example_Object"));
|
||||
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("Example_Object"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateTwoNamedInstances)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes1 = pRepositoryControl->CreateObject("Example_Object", "Obj_1", nullptr);
|
||||
EXPECT_TRUE(bRes1);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("Obj_1"));
|
||||
|
||||
bool bRes2 = pRepositoryControl->CreateObject("Example_Object", "Obj_2", nullptr);
|
||||
EXPECT_TRUE(bRes2);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("Obj_2"));
|
||||
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("Example_Object"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("Obj_1"));
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("Obj_2"));
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, ChainCreateSimple)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", nullptr, "ChainedObject");
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("TestObject_CreateChain"));
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("ChainedObject"));
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("TestObject_CreateChain"));
|
||||
EXPECT_EQ(nullptr, pObjectAccess->GetObject("ChainedObject"));
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallel)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
std::thread testThread([pRepositoryControl, pObjectAccess]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", "Bar_" + count, "BarFoo_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("BarFoo_" + count));
|
||||
}
|
||||
});
|
||||
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", "Foo_" + count, "FooBar_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("FooBar_" + count));
|
||||
}
|
||||
|
||||
testThread.join();
|
||||
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallelLock)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("TestLockService", nullptr, nullptr);
|
||||
ASSERT_TRUE(bRes);
|
||||
auto pLock = sdv::core::GetObject("TestLockService").GetInterface<ITestLock>();
|
||||
|
||||
ASSERT_NE(pLock, nullptr);
|
||||
|
||||
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
|
||||
|
||||
std::thread testThread([&]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
//locks using TestLockService during construction
|
||||
bRes = pRepositoryControl->CreateObject("TestObject_CreateChainLock", "Bar_" + count, "BarFoo_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("BarFoo_" + count));
|
||||
}
|
||||
});
|
||||
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
pLock->Lock();
|
||||
bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", "Foo_" + count, "FooBar_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("FooBar_" + count));
|
||||
pLock->Unlock();
|
||||
}
|
||||
|
||||
testThread.join();
|
||||
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, ChainCreateParallelThreadLock)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("TestLockService", nullptr, nullptr);
|
||||
ASSERT_TRUE(bRes);
|
||||
auto pLock = sdv::core::GetObject("TestLockService").GetInterface<ITestLock>();
|
||||
|
||||
ASSERT_NE(pLock, nullptr);
|
||||
|
||||
//attempt to create deadlock by taking lock during initialize and by taking lock before call to create object
|
||||
|
||||
std::thread testThread([&]()
|
||||
{
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
//locks using TestLockService during construction in a seperate thread
|
||||
bRes = pRepositoryControl->CreateObject("TestObject_CreateChainLockThread", "Bar_" + count, "BarFoo_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("BarFoo_" + count));
|
||||
}
|
||||
});
|
||||
|
||||
for (uint32_t i = 0; i < LoopCount; ++i)
|
||||
{
|
||||
std::string count = std::to_string(i);
|
||||
pLock->Lock();
|
||||
bRes = pRepositoryControl->CreateObject("TestObject_CreateChain", "Foo_" + count, "FooBar_" + count);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, pObjectAccess->GetObject("FooBar_" + count));
|
||||
pLock->Unlock();
|
||||
}
|
||||
|
||||
testThread.join();
|
||||
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateDuringShutdown)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_TRUE(pModuleControl);
|
||||
auto pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_TRUE(pRepositoryControl);
|
||||
auto pObjectAccess = sdv::core::GetObject<sdv::core::IObjectAccess>("RepositoryService");
|
||||
ASSERT_TRUE(pObjectAccess);
|
||||
|
||||
ASSERT_TRUE(pModuleControl->Load((GetExecDirectory() / "ComponentTest_Repository_test_module.sdv").generic_u8string()));
|
||||
|
||||
//object creates new object during shutdown
|
||||
//this is needed in case new proxies are requested during shutdown
|
||||
|
||||
bool bRes = pRepositoryControl->CreateObject("TestObject_CreateDuringShutdown", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, CreateUtility)
|
||||
{
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
auto ptrUtility = sdv::core::CreateUtility("TOMLParserUtility");
|
||||
ASSERT_TRUE(ptrUtility);
|
||||
ptrUtility.Clear();
|
||||
ASSERT_FALSE(ptrUtility);
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST(RepositoryTest, DISABLED_MainApplication_GetInstalledAndLoadedComponent)
|
||||
{
|
||||
// Start the app control. The application automatically loads the installation manifests and the application configuration,
|
||||
// starting automatically the objects.
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
// The example object is part of the installation and should have automatically instantiated through the configuration.
|
||||
auto pInterfaceAccess = sdv::core::GetObject<sdv::IInterfaceAccess>("Example_Object_2");
|
||||
EXPECT_NE(pInterfaceAccess, nullptr);
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
// TODO EVE: Disabled until the implementation of configuration installation is finished. See
|
||||
// https://dev.azure.com/SW4ZF/AZP-431_DivDI_Vehicle_API/_workitems/edit/705891
|
||||
TEST(RepositoryTest, DISABLED_MainApplication_GetInstalledComponent)
|
||||
{
|
||||
// Start the app control. The application automatically loads the installation manifests, but since there is no application
|
||||
// configuration, it doesn't load the objects.
|
||||
sdv::app::CAppControl control(R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Main"
|
||||
Instance = 2005
|
||||
AppConfig = "" # override application config
|
||||
)code");
|
||||
ASSERT_TRUE(control.IsRunning());
|
||||
control.SetConfigMode();
|
||||
|
||||
// The example object is part of the installation and should have be automatically instantiated.
|
||||
auto pInterfaceAccess = sdv::core::GetObject<sdv::IInterfaceAccess>("Example_Object_2");
|
||||
EXPECT_NE(pInterfaceAccess, nullptr);
|
||||
|
||||
control.SetRunningMode();
|
||||
control.Shutdown();
|
||||
}
|
||||
|
||||
870
tests/component_tests/repository/test_component.cpp
Normal file
870
tests/component_tests/repository/test_component.cpp
Normal file
@@ -0,0 +1,870 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include "generated/test_component.h"
|
||||
|
||||
inline sdv::process::TProcessID GetProcessID()
|
||||
{
|
||||
static sdv::process::TProcessID tProcessID = 0;
|
||||
if (!tProcessID)
|
||||
{
|
||||
sdv::process::IProcessInfo* pProcessInfo = sdv::core::GetObject<sdv::process::IProcessInfo>("ProcessControlService");
|
||||
if (!pProcessInfo) return 0;
|
||||
tProcessID = pProcessInfo->GetProcessID();
|
||||
}
|
||||
return tProcessID;
|
||||
}
|
||||
|
||||
class CTestLockService : public sdv::CSdvObject, public ITestLock
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(ITestLock)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestLockService")
|
||||
|
||||
void Lock() override
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void Unlock() override
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_mutex;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestLockService)
|
||||
|
||||
/**
|
||||
* @brief Example component testing IObjectControl
|
||||
*/
|
||||
class CTestObjectControl
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
~CTestObjectControl()
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
|
||||
}
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("Example_Object")
|
||||
|
||||
/**
|
||||
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown method called before the object is destroyed.
|
||||
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
|
||||
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
|
||||
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
|
||||
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectControl)
|
||||
|
||||
/**
|
||||
* @brief Example component testing IObjectControl - 2nd component to test duplicate instantiation
|
||||
*/
|
||||
class CTestObjectControl2
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
~CTestObjectControl2()
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::destruction_pending);
|
||||
}
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("Example_Object_2")
|
||||
|
||||
/**
|
||||
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown method called before the object is destroyed.
|
||||
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
|
||||
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
|
||||
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
|
||||
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectControl2)
|
||||
|
||||
/**
|
||||
* @brief Example component testing IObjectControl
|
||||
*/
|
||||
class CTestObjectControlFail
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_IObjectControlFail")
|
||||
|
||||
/**
|
||||
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialization_failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown method called before the object is destroyed.
|
||||
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
|
||||
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
|
||||
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
|
||||
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectControlFail)
|
||||
|
||||
/**
|
||||
* @brief Example component testing chained object creation in Initialize
|
||||
*/
|
||||
class CTestObjectCreate
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_CreateChain")
|
||||
|
||||
/**
|
||||
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize( const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
//create new example object with name ssObjectConfig
|
||||
|
||||
auto pRepo = sdv::core::GetObject("RepositoryService");
|
||||
ASSERT_TRUE(pRepo);
|
||||
|
||||
auto pCreate = sdv::TInterfaceAccessPtr(pRepo).GetInterface<sdv::core::IRepositoryControl>();
|
||||
ASSERT_TRUE(pCreate);
|
||||
|
||||
ASSERT_FALSE(ssObjectConfig.empty());
|
||||
|
||||
ASSERT_TRUE(pCreate->CreateObject("Example_Object", ssObjectConfig,nullptr));
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown method called before the object is destroyed.
|
||||
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
|
||||
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
|
||||
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
|
||||
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectCreate)
|
||||
|
||||
/**
|
||||
* @brief Example component testing chained object creation in Initialize while holding a lock
|
||||
*/
|
||||
class CTestObjectCreateLock
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_CreateChainLock")
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize(const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
//create new example object with name ssObjectConfig while holding lock
|
||||
|
||||
auto pLock = sdv::core::GetObject<ITestLock>("TestLockService");
|
||||
ASSERT_NE(pLock,nullptr);
|
||||
|
||||
struct SAutoLock
|
||||
{
|
||||
SAutoLock(ITestLock* pLockParam) : m_pLockParam(pLockParam) { pLockParam->Lock(); }
|
||||
~SAutoLock() { m_pLockParam->Unlock(); }
|
||||
ITestLock* m_pLockParam = nullptr;
|
||||
} sAutoLock(pLock);
|
||||
|
||||
auto pRepo = sdv::core::GetObject("RepositoryService");
|
||||
ASSERT_TRUE(pRepo);
|
||||
|
||||
auto pCreate = sdv::TInterfaceAccessPtr(pRepo).GetInterface<sdv::core::IRepositoryControl>();
|
||||
ASSERT_TRUE(pCreate);
|
||||
|
||||
ASSERT_FALSE(ssObjectConfig.empty());
|
||||
|
||||
ASSERT_TRUE(pCreate->CreateObject("Example_Object", ssObjectConfig, nullptr));
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectCreateLock)
|
||||
|
||||
/**
|
||||
* @brief Example component testing chained object creation in Initialize in extra thread holding a lock
|
||||
*/
|
||||
class CTestObjectCreateLockThread
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_CreateChainLockThread")
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize(const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
auto fun = [ssObjectConfig]()
|
||||
{
|
||||
//create new example object with name ssObjectConfig while holding lock
|
||||
|
||||
auto pLock = sdv::core::GetObject<ITestLock>("TestLockService");
|
||||
ASSERT_NE(pLock, nullptr);
|
||||
|
||||
struct SAutoLock
|
||||
{
|
||||
SAutoLock(ITestLock* pLockParam) : m_pLockParam(pLockParam) { pLockParam->Lock(); }
|
||||
~SAutoLock() { m_pLockParam->Unlock(); }
|
||||
ITestLock* m_pLockParam = nullptr;
|
||||
} sAutoLock(pLock);
|
||||
|
||||
auto pRepo = sdv::core::GetObject("RepositoryService");
|
||||
ASSERT_TRUE(pRepo);
|
||||
|
||||
auto pCreate = sdv::TInterfaceAccessPtr(pRepo).GetInterface<sdv::core::IRepositoryControl>();
|
||||
ASSERT_TRUE(pCreate);
|
||||
|
||||
ASSERT_FALSE(ssObjectConfig.empty());
|
||||
|
||||
ASSERT_TRUE(pCreate->CreateObject("Example_Object", ssObjectConfig, nullptr));
|
||||
};
|
||||
|
||||
std::thread testThread(fun);
|
||||
|
||||
testThread.join();
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CTestObjectCreateLockThread)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Example component testing IObjectControl
|
||||
*/
|
||||
class CTestObjectCreateDuringShutdown
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_CreateDuringShutdown")
|
||||
|
||||
/**
|
||||
* @brief Initialize method. On success, a subsequent call to GetStatus returns EObjectStatus::running
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
EXPECT_EQ(m_eObjectStatus, sdv::EObjectStatus::initialization_pending);
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
virtual sdv::EObjectStatus GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown method called before the object is destroyed.
|
||||
* @attention Implement calls to other SDV objects here as this is no longer considered safe during the destructor of the object!
|
||||
* After a call to shutdown any threads/callbacks/etc that could call other SDV objects need to have been stopped.
|
||||
* The SDV object itself is to remain in a state where it can respond to calls to its interfaces as other objects may still call it during the shutdown sequence!
|
||||
* Any subsequent call to GetStatus should return EObjectStatus::destruction_pending
|
||||
*/
|
||||
virtual void Shutdown()
|
||||
{
|
||||
EXPECT_TRUE(m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized ||
|
||||
m_eObjectStatus == sdv::EObjectStatus::configuring);
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::running && m_eObjectStatus != sdv::EObjectStatus::initialized
|
||||
&& m_eObjectStatus != sdv::EObjectStatus::configuring)
|
||||
std::cout << "Object status = " << static_cast<uint32_t>(m_eObjectStatus) << " (expected initialized=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::initialized) << " or configuring=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::configuring) << " or running=" <<
|
||||
static_cast<uint32_t>(sdv::EObjectStatus::running) << ")." << std::endl;
|
||||
|
||||
//create new example object
|
||||
//this is allowed during shutdown as it's needed in case new proxies are created
|
||||
|
||||
auto pRepo = sdv::core::GetObject("RepositoryService");
|
||||
ASSERT_TRUE(pRepo);
|
||||
|
||||
auto pCreate = sdv::TInterfaceAccessPtr(pRepo).GetInterface<sdv::core::IRepositoryControl>();
|
||||
ASSERT_TRUE(pCreate);
|
||||
|
||||
ASSERT_FALSE(pCreate->CreateObject("Example_Object", nullptr, nullptr));
|
||||
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
private:
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending;
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CTestObjectCreateDuringShutdown)
|
||||
|
||||
/**
|
||||
* @brief Hello device
|
||||
*/
|
||||
class CHelloDevice : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_HelloDevice")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello() const override
|
||||
{
|
||||
return "Hello from device";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CHelloDevice)
|
||||
|
||||
/**
|
||||
* @brief Basic hello service
|
||||
*/
|
||||
class CBasicHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_BasicHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello() const override
|
||||
{
|
||||
return "Hello from basic service";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CBasicHelloService)
|
||||
|
||||
/**
|
||||
* @brief Complex hello service
|
||||
*/
|
||||
class CComplexHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
CComplexHelloService()
|
||||
{
|
||||
std::cout << "CComplexHelloService constructor" << std::endl;
|
||||
}
|
||||
~CComplexHelloService()
|
||||
{
|
||||
std::cout << "CComplexHelloService destructor" << std::endl;
|
||||
}
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_ComplexHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello() const override
|
||||
{
|
||||
return "Hello from complex service";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CComplexHelloService)
|
||||
|
||||
/**
|
||||
* @brief Hello utlity
|
||||
*/
|
||||
class CHelloUtility : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Utility)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_HelloUtility")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello() const override
|
||||
{
|
||||
return "Hello from utility";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CHelloUtility)
|
||||
|
||||
/**
|
||||
* @brief Hello utlity
|
||||
*/
|
||||
class CSystemHelloService : public sdv::CSdvObject, public IHello
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(IHello)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::SystemObject)
|
||||
DECLARE_OBJECT_CLASS_NAME("TestObject_SystemHelloService")
|
||||
|
||||
/**
|
||||
* @brief Say hello. Overload of IHello::SayHello.
|
||||
* @return The greetings string.
|
||||
*/
|
||||
virtual sdv::u8string SayHello() const override
|
||||
{
|
||||
return "Hello from system service";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in... Overload of IHello::GetPID.
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const
|
||||
{
|
||||
return GetProcessID();
|
||||
}
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CSystemHelloService)
|
||||
35
tests/component_tests/repository/test_component.idl
Normal file
35
tests/component_tests/repository/test_component.idl
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <interfaces/core.idl>
|
||||
#include <interfaces/process.idl>
|
||||
|
||||
/**
|
||||
* @brief Example interface
|
||||
*/
|
||||
interface ITestLock
|
||||
{
|
||||
/**
|
||||
* @brief Lock Mutex
|
||||
*/
|
||||
void Lock();
|
||||
|
||||
/**
|
||||
* @brief Unlock Mutex
|
||||
*/
|
||||
void Unlock();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hello interface
|
||||
*/
|
||||
interface IHello
|
||||
{
|
||||
/**
|
||||
* @brief Say hello
|
||||
* @return The greetings string.
|
||||
*/
|
||||
u8string SayHello() const;
|
||||
|
||||
/**
|
||||
* @brief Get the PID of the process the component is running in...
|
||||
*/
|
||||
sdv::process::TProcessID GetPID() const;
|
||||
};
|
||||
1
tests/component_tests/repository/test_component_ps.cpp
Normal file
1
tests/component_tests/repository/test_component_ps.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "generated/ps/proxystub.cpp"
|
||||
60
tests/component_tests/task_timer/CMakeLists.txt
Normal file
60
tests/component_tests/task_timer/CMakeLists.txt
Normal file
@@ -0,0 +1,60 @@
|
||||
# Define project (multiple EXEs)
|
||||
project(TaskTimerTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# TaskTimer executable
|
||||
add_executable(ComponentTest_TaskTimer
|
||||
task_timer_test.cpp
|
||||
)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(ComponentTest_TaskTimer GTest::GTest ${CMAKE_THREAD_LIBS_INIT} stdc++fs)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_TaskTimer Winmm Ws2_32 Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_TaskTimer rt ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_TaskTimer GTest::GTest Winmm Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the tasktimer unittest
|
||||
add_test(NAME ComponentTest_TaskTimer COMMAND ComponentTest_TaskTimer)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_TaskTimer POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_TaskTimer>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_TaskTimer.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# SimulationTaskTimer executable
|
||||
add_executable(ComponentTest_Simulation_TaskTimer
|
||||
task_simulation_timer_test.cpp
|
||||
)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(ComponentTest_Simulation_TaskTimer GTest::GTest ${CMAKE_THREAD_LIBS_INIT} stdc++fs)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_Simulation_TaskTimer Winmm Ws2_32 Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_Simulation_TaskTimer rt ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_Simulation_TaskTimer GTest::GTest Winmm Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the tasktimer unittest
|
||||
add_test(NAME ComponentTest_Simulation_TaskTimer COMMAND ComponentTest_Simulation_TaskTimer)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_Simulation_TaskTimer POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_Simulation_TaskTimer>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_Simulation_TaskTimer.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
||||
# copy the configuration to output folder 'config'
|
||||
# and build dependencies
|
||||
add_dependencies(ComponentTest_TaskTimer dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_TaskTimer task_timer)
|
||||
add_dependencies(ComponentTest_Simulation_TaskTimer dependency_sdv_components)
|
||||
add_dependencies(ComponentTest_Simulation_TaskTimer simulation_task_timer)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_tt_config.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/test_simulation_tt_config.toml DESTINATION ${CMAKE_BINARY_DIR}/tests/bin/config/)
|
||||
404
tests/component_tests/task_timer/task_simulation_timer_test.cpp
Normal file
404
tests/component_tests/task_timer/task_simulation_timer_test.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <support/timer.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
//test object which counts how many times the cb has been called
|
||||
class CTestTask : public sdv::core::ITaskExecute, public sdv::IInterfaceAccess
|
||||
{
|
||||
public:
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IInterfaceAccess)
|
||||
SDV_INTERFACE_ENTRY(sdv::core::ITaskExecute)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
std::atomic_bool m_bEnabled = true;
|
||||
void Enable(bool bEnable) { m_bEnabled = bEnable; }
|
||||
|
||||
virtual void Execute() override
|
||||
{
|
||||
if (!m_bEnabled) return;
|
||||
counter++;
|
||||
}
|
||||
|
||||
uint32_t counter = 0;
|
||||
};
|
||||
|
||||
TEST(TaskSimulationTimerTest, Initialization)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
sdv::TInterfaceAccessPtr ptrDispatchService = sdv::core::GetObject("SimulationTaskTimerService");
|
||||
sdv::core::ITaskTimer* pTimerSvc = ptrDispatchService.GetInterface<sdv::core::ITaskTimer>();
|
||||
EXPECT_NE(pTimerSvc, nullptr);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskSimulationTimerTest, BasicCounterTestInterface)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task;
|
||||
|
||||
sdv::core::CTaskTimer timer(3, &task);
|
||||
EXPECT_TRUE(timer);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected = 5;
|
||||
uint32_t expectedAdditional = 11;
|
||||
uint32_t loop = expected;
|
||||
|
||||
while (loop > 0) // 5 x 3 steps = 15 steps ==> 5 executions
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
EXPECT_EQ(expected, task.counter);
|
||||
|
||||
loop = expected;
|
||||
while (loop > 0) // 5 * 7 steps = 35 steps ==> 11 executions, 2 rest
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
EXPECT_EQ(expected + expectedAdditional, task.counter);
|
||||
|
||||
pTimerSimulationStep->SimulationStep(1000); // one more step, one more execution
|
||||
EXPECT_EQ(expected + expectedAdditional + 1, task.counter);
|
||||
|
||||
timer.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskSimulationTimerTest, LargerTaskPeriodTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task150;
|
||||
CTestTask task1150;
|
||||
CTestTask task3100;
|
||||
|
||||
sdv::core::CTaskTimer timer150(150, &task150);
|
||||
sdv::core::CTaskTimer timer1150(1150, &task1150);
|
||||
sdv::core::CTaskTimer timer3100(3100, &task3100);
|
||||
EXPECT_TRUE(timer150);
|
||||
EXPECT_TRUE(timer1150);
|
||||
EXPECT_TRUE(timer3100);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected150 = 33;
|
||||
uint32_t expected1150 = 4;
|
||||
uint32_t expected3100 = 1;
|
||||
uint32_t loop = 5000;
|
||||
while (loop > 0) // 5 x 3 steps = 15 steps ==> 5 executions
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected150, task150.counter);
|
||||
EXPECT_EQ(expected1150, task1150.counter);
|
||||
EXPECT_EQ(expected3100, task3100.counter);
|
||||
|
||||
loop = 7000;
|
||||
while (loop > 0)
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
EXPECT_EQ(expected150 + 47, task150.counter);
|
||||
EXPECT_EQ(expected1150 + 6, task1150.counter);
|
||||
EXPECT_EQ(expected3100 + 2, task3100.counter);
|
||||
|
||||
timer150.Reset();
|
||||
timer1150.Reset();
|
||||
timer3100.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
TEST(TaskSimulationTimerTest, MultipleTimerIdenticalTaskPeriodTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task1;
|
||||
CTestTask task2;
|
||||
CTestTask task3;
|
||||
|
||||
sdv::core::CTaskTimer timer1(3, &task1);
|
||||
sdv::core::CTaskTimer timer2(3, &task2);
|
||||
sdv::core::CTaskTimer timer3(3, &task3);
|
||||
EXPECT_TRUE(timer1);
|
||||
EXPECT_TRUE(timer2);
|
||||
EXPECT_TRUE(timer3);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected = 5;
|
||||
uint32_t expectedAdditional = 11;
|
||||
uint32_t loop = expected;
|
||||
|
||||
while (loop > 0) // 5 x 3 steps = 15 steps ==> 5 executions
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected, task1.counter);
|
||||
EXPECT_EQ(expected, task2.counter);
|
||||
EXPECT_EQ(expected, task3.counter);
|
||||
|
||||
loop = expected;
|
||||
while (loop > 0) // 5 * 7 steps = 35 steps ==> 11 executions, 2 rest
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
EXPECT_EQ(expected + expectedAdditional, task1.counter);
|
||||
EXPECT_EQ(expected + expectedAdditional, task2.counter);
|
||||
EXPECT_EQ(expected + expectedAdditional, task3.counter);
|
||||
|
||||
pTimerSimulationStep->SimulationStep(1000); // one more step, one more execution
|
||||
EXPECT_EQ(expected + expectedAdditional + 1, task1.counter);
|
||||
EXPECT_EQ(expected + expectedAdditional + 1, task2.counter);
|
||||
EXPECT_EQ(expected + expectedAdditional + 1, task3.counter);
|
||||
|
||||
timer1.Reset();
|
||||
timer2.Reset();
|
||||
timer3.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskSimulationTimerTest, MultipleTimerDifferentTaskPeriodTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task2;
|
||||
CTestTask task3;
|
||||
CTestTask task4;
|
||||
|
||||
sdv::core::CTaskTimer timer2(2, &task2);
|
||||
sdv::core::CTaskTimer timer3(3, &task3);
|
||||
sdv::core::CTaskTimer timer4(4, &task4);
|
||||
EXPECT_TRUE(timer2);
|
||||
EXPECT_TRUE(timer3);
|
||||
EXPECT_TRUE(timer4);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected2 = 7;
|
||||
uint32_t expected3 = 5;
|
||||
uint32_t expected4 = 3;
|
||||
uint32_t expectedAdditional2 = 18;
|
||||
uint32_t expectedAdditional3 = 11;
|
||||
uint32_t expectedAdditional4 = 9;
|
||||
uint32_t loop = 5;
|
||||
|
||||
while (loop > 0) // 5 x 3 steps = 15 steps ==> 5 executions
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
|
||||
EXPECT_EQ(expected2, task2.counter);
|
||||
EXPECT_EQ(expected3, task3.counter);
|
||||
EXPECT_EQ(expected4, task4.counter);
|
||||
|
||||
loop = 5;
|
||||
while (loop > 0)
|
||||
{
|
||||
loop--;
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
EXPECT_EQ(expected2 + expectedAdditional2, task2.counter);
|
||||
EXPECT_EQ(expected3 + expectedAdditional3, task3.counter);
|
||||
EXPECT_EQ(expected4 + expectedAdditional4, task4.counter);
|
||||
|
||||
pTimerSimulationStep->SimulationStep(1000);
|
||||
EXPECT_EQ(expected2 + expectedAdditional2 + 0, task2.counter);
|
||||
EXPECT_EQ(expected3 + expectedAdditional3 + 1, task3.counter);
|
||||
EXPECT_EQ(expected4 + expectedAdditional4 + 0, task4.counter);
|
||||
|
||||
timer2.Reset();
|
||||
timer3.Reset();
|
||||
timer4.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
TEST(TaskSimulationTimerTest, MultipleTimerLargeSimulationStepTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task1;
|
||||
CTestTask task150;
|
||||
CTestTask task450;
|
||||
|
||||
sdv::core::CTaskTimer timer1(1, &task1);
|
||||
sdv::core::CTaskTimer timer150(150, &task150);
|
||||
sdv::core::CTaskTimer timer450(450, &task450);
|
||||
EXPECT_TRUE(timer1);
|
||||
EXPECT_TRUE(timer150);
|
||||
EXPECT_TRUE(timer450);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected1 = 480;
|
||||
uint32_t expected150 = 3;
|
||||
uint32_t expected450 = 1;
|
||||
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
pTimerSimulationStep->SimulationStep(80000);
|
||||
|
||||
EXPECT_EQ(expected1, task1.counter);
|
||||
EXPECT_EQ(expected150, task150.counter);
|
||||
EXPECT_EQ(expected450, task450.counter);
|
||||
|
||||
timer1.Reset();
|
||||
timer150.Reset();
|
||||
timer450.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskSimulationTimerTest, MultipleTimerLargeAndDifferentSimulationStepTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_simulation_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task1;
|
||||
CTestTask task150;
|
||||
CTestTask task450;
|
||||
|
||||
sdv::core::CTaskTimer timer1(1, &task1);
|
||||
sdv::core::CTaskTimer timer150(150, &task150);
|
||||
sdv::core::CTaskTimer timer450(450, &task450);
|
||||
EXPECT_TRUE(timer1);
|
||||
EXPECT_TRUE(timer150);
|
||||
EXPECT_TRUE(timer450);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
// Get the simulation task timer service.
|
||||
sdv::core::ITimerSimulationStep* pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
EXPECT_TRUE(pTimerSimulationStep);
|
||||
|
||||
uint32_t expected1 = 480;
|
||||
uint32_t expected150 = 3;
|
||||
uint32_t expected450 = 1;
|
||||
|
||||
pTimerSimulationStep->SimulationStep(67000);
|
||||
pTimerSimulationStep->SimulationStep(99000);
|
||||
pTimerSimulationStep->SimulationStep(72000);
|
||||
pTimerSimulationStep->SimulationStep(64000);
|
||||
pTimerSimulationStep->SimulationStep(85000);
|
||||
pTimerSimulationStep->SimulationStep(93000);
|
||||
|
||||
EXPECT_EQ(expected1, task1.counter);
|
||||
EXPECT_EQ(expected150, task150.counter);
|
||||
EXPECT_EQ(expected450, task450.counter);
|
||||
|
||||
timer1.Reset();
|
||||
timer150.Reset();
|
||||
timer450.Reset();
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
267
tests/component_tests/task_timer/task_timer_test.cpp
Normal file
267
tests/component_tests/task_timer/task_timer_test.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include <support/timer.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <support/app_control.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
static uint32_t TimeTolerance = 50; //tolerate a small delay for task execution
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
//test object which counts how many times the cb has been called
|
||||
class CTestTask : public sdv::core::ITaskExecute, public sdv::IInterfaceAccess
|
||||
{
|
||||
public:
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IInterfaceAccess)
|
||||
SDV_INTERFACE_ENTRY(sdv::core::ITaskExecute)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
std::atomic_bool m_bEnabled = true;
|
||||
void Enable(bool bEnable) { m_bEnabled = bEnable; }
|
||||
|
||||
virtual void Execute() override
|
||||
{
|
||||
if (!m_bEnabled) return;
|
||||
std::unique_lock<std::mutex> lock(mtxTimes);
|
||||
vecTimes.push_back(std::chrono::high_resolution_clock::now());
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
double CalcAvrgTime()
|
||||
{
|
||||
if (vecTimes.empty()) return 0.0;
|
||||
double dTotal = 0.0;
|
||||
for (size_t n = 1; n < vecTimes.size(); n++)
|
||||
dTotal += std::chrono::duration<double>(vecTimes[n] - vecTimes[n - 1]).count();
|
||||
return dTotal / static_cast<double>(vecTimes.size() - 1);
|
||||
}
|
||||
|
||||
std::atomic<uint64_t> counter = 0ull;
|
||||
std::mutex mtxTimes;
|
||||
std::vector<std::chrono::high_resolution_clock::time_point> vecTimes;
|
||||
};
|
||||
|
||||
TEST(TaskTimerTest, Initialization)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
sdv::TInterfaceAccessPtr ptrDispatchService = sdv::core::GetObject("TaskTimerService");
|
||||
sdv::core::ITaskTimer* pTimerSvc = ptrDispatchService.GetInterface<sdv::core::ITaskTimer>();
|
||||
EXPECT_NE(pTimerSvc, nullptr);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskTimerTest, BasicCounterTestInterface)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task;
|
||||
|
||||
sdv::core::CTaskTimer timer(100, &task);
|
||||
EXPECT_TRUE(timer);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
std::chrono::milliseconds sleepDuration (500 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
timer.Reset();
|
||||
|
||||
EXPECT_EQ(5ull, task.counter);
|
||||
|
||||
sleepDuration = std::chrono::milliseconds(20 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
EXPECT_EQ(5ull, task.counter);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskTimerTest, BasicCounterTestFunction)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task;
|
||||
|
||||
sdv::core::CTaskTimer timer(100, [&]() {task.Execute(); });
|
||||
EXPECT_TRUE(timer);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
std::chrono::milliseconds sleepDuration (500 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
timer.Reset();
|
||||
|
||||
EXPECT_EQ(5ull, task.counter);
|
||||
|
||||
sleepDuration = std::chrono::milliseconds(20 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
EXPECT_EQ(5ull, task.counter);
|
||||
|
||||
// 1ms buffer
|
||||
if (0.101 <= task.CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (0.101) > (task.CalcAvrgTime()), actual: " <<
|
||||
(0.101) << "vs" << task.CalcAvrgTime() << std::endl;
|
||||
//EXPECT_GT(0.101, task.CalcAvrgTime());
|
||||
if (0.099 >= task.CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (0.099) < (task.CalcAvrgTime()), actual: " <<
|
||||
(0.099) << "vs" << task.CalcAvrgTime() << std::endl;
|
||||
//EXPECT_LT(0.099, task.CalcAvrgTime());
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskTimerTest, LongPeriodTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task;
|
||||
|
||||
sdv::core::CTaskTimer timer(1500, &task);
|
||||
EXPECT_TRUE(timer);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
std::chrono::milliseconds sleepDuration (3000 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
timer.Reset();
|
||||
|
||||
EXPECT_EQ(2ull, task.counter);
|
||||
|
||||
// 1ms buffer
|
||||
if (1.501 <= task.CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (1.501) > (task.CalcAvrgTime()), actual: " <<
|
||||
(1.501) << "vs" << task.CalcAvrgTime() << std::endl;
|
||||
//EXPECT_GT(1.501, task.CalcAvrgTime());
|
||||
if (1.499 >= task.CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (1.499) < (task.CalcAvrgTime()), actual: " <<
|
||||
(1.499) << "vs" << task.CalcAvrgTime() << std::endl;
|
||||
//EXPECT_LT(1.499, task.CalcAvrgTime());
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskTimerTest, SpawnTaskTwice)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
CTestTask task;
|
||||
|
||||
sdv::core::CTaskTimer timer1(100, &task);
|
||||
sdv::core::CTaskTimer timer2(100, &task);
|
||||
EXPECT_TRUE(timer1);
|
||||
EXPECT_TRUE(timer2);
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
std::chrono::milliseconds sleepDuration (500 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
//shutdown both tasks here
|
||||
timer1.Reset();
|
||||
timer2.Reset();
|
||||
|
||||
//check for counter - expectation: twice the count
|
||||
EXPECT_EQ(10ull, task.counter);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(TaskTimerTest, MultiTaskTest)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
bool bResult = appcontrol.Startup("");
|
||||
EXPECT_TRUE(bResult);
|
||||
appcontrol.SetConfigMode();
|
||||
sdv::core::EConfigProcessResult eResult = appcontrol.LoadConfig("test_tt_config.toml");
|
||||
EXPECT_EQ(eResult, sdv::core::EConfigProcessResult::successful);
|
||||
|
||||
uint32_t rguiPeriods[] = { 100, 133, 150, 250, 333, 50, 73, 120, 10, 415, 115, 60, 5/*, 1*/ };
|
||||
const size_t nExtent = std::extent_v<decltype(rguiPeriods)>;
|
||||
CTestTask rgtask[nExtent];
|
||||
sdv::core::CTaskTimer rgtimer[nExtent];
|
||||
for (size_t n = 0; n < nExtent; n++)
|
||||
{
|
||||
rgtask[n].Enable(false);
|
||||
rgtimer[n] = sdv::core::CTaskTimer(rguiPeriods[n], rgtask + n);
|
||||
EXPECT_TRUE(rgtimer[n]);
|
||||
}
|
||||
appcontrol.SetRunningMode();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
for (size_t n = 0; n < std::extent_v<decltype(rguiPeriods)>; n++)
|
||||
{
|
||||
rgtask[n].Enable(true);
|
||||
}
|
||||
|
||||
std::chrono::milliseconds sleepDuration(1500 + TimeTolerance);
|
||||
std::this_thread::sleep_for(sleepDuration);
|
||||
|
||||
// NOTE: If running in a virtual environment, the constraints cannot be kept.
|
||||
for (size_t n = 0; n < nExtent; n++)
|
||||
{
|
||||
rgtimer[n].Reset();
|
||||
EXPECT_FALSE(rgtimer[n]);
|
||||
if (rgtask[n].counter < 1500 / rguiPeriods[n])
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (rgtask[n].counter) >= (1500 / (rguiPeriods[n]), actual: " << rgtask[n].counter << "vs" << (1500 / rguiPeriods[n]) << std::endl;
|
||||
//EXPECT_GE(rgtask[n].counter, 1500 / rguiPeriods[n]);
|
||||
|
||||
// 1ms buffer
|
||||
if ((static_cast<double>(rguiPeriods[n]) / 1000.0 + 0.001) <= rgtask[n].CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (static_cast<double>(rguiPeriods[n]) / 1000.0 + 0.001) > (rgtask[n].CalcAvrgTime()), actual: " <<
|
||||
(static_cast<double>(rguiPeriods[n]) / 1000.0 + 0.001) << "vs" << rgtask[n].CalcAvrgTime() << std::endl;
|
||||
//EXPECT_GT(static_cast<double>(rguiPeriods[n]) / 1000.0 + 0.001, rgtask[n].CalcAvrgTime());
|
||||
if ((static_cast<double>(rguiPeriods[n]) / 1000.0 - 0.001) >= rgtask[n].CalcAvrgTime())
|
||||
std::cout << __FILE__ << ":" << __LINE__ << ":" << "Warning" << std::endl <<
|
||||
"Expected: (static_cast<double>(rguiPeriods[n]) / 1000.0 - 0.001) < (rgtask[n].CalcAvrgTime()), actual: " <<
|
||||
(static_cast<double>(rguiPeriods[n]) / 1000.0 + 0.001) << "vs" << rgtask[n].CalcAvrgTime() << std::endl;
|
||||
//EXPECT_LT(static_cast<double>(rguiPeriods[n]) / 1000.0 - 0.001, rgtask[n].CalcAvrgTime());
|
||||
}
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "simulation_task_timer.sdv"
|
||||
Class = "SimulationTaskTimerService"
|
||||
|
||||
6
tests/component_tests/task_timer/test_tt_config.toml
Normal file
6
tests/component_tests/task_timer/test_tt_config.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
34
tests/component_tests/vss_util/CMakeLists.txt
Normal file
34
tests/component_tests/vss_util/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
# Define project
|
||||
project (VSSUtilTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/vss_multiple_names.csv DESTINATION ${CMAKE_BINARY_DIR}/bin/)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/vss_unique_names.csv DESTINATION ${CMAKE_BINARY_DIR}/bin/)
|
||||
|
||||
# VSS util component test executable
|
||||
add_executable(ComponentTest_VSSUtil vss_util_test.cpp)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
target_link_libraries(ComponentTest_VSSUtil ${CMAKE_THREAD_LIBS_INIT} GTest::GTest)
|
||||
if (WIN32)
|
||||
target_link_libraries(ComponentTest_VSSUtil Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(ComponentTest_VSSUtil ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(ComponentTest_VSSUtil GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the VSS utility component test
|
||||
add_test(NAME ComponentTest_VSSUtil COMMAND ComponentTest_VSSUtil WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET ComponentTest_VSSUtil POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ComponentTest_VSSUtil>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ComponentTest_VSSUtil.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ComponentTest_VSSUtil sdv_vss_util)
|
||||
|
||||
|
||||
18
tests/component_tests/vss_util/vss_multiple_names.csv
Normal file
18
tests/component_tests/vss_util/vss_multiple_names.csv
Normal file
@@ -0,0 +1,18 @@
|
||||
;Class name;Function name;Signal name;vss;Signal direction;type;DBC CAN name includes CAN message name
|
||||
;;;;;;;
|
||||
VD;SteeringWheel;SteeringWheelAngle_VD;angle_VD;Vehicle.ChassisVD.SteeringWheel.Angle;RX;float;CAN_Input.SteeringWheel
|
||||
VD;SteeringWheel;VehicleSpeed_VD;speed_VD;Vehicle.ChassisVD.SteeringWheel.Angle;RX;float;CAN_Input.Speed
|
||||
VD;SteeringWheel;VehicleDoor_VD;doorStatus_VD;Vehicle.ChassisVD.SteeringWheel.Angle;RX;uint8;CAN_Input.Door
|
||||
VD;SteeringWheel;VehicleWeight_VD;weight_VD;Vehicle.ChassisVD.SteeringWheel.Angle;RX;float;CAN_Input.Weight
|
||||
VD;VehicleChassisAxle;RearAxleAngle_VD;rearAngle_VD;Vehicle.ChassisVD.RearAxle.Row.Wheel;TX;float;CAN_Output.RearAngle
|
||||
VD;VehicleChassisAxle;ApplicationCounter_VD;liveCounter_VD;Vehicle.ChassisVD.RearAxle.Row.Wheel;TX;uint8;CAN_Output.IsActiveCounter
|
||||
VD;VehicleChassisAxle;VehicleFrontLight_VD;frontLightStatus_VD;Vehicle.ChassisVD.RearAxle.Row.Wheel;TX;boolean;CAN_Output.FrontLight
|
||||
VD;VehicleChassisAxle;VehicleBackLight_VD;backLightStatus_VD;Vehicle.ChassisVD.RearAxle.Row.Wheel;TX;boolean;CAN_Output.BackLight
|
||||
BS;SteeringWheel;SteeringWheelAngle_BS;angle_BS;Vehicle.ChassisBS.SteeringWheel.Angle;RX;float;Vehicle.ChassisVD.SteeringWheel.Angle
|
||||
BS;SteeringWheel;VehicleSpeed_BS;speed_BS;Vehicle.ChassisBS.SteeringWheel.Angle;RX;float;Vehicle.ChassisVD.SteeringWheel.Angle
|
||||
BS;SteeringWheel;VehicleDoor_BS;doorStatus_BS;Vehicle.ChassisBS.SteeringWheel.Angle;RX;uint8;Vehicle.ChassisVD.SteeringWheel.Angle
|
||||
BS;SteeringWheel;VehicleWeight_BS;weight_BS;Vehicle.ChassisBS.SteeringWheel.Angle;RX;float;Vehicle.ChassisVD.SteeringWheel.Angle
|
||||
BS;VehicleChassisAxle;RearAxleAngle_BS;rearAngle_BS;Vehicle.ChassisBS.RearAxle.Row.Wheel;TX;float;Vehicle.ChassisVD.RearAxle.Row.Wheel
|
||||
BS;VehicleChassisAxle;ApplicationCounter_BS;liveCounter_BS;Vehicle.ChassisBS.RearAxle.Row.Wheel;TX;uint8;Vehicle.ChassisVD.RearAxle.Row.Wheel
|
||||
BS;VehicleChassisAxle;VehicleFrontLight_BS;frontLightStatus_BS;Vehicle.ChassisBS.RearAxle.Row.Wheel;TX;boolean;Vehicle.ChassisVD.RearAxle.Row.Wheel
|
||||
BS;VehicleChassisAxle;VehicleBackLight_BS;backLightStatus_BS;Vehicle.ChassisBS.RearAxle.Row.Wheel;TX;boolean;Vehicle.ChassisVD.RearAxle.Row.Wheel
|
||||
|
10
tests/component_tests/vss_util/vss_unique_names.csv
Normal file
10
tests/component_tests/vss_util/vss_unique_names.csv
Normal file
@@ -0,0 +1,10 @@
|
||||
;Class name;Function name;Signal name;vss;Signal direction;type;DBC CAN name includes CAN message name
|
||||
;;;;;;;
|
||||
VD;SteeringWheel;SteeringWheelAngle_VD;angle_VD;Vehicle.ChassisVD.SteeringWheel.Angle;RX;float;CAN_Input.SteeringWheel
|
||||
VD;Vehicle;VehicleSpeed_VD;speed_VD;Vehicle.ChassisVD.Vehicle.Speed;RX;float;CAN_Input.Speed
|
||||
VD;VehicleChassisAxle;RearAxleAngle_VD;rearAngle_VD;Vehicle.ChassisVD.RearAxle.Row.Wheel;TX;float;CAN_Output.RearAngle
|
||||
VD;VehicleApplication;ApplicationCounter_VD;liveCounter_VD;Vehicle.SoftwareVD.Application.SystemCounter;TX;uint8;CAN_Output.IsActiveCounter
|
||||
BS;SteeringWheel;SteeringWheelAngle_BS;angle_BS;Vehicle.ChassisBS.SteeringWheel.Angle;RX;float;Vehicle.ChassisVD.SteeringWheel.Angle
|
||||
BS;Vehicle;VehicleSpeed_BS;speed_BS;Vehicle.ChassisBS.Vehicle.Speed;RX;float;Vehicle.ChassisVD.Vehicle.Speed
|
||||
BS;VehicleChassisAxle;RearAxleAngle_BS;rearAngle_BS;Vehicle.ChassisBS.RearAxle.Row.Wheel;TX;float;Vehicle.ChassisVD.RearAxle.Row.Wheel
|
||||
BS;VehicleApplication;ApplicationCounter_BS;liveCounter_BS;Vehicle.SoftwareBS.Application.SystemCounter;TX;uint8;Vehicle.SoftwareVD.Application.SystemCounter
|
||||
|
348
tests/component_tests/vss_util/vss_util_test.cpp
Normal file
348
tests/component_tests/vss_util/vss_util_test.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../global/exec_dir_helper.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
class VSSUtilTest : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
virtual void SetUp() override {}
|
||||
|
||||
virtual void TearDown() override {}
|
||||
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
std::cout << "SetUpTestCase()" << std::endl;
|
||||
|
||||
std::vector<std::string> subFolders = { "generated0", "generated1", "generated2" };
|
||||
for (auto subFolder : subFolders)
|
||||
{
|
||||
auto generatedPath = GetExecDirectory() / subFolder;
|
||||
try
|
||||
{
|
||||
if (std::filesystem::is_directory(generatedPath))
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(generatedPath))
|
||||
{
|
||||
std::filesystem::remove_all(entry.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "catch (const std::filesystem::filesystem_error& e)" << std::endl;
|
||||
std::cout << "Error removing directory: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TearDownTestSuite() {}
|
||||
};
|
||||
|
||||
|
||||
std::uintmax_t CountNumberOfFiles(const std::filesystem::path allFilesPath)
|
||||
{
|
||||
std::uintmax_t allFilesCount = 0;
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(allFilesPath))
|
||||
{
|
||||
if (std::filesystem::is_regular_file(entry.status()))
|
||||
{
|
||||
++allFilesCount;
|
||||
}
|
||||
}
|
||||
return allFilesCount;
|
||||
}
|
||||
|
||||
void DeleteExistingHeaderFiles(const std::filesystem::path allFilesPath)
|
||||
{
|
||||
std::string doNotDeleteSignalIdentifier = "signal_identifier.h";
|
||||
|
||||
if (std::filesystem::is_directory(allFilesPath))
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(allFilesPath))
|
||||
{
|
||||
if (entry.path().extension() == ".h")
|
||||
{
|
||||
if (entry.path().filename() != doNotDeleteSignalIdentifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove(entry.path());
|
||||
std::cout << "File deleted: " << entry.path().filename().string() << std::endl;
|
||||
} catch (const std::filesystem::filesystem_error&)
|
||||
{
|
||||
std::cout << "Failed to delete: " << entry.path().filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeletePSAndSerdesFolder(const std::filesystem::path allFilesPath)
|
||||
{
|
||||
auto psFolder = allFilesPath / "ps";
|
||||
auto serdesolder = allFilesPath / "serdes";
|
||||
if (std::filesystem::is_directory(psFolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(psFolder);
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "catch (const std::filesystem::filesystem_error& e)" << std::endl;
|
||||
std::cout << "Error removing directory: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
if (std::filesystem::is_directory(serdesolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(serdesolder);
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "catch (const std::filesystem::filesystem_error& e)" << std::endl;
|
||||
std::cout << "Error removing directory: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::path GetExportFolder(std::filesystem::path folder)
|
||||
{
|
||||
while (!folder.empty())
|
||||
{
|
||||
auto exportFolder = folder / "export";
|
||||
if (std::filesystem::is_directory(exportFolder))
|
||||
return exportFolder;
|
||||
folder = folder.parent_path();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build the command line by quoting all arguments. This is the one argument function.
|
||||
* @param[in] rssArg The argument to quote.
|
||||
* @return The quoted argument.
|
||||
*/
|
||||
inline std::string BuildCommandLine(const std::string& rssArg)
|
||||
{
|
||||
return std::string("\"") + rssArg + std::string("\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build the command line by quoting all arguments. This is the multiple argument function.
|
||||
* @tparam ...TArgs Argument types. Needs to be implicitly convertable to std::string.
|
||||
* @param[in] rssArg The one argument to quote.
|
||||
* @param[in] rgtArgs The other arguments to quote.
|
||||
* @return The command line with the quoted arguments.
|
||||
*/
|
||||
template <typename... TArgs>
|
||||
inline std::string BuildCommandLine(const std::string& rssArg, const TArgs&... rgtArgs)
|
||||
{
|
||||
return std::string("\"") + rssArg + std::string("\" ") + BuildCommandLine(rgtArgs...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Platform specific implementation for executing command having space in the command path and in the parameters.
|
||||
* @tparam ...TArgs
|
||||
* @param[in] rssCommand The command line string.
|
||||
* @param[in] rgtArgs List of string arguments.
|
||||
* @return The result of the application or -1 when the application could not be started.
|
||||
*/
|
||||
template <typename... TArgs>
|
||||
inline int ExecuteCommand(const std::string& rssCommand, const TArgs&... rgtArgs)
|
||||
{
|
||||
// Build the command line by quoting each argument.
|
||||
std::string ssFullCommand = BuildCommandLine(rssCommand, rgtArgs...);
|
||||
|
||||
// NOTE: The std::system command is a bit peculiar when dealing with spaces int he path name under Windows. Even though each
|
||||
// command line argument is quoted, the quotes are removed before the command line is supplied to CMD /C. To solve this issue
|
||||
// add additional quotes at the beginning and end of the complete command line: \"app arg1 arg2 arg3\". See also:
|
||||
// https://stackoverflow.com/questions/27975969/how-to-run-an-executable-with-spaces-using-stdsystem-on-windows
|
||||
// --> This seems to work with the std::system of MSVC, not not of MINGW!
|
||||
// --> For MINGW there is no solution... use platform specific solution is the advice.
|
||||
|
||||
#ifdef _WIN32
|
||||
STARTUPINFOA si{};
|
||||
PROCESS_INFORMATION pi{};
|
||||
si.cb = sizeof(si);
|
||||
|
||||
// Convert std::string to LPSTR
|
||||
LPSTR szCommand = const_cast<char*>(ssFullCommand.c_str());
|
||||
|
||||
// Start the child process
|
||||
if (!CreateProcessA(NULL, szCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
std::cerr << "CreateProcess failed (" << GetLastError() << ")." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait until child process exits
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
// Get the exit code
|
||||
int iRet = 0;
|
||||
GetExitCodeProcess(pi.hProcess, reinterpret_cast<DWORD*>(&iRet));
|
||||
|
||||
// Close process and thread handles
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
return iRet;
|
||||
#elif defined __unix__
|
||||
return std::system(ssFullCommand.c_str());
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
}
|
||||
|
||||
int CreateCode(const std::string& document, const std::string& subfolder, const bool bCreateComponents)
|
||||
{
|
||||
auto vssUtility = (GetExecDirectory() / "../../bin/sdv_vss_util").lexically_normal();
|
||||
auto documentPath = (GetExecDirectory() / "../../bin" / document).lexically_normal();
|
||||
auto outputFolder = (GetExecDirectory() / subfolder).lexically_normal();
|
||||
|
||||
// VSS_Sheet_Single.csv -O${VSSUTIL_OUTPUT_DIRECTORY}/generated/ --version1.0.0.2 --prefixdemo --enable_components
|
||||
if (bCreateComponents)
|
||||
{
|
||||
return ExecuteCommand(vssUtility.generic_string(), documentPath.generic_string(), std::string("-O") + outputFolder.generic_string(),
|
||||
std::string("--enable_components"), std::string("--prefixdemo"), std::string("--version1.2.3.4"), std::string("--silent"));//
|
||||
}
|
||||
|
||||
|
||||
return ExecuteCommand(vssUtility.generic_string(), documentPath.generic_string(), std::string("-O") + outputFolder.generic_string(),
|
||||
std::string("--prefixdemo"), std::string("--version1.2.3.4"), std::string("--silent"));
|
||||
}
|
||||
|
||||
int CompileIDLFiles(const std::filesystem::path allFilesPath)
|
||||
{
|
||||
bool noFilesFound = true;
|
||||
int result = 0;
|
||||
auto idlCompiler = GetExecDirectory() / "../../bin/sdv_idl_compiler";
|
||||
auto idlFiles = allFilesPath / "vss_files";
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(idlFiles))
|
||||
{
|
||||
if (!entry.is_regular_file() || entry.path().extension() != ".idl") continue;
|
||||
noFilesFound = false;
|
||||
|
||||
std::cout << "Call IDL Compiler for file " << entry.path().filename().string() << std::endl;
|
||||
|
||||
// C:/Data/out/build/x64-Debug/tests/bin/../../bin/sdv_idl_compiler "../tests/bin/generated2/vss_files/VSS_VehicleVehicleDrivetrainTransmissionIsParkLockEngaged_tx.idl"
|
||||
// -O../tests/bin/generated2/vss_files -I../tests/bin/generated2/vss_files -I../../../../export
|
||||
result += ExecuteCommand(idlCompiler.lexically_normal().generic_string(),
|
||||
(idlFiles.lexically_normal() / entry.path().filename()).generic_string(),
|
||||
std::string("-O") + idlFiles.lexically_normal().generic_string(),
|
||||
std::string("-I") + idlFiles.lexically_normal().generic_string(),
|
||||
std::string("-I") + GetExportFolder(allFilesPath).lexically_normal().generic_string());
|
||||
}
|
||||
if (noFilesFound)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TEST_F(VSSUtilTest, CreateCodeValidateGeneratedFilesUniqueSignalNamesNoComponents)
|
||||
{
|
||||
EXPECT_EQ(0, CreateCode("vss_unique_names.csv", "generated0", false));
|
||||
|
||||
// files created by VSS_DifferentVDandBSSingleSignals.csv
|
||||
// find expected IDL files and check number of files in folder 'generated0'
|
||||
std::filesystem::path allFilesPath = GetExecDirectory() / "generated0";
|
||||
std::filesystem::path vssFilePath = allFilesPath / "vss_files";
|
||||
std::filesystem::path signalIdentifierVDFilePath = vssFilePath / "signal_identifier.h";
|
||||
std::filesystem::path summaryVDFilePath = vssFilePath / "summary.txt";
|
||||
|
||||
EXPECT_TRUE(std::filesystem::exists(summaryVDFilePath));
|
||||
EXPECT_TRUE(std::filesystem::exists(signalIdentifierVDFilePath));
|
||||
|
||||
std::uintmax_t allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
|
||||
// 4 signals, but they are combined in the same vss definition so we have 1 rx and 1 tx
|
||||
uint32_t signals = 4; // 8 header files *.h + 0 cpp files *.cpp + 0 cmake files + 8 *.idl + 2 * identifier.h + 2 * summary.txt
|
||||
uint32_t expected = 2 * signals + 2;
|
||||
EXPECT_EQ(allFilesCount, expected);
|
||||
|
||||
auto result = CompileIDLFiles(allFilesPath);
|
||||
EXPECT_EQ(0, result);
|
||||
|
||||
DeletePSAndSerdesFolder(vssFilePath); // created by the idl compiler
|
||||
allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
EXPECT_EQ(allFilesCount, expected + (2 * signals)); // + compiled header files
|
||||
}
|
||||
|
||||
TEST_F(VSSUtilTest, ValidateGeneratedFilesUniqueSignalNames)
|
||||
{
|
||||
EXPECT_EQ(0, CreateCode("vss_unique_names.csv", "generated1", true));
|
||||
|
||||
// files created by VSS_DifferentVDandBSSingleSignals.csv
|
||||
// find expected IDL files and check number of files in folder 'generated1'
|
||||
std::filesystem::path allFilesPath = GetExecDirectory() / "generated1";
|
||||
std::filesystem::path vssFilePath = allFilesPath / "vss_files";
|
||||
std::filesystem::path signalIdentifierVDFilePath = vssFilePath / "signal_identifier.h";
|
||||
std::filesystem::path summaryVDFilePath = vssFilePath / "summary.txt";
|
||||
|
||||
EXPECT_TRUE(std::filesystem::exists(summaryVDFilePath));
|
||||
EXPECT_TRUE(std::filesystem::exists(signalIdentifierVDFilePath));
|
||||
|
||||
std::uintmax_t allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
|
||||
// 4 signals, but they are combined in the same vss definition so we have 1 rx and 1 tx
|
||||
uint32_t signals = 4; // 2 header files *.h + 2 cpp files *.cpp + 2 cmake files + 2 *.idl + 2 * identifier.h + 2 * summary.txt
|
||||
uint32_t expected = 2 * signals + 2 * signals + 2 *signals + (2 * signals) + 2;
|
||||
EXPECT_EQ(allFilesCount, expected);
|
||||
|
||||
auto result = CompileIDLFiles(allFilesPath);
|
||||
EXPECT_EQ(0, result);
|
||||
|
||||
DeletePSAndSerdesFolder(vssFilePath); // created by the idl compiler
|
||||
allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
EXPECT_EQ(allFilesCount, expected + (2 * signals)); // + compiled header files
|
||||
}
|
||||
|
||||
TEST_F(VSSUtilTest, ValidateGeneratedFilesCombinedSignalNames)
|
||||
{
|
||||
EXPECT_EQ(0, CreateCode("vss_multiple_names.csv", "generated2", true));
|
||||
|
||||
// files created by VSS_DifferentVDandBSMultipleSignals.csv
|
||||
// find expected IDL files and check number of files in folder 'generated2'
|
||||
std::filesystem::path allFilesPath = GetExecDirectory() / "generated2";
|
||||
std::filesystem::path vssFilePath = allFilesPath / "vss_files";
|
||||
std::filesystem::path signalIdentifierVDFilePath = vssFilePath / "signal_identifier.h";
|
||||
std::filesystem::path summaryVDFilePath = vssFilePath / "summary.txt";
|
||||
|
||||
EXPECT_TRUE(std::filesystem::exists(summaryVDFilePath));
|
||||
EXPECT_TRUE(std::filesystem::exists(signalIdentifierVDFilePath));
|
||||
|
||||
std::uintmax_t allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
|
||||
// 4 signals, but they are combined in the same vss definition so we have 1 rx and 1 tx
|
||||
uint32_t signals = 2; // 2 signals = 4 *.h + 4 *.cpp + 4 cmakelists + 4 *.idl + 2 * identifier.h + 2 * summary.txt
|
||||
uint32_t expected = (2 * signals) + (2 * signals) + (2 * signals) + (2 * signals) + 2;
|
||||
EXPECT_EQ(allFilesCount, expected);
|
||||
|
||||
EXPECT_EQ(0, CompileIDLFiles(allFilesPath));
|
||||
|
||||
DeletePSAndSerdesFolder(vssFilePath); // created by the idl compiler
|
||||
allFilesCount = CountNumberOfFiles(allFilesPath);
|
||||
EXPECT_EQ(allFilesCount, expected + (2 * signals));
|
||||
}
|
||||
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
return result;
|
||||
}
|
||||
45
tests/include/basic_test_helper.h
Normal file
45
tests/include/basic_test_helper.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "../../global/exec_dir_helper.h"
|
||||
#include <filesystem>
|
||||
|
||||
inline std::filesystem::path GetRootDirectory()
|
||||
{
|
||||
std::filesystem::path path = GetExecDirectory();
|
||||
std::filesystem::path root = path.root_path();
|
||||
// Check for three existing directories: sdv_services, export and tests. This is the root!
|
||||
do
|
||||
{
|
||||
if (!std::filesystem::exists(path / "sdv_services"))
|
||||
continue;
|
||||
if (!std::filesystem::exists(path / "export"))
|
||||
continue;
|
||||
if (!std::filesystem::exists(path / "tests"))
|
||||
continue;
|
||||
|
||||
// Root directory found
|
||||
break;
|
||||
} while ((path = path.parent_path()), path != root);
|
||||
;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
inline std::filesystem::path GetConfigFilePath(const std::filesystem::path& filename)
|
||||
{
|
||||
return GetExecDirectory() / "config" / filename;
|
||||
}
|
||||
|
||||
inline std::string GetConfigFile(const std::filesystem::path& filename)
|
||||
{
|
||||
std::filesystem::path configPath = GetConfigFilePath(filename);
|
||||
|
||||
std::ifstream inputStream(configPath);
|
||||
std::string configFileContent((std::istreambuf_iterator<char>(inputStream)), std::istreambuf_iterator<char>());
|
||||
|
||||
return configFileContent;
|
||||
}
|
||||
|
||||
inline std::string GetRepositoryServiceModulePath()
|
||||
{
|
||||
std::filesystem::path currentPath = GetExecDirectory() / "../../bin/repository_service.sdv";
|
||||
return currentPath.generic_u8string();
|
||||
}
|
||||
59
tests/include/gtest_custom.h
Normal file
59
tests/include/gtest_custom.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef GTEST_CUSTOM_H
|
||||
#define GTEST_CUSTOM_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4102)
|
||||
#endif
|
||||
|
||||
#define GTEST_HAS_EXCEPTIONS 1
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef countof
|
||||
/**
|
||||
* @brief Count the amount of elements in the array.
|
||||
* @tparam T Array base type.
|
||||
* @tparam N The amount of elements.
|
||||
* @return The amount of elements in the array.
|
||||
*/
|
||||
template <typename T, int N>
|
||||
constexpr int countof(T const (&)[N]) noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Equality test macro for container functions.
|
||||
*/
|
||||
#define EXPECT_ARREQ(val1, ...) { bool b = val1 == decltype(val1)({__VA_ARGS__}); EXPECT_TRUE(b); }
|
||||
|
||||
/**
|
||||
* @brief Unequality test macro for container functions.
|
||||
*/
|
||||
#define EXPECT_ARRNE(val1, ...) { bool b = val1 == decltype(val1)({__VA_ARGS__}); EXPECT_FALSE(b); }
|
||||
|
||||
/**
|
||||
* @brief Check for equality fo floating point values.
|
||||
*/
|
||||
#define EXPECT_FPEQ(val1, val2) EXPECT_TRUE(std::fabs(val1 - val2) < std::numeric_limits<decltype(val1)>::epsilon());
|
||||
|
||||
#include "simple_cpp_decomposer.h"
|
||||
|
||||
/**
|
||||
* @brief Compare CPP code for equality.
|
||||
*/
|
||||
#define EXPECT_CPPEQ(s1, s2) \
|
||||
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperCPPEQ, s1, s2)
|
||||
|
||||
/**
|
||||
* @brief Compare CPP code for inequality.
|
||||
*/
|
||||
#define EXPECT_CPPNE(s1, s2) \
|
||||
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperCPPNE, s1, s2)
|
||||
|
||||
|
||||
#endif // ! defined GTEST_CUSTOM_H
|
||||
112
tests/include/logger_test_helper.h
Normal file
112
tests/include/logger_test_helper.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "../../global/exec_dir_helper.h"
|
||||
|
||||
inline int GetLoggerFilesCount(const std::string& prefix)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
std::string path = GetExecDirectory().generic_string();
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path))
|
||||
{
|
||||
std::string filename = entry.path().filename().generic_string().c_str();
|
||||
if (filename.rfind(prefix, 0) == 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
inline void DeleteLoggerFile(const std::string& filename)
|
||||
{
|
||||
auto path = GetExecDirectory() / filename;
|
||||
try
|
||||
{
|
||||
std::filesystem::remove(path);
|
||||
} catch (const std::filesystem::filesystem_error&)
|
||||
{}
|
||||
}
|
||||
|
||||
inline uint32_t GetErrorCountFromLogFile(const std::string& filename)
|
||||
{
|
||||
uint32_t errorCount = 0;
|
||||
auto path = GetExecDirectory() / filename;
|
||||
std::ifstream infile(path);
|
||||
if (infile.is_open())
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(infile, line))
|
||||
{
|
||||
size_t foundStart = line.find("Error;");
|
||||
if (foundStart != std::string::npos)
|
||||
{
|
||||
std::cout << line << std::endl;
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCount != 0)
|
||||
{
|
||||
std::cout << "Checking " << filename << ", found: " << std::to_string(errorCount) << std::endl;
|
||||
}
|
||||
|
||||
return errorCount;
|
||||
}
|
||||
|
||||
inline bool FileNameStartsWith(const std::string& fileName, const std::string& startOfLogName)
|
||||
{
|
||||
if (!startOfLogName.empty())
|
||||
{
|
||||
if (fileName.rfind(startOfLogName, 0) != 0) // returns std::string::npos (i.e. not found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline uint32_t GetStringCountFromLogFiles(const std::string& startOfLogName, const std::string& subString)
|
||||
{
|
||||
uint32_t errorCount = 0;
|
||||
|
||||
auto path = GetExecDirectory();
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path))
|
||||
{
|
||||
if ((entry.path().extension() == ".log") &&
|
||||
(FileNameStartsWith(entry.path().filename().string(), startOfLogName)))
|
||||
{
|
||||
std::ifstream infile(entry.path());
|
||||
if (infile.is_open())
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(infile, line))
|
||||
{
|
||||
size_t foundStart = line.find(subString);
|
||||
if (foundStart != std::string::npos)
|
||||
{
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
infile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCount;
|
||||
}
|
||||
|
||||
inline uint32_t GetErrorCountFromLogFiles(const std::string& logName) { return GetStringCountFromLogFiles(logName, ";Error;"); }
|
||||
inline uint32_t GetWarningCountFromLogFiles(const std::string& logName) { return GetStringCountFromLogFiles(logName, "Warning;"); }
|
||||
inline uint32_t GetTraceCountFromLogFiles(const std::string& logName) { return GetStringCountFromLogFiles(logName, "Trace;"); }
|
||||
|
||||
|
||||
#else
|
||||
inline int GetLoggerFilesCount(const std::string& ) { return 0; }
|
||||
inline void DeleteLoggerFile(const std::string& ) { return; }
|
||||
inline uint32_t GetErrorCountFromLogFile(const std::string&) { return 0; }
|
||||
inline uint32_t GetErrorCountFromLogFiles(const std::string&) { return 0; }
|
||||
inline uint32_t GetWarningCountFromLogFiles(const std::string&) { return 0; }
|
||||
inline uint32_t GetTraceCountFromLogFiles(const std::string&) { return 0; }
|
||||
#endif
|
||||
96
tests/include/simple_cpp_decomposer.h
Normal file
96
tests/include/simple_cpp_decomposer.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef SIMPLE_CPP_DECOMPOSER_H
|
||||
#define SIMPLE_CPP_DECOMPOSER_H
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Decomposes C++ code into text chunks. Supports simple grammar.
|
||||
*/
|
||||
class CSimpleCppDecomposer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rssCppCode Reference to the source code to decompose.
|
||||
*/
|
||||
CSimpleCppDecomposer(const std::string& rssCppCode);
|
||||
|
||||
/**
|
||||
* @brief Get the list of decomposed source code chunks.
|
||||
* @return A reference to the list of source code chunks.
|
||||
*/
|
||||
const std::list<std::string>& GetDecomposedCode() const;
|
||||
|
||||
/**
|
||||
* @brief Compare with another decomposed code for equality.
|
||||
* @param[in] rdecompChunk Reference to the decomposed chunk of code to use for this comparison.
|
||||
* @return Returns 'true' when equal; 'false' when not.
|
||||
*/
|
||||
bool operator==(const CSimpleCppDecomposer& rdecompChunk) const;
|
||||
|
||||
/**
|
||||
* @brief Compare with another decomposed code for un-equality.
|
||||
* @param[in] rdecompChunk Reference to the decomposed chunk of code to use for this comparison.
|
||||
* @return Returns 'true' when not equal; 'false' when equal.
|
||||
*/
|
||||
bool operator!=(const CSimpleCppDecomposer& rdecompChunk) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Iterate through the source code collecting the source code chunks.
|
||||
*/
|
||||
void Process();
|
||||
|
||||
/**
|
||||
* @brief Skip whitespace
|
||||
*/
|
||||
void SkipWhitespace();
|
||||
|
||||
/**
|
||||
* @brief Skip the rest of the line.
|
||||
*/
|
||||
void SkipLine();
|
||||
|
||||
/**
|
||||
*@brief Skip C-comments.
|
||||
*/
|
||||
void SkipComment();
|
||||
|
||||
/**
|
||||
* @brief Process text and numbers
|
||||
*/
|
||||
void ProcessText();
|
||||
|
||||
/**
|
||||
* @brief Process strings
|
||||
*/
|
||||
void ProcessString();
|
||||
|
||||
/**
|
||||
* @brief Process symbols.
|
||||
*/
|
||||
void ProcessSymbol();
|
||||
|
||||
std::string m_ssCode; ///< Current position within the source code.
|
||||
size_t m_nPos = 0; ///< The current position.
|
||||
std::list<std::string> m_lstCode; ///< Decomposed code.
|
||||
bool m_bNewLine = true; ///< Set when a new line has occurred (ignoring any whitespace).
|
||||
};
|
||||
|
||||
namespace testing::internal
|
||||
{
|
||||
// Additional helpers for testing C++ code
|
||||
GTEST_API_ AssertionResult CmpHelperCPPEQ(const char* szLeftExpression, const char* szRightExpression,
|
||||
const char* szLeft, const char* szRight);
|
||||
GTEST_API_ AssertionResult CmpHelperCPPNE(const char* szLeftExpression, const char* szRightExpression,
|
||||
const char* szLeft, const char* szRight);
|
||||
GTEST_API_ AssertionResult CmpHelperCPPEQ(const char* szLeftExpression, const char* szRightExpression,
|
||||
const std::string& rssLeft, const std::string& rssRight);
|
||||
GTEST_API_ AssertionResult CmpHelperCPPNE(const char* szLeftExpression, const char* szRightExpression,
|
||||
const std::string& rssLeft, const std::string& rssRight);
|
||||
}
|
||||
|
||||
#include "simple_cpp_decomposer.inl"
|
||||
|
||||
#endif //! SIMPLE_CPP_DECOMPOSER_H
|
||||
241
tests/include/simple_cpp_decomposer.inl
Normal file
241
tests/include/simple_cpp_decomposer.inl
Normal file
@@ -0,0 +1,241 @@
|
||||
#ifndef SIMPLE_CPP_DECOMPOSER_INL
|
||||
#define SIMPLE_CPP_DECOMPOSER_INL
|
||||
|
||||
#ifndef SIMPLE_CPP_DECOMPOSER_H
|
||||
#error Do not include "simple_cpp_composer.inl" directly. Include "simple_cpp_composer.h" instead!
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace testing::internal
|
||||
{
|
||||
// Additional helpers for testing C++ code
|
||||
inline GTEST_API_ AssertionResult CmpHelperCPPEQ(const char* szLeftExpression, const char* szRightExpression,
|
||||
const char* szLeft, const char* szRight)
|
||||
{
|
||||
if (CSimpleCppDecomposer(szLeft) == CSimpleCppDecomposer(szRight))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(szLeftExpression, szRightExpression, PrintToString(szLeft), PrintToString(szRight), false);
|
||||
}
|
||||
inline GTEST_API_ AssertionResult CmpHelperCPPNE(const char* szLeftExpression, const char* szRightExpression,
|
||||
const char* szLeft, const char* szRight)
|
||||
{
|
||||
if (CSimpleCppDecomposer(szLeft) != CSimpleCppDecomposer(szRight))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(szLeftExpression, szRightExpression, PrintToString(szLeft), PrintToString(szRight), false);
|
||||
}
|
||||
inline GTEST_API_ AssertionResult CmpHelperCPPEQ(const char* szLeftExpression, const char* szRightExpression,
|
||||
const std::string& rssLeft, const std::string& rssRight)
|
||||
{
|
||||
if (CSimpleCppDecomposer(rssLeft) == CSimpleCppDecomposer(rssRight))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(szLeftExpression, szRightExpression, PrintToString(rssLeft), PrintToString(rssRight), false);
|
||||
}
|
||||
inline GTEST_API_ AssertionResult CmpHelperCPPNE(const char* szLeftExpression, const char* szRightExpression,
|
||||
const std::string& rssLeft, const std::string& rssRight)
|
||||
{
|
||||
if (CSimpleCppDecomposer(rssLeft) != CSimpleCppDecomposer(rssRight))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(szLeftExpression, szRightExpression, PrintToString(rssLeft), PrintToString(rssRight), false);
|
||||
}
|
||||
}
|
||||
|
||||
inline CSimpleCppDecomposer::CSimpleCppDecomposer(const std::string& rssCppCode) : m_ssCode(rssCppCode)
|
||||
{
|
||||
Process();
|
||||
}
|
||||
|
||||
inline const std::list<std::string>& CSimpleCppDecomposer::GetDecomposedCode() const
|
||||
{
|
||||
return m_lstCode;
|
||||
}
|
||||
|
||||
inline bool CSimpleCppDecomposer::operator==(const CSimpleCppDecomposer& rdecompChunk) const
|
||||
{
|
||||
return m_lstCode == rdecompChunk.GetDecomposedCode();
|
||||
}
|
||||
|
||||
inline bool CSimpleCppDecomposer::operator!=(const CSimpleCppDecomposer& rdecompChunk) const
|
||||
{
|
||||
return m_lstCode != rdecompChunk.GetDecomposedCode();
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::Process()
|
||||
{
|
||||
while (m_nPos < m_ssCode.size())
|
||||
{
|
||||
// First skip whitespace...
|
||||
SkipWhitespace();
|
||||
if (m_nPos >= m_ssCode.size()) break;
|
||||
|
||||
// Check for preproc directives... skip those
|
||||
if (m_ssCode[m_nPos] == '#')
|
||||
{
|
||||
SkipLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for comment
|
||||
if (m_ssCode[m_nPos] == '/' && (m_ssCode[m_nPos + 1] == '/' || m_ssCode[m_nPos + 1] == '*'))
|
||||
{
|
||||
SkipComment();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the current character represents an underscore a string or a number, it is a keyword, variable, prefix or a number.
|
||||
if (std::isalnum(m_ssCode[m_nPos]) || m_ssCode[m_nPos] == '_')
|
||||
{
|
||||
ProcessText();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the current character represents a quote (single or double), it is a string or a character.
|
||||
// NOTE: Cannot deal with raw strings
|
||||
if (m_ssCode[m_nPos] == '\"' || m_ssCode[m_nPos] == '\'')
|
||||
{
|
||||
ProcessString();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the current character is anything else, it represents a symbol.
|
||||
ProcessSymbol();
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::SkipWhitespace()
|
||||
{
|
||||
while (m_nPos < m_ssCode.size() && std::isspace(m_ssCode[m_nPos]))
|
||||
{
|
||||
// Skip concatinating lines (not setting the new line flag).
|
||||
if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 1] == '\r' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 3;
|
||||
continue;
|
||||
}
|
||||
else if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remember the new line
|
||||
if (m_ssCode[m_nPos] == '\n') m_bNewLine = true;
|
||||
|
||||
// Skip the whitespace
|
||||
m_nPos++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::SkipLine()
|
||||
{
|
||||
while (m_nPos < m_ssCode.size())
|
||||
{
|
||||
// Ignore the line ending with concatinating lines
|
||||
if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 1] == '\r' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 3;
|
||||
continue;
|
||||
}
|
||||
else if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Finished when a new line has been reached
|
||||
if (m_ssCode[m_nPos] == '\n')
|
||||
{
|
||||
m_nPos++; // Skip the newline
|
||||
m_bNewLine = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip the character
|
||||
m_nPos++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::SkipComment()
|
||||
{
|
||||
if (m_nPos >= m_ssCode.size()) return;
|
||||
if (m_ssCode[m_nPos] != '/') return;
|
||||
if (m_ssCode[m_nPos + 1] == '/') // C++ comment
|
||||
{
|
||||
SkipLine();
|
||||
return;
|
||||
}
|
||||
if (m_ssCode[m_nPos + 1] != '*') return;
|
||||
|
||||
// C comment
|
||||
m_nPos += 2;
|
||||
while (m_nPos < m_ssCode.size())
|
||||
{
|
||||
// End of comment
|
||||
if (m_ssCode[m_nPos] == '*' && m_ssCode[m_nPos + 1] == '/')
|
||||
{
|
||||
m_nPos += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Ignore the line ending with concatinating lines
|
||||
if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 1] == '\r' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 3;
|
||||
continue;
|
||||
}
|
||||
else if (m_ssCode[m_nPos] == '\\' && m_ssCode[m_nPos + 2] == '\n')
|
||||
{
|
||||
m_nPos += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Detect a new line
|
||||
if (m_ssCode[m_nPos] == '\n') m_bNewLine = true;
|
||||
|
||||
// Skip the character
|
||||
m_nPos++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::ProcessText()
|
||||
{
|
||||
m_bNewLine = false;
|
||||
size_t nStart = m_nPos;
|
||||
while (m_nPos < m_ssCode.size() && (std::isalnum(m_ssCode[m_nPos]) || m_ssCode[m_nPos] == '_'))
|
||||
m_nPos++;
|
||||
if (m_nPos == nStart) return;
|
||||
m_lstCode.push_back(m_ssCode.substr(nStart, m_nPos - nStart));
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::ProcessString()
|
||||
{
|
||||
m_bNewLine = false;
|
||||
size_t nStart = m_nPos;
|
||||
m_nPos++; // Skip quote
|
||||
while (m_nPos < m_ssCode.size() && m_ssCode[m_nPos] != '\"' && m_ssCode[m_nPos] == '\'') m_nPos++;
|
||||
if (m_nPos < m_ssCode.size()) m_nPos++; // Skip quote
|
||||
if (m_nPos == nStart) return;
|
||||
m_lstCode.push_back(m_ssCode.substr(nStart, m_nPos - nStart));
|
||||
}
|
||||
|
||||
inline void CSimpleCppDecomposer::ProcessSymbol()
|
||||
{
|
||||
m_bNewLine = false;
|
||||
if (m_nPos >= m_ssCode.size()) return;
|
||||
m_lstCode.push_back(std::string(1, m_ssCode[m_nPos]));
|
||||
m_nPos++; // Skip symbol
|
||||
}
|
||||
|
||||
#endif // !defined SIMPLE_CPP_DECOMPOSER_INL
|
||||
103
tests/include/test_watchdog.h
Normal file
103
tests/include/test_watchdog.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef TEST_WATCHDOG_H
|
||||
#define TEST_WATCHDOG_H
|
||||
|
||||
#include <thread>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#ifdef _WIN32
|
||||
// Prevent reassignment of "interface"
|
||||
#pragma push_macro("interface")
|
||||
#undef interface
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
// Include windows headers
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
// Use previous assignment of "interface"
|
||||
#pragma pop_macro("interface")
|
||||
|
||||
// Remove "GetObject" assignment
|
||||
#ifdef GetObject
|
||||
#undef GetObject
|
||||
#endif
|
||||
|
||||
// Remove "GetClassInfo" assignment
|
||||
#ifdef GetClassInfo
|
||||
#undef GetClassInfo
|
||||
#endif
|
||||
|
||||
#elif defined __unix__
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Test watchdog class; ends test process when runtime duration has superseded.
|
||||
*/
|
||||
class CProcessWatchdog
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] m_iWatchdogTimeS The duration the watchdog is monitoring before process termination in seconds (default 300s).
|
||||
*/
|
||||
CProcessWatchdog(int64_t iWatchdogTimeS = 300ll)
|
||||
{
|
||||
m_threadWatchdog = std::thread(&CProcessWatchdog::WatchdogThreadFunc, this, iWatchdogTimeS );
|
||||
}
|
||||
|
||||
/**
|
||||
* @breif Destructor; cancels the watch thread.
|
||||
*/
|
||||
~CProcessWatchdog()
|
||||
{
|
||||
m_bTerminateWatchdog = true;
|
||||
if (m_threadWatchdog.joinable())
|
||||
m_threadWatchdog.join();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Watch thread function.
|
||||
* @param[in] iWatchdogTimeS The duration the watchdog is monitoring before process termination in seconds (default 120s).
|
||||
*/
|
||||
void WatchdogThreadFunc(int64_t iWatchdogTimeS = 120ll)
|
||||
{
|
||||
// Run for the most the set time; then terminate...
|
||||
auto tpStart = std::chrono::steady_clock::now();
|
||||
while (!m_bTerminateWatchdog)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
auto tpNow = std::chrono::steady_clock::now();
|
||||
if (std::chrono::duration_cast<std::chrono::seconds>(tpNow - tpStart).count() > iWatchdogTimeS)
|
||||
{
|
||||
std::cerr << "ERROR PROCESS WATCHDOG: POTENTIAL DEADLOCK DETECTED - TERMINATION ENFORCED!!!" << std::endl;
|
||||
std::cerr.flush();
|
||||
#ifdef _WIN32
|
||||
// Get the current process handle
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
// Terminate the current process with exit code -100
|
||||
TerminateProcess(hProcess, static_cast<UINT>(-100));
|
||||
#elif defined __unix__
|
||||
|
||||
// Send SIGTERM signal to the current process
|
||||
kill(getpid(), SIGTERM);
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool m_bTerminateWatchdog = false; ///< When set, allows the thread to terminate.
|
||||
std::thread m_threadWatchdog; ///< The watchdog thread.
|
||||
};
|
||||
|
||||
#endif // !defined TEST_WATCHDOG_H
|
||||
40
tests/loop_test_runner_linux.sh
Normal file
40
tests/loop_test_runner_linux.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
################################## ATTENTION #################################
|
||||
# Shell Script to execute the tests on Linux #
|
||||
# Adjust the permission with: chmod +x loop_test_runner_linux.sh #
|
||||
# Run the script with: ./loop_test_runner_linux.sh <TestName> <NumberOfRuns> #
|
||||
# or: bash ./loop_test_runner_linux.sh <TestName> <NumberOfRuns> #
|
||||
##############################################################################
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the correct number of arguments is provided
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <TestName> <NumberOfRuns>"
|
||||
echo "Example: $0 UnitTest_SharedMemConnectTests 1000"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the test name and number of runs from command-line arguments
|
||||
TEST_NAME="$1"
|
||||
MAX_RUNS="$2"
|
||||
|
||||
# Build the full path to the test executable
|
||||
TARGET_TEST="../build/tests/bin/$TEST_NAME"
|
||||
|
||||
# Check if the test executable exists
|
||||
if [ -f "$TARGET_TEST" ]; then
|
||||
echo -e "\nStarting looped execution of $TARGET_TEST to catch intermittent failures..."
|
||||
|
||||
# Loop the test execution for the specified number of times
|
||||
for i in $(seq 1 $MAX_RUNS); do
|
||||
echo -e "\nRun #$i"
|
||||
$TARGET_TEST
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\nTest failed on run #$i"
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Target test $TARGET_TEST not found!"
|
||||
exit 1
|
||||
fi
|
||||
36
tests/loop_test_runner_windows.ps1
Normal file
36
tests/loop_test_runner_windows.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
PowerShell script to loop a specific test executable multiple times to catch intermittent failures.
|
||||
|
||||
.DESCRIPTION
|
||||
Usage: .\loop_test_runner.ps1 <TestName> <NumberOfRuns>
|
||||
Example: .\loop_test_runner.ps1 UnitTest_SharedMemConnectTests.exe 1000
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TestName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$NumberOfRuns
|
||||
)
|
||||
|
||||
# Build the full path to the test executable
|
||||
$TargetTest = Join-Path "..\build\tests\bin" $TestName
|
||||
|
||||
# Check if the test executable exists
|
||||
if (Test-Path $TargetTest) {
|
||||
Write-Host "`nStarting looped execution of $TargetTest to catch intermittent failures..." -ForegroundColor Cyan
|
||||
|
||||
for ($i = 1; $i -le $NumberOfRuns; $i++) {
|
||||
Write-Host "`nRun #$i" -ForegroundColor Yellow
|
||||
& $TargetTest
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "`nTest failed on run #$i" -ForegroundColor Red
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "Target test $TargetTest not found!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_silkit.sdv"
|
||||
Class = "CAN_Com_SilKit"
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "CAN1"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
|
||||
[[Component]]
|
||||
Path = "can_datalink.sdv"
|
||||
Class = "CAN_data_link"
|
||||
|
||||
55
tests/manual_tests/silkit_can_com_tests/CMakeLists.txt
Normal file
55
tests/manual_tests/silkit_can_com_tests/CMakeLists.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
# Only build on MSVC/Windows or 64-bit Linux (not ARM)
|
||||
if((WIN32 AND NOT MSVC) OR (UNIX AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64"))
|
||||
|
||||
project(ManualTestCanComSilKit)
|
||||
|
||||
FetchContent_MakeAvailable(SilKit)
|
||||
|
||||
set(SilKit_DIR "${silkit_SOURCE_DIR}/SilKit/lib/cmake/SilKit")
|
||||
|
||||
find_package(SilKit REQUIRED CONFIG)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_compile_options(-Wno-shadow)
|
||||
endif()
|
||||
|
||||
add_executable(ManualTest_CANComSilKit
|
||||
src/can_com_manual_test_silkit.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../sdv_services/can_communication_silkit/can_com_silkit.cpp
|
||||
)
|
||||
|
||||
add_executable(can_writer
|
||||
src/can_writer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../sdv_services/can_communication_silkit/can_com_silkit.cpp
|
||||
)
|
||||
|
||||
add_executable(can_reader
|
||||
src/can_reader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../sdv_services/can_communication_silkit/can_com_silkit.cpp
|
||||
)
|
||||
|
||||
# Copy the config files
|
||||
if(UNIX)
|
||||
file(COPY ${PROJECT_SOURCE_DIR}/run_silkit_util.sh DESTINATION ${CMAKE_BINARY_DIR}/tests/manual_tests/)
|
||||
elseif(WIN32)
|
||||
file(COPY ${PROJECT_SOURCE_DIR}/run_silkit_util.bat DESTINATION ${CMAKE_BINARY_DIR}/tests/manual_tests/)
|
||||
endif()
|
||||
|
||||
target_link_libraries(ManualTest_CANComSilKit ${CMAKE_DL_LIBS} GTest::GTest SilKit::SilKit)
|
||||
target_link_libraries(can_writer ${CMAKE_DL_LIBS} GTest::GTest SilKit::SilKit )
|
||||
target_link_libraries(can_reader ${CMAKE_DL_LIBS} GTest::GTest SilKit::SilKit)
|
||||
|
||||
add_test(NAME ManualTest_CANComSilKit COMMAND ManualTest_CANComSilKit)
|
||||
|
||||
# add_custom_command(TARGET ManualTest_CANComSilKit POST_BUILD
|
||||
# COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:ManualTest_CANComSilKit>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ManualTest_CANComSilKit.xml
|
||||
# VERBATIM
|
||||
# )
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ManualTest_CANComSilKit dependency_sdv_components can_com_silkit)
|
||||
add_dependencies(can_reader dependency_sdv_components can_com_silkit)
|
||||
add_dependencies(can_writer dependency_sdv_components can_com_silkit)
|
||||
|
||||
endif() # Only build on MSVC/Windows or 64-bit Linux (not ARM)
|
||||
|
||||
128
tests/manual_tests/silkit_can_com_tests/README.md
Normal file
128
tests/manual_tests/silkit_can_com_tests/README.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# SilKit CAN Communication Tests
|
||||
This guide provides instructions on how to execute the manual tests for the SilKit CAN communication system, including the `can_reader` and `can_writer` components.
|
||||
|
||||
## Prerequisites
|
||||
Before running the tests, ensure the following:
|
||||
|
||||
- Operating System: Ubuntu (or a Linux distribution with gnome-terminal installed) **or Windows**.
|
||||
- Dependencies:
|
||||
- `sil-kit-registry` and `sil-kit-system-controller` binaries are available in the directory: `<...>/vapi-cpp-vehicle-api-platform/build/<compiler_version>/_deps/silkit-src/SilKit/bin/`
|
||||
- gnome-terminal is installed on your system (Linux only).
|
||||
- Build: The project has been built successfully, and the binaries for can_reader and can_writer are available in the directory: `<...>/vapi-cpp-vehicle-api-platform/build/<compiler_version>/tests/bin/`
|
||||
|
||||
## Test Components
|
||||
The tests involve the following components:
|
||||
|
||||
- `sil-kit-registry`: Manages the SilKit network.
|
||||
- `sil-kit-system-controller`: Controls the lifecycle of SilKit participants.
|
||||
- `can_writer`: Sends CAN messages to the network.
|
||||
- `can_reader`: Receives CAN messages from the network.
|
||||
|
||||
## Instructions
|
||||
|
||||
### Linux
|
||||
1. **Start the SilKit Utilities**
|
||||
- Navigate to the directory containing the `run_silkit_util.sh` script:
|
||||
```bash
|
||||
cd <...>/vapi-cpp-vehicle-api-platform/build/<compiler_version>/tests/manual_tests/
|
||||
```
|
||||
|
||||
- Make the script executable (if not already):
|
||||
```bash
|
||||
chmod +x run_silkit_util.sh
|
||||
```
|
||||
- Run the script to start the SilKit utilities:
|
||||
```bash
|
||||
./run_silkit_util.sh
|
||||
```
|
||||
This will open two new terminal windows:
|
||||
- One running `sil-kit-registry`.
|
||||
- Another running `sil-kit-system-controller` with the arguments `can_reader can_writer`.
|
||||
|
||||
2. **Run the CAN Writer**
|
||||
In a new terminal, navigate to the directory containing the can_writer binary:
|
||||
```bash
|
||||
cd <...>/vapi-cpp-vehicle-api-platform/build/<compiler_version>/tests/bin/
|
||||
```
|
||||
|
||||
- Run the can_writer binary:
|
||||
```bash
|
||||
./can_writer
|
||||
```
|
||||
|
||||
The `can_writer` will send different CAN messages to the network. Each message will be logged in the terminal.
|
||||
|
||||
3. **Run the CAN Reader**
|
||||
In another terminal, navigate to the directory containing the can_reader binary:
|
||||
```bash
|
||||
cd <...>/vapi-cpp-vehicle-api-platform/build/<compiler_version>/tests/bin/
|
||||
```
|
||||
|
||||
- Run the `can_reader` binary:
|
||||
```bash
|
||||
./can_reader
|
||||
```
|
||||
|
||||
The `can_reader` will receive and log the CAN messages sent by the `can_writer`. Each message will be logged in the terminal.
|
||||
|
||||
### Windows
|
||||
1. **Start the SilKit Utilities**
|
||||
- Before running the executables, copy the `SilKit.dll` and `SilKitd.dll` DLLs from the SilKit source directory `<..>\_deps\silkit-src\SilKit\bin` to the `<..>\test\bin` directory.
|
||||
|
||||
- Open PowerShell or Command Prompt and navigate to the directory containing the `run_silkit_util.bat` script (if available):
|
||||
```bat
|
||||
cd <...>\vapi-cpp-vehicle-api-platform\build\<compiler_version>\tests\manual_tests
|
||||
```
|
||||
- Run the script to start the SilKit utilities:
|
||||
```bat
|
||||
run_silkit_util.bat
|
||||
```
|
||||
This will open two new windows:
|
||||
- One running `sil-kit-registry`.
|
||||
- Another running `sil-kit-system-controller` with the arguments `can_reader can_writer`.
|
||||
|
||||
**If the script is not available, you can start the utilities manually:**
|
||||
- Open two Command Prompt or PowerShell windows:
|
||||
- In the first window, navigate to the SilKit bin directory and run:
|
||||
```bat
|
||||
cd <...>\vapi-cpp-vehicle-api-platform\build\<compiler_version>\_deps\silkit-src\SilKit\bin
|
||||
sil-kit-registry.exe
|
||||
```
|
||||
- In the second window, run:
|
||||
```bat
|
||||
sil-kit-system-controller.exe can_reader can_writer
|
||||
```
|
||||
|
||||
1. **Run the CAN Writer**
|
||||
- Open a new Command Prompt or PowerShell window and navigate to the directory containing the can_writer binary:
|
||||
```bat
|
||||
cd <...>\vapi-cpp-vehicle-api-platform\build\<compiler_version>\tests\bin
|
||||
can_writer.exe
|
||||
```
|
||||
|
||||
The `can_writer` will send different CAN messages to the network. Each message will be logged in the terminal.
|
||||
|
||||
3. **Run the CAN Reader**
|
||||
- Open another Command Prompt or PowerShell window and navigate to the directory containing the can_reader binary:
|
||||
```bat
|
||||
cd <...>\vapi-cpp-vehicle-api-platform\build\<compiler_version>\tests\bin
|
||||
can_reader.exe
|
||||
```
|
||||
|
||||
The `can_reader` will receive and log the CAN messages sent by the `can_writer`. Each message will be logged in the terminal.
|
||||
|
||||
## Expected Output
|
||||
- **CAN Writer:** Logs the messages being sent, including the CAN ID, data length, and data content in the terminal.
|
||||
|
||||
- **CAN Reader:** Logs the messages being received, including the CAN ID, data length, and data content in the terminal.
|
||||
|
||||
## Troubleshooting
|
||||
- Binaries Not Found: Ensure the `sil-kit-registry`, `sil-kit-system-controller`, `can_writer`, and `can_reader` binaries are built and located in the correct directories.
|
||||
|
||||
- **Terminal Emulator: The script uses gnome-terminal on Linux. On Windows, PowerShell is used. If you use a different terminal emulator, modify the scripts accordingly.**
|
||||
|
||||
- Network Issues: Ensure the RegistryURI in the configuration matches the address of the sil-kit-registry.
|
||||
|
||||
## Additional Notes
|
||||
- The `can_writer` and `can_reader` configurations are hardcoded in their respective source files. If you need to modify the configurations (e.g., participant names, network names, or registry URI), update the source code and rebuild the binaries.
|
||||
- The tests are designed to run in synchronous mode (SyncMode = true). Ensure this setting is consistent across all components.
|
||||
@@ -0,0 +1,217 @@
|
||||
#ifndef TEST_CAN_SILKIT_HELPER_H
|
||||
#define TEST_CAN_SILKIT_HELPER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <thread>
|
||||
#include <gtest/gtest.h>
|
||||
#include <interfaces/can.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/toml.h>
|
||||
#include <support/component_impl.h>
|
||||
#include "../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../../sdv_services/can_communication_silkit/can_com_silkit.h"
|
||||
#include "../../../../export/support/app_control.h"
|
||||
|
||||
class CTestCanSilKit : public CCANSilKit
|
||||
{
|
||||
public:
|
||||
virtual void Initialize(const sdv::u8string& ssObjectConfig) override
|
||||
{
|
||||
return CCANSilKit::Initialize(ssObjectConfig);
|
||||
}
|
||||
|
||||
virtual sdv::EObjectStatus GetStatus() const override
|
||||
{
|
||||
return CCANSilKit::GetStatus();
|
||||
}
|
||||
|
||||
virtual void Shutdown() override
|
||||
{
|
||||
return CCANSilKit::Shutdown();
|
||||
}
|
||||
|
||||
virtual void RegisterReceiver(/*in*/ sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
return CCANSilKit::RegisterReceiver(pReceiver);
|
||||
}
|
||||
|
||||
virtual void UnregisterReceiver(/*in*/ sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
return CCANSilKit::UnregisterReceiver(pReceiver);
|
||||
}
|
||||
|
||||
virtual void Send(/*in*/ const sdv::can::SMessage& sMsg, /*in*/ uint32_t uiIfcIndex) override
|
||||
{
|
||||
return CCANSilKit::Send(sMsg, uiIfcIndex);
|
||||
}
|
||||
|
||||
virtual sdv::sequence<sdv::u8string> GetInterfaces() const override
|
||||
{
|
||||
return CCANSilKit::GetInterfaces();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
sdv::can::SMessage CreateCanMsgData(uint8_t init, uint8_t dataSize)
|
||||
{
|
||||
uint8_t value = init;
|
||||
sdv::can::SMessage testMsg;
|
||||
testMsg.uiID = value;
|
||||
testMsg.bCanFd = false;
|
||||
testMsg.bExtended = false;
|
||||
testMsg.seqData.resize(dataSize);
|
||||
for (uint8_t i = 0; i < dataSize; i++)
|
||||
{
|
||||
testMsg.seqData[i] = value;
|
||||
value += 2;
|
||||
}
|
||||
return testMsg;
|
||||
}
|
||||
|
||||
|
||||
class CanReceiver : public sdv::can::IReceive
|
||||
{
|
||||
public:
|
||||
|
||||
void Receive(const sdv::can::SMessage& sMessage, uint32_t) override
|
||||
{
|
||||
vecReceivedMessages.push_back(sMessage);
|
||||
}
|
||||
void Error(const sdv::can::SErrorFrame&, uint32_t) override {}
|
||||
|
||||
std::vector<sdv::can::SMessage> GetReceivedMessages()
|
||||
{
|
||||
return vecReceivedMessages;
|
||||
}
|
||||
|
||||
void ClearReceivedMessages()
|
||||
{
|
||||
vecReceivedMessages.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<sdv::can::SMessage> vecReceivedMessages;
|
||||
};
|
||||
|
||||
class CComTestHelper
|
||||
{
|
||||
public:
|
||||
struct PcloseDeleter
|
||||
{
|
||||
void operator()(FILE* file) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_pclose(file);
|
||||
#else
|
||||
pclose(file);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
std::string exec(const char* cmd)
|
||||
{
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
#ifdef _WIN32
|
||||
std::unique_ptr<FILE, PcloseDeleter> pipe(_popen(cmd, "r"));
|
||||
#else
|
||||
std::unique_ptr<FILE, PcloseDeleter> pipe(popen(cmd, "r"));
|
||||
#endif
|
||||
if (!pipe)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe.get()) != nullptr)
|
||||
{
|
||||
result += buffer.data();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
sdv::can::SMessage CreateTestData(uint8_t init, uint8_t dataSize)
|
||||
{
|
||||
uint8_t value = 65;
|
||||
// uint8_t value = init;
|
||||
sdv::can::SMessage testMsg;
|
||||
testMsg.uiID = init;
|
||||
testMsg.bCanFd = false;
|
||||
testMsg.bExtended = false;
|
||||
testMsg.seqData.resize(dataSize);
|
||||
for (uint8_t i = 0; i < dataSize; i++)
|
||||
{
|
||||
testMsg.seqData[i] = value;
|
||||
value += 2;
|
||||
}
|
||||
return testMsg;
|
||||
}
|
||||
|
||||
bool ValidateInterfaces(const sdv::sequence<sdv::u8string>& seqExpectedInterfaces, const sdv::sequence<sdv::u8string>& seqInterfaces)
|
||||
{
|
||||
bool success = true;
|
||||
if (seqExpectedInterfaces.size() != seqInterfaces.size())
|
||||
{
|
||||
std::cout << "Interfaces failure, expected: " << std::to_string(seqExpectedInterfaces.size()) << " got: " << std::to_string(seqInterfaces.size()) << std::endl;
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t nIndex = 0; nIndex < seqInterfaces.size(); nIndex++)
|
||||
{
|
||||
if (seqExpectedInterfaces[nIndex].compare(seqInterfaces[nIndex]) != 0)
|
||||
{
|
||||
success = false,
|
||||
std::cout << "Interface mismatch, expected: " << seqExpectedInterfaces[nIndex].c_str() << " got: " << seqInterfaces[nIndex].c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ValidateReceivedMessages(const std::deque<std::pair<std::string, sdv::can::SMessage>>& received,
|
||||
const sdv::can::SMessage& testMessage, const std::string& interfaceName, size_t expectedSize)
|
||||
{
|
||||
uint32_t error = 0;
|
||||
if (expectedSize == 0)
|
||||
error++;
|
||||
|
||||
if (received.size() != expectedSize)
|
||||
error++;
|
||||
|
||||
for (auto message : received)
|
||||
{
|
||||
if (interfaceName.compare(message.first) != 0)
|
||||
error++;
|
||||
|
||||
if (message.second.uiID != testMessage.uiID)
|
||||
error++;
|
||||
|
||||
if (message.second.seqData.size() != testMessage.seqData.size())
|
||||
error++;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
std::cout << "Got " << std::to_string(error) << " errors from validation of "
|
||||
<< interfaceName << ", expect " << std::to_string(expectedSize)
|
||||
<< " messages, got " << std::to_string(received.size()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string NormalizeWhitespace(const std::string& str)
|
||||
{
|
||||
std::string trimmed = str;
|
||||
trimmed.erase(trimmed.find_last_not_of(" \t\n\r") + 1); // Trim trailing whitespace
|
||||
trimmed.erase(0, trimmed.find_first_not_of(" \t\n\r")); // Trim leading whitespace
|
||||
std::string result;
|
||||
std::unique_copy(trimmed.begin(), trimmed.end(), std::back_inserter(result),
|
||||
[](char a, char b) { return std::isspace(a) && std::isspace(b); });
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ! defined TEST_CAN_SILKIT_HELPER_H
|
||||
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Run sil-kit-registry in a new Command Prompt window
|
||||
start cmd /k "..\..\_deps\silkit-src\SilKit\bin\sil-kit-registry.exe"
|
||||
|
||||
REM Run sil-kit-system-controller with arguments in another new Command Prompt window
|
||||
start cmd /k "..\..\_deps\silkit-src\SilKit\bin\sil-kit-system-controller.exe can_reader can_writer"
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run sil-kit-registry in a new terminal window
|
||||
gnome-terminal -- bash -c "./../../_deps/silkit-src/SilKit/bin/sil-kit-registry; exec bash"
|
||||
|
||||
# Run sil-kit-system-controller with arguments in another new terminal window
|
||||
gnome-terminal -- bash -c "./../../_deps/silkit-src/SilKit/bin/sil-kit-system-controller can_reader can_writer; exec bash"
|
||||
@@ -0,0 +1,270 @@
|
||||
#include "../../../../global/process_watchdog.h"
|
||||
#include "../include/can_com_test_helper.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
#endif
|
||||
|
||||
class CANSilkitTest : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
virtual void SetUp() override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void TearDown() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CTestCANSilkit : public CCANSilKit
|
||||
{
|
||||
public:
|
||||
virtual void Initialize(const sdv::u8string& ssObjectConfig) override
|
||||
{
|
||||
CCANSilKit::Initialize(ssObjectConfig);
|
||||
}
|
||||
|
||||
virtual void Shutdown() override
|
||||
{
|
||||
CCANSilKit::Shutdown();
|
||||
}
|
||||
|
||||
virtual void Send(const sdv::can::SMessage& sMsg, uint32_t uiIfcIndex) override
|
||||
{
|
||||
CCANSilKit::Send(sMsg, uiIfcIndex);
|
||||
m_MessagesSent++;
|
||||
}
|
||||
|
||||
virtual void RegisterReceiver(sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
CCANSilKit::RegisterReceiver(pReceiver);
|
||||
}
|
||||
|
||||
virtual void UnregisterReceiver(sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
CCANSilKit::UnregisterReceiver(pReceiver);
|
||||
}
|
||||
|
||||
virtual sdv::sequence<sdv::u8string> GetInterfaces() const override
|
||||
{
|
||||
return CCANSilKit::GetInterfaces();
|
||||
}
|
||||
|
||||
sdv::EObjectStatus GetTestStatus() const
|
||||
{
|
||||
return CCANSilKit::GetStatus();
|
||||
}
|
||||
|
||||
uint64_t GetMessagesSent() const
|
||||
{
|
||||
return m_MessagesSent;
|
||||
}
|
||||
|
||||
uint64_t m_MessagesSent = 0;
|
||||
};
|
||||
|
||||
class MockCANReceiver : public sdv::can::IReceive
|
||||
{
|
||||
public:
|
||||
void Receive(const sdv::can::SMessage& msg, uint32_t ifIndex) override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_receivedMessages.push_back(std::make_pair(ifIndex, msg));
|
||||
}
|
||||
|
||||
void Error(const sdv::can::SErrorFrame&, uint32_t) override {}
|
||||
|
||||
std::deque<std::pair<uint32_t, sdv::can::SMessage>>GetReceivedMessages() const
|
||||
{
|
||||
return m_receivedMessages;
|
||||
}
|
||||
|
||||
private:
|
||||
std::deque<std::pair<uint32_t, sdv::can::SMessage>> m_receivedMessages; ///< Storing index and received messages
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
bool InitializeAppControl(sdv::app::CAppControl* appcontrol, const std::string& configFileName)
|
||||
{
|
||||
auto bResult = appcontrol->AddModuleSearchDir("../../bin");
|
||||
bResult &= appcontrol->Startup("");
|
||||
appcontrol->SetConfigMode();
|
||||
bResult &= appcontrol->AddConfigSearchDir("../../tests/bin/config");
|
||||
|
||||
if (!configFileName.empty())
|
||||
{
|
||||
bResult &= appcontrol->LoadConfig(configFileName.c_str()) == sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void InitializeCanComObject(CTestCANSilkit& canComObj, const std::string config, MockCANReceiver& mockRcv)
|
||||
{
|
||||
ASSERT_NO_THROW(canComObj.Initialize(config.c_str()));
|
||||
EXPECT_EQ(canComObj.GetStatus(), sdv::EObjectStatus::initialized);
|
||||
ASSERT_NO_THROW(canComObj.SetOperationMode(sdv::EOperationMode::configuring));
|
||||
ASSERT_NO_THROW(canComObj.RegisterReceiver(&mockRcv));
|
||||
EXPECT_NO_THROW(canComObj.SetOperationMode(sdv::EOperationMode::running));
|
||||
}
|
||||
|
||||
void ShutDownCanComObject(CTestCANSilkit& canComObj, MockCANReceiver& mockRcv)
|
||||
{
|
||||
EXPECT_NO_THROW(canComObj.UnregisterReceiver(&mockRcv));
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
}
|
||||
|
||||
void SendThread(bool& stop, CTestCANSilkit& canComObj, sdv::can::SMessage& testData)
|
||||
{
|
||||
while (!stop)
|
||||
{
|
||||
EXPECT_NO_THROW(canComObj.Send(testData, 1)); // Send to second configuration
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CANSilkitTest, ValidConfigString)
|
||||
{
|
||||
sdv::can::SMessage testMsg {1, 0, 0, {0x11, 0x22, 0x33, 0x44}};
|
||||
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig =
|
||||
R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "can_writer"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
CTestCANSilkit canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_EQ(canComObj.GetStatus(), sdv::EObjectStatus::initialized);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Send(testMsg, 0));
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
ASSERT_EQ(canComObj.GetStatus(), sdv::EObjectStatus::shutdown_in_progress);
|
||||
}
|
||||
|
||||
TEST_F(CANSilkitTest, InvalidConfigIdentifier)
|
||||
{
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig =
|
||||
R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
InvalidSilKitParticipantName = "can_writer"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
|
||||
CTestCANSilkit canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
EXPECT_EQ(canComObj.GetStatus(), sdv::EObjectStatus::initialization_failure);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
EXPECT_EQ(canComObj.GetStatus(), sdv::EObjectStatus::shutdown_in_progress);
|
||||
}
|
||||
|
||||
TEST_F(CANSilkitTest, SendReceiveTest)
|
||||
{
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssConfig1 =
|
||||
R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "can_writer"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
sdv::u8string ssConfig2 =
|
||||
R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "can_reader"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
|
||||
CTestCANSilkit canComObj1;
|
||||
CTestCANSilkit canComObj2;
|
||||
MockCANReceiver mockRcv;
|
||||
|
||||
canComObj1.Initialize(ssConfig1.c_str());
|
||||
ASSERT_EQ(canComObj1.GetStatus(), sdv::EObjectStatus::initialized);
|
||||
canComObj2.Initialize(ssConfig2.c_str());
|
||||
ASSERT_EQ(canComObj2.GetStatus(), sdv::EObjectStatus::initialized);
|
||||
|
||||
ASSERT_NO_THROW(canComObj1.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_NO_THROW(canComObj2.SetOperationMode(sdv::EOperationMode::configuring));
|
||||
ASSERT_NO_THROW(canComObj2.RegisterReceiver(&mockRcv));
|
||||
ASSERT_NO_THROW(canComObj2.SetOperationMode(sdv::EOperationMode::running));
|
||||
|
||||
uint8_t msgId = 102;
|
||||
uint8_t dataSize = 1;
|
||||
uint32_t expectToBeSend = 8;
|
||||
uint32_t msgToBeSend = 8;
|
||||
CComTestHelper testHelper;
|
||||
while (dataSize <= msgToBeSend)
|
||||
{
|
||||
auto testData = testHelper.CreateTestData(msgId, dataSize);
|
||||
EXPECT_NO_THROW(canComObj1.Send(testData, 0)); // Send to CAN1
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
dataSize++;
|
||||
}
|
||||
|
||||
auto receivedMessages = mockRcv.GetReceivedMessages();
|
||||
|
||||
if (expectToBeSend != receivedMessages.size())
|
||||
{
|
||||
std::stringstream sstream;
|
||||
sstream << " Failed, expected " << std::to_string(expectToBeSend ) << " messages, got from CAN1 to CAN2: "
|
||||
<< std::to_string(receivedMessages.size());
|
||||
FAIL() << sstream.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize = 1;
|
||||
for(auto rcvMsg : receivedMessages)
|
||||
{
|
||||
auto testData = testHelper.CreateTestData(msgId, dataSize);
|
||||
EXPECT_EQ(msgId, rcvMsg.second.uiID);
|
||||
EXPECT_EQ(dataSize++, rcvMsg.second.seqData.size());
|
||||
EXPECT_EQ(testData.seqData, rcvMsg.second.seqData);
|
||||
std::cout << "Expected " << std::to_string(expectToBeSend ) << " messages, got from CAN1 to CAN2: "
|
||||
<< std::to_string(receivedMessages.size()) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NO_THROW(canComObj2.UnregisterReceiver(&mockRcv));
|
||||
canComObj1.Shutdown();
|
||||
canComObj2.Shutdown();
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <condition_variable>
|
||||
#include <gtest/gtest.h>
|
||||
#include <interfaces/can.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/toml.h>
|
||||
#include <support/component_impl.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
/**
|
||||
* @brief Dummy CAN Component to be able to load data link for testing purposes.
|
||||
* Sends and receives CAN messages with multiple signals.
|
||||
*/
|
||||
class CDummyCANSilKit
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
, public sdv::can::IRegisterReceiver
|
||||
, public sdv::can::ISend
|
||||
{
|
||||
public:
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(sdv::can::IRegisterReceiver)
|
||||
SDV_INTERFACE_ENTRY(sdv::can::ISend)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("Dummy_CAN_Sockets")
|
||||
DECLARE_DEFAULT_OBJECT_NAME("CAN_Communication_Object")
|
||||
DECLARE_OBJECT_SINGLETON()
|
||||
|
||||
virtual void Initialize(const sdv::u8string& ) override
|
||||
{
|
||||
m_StopThread = false;
|
||||
//m_thSend2DatalinkThread = std::thread(&CDummyCANSockets::Send2DatalinkThread, this);
|
||||
m_status = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
virtual sdv::EObjectStatus GetStatus() const override
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void SetOperationMode(sdv::EOperationMode eMode) override
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_status == sdv::EObjectStatus::running || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_status == sdv::EObjectStatus::configuring || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Shutdown() override
|
||||
{
|
||||
m_StopThread = true;
|
||||
if (m_thSend2DatalinkThread.joinable())
|
||||
{
|
||||
m_thSend2DatalinkThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void RegisterReceiver(sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
if (!pReceiver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Registering Dummy CAN communication receiver...\n";
|
||||
std::unique_lock<std::mutex> lock(m_mtxReceivers);
|
||||
m_setReceivers.insert(pReceiver);
|
||||
}
|
||||
|
||||
virtual void UnregisterReceiver(sdv::can::IReceive* pReceiver) override
|
||||
{
|
||||
if (!pReceiver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Unregistering Dummy CAN communication receiver...\n";
|
||||
std::unique_lock<std::mutex> lock(m_mtxReceivers);
|
||||
m_setReceivers.erase(pReceiver);
|
||||
}
|
||||
|
||||
virtual void Send(const sdv::can::SMessage& sMsg, uint32_t uiIfcIndex) override
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lockReceivers(m_mtxReceivers);
|
||||
for (sdv::can::IReceive* pReceiver : m_setReceivers)
|
||||
{
|
||||
pReceiver->Receive(sMsg, uiIfcIndex);
|
||||
}
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx);
|
||||
m_messageSent = true;
|
||||
}
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
||||
// Synchronization members
|
||||
std::condition_variable m_cv;
|
||||
std::mutex m_mtx;
|
||||
bool m_messageSent = false;
|
||||
|
||||
private:
|
||||
bool m_StopThread = false;
|
||||
std::thread m_thSend2DatalinkThread;
|
||||
mutable std::mutex m_mtxReceivers;
|
||||
std::set<sdv::can::IReceive*> m_setReceivers;
|
||||
std::atomic<sdv::EObjectStatus> m_status = { sdv::EObjectStatus::initialization_pending };
|
||||
};
|
||||
|
||||
class MockCANReceiver : public sdv::can::IReceive
|
||||
{
|
||||
public:
|
||||
std::vector<sdv::can::SMessage> vecReceivedMessages;
|
||||
|
||||
void Receive(const sdv::can::SMessage& sMessage, uint32_t) override
|
||||
{
|
||||
vecReceivedMessages.push_back(sMessage);
|
||||
}
|
||||
|
||||
void Error(const sdv::can::SErrorFrame&, uint32_t) override {}
|
||||
};
|
||||
|
||||
bool InitializeAppControl(sdv::app::CAppControl* appcontrol, const std::string& configFileName)
|
||||
{
|
||||
auto bResult = appcontrol->AddModuleSearchDir("../../bin");
|
||||
bResult &= appcontrol->Startup("");
|
||||
appcontrol->SetConfigMode();
|
||||
bResult &= appcontrol->AddConfigSearchDir("../../tests/bin/config");
|
||||
|
||||
if (!configFileName.empty())
|
||||
{
|
||||
bResult &= appcontrol->LoadConfig(configFileName.c_str()) == sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
std::string ReplaceWhitespaceWithSingleSpaceAndEscapeQuotes(const std::string& input)
|
||||
{
|
||||
std::stringstream result;
|
||||
bool inWhitespace = false;
|
||||
|
||||
for (uint8_t singleChar : input)
|
||||
{
|
||||
if (std::isspace(static_cast<uint8_t>(singleChar)))
|
||||
{
|
||||
if (!inWhitespace)
|
||||
{
|
||||
result << ' '; // Add a single space for whitespace
|
||||
inWhitespace = true;
|
||||
}
|
||||
}
|
||||
else if (singleChar == '"')
|
||||
{
|
||||
// Escape the quote character
|
||||
result << "\\\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
result << singleChar; // Add the character as is
|
||||
inWhitespace = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
bool StringToBool(const std::string& value) {
|
||||
return value == "true" || value == "1"; // Return true for "true" or "1", false otherwise
|
||||
}
|
||||
|
||||
std::string ExtractValue(const std::string& content, const std::string& key)
|
||||
{
|
||||
std::size_t startPos = content.find(key + " = ");
|
||||
if (startPos == std::string::npos) {
|
||||
return ""; // Key not found
|
||||
}
|
||||
|
||||
startPos += key.length() + 3; // Move past the key and " = "
|
||||
|
||||
// If the value is multi-line (enclosed by triple quotes), find the start and end
|
||||
std::size_t endPos;
|
||||
if (content.substr(startPos, 3) == "\"\"\"") { // Check for starting triple quotes
|
||||
startPos += 3; // Skip over the triple quotes
|
||||
endPos = content.find("\"\"\"", startPos); // Look for the closing triple quotes
|
||||
if (endPos == std::string::npos) {
|
||||
return ""; // End of value not found, invalid format
|
||||
}
|
||||
} else {
|
||||
// Otherwise, find the first newline or end of the string
|
||||
endPos = content.find_first_of("\n", startPos);
|
||||
if (endPos == std::string::npos) {
|
||||
endPos = content.length();
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the value between startPos and endPos
|
||||
std::string value = content.substr(startPos, endPos - startPos);
|
||||
|
||||
// Remove surrounding whitespace and newline characters if present
|
||||
value.erase(std::remove(value.begin(), value.end(), '\"'), value.end());
|
||||
value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
|
||||
value.erase(std::remove(value.begin(), value.end(), '\r'), value.end());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
class CANCommunicationTest : public ::testing::Test
|
||||
{
|
||||
void SetUp() override {}
|
||||
|
||||
void TearDown() override {}
|
||||
};
|
||||
|
||||
TEST_F(CANCommunicationTest, BasicSendAndReceiveMessageTest)
|
||||
{
|
||||
// Dummy test message
|
||||
sdv::can::SMessage testMsg;
|
||||
testMsg.uiID = 0x1234;
|
||||
testMsg.bCanFd = false;
|
||||
testMsg.bExtended = false;
|
||||
testMsg.seqData = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x77, 0x88};
|
||||
|
||||
// Configuration content as a string
|
||||
std::string testConfigFileContent = R"(
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_silkit.sdv"
|
||||
Class = "CAN_Com_SilKit"
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
CanSilKitChannel = "CAN1"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
|
||||
[[Component]]
|
||||
Path = "can_datalink.sdv"
|
||||
Class = "CAN_data_link"
|
||||
"""
|
||||
)";
|
||||
|
||||
sdv::app::CAppControl appControl;
|
||||
auto bResult = InitializeAppControl(&appControl, "test_manual_can_com_silkit.toml");
|
||||
EXPECT_EQ(bResult, true);
|
||||
|
||||
std::string SilKitChannel = ExtractValue(testConfigFileContent, "CanSilKitChannel");
|
||||
EXPECT_EQ(SilKitChannel, "CAN1");
|
||||
|
||||
// Check RegistryURI
|
||||
std::string SilKitRegistryUri = ExtractValue(testConfigFileContent, "RegistryURI");
|
||||
EXPECT_EQ(SilKitRegistryUri, "silkit://localhost:8500");
|
||||
|
||||
// Check CanSilKitNetwork
|
||||
std::string SilKitNetwork = ExtractValue(testConfigFileContent, "CanSilKitNetwork");
|
||||
EXPECT_EQ(SilKitNetwork, "PrivateCAN");
|
||||
|
||||
// Check SyncMode
|
||||
std::string SyncModeString = ExtractValue(testConfigFileContent, "SyncMode");
|
||||
|
||||
// Convert the extracted value to a bool
|
||||
bool SilKitSyncMode = StringToBool(SyncModeString);
|
||||
EXPECT_EQ(SilKitSyncMode, true);
|
||||
|
||||
// Check SilKitConfig
|
||||
std::string SilKitJSONConfigContent = ExtractValue(testConfigFileContent, "SilKitConfig");
|
||||
std::string ExpectedConfigContent = R"({
|
||||
Logging: {
|
||||
Sinks: [ { Type: Stdout, Level: Info } ]
|
||||
},
|
||||
})";
|
||||
EXPECT_EQ(ReplaceWhitespaceWithSingleSpaceAndEscapeQuotes(SilKitJSONConfigContent), ReplaceWhitespaceWithSingleSpaceAndEscapeQuotes(ExpectedConfigContent));
|
||||
|
||||
|
||||
// Create an object of the CDummyCANSilKit class
|
||||
CDummyCANSilKit canComObj;
|
||||
canComObj.Initialize("");
|
||||
|
||||
sdv::can::ISend* pCanSend = &canComObj;
|
||||
EXPECT_NE(pCanSend, nullptr);
|
||||
|
||||
sdv::can::IRegisterReceiver* pCanRegRcvr = &canComObj;
|
||||
EXPECT_NE(pCanRegRcvr, nullptr);
|
||||
|
||||
MockCANReceiver mockRcv;
|
||||
EXPECT_NO_THROW(pCanRegRcvr->RegisterReceiver(&mockRcv));
|
||||
|
||||
appControl.SetRunningMode();
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
// Send a message
|
||||
EXPECT_NO_THROW(pCanSend->Send(testMsg, 0));
|
||||
|
||||
// Wait for the message to be received
|
||||
std::unique_lock<std::mutex> lock(canComObj.m_mtx);
|
||||
canComObj.m_cv.wait(lock, [&] { return canComObj.m_messageSent; });
|
||||
|
||||
// Verify received messages
|
||||
ASSERT_FALSE(mockRcv.vecReceivedMessages.empty());
|
||||
auto rcvMsg = mockRcv.vecReceivedMessages.front();
|
||||
EXPECT_EQ(rcvMsg.uiID, testMsg.uiID);
|
||||
EXPECT_EQ(rcvMsg.seqData, testMsg.seqData);
|
||||
|
||||
// Reset the flag for the next iteration
|
||||
canComObj.m_messageSent = false;
|
||||
mockRcv.vecReceivedMessages.clear();
|
||||
}
|
||||
|
||||
EXPECT_NO_THROW(pCanRegRcvr->UnregisterReceiver(&mockRcv));
|
||||
|
||||
// Ensure proper shutdown
|
||||
canComObj.Shutdown();
|
||||
}
|
||||
|
||||
TEST_F(CANCommunicationTest, ExtractAndCompareSignals)
|
||||
{
|
||||
// Dummy test message
|
||||
sdv::can::SMessage testMsg;
|
||||
testMsg.uiID = 0x1234;
|
||||
testMsg.bCanFd = false;
|
||||
testMsg.bExtended = false;
|
||||
testMsg.seqData = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x77, 0x88};
|
||||
|
||||
sdv::app::CAppControl appControl;
|
||||
auto bResult = InitializeAppControl(&appControl, "test_manual_can_com_silkit.toml");
|
||||
EXPECT_EQ(bResult, true);
|
||||
|
||||
// Create a normal object of the CDummyCANSilKit class
|
||||
CDummyCANSilKit canComObj;
|
||||
canComObj.Initialize("");
|
||||
|
||||
sdv::can::ISend* pCanSend = &canComObj;
|
||||
EXPECT_NE(pCanSend, nullptr);
|
||||
|
||||
sdv::can::IRegisterReceiver* pCanRegRcvr = &canComObj;
|
||||
EXPECT_NE(pCanRegRcvr, nullptr);
|
||||
|
||||
MockCANReceiver mockRcv;
|
||||
EXPECT_NO_THROW(pCanRegRcvr->RegisterReceiver(&mockRcv));
|
||||
|
||||
appControl.SetRunningMode();
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
// Send a message
|
||||
EXPECT_NO_THROW(pCanSend->Send(testMsg, 0));
|
||||
|
||||
// Wait for the message to be received
|
||||
std::unique_lock<std::mutex> lock(canComObj.m_mtx);
|
||||
canComObj.m_cv.wait(lock, [&] { return canComObj.m_messageSent; });
|
||||
|
||||
// Verify received messages
|
||||
ASSERT_FALSE(mockRcv.vecReceivedMessages.empty());
|
||||
auto rcvMsg = mockRcv.vecReceivedMessages.front();
|
||||
EXPECT_EQ(rcvMsg.uiID, testMsg.uiID);
|
||||
EXPECT_EQ(rcvMsg.seqData, testMsg.seqData);
|
||||
|
||||
// Extract and compare signals
|
||||
uint32_t sentSpeed = (testMsg.seqData[6] << 8) | testMsg.seqData[7];
|
||||
uint32_t receivedSpeed = (rcvMsg.seqData[6] << 8) | rcvMsg.seqData[7];
|
||||
EXPECT_EQ(sentSpeed, receivedSpeed);
|
||||
|
||||
int32_t sentSteeringWheel = (testMsg.seqData[4] << 8) | testMsg.seqData[5];
|
||||
int32_t receivedSteeringWheel = (rcvMsg.seqData[4] << 8) | rcvMsg.seqData[5];
|
||||
EXPECT_EQ(sentSteeringWheel, receivedSteeringWheel);
|
||||
|
||||
// Reset the flag for the next iteration
|
||||
canComObj.m_messageSent = false;
|
||||
mockRcv.vecReceivedMessages.clear();
|
||||
}
|
||||
|
||||
EXPECT_NO_THROW(pCanRegRcvr->UnregisterReceiver(&mockRcv));
|
||||
|
||||
// Ensure proper shutdown
|
||||
canComObj.Shutdown();
|
||||
}
|
||||
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
67
tests/manual_tests/silkit_can_com_tests/src/can_reader.cpp
Normal file
67
tests/manual_tests/silkit_can_com_tests/src/can_reader.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "../include/can_com_test_helper.h"
|
||||
|
||||
void ReceiveData()
|
||||
{
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string config = R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "can_reader"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
|
||||
CTestCanSilKit canComObj;
|
||||
canComObj.Initialize(config.c_str());
|
||||
canComObj.SetOperationMode(sdv::EOperationMode::configuring);
|
||||
|
||||
CanReceiver mockRcv;
|
||||
canComObj.RegisterReceiver(&mockRcv);
|
||||
canComObj.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
while(true)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
auto receivedMessages = mockRcv.GetReceivedMessages();
|
||||
if(receivedMessages.size() != 0)
|
||||
{
|
||||
for(auto rcvdMsg : receivedMessages)
|
||||
{
|
||||
std::stringstream buffer;
|
||||
buffer << "\n[RX] CAN message being received [CANID=";
|
||||
buffer << rcvdMsg.uiID; buffer << ", Length=" ;
|
||||
buffer << unsigned(rcvdMsg.seqData.size()); buffer << "]" ;
|
||||
|
||||
buffer << " Data=";
|
||||
for(uint16_t i = 0; i < rcvdMsg.seqData.size(); i++)
|
||||
{
|
||||
buffer << "[" ; buffer << std::hex << unsigned(rcvdMsg.seqData[i]); buffer << "] ";
|
||||
}
|
||||
std::cout << buffer.str().c_str();
|
||||
mockRcv.ClearReceivedMessages();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "[RX] Received Message size is " << receivedMessages.size() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
canComObj.UnregisterReceiver(&mockRcv);
|
||||
std::cout << "CAN has read all messages\n";
|
||||
|
||||
canComObj.Shutdown();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ReceiveData();
|
||||
return 0;
|
||||
}
|
||||
59
tests/manual_tests/silkit_can_com_tests/src/can_writer.cpp
Normal file
59
tests/manual_tests/silkit_can_com_tests/src/can_writer.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "../include/can_com_test_helper.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string config = R"(
|
||||
DebugInfo = true
|
||||
SyncMode = true
|
||||
SilKitParticipantName = "can_writer"
|
||||
CanSilKitNetwork = "PrivateCAN"
|
||||
RegistryURI = "silkit://localhost:8500"
|
||||
SilKitConfig = """{
|
||||
"Logging": {
|
||||
"Sinks": [ { "Type": "Stdout", "Level": "Info" } ]
|
||||
},
|
||||
}"""
|
||||
)";
|
||||
|
||||
CTestCanSilKit canComObj;
|
||||
canComObj.Initialize(config.c_str());
|
||||
canComObj.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
uint8_t msgId = 65;
|
||||
uint8_t dataSize = 1;
|
||||
uint16_t i = 0;
|
||||
std::cout << "Can writes 30 different datas:\n";
|
||||
CComTestHelper testHelper;
|
||||
while(i < 30) //Sending 30 messages
|
||||
{
|
||||
auto testData = testHelper.CreateTestData(msgId, dataSize);
|
||||
canComObj.Send(testData, 0);
|
||||
|
||||
if(testData.seqData.size() != 0)
|
||||
{
|
||||
std::stringstream buffer;
|
||||
buffer << "\n[TX] CAN message being sent [CANID=";
|
||||
buffer << testData.uiID; buffer << ", Length=" ;
|
||||
buffer << unsigned(testData.seqData.size()); buffer << "]" ;
|
||||
|
||||
buffer << " Data=";
|
||||
for(uint16_t j = 0; j < testData.seqData.size(); j++)
|
||||
{
|
||||
buffer << "[" ; buffer << std::hex << unsigned(testData.seqData[j]); buffer << "] ";
|
||||
}
|
||||
std::cout << buffer.str().c_str();
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
msgId++;
|
||||
i++;
|
||||
dataSize++;
|
||||
if(dataSize > 8)
|
||||
dataSize = 1;
|
||||
}
|
||||
|
||||
canComObj.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
40
tests/run_tests_on_linux.sh
Normal file
40
tests/run_tests_on_linux.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
############################## ATTENTION ##############################
|
||||
# Shell Script to execute the tests on Linux #
|
||||
# Adjust the permission with: chmod +x run_tests_on_linux.sh #
|
||||
# Run the script with: ./run_tests_on_linux.sh #
|
||||
# or: bash ./run_tests_on_linux.sh #
|
||||
#######################################################################
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Define the directory to search
|
||||
directory="bin"
|
||||
|
||||
# Sammeln der ausführbaren Dateien in einem Array
|
||||
IFS=$'\n' read -r -d '' -a RUN_TESTS < <(find bin -type f \( -name "ComponentTest_*" -o -name "UnitTest_*" \) -executable -exec sh -c 'for file; do [ "${file##*.}" = "$file" ] && echo "$file"; done' sh {} \; && printf '\0')
|
||||
|
||||
# Array to hold failed tests
|
||||
FAILED_TESTS=()
|
||||
|
||||
# Run all tests and capture output
|
||||
for TEST_EXECUTABLE in "${RUN_TESTS[@]}"; do
|
||||
if [ -f "$TEST_EXECUTABLE" ]; then
|
||||
OUTPUT=$($TEST_EXECUTABLE --gtest_output=xml:../bin/$(basename $TEST_EXECUTABLE).xml 2>&1)
|
||||
echo "$OUTPUT"
|
||||
if echo "$OUTPUT" | grep -q "FAILED"; then
|
||||
FAILED_TESTS+=("$TEST_EXECUTABLE")
|
||||
fi
|
||||
else
|
||||
echo "Executable $TEST_EXECUTABLE not found!"
|
||||
fi
|
||||
done
|
||||
|
||||
# List all failed tests at the end
|
||||
if [ ${#FAILED_TESTS[@]} -ne 0 ]; then
|
||||
echo -e "\n\e[31mFailed tests:\e[0m"
|
||||
for TEST in "${FAILED_TESTS[@]}"; do
|
||||
echo -e "\e[31m$TEST\e[0m"
|
||||
done
|
||||
else
|
||||
echo -e "\n\e[32mAll tests passed!\e[0m"
|
||||
fi
|
||||
37
tests/run_tests_on_windows.ps1
Normal file
37
tests/run_tests_on_windows.ps1
Normal file
@@ -0,0 +1,37 @@
|
||||
# PowerShell Script to execute the tests on Windows
|
||||
# Save this script as run_tests_on_windows.ps1
|
||||
# Run the script with: .\run_tests_on_windows.ps1
|
||||
|
||||
# Set the paths to the executables
|
||||
$runTests = Get-ChildItem -Path "bin" -Filter "*.exe" | Where-Object {
|
||||
$_.Name -like "ComponentTest_*" -or $_.Name -like "UnitTest_*"
|
||||
} | ForEach-Object {
|
||||
$_.FullName
|
||||
}
|
||||
|
||||
# Array to hold failed tests
|
||||
$failedTests = @()
|
||||
|
||||
# Run all tests and capture output
|
||||
foreach ($testExecutable in $runTests) {
|
||||
if (Test-Path $testExecutable) {
|
||||
$output = & $testExecutable --gtest_output=xml:../bin/$(Split-Path -Leaf $testExecutable).xml 2>&1
|
||||
Write-Output $output
|
||||
if ($output -match "FAILED") {
|
||||
$failedTests += $testExecutable
|
||||
}
|
||||
} else {
|
||||
Write-Output "Executable $testExecutable not found!"
|
||||
}
|
||||
}
|
||||
|
||||
# List all failed tests at the end
|
||||
if ($failedTests.Count -ne 0) {
|
||||
Write-Host "`nFailed tests:" -ForegroundColor Red
|
||||
foreach ($test in $failedTests) {
|
||||
Write-Host $test -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host "`nAll tests passed!" -ForegroundColor Green
|
||||
|
||||
}
|
||||
2
tests/sdv_core_reloc.toml
Normal file
2
tests/sdv_core_reloc.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
# Location of the SDV core library
|
||||
directory = "../../bin"
|
||||
20
tests/unit_tests/app_connect/CMakeLists.txt
Normal file
20
tests/unit_tests/app_connect/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# Define project
|
||||
project (UnitTest_App_Connect VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_App_Connect
|
||||
"main.cpp"
|
||||
"app_connect_local.cpp")
|
||||
target_link_libraries(UnitTest_App_Connect ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the IDL Compiler unittest
|
||||
add_test(NAME UnitTest_App_Connect COMMAND UnitTest_App_Connect)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_App_Connect POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_App_Connect>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_App_Connect.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(UnitTest_App_Connect dependency_sdv_components)
|
||||
7
tests/unit_tests/app_connect/app_connect_local.cpp
Normal file
7
tests/unit_tests/app_connect/app_connect_local.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
- Default instantiate listener
|
||||
- Instantiate with specific info
|
||||
- Multiple instantiate with identical info (failure)
|
||||
- Multiple instantiate with different info
|
||||
- Default instantiate client and get connection information
|
||||
- */
|
||||
19
tests/unit_tests/app_connect/main.cpp
Normal file
19
tests/unit_tests/app_connect/main.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/localmemmgr.h"
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
*/
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
CLocalMemMgr memmgr;
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
27
tests/unit_tests/asc_format/CMakeLists.txt
Normal file
27
tests/unit_tests/asc_format/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# Define project
|
||||
project (UnitTest_ASC_Format VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_ASC_Format
|
||||
"asc_reader_test.cpp"
|
||||
"main.cpp"
|
||||
"asc_writer_test.cpp")
|
||||
target_link_libraries(UnitTest_ASC_Format ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the IDL Compiler unittest
|
||||
add_test(NAME UnitTest_ASC_Format COMMAND UnitTest_ASC_Format)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_ASC_Format POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_ASC_Format>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_ASC_Format.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# copy the ASC test file to binary folder
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/asc_reader_timing_test.asc DESTINATION ${CMAKE_BINARY_DIR}/tests/bin)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/asc_reader_test.asc DESTINATION ${CMAKE_BINARY_DIR}/tests/bin)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/asc_reader_ext_id_test.asc DESTINATION ${CMAKE_BINARY_DIR}/tests/bin)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/asc_reader_canfd_test.asc DESTINATION ${CMAKE_BINARY_DIR}/tests/bin)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(UnitTest_ASC_Format dependency_sdv_components)
|
||||
9
tests/unit_tests/asc_format/asc_reader_canfd_test.asc
Normal file
9
tests/unit_tests/asc_format/asc_reader_canfd_test.asc
Normal file
@@ -0,0 +1,9 @@
|
||||
date Dez. 3 2014 16:34:20
|
||||
base hex timestamps absolute
|
||||
no internal events logged
|
||||
Begin Triggerblock
|
||||
3.35516 1 B4323x Rx D 8 72 E4 19 2F 14 00 00 00
|
||||
3.35522 6 52 Rx D 2 6C 60
|
||||
3.36716 1 B4323x Rx D 8 73 E5 E9 24 e2 00 00 00
|
||||
3.36722 CANFD 15 Rx 86 1 0 8 8 48 75 6d 61 6e 69 73 6d 0 0 3000 0 0 0
|
||||
End TriggerBlock
|
||||
11
tests/unit_tests/asc_format/asc_reader_ext_id_test.asc
Normal file
11
tests/unit_tests/asc_format/asc_reader_ext_id_test.asc
Normal file
@@ -0,0 +1,11 @@
|
||||
date Mon Mai 19 15:37:13.000 2014
|
||||
base hex timestamps absolute
|
||||
internal events logged
|
||||
// version 8.5.0
|
||||
Begin Triggerblock Mon Mai 19 15:37:13.690 2014
|
||||
0.590000 1 539 Rx d 1 03 Length 108000 BitCount = 58 ID = 1337
|
||||
0.619000 1 71x Rx d 1 42 Length 152000 BitCount = 80 ID = 113x
|
||||
0.690000 1 539 Rx d 1 04 Length 106000 BitCount = 57 ID = 1337
|
||||
0.690000 log trigger event
|
||||
0.719000 1 71x Rx d 1 42 Length 152000 BitCount 80 ID 113x
|
||||
End TriggerBlock
|
||||
3540
tests/unit_tests/asc_format/asc_reader_test.asc
Normal file
3540
tests/unit_tests/asc_format/asc_reader_test.asc
Normal file
File diff suppressed because it is too large
Load Diff
512
tests/unit_tests/asc_format/asc_reader_test.cpp
Normal file
512
tests/unit_tests/asc_format/asc_reader_test.cpp
Normal file
@@ -0,0 +1,512 @@
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include "../../../global/ascformat/ascreader.cpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
|
||||
TEST(CAscReaderTest, ReadASCFile)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_TRUE(reader.IsEOF());
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, SingleSampleNavigation)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// First value
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007096);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0xb6ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 5ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x80);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xc8);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x00);
|
||||
|
||||
// Next value
|
||||
++reader;
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007123);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 2ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x85ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 8ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xff);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0xff);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], 0xf3);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], 0x1d);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], 0x00);
|
||||
|
||||
// Next value
|
||||
++reader;
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007333);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x19eul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 8ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0xec);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0xef);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0xfc);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xff);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x0c);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], 0x85);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], 0x00);
|
||||
|
||||
// Previous value
|
||||
--reader;
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007123);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 2ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x85ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 8ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xff);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0xff);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], 0xf3);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], 0x1d);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], 0x00);
|
||||
|
||||
// Previous value
|
||||
--reader;
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007096);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0xb6ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 5ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x80);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xc8);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x00);
|
||||
|
||||
// Jump to end
|
||||
reader.JumpEnd();
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_TRUE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_FALSE(prSample.second);
|
||||
|
||||
// Jump to begin
|
||||
reader.JumpBegin();
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.007096);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0xb6ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 5ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x06);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x80);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xc8);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x00);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, NormalPlayback)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Do measurement
|
||||
asc::SCanMessage sMsg{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg = rsMsg; }, false);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
reader.StopPlayback();
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg.rguiData[8]);
|
||||
|
||||
// Time deviation
|
||||
std::cout << "The current timestamp is " << sMsg.dTimestamp << " (should be somewhat more than 250ms)" << std::endl;
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, PlaybackRestart)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Do first measurement
|
||||
asc::SCanMessage sMsg1{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg1 = rsMsg; }, false);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
reader.StopPlayback();
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg1.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg1.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg1.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg1.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg1.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg1.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg1.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg1.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg1.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg1.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg1.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg1.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg1.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg1.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg1.rguiData[8]);
|
||||
|
||||
// Do second measurement
|
||||
asc::SCanMessage sMsg2{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg2 = rsMsg; }, false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
reader.StopPlayback();
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg2.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg2.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg2.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg2.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg2.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg2.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg2.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg2.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg2.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg2.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg2.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg2.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg2.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg2.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg2.rguiData[8]);
|
||||
|
||||
// The time of message 1 should be less than the time of message 2.
|
||||
EXPECT_LT(sMsg1.dTimestamp, sMsg2.dTimestamp);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, PlaybackReset)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Do first measurement
|
||||
asc::SCanMessage sMsg1{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg1 = rsMsg; }, false);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
reader.StopPlayback();
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg1.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg1.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg1.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg1.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg1.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg1.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg1.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg1.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg1.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg1.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg1.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg1.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg1.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg1.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg1.rguiData[8]);
|
||||
|
||||
// Do second measurement
|
||||
asc::SCanMessage sMsg2{};
|
||||
reader.ResetPlayback();
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg2 = rsMsg; }, false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(125));
|
||||
reader.StopPlayback();
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg2.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg2.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg2.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg2.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg2.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg2.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg2.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg2.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg2.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg2.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg2.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg2.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg2.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg2.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg2.rguiData[8]);
|
||||
|
||||
// The time of message 1 should be more than the time of message 2.
|
||||
EXPECT_GT(sMsg1.dTimestamp, sMsg2.dTimestamp);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, FinishPlayback)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Do measurement
|
||||
reader.JumpEnd();
|
||||
for (size_t n = 0; n < 150; n++)
|
||||
--reader;
|
||||
asc::SCanMessage sMsg{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg = rsMsg; }, false);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
EXPECT_FALSE(reader.PlaybackRunning());
|
||||
reader.StopPlayback(); // Just in case...
|
||||
EXPECT_TRUE(reader.IsEOF());
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsg.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsg.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsg.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsg.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsg.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsg.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsg.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsg.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsg.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsg.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsg.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsg.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsg.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsg.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsg.rguiData[8]);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, RepeatPlayback)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Do a measurement startin at the end
|
||||
reader.JumpEnd();
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
--reader;
|
||||
asc::SCanMessage sMsgStart = reader.Get().first;
|
||||
asc::SCanMessage sMsgCurrent{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsgCurrent = rsMsg; }, true);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
reader.StopPlayback();
|
||||
|
||||
// Last sent message is the one before the current message.
|
||||
--reader;
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, sMsgCurrent.dTimestamp);
|
||||
EXPECT_EQ(prSample.first.uiChannel, sMsgCurrent.uiChannel);
|
||||
EXPECT_EQ(prSample.first.uiId, sMsgCurrent.uiId);
|
||||
EXPECT_EQ(prSample.first.bExtended, sMsgCurrent.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, sMsgCurrent.eDirection);
|
||||
EXPECT_EQ(prSample.first.uiLength, sMsgCurrent.uiLength);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], sMsgCurrent.rguiData[0]);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], sMsgCurrent.rguiData[1]);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], sMsgCurrent.rguiData[2]);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], sMsgCurrent.rguiData[3]);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], sMsgCurrent.rguiData[4]);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], sMsgCurrent.rguiData[5]);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], sMsgCurrent.rguiData[6]);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], sMsgCurrent.rguiData[7]);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], sMsgCurrent.rguiData[8]);
|
||||
|
||||
// The time of start message should be more than the time of the current message.
|
||||
EXPECT_GT(sMsgStart.dTimestamp, sMsgCurrent.dTimestamp);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, RepeatPlaybackCheckLoopExecution)
|
||||
{
|
||||
asc::CAscReader readerOneLoop;
|
||||
EXPECT_TRUE(readerOneLoop.Read(GetExecDirectory() / "asc_reader_timing_test.asc"));
|
||||
|
||||
asc::SCanMessage sMsgOneLoop{};
|
||||
readerOneLoop.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsgOneLoop = rsMsg; }, false);
|
||||
EXPECT_TRUE(readerOneLoop.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(400));
|
||||
readerOneLoop.StopPlayback();
|
||||
EXPECT_TRUE(readerOneLoop.GetLoopCount() == 1);
|
||||
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_timing_test.asc"));
|
||||
|
||||
asc::SCanMessage sMsg{};
|
||||
reader.StartPlayback([&](const asc::SCanMessage& rsMsg) { sMsg = rsMsg; }, true);
|
||||
EXPECT_TRUE(reader.PlaybackRunning());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(400));
|
||||
reader.StopPlayback();
|
||||
|
||||
// Second loop must run in the same speed, therfore LoopCount = 2, not mmore
|
||||
EXPECT_TRUE((readerOneLoop.GetLoopCount() + 1) == reader.GetLoopCount());
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, ExtendedId)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_ext_id_test.asc"));
|
||||
|
||||
// First value
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.590000);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x539ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 1ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x03);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x00);
|
||||
|
||||
// Next value
|
||||
++reader;
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 0.619000);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x71ul);
|
||||
EXPECT_TRUE(prSample.first.bExtended);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 1ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x42);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x00);
|
||||
}
|
||||
|
||||
TEST(CAscReaderTest, CAN_FD)
|
||||
{
|
||||
asc::CAscReader reader;
|
||||
EXPECT_TRUE(reader.Read(GetExecDirectory() / "asc_reader_canfd_test.asc"));
|
||||
|
||||
EXPECT_TRUE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
|
||||
// Skip two values
|
||||
++reader;
|
||||
++reader;
|
||||
|
||||
// third value
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
auto prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 3.36716);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 1ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0xB4323ul);
|
||||
EXPECT_TRUE(prSample.first.bExtended);
|
||||
EXPECT_FALSE(prSample.first.bCanFd);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 8ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x73);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0xe5);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0xe9);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x24);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0xe2);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], 0x00);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], 0x00);
|
||||
|
||||
// Next value
|
||||
++reader;
|
||||
EXPECT_FALSE(reader.IsBOF());
|
||||
EXPECT_FALSE(reader.IsEOF());
|
||||
prSample = reader.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
EXPECT_EQ(prSample.first.dTimestamp, 3.36722);
|
||||
EXPECT_EQ(prSample.first.uiChannel, 15ul);
|
||||
EXPECT_EQ(prSample.first.uiId, 0x86ul);
|
||||
EXPECT_FALSE(prSample.first.bExtended);
|
||||
EXPECT_TRUE(prSample.first.bCanFd);
|
||||
EXPECT_EQ(prSample.first.eDirection, asc::SCanMessage::EDirection::rx);
|
||||
EXPECT_EQ(prSample.first.uiLength, 8ul);
|
||||
EXPECT_EQ(prSample.first.rguiData[0], 0x48);
|
||||
EXPECT_EQ(prSample.first.rguiData[1], 0x75);
|
||||
EXPECT_EQ(prSample.first.rguiData[2], 0x6d);
|
||||
EXPECT_EQ(prSample.first.rguiData[3], 0x61);
|
||||
EXPECT_EQ(prSample.first.rguiData[4], 0x6e);
|
||||
EXPECT_EQ(prSample.first.rguiData[5], 0x69);
|
||||
EXPECT_EQ(prSample.first.rguiData[6], 0x73);
|
||||
EXPECT_EQ(prSample.first.rguiData[7], 0x6d);
|
||||
EXPECT_EQ(prSample.first.rguiData[8], 0x00);
|
||||
}
|
||||
|
||||
15
tests/unit_tests/asc_format/asc_reader_timing_test.asc
Normal file
15
tests/unit_tests/asc_format/asc_reader_timing_test.asc
Normal file
@@ -0,0 +1,15 @@
|
||||
date Wed Jul 28 06:47:19 pm 2010
|
||||
base hex timestamps absolute
|
||||
internal events logged
|
||||
// version 7.0.1
|
||||
Begin Triggerblock Wed Jul 28 06:47:19 pm 2010
|
||||
0.000000 Start of measurement
|
||||
0.005502 CAN 1 Status:chip status error active
|
||||
0.005675 CAN 2 Status:chip status error active
|
||||
0.007096 1 B6 Rx d 5 06 06 80 00 C8
|
||||
0.007123 2 85 Rx d 8 00 00 00 00 FF FF F3 1D
|
||||
0.007333 1 19E Rx d 8 00 EC EF FC FF 0C 00 85
|
||||
0.110300 2 D8 Rx d 8 01 80 00 FF F8 7F 05 34
|
||||
0.210421 1 A8 Rx d 8 EE 45 01 00 00 00 00 00
|
||||
0.310541 2 E3 Rx d 8 00 80 10 00 FE 7F 05 24
|
||||
End TriggerBlock
|
||||
224
tests/unit_tests/asc_format/asc_writer_test.cpp
Normal file
224
tests/unit_tests/asc_format/asc_writer_test.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include "../../../global/ascformat/ascwriter.cpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include <support/sdv_test_macro.h>
|
||||
|
||||
TEST(CAscWriterTest, AddSamplesDirect)
|
||||
{
|
||||
asc::CAscReader readerGroundThruth;
|
||||
EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Add 20 samples
|
||||
asc::CAscWriter writer;
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
{
|
||||
auto prSample = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
writer.AddSample(prSample.first);
|
||||
++readerGroundThruth;
|
||||
}
|
||||
|
||||
// Write the samples
|
||||
writer.Write(GetExecDirectory() / "asc_writer_test.asc");
|
||||
|
||||
// Read the samples
|
||||
asc::CAscReader readerGenerate;
|
||||
EXPECT_TRUE(readerGenerate.Read(GetExecDirectory() / "asc_writer_test.asc"));
|
||||
|
||||
// Check whether the 20 samples correspond to the original samples
|
||||
readerGroundThruth.JumpBegin();
|
||||
while (!readerGenerate.IsEOF())
|
||||
{
|
||||
auto prSampleGroundTruth = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSampleGroundTruth.second);
|
||||
auto prSampleGenerated = readerGenerate.Get();
|
||||
|
||||
EXPECT_EQ(prSampleGroundTruth.first.dTimestamp, prSampleGenerated.first.dTimestamp);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiChannel, prSampleGenerated.first.uiChannel);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiId, prSampleGenerated.first.uiId);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.bExtended, prSampleGenerated.first.bExtended);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.eDirection, prSampleGenerated.first.eDirection);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiLength, prSampleGenerated.first.uiLength);
|
||||
for (size_t nIndex = 0; nIndex < 64; nIndex++)
|
||||
EXPECT_EQ(prSampleGroundTruth.first.rguiData[nIndex], prSampleGenerated.first.rguiData[nIndex]);
|
||||
|
||||
++readerGroundThruth;
|
||||
++readerGenerate;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CAscWriterTest, AddTimedSamples)
|
||||
{
|
||||
asc::CAscReader readerGroundThruth;
|
||||
EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_test.asc"));
|
||||
|
||||
// Skip 100 samples
|
||||
for (size_t n = 0; n < 100; n++)
|
||||
++readerGroundThruth;
|
||||
EXPECT_FALSE(readerGroundThruth.IsBOF());
|
||||
EXPECT_FALSE(readerGroundThruth.IsEOF());
|
||||
|
||||
// Start the timer
|
||||
asc::CAscWriter writer;
|
||||
writer.StartTimer();
|
||||
|
||||
// Add 250ms of samples
|
||||
readerGroundThruth.StartPlayback([&](const asc::SCanMessage& rsSample)
|
||||
{
|
||||
asc::SCanMessage sSampleCopy(rsSample);
|
||||
sSampleCopy.dTimestamp = 0.000;
|
||||
writer.AddSample(sSampleCopy);
|
||||
}, false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
readerGroundThruth.StopPlayback();
|
||||
|
||||
// Write the samples
|
||||
writer.Write(GetExecDirectory() / "asc_writer_test.asc");
|
||||
|
||||
// Read the samples
|
||||
asc::CAscReader readerGenerate;
|
||||
EXPECT_TRUE(readerGenerate.Read(GetExecDirectory() / "asc_writer_test.asc"));
|
||||
|
||||
// Start at the 101st sample
|
||||
readerGroundThruth.JumpBegin();
|
||||
for (size_t n = 0; n < 100; n++)
|
||||
++readerGroundThruth;
|
||||
|
||||
auto fnRound = [](double dTimestamp) { return std::round(dTimestamp * 1000.0) / 1000.0; };
|
||||
|
||||
// Check whether the samples correspond to the original samples, except for the generated timestamp
|
||||
double dLastTSGroundThruth = fnRound(readerGroundThruth.Get().first.dTimestamp);
|
||||
double dLastTSGenerated = fnRound(readerGenerate.Get().first.dTimestamp);
|
||||
++readerGroundThruth;
|
||||
++readerGenerate;
|
||||
|
||||
while (!readerGenerate.IsEOF())
|
||||
{
|
||||
auto prSampleGroundTruth = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSampleGroundTruth.second);
|
||||
auto prSampleGenerated = readerGenerate.Get();
|
||||
|
||||
// Delta timestamp should not differ more than +/- 2 ms.
|
||||
double dDeltaTSGroundThruth = fnRound(readerGroundThruth.Get().first.dTimestamp) - dLastTSGroundThruth;
|
||||
dLastTSGroundThruth = fnRound(readerGroundThruth.Get().first.dTimestamp);
|
||||
double dDeltaTSGenerated = fnRound(readerGenerate.Get().first.dTimestamp) - dLastTSGenerated;
|
||||
dLastTSGenerated = fnRound(readerGenerate.Get().first.dTimestamp);
|
||||
if (dDeltaTSGenerated < dDeltaTSGroundThruth - 0.002)
|
||||
{
|
||||
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
|
||||
SDV_TIMING_EXPECT_GE(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv::TEST::WarningLevel::WARNING_REDUCED);
|
||||
else
|
||||
SDV_TIMING_EXPECT_GE(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv::TEST::WarningLevel::WARNING_ENABLED);
|
||||
}
|
||||
if (dDeltaTSGenerated > dDeltaTSGroundThruth + 0.002)
|
||||
{
|
||||
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
|
||||
SDV_TIMING_EXPECT_LE(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv::TEST::WarningLevel::WARNING_REDUCED);
|
||||
else
|
||||
SDV_TIMING_EXPECT_LE(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv::TEST::WarningLevel::WARNING_ENABLED);
|
||||
}
|
||||
std::cout << "TIMING: Expected generated timestamp <= ground truth + 2ms (generated=" << dDeltaTSGenerated << "ms, ground truth=" << dDeltaTSGroundThruth << ")..." << std::endl;
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiChannel, prSampleGenerated.first.uiChannel);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiId, prSampleGenerated.first.uiId);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.bExtended, prSampleGenerated.first.bExtended);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.eDirection, prSampleGenerated.first.eDirection);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiLength, prSampleGenerated.first.uiLength);
|
||||
for (size_t nIndex = 0; nIndex < 64; nIndex++)
|
||||
EXPECT_EQ(prSampleGroundTruth.first.rguiData[nIndex], prSampleGenerated.first.rguiData[nIndex]);
|
||||
|
||||
++readerGroundThruth;
|
||||
++readerGenerate;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CAscWriterTest, ExtendedID)
|
||||
{
|
||||
asc::CAscReader readerGroundThruth;
|
||||
SDV_EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_ext_id_test.asc"), sdv::TEST::WarningLevel::WARNING_REDUCED);
|
||||
|
||||
// Add all samples
|
||||
asc::CAscWriter writer;
|
||||
while (!readerGroundThruth.IsEOF())
|
||||
{
|
||||
auto prSample = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
writer.AddSample(prSample.first);
|
||||
++readerGroundThruth;
|
||||
}
|
||||
|
||||
// Write the samples
|
||||
writer.Write(GetExecDirectory() / "asc_writer_test.asc");
|
||||
|
||||
// Read the samples
|
||||
asc::CAscReader readerGenerate;
|
||||
EXPECT_TRUE(readerGenerate.Read(GetExecDirectory() / "asc_writer_test.asc"));
|
||||
|
||||
// Check whether the samples correspond to the original samples
|
||||
readerGroundThruth.JumpBegin();
|
||||
while (!readerGenerate.IsEOF())
|
||||
{
|
||||
auto prSampleGroundTruth = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSampleGroundTruth.second);
|
||||
auto prSampleGenerated = readerGenerate.Get();
|
||||
|
||||
EXPECT_EQ(prSampleGroundTruth.first.dTimestamp, prSampleGenerated.first.dTimestamp);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiChannel, prSampleGenerated.first.uiChannel);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiId, prSampleGenerated.first.uiId);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.bExtended, prSampleGenerated.first.bExtended);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.eDirection, prSampleGenerated.first.eDirection);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiLength, prSampleGenerated.first.uiLength);
|
||||
for (size_t nIndex = 0; nIndex < 64; nIndex++)
|
||||
EXPECT_EQ(prSampleGroundTruth.first.rguiData[nIndex], prSampleGenerated.first.rguiData[nIndex]);
|
||||
|
||||
++readerGroundThruth;
|
||||
++readerGenerate;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CAscWriterTest, CAN_FD)
|
||||
{
|
||||
asc::CAscReader readerGroundThruth;
|
||||
EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_canfd_test.asc"));
|
||||
|
||||
// Add all samples
|
||||
asc::CAscWriter writer;
|
||||
while (!readerGroundThruth.IsEOF())
|
||||
{
|
||||
auto prSample = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSample.second);
|
||||
writer.AddSample(prSample.first);
|
||||
++readerGroundThruth;
|
||||
}
|
||||
|
||||
// Write the samples
|
||||
writer.Write(GetExecDirectory() / "asc_writer_test.asc");
|
||||
|
||||
// Read the samples
|
||||
asc::CAscReader readerGenerate;
|
||||
EXPECT_TRUE(readerGenerate.Read(GetExecDirectory() / "asc_writer_test.asc"));
|
||||
|
||||
// Check whether the samples correspond to the original samples
|
||||
readerGroundThruth.JumpBegin();
|
||||
while (!readerGenerate.IsEOF())
|
||||
{
|
||||
auto prSampleGroundTruth = readerGroundThruth.Get();
|
||||
EXPECT_TRUE(prSampleGroundTruth.second);
|
||||
auto prSampleGenerated = readerGenerate.Get();
|
||||
|
||||
EXPECT_EQ(prSampleGroundTruth.first.dTimestamp, prSampleGenerated.first.dTimestamp);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiChannel, prSampleGenerated.first.uiChannel);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiId, prSampleGenerated.first.uiId);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.bExtended, prSampleGenerated.first.bExtended);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.bCanFd, prSampleGenerated.first.bCanFd);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.eDirection, prSampleGenerated.first.eDirection);
|
||||
EXPECT_EQ(prSampleGroundTruth.first.uiLength, prSampleGenerated.first.uiLength);
|
||||
for (size_t nIndex = 0; nIndex < 64; nIndex++)
|
||||
EXPECT_EQ(prSampleGroundTruth.first.rguiData[nIndex], prSampleGenerated.first.rguiData[nIndex]);
|
||||
|
||||
++readerGroundThruth;
|
||||
++readerGenerate;
|
||||
}
|
||||
}
|
||||
|
||||
19
tests/unit_tests/asc_format/main.cpp
Normal file
19
tests/unit_tests/asc_format/main.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/localmemmgr.h"
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
*/
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
CLocalMemMgr memmgr;
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
39
tests/unit_tests/basic_types/CMakeLists.txt
Normal file
39
tests/unit_tests/basic_types/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# Define project (multiple EXEs)
|
||||
project(BasicTypesTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# BasicTypes unit test executable
|
||||
add_executable(UnitTest_BasicTypes
|
||||
"main.cpp"
|
||||
"basic_types_test.h"
|
||||
"basic_types_test.cpp"
|
||||
"string.cpp"
|
||||
"u8string.cpp"
|
||||
"u16string.cpp"
|
||||
"u32string.cpp"
|
||||
"wstring.cpp"
|
||||
"ptr.cpp"
|
||||
"ptr_simple.cpp"
|
||||
"ptr_complex.cpp"
|
||||
"sequence_simple.cpp"
|
||||
"sequence_complex.cpp"
|
||||
"serdes.cpp"
|
||||
"crc.cpp"
|
||||
"interface.cpp"
|
||||
"any.cpp" )
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(UnitTest_BasicTypes GTest::GTest ${CMAKE_THREAD_LIBS_INIT} stdc++fs)
|
||||
else()
|
||||
target_link_libraries(UnitTest_BasicTypes GTest::GTest)
|
||||
endif()
|
||||
|
||||
# Add the BasicTypes unittest
|
||||
add_test(NAME UnitTest_BasicTypes COMMAND UnitTest_BasicTypes)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_BasicTypes POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_BasicTypes>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_BasicTypes.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(UnitTest_BasicTypes dependency_sdv_components)
|
||||
8033
tests/unit_tests/basic_types/any.cpp
Normal file
8033
tests/unit_tests/basic_types/any.cpp
Normal file
File diff suppressed because it is too large
Load Diff
45
tests/unit_tests/basic_types/basic_types_test.cpp
Normal file
45
tests/unit_tests/basic_types/basic_types_test.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "basic_types_test.h"
|
||||
|
||||
void CBasicTypesTest::SetUpTestCase()
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
void CBasicTypesTest::TearDownTestCase() {}
|
||||
|
||||
void CBasicTypesTest::SetUp()
|
||||
{}
|
||||
|
||||
void CBasicTypesTest::TearDown()
|
||||
{}
|
||||
|
||||
size_t CBasicTypesTestAllocator::GetPtrCount() const
|
||||
{
|
||||
return m_setPointers.size();
|
||||
}
|
||||
|
||||
void CBasicTypesTestAllocator::ResetPtrSet()
|
||||
{
|
||||
m_setPointers.clear();
|
||||
}
|
||||
|
||||
void* CBasicTypesTestAllocator::Alloc(size_t nSize)
|
||||
{
|
||||
void* p = CLocalMemMgr::Alloc(nSize);
|
||||
m_setPointers.insert(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* CBasicTypesTestAllocator::Realloc(void* pData, size_t nSize)
|
||||
{
|
||||
m_setPointers.erase(pData);
|
||||
void* p = CLocalMemMgr::Realloc(pData, nSize);
|
||||
m_setPointers.insert(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void CBasicTypesTestAllocator::Free(void* pData)
|
||||
{
|
||||
m_setPointers.erase(pData);
|
||||
CLocalMemMgr::Free(pData);
|
||||
}
|
||||
162
tests/unit_tests/basic_types/basic_types_test.h
Normal file
162
tests/unit_tests/basic_types/basic_types_test.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef BASIC_TYPES_TEST_H
|
||||
#define BASIC_TYPES_TEST_H
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define NO_SDV_LOCAL_CORE_FUNC
|
||||
#include "../../../global/localmemmgr.h"
|
||||
|
||||
class CBasicTypesTestAllocator : public CLocalMemMgr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Get the amount of pointers allocated.
|
||||
* @return
|
||||
*/
|
||||
size_t GetPtrCount() const;
|
||||
|
||||
/**
|
||||
* @brief Reset the pointer set to start a new measurement.
|
||||
*/
|
||||
void ResetPtrSet();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Allocate memory. Overload of sdv::internal::IInternalMemAlloc::Alloc.
|
||||
* @param[in] nSize The size of the memory to allocate (in bytes).
|
||||
* @return Pointer to the memory allocation or NULL when memory allocation failed.
|
||||
*/
|
||||
virtual void* Alloc(size_t nSize) override;
|
||||
|
||||
/**
|
||||
* @brief Reallocate memory. Overload of sdv::internal::IInternalMemAlloc::Realloc.
|
||||
* @param[in] pData Pointer to a previous allocation or NULL when no previous allocation was available.
|
||||
* @param[in] nSize The size of the memory to allocate (in bytes).
|
||||
* @return Pointer to the memory allocation or NULL when memory allocation failed.
|
||||
*/
|
||||
virtual void* Realloc(void* pData, size_t nSize) override;
|
||||
|
||||
/**
|
||||
* @brief Free a memory allocation. Overload of sdv::internal::IInternalMemAlloc::Free.
|
||||
* @param[in] pData Pointer to a previous allocation.
|
||||
*/
|
||||
virtual void Free(void* pData) override;
|
||||
|
||||
std::set<void*> m_setPointers; ///< Pointer set for pointer tracking.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get the instance of the local memory manager.
|
||||
* @return Reference to the memory manager.
|
||||
*/
|
||||
inline CBasicTypesTestAllocator& GetMemMgr()
|
||||
{
|
||||
static CBasicTypesTestAllocator memmgr;
|
||||
return memmgr;
|
||||
}
|
||||
|
||||
namespace sdv
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
/**
|
||||
* @brief Access to the core.
|
||||
* @return Smart pointer to the core services interface.
|
||||
*/
|
||||
inline TInterfaceAccessPtr GetCore()
|
||||
{
|
||||
static CBasicTypesTestAllocator& rmemmgr = ::GetMemMgr();
|
||||
return &rmemmgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access to specific interface of the core.
|
||||
* @tparam TInterface Type of interface to return.
|
||||
* @return Pointer to the interface or NULL when the interface was not exposed.
|
||||
*/
|
||||
template <typename TInterface>
|
||||
inline TInterface* GetCore()
|
||||
{
|
||||
return GetCore().GetInterface<TInterface>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test class for code genertion tests.
|
||||
*/
|
||||
class CBasicTypesTest : public testing::Test
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicTypesTest() = default;
|
||||
|
||||
/**
|
||||
* @brief Set up the test suite.
|
||||
*/
|
||||
static void SetUpTestCase();
|
||||
|
||||
/**
|
||||
* @brief Tear down the test suite.
|
||||
*/
|
||||
static void TearDownTestCase();
|
||||
|
||||
/**
|
||||
* @brief Test setup.
|
||||
*/
|
||||
void SetUp() override;
|
||||
|
||||
/**
|
||||
* @brief Test teardown.
|
||||
*/
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
namespace testing::internal
|
||||
{
|
||||
// Helper function for *_STREQ on wide strings.
|
||||
inline AssertionResult CmpHelperSTREQ(const char* lhs_expression, const char* rhs_expression, const char16_t* lhs, const char16_t* rhs)
|
||||
{
|
||||
if (std::equal(lhs, lhs + std::char_traits<char16_t>::length(lhs), rhs))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), PrintToString(rhs), false);
|
||||
}
|
||||
|
||||
inline AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char16_t* lhs, const char16_t* rhs)
|
||||
{
|
||||
if (!std::equal(lhs, lhs + std::char_traits<char16_t>::length(lhs), rhs))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression
|
||||
<< "), actual: " << PrintToString(lhs) << " vs " << PrintToString(rhs);
|
||||
}
|
||||
|
||||
inline AssertionResult CmpHelperSTREQ(const char* lhs_expression, const char* rhs_expression, const char32_t* lhs, const char32_t* rhs)
|
||||
{
|
||||
if (std::equal(lhs, lhs + std::char_traits<char32_t>::length(lhs), rhs))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), PrintToString(rhs), false);
|
||||
}
|
||||
|
||||
inline AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char32_t* lhs, const char32_t* rhs)
|
||||
{
|
||||
if (!std::equal(lhs, lhs + std::char_traits<char32_t>::length(lhs), rhs))
|
||||
{
|
||||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression
|
||||
<< "), actual: " << PrintToString(lhs) << " vs " << PrintToString(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined BASIC_TYPES_TEST_H
|
||||
102
tests/unit_tests/basic_types/crc.cpp
Normal file
102
tests/unit_tests/basic_types/crc.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include <support/crc.h>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CCrcTest = CBasicTypesTest;
|
||||
|
||||
TEST_F(CCrcTest, BitReflection)
|
||||
{
|
||||
uint8_t ui8 = 0b11001010;
|
||||
EXPECT_EQ(sdv::reflect(ui8), 0b01010011);
|
||||
uint16_t ui16 = 0b0111001111001010;
|
||||
EXPECT_EQ(sdv::reflect(ui16), 0b0101001111001110);
|
||||
uint32_t ui32 = 0b01110011110010100111001111001010u;
|
||||
EXPECT_EQ(sdv::reflect(ui32), 0b01010011110011100101001111001110u);
|
||||
uint64_t ui64 = 0b0111001111001010011100111100101001110011110010100111001111001010ull;
|
||||
EXPECT_EQ(sdv::reflect(ui64), 0b0101001111001110010100111100111001010011110011100101001111001110ull);
|
||||
}
|
||||
|
||||
TEST_F(CCrcTest, CalcCRC)
|
||||
{
|
||||
// Create data table
|
||||
constexpr auto arrTable = []
|
||||
{
|
||||
std::array<uint8_t, 1024> arrTemp{};
|
||||
for (size_t n = 0; n < 1024; n++)
|
||||
arrTemp[n] = static_cast<uint8_t>(n & 0xff);
|
||||
return arrTemp;
|
||||
}();
|
||||
|
||||
// Use http://www.sunshine2k.de/coding/javascript/crc/crc_js.html to check the CRC values.
|
||||
// for (size_t nRow = 0; nRow < 64; nRow++)
|
||||
//{
|
||||
// for (size_t nCol = 0; nCol < 16; nCol++)
|
||||
// std::cout << " 0x" << std::setfill('0') << std::setw(2) << std::hex << (int)arrTable[nRow * 16 + nCol];
|
||||
// std::cout << std::endl;
|
||||
//}
|
||||
|
||||
// SAE-J1850: polynomial 0x1D, initial = 0xFF, final_xor = 0xFF, reflect_input = false, reflect_output = false
|
||||
sdv::crcSAE_J1850 crcSAE_J1850;
|
||||
EXPECT_EQ(crcSAE_J1850.calc_checksum(arrTable.data(), 1024), 0x84);
|
||||
|
||||
// AUTOSAR_8H2F: polynomial 0x2F, initial = 0xFF, final_xor = 0xFF, reflect_input = false, reflect_output = false)
|
||||
sdv::crcAUTOSAR_8H2F crcAUTOSAR_8H2F;
|
||||
EXPECT_EQ(crcAUTOSAR_8H2F.calc_checksum(arrTable.data(), 1024), 0x36);
|
||||
|
||||
// CCITT-FALSE: polynomial 0x1021, initial = 0xFFFF, final_xor = 0, reflect_input = false, reflect_output = false
|
||||
sdv::crcCCITT_FALSE crcCCITT_FALSE;
|
||||
EXPECT_EQ(crcCCITT_FALSE.calc_checksum(arrTable.data(), 1024), 0x758f);
|
||||
|
||||
// ARC: polynomial 0x8005, initial = 0, final_xor = 0, reflect_input = true, reflect_output = true
|
||||
sdv::crcARC crcARC;
|
||||
EXPECT_EQ(crcARC.calc_checksum(arrTable.data(), 1024), 0x3840);
|
||||
|
||||
// IEEE_802_3 polynomial 0x04C11DB7, initial = 0xFFFFFFFF, final_xor = 0xFFFFFFFF, reflect_input = true, reflect_output = true
|
||||
sdv::crcIEEE_802_3 crcIEEE_802_3;
|
||||
EXPECT_EQ(crcIEEE_802_3.calc_checksum(arrTable.data(), 1024), 0xB70B4C26);
|
||||
|
||||
// AUTOSAR_P4 polynomial 0xF4ACFB13, initial = 0xFFFFFFFF, final_xor = 0xFFFFFFFF, reflect_input = true, reflect_output = true
|
||||
sdv::crcAUTOSAR_P4 crcAUTOSAR_P4;
|
||||
EXPECT_EQ(crcAUTOSAR_P4.calc_checksum(arrTable.data(), 1024), 0xCF0881B6);
|
||||
|
||||
// CRC32-C Castagnoli polynomial 0x1EDC6F41, initial = 0xFFFFFFFF, final_xor = 0xFFFFFFFF, reflect_input = true, reflect_output
|
||||
// = true
|
||||
sdv::crcCRC32C crcCRC32C;
|
||||
EXPECT_EQ(crcCRC32C.calc_checksum(arrTable.data(), 1024), 0x2CDF6E8Fu);
|
||||
|
||||
// ECMA (polynomial 0x42F0E1EBA9EA3693, initial = 0xFFFFFFFFFFFFFFFF, final_xor = 0xFFFFFFFFFFFFFFFF, reflect_input = true,
|
||||
// reflect_output = true)
|
||||
sdv::crcECMA crcECMA;
|
||||
EXPECT_EQ(crcECMA.calc_checksum(arrTable.data(), 1024), 0xD51FB58DC789C400);
|
||||
}
|
||||
|
||||
TEST_F(CCrcTest, CalcPartialCRC)
|
||||
{
|
||||
// Create data table
|
||||
constexpr auto arrTable = []
|
||||
{
|
||||
std::array<uint8_t, 1024> arrTemp{};
|
||||
for (size_t n = 0; n < 1024; n++)
|
||||
arrTemp[n] = static_cast<uint8_t>(n & 0xff);
|
||||
return arrTemp;
|
||||
}();
|
||||
|
||||
sdv::crcCRC32C crcCRC32C;
|
||||
|
||||
// Full calculation
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0x00000000u);
|
||||
crcCRC32C.calc_checksum(arrTable.data(), 1024);
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0x2CDF6E8Fu);
|
||||
|
||||
// Partial calulcation
|
||||
crcCRC32C.reset();
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0x00000000u);
|
||||
crcCRC32C.calc_checksum(arrTable.data(), 512);
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0xAE10EE5Au);
|
||||
crcCRC32C.calc_checksum(arrTable.data() + 512, 512);
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0x2CDF6E8Fu);
|
||||
|
||||
crcCRC32C.set_checksum(0xAE10EE5Au);
|
||||
crcCRC32C.calc_checksum(arrTable.data() + 512, 512);
|
||||
EXPECT_EQ(crcCRC32C.get_checksum(), 0x2CDF6E8Fu);
|
||||
}
|
||||
162
tests/unit_tests/basic_types/interface.cpp
Normal file
162
tests/unit_tests/basic_types/interface.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <support/string.h>
|
||||
#include <sstream>
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CInterfaceTypeTest = CBasicTypesTest;
|
||||
|
||||
// Test class
|
||||
class CTest : public sdv::IInterfaceAccess, public sdv::core::IMemoryAlloc
|
||||
{
|
||||
public:
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
/**
|
||||
* @brief Allocate a memory block of the provided length. Overload of IMemoryAlloc::Allocate.
|
||||
* @param[in] uiLength The length of the memory block to allocate.
|
||||
* @return Smart pointer to the memory allocation or NULL when allocating was not possible.
|
||||
*/
|
||||
virtual sdv::pointer<uint8_t> Allocate(/*in*/ uint32_t /*uiLength*/) override { return sdv::pointer<uint8_t>(); };
|
||||
|
||||
};
|
||||
|
||||
TEST_F(CInterfaceTypeTest, Constructor)
|
||||
{
|
||||
sdv::interface_t ifc;
|
||||
EXPECT_FALSE(ifc);
|
||||
|
||||
CTest test;
|
||||
sdv::interface_t ifc2(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
EXPECT_TRUE(ifc2);
|
||||
|
||||
sdv::interface_t ifc3(ifc2);
|
||||
EXPECT_TRUE(ifc3);
|
||||
EXPECT_EQ(ifc2, ifc3);
|
||||
|
||||
sdv::interface_t ifc4(std::move(ifc3));
|
||||
EXPECT_FALSE(ifc3);
|
||||
EXPECT_TRUE(ifc4);
|
||||
EXPECT_EQ(ifc2, ifc4);
|
||||
|
||||
sdv::interface_t ifc5(nullptr);
|
||||
EXPECT_FALSE(ifc5);
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, AssignmentOperator)
|
||||
{
|
||||
sdv::interface_t ifc, ifc2, ifc3;
|
||||
EXPECT_FALSE(ifc);
|
||||
EXPECT_FALSE(ifc2);
|
||||
EXPECT_FALSE(ifc3);
|
||||
|
||||
CTest test;
|
||||
ifc = static_cast<sdv::IInterfaceAccess*>(&test);
|
||||
EXPECT_TRUE(ifc);
|
||||
|
||||
ifc2 = ifc;
|
||||
EXPECT_TRUE(ifc);
|
||||
EXPECT_TRUE(ifc2);
|
||||
|
||||
ifc3 = std::move(ifc2);
|
||||
EXPECT_TRUE(ifc3);
|
||||
EXPECT_FALSE(ifc2);
|
||||
|
||||
ifc3 = nullptr;
|
||||
EXPECT_FALSE(ifc3);
|
||||
|
||||
ifc = static_cast<sdv::core::IMemoryAlloc*>(&test);
|
||||
EXPECT_TRUE(ifc);
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, Reset)
|
||||
{
|
||||
CTest test;
|
||||
sdv::interface_t ifc(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
EXPECT_TRUE(ifc);
|
||||
|
||||
ifc.reset();
|
||||
EXPECT_FALSE(ifc);
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, ID)
|
||||
{
|
||||
CTest test;
|
||||
sdv::interface_t ifc(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
EXPECT_TRUE(ifc);
|
||||
EXPECT_EQ(ifc.id(), sdv::GetInterfaceId<sdv::IInterfaceAccess>());
|
||||
|
||||
ifc = static_cast<sdv::core::IMemoryAlloc*>(&test);
|
||||
EXPECT_EQ(ifc.id(), sdv::GetInterfaceId<sdv::core::IMemoryAlloc>());
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, Get)
|
||||
{
|
||||
CTest test;
|
||||
sdv::interface_t ifc(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
EXPECT_TRUE(ifc);
|
||||
EXPECT_EQ(ifc.template get<sdv::IInterfaceAccess>(), static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
EXPECT_EQ(ifc.template get<sdv::core::IMemoryAlloc>(), nullptr);
|
||||
|
||||
ifc = static_cast<sdv::core::IMemoryAlloc*>(&test);
|
||||
EXPECT_EQ(ifc.template get<sdv::core::IMemoryAlloc>(), static_cast<sdv::core::IMemoryAlloc*>(&test));
|
||||
EXPECT_EQ(ifc.template get<sdv::IInterfaceAccess>(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, Compare)
|
||||
{
|
||||
CTest test;
|
||||
sdv::interface_t ifc(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
sdv::interface_t ifc2(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
sdv::interface_t ifc3(static_cast<sdv::core::IMemoryAlloc*>(&test));
|
||||
EXPECT_TRUE(ifc);
|
||||
EXPECT_TRUE(ifc2);
|
||||
EXPECT_TRUE(ifc3);
|
||||
|
||||
EXPECT_EQ(ifc.compare(ifc2), 0);
|
||||
if (sdv::GetInterfaceId<sdv::IInterfaceAccess>() > sdv::GetInterfaceId<sdv::core::IMemoryAlloc>())
|
||||
EXPECT_GT(ifc.compare(ifc3), 0);
|
||||
else
|
||||
EXPECT_LT(ifc.compare(ifc3), 0);
|
||||
}
|
||||
|
||||
TEST_F(CInterfaceTypeTest, CompareOperators)
|
||||
{
|
||||
CTest test;
|
||||
sdv::interface_t ifc(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
sdv::interface_t ifc2(static_cast<sdv::IInterfaceAccess*>(&test));
|
||||
sdv::interface_t ifc3(static_cast<sdv::core::IMemoryAlloc*>(&test));
|
||||
sdv::interface_t ifc4;
|
||||
EXPECT_TRUE(ifc);
|
||||
EXPECT_TRUE(ifc2);
|
||||
EXPECT_TRUE(ifc3);
|
||||
|
||||
EXPECT_EQ(ifc, ifc2);
|
||||
EXPECT_NE(ifc2, ifc3);
|
||||
if (sdv::GetInterfaceId<sdv::IInterfaceAccess>() > sdv::GetInterfaceId<sdv::core::IMemoryAlloc>())
|
||||
{
|
||||
EXPECT_GT(ifc2, ifc3);
|
||||
EXPECT_GE(ifc2, ifc3);
|
||||
EXPECT_LT(ifc3, ifc2);
|
||||
EXPECT_LE(ifc3, ifc2);
|
||||
} else
|
||||
{
|
||||
EXPECT_GT(ifc3, ifc2);
|
||||
EXPECT_GE(ifc3, ifc2);
|
||||
EXPECT_LT(ifc2, ifc3);
|
||||
EXPECT_LE(ifc2, ifc3);
|
||||
}
|
||||
|
||||
EXPECT_NE(ifc2, nullptr);
|
||||
EXPECT_NE(nullptr, ifc2);
|
||||
EXPECT_GT(ifc2, nullptr);
|
||||
EXPECT_GE(ifc2, nullptr);
|
||||
EXPECT_FALSE(ifc2 < nullptr);
|
||||
EXPECT_FALSE(ifc2 <= nullptr);
|
||||
EXPECT_LT(nullptr, ifc2);
|
||||
EXPECT_LE(nullptr, ifc2);
|
||||
EXPECT_FALSE(nullptr > ifc2);
|
||||
EXPECT_FALSE(nullptr >= ifc2);
|
||||
EXPECT_EQ(nullptr, ifc4);
|
||||
EXPECT_EQ(ifc4, nullptr);
|
||||
}
|
||||
14
tests/unit_tests/basic_types/main.cpp
Normal file
14
tests/unit_tests/basic_types/main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
935
tests/unit_tests/basic_types/ptr.cpp
Normal file
935
tests/unit_tests/basic_types/ptr.cpp
Normal file
@@ -0,0 +1,935 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <support/pointer.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
// There are some versions of GCC that produce bogus warnings for -Wstringop-overflow (e.g. version 9.4 warns, 11.4 not - changing
|
||||
// the compile order without changing the logical behavior, will produce different results).
|
||||
// See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100477
|
||||
// And https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115074
|
||||
// Suppress this warning for the string class.
|
||||
// NOTE 03.08.2025: Additional bogus warnigs/errors are suppressed for newer versions of the compiler.
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
|
||||
using CPointerTypeTest = CBasicTypesTest;
|
||||
|
||||
TEST_F(CPointerTypeTest, MakeFixedPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t, 1> ptr0;
|
||||
EXPECT_TRUE(ptr0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, MakeDynamicPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t> ptr0 = sdv::make_ptr<uint32_t>(0);
|
||||
EXPECT_TRUE(ptr0);
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr1);
|
||||
sdv::pointer<uint32_t> ptr2 = sdv::make_ptr<uint32_t>(2);
|
||||
EXPECT_TRUE(ptr2);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ConstructorDynamicPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move constructor
|
||||
sdv::pointer<uint32_t> ptrMove(std::move(ptr));
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
|
||||
// Destructor
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<uint32_t>* pptr = new sdv::pointer<uint32_t>(sdv::make_ptr<uint32_t>());
|
||||
EXPECT_NE(pptr, nullptr);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
delete pptr;
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ConstructorFixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t, 1> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1(ptr);
|
||||
EXPECT_TRUE(ptrCopy1);
|
||||
EXPECT_EQ(ptrCopy1.size(), 0);
|
||||
sdv::pointer<uint32_t, 10> ptrCopy10(ptr);
|
||||
EXPECT_TRUE(ptrCopy10);
|
||||
EXPECT_EQ(ptrCopy10.size(), 0);
|
||||
using TCopy2 = sdv::pointer<uint32_t, 2>;
|
||||
EXPECT_NO_THROW(TCopy2 ptrCopy2(ptrCopy10));
|
||||
ptrCopy10.resize(5);
|
||||
EXPECT_EQ(ptrCopy10.size(), 5);
|
||||
using TCopy3 = sdv::pointer<uint32_t, 3>;
|
||||
EXPECT_THROW(TCopy3 ptrCopy3(ptrCopy10), sdv::XBufferTooSmall);
|
||||
|
||||
// Move constructor
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1);
|
||||
sdv::pointer<uint32_t, 1> ptrMove(std::move(ptr));
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptrMove.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ConstructorMixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t> ptr0;
|
||||
sdv::pointer<uint32_t, 1> ptr1;
|
||||
sdv::pointer<uint32_t, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy0a(ptr0);
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
using TCopy2 = sdv::pointer<uint32_t, 2>;
|
||||
EXPECT_THROW(TCopy2 ptrCopy2a(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1);
|
||||
EXPECT_THROW(TCopy2 ptrCopy2c(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, AssignmentOperatorsDynamicPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<uint32_t> ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy assignment
|
||||
sdv::pointer<uint32_t> ptrCopy;
|
||||
EXPECT_FALSE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<uint32_t> ptrMove;
|
||||
EXPECT_FALSE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, AssignmentOperatorsFixedPointer)
|
||||
{
|
||||
// Copy assignment
|
||||
sdv::pointer<uint32_t, 3> ptr;
|
||||
sdv::pointer<uint32_t, 1> ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_EQ(ptrCopy.size(), 1);
|
||||
ptr.resize(2);
|
||||
EXPECT_EQ(ptr.size(), 2);
|
||||
EXPECT_THROW(ptrCopy = ptr, sdv::XBufferTooSmall);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<uint32_t, 3> ptrMove;
|
||||
EXPECT_TRUE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, AssignmentOperatorsMixedPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t> ptr0;
|
||||
sdv::pointer<uint32_t, 1> ptr1;
|
||||
sdv::pointer<uint32_t, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy0a;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
ptrCopy0a = ptr0;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0b;
|
||||
EXPECT_FALSE(ptrCopy0b);
|
||||
ptrCopy0b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0c;
|
||||
EXPECT_FALSE(ptrCopy0c);
|
||||
ptrCopy0c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1a;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
ptrCopy1a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1b;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
ptrCopy1b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1c;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
ptrCopy1c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2a;
|
||||
EXPECT_TRUE(ptrCopy2a);
|
||||
EXPECT_THROW(ptrCopy2a = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2b;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
ptrCopy2b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2c;
|
||||
EXPECT_TRUE(ptrCopy2c);
|
||||
EXPECT_THROW(ptrCopy2c = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3a;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
ptrCopy3a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3b;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
ptrCopy3b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3c;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
ptrCopy3c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, AttachmentDynamicPointer)
|
||||
{
|
||||
// Functions are protected. Derive the class to access the functions
|
||||
class CDerivedPtr : public sdv::pointer<uint32_t>
|
||||
{
|
||||
public:
|
||||
void attach(pointer<uint8_t>&& rptrBuffer) { sdv::pointer<uint32_t>::attach(std::move(rptrBuffer)); }
|
||||
pointer<uint8_t>&& detach() { return sdv::pointer<uint32_t>::detach(); }
|
||||
};
|
||||
|
||||
// Create the buffer
|
||||
sdv::pointer<uint8_t> ptrBuffer = sdv::make_ptr<uint8_t>(101);
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 101);
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
|
||||
// Attach
|
||||
CDerivedPtr ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
ptr.attach(std::move(ptrBuffer));
|
||||
EXPECT_FALSE(ptrBuffer);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 25);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Detach
|
||||
ptrBuffer = ptr.detach();
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 101);
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ResetFunctionStaticPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<uint32_t, 10> ptr;
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10);
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ResetFunction)
|
||||
{
|
||||
// Create pointer
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<uint32_t> ptr = sdv::make_ptr<uint32_t>();
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, SwapFunctionStaticPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t, 250> ptr1;
|
||||
EXPECT_TRUE(ptr1);
|
||||
ptr1.resize(100);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<uint32_t, 150> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr3.size(), 100);
|
||||
EXPECT_EQ(ptr1.size(), 0);
|
||||
sdv::pointer<uint32_t, 150> ptr4;
|
||||
EXPECT_THROW(sdv::swap(ptr4, ptr2), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, SwapFunctionDynamicPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t> ptr2 = sdv::make_ptr<uint32_t>(200);
|
||||
EXPECT_TRUE(ptr2);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<uint32_t> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_FALSE(ptr1);
|
||||
sdv::swap(ptr3, ptr1);
|
||||
EXPECT_FALSE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, SwapFunctionMixedPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, AccessFunctions)
|
||||
{
|
||||
struct STest
|
||||
{
|
||||
uint32_t uiValue;
|
||||
};
|
||||
|
||||
// Empty pointer
|
||||
sdv::pointer<STest> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Get
|
||||
EXPECT_EQ(ptr.get(), nullptr);
|
||||
EXPECT_THROW(*ptr, sdv::XNullPointer);
|
||||
EXPECT_THROW(ptr->uiValue, sdv::XNullPointer);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<STest>(100);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
|
||||
// Get function
|
||||
EXPECT_NE(ptr.get(), nullptr);
|
||||
|
||||
// Assign the value to the array
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr.get()[uiIndex].uiValue = uiIndex;
|
||||
|
||||
// Reference functions
|
||||
EXPECT_EQ((*ptr).uiValue, 0u);
|
||||
*ptr = STest{101u};
|
||||
EXPECT_EQ(ptr->uiValue, 101u);
|
||||
EXPECT_EQ((*ptr.get()).uiValue, 101u);
|
||||
ptr->uiValue = 0;
|
||||
EXPECT_EQ((*ptr).uiValue, 0u);
|
||||
EXPECT_EQ((*ptr.get()).uiValue, 0u);
|
||||
|
||||
// Indexed values
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = STest{uiIndex + 200u};
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
EXPECT_EQ(ptr.get()[uiIndex].uiValue, uiIndex + 200u);
|
||||
EXPECT_THROW(ptr[100], sdv::XIndexOutOfRange);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, SizeFunctionsStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 150> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
|
||||
// Resize to many
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Exceed buffer capacity
|
||||
EXPECT_THROW(ptr.resize(151), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, SizeFunctionsDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(ptr.capacity(), 100);
|
||||
|
||||
// Allocate zero
|
||||
ptr = sdv::make_ptr<uint32_t>(0);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptr.capacity(), 0);
|
||||
|
||||
// Resize to many
|
||||
ptr.resize(100);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Copy the pointer an resize to giant; both pointers should still be valid.
|
||||
sdv::pointer<uint32_t> ptrGiant(ptr);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
ptrGiant.resize(1024 * 1024 * 8);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, RefCountFunctionDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_EQ(ptr.ref_count(), 0);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Copy
|
||||
sdv::pointer<uint32_t> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 2);
|
||||
sdv::pointer<uint32_t> ptrCopy2;
|
||||
EXPECT_FALSE(ptrCopy2);
|
||||
ptrCopy2 = ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
|
||||
// Move
|
||||
sdv::pointer<uint32_t> ptrMove(std::move(ptrCopy));
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
sdv::pointer<uint32_t> ptrMove2;
|
||||
EXPECT_FALSE(ptrMove2);
|
||||
ptrMove2 = std::move(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 3);
|
||||
|
||||
// Reset
|
||||
ptrMove.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 2);
|
||||
ptrMove2.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, CompareOperatorStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 10> ptrLeft;
|
||||
sdv::pointer<uint32_t, 15> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex] = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, CompareOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptrLeft, ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Allocate one pointer
|
||||
ptrLeft = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_TRUE(ptrLeft);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
|
||||
// Reallocate left allocation
|
||||
ptrLeft = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, CompareOperatorMixedPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 10> ptrLeft;
|
||||
sdv::pointer<uint32_t> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex] = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, CompareNullOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
|
||||
// Allocate one pointer
|
||||
ptr = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_FALSE(ptr == nullptr);
|
||||
EXPECT_FALSE(nullptr == ptr);
|
||||
EXPECT_TRUE(ptr != nullptr);
|
||||
EXPECT_TRUE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_TRUE(nullptr < ptr);
|
||||
EXPECT_FALSE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_TRUE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_FALSE(nullptr >= ptr);
|
||||
|
||||
// Free allocation
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, StreamOperatorStaticPointer)
|
||||
{
|
||||
// Stream one number
|
||||
std::stringstream sstream;
|
||||
sdv::pointer<uint32_t, 1> ptr;
|
||||
ptr.resize(1);
|
||||
*ptr = 100;
|
||||
sstream << ptr;
|
||||
EXPECT_EQ(sstream.str(), "100");
|
||||
|
||||
// Stream multiple numbers
|
||||
std::stringstream sstream2;
|
||||
sdv::pointer<uint32_t, 10> ptr2;
|
||||
ptr2.resize(10);
|
||||
for (uint32_t uiIndex = 0u; uiIndex < 10u; uiIndex++)
|
||||
ptr2[uiIndex] = 100u + uiIndex;
|
||||
sstream2 << ptr2;
|
||||
EXPECT_EQ(sstream2.str(), "100101102103104105106107108109");
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, StreamOperatorDynamicPointer)
|
||||
{
|
||||
// Stream one number
|
||||
std::stringstream sstream;
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
ptr = sdv::make_ptr<uint32_t>();
|
||||
*ptr = 100;
|
||||
sstream << ptr;
|
||||
EXPECT_EQ(sstream.str(), "100");
|
||||
|
||||
// Stream multiple numbers
|
||||
std::stringstream sstream2;
|
||||
ptr = sdv::make_ptr<uint32_t>(10);
|
||||
for (uint32_t uiIndex = 0u; uiIndex < 10u; uiIndex++)
|
||||
ptr[uiIndex] = 100u + uiIndex;
|
||||
sstream2 << ptr;
|
||||
EXPECT_EQ(sstream2.str(), "100101102103104105106107108109");
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, MakePointerFromStream)
|
||||
{
|
||||
std::stringstream sstream;
|
||||
sstream << "Hello, this is a text which should be used to check the from-stream functionality!";
|
||||
sdv::pointer<uint8_t> ptrData = sdv::from_stream(sstream.rdbuf());
|
||||
ASSERT_EQ(ptrData.size(), sstream.str().size());
|
||||
// NOTE: Since the C-string is zero base, it is not possible to do a simple string compare.
|
||||
EXPECT_EQ(memcmp(sstream.str().c_str(), ptrData.get(), ptrData.size()), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, StorePointerIntoStream)
|
||||
{
|
||||
char sz[] = "Hello, this is a text which should be used to check the to-stream functionality!";
|
||||
sdv::pointer<uint8_t> ptrData;
|
||||
ptrData.resize(sizeof(sz));
|
||||
ASSERT_EQ(ptrData.size(), sizeof(sz));
|
||||
std::copy(std::begin(sz), std::end(sz), ptrData.get());
|
||||
std::stringstream sstream;
|
||||
sdv::to_stream(ptrData, sstream.rdbuf());
|
||||
// NOTE: Since the C-string is zero base, it is not possible to do a simple string compare.
|
||||
EXPECT_EQ(memcmp(sstream.str().c_str(), sz, ptrData.size()), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, CastFromPointer)
|
||||
{
|
||||
struct STest
|
||||
{
|
||||
int32_t i32 = 10;
|
||||
uint16_t ui16 = 99;
|
||||
char sz[2] = { 'a', 'b' };
|
||||
int64_t i64 = -98765432;
|
||||
uint64_t ui64 = 123456789;
|
||||
} test;
|
||||
|
||||
// Test for exact size
|
||||
sdv::pointer<uint8_t> ptrNoOffset;
|
||||
ptrNoOffset.resize(sizeof(test));
|
||||
ASSERT_EQ(ptrNoOffset.size(), sizeof(test));
|
||||
std::memcpy(ptrNoOffset.get(), &test, sizeof(STest));
|
||||
STest* pTest = sdv::cast<STest>(ptrNoOffset);
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test for smaller size
|
||||
sdv::pointer<uint8_t> ptrSmaller;
|
||||
ptrSmaller.resize(sizeof(test));
|
||||
ASSERT_EQ(ptrSmaller.size(), sizeof(test));
|
||||
std::memcpy(ptrSmaller.get(), &test, sizeof(STest));
|
||||
ptrSmaller.resize(sizeof(STest) - 1);
|
||||
pTest = sdv::cast<STest>(ptrSmaller);
|
||||
EXPECT_EQ(pTest, nullptr);
|
||||
|
||||
// Test for larger size
|
||||
sdv::pointer<uint8_t> ptrLarger;
|
||||
ptrLarger.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrLarger.size(), sizeof(test));
|
||||
std::memcpy(ptrLarger.get(), &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(ptrLarger);
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test with offset
|
||||
sdv::pointer<uint8_t> ptrOffset;
|
||||
ptrOffset.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrOffset.size(), sizeof(test));
|
||||
std::memcpy(ptrOffset.get() + 100, &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(ptrOffset, 100);
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test with offset, beyond size
|
||||
sdv::pointer<uint8_t> ptrOffsetBeyond;
|
||||
ptrOffsetBeyond.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrOffsetBeyond.size(), sizeof(test));
|
||||
std::memcpy(ptrOffsetBeyond.get() + 100, &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(ptrOffsetBeyond, 101);
|
||||
EXPECT_EQ(pTest, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CPointerTypeTest, ConstCastFromPointer)
|
||||
{
|
||||
struct STest
|
||||
{
|
||||
int32_t i32 = 10;
|
||||
uint16_t ui16 = 99;
|
||||
char sz[2] = { 'a', 'b' };
|
||||
int64_t i64 = -98765432;
|
||||
uint64_t ui64 = 123456789;
|
||||
} test;
|
||||
|
||||
// Test for exact size
|
||||
sdv::pointer<uint8_t> ptrNoOffset;
|
||||
ptrNoOffset.resize(sizeof(test));
|
||||
ASSERT_EQ(ptrNoOffset.size(), sizeof(test));
|
||||
std::memcpy(ptrNoOffset.get(), &test, sizeof(STest));
|
||||
const STest* pTest = sdv::cast<STest>(static_cast<const sdv::pointer<uint8_t>&>(ptrNoOffset));
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test for smaller size
|
||||
sdv::pointer<uint8_t> ptrSmaller;
|
||||
ptrSmaller.resize(sizeof(test));
|
||||
ASSERT_EQ(ptrSmaller.size(), sizeof(test));
|
||||
std::memcpy(ptrSmaller.get(), &test, sizeof(STest));
|
||||
ptrSmaller.resize(sizeof(STest) - 1);
|
||||
pTest = sdv::cast<STest>(static_cast<const sdv::pointer<uint8_t>&>(ptrSmaller));
|
||||
EXPECT_EQ(pTest, nullptr);
|
||||
|
||||
// Test for larger size
|
||||
sdv::pointer<uint8_t> ptrLarger;
|
||||
ptrLarger.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrLarger.size(), sizeof(test));
|
||||
std::memcpy(ptrLarger.get(), &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(static_cast<const sdv::pointer<uint8_t>&>(ptrLarger));
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test with offset
|
||||
sdv::pointer<uint8_t> ptrOffset;
|
||||
ptrOffset.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrOffset.size(), sizeof(test));
|
||||
std::memcpy(ptrOffset.get() + 100, &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(static_cast<const sdv::pointer<uint8_t>&>(ptrOffset), 100);
|
||||
EXPECT_NE(pTest, nullptr);
|
||||
EXPECT_EQ(std::memcmp(&test, pTest, sizeof(STest)), 0);
|
||||
|
||||
// Test with offset, beyond size
|
||||
sdv::pointer<uint8_t> ptrOffsetBeyond;
|
||||
ptrOffsetBeyond.resize(sizeof(test) + 100);
|
||||
ASSERT_GT(ptrOffsetBeyond.size(), sizeof(test));
|
||||
std::memcpy(ptrOffsetBeyond.get() + 100, &test, sizeof(STest));
|
||||
pTest = sdv::cast<STest>(static_cast<const sdv::pointer<uint8_t>&>(ptrOffsetBeyond), 101);
|
||||
EXPECT_EQ(pTest, nullptr);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
869
tests/unit_tests/basic_types/ptr_complex.cpp
Normal file
869
tests/unit_tests/basic_types/ptr_complex.cpp
Normal file
@@ -0,0 +1,869 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <support/pointer.h>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CPointerComplexTypeTest = CBasicTypesTest;
|
||||
|
||||
struct SComplexStruct
|
||||
{
|
||||
sdv::string ssHello = {"Hello"};
|
||||
uint8_t ui8 = 8u;
|
||||
uint32_t ui32 = 32u;
|
||||
std::vector<std::string> vecHello = {"Hello1", "Hello2", "Hello3", "Hello4"};
|
||||
};
|
||||
|
||||
bool operator==(const SComplexStruct& rsLeft, const SComplexStruct& rsRight)
|
||||
{
|
||||
return rsLeft.ssHello == rsRight.ssHello && rsLeft.ui8 == rsRight.ui8 && rsLeft.ui32 == rsRight.ui32
|
||||
&& rsLeft.vecHello == rsRight.vecHello;
|
||||
}
|
||||
|
||||
bool operator<(const SComplexStruct& rsLeft, const SComplexStruct& rsRight)
|
||||
{
|
||||
if (rsLeft.ssHello < rsRight.ssHello) return true;
|
||||
if (rsLeft.ssHello > rsRight.ssHello) return false;
|
||||
if (rsLeft.ui8 < rsRight.ui8) return true;
|
||||
if (rsLeft.ui8 > rsRight.ui8) return false;
|
||||
if (rsLeft.ui32 < rsRight.ui32) return true;
|
||||
if (rsLeft.ui32 > rsRight.ui32) return false;
|
||||
if (rsLeft.vecHello < rsRight.vecHello) return true;
|
||||
if (rsLeft.vecHello > rsRight.vecHello) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class U, class V>
|
||||
inline std::basic_ostream<U, V>& operator<<(std::basic_ostream<U, V>& rstream, const SComplexStruct& rsComplex)
|
||||
{
|
||||
rstream << "{" << rsComplex.ssHello << ", " << rsComplex.ui8 << ", " << rsComplex.ui32 << "{";
|
||||
bool bInitial = true;
|
||||
for (const std::string& rss : rsComplex.vecHello)
|
||||
{
|
||||
if (!bInitial) rstream << ", ";
|
||||
bInitial = false;
|
||||
rstream << rss;
|
||||
}
|
||||
rstream << "}}";
|
||||
return rstream;
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct less<SComplexStruct>
|
||||
{
|
||||
bool operator()(const SComplexStruct& rsLeft, const SComplexStruct& rsRight) const
|
||||
{
|
||||
if (rsLeft.ssHello < rsRight.ssHello) return true;
|
||||
if (rsLeft.ssHello > rsRight.ssHello) return false;
|
||||
if (rsLeft.ui8 < rsRight.ui8) return true;
|
||||
if (rsLeft.ui8 > rsRight.ui8) return false;
|
||||
if (rsLeft.ui32 < rsRight.ui32) return true;
|
||||
if (rsLeft.ui32 > rsRight.ui32) return false;
|
||||
if (rsLeft.vecHello < rsRight.vecHello) return true;
|
||||
if (rsLeft.vecHello > rsRight.vecHello) return false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, MakeFixedPointer)
|
||||
{
|
||||
sdv::pointer<SComplexStruct, 1> ptr0;
|
||||
EXPECT_TRUE(ptr0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, MakeDynamicPointer)
|
||||
{
|
||||
sdv::pointer<SComplexStruct> ptr0 = sdv::make_ptr<SComplexStruct>(0);
|
||||
EXPECT_TRUE(ptr0);
|
||||
sdv::pointer<SComplexStruct> ptr1 = sdv::make_ptr<SComplexStruct>();
|
||||
EXPECT_TRUE(ptr1);
|
||||
sdv::pointer<SComplexStruct> ptr2 = sdv::make_ptr<SComplexStruct>(2);
|
||||
EXPECT_TRUE(ptr2);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, ConstructorDynamicPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<SComplexStruct> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<SComplexStruct>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<SComplexStruct> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move constructor
|
||||
sdv::pointer<SComplexStruct> ptrMove(std::move(ptr));
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
|
||||
// Destructor
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<SComplexStruct>* pptr = new sdv::pointer<SComplexStruct>(sdv::make_ptr<SComplexStruct>());
|
||||
EXPECT_NE(pptr, nullptr);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
delete pptr;
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, ConstructorFixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<SComplexStruct, 1> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1(ptr);
|
||||
EXPECT_TRUE(ptrCopy1);
|
||||
EXPECT_EQ(ptrCopy1.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 10> ptrCopy10(ptr);
|
||||
EXPECT_TRUE(ptrCopy10);
|
||||
EXPECT_EQ(ptrCopy10.size(), 0u);
|
||||
using TCopy2 = sdv::pointer<SComplexStruct, 2>;
|
||||
EXPECT_NO_THROW(TCopy2 ptrCopy2(ptrCopy10));
|
||||
ptrCopy10.resize(5);
|
||||
EXPECT_EQ(ptrCopy10.size(), 5u);
|
||||
using TCopy3 = sdv::pointer<SComplexStruct, 3>;
|
||||
EXPECT_THROW(TCopy3 ptrCopy3(ptrCopy10), sdv::XBufferTooSmall);
|
||||
|
||||
// Move constructor
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrMove(std::move(ptr));
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
EXPECT_EQ(ptrMove.size(), 1u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, ConstructorMixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<SComplexStruct> ptr0;
|
||||
sdv::pointer<SComplexStruct, 1> ptr1;
|
||||
sdv::pointer<SComplexStruct, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<SComplexStruct> ptrCopy0a(ptr0);
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0u);
|
||||
sdv::pointer<SComplexStruct> ptrCopy0b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0u);
|
||||
sdv::pointer<SComplexStruct> ptrCopy0c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0u);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
using TCopy2 = sdv::pointer<SComplexStruct, 2>;
|
||||
EXPECT_THROW(TCopy2 ptrCopy2a(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<SComplexStruct, 2> ptrCopy2b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1u);
|
||||
EXPECT_THROW(TCopy2 ptrCopy2c(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3u);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1u);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, AssignmentOperatorsDynamicPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<SComplexStruct> ptr = sdv::make_ptr<SComplexStruct>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy assignment
|
||||
sdv::pointer<SComplexStruct> ptrCopy;
|
||||
EXPECT_FALSE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<SComplexStruct> ptrMove;
|
||||
EXPECT_FALSE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, AssignmentOperatorsFixedPointer)
|
||||
{
|
||||
// Copy assignment
|
||||
sdv::pointer<SComplexStruct, 3> ptr;
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1u);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_EQ(ptrCopy.size(), 1u);
|
||||
ptr.resize(2);
|
||||
EXPECT_EQ(ptr.size(), 2u);
|
||||
EXPECT_THROW(ptrCopy = ptr, sdv::XBufferTooSmall);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<SComplexStruct, 3> ptrMove;
|
||||
EXPECT_TRUE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, AssignmentOperatorsMixedPointer)
|
||||
{
|
||||
sdv::pointer<SComplexStruct> ptr0;
|
||||
sdv::pointer<SComplexStruct, 1> ptr1;
|
||||
sdv::pointer<SComplexStruct, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<SComplexStruct> ptrCopy0a;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
ptrCopy0a = ptr0;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0u);
|
||||
sdv::pointer<SComplexStruct> ptrCopy0b;
|
||||
EXPECT_FALSE(ptrCopy0b);
|
||||
ptrCopy0b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0u);
|
||||
sdv::pointer<SComplexStruct> ptrCopy0c;
|
||||
EXPECT_FALSE(ptrCopy0c);
|
||||
ptrCopy0c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1a;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
ptrCopy1a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1b;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
ptrCopy1b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 1> ptrCopy1c;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
ptrCopy1c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0u);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
sdv::pointer<SComplexStruct, 2> ptrCopy2a;
|
||||
EXPECT_TRUE(ptrCopy2a);
|
||||
EXPECT_THROW(ptrCopy2a = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<SComplexStruct, 2> ptrCopy2b;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
ptrCopy2b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1u);
|
||||
sdv::pointer<SComplexStruct, 2> ptrCopy2c;
|
||||
EXPECT_TRUE(ptrCopy2c);
|
||||
EXPECT_THROW(ptrCopy2c = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3a;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
ptrCopy3a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3u);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3b;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
ptrCopy3b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1u);
|
||||
sdv::pointer<SComplexStruct, 3> ptrCopy3c;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
ptrCopy3c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3u);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper class to access attach and detach functions.
|
||||
* @tparam T Type of the variable to store.
|
||||
*/
|
||||
template <typename T>
|
||||
class CPointerHelper : public sdv::pointer<T>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Attach a uint8_t buffer.
|
||||
* @param[in] rptrBuffer Reference to the pointer to attach.
|
||||
*/
|
||||
void attach(sdv::pointer<uint8_t>&& rptrBuffer)
|
||||
{
|
||||
sdv::pointer<T>::attach(std::move(rptrBuffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detach the uint8_t buffer.
|
||||
* @return Reference to the pointer to detach.
|
||||
*/
|
||||
sdv::pointer<uint8_t>&& detach()
|
||||
{
|
||||
return std::move(sdv::pointer<T>::detach());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, AttachmentDynamicPointer)
|
||||
{
|
||||
// Create the buffer
|
||||
sdv::pointer<uint8_t> ptrBuffer = sdv::make_ptr<uint8_t>(25 * sizeof(SComplexStruct));
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 25 * sizeof(SComplexStruct));
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
|
||||
// Attach
|
||||
CPointerHelper<SComplexStruct> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
ptr.attach(std::move(ptrBuffer));
|
||||
EXPECT_FALSE(ptrBuffer);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 25u);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Detach
|
||||
ptrBuffer = ptr.detach();
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 25 * sizeof(SComplexStruct));
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, ResetFunctionStaticPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<SComplexStruct, 10> ptr;
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10u);
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, ResetFunction)
|
||||
{
|
||||
// Create pointer
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<SComplexStruct> ptr = sdv::make_ptr<SComplexStruct>();
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10u);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, SwapFunctionStaticPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<SComplexStruct, 250> ptr1;
|
||||
EXPECT_TRUE(ptr1);
|
||||
ptr1.resize(100);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
sdv::pointer<SComplexStruct, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200u);
|
||||
EXPECT_EQ(ptr2.size(), 100u);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<SComplexStruct, 150> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr3.size(), 100u);
|
||||
EXPECT_EQ(ptr1.size(), 0u);
|
||||
sdv::pointer<SComplexStruct, 150> ptr4;
|
||||
EXPECT_THROW(sdv::swap(ptr4, ptr2), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, SwapFunctionDynamicPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<SComplexStruct> ptr1 = sdv::make_ptr<SComplexStruct>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
sdv::pointer<SComplexStruct> ptr2 = sdv::make_ptr<SComplexStruct>(200);
|
||||
EXPECT_TRUE(ptr2);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200u);
|
||||
EXPECT_EQ(ptr2.size(), 100u);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<SComplexStruct> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_FALSE(ptr1);
|
||||
sdv::swap(ptr3, ptr1);
|
||||
EXPECT_FALSE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, SwapFunctionMixedPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<SComplexStruct> ptr1 = sdv::make_ptr<SComplexStruct>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
sdv::pointer<SComplexStruct, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200u);
|
||||
EXPECT_EQ(ptr2.size(), 100u);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, AccessFunctions)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Get
|
||||
EXPECT_EQ(ptr.get(), nullptr);
|
||||
EXPECT_THROW(*ptr, sdv::XNullPointer);
|
||||
EXPECT_THROW(ptr->ssHello, sdv::XNullPointer);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<SComplexStruct>(100);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 100u);
|
||||
|
||||
// Get function
|
||||
EXPECT_NE(ptr.get(), nullptr);
|
||||
|
||||
// Assign the value to the array
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
{
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ssHello, "Hello");
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui8, 8u);
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui32, 32u);
|
||||
EXPECT_EQ(ptr.get()[uiIndex].vecHello.size(), 4u);
|
||||
ptr.get()[uiIndex].ssHello = "Hi" + std::to_string(uiIndex);
|
||||
ptr.get()[uiIndex].ui8 = 9u + static_cast<uint8_t>(uiIndex);
|
||||
ptr.get()[uiIndex].ui32 = 33u + uiIndex;
|
||||
ptr.get()[uiIndex].vecHello = {std::string("Hi1") + std::to_string(uiIndex), std::string("Hi2") + std::to_string(uiIndex)};
|
||||
}
|
||||
|
||||
// Reference functions (getter)
|
||||
EXPECT_EQ((*ptr).ssHello, "Hi0");
|
||||
EXPECT_EQ((*ptr).ui8, 9u);
|
||||
EXPECT_EQ((*ptr).ui32, 33u);
|
||||
EXPECT_EQ((*ptr).vecHello.size(), 2u);
|
||||
|
||||
// Indexed values (getter)
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
{
|
||||
EXPECT_EQ(ptr[uiIndex].ssHello, std::string("Hi") + std::to_string(uiIndex));
|
||||
EXPECT_EQ(ptr[uiIndex].ui8, 9u + static_cast<uint8_t>(uiIndex));
|
||||
EXPECT_EQ(ptr[uiIndex].ui32, 33u + uiIndex);
|
||||
EXPECT_EQ(ptr[uiIndex].vecHello.size(), 2u);
|
||||
}
|
||||
|
||||
// Reference functions (setter)
|
||||
(*ptr).ssHello = "Hello mio";
|
||||
(*ptr).ui8 = 255u;
|
||||
(*ptr).ui32 = 255u;
|
||||
(*ptr).vecHello = {"Hello mio1", "Hello mio2", "Hello mio3"};
|
||||
EXPECT_EQ(ptr.get()->ssHello, "Hello mio");
|
||||
EXPECT_EQ(ptr.get()->ui8, 255u);
|
||||
EXPECT_EQ(ptr.get()->ui32, 255u);
|
||||
EXPECT_EQ(ptr.get()->vecHello.size(), 3u);
|
||||
|
||||
// Indexed values (setter)
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
{
|
||||
ptr[uiIndex].ssHello= "Hi miomio" + std::to_string(uiIndex);
|
||||
ptr[uiIndex].ui8 = 109u + static_cast<uint8_t>(uiIndex);
|
||||
ptr[uiIndex].ui32 = 133u + uiIndex;
|
||||
ptr[uiIndex].vecHello = {std::string("Hi miomio1") + std::to_string(uiIndex),
|
||||
std::string("Hi miomio2") + std::to_string(uiIndex),
|
||||
std::string("Hi miomio3") + std::to_string(uiIndex),
|
||||
std::string("Hi miomio4") + std::to_string(uiIndex),
|
||||
std::string("Hi miomio5") + std::to_string(uiIndex)};
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ssHello, std::string("Hi miomio") + std::to_string(uiIndex));
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui8, 109u + static_cast<uint8_t>(uiIndex));
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui32, 133u + uiIndex);
|
||||
EXPECT_EQ(ptr.get()[uiIndex].vecHello.size(), 5u);
|
||||
}
|
||||
|
||||
// Resizing to 0 and then back to 100 should reset all elements to the default value.
|
||||
ptr.resize(0);
|
||||
EXPECT_TRUE(ptr);
|
||||
ptr.resize(100);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 100u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
{
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ssHello, "Hello");
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui8, 8u);
|
||||
EXPECT_EQ(ptr.get()[uiIndex].ui32, 32u);
|
||||
EXPECT_EQ(ptr.get()[uiIndex].vecHello.size(), 4u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, SizeFunctionsStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct, 150> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100u);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
|
||||
// Resize to many
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex].ui32 = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex].ui32, uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex].ui32, uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Exceed buffer capacity
|
||||
EXPECT_THROW(ptr.resize(151), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, SizeFunctionsDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100u);
|
||||
EXPECT_EQ(ptr.capacity(), 100);
|
||||
|
||||
// Allocate zero
|
||||
ptr = sdv::make_ptr<SComplexStruct>(0);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
EXPECT_EQ(ptr.capacity(), 0);
|
||||
|
||||
// Resize to many
|
||||
ptr.resize(100);
|
||||
EXPECT_EQ(ptr.size(), 100u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex].ui32 = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex].ui32, uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150u);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex].ui32, uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Copy the pointer an resize to giant; both pointers should still be valid.
|
||||
sdv::pointer<SComplexStruct> ptrGiant(ptr);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
ptrGiant.resize(1024 * 8);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, RefCountFunctionDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct> ptr;
|
||||
EXPECT_EQ(ptr.ref_count(), 0);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<SComplexStruct>();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Copy
|
||||
sdv::pointer<SComplexStruct> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 2);
|
||||
sdv::pointer<SComplexStruct> ptrCopy2;
|
||||
EXPECT_FALSE(ptrCopy2);
|
||||
ptrCopy2 = ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
|
||||
// Move
|
||||
sdv::pointer<SComplexStruct> ptrMove(std::move(ptrCopy));
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
sdv::pointer<SComplexStruct> ptrMove2;
|
||||
EXPECT_FALSE(ptrMove2);
|
||||
ptrMove2 = std::move(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 3);
|
||||
|
||||
// Reset
|
||||
ptrMove.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 2);
|
||||
ptrMove2.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, CompareOperatorStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct, 10> ptrLeft;
|
||||
sdv::pointer<SComplexStruct, 15> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex].ui32 = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10u);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, CompareOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct> ptrLeft, ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Allocate one pointer
|
||||
ptrLeft = sdv::make_ptr<SComplexStruct>(10);
|
||||
EXPECT_TRUE(ptrLeft);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
|
||||
// Reallocate left allocation
|
||||
ptrLeft = sdv::make_ptr<SComplexStruct>(10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, CompareOperatorMixedPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct, 10> ptrLeft;
|
||||
sdv::pointer<SComplexStruct> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex].ui32 = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10u);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerComplexTypeTest, CompareNullOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<SComplexStruct> ptr;
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
|
||||
// Allocate one pointer
|
||||
ptr = sdv::make_ptr<SComplexStruct>(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_FALSE(ptr == nullptr);
|
||||
EXPECT_FALSE(nullptr == ptr);
|
||||
EXPECT_TRUE(ptr != nullptr);
|
||||
EXPECT_TRUE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_TRUE(nullptr < ptr);
|
||||
EXPECT_FALSE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_TRUE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_FALSE(nullptr >= ptr);
|
||||
|
||||
// Free allocation
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
}
|
||||
916
tests/unit_tests/basic_types/ptr_simple.cpp
Normal file
916
tests/unit_tests/basic_types/ptr_simple.cpp
Normal file
@@ -0,0 +1,916 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <support/pointer.h>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CPointerSimpleTypeTest = CBasicTypesTest;
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, MakeFixedPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t, 1> ptr0;
|
||||
EXPECT_TRUE(ptr0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, MakeDynamicPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t> ptr0 = sdv::make_ptr<uint32_t>(0);
|
||||
EXPECT_TRUE(ptr0);
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr1);
|
||||
sdv::pointer<uint32_t> ptr2 = sdv::make_ptr<uint32_t>(2);
|
||||
EXPECT_TRUE(ptr2);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, ConstructorDynamicPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move constructor
|
||||
sdv::pointer<uint32_t> ptrMove(std::move(ptr));
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
|
||||
// Destructor
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<uint32_t>* pptr = new sdv::pointer<uint32_t>(sdv::make_ptr<uint32_t>());
|
||||
EXPECT_NE(pptr, nullptr);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
delete pptr;
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, ConstructorFixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t, 1> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1(ptr);
|
||||
EXPECT_TRUE(ptrCopy1);
|
||||
EXPECT_EQ(ptrCopy1.size(), 0);
|
||||
sdv::pointer<uint32_t, 10> ptrCopy10(ptr);
|
||||
EXPECT_TRUE(ptrCopy10);
|
||||
EXPECT_EQ(ptrCopy10.size(), 0);
|
||||
using TCopy2 = sdv::pointer<uint32_t, 2>;
|
||||
EXPECT_NO_THROW(TCopy2 ptrCopy2(ptrCopy10));
|
||||
ptrCopy10.resize(5);
|
||||
EXPECT_EQ(ptrCopy10.size(), 5);
|
||||
using TCopy3 = sdv::pointer<uint32_t, 3>;
|
||||
EXPECT_THROW(TCopy3 ptrCopy3(ptrCopy10), sdv::XBufferTooSmall);
|
||||
|
||||
// Move constructor
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1);
|
||||
sdv::pointer<uint32_t, 1> ptrMove(std::move(ptr));
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptrMove.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, ConstructorMixedPointer)
|
||||
{
|
||||
// Default constructor
|
||||
sdv::pointer<uint32_t> ptr0;
|
||||
sdv::pointer<uint32_t, 1> ptr1;
|
||||
sdv::pointer<uint32_t, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy0a(ptr0);
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
using TCopy2 = sdv::pointer<uint32_t, 2>;
|
||||
EXPECT_THROW(TCopy2 ptrCopy2a(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1);
|
||||
EXPECT_THROW(TCopy2 ptrCopy2c(ptr5), sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3a(ptr0);
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3b(ptr1);
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3c(ptr5);
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, AssignmentOperatorsDynamicPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<uint32_t> ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
|
||||
// Copy assignment
|
||||
sdv::pointer<uint32_t> ptrCopy;
|
||||
EXPECT_FALSE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<uint32_t> ptrMove;
|
||||
EXPECT_FALSE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, AssignmentOperatorsFixedPointer)
|
||||
{
|
||||
// Copy assignment
|
||||
sdv::pointer<uint32_t, 3> ptr;
|
||||
sdv::pointer<uint32_t, 1> ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
ptr.resize(1);
|
||||
EXPECT_EQ(ptr.size(), 1);
|
||||
ptrCopy = ptr;
|
||||
EXPECT_EQ(ptrCopy.size(), 1);
|
||||
ptr.resize(2);
|
||||
EXPECT_EQ(ptr.size(), 2);
|
||||
EXPECT_THROW(ptrCopy = ptr, sdv::XBufferTooSmall);
|
||||
|
||||
// Move assignment
|
||||
sdv::pointer<uint32_t, 3> ptrMove;
|
||||
EXPECT_TRUE(ptrMove);
|
||||
ptrMove = std::move(ptr);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_TRUE(ptrMove);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, AssignmentOperatorsMixedPointer)
|
||||
{
|
||||
sdv::pointer<uint32_t> ptr0;
|
||||
sdv::pointer<uint32_t, 1> ptr1;
|
||||
sdv::pointer<uint32_t, 5> ptr5;
|
||||
EXPECT_FALSE(ptr0);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_TRUE(ptr5);
|
||||
|
||||
// Copy constructor
|
||||
sdv::pointer<uint32_t> ptrCopy0a;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
ptrCopy0a = ptr0;
|
||||
EXPECT_FALSE(ptrCopy0a);
|
||||
EXPECT_EQ(ptrCopy0a.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0b;
|
||||
EXPECT_FALSE(ptrCopy0b);
|
||||
ptrCopy0b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy0b);
|
||||
EXPECT_EQ(ptrCopy0b.size(), 0);
|
||||
sdv::pointer<uint32_t> ptrCopy0c;
|
||||
EXPECT_FALSE(ptrCopy0c);
|
||||
ptrCopy0c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy0c);
|
||||
EXPECT_EQ(ptrCopy0c.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1a;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
ptrCopy1a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy1a);
|
||||
EXPECT_EQ(ptrCopy1a.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1b;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
ptrCopy1b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy1b);
|
||||
EXPECT_EQ(ptrCopy1b.size(), 0);
|
||||
sdv::pointer<uint32_t, 1> ptrCopy1c;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
ptrCopy1c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy1c);
|
||||
EXPECT_EQ(ptrCopy1c.size(), 0);
|
||||
ptr0.resize(3);
|
||||
ptr1.resize(1);
|
||||
ptr5.resize(3);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2a;
|
||||
EXPECT_TRUE(ptrCopy2a);
|
||||
EXPECT_THROW(ptrCopy2a = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2b;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
ptrCopy2b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy2b);
|
||||
EXPECT_EQ(ptrCopy2b.size(), 1);
|
||||
sdv::pointer<uint32_t, 2> ptrCopy2c;
|
||||
EXPECT_TRUE(ptrCopy2c);
|
||||
EXPECT_THROW(ptrCopy2c = ptr5, sdv::XBufferTooSmall);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3a;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
ptrCopy3a = ptr0;
|
||||
EXPECT_TRUE(ptrCopy3a);
|
||||
EXPECT_EQ(ptrCopy3a.size(), 3);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3b;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
ptrCopy3b = ptr1;
|
||||
EXPECT_TRUE(ptrCopy3b);
|
||||
EXPECT_EQ(ptrCopy3b.size(), 1);
|
||||
sdv::pointer<uint32_t, 3> ptrCopy3c;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
ptrCopy3c = ptr5;
|
||||
EXPECT_TRUE(ptrCopy3c);
|
||||
EXPECT_EQ(ptrCopy3c.size(), 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper class to access attach and detach functions.
|
||||
* @tparam T Type of the variable to store.
|
||||
*/
|
||||
template <typename T>
|
||||
class CPointerHelper : public sdv::pointer<T>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Attach a uint8_t buffer.
|
||||
* @param[in] rptrBuffer Reference to the pointer to attach.
|
||||
*/
|
||||
void attach(sdv::pointer<uint8_t>&& rptrBuffer)
|
||||
{
|
||||
sdv::pointer<T>::attach(std::move(rptrBuffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detach the uint8_t buffer.
|
||||
* @return Reference to the pointer to detach.
|
||||
*/
|
||||
sdv::pointer<uint8_t>&& detach()
|
||||
{
|
||||
return std::move(sdv::pointer<T>::detach());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, AttachmentDynamicPointer)
|
||||
{
|
||||
// Create the buffer
|
||||
sdv::pointer<uint8_t> ptrBuffer = sdv::make_ptr<uint8_t>(101);
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 101);
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
|
||||
// Attach
|
||||
CPointerHelper<uint32_t> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
ptr.attach(std::move(ptrBuffer));
|
||||
EXPECT_FALSE(ptrBuffer);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 25);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Detach
|
||||
ptrBuffer = ptr.detach();
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_TRUE(ptrBuffer);
|
||||
EXPECT_EQ(ptrBuffer.size(), 101);
|
||||
EXPECT_EQ(ptrBuffer.ref_count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, ResetFunctionStaticPointer)
|
||||
{
|
||||
// Create pointer
|
||||
sdv::pointer<uint32_t, 10> ptr;
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10);
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, ResetFunction)
|
||||
{
|
||||
// Create pointer
|
||||
GetMemMgr().ResetPtrSet();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
sdv::pointer<uint32_t> ptr = sdv::make_ptr<uint32_t>();
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10);
|
||||
EXPECT_NE(GetMemMgr().GetPtrCount(), 0);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, SwapFunctionStaticPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t, 250> ptr1;
|
||||
EXPECT_TRUE(ptr1);
|
||||
ptr1.resize(100);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<uint32_t, 150> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr3.size(), 100);
|
||||
EXPECT_EQ(ptr1.size(), 0);
|
||||
sdv::pointer<uint32_t, 150> ptr4;
|
||||
EXPECT_THROW(sdv::swap(ptr4, ptr2), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, SwapFunctionDynamicPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t> ptr2 = sdv::make_ptr<uint32_t>(200);
|
||||
EXPECT_TRUE(ptr2);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap with empty pointer
|
||||
sdv::pointer<uint32_t> ptr3;
|
||||
ptr3.swap(ptr1);
|
||||
EXPECT_TRUE(ptr3);
|
||||
EXPECT_FALSE(ptr1);
|
||||
sdv::swap(ptr3, ptr1);
|
||||
EXPECT_FALSE(ptr3);
|
||||
EXPECT_TRUE(ptr1);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, SwapFunctionMixedPointer)
|
||||
{
|
||||
// Allocate
|
||||
sdv::pointer<uint32_t> ptr1 = sdv::make_ptr<uint32_t>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
sdv::pointer<uint32_t, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200);
|
||||
EXPECT_EQ(ptr2.size(), 100);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100);
|
||||
EXPECT_EQ(ptr2.size(), 200);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, AccessFunctions)
|
||||
{
|
||||
struct STest
|
||||
{
|
||||
uint32_t uiValue;
|
||||
};
|
||||
|
||||
// Empty pointer
|
||||
sdv::pointer<STest> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
|
||||
// Get
|
||||
EXPECT_EQ(ptr.get(), nullptr);
|
||||
EXPECT_THROW(*ptr, sdv::XNullPointer);
|
||||
EXPECT_THROW(ptr->uiValue, sdv::XNullPointer);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<STest>(100);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
|
||||
// Get function
|
||||
EXPECT_NE(ptr.get(), nullptr);
|
||||
|
||||
// Assign the value to the array
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr.get()[uiIndex].uiValue = uiIndex;
|
||||
|
||||
// Reference functions
|
||||
EXPECT_EQ((*ptr).uiValue, 0u);
|
||||
*ptr = STest{101u};
|
||||
EXPECT_EQ(ptr->uiValue, 101u);
|
||||
EXPECT_EQ((*ptr.get()).uiValue, 101u);
|
||||
ptr->uiValue = 0;
|
||||
EXPECT_EQ((*ptr).uiValue, 0u);
|
||||
EXPECT_EQ((*ptr.get()).uiValue, 0u);
|
||||
|
||||
// Indexed values
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = STest{uiIndex + 200u};
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
EXPECT_EQ(ptr.get()[uiIndex].uiValue, uiIndex + 200u);
|
||||
EXPECT_THROW(ptr[100], sdv::XIndexOutOfRange);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, SizeFunctionsStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 150> ptr;
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(ptr.capacity(), 150);
|
||||
|
||||
// Resize to many
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Exceed buffer capacity
|
||||
EXPECT_THROW(ptr.resize(151), sdv::XBufferTooSmall);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, SizeFunctionsDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_FALSE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_NO_THROW(ptr.resize(100));
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(ptr.capacity(), 100);
|
||||
|
||||
// Allocate zero
|
||||
ptr = sdv::make_ptr<uint32_t>(0);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(ptr.capacity(), 0);
|
||||
|
||||
// Resize to many
|
||||
ptr.resize(100);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 100; uiIndex++)
|
||||
ptr[uiIndex] = uiIndex + 1000;
|
||||
EXPECT_THROW(ptr[101], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize smaller
|
||||
ptr.resize(50);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 50);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[51], sdv::XIndexOutOfRange);
|
||||
|
||||
// Resize larger (the first 50 should still be valid)
|
||||
ptr.resize(150);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 150);
|
||||
for (uint32_t uiIndex = 0; ptr.get() && uiIndex < 50; uiIndex++)
|
||||
EXPECT_EQ(ptr[uiIndex], uiIndex + 1000);
|
||||
EXPECT_THROW(ptr[151], sdv::XIndexOutOfRange);
|
||||
|
||||
// Copy the pointer an resize to giant; both pointers should still be valid.
|
||||
sdv::pointer<uint32_t> ptrGiant(ptr);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
ptrGiant.resize(1024 * 1024 * 8);
|
||||
EXPECT_EQ(ptr, ptrGiant);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Count class increasing the count on construction and descreasing on destruction.
|
||||
*/
|
||||
class CCountLifetime
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor increasing the counter.
|
||||
*/
|
||||
CCountLifetime()
|
||||
{
|
||||
m_nCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor increasing the counter.
|
||||
*/
|
||||
CCountLifetime(const CCountLifetime&)
|
||||
{
|
||||
m_nCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor increasing the counter.
|
||||
*/
|
||||
CCountLifetime(CCountLifetime&)
|
||||
{
|
||||
m_nCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor not increasing the counter.
|
||||
*/
|
||||
CCountLifetime(CCountLifetime&&)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Destructor descreasing the counter.
|
||||
*/
|
||||
~CCountLifetime()
|
||||
{
|
||||
m_nCount--;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment operator
|
||||
* @return Reference to this class.
|
||||
*/
|
||||
CCountLifetime& operator=(const CCountLifetime&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move operator
|
||||
* @return Reference to this class.
|
||||
*/
|
||||
CCountLifetime& operator=(CCountLifetime&&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
static int m_nCount; ///< Global lifetime counter.
|
||||
};
|
||||
|
||||
int CCountLifetime::m_nCount = 0;
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, LifetimeSizeFunctionsStaticPointer)
|
||||
{
|
||||
CCountLifetime::m_nCount = 0;
|
||||
|
||||
// Create local scope to test destructor
|
||||
{
|
||||
sdv::pointer<CCountLifetime, 1000> ptr;
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
ptr.resize(100);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
ptr.resize(20);
|
||||
EXPECT_EQ(ptr.size(), 20);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
ptr.resize(500);
|
||||
EXPECT_EQ(ptr.size(), 500);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
ptr.resize(750);
|
||||
EXPECT_EQ(ptr.size(), 750);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 1000);
|
||||
}
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, LifetimeSizeFunctionsDynamicPointer)
|
||||
{
|
||||
CCountLifetime::m_nCount = 0;
|
||||
|
||||
// Create local scope to test destructor
|
||||
{
|
||||
sdv::pointer<CCountLifetime> ptr;
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 0);
|
||||
ptr.resize(100);
|
||||
EXPECT_EQ(ptr.size(), 100);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 100);
|
||||
ptr.resize(20);
|
||||
EXPECT_EQ(ptr.size(), 20);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 20);
|
||||
ptr.resize(500);
|
||||
EXPECT_EQ(ptr.size(), 500);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 500);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(ptr.size(), 0);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 0);
|
||||
ptr.resize(750);
|
||||
EXPECT_EQ(ptr.size(), 750);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 750);
|
||||
}
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 0);
|
||||
|
||||
// Create pointer
|
||||
CCountLifetime::m_nCount = 0;
|
||||
sdv::pointer<CCountLifetime> ptr = sdv::make_ptr<CCountLifetime>();
|
||||
ptr.resize(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.size(), 10u);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 10);
|
||||
ptr.reset();
|
||||
EXPECT_EQ(GetMemMgr().GetPtrCount(), 0);
|
||||
EXPECT_EQ(ptr.size(), 0u);
|
||||
EXPECT_EQ(CCountLifetime::m_nCount, 0);
|
||||
|
||||
// Allocate
|
||||
sdv::pointer<CCountLifetime> ptr1 = sdv::make_ptr<CCountLifetime>(100);
|
||||
EXPECT_TRUE(ptr1);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
sdv::pointer<CCountLifetime, 200> ptr2;
|
||||
EXPECT_TRUE(ptr2);
|
||||
ptr2.resize(200);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
|
||||
// Swap two pointers
|
||||
ptr1.swap(ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 200u);
|
||||
EXPECT_EQ(ptr2.size(), 100u);
|
||||
sdv::swap(ptr1, ptr2);
|
||||
EXPECT_EQ(ptr1.size(), 100u);
|
||||
EXPECT_EQ(ptr2.size(), 200u);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, RefCountFunctionDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_EQ(ptr.ref_count(), 0);
|
||||
|
||||
// Allocate
|
||||
ptr = sdv::make_ptr<uint32_t>();
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
|
||||
// Copy
|
||||
sdv::pointer<uint32_t> ptrCopy(ptr);
|
||||
EXPECT_TRUE(ptrCopy);
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 2);
|
||||
sdv::pointer<uint32_t> ptrCopy2;
|
||||
EXPECT_FALSE(ptrCopy2);
|
||||
ptrCopy2 = ptrCopy;
|
||||
EXPECT_TRUE(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
|
||||
// Move
|
||||
sdv::pointer<uint32_t> ptrMove(std::move(ptrCopy));
|
||||
EXPECT_TRUE(ptrMove);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
sdv::pointer<uint32_t> ptrMove2;
|
||||
EXPECT_FALSE(ptrMove2);
|
||||
ptrMove2 = std::move(ptrCopy2);
|
||||
EXPECT_EQ(ptr.ref_count(), 3);
|
||||
EXPECT_EQ(ptrCopy.ref_count(), 0);
|
||||
EXPECT_EQ(ptrCopy2.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 3);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 3);
|
||||
|
||||
// Reset
|
||||
ptrMove.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 2);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 2);
|
||||
ptrMove2.reset();
|
||||
EXPECT_EQ(ptr.ref_count(), 1);
|
||||
EXPECT_EQ(ptrMove.ref_count(), 0);
|
||||
EXPECT_EQ(ptrMove2.ref_count(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, CompareOperatorStaticPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 10> ptrLeft;
|
||||
sdv::pointer<uint32_t, 15> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex] = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, CompareOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptrLeft, ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Allocate one pointer
|
||||
ptrLeft = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_TRUE(ptrLeft);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
|
||||
// Reallocate left allocation
|
||||
ptrLeft = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, CompareOperatorMixedPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t, 10> ptrLeft;
|
||||
sdv::pointer<uint32_t> ptrRight;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Resize one pointer and fill with counter
|
||||
ptrLeft.resize(10);
|
||||
for (size_t nIndex = 0; nIndex < ptrLeft.size(); nIndex++)
|
||||
ptrLeft[nIndex] = static_cast<uint32_t>(nIndex);
|
||||
EXPECT_EQ(ptrLeft.size(), 10);
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_FALSE(ptrLeft <= ptrRight);
|
||||
EXPECT_TRUE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Copy the allocation
|
||||
ptrRight = ptrLeft;
|
||||
EXPECT_TRUE(ptrLeft == ptrRight);
|
||||
EXPECT_FALSE(ptrLeft != ptrRight);
|
||||
EXPECT_FALSE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_TRUE(ptrLeft >= ptrRight);
|
||||
|
||||
// Free left allocation
|
||||
ptrLeft.reset();
|
||||
EXPECT_FALSE(ptrLeft == ptrRight);
|
||||
EXPECT_TRUE(ptrLeft != ptrRight);
|
||||
EXPECT_TRUE(ptrLeft < ptrRight);
|
||||
EXPECT_TRUE(ptrLeft <= ptrRight);
|
||||
EXPECT_FALSE(ptrLeft > ptrRight);
|
||||
EXPECT_FALSE(ptrLeft >= ptrRight);
|
||||
}
|
||||
|
||||
TEST_F(CPointerSimpleTypeTest, CompareNullOperatorDynamicPointer)
|
||||
{
|
||||
// Empty pointer
|
||||
sdv::pointer<uint32_t> ptr;
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
|
||||
// Allocate one pointer
|
||||
ptr = sdv::make_ptr<uint32_t>(10);
|
||||
EXPECT_TRUE(ptr);
|
||||
EXPECT_FALSE(ptr == nullptr);
|
||||
EXPECT_FALSE(nullptr == ptr);
|
||||
EXPECT_TRUE(ptr != nullptr);
|
||||
EXPECT_TRUE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_TRUE(nullptr < ptr);
|
||||
EXPECT_FALSE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_TRUE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_FALSE(nullptr >= ptr);
|
||||
|
||||
// Free allocation
|
||||
ptr.reset();
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
EXPECT_TRUE(nullptr == ptr);
|
||||
EXPECT_FALSE(ptr != nullptr);
|
||||
EXPECT_FALSE(nullptr != ptr);
|
||||
EXPECT_FALSE(ptr < nullptr);
|
||||
EXPECT_FALSE(nullptr < ptr);
|
||||
EXPECT_TRUE(ptr <= nullptr);
|
||||
EXPECT_TRUE(nullptr <= ptr);
|
||||
EXPECT_FALSE(ptr > nullptr);
|
||||
EXPECT_FALSE(nullptr > ptr);
|
||||
EXPECT_TRUE(ptr >= nullptr);
|
||||
EXPECT_TRUE(nullptr >= ptr);
|
||||
}
|
||||
|
||||
959
tests/unit_tests/basic_types/sequence_complex.cpp
Normal file
959
tests/unit_tests/basic_types/sequence_complex.cpp
Normal file
@@ -0,0 +1,959 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <support/sequence.h>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CComplexSequenceTypeTest = CBasicTypesTest;
|
||||
|
||||
struct SComplexNumber
|
||||
{
|
||||
uint32_t uiIm;
|
||||
uint32_t uiRe;
|
||||
};
|
||||
|
||||
inline bool operator==(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
return s1.uiIm == s2.uiIm && s1.uiRe == s2.uiRe;
|
||||
}
|
||||
|
||||
inline bool operator!=(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
return !operator==(s1, s2);
|
||||
}
|
||||
|
||||
inline bool operator<(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
if (s1.uiIm < s2.uiIm)
|
||||
return true;
|
||||
if (s1.uiIm != s2.uiIm)
|
||||
return false;
|
||||
return s1.uiRe < s2.uiRe;
|
||||
}
|
||||
|
||||
inline bool operator<=(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
if (s1.uiIm < s2.uiIm)
|
||||
return true;
|
||||
if (s1.uiIm != s2.uiIm)
|
||||
return false;
|
||||
return s1.uiRe <= s2.uiRe;
|
||||
}
|
||||
|
||||
inline bool operator>(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
if (s1.uiIm > s2.uiIm)
|
||||
return true;
|
||||
if (s1.uiIm != s2.uiIm)
|
||||
return false;
|
||||
return s1.uiRe > s2.uiRe;
|
||||
}
|
||||
|
||||
inline bool operator>=(SComplexNumber s1, SComplexNumber s2)
|
||||
{
|
||||
if (s1.uiIm > s2.uiIm)
|
||||
return true;
|
||||
if (s1.uiIm != s2.uiIm)
|
||||
return false;
|
||||
return s1.uiRe >= s2.uiRe;
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, ConstructorStatic)
|
||||
{
|
||||
// Empty sequence
|
||||
sdv::sequence<SComplexNumber> seqEmpty;
|
||||
EXPECT_TRUE(seqEmpty.empty());
|
||||
|
||||
// Fill constructor
|
||||
SComplexNumber sVal = {100u, 200u};
|
||||
sdv::sequence<SComplexNumber, 10> seqFill(5, sVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], sVal);
|
||||
EXPECT_EQ(seqFill[1], sVal);
|
||||
EXPECT_EQ(seqFill[2], sVal);
|
||||
EXPECT_EQ(seqFill[3], sVal);
|
||||
EXPECT_EQ(seqFill[4], sVal);
|
||||
|
||||
// Reserve constructor
|
||||
sdv::sequence<SComplexNumber, 10> seqReserve(10);
|
||||
EXPECT_FALSE(seqReserve.empty());
|
||||
EXPECT_EQ(seqReserve.size(), 10);
|
||||
|
||||
// Iterator constructor
|
||||
sdv::sequence<SComplexNumber, 15> seqIterator(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], sVal);
|
||||
EXPECT_EQ(seqIterator[1], sVal);
|
||||
EXPECT_EQ(seqIterator[2], sVal);
|
||||
EXPECT_EQ(seqIterator[3], sVal);
|
||||
EXPECT_EQ(seqIterator[4], sVal);
|
||||
|
||||
// Copy constructor
|
||||
sdv::sequence<SComplexNumber, 12> seqCopy(seqFill);
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 5);
|
||||
EXPECT_EQ(seqCopy[0], sVal);
|
||||
EXPECT_EQ(seqCopy[1], sVal);
|
||||
EXPECT_EQ(seqCopy[2], sVal);
|
||||
EXPECT_EQ(seqCopy[3], sVal);
|
||||
EXPECT_EQ(seqCopy[4], sVal);
|
||||
|
||||
// Move constructor
|
||||
sdv::sequence<SComplexNumber, 10> seqMove(std::move(seqFill));
|
||||
EXPECT_TRUE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 5);
|
||||
|
||||
// C++ vector constructor
|
||||
std::vector<SComplexNumber> vec = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
sdv::sequence<SComplexNumber, 5> seqVector(vec);
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], sVal10);
|
||||
EXPECT_EQ(seqVector[1], sVal20);
|
||||
EXPECT_EQ(seqVector[2], sVal30);
|
||||
|
||||
// Initializer list constructor
|
||||
sdv::sequence<SComplexNumber, 5> seqIList = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], sVal10);
|
||||
EXPECT_EQ(seqIList[1], sVal20);
|
||||
EXPECT_EQ(seqIList[2], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, ConstructorDynamic)
|
||||
{
|
||||
// Empty sequence
|
||||
sdv::sequence<SComplexNumber> seqEmpty;
|
||||
EXPECT_TRUE(seqEmpty.empty());
|
||||
|
||||
// Fill constructor
|
||||
SComplexNumber sVal = {100u, 200u};
|
||||
sdv::sequence<SComplexNumber> seqFill(5, sVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], sVal);
|
||||
EXPECT_EQ(seqFill[1], sVal);
|
||||
EXPECT_EQ(seqFill[2], sVal);
|
||||
EXPECT_EQ(seqFill[3], sVal);
|
||||
EXPECT_EQ(seqFill[4], sVal);
|
||||
|
||||
// Reserve constructor
|
||||
sdv::sequence<SComplexNumber> seqReserve(10);
|
||||
EXPECT_FALSE(seqReserve.empty());
|
||||
EXPECT_EQ(seqReserve.size(), 10);
|
||||
|
||||
// Iterator constructor
|
||||
sdv::sequence<SComplexNumber> seqIterator(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], sVal);
|
||||
EXPECT_EQ(seqIterator[1], sVal);
|
||||
EXPECT_EQ(seqIterator[2], sVal);
|
||||
EXPECT_EQ(seqIterator[3], sVal);
|
||||
EXPECT_EQ(seqIterator[4], sVal);
|
||||
|
||||
// Copy constructor
|
||||
sdv::sequence<SComplexNumber> seqCopy(seqFill);
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 5);
|
||||
EXPECT_EQ(seqCopy[0], sVal);
|
||||
EXPECT_EQ(seqCopy[1], sVal);
|
||||
EXPECT_EQ(seqCopy[2], sVal);
|
||||
EXPECT_EQ(seqCopy[3], sVal);
|
||||
EXPECT_EQ(seqCopy[4], sVal);
|
||||
|
||||
// Move constructor
|
||||
sdv::sequence<SComplexNumber> seqMove(std::move(seqFill));
|
||||
EXPECT_TRUE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 5);
|
||||
|
||||
// C++ vector constructor
|
||||
std::vector<SComplexNumber> vec = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
sdv::sequence<SComplexNumber> seqVector(vec);
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], sVal10);
|
||||
EXPECT_EQ(seqVector[1], sVal20);
|
||||
EXPECT_EQ(seqVector[2], sVal30);
|
||||
|
||||
// Initializer list constructor
|
||||
sdv::sequence<SComplexNumber> seqIList = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], sVal10);
|
||||
EXPECT_EQ(seqIList[1], sVal20);
|
||||
EXPECT_EQ(seqIList[2], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, AssignmentOperatorStatic)
|
||||
{
|
||||
sdv::sequence<SComplexNumber, 5> seq = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
EXPECT_EQ(seq[0], sVal10);
|
||||
EXPECT_EQ(seq[1], sVal20);
|
||||
EXPECT_EQ(seq[2], sVal30);
|
||||
|
||||
// Copy assignment
|
||||
sdv::sequence<SComplexNumber, 7> seqCopy;
|
||||
EXPECT_TRUE(seqCopy.empty());
|
||||
seqCopy = seq;
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 3);
|
||||
EXPECT_EQ(seqCopy[0], sVal10);
|
||||
EXPECT_EQ(seqCopy[1], sVal20);
|
||||
EXPECT_EQ(seqCopy[2], sVal30);
|
||||
|
||||
// Move assignment
|
||||
sdv::sequence<SComplexNumber, 3> seqMove;
|
||||
EXPECT_TRUE(seqMove.empty());
|
||||
seqMove = std::move(seq);
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 3);
|
||||
|
||||
// C++ vector assignment
|
||||
std::vector<SComplexNumber> vec = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber, 5> seqVector;
|
||||
EXPECT_TRUE(seqVector.empty());
|
||||
seqVector = vec;
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], sVal10);
|
||||
EXPECT_EQ(seqVector[1], sVal20);
|
||||
EXPECT_EQ(seqVector[2], sVal30);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<SComplexNumber, 5> seqIList;
|
||||
EXPECT_TRUE(seqIList.empty());
|
||||
seqIList = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], sVal10);
|
||||
EXPECT_EQ(seqIList[1], sVal20);
|
||||
EXPECT_EQ(seqIList[2], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, AssignmentOperatorDynamic)
|
||||
{
|
||||
sdv::sequence<SComplexNumber> seq = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
EXPECT_EQ(seq[0], sVal10);
|
||||
EXPECT_EQ(seq[1], sVal20);
|
||||
EXPECT_EQ(seq[2], sVal30);
|
||||
|
||||
// Copy assignment
|
||||
sdv::sequence<SComplexNumber> seqCopy;
|
||||
EXPECT_TRUE(seqCopy.empty());
|
||||
seqCopy = seq;
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 3);
|
||||
EXPECT_EQ(seqCopy[0], sVal10);
|
||||
EXPECT_EQ(seqCopy[1], sVal20);
|
||||
EXPECT_EQ(seqCopy[2], sVal30);
|
||||
|
||||
// Move assignment
|
||||
sdv::sequence<SComplexNumber> seqMove;
|
||||
EXPECT_TRUE(seqMove.empty());
|
||||
seqMove = std::move(seq);
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 3);
|
||||
|
||||
// C++ vector assignment
|
||||
std::vector<SComplexNumber> vec = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber> seqVector;
|
||||
EXPECT_TRUE(seqVector.empty());
|
||||
seqVector = vec;
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], sVal10);
|
||||
EXPECT_EQ(seqVector[1], sVal20);
|
||||
EXPECT_EQ(seqVector[2], sVal30);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<SComplexNumber> seqIList;
|
||||
EXPECT_TRUE(seqIList.empty());
|
||||
seqIList = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], sVal10);
|
||||
EXPECT_EQ(seqIList[1], sVal20);
|
||||
EXPECT_EQ(seqIList[2], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, AssignmentFunction)
|
||||
{
|
||||
// Fill assignment
|
||||
sdv::sequence<SComplexNumber> seqFill;
|
||||
SComplexNumber sVal = {100u, 200u};
|
||||
seqFill.assign(5, sVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], sVal);
|
||||
EXPECT_EQ(seqFill[1], sVal);
|
||||
EXPECT_EQ(seqFill[2], sVal);
|
||||
EXPECT_EQ(seqFill[3], sVal);
|
||||
EXPECT_EQ(seqFill[4], sVal);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence<SComplexNumber> seqIterator;
|
||||
seqIterator.assign(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], sVal);
|
||||
EXPECT_EQ(seqIterator[1], sVal);
|
||||
EXPECT_EQ(seqIterator[2], sVal);
|
||||
EXPECT_EQ(seqIterator[3], sVal);
|
||||
EXPECT_EQ(seqIterator[4], sVal);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<SComplexNumber> seqIList;
|
||||
seqIList.assign({SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], sVal10);
|
||||
EXPECT_EQ(seqIList[1], sVal20);
|
||||
EXPECT_EQ(seqIList[2], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, PositionFunction)
|
||||
{
|
||||
// Position in the sequence
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u};
|
||||
sdv::sequence<SComplexNumber> seq1{sVal10, sVal20, sVal30, sVal40, sVal50};
|
||||
EXPECT_EQ(seq1.at(0), sVal10);
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
EXPECT_EQ(seq1.front(), sVal10);
|
||||
EXPECT_EQ(seq1.at(4), sVal50);
|
||||
EXPECT_EQ(seq1[4], sVal50);
|
||||
EXPECT_EQ(seq1.back(), sVal50);
|
||||
EXPECT_THROW(seq1.at(5), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq1[5], sdv::XIndexOutOfRange);
|
||||
|
||||
// Empty sequence
|
||||
sdv::sequence<SComplexNumber> seq2;
|
||||
EXPECT_THROW(seq2.at(0), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2[0], sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2.front(), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2.back(), sdv::XIndexOutOfRange);
|
||||
|
||||
// Assignment
|
||||
SComplexNumber sVal110{110u, 210u};
|
||||
seq1.at(0) = sVal110;
|
||||
EXPECT_EQ(seq1[0], sVal110);
|
||||
seq1[0] = sVal10;
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
seq1.front() = sVal110;
|
||||
EXPECT_EQ(seq1[0], sVal110);
|
||||
SComplexNumber sVal150{150u, 250u};
|
||||
seq1.back() = sVal150;
|
||||
EXPECT_EQ(seq1[4], sVal150);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, CppVectorAccess)
|
||||
{
|
||||
// C++ cast operator
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u};
|
||||
sdv::sequence<SComplexNumber> seq = {sVal10, sVal20, sVal30};
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
std::vector<SComplexNumber> vec;
|
||||
EXPECT_TRUE(vec.empty());
|
||||
vec = seq;
|
||||
EXPECT_EQ(vec.size(), 3);
|
||||
|
||||
// Data access
|
||||
EXPECT_EQ(memcmp(seq.data(), vec.data(), 3 * sizeof(uint32_t)), 0);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, ForwardIteratorBasedAccess)
|
||||
{
|
||||
// Empty forward iterator
|
||||
sdv::sequence<SComplexNumber>::iterator itEmpty;
|
||||
EXPECT_NO_THROW(itEmpty++);
|
||||
EXPECT_NO_THROW(itEmpty--);
|
||||
EXPECT_NO_THROW(itEmpty += 2);
|
||||
EXPECT_NO_THROW(itEmpty -= 2);
|
||||
EXPECT_THROW(itEmpty[0], sdv::XIndexOutOfRange);
|
||||
|
||||
// Iterator assignment
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u};
|
||||
sdv::sequence seq{sVal10, sVal20, sVal30, sVal40, sVal50};
|
||||
EXPECT_NE(itEmpty, seq.begin());
|
||||
sdv::sequence<SComplexNumber>::iterator itPos = seq.begin();
|
||||
EXPECT_NE(itEmpty, itPos);
|
||||
EXPECT_EQ(itPos, seq.begin());
|
||||
sdv::sequence<SComplexNumber>::iterator itPosCopy;
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
itPosCopy = itPos;
|
||||
EXPECT_EQ(itPosCopy, itPos);
|
||||
sdv::sequence<SComplexNumber>::iterator itPosNew;
|
||||
EXPECT_NE(itPosNew, itPos);
|
||||
itPosNew = std::move(itPosCopy);
|
||||
EXPECT_EQ(itPosNew, itPos);
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
|
||||
// Iterator element access
|
||||
EXPECT_EQ(*itPos, sVal10);
|
||||
EXPECT_EQ(itPos[0], sVal10);
|
||||
EXPECT_EQ(itPos[4], sVal50);
|
||||
EXPECT_THROW(itPos[5], sdv::XIndexOutOfRange);
|
||||
SComplexNumber sVal110{110u, 210u}, sVal150{150u, 250u};
|
||||
*itPos = sVal110;
|
||||
EXPECT_EQ(seq[0], sVal110);
|
||||
itPos[4] = sVal150;
|
||||
EXPECT_EQ(seq[4], sVal150);
|
||||
seq[0] = sVal10;
|
||||
seq[4] = sVal50;
|
||||
|
||||
// Iterator iteration
|
||||
itPos++;
|
||||
EXPECT_EQ(*itPos, sVal20);
|
||||
itPos += 3;
|
||||
EXPECT_EQ(*itPos, sVal50);
|
||||
EXPECT_NO_THROW(itPos++); // Increases at the position following last
|
||||
EXPECT_THROW(*itPos, sdv::XIndexOutOfRange);
|
||||
EXPECT_EQ(itPos, seq.end());
|
||||
EXPECT_NO_THROW(itPos++); // Will be ignored; doesn't increase even more
|
||||
itPos--;
|
||||
EXPECT_EQ(*itPos, sVal50);
|
||||
itPos -= 4;
|
||||
EXPECT_EQ(*itPos, sVal10);
|
||||
EXPECT_NO_THROW(itPos--); // Will be ignored; doesn't decrease even more
|
||||
EXPECT_EQ(*itPos, sVal10);
|
||||
EXPECT_EQ(itPos, seq.begin());
|
||||
|
||||
// Const iterator
|
||||
sdv::sequence<SComplexNumber>::const_iterator itPosConst = seq.cbegin();
|
||||
EXPECT_EQ(itPos, itPosConst);
|
||||
itPosConst++;
|
||||
EXPECT_EQ(*itPosConst, sVal20);
|
||||
EXPECT_NE(itPosConst, itPos);
|
||||
itPos++;
|
||||
EXPECT_EQ(itPosConst, itPos);
|
||||
EXPECT_EQ(seq.cbegin(), seq.begin());
|
||||
EXPECT_EQ(seq.begin(), seq.cbegin());
|
||||
EXPECT_EQ(seq.cend(), seq.end());
|
||||
EXPECT_EQ(seq.end(), seq.cend());
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, ReverseIteratorBasedAccess)
|
||||
{
|
||||
// Empty reverse iterator
|
||||
sdv::sequence<SComplexNumber>::reverse_iterator itEmpty;
|
||||
EXPECT_NO_THROW(itEmpty--);
|
||||
EXPECT_NO_THROW(itEmpty++);
|
||||
EXPECT_NO_THROW(itEmpty -= 2);
|
||||
EXPECT_NO_THROW(itEmpty += 2);
|
||||
EXPECT_THROW(itEmpty[0], sdv::XIndexOutOfRange);
|
||||
|
||||
// Iterator assignment
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u};
|
||||
sdv::sequence seq{sVal10, sVal20, sVal30, sVal40, sVal50};
|
||||
EXPECT_NE(itEmpty, seq.rbegin());
|
||||
sdv::sequence<SComplexNumber>::reverse_iterator itPos = seq.rbegin();
|
||||
EXPECT_NE(itEmpty, itPos);
|
||||
EXPECT_EQ(itPos, seq.rbegin());
|
||||
sdv::sequence<SComplexNumber>::reverse_iterator itPosCopy;
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
itPosCopy = itPos;
|
||||
EXPECT_EQ(itPosCopy, itPos);
|
||||
sdv::sequence<SComplexNumber>::reverse_iterator itPosNew;
|
||||
EXPECT_NE(itPosNew, itPos);
|
||||
itPosNew = std::move(itPosCopy);
|
||||
EXPECT_EQ(itPosNew, itPos);
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
|
||||
// Iterator element access
|
||||
SComplexNumber sVal110{110u, 210u}, sVal150{150u, 250u};
|
||||
EXPECT_EQ(*itPos, sVal50);
|
||||
EXPECT_EQ(itPos[0], sVal50);
|
||||
EXPECT_EQ(itPos[4], sVal10);
|
||||
EXPECT_THROW(itPos[5], sdv::XIndexOutOfRange);
|
||||
*itPos = sVal150;
|
||||
EXPECT_EQ(seq[4], sVal150);
|
||||
itPos[4] = sVal110;
|
||||
EXPECT_EQ(seq[0], sVal110);
|
||||
seq[0] = sVal10;
|
||||
seq[4] = sVal50;
|
||||
|
||||
// Iterator iteration
|
||||
itPos++;
|
||||
EXPECT_EQ(*itPos, sVal40);
|
||||
itPos += 3;
|
||||
EXPECT_EQ(*itPos, sVal10);
|
||||
EXPECT_NO_THROW(itPos++); // Increases at the position following last
|
||||
EXPECT_THROW(*itPos, sdv::XIndexOutOfRange);
|
||||
EXPECT_EQ(itPos, seq.rend());
|
||||
EXPECT_NO_THROW(itPos++); // Will be ignored; doesn't increase even more
|
||||
itPos--;
|
||||
EXPECT_EQ(*itPos, sVal10);
|
||||
itPos -= 4;
|
||||
EXPECT_EQ(*itPos, sVal50);
|
||||
EXPECT_NO_THROW(itPos--); // Will be ignored; doesn't decrease even more
|
||||
EXPECT_EQ(*itPos, sVal50);
|
||||
EXPECT_EQ(itPos, seq.rbegin());
|
||||
|
||||
// Const iterator
|
||||
sdv::sequence<SComplexNumber>::const_reverse_iterator itPosConst = seq.crbegin();
|
||||
EXPECT_EQ(itPos, itPosConst);
|
||||
itPosConst++;
|
||||
EXPECT_EQ(*itPosConst, sVal40);
|
||||
EXPECT_NE(itPosConst, itPos);
|
||||
itPos++;
|
||||
EXPECT_EQ(itPosConst, itPos);
|
||||
EXPECT_EQ(seq.crbegin(), seq.rbegin());
|
||||
EXPECT_EQ(seq.rbegin(), seq.crbegin());
|
||||
EXPECT_EQ(seq.crend(), seq.rend());
|
||||
EXPECT_EQ(seq.rend(), seq.crend());
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, SequenceCapacityStatic)
|
||||
{
|
||||
// Empty string
|
||||
sdv::sequence<SComplexNumber, 20> seq;
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Filled string
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u};
|
||||
seq = {sVal10, sVal20, sVal30, sVal40, sVal50};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Resize, reserve
|
||||
seq.resize(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(4);
|
||||
EXPECT_EQ(seq.size(), 4);
|
||||
EXPECT_EQ(seq.length(), 4);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.push_back(sVal50);
|
||||
seq.resize(10, sVal60);
|
||||
EXPECT_EQ(seq[4], sVal50);
|
||||
EXPECT_EQ(seq[5], sVal60);
|
||||
EXPECT_EQ(seq[6], sVal60);
|
||||
EXPECT_EQ(seq[7], sVal60);
|
||||
EXPECT_EQ(seq[8], sVal60);
|
||||
EXPECT_EQ(seq[9], sVal60);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(5);
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.reserve(4);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(5);
|
||||
|
||||
// Shrink to fit
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.shrink_to_fit();
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Clear
|
||||
seq.clear();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, SequenceCapacityDynamic)
|
||||
{
|
||||
// Empty string
|
||||
sdv::sequence<SComplexNumber> seq;
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 0);
|
||||
|
||||
// Filled string
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u};
|
||||
seq = {sVal10, sVal20, sVal30, sVal40, sVal50};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 5);
|
||||
|
||||
// Resize, reserve
|
||||
seq.resize(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(4);
|
||||
EXPECT_EQ(seq.size(), 4);
|
||||
EXPECT_EQ(seq.length(), 4);
|
||||
EXPECT_EQ(seq.capacity(), 4);
|
||||
seq.push_back(sVal50);
|
||||
seq.resize(10, sVal60);
|
||||
EXPECT_EQ(seq[4], sVal50);
|
||||
EXPECT_EQ(seq[5], sVal60);
|
||||
EXPECT_EQ(seq[6], sVal60);
|
||||
EXPECT_EQ(seq[7], sVal60);
|
||||
EXPECT_EQ(seq[8], sVal60);
|
||||
EXPECT_EQ(seq[9], sVal60);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(5);
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 5);
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.reserve(4);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(5);
|
||||
|
||||
// Shrink to fit
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.shrink_to_fit();
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
|
||||
// Clear
|
||||
seq.clear();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, InsertFunction)
|
||||
{
|
||||
// Value assignment
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u};
|
||||
sdv::sequence<SComplexNumber> seq1;
|
||||
EXPECT_TRUE(seq1.empty());
|
||||
seq1.insert(seq1.begin(), 3, sVal10);
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
EXPECT_EQ(seq1[1], sVal10);
|
||||
EXPECT_EQ(seq1[2], sVal10);
|
||||
seq1.insert(seq1.begin(), 2, sVal20);
|
||||
EXPECT_EQ(seq1[0], sVal20);
|
||||
EXPECT_EQ(seq1[1], sVal20);
|
||||
EXPECT_EQ(seq1[2], sVal10);
|
||||
seq1.insert(seq1.end(), 2, sVal30);
|
||||
EXPECT_EQ(seq1[4], sVal10);
|
||||
EXPECT_EQ(seq1[5], sVal30);
|
||||
EXPECT_EQ(seq1[6], sVal30);
|
||||
seq1.insert(seq1.begin() + 4, 2, sVal40);
|
||||
EXPECT_EQ(seq1[0], sVal20);
|
||||
EXPECT_EQ(seq1[1], sVal20);
|
||||
EXPECT_EQ(seq1[2], sVal10);
|
||||
EXPECT_EQ(seq1[3], sVal10);
|
||||
EXPECT_EQ(seq1[4], sVal40);
|
||||
EXPECT_EQ(seq1[5], sVal40);
|
||||
EXPECT_EQ(seq1[6], sVal10);
|
||||
EXPECT_EQ(seq1[7], sVal30);
|
||||
EXPECT_EQ(seq1[8], sVal30);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence<SComplexNumber> seq2;
|
||||
sdv::sequence<SComplexNumber> seq({SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
EXPECT_TRUE(seq2.empty());
|
||||
seq2.insert(seq2.begin(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
seq2.insert(seq2.begin(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
EXPECT_EQ(seq2[3], sVal10);
|
||||
seq2.insert(seq2.end(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[5], sVal30);
|
||||
EXPECT_EQ(seq2[6], sVal10);
|
||||
EXPECT_EQ(seq2[7], sVal20);
|
||||
EXPECT_EQ(seq2[8], sVal30);
|
||||
seq2.insert(seq2.begin() + 4, seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
EXPECT_EQ(seq2[3], sVal10);
|
||||
EXPECT_EQ(seq2[4], sVal10);
|
||||
EXPECT_EQ(seq2[5], sVal20);
|
||||
EXPECT_EQ(seq2[6], sVal30);
|
||||
EXPECT_EQ(seq2[7], sVal20);
|
||||
EXPECT_EQ(seq2[8], sVal30);
|
||||
EXPECT_EQ(seq2[9], sVal10);
|
||||
EXPECT_EQ(seq2[10], sVal20);
|
||||
EXPECT_EQ(seq2[11], sVal30);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<SComplexNumber> seq3;
|
||||
EXPECT_TRUE(seq3.empty());
|
||||
seq3.insert(seq3.begin(), {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
EXPECT_EQ(seq3[0], sVal10);
|
||||
EXPECT_EQ(seq3[1], sVal20);
|
||||
EXPECT_EQ(seq3[2], sVal30);
|
||||
seq3.insert(seq3.begin(), {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
EXPECT_EQ(seq3[0], sVal10);
|
||||
EXPECT_EQ(seq3[1], sVal20);
|
||||
EXPECT_EQ(seq3[2], sVal30);
|
||||
EXPECT_EQ(seq3[3], sVal10);
|
||||
seq3.insert(seq3.end(), {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
EXPECT_EQ(seq3[5], sVal30);
|
||||
EXPECT_EQ(seq3[6], sVal10);
|
||||
EXPECT_EQ(seq3[7], sVal20);
|
||||
EXPECT_EQ(seq3[8], sVal30);
|
||||
seq3.insert(seq3.begin() + 4, {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}});
|
||||
EXPECT_EQ(seq3[0], sVal10);
|
||||
EXPECT_EQ(seq3[1], sVal20);
|
||||
EXPECT_EQ(seq3[2], sVal30);
|
||||
EXPECT_EQ(seq3[3], sVal10);
|
||||
EXPECT_EQ(seq3[4], sVal10);
|
||||
EXPECT_EQ(seq3[5], sVal20);
|
||||
EXPECT_EQ(seq3[6], sVal30);
|
||||
EXPECT_EQ(seq3[7], sVal20);
|
||||
EXPECT_EQ(seq3[8], sVal30);
|
||||
EXPECT_EQ(seq3[9], sVal10);
|
||||
EXPECT_EQ(seq3[10], sVal20);
|
||||
EXPECT_EQ(seq3[11], sVal30);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, EraseFunction)
|
||||
{
|
||||
// Single element erasure
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u},
|
||||
sVal70{70u, 170u}, sVal80{80u, 180u}, sVal90{90u, 190u}, sVal100{100u, 200u};
|
||||
sdv::sequence<SComplexNumber> seq({sVal10, sVal20, sVal30, sVal40, sVal50, sVal60, sVal70, sVal80, sVal90, sVal100});
|
||||
sdv::sequence<SComplexNumber>::iterator it = seq.begin();
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
it = seq.end() - 1;
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[seq.size() - 1], sVal90);
|
||||
it = seq.begin() + 4;
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[3], sVal50);
|
||||
EXPECT_EQ(seq[4], sVal70);
|
||||
seq = {sVal10, sVal20, sVal30, sVal40, sVal50, sVal60, sVal70, sVal80, sVal90, sVal100};
|
||||
sdv::sequence<SComplexNumber>::const_iterator cit = seq.cbegin();
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
cit = seq.cend() - 1;
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[seq.size() - 1], sVal90);
|
||||
cit = seq.begin() + 4;
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[3], sVal50);
|
||||
EXPECT_EQ(seq[4], sVal70);
|
||||
|
||||
// Element range erasure
|
||||
seq = {sVal10, sVal20, sVal30, sVal40, sVal50, sVal60, sVal70, sVal80, sVal90, sVal100};
|
||||
sdv::sequence<SComplexNumber>::iterator it1 = seq.begin();
|
||||
sdv::sequence<SComplexNumber>::iterator it2 = it1 + 1;
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
it1 = seq.end() - 1;
|
||||
it2 = seq.end();
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[seq.size() - 1], sVal90);
|
||||
it1 = seq.begin() + 1;
|
||||
it2 = it1 + 3;
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
EXPECT_EQ(seq[1], sVal60);
|
||||
seq = {sVal10, sVal20, sVal30, sVal40, sVal50, sVal60, sVal70, sVal80, sVal90, sVal100};
|
||||
sdv::sequence<SComplexNumber>::const_iterator cit1 = seq.cbegin();
|
||||
sdv::sequence<SComplexNumber>::const_iterator cit2 = cit1 + 1;
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
cit1 = seq.end() - 1;
|
||||
cit2 = seq.end();
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[seq.size() - 1], sVal90);
|
||||
cit1 = seq.begin() + 1;
|
||||
cit2 = cit1 + 3;
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[0], sVal20);
|
||||
EXPECT_EQ(seq[1], sVal60);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, PushPopFunctions)
|
||||
{
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u};
|
||||
sdv::sequence<SComplexNumber> seq;
|
||||
seq.push_back(sVal10);
|
||||
EXPECT_EQ(seq[0], sVal10);
|
||||
EXPECT_EQ(seq.size(), 1);
|
||||
seq.push_back(std::move(sVal20));
|
||||
EXPECT_EQ(seq[1], sVal20);
|
||||
EXPECT_EQ(seq.size(), 2);
|
||||
seq.pop_back();
|
||||
EXPECT_EQ(seq.size(), 1);
|
||||
seq.pop_back();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_NO_THROW(seq.pop_back());
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, SwapFunctionStatic)
|
||||
{
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u},
|
||||
sVal70{70u, 170u};
|
||||
sdv::sequence<SComplexNumber, 5> seq1 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber, 10> seq2 = {SComplexNumber{40u, 140u}, SComplexNumber{50u, 150u}, SComplexNumber{60u, 160u}, SComplexNumber{70u, 170u}};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], sVal40);
|
||||
EXPECT_EQ(seq1[1], sVal50);
|
||||
EXPECT_EQ(seq1[2], sVal60);
|
||||
EXPECT_EQ(seq1[3], sVal70);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
EXPECT_EQ(seq1[1], sVal20);
|
||||
EXPECT_EQ(seq1[2], sVal30);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], sVal40);
|
||||
EXPECT_EQ(seq2[1], sVal50);
|
||||
EXPECT_EQ(seq2[2], sVal60);
|
||||
EXPECT_EQ(seq2[3], sVal70);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, SwapFunctionDynamic)
|
||||
{
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u},
|
||||
sVal70{70u, 170u};
|
||||
sdv::sequence<SComplexNumber> seq1 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber> seq2 = {SComplexNumber{40u, 140u}, SComplexNumber{50u, 150u}, SComplexNumber{60u, 160u}, SComplexNumber{70u, 170u}};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], sVal40);
|
||||
EXPECT_EQ(seq1[1], sVal50);
|
||||
EXPECT_EQ(seq1[2], sVal60);
|
||||
EXPECT_EQ(seq1[3], sVal70);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
EXPECT_EQ(seq1[1], sVal20);
|
||||
EXPECT_EQ(seq1[2], sVal30);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], sVal40);
|
||||
EXPECT_EQ(seq2[1], sVal50);
|
||||
EXPECT_EQ(seq2[2], sVal60);
|
||||
EXPECT_EQ(seq2[3], sVal70);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, SwapFunctionMixed)
|
||||
{
|
||||
SComplexNumber sVal10{10u, 110u}, sVal20{20u, 120u}, sVal30{30u, 130u}, sVal40{40u, 140u}, sVal50{50u, 150u}, sVal60{60u, 160u},
|
||||
sVal70{70u, 170u};
|
||||
sdv::sequence<SComplexNumber, 5> seq1 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber> seq2 = {SComplexNumber{40u, 140u}, SComplexNumber{50u, 150u}, SComplexNumber{60u, 160u}, SComplexNumber{70u, 170u}};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], sVal40);
|
||||
EXPECT_EQ(seq1[1], sVal50);
|
||||
EXPECT_EQ(seq1[2], sVal60);
|
||||
EXPECT_EQ(seq1[3], sVal70);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], sVal10);
|
||||
EXPECT_EQ(seq2[1], sVal20);
|
||||
EXPECT_EQ(seq2[2], sVal30);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], sVal10);
|
||||
EXPECT_EQ(seq1[1], sVal20);
|
||||
EXPECT_EQ(seq1[2], sVal30);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], sVal40);
|
||||
EXPECT_EQ(seq2[1], sVal50);
|
||||
EXPECT_EQ(seq2[2], sVal60);
|
||||
EXPECT_EQ(seq2[3], sVal70);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, CompareOperator)
|
||||
{
|
||||
sdv::sequence<SComplexNumber> seq1 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
sdv::sequence<SComplexNumber> seq2;
|
||||
EXPECT_FALSE(seq1 == seq2);
|
||||
EXPECT_TRUE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_FALSE(seq1 <= seq2);
|
||||
EXPECT_TRUE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
seq2 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_TRUE(seq1 == seq2);
|
||||
EXPECT_FALSE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
SComplexNumber sVal40{40u, 140u};
|
||||
seq2.push_back(sVal40);
|
||||
EXPECT_FALSE(seq1 == seq2);
|
||||
EXPECT_TRUE(seq1 != seq2);
|
||||
EXPECT_TRUE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_FALSE(seq1 >= seq2);
|
||||
seq1.clear();
|
||||
seq2.clear();
|
||||
EXPECT_TRUE(seq1 == seq2);
|
||||
EXPECT_FALSE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
}
|
||||
|
||||
TEST_F(CComplexSequenceTypeTest, IteratorDistance)
|
||||
{
|
||||
sdv::sequence<SComplexNumber> seq1 = {SComplexNumber{10u, 110u}, SComplexNumber{20u, 120u}, SComplexNumber{30u, 130u}};
|
||||
EXPECT_EQ(std::distance(seq1.begin(), seq1.end()), seq1.length());
|
||||
}
|
||||
883
tests/unit_tests/basic_types/sequence_simple.cpp
Normal file
883
tests/unit_tests/basic_types/sequence_simple.cpp
Normal file
@@ -0,0 +1,883 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <support/sequence.h>
|
||||
|
||||
#include "basic_types_test.h"
|
||||
|
||||
using CSimpleSequenceTypeTest = CBasicTypesTest;
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, ConstructorStatic)
|
||||
{
|
||||
// Empty sequence
|
||||
sdv::sequence<uint32_t, 10> seqEmpty;
|
||||
EXPECT_TRUE(seqEmpty.empty());
|
||||
|
||||
// Fill constructor
|
||||
uint32_t uiVal = 100u;
|
||||
sdv::sequence<uint32_t, 10> seqFill(5, uiVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], 100u);
|
||||
EXPECT_EQ(seqFill[1], 100u);
|
||||
EXPECT_EQ(seqFill[2], 100u);
|
||||
EXPECT_EQ(seqFill[3], 100u);
|
||||
EXPECT_EQ(seqFill[4], 100u);
|
||||
|
||||
// Reserve constructor
|
||||
sdv::sequence<uint32_t, 10> seqReserve(10);
|
||||
EXPECT_FALSE(seqReserve.empty());
|
||||
EXPECT_EQ(seqReserve.size(), 10);
|
||||
|
||||
// Iterator constructor
|
||||
sdv::sequence<uint32_t, 15> seqIterator(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], 100u);
|
||||
EXPECT_EQ(seqIterator[1], 100u);
|
||||
EXPECT_EQ(seqIterator[2], 100u);
|
||||
EXPECT_EQ(seqIterator[3], 100u);
|
||||
EXPECT_EQ(seqIterator[4], 100u);
|
||||
|
||||
// Copy constructor
|
||||
sdv::sequence<uint32_t, 12> seqCopy(seqFill);
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 5);
|
||||
EXPECT_EQ(seqCopy[0], 100u);
|
||||
EXPECT_EQ(seqCopy[1], 100u);
|
||||
EXPECT_EQ(seqCopy[2], 100u);
|
||||
EXPECT_EQ(seqCopy[3], 100u);
|
||||
EXPECT_EQ(seqCopy[4], 100u);
|
||||
|
||||
// Move constructor
|
||||
sdv::sequence<uint32_t, 10> seqMove(std::move(seqFill));
|
||||
EXPECT_TRUE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 5);
|
||||
|
||||
// C++ vector constructor
|
||||
std::vector<uint32_t> vec = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t, 5> seqVector(vec);
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], 10u);
|
||||
EXPECT_EQ(seqVector[1], 20u);
|
||||
EXPECT_EQ(seqVector[2], 30u);
|
||||
|
||||
// Initializer list constructor
|
||||
sdv::sequence<uint32_t, 5> seqIList = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], 10u);
|
||||
EXPECT_EQ(seqIList[1], 20u);
|
||||
EXPECT_EQ(seqIList[2], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, ConstructorDynamic)
|
||||
{
|
||||
// Empty sequence
|
||||
sdv::sequence<uint32_t> seqEmpty;
|
||||
EXPECT_TRUE(seqEmpty.empty());
|
||||
|
||||
// Fill constructor
|
||||
uint32_t uiVal = 100u;
|
||||
sdv::sequence<uint32_t> seqFill(5, uiVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], 100u);
|
||||
EXPECT_EQ(seqFill[1], 100u);
|
||||
EXPECT_EQ(seqFill[2], 100u);
|
||||
EXPECT_EQ(seqFill[3], 100u);
|
||||
EXPECT_EQ(seqFill[4], 100u);
|
||||
|
||||
// Reserve constructor
|
||||
sdv::sequence<uint32_t> seqReserve(10);
|
||||
EXPECT_FALSE(seqReserve.empty());
|
||||
EXPECT_EQ(seqReserve.size(), 10);
|
||||
|
||||
// Iterator constructor
|
||||
sdv::sequence<uint32_t> seqIterator(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], 100u);
|
||||
EXPECT_EQ(seqIterator[1], 100u);
|
||||
EXPECT_EQ(seqIterator[2], 100u);
|
||||
EXPECT_EQ(seqIterator[3], 100u);
|
||||
EXPECT_EQ(seqIterator[4], 100u);
|
||||
|
||||
// Copy constructor
|
||||
sdv::sequence<uint32_t> seqCopy(seqFill);
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 5);
|
||||
EXPECT_EQ(seqCopy[0], 100u);
|
||||
EXPECT_EQ(seqCopy[1], 100u);
|
||||
EXPECT_EQ(seqCopy[2], 100u);
|
||||
EXPECT_EQ(seqCopy[3], 100u);
|
||||
EXPECT_EQ(seqCopy[4], 100u);
|
||||
|
||||
// Move constructor
|
||||
sdv::sequence<uint32_t> seqMove(std::move(seqFill));
|
||||
EXPECT_TRUE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 5);
|
||||
|
||||
// C++ vector constructor
|
||||
std::vector<uint32_t> vec = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t> seqVector(vec);
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], 10u);
|
||||
EXPECT_EQ(seqVector[1], 20u);
|
||||
EXPECT_EQ(seqVector[2], 30u);
|
||||
|
||||
// Initializer list constructor
|
||||
sdv::sequence<uint32_t> seqIList = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], 10u);
|
||||
EXPECT_EQ(seqIList[1], 20u);
|
||||
EXPECT_EQ(seqIList[2], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, AssignmentOperatorStatic)
|
||||
{
|
||||
sdv::sequence<uint32_t, 5> seq = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
EXPECT_EQ(seq[0], 10u);
|
||||
EXPECT_EQ(seq[1], 20u);
|
||||
EXPECT_EQ(seq[2], 30u);
|
||||
|
||||
// Copy assignment
|
||||
sdv::sequence<uint32_t, 7> seqCopy;
|
||||
EXPECT_TRUE(seqCopy.empty());
|
||||
seqCopy = seq;
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 3);
|
||||
EXPECT_EQ(seqCopy[0], 10u);
|
||||
EXPECT_EQ(seqCopy[1], 20u);
|
||||
EXPECT_EQ(seqCopy[2], 30u);
|
||||
|
||||
// Move assignment
|
||||
sdv::sequence<uint32_t, 3> seqMove;
|
||||
EXPECT_TRUE(seqMove.empty());
|
||||
seqMove = std::move(seq);
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 3);
|
||||
|
||||
// C++ vector assignment
|
||||
std::vector<uint32_t> vec = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t, 5> seqVector;
|
||||
EXPECT_TRUE(seqVector.empty());
|
||||
seqVector = vec;
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], 10u);
|
||||
EXPECT_EQ(seqVector[1], 20u);
|
||||
EXPECT_EQ(seqVector[2], 30u);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<uint32_t, 5> seqIList;
|
||||
EXPECT_TRUE(seqIList.empty());
|
||||
seqIList = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], 10u);
|
||||
EXPECT_EQ(seqIList[1], 20u);
|
||||
EXPECT_EQ(seqIList[2], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, AssignmentOperatorDynamic)
|
||||
{
|
||||
sdv::sequence<uint32_t> seq = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
EXPECT_EQ(seq[0], 10u);
|
||||
EXPECT_EQ(seq[1], 20u);
|
||||
EXPECT_EQ(seq[2], 30u);
|
||||
|
||||
// Copy assignment
|
||||
sdv::sequence<uint32_t> seqCopy;
|
||||
EXPECT_TRUE(seqCopy.empty());
|
||||
seqCopy = seq;
|
||||
EXPECT_FALSE(seqCopy.empty());
|
||||
EXPECT_EQ(seqCopy.size(), 3);
|
||||
EXPECT_EQ(seqCopy[0], 10u);
|
||||
EXPECT_EQ(seqCopy[1], 20u);
|
||||
EXPECT_EQ(seqCopy[2], 30u);
|
||||
|
||||
// Move assignment
|
||||
sdv::sequence<uint32_t> seqMove;
|
||||
EXPECT_TRUE(seqMove.empty());
|
||||
seqMove = std::move(seq);
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_FALSE(seqMove.empty());
|
||||
EXPECT_EQ(seqMove.size(), 3);
|
||||
|
||||
// C++ vector assignment
|
||||
std::vector<uint32_t> vec = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t> seqVector;
|
||||
EXPECT_TRUE(seqVector.empty());
|
||||
seqVector = vec;
|
||||
EXPECT_FALSE(seqVector.empty());
|
||||
EXPECT_EQ(seqVector.size(), 3);
|
||||
EXPECT_EQ(seqVector[0], 10u);
|
||||
EXPECT_EQ(seqVector[1], 20u);
|
||||
EXPECT_EQ(seqVector[2], 30u);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<uint32_t> seqIList;
|
||||
EXPECT_TRUE(seqIList.empty());
|
||||
seqIList = {10u, 20u, 30u};
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], 10u);
|
||||
EXPECT_EQ(seqIList[1], 20u);
|
||||
EXPECT_EQ(seqIList[2], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, AssignmentFunction)
|
||||
{
|
||||
// Fill assignment
|
||||
sdv::sequence<uint32_t> seqFill;
|
||||
uint32_t uiVal = 100;
|
||||
seqFill.assign(5, uiVal);
|
||||
EXPECT_FALSE(seqFill.empty());
|
||||
EXPECT_EQ(seqFill.size(), 5);
|
||||
EXPECT_EQ(seqFill[0], 100u);
|
||||
EXPECT_EQ(seqFill[1], 100u);
|
||||
EXPECT_EQ(seqFill[2], 100u);
|
||||
EXPECT_EQ(seqFill[3], 100u);
|
||||
EXPECT_EQ(seqFill[4], 100u);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence<uint32_t> seqIterator;
|
||||
seqIterator.assign(seqFill.begin(), seqFill.end());
|
||||
EXPECT_FALSE(seqIterator.empty());
|
||||
EXPECT_EQ(seqIterator.size(), 5);
|
||||
EXPECT_EQ(seqIterator[0], 100u);
|
||||
EXPECT_EQ(seqIterator[1], 100u);
|
||||
EXPECT_EQ(seqIterator[2], 100u);
|
||||
EXPECT_EQ(seqIterator[3], 100u);
|
||||
EXPECT_EQ(seqIterator[4], 100u);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<uint32_t> seqIList;
|
||||
seqIList.assign({10u, 20u, 30u});
|
||||
EXPECT_FALSE(seqIList.empty());
|
||||
EXPECT_EQ(seqIList.size(), 3);
|
||||
EXPECT_EQ(seqIList[0], 10u);
|
||||
EXPECT_EQ(seqIList[1], 20u);
|
||||
EXPECT_EQ(seqIList[2], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, PositionFunction)
|
||||
{
|
||||
// Position in the sequence
|
||||
sdv::sequence<uint32_t> seq1({10u, 20u, 30u, 40u, 50u});
|
||||
EXPECT_EQ(seq1.at(0), 10u);
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
EXPECT_EQ(seq1.front(), 10u);
|
||||
EXPECT_EQ(seq1.at(4), 50u);
|
||||
EXPECT_EQ(seq1[4], 50u);
|
||||
EXPECT_EQ(seq1.back(), 50u);
|
||||
EXPECT_THROW(seq1.at(5), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq1[5], sdv::XIndexOutOfRange);
|
||||
|
||||
// Empty sequence
|
||||
sdv::sequence<uint32_t> seq2;
|
||||
EXPECT_THROW(seq2.at(0), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2[0], sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2.front(), sdv::XIndexOutOfRange);
|
||||
EXPECT_THROW(seq2.back(), sdv::XIndexOutOfRange);
|
||||
|
||||
// Assignment
|
||||
seq1.at(0) = 110u;
|
||||
EXPECT_EQ(seq1[0], 110u);
|
||||
seq1[0] = 10u;
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
seq1.front() = 110u;
|
||||
EXPECT_EQ(seq1[0], 110u);
|
||||
seq1.back() = 150u;
|
||||
EXPECT_EQ(seq1[4], 150u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, CppVectorAccess)
|
||||
{
|
||||
// C++ cast operator
|
||||
sdv::sequence<uint32_t> seq = {10u, 20u, 30u};
|
||||
EXPECT_EQ(seq.size(), 3);
|
||||
std::vector<uint32_t> vec;
|
||||
EXPECT_TRUE(vec.empty());
|
||||
vec = seq;
|
||||
EXPECT_EQ(vec.size(), 3);
|
||||
|
||||
// Data access
|
||||
EXPECT_EQ(memcmp(seq.data(), vec.data(), 3 * sizeof(uint32_t)), 0);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, ForwardIteratorBasedAccess)
|
||||
{
|
||||
// Empty forward iterator
|
||||
sdv::sequence<uint32_t>::iterator itEmpty;
|
||||
EXPECT_NO_THROW(itEmpty++);
|
||||
EXPECT_NO_THROW(itEmpty--);
|
||||
EXPECT_NO_THROW(itEmpty += 2);
|
||||
EXPECT_NO_THROW(itEmpty -= 2);
|
||||
EXPECT_THROW(itEmpty[0], sdv::XIndexOutOfRange);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence seq({10u, 20u, 30u, 40u, 50u});
|
||||
EXPECT_NE(itEmpty, seq.begin());
|
||||
sdv::sequence<uint32_t>::iterator itPos = seq.begin();
|
||||
EXPECT_NE(itEmpty, itPos);
|
||||
EXPECT_EQ(itPos, seq.begin());
|
||||
sdv::sequence<uint32_t>::iterator itPosCopy;
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
itPosCopy = itPos;
|
||||
EXPECT_EQ(itPosCopy, itPos);
|
||||
sdv::sequence<uint32_t>::iterator itPosNew;
|
||||
EXPECT_NE(itPosNew, itPos);
|
||||
itPosNew = std::move(itPosCopy);
|
||||
EXPECT_EQ(itPosNew, itPos);
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
|
||||
// Iterator element access
|
||||
EXPECT_EQ(*itPos, 10u);
|
||||
EXPECT_EQ(itPos[0], 10u);
|
||||
EXPECT_EQ(itPos[4], 50u);
|
||||
EXPECT_THROW(itPos[5], sdv::XIndexOutOfRange);
|
||||
*itPos = 110u;
|
||||
EXPECT_EQ(seq[0], 110u);
|
||||
itPos[4] = 150u;
|
||||
EXPECT_EQ(seq[4], 150u);
|
||||
seq[0] = 10u;
|
||||
seq[4] = 50u;
|
||||
|
||||
// Iterator iteration
|
||||
itPos++;
|
||||
EXPECT_EQ(*itPos, 20u);
|
||||
itPos += 3;
|
||||
EXPECT_EQ(*itPos, 50u);
|
||||
EXPECT_NO_THROW(itPos++); // Increases at the position following last
|
||||
EXPECT_THROW(*itPos, sdv::XIndexOutOfRange);
|
||||
EXPECT_EQ(itPos, seq.end());
|
||||
EXPECT_NO_THROW(itPos++); // Will be ignored; doesn't increase even more
|
||||
itPos--;
|
||||
EXPECT_EQ(*itPos, 50u);
|
||||
itPos -= 4;
|
||||
EXPECT_EQ(*itPos, 10u);
|
||||
EXPECT_NO_THROW(itPos--); // Will be ignored; doesn't decrease even more
|
||||
EXPECT_EQ(*itPos, 10u);
|
||||
EXPECT_EQ(itPos, seq.begin());
|
||||
|
||||
// Const iterator
|
||||
sdv::sequence<uint32_t>::const_iterator itPosConst = seq.cbegin();
|
||||
EXPECT_EQ(itPos, itPosConst);
|
||||
itPosConst++;
|
||||
EXPECT_EQ(*itPosConst, 20u);
|
||||
EXPECT_NE(itPosConst, itPos);
|
||||
itPos++;
|
||||
EXPECT_EQ(itPosConst, itPos);
|
||||
EXPECT_EQ(seq.cbegin(), seq.begin());
|
||||
EXPECT_EQ(seq.begin(), seq.cbegin());
|
||||
EXPECT_EQ(seq.cend(), seq.end());
|
||||
EXPECT_EQ(seq.end(), seq.cend());
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, ReverseIteratorBasedAccess)
|
||||
{
|
||||
// Empty reverse iterator
|
||||
sdv::sequence<uint32_t>::reverse_iterator itEmpty;
|
||||
EXPECT_NO_THROW(itEmpty--);
|
||||
EXPECT_NO_THROW(itEmpty++);
|
||||
EXPECT_NO_THROW(itEmpty -= 2);
|
||||
EXPECT_NO_THROW(itEmpty += 2);
|
||||
EXPECT_THROW(itEmpty[0], sdv::XIndexOutOfRange);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence seq({10u, 20u, 30u, 40u, 50u});
|
||||
EXPECT_NE(itEmpty, seq.rbegin());
|
||||
sdv::sequence<uint32_t>::reverse_iterator itPos = seq.rbegin();
|
||||
EXPECT_NE(itEmpty, itPos);
|
||||
EXPECT_EQ(itPos, seq.rbegin());
|
||||
sdv::sequence<uint32_t>::reverse_iterator itPosCopy;
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
itPosCopy = itPos;
|
||||
EXPECT_EQ(itPosCopy, itPos);
|
||||
sdv::sequence<uint32_t>::reverse_iterator itPosNew;
|
||||
EXPECT_NE(itPosNew, itPos);
|
||||
itPosNew = std::move(itPosCopy);
|
||||
EXPECT_EQ(itPosNew, itPos);
|
||||
EXPECT_NE(itPosCopy, itPos);
|
||||
|
||||
// Iterator element access
|
||||
EXPECT_EQ(*itPos, 50u);
|
||||
EXPECT_EQ(itPos[0], 50u);
|
||||
EXPECT_EQ(itPos[4], 10u);
|
||||
EXPECT_THROW(itPos[5], sdv::XIndexOutOfRange);
|
||||
*itPos = 150u;
|
||||
EXPECT_EQ(seq[4], 150u);
|
||||
itPos[4] = 110u;
|
||||
EXPECT_EQ(seq[0], 110u);
|
||||
seq[0] = 10u;
|
||||
seq[4] = 50u;
|
||||
|
||||
// Iterator iteration
|
||||
itPos++;
|
||||
EXPECT_EQ(*itPos, 40u);
|
||||
itPos += 3;
|
||||
EXPECT_EQ(*itPos, 10u);
|
||||
EXPECT_NO_THROW(itPos++); // Increases at the position following last
|
||||
EXPECT_THROW(*itPos, sdv::XIndexOutOfRange);
|
||||
EXPECT_EQ(itPos, seq.rend());
|
||||
EXPECT_NO_THROW(itPos++); // Will be ignored; doesn't increase even more
|
||||
itPos--;
|
||||
EXPECT_EQ(*itPos, 10u);
|
||||
itPos -= 4;
|
||||
EXPECT_EQ(*itPos, 50u);
|
||||
EXPECT_NO_THROW(itPos--); // Will be ignored; doesn't decrease even more
|
||||
EXPECT_EQ(*itPos, 50u);
|
||||
EXPECT_EQ(itPos, seq.rbegin());
|
||||
|
||||
// Const iterator
|
||||
sdv::sequence<uint32_t>::const_reverse_iterator itPosConst = seq.crbegin();
|
||||
EXPECT_EQ(itPos, itPosConst);
|
||||
itPosConst++;
|
||||
EXPECT_EQ(*itPosConst, 40u);
|
||||
EXPECT_NE(itPosConst, itPos);
|
||||
itPos++;
|
||||
EXPECT_EQ(itPosConst, itPos);
|
||||
EXPECT_EQ(seq.crbegin(), seq.rbegin());
|
||||
EXPECT_EQ(seq.rbegin(), seq.crbegin());
|
||||
EXPECT_EQ(seq.crend(), seq.rend());
|
||||
EXPECT_EQ(seq.rend(), seq.crend());
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, SequenceCapacityStatic)
|
||||
{
|
||||
// Empty string
|
||||
sdv::sequence<uint32_t, 20> seq;
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Filled string
|
||||
seq = {10u, 20u, 30u, 40u, 50u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Resize, reserve
|
||||
seq.resize(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(4);
|
||||
EXPECT_EQ(seq.size(), 4);
|
||||
EXPECT_EQ(seq.length(), 4);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.push_back(50u);
|
||||
seq.resize(10, 60u);
|
||||
EXPECT_EQ(seq[4], 50u);
|
||||
EXPECT_EQ(seq[5], 60u);
|
||||
EXPECT_EQ(seq[6], 60u);
|
||||
EXPECT_EQ(seq[7], 60u);
|
||||
EXPECT_EQ(seq[8], 60u);
|
||||
EXPECT_EQ(seq[9], 60u);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(5);
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.reserve(4);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.resize(5);
|
||||
|
||||
// Shrink to fit
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
seq.shrink_to_fit();
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
|
||||
// Clear
|
||||
seq.clear();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 20);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, SequenceCapacityDynamic)
|
||||
{
|
||||
// Empty string
|
||||
sdv::sequence<uint32_t> seq;
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 0);
|
||||
|
||||
// Filled string
|
||||
seq = {10u, 20u, 30u, 40u, 50u};
|
||||
EXPECT_FALSE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 5);
|
||||
|
||||
// Resize, reserve
|
||||
seq.resize(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(4);
|
||||
EXPECT_EQ(seq.size(), 4);
|
||||
EXPECT_EQ(seq.length(), 4);
|
||||
EXPECT_EQ(seq.capacity(), 4);
|
||||
seq.push_back(50u);
|
||||
seq.resize(10, 60u);
|
||||
EXPECT_EQ(seq[4], 50u);
|
||||
EXPECT_EQ(seq[5], 60u);
|
||||
EXPECT_EQ(seq[6], 60u);
|
||||
EXPECT_EQ(seq[7], 60u);
|
||||
EXPECT_EQ(seq[8], 60u);
|
||||
EXPECT_EQ(seq[9], 60u);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(5);
|
||||
EXPECT_EQ(seq.size(), 5);
|
||||
EXPECT_EQ(seq.length(), 5);
|
||||
EXPECT_EQ(seq.capacity(), 5);
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.reserve(4);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.resize(5);
|
||||
|
||||
// Shrink to fit
|
||||
seq.reserve(10);
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
seq.shrink_to_fit();
|
||||
EXPECT_EQ(seq.size(), 10);
|
||||
EXPECT_EQ(seq.length(), 10);
|
||||
EXPECT_EQ(seq.capacity(), 10);
|
||||
|
||||
// Clear
|
||||
seq.clear();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_EQ(seq.size(), 0);
|
||||
EXPECT_EQ(seq.length(), 0);
|
||||
EXPECT_EQ(seq.capacity(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, InsertFunction)
|
||||
{
|
||||
// Value assignment
|
||||
sdv::sequence<uint32_t> seq1;
|
||||
EXPECT_TRUE(seq1.empty());
|
||||
seq1.insert(seq1.begin(), 3, 10u);
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
EXPECT_EQ(seq1[1], 10u);
|
||||
EXPECT_EQ(seq1[2], 10u);
|
||||
seq1.insert(seq1.begin(), 2, 20u);
|
||||
EXPECT_EQ(seq1[0], 20u);
|
||||
EXPECT_EQ(seq1[1], 20u);
|
||||
EXPECT_EQ(seq1[2], 10u);
|
||||
seq1.insert(seq1.end(), 2, 30u);
|
||||
EXPECT_EQ(seq1[4], 10u);
|
||||
EXPECT_EQ(seq1[5], 30u);
|
||||
EXPECT_EQ(seq1[6], 30u);
|
||||
seq1.insert(seq1.begin() + 4, 2, 40u);
|
||||
EXPECT_EQ(seq1[0], 20u);
|
||||
EXPECT_EQ(seq1[1], 20u);
|
||||
EXPECT_EQ(seq1[2], 10u);
|
||||
EXPECT_EQ(seq1[3], 10u);
|
||||
EXPECT_EQ(seq1[4], 40u);
|
||||
EXPECT_EQ(seq1[5], 40u);
|
||||
EXPECT_EQ(seq1[6], 10u);
|
||||
EXPECT_EQ(seq1[7], 30u);
|
||||
EXPECT_EQ(seq1[8], 30u);
|
||||
|
||||
// Iterator assignment
|
||||
sdv::sequence<uint32_t> seq2;
|
||||
sdv::sequence<uint32_t> seq({10u, 20u, 30u});
|
||||
EXPECT_TRUE(seq2.empty());
|
||||
seq2.insert(seq2.begin(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
seq2.insert(seq2.begin(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
EXPECT_EQ(seq2[3], 10u);
|
||||
seq2.insert(seq2.end(), seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[5], 30u);
|
||||
EXPECT_EQ(seq2[6], 10u);
|
||||
EXPECT_EQ(seq2[7], 20u);
|
||||
EXPECT_EQ(seq2[8], 30u);
|
||||
seq2.insert(seq2.begin() + 4, seq.begin(), seq.end());
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
EXPECT_EQ(seq2[3], 10u);
|
||||
EXPECT_EQ(seq2[4], 10u);
|
||||
EXPECT_EQ(seq2[5], 20u);
|
||||
EXPECT_EQ(seq2[6], 30u);
|
||||
EXPECT_EQ(seq2[7], 20u);
|
||||
EXPECT_EQ(seq2[8], 30u);
|
||||
EXPECT_EQ(seq2[9], 10u);
|
||||
EXPECT_EQ(seq2[10], 20u);
|
||||
EXPECT_EQ(seq2[11], 30u);
|
||||
|
||||
// Initializer list assignment
|
||||
sdv::sequence<uint32_t> seq3;
|
||||
EXPECT_TRUE(seq3.empty());
|
||||
seq3.insert(seq3.begin(), {10u, 20u, 30u});
|
||||
EXPECT_EQ(seq3[0], 10u);
|
||||
EXPECT_EQ(seq3[1], 20u);
|
||||
EXPECT_EQ(seq3[2], 30u);
|
||||
seq3.insert(seq3.begin(), {10u, 20u, 30u});
|
||||
EXPECT_EQ(seq3[0], 10u);
|
||||
EXPECT_EQ(seq3[1], 20u);
|
||||
EXPECT_EQ(seq3[2], 30u);
|
||||
EXPECT_EQ(seq3[3], 10u);
|
||||
seq3.insert(seq3.end(), {10u, 20u, 30u});
|
||||
EXPECT_EQ(seq3[5], 30u);
|
||||
EXPECT_EQ(seq3[6], 10u);
|
||||
EXPECT_EQ(seq3[7], 20u);
|
||||
EXPECT_EQ(seq3[8], 30u);
|
||||
seq3.insert(seq3.begin() + 4, {10u, 20u, 30u});
|
||||
EXPECT_EQ(seq3[0], 10u);
|
||||
EXPECT_EQ(seq3[1], 20u);
|
||||
EXPECT_EQ(seq3[2], 30u);
|
||||
EXPECT_EQ(seq3[3], 10u);
|
||||
EXPECT_EQ(seq3[4], 10u);
|
||||
EXPECT_EQ(seq3[5], 20u);
|
||||
EXPECT_EQ(seq3[6], 30u);
|
||||
EXPECT_EQ(seq3[7], 20u);
|
||||
EXPECT_EQ(seq3[8], 30u);
|
||||
EXPECT_EQ(seq3[9], 10u);
|
||||
EXPECT_EQ(seq3[10], 20u);
|
||||
EXPECT_EQ(seq3[11], 30u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, EraseFunction)
|
||||
{
|
||||
// Single element erasure
|
||||
sdv::sequence<uint32_t> seq({10u, 20u, 30u, 40u, 50u, 60u, 70u, 80u, 90u, 100u});
|
||||
sdv::sequence<uint32_t>::iterator it = seq.begin();
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
it = seq.end() - 1;
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[seq.size() - 1], 90u);
|
||||
it = seq.begin() + 4;
|
||||
seq.erase(it);
|
||||
EXPECT_EQ(seq[3], 50u);
|
||||
EXPECT_EQ(seq[4], 70u);
|
||||
seq = {10u, 20u, 30u, 40u, 50u, 60u, 70u, 80u, 90u, 100u};
|
||||
sdv::sequence<uint32_t>::const_iterator cit = seq.cbegin();
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
cit = seq.cend() - 1;
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[seq.size() - 1], 90u);
|
||||
cit = seq.begin() + 4;
|
||||
seq.erase(cit);
|
||||
EXPECT_EQ(seq[3], 50u);
|
||||
EXPECT_EQ(seq[4], 70u);
|
||||
|
||||
// Element range erasure
|
||||
seq = {10u, 20u, 30u, 40u, 50u, 60u, 70u, 80u, 90u, 100u};
|
||||
sdv::sequence<uint32_t>::iterator it1 = seq.begin();
|
||||
sdv::sequence<uint32_t>::iterator it2 = it1 + 1;
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
it1 = seq.end() - 1;
|
||||
it2 = seq.end();
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[seq.size() - 1], 90u);
|
||||
it1 = seq.begin() + 1;
|
||||
it2 = it1 + 3;
|
||||
seq.erase(it1, it2);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
EXPECT_EQ(seq[1], 60u);
|
||||
seq = {10u, 20u, 30u, 40u, 50u, 60u, 70u, 80u, 90u, 100u};
|
||||
sdv::sequence<uint32_t>::const_iterator cit1 = seq.cbegin();
|
||||
sdv::sequence<uint32_t>::const_iterator cit2 = cit1 + 1;
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
cit1 = seq.end() - 1;
|
||||
cit2 = seq.end();
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[seq.size() - 1], 90u);
|
||||
cit1 = seq.begin() + 1;
|
||||
cit2 = cit1 + 3;
|
||||
seq.erase(cit1, cit2);
|
||||
EXPECT_EQ(seq[0], 20u);
|
||||
EXPECT_EQ(seq[1], 60u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, PushPopFunctions)
|
||||
{
|
||||
sdv::sequence<uint32_t> seq;
|
||||
uint32_t uiVal1 = 10u;
|
||||
seq.push_back(10u);
|
||||
EXPECT_EQ(seq[0], uiVal1);
|
||||
EXPECT_EQ(seq.size(), 1);
|
||||
uint32_t uiVal2 = 20u;
|
||||
seq.push_back(std::move(uiVal2));
|
||||
EXPECT_EQ(seq[1], 20u);
|
||||
EXPECT_EQ(seq.size(), 2);
|
||||
seq.pop_back();
|
||||
EXPECT_EQ(seq.size(), 1);
|
||||
seq.pop_back();
|
||||
EXPECT_TRUE(seq.empty());
|
||||
EXPECT_NO_THROW(seq.pop_back());
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, SwapFunctionStatic)
|
||||
{
|
||||
sdv::sequence<uint32_t, 5> seq1 = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t, 10> seq2 = {40u, 50u, 60u, 70u};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], 40u);
|
||||
EXPECT_EQ(seq1[1], 50u);
|
||||
EXPECT_EQ(seq1[2], 60u);
|
||||
EXPECT_EQ(seq1[3], 70u);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
EXPECT_EQ(seq1[1], 20u);
|
||||
EXPECT_EQ(seq1[2], 30u);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], 40u);
|
||||
EXPECT_EQ(seq2[1], 50u);
|
||||
EXPECT_EQ(seq2[2], 60u);
|
||||
EXPECT_EQ(seq2[3], 70u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, SwapFunctionDynamic)
|
||||
{
|
||||
sdv::sequence<uint32_t> seq1 = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t> seq2 = {40u, 50u, 60u, 70u};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], 40u);
|
||||
EXPECT_EQ(seq1[1], 50u);
|
||||
EXPECT_EQ(seq1[2], 60u);
|
||||
EXPECT_EQ(seq1[3], 70u);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
EXPECT_EQ(seq1[1], 20u);
|
||||
EXPECT_EQ(seq1[2], 30u);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], 40u);
|
||||
EXPECT_EQ(seq2[1], 50u);
|
||||
EXPECT_EQ(seq2[2], 60u);
|
||||
EXPECT_EQ(seq2[3], 70u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, SwapFunctionMixed)
|
||||
{
|
||||
sdv::sequence<uint32_t, 5> seq1 = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t> seq2 = {40u, 50u, 60u, 70u};
|
||||
seq1.swap(seq2);
|
||||
EXPECT_EQ(seq1.size(), 4);
|
||||
EXPECT_EQ(seq1[0], 40u);
|
||||
EXPECT_EQ(seq1[1], 50u);
|
||||
EXPECT_EQ(seq1[2], 60u);
|
||||
EXPECT_EQ(seq1[3], 70u);
|
||||
EXPECT_EQ(seq2.size(), 3);
|
||||
EXPECT_EQ(seq2[0], 10u);
|
||||
EXPECT_EQ(seq2[1], 20u);
|
||||
EXPECT_EQ(seq2[2], 30u);
|
||||
|
||||
sdv::swap(seq1, seq2);
|
||||
EXPECT_EQ(seq1.size(), 3);
|
||||
EXPECT_EQ(seq1[0], 10u);
|
||||
EXPECT_EQ(seq1[1], 20u);
|
||||
EXPECT_EQ(seq1[2], 30u);
|
||||
EXPECT_EQ(seq2.size(), 4);
|
||||
EXPECT_EQ(seq2[0], 40u);
|
||||
EXPECT_EQ(seq2[1], 50u);
|
||||
EXPECT_EQ(seq2[2], 60u);
|
||||
EXPECT_EQ(seq2[3], 70u);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, CompareOperator)
|
||||
{
|
||||
sdv::sequence<uint32_t> seq1 = {10u, 20u, 30u};
|
||||
sdv::sequence<uint32_t> seq2;
|
||||
EXPECT_FALSE(seq1 == seq2);
|
||||
EXPECT_TRUE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_FALSE(seq1 <= seq2);
|
||||
EXPECT_TRUE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
seq2 = {10u, 20u, 30u};
|
||||
EXPECT_TRUE(seq1 == seq2);
|
||||
EXPECT_FALSE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
seq2.push_back(40u);
|
||||
EXPECT_FALSE(seq1 == seq2);
|
||||
EXPECT_TRUE(seq1 != seq2);
|
||||
EXPECT_TRUE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_FALSE(seq1 >= seq2);
|
||||
seq1.clear();
|
||||
seq2.clear();
|
||||
EXPECT_TRUE(seq1 == seq2);
|
||||
EXPECT_FALSE(seq1 != seq2);
|
||||
EXPECT_FALSE(seq1 < seq2);
|
||||
EXPECT_TRUE(seq1 <= seq2);
|
||||
EXPECT_FALSE(seq1 > seq2);
|
||||
EXPECT_TRUE(seq1 >= seq2);
|
||||
}
|
||||
|
||||
TEST_F(CSimpleSequenceTypeTest, IteratorDistance)
|
||||
{
|
||||
sdv::sequence<uint32_t> seq1 = {10u, 20u, 30u};
|
||||
EXPECT_EQ(std::distance(seq1.begin(), seq1.end()), seq1.length());
|
||||
}
|
||||
1226
tests/unit_tests/basic_types/serdes.cpp
Normal file
1226
tests/unit_tests/basic_types/serdes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3881
tests/unit_tests/basic_types/string.cpp
Normal file
3881
tests/unit_tests/basic_types/string.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3797
tests/unit_tests/basic_types/u16string.cpp
Normal file
3797
tests/unit_tests/basic_types/u16string.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3797
tests/unit_tests/basic_types/u32string.cpp
Normal file
3797
tests/unit_tests/basic_types/u32string.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3792
tests/unit_tests/basic_types/u8string.cpp
Normal file
3792
tests/unit_tests/basic_types/u8string.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3792
tests/unit_tests/basic_types/wstring.cpp
Normal file
3792
tests/unit_tests/basic_types/wstring.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user