* Refs #5607. Fix logger compilation error and memory profiling test.

* Refs #5609. Add regresion test for writing/reading serialization.

* Refs #5609. Fix uint64 bug.

* Refs #5609. Add gtest as external project.

* Refs #5609. Fix googletest download.

* Refs #5609. Fix WriteUint64 test in Session.

* Refs #5609. Fix googletest find_package.

* Refs #5607. Fix printf warning.
This commit is contained in:
Julián Bermúdez Ortega 2019-06-12 17:10:46 +02:00 committed by Borja Outerelo
parent abcef44b1c
commit c59ead14c6
10 changed files with 280 additions and 26 deletions

View File

@ -26,11 +26,17 @@ option(UCLIENT_BUILD_EXAMPLES "Build examples" OFF)
option(UCLIENT_VERBOSE_SERIALIZATION "Build with serialization verbosity" OFF)
option(UCLIENT_VERBOSE_MESSAGE "Build with message verbosity" OFF)
option(BUILD_SHARED_LIBS "Control shared/static library building." OFF)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if((CMAKE_SYSTEM_NAME STREQUAL "") AND (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux"))
option(UCLIENT_MEMORY_TESTS "Build memory tests" OFF)
option(UCLIENT_PERFORMANCE_TESTS "Build performance tests" OFF)
endif()
option(UCLIENT_BIG_ENDIANNESS "Set the machine endianness to big endianness (by default is little endianness)" OFF)
set(UCLIENT_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/client.config" CACHE PATH "Configuration client file.")
###############################################################################
# Project
###############################################################################
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
if(UCLIENT_SUPERBUILD)
project(uclient_superbuild NONE)
include(${PROJECT_SOURCE_DIR}/cmake/SuperBuild.cmake)
@ -67,10 +73,8 @@ endif()
# Client configuration options
###############################################################################
# Load configuration file.
set(CLIENT_CONFIG "${PROJECT_SOURCE_DIR}/client.config" CACHE PATH "Configuration client file.")
if(EXISTS ${CLIENT_CONFIG})
configure_file(${CLIENT_CONFIG} ${PROJECT_SOURCE_DIR}/CMakeCache.txt COPYONLY)
if(EXISTS ${UCLIENT_CONFIG})
configure_file(${UCLIENT_CONFIG} ${PROJECT_SOURCE_DIR}/CMakeCache.txt COPYONLY)
load_cache(${PROJECT_SOURCE_DIR})
file(REMOVE ${PROJECT_SOURCE_DIR}/CMakeCache.txt)
else()
@ -269,7 +273,9 @@ endif()
###############################################################################
if(UCLIENT_BUILD_TESTS)
include(${PROJECT_SOURCE_DIR}/cmake/common/gtest.cmake)
check_gtest()
find_package(GTest REQUIRED)
find_package(GMock REQUIRED)
find_package(Threads REQUIRED)
enable_testing()
include(CTest)

View File

@ -34,11 +34,45 @@ if(NOT microcdr_FOUND)
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_SYSROOT:PATH=${CMAKE_SYSROOT}
-DCHECK_ENDIANNESS:BOOL=${CHECK_ENDIANNESS}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCONFIG_BIG_ENDIANNESS:BOOL=${UCLIENT_BIG_ENDIANNESS}
)
list(APPEND _deps ucdr)
endif()
if(UCLIENT_BUILD_TESTS)
unset(googletest_DIR CACHE)
enable_language(CXX)
find_package(GTest QUIET)
find_package(GMock QUIET)
if(NOT GTest_FOUND OR NOT GMock_FOUND)
unset(GTEST_ROOT CACHE)
unset(GMOCK_ROOT CACHE)
ExternalProject_Add(googletest
GIT_REPOSITORY
https://github.com/google/googletest.git
GIT_TAG
2fe3bd994b3189899d93f1d5a881e725e046fdc2
PREFIX
${PROJECT_BINARY_DIR}/googletest
INSTALL_DIR
${PROJECT_BINARY_DIR}/temp_install
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
$<$<PLATFORM_ID:Windows>:-Dgtest_force_shared_crt:BOOL=ON>
BUILD_COMMAND
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config Release --target install
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config Debug --target install
INSTALL_COMMAND
""
)
set(GTEST_ROOT ${PROJECT_BINARY_DIR}/temp_install CACHE PATH "" FORCE)
set(GMOCK_ROOT ${PROJECT_BINARY_DIR}/temp_install CACHE PATH "" FORCE)
list(APPEND _deps googletest)
endif()
endif()
# Client project.
ExternalProject_Add(uclient
SOURCE_DIR

View File

@ -0,0 +1,130 @@
# Locate the Google C++ Mocking Framework.
# (This file is almost an identical copy of the original FindGTest.cmake file,
# feel free to use it as it is or modify it for your own needs.)
#
#
# Defines the following variables:
#
# GMOCK_FOUND - Found the Google Testing framework
# GMOCK_INCLUDE_DIRS - Include directories
#
# Also defines the library variables below as normal
# variables. These contain debug/optimized keywords when
# a debugging library is found.
#
# GMOCK_BOTH_LIBRARIES - Both libgmock & libgmock-main
# GMOCK_LIBRARIES - libgmock
# GMOCK_MAIN_LIBRARIES - libgmock-main
#
# Accepts the following variables as input:
#
# GMOCK_ROOT - (as a CMake or environment variable)
# The root directory of the gmock install prefix
#
# GMOCK_MSVC_SEARCH - If compiling with MSVC, this variable can be set to
# "MD" or "MT" to enable searching a gmock build tree
# (defaults: "MD")
#
#-----------------------
# Example Usage:
#
# find_package(GMock REQUIRED)
# include_directories(${GMOCK_INCLUDE_DIRS})
#
# add_executable(foo foo.cc)
# target_link_libraries(foo ${GMOCK_BOTH_LIBRARIES})
#
#=============================================================================
# This file is released under the MIT licence:
#
# Copyright (c) 2011 Matej Svec
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#=============================================================================
function(_gmock_append_debugs _endvar _library)
if(${_library} AND ${_library}_DEBUG)
set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
else()
set(_output ${${_library}})
endif()
set(${_endvar} ${_output} PARENT_SCOPE)
endfunction()
function(_gmock_find_library _name)
find_library(${_name}
NAMES ${ARGN}
HINTS
$ENV{GMOCK_ROOT}
${GMOCK_ROOT}
PATH_SUFFIXES ${_gmock_libpath_suffixes}
)
mark_as_advanced(${_name})
endfunction()
if(NOT DEFINED GMOCK_MSVC_SEARCH)
set(GMOCK_MSVC_SEARCH MD)
endif()
set(_gmock_libpath_suffixes lib)
if(MSVC)
if(GMOCK_MSVC_SEARCH STREQUAL "MD")
list(APPEND _gmock_libpath_suffixes
msvc/gmock-md/Debug
msvc/gmock-md/Release)
elseif(GMOCK_MSVC_SEARCH STREQUAL "MT")
list(APPEND _gmock_libpath_suffixes
msvc/gmock/Debug
msvc/gmock/Release)
endif()
endif()
find_path(GMOCK_INCLUDE_DIR gmock/gmock.h
HINTS
$ENV{GMOCK_ROOT}/include
${GMOCK_ROOT}/include
)
mark_as_advanced(GMOCK_INCLUDE_DIR)
if(MSVC AND GMOCK_MSVC_SEARCH STREQUAL "MD")
# The provided /MD project files for Google Mock add -md suffixes to the
# library names.
_gmock_find_library(GMOCK_LIBRARY gmock-md gmock)
_gmock_find_library(GMOCK_LIBRARY_DEBUG gmock-mdd gmockd)
_gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main-md gmock_main)
_gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_main-mdd gmock_maind)
else()
_gmock_find_library(GMOCK_LIBRARY gmock)
_gmock_find_library(GMOCK_LIBRARY_DEBUG gmockd)
_gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main)
_gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_maind)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMock DEFAULT_MSG GMOCK_LIBRARY GMOCK_INCLUDE_DIR GMOCK_MAIN_LIBRARY)
if(GMOCK_FOUND)
set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR})
_gmock_append_debugs(GMOCK_LIBRARIES GMOCK_LIBRARY)
_gmock_append_debugs(GMOCK_MAIN_LIBRARIES GMOCK_MAIN_LIBRARY)
set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES})
endif()

View File

@ -23,6 +23,7 @@
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
#define YELLOW_DARK "\x1B[0;33m"
#define PURPLE_DARK "\x1B[0;35m"
@ -375,9 +376,8 @@ const char* reply_to_string(const BaseObjectReply* reply)
void print_create_client_submessage(const char* pre, const CREATE_CLIENT_Payload* payload)
{
printf("%s[CREATE CLIENT | %s | session: 0x%02X | key: %s]%s",
printf("%s[CREATE CLIENT | session: 0x%02X | key: %s]%s",
pre,
request_to_string(&payload->base),
payload->client_representation.session_id,
data_to_string(payload->client_representation.client_key.data, 4),
RESTORE_COLOR);
@ -481,9 +481,9 @@ void print_delete_submessage(const char* pre, const DELETE_Payload* payload)
void print_status_agent_submessage(const char* pre, const STATUS_AGENT_Payload* payload)
{
printf("%s[STATUS AGENT | %s]%s",
(void) payload;
printf("%s[STATUS AGENT]%s",
pre,
reply_to_string(&payload->base),
RESTORE_COLOR);
}
@ -536,7 +536,7 @@ void print_read_data_submessage(const char* pre, const READ_DATA_Payload* payloa
printf("%s[READ DATA | format: %s | istream: 0x%02X | %s | dc: %s]%s",
pre,
format,
payload->read_specification.input_stream_id,
payload->read_specification.preferred_stream_id,
request_to_string(&payload->base),
(payload->read_specification.optional_delivery_control) ? "yes" : "no",
RESTORE_COLOR);
@ -655,7 +655,7 @@ void print_tail(int64_t initial_log_time)
#ifdef WIN32
printf(" %st: %I64ims%s", BLUE, ms, RESTORE_COLOR);
#else
printf(" %st: %lims%s", BLUE, ms, RESTORE_COLOR);
printf(" %st: %" PRId64 "ms%s", BLUE, ms, RESTORE_COLOR);
#endif
}

View File

@ -154,7 +154,7 @@ inline void read_format_data(
uint16_t request_id)
{
(void) length;
ub->last_data_size = 0; //reset alignment (as if we were created a new ucdrBuffer)
ub->last_data_size = 8; //reset alignment (as if we were created a new ucdrBuffer)
session->on_topic(session, object_id, request_id, stream_id, ub, session->on_topic_args);
}

View File

@ -21,7 +21,7 @@ bool uxr_prepare_output_stream(uxrSession* session, uxrStreamId stream_id, uxrOb
uxr_init_base_object_request(&session->info, datawriter_id, &payload.base);
(void) uxr_serialize_WRITE_DATA_Payload_Data(ub, &payload);
ub->last_data_size = 0; //reset alignment (as if we were created a new ucdrBuffer)
ub->last_data_size = 8; //reset alignment (as if we were created a new ucdrBuffer)
}
return !ub->error;

View File

@ -7,13 +7,13 @@ fi
mkdir build && cd build;
# Configure global cmake.
cmake -DTHIRDPARTY=ON ..;
cmake ..;
# Compile profiles.
PROFILES="complete_profile core_profile xml_profile ref_profile tcp_profile udp_profile serial_profile"
PROFILES="complete_profile core_profile tcp_profile udp_profile serial_profile"
for P in $PROFILES
do
cmake -DCLIENT_CONFIG="${PWD}"/../test/memory/memory_map/$P.config ..;
cmake -DUCLIENT_CONFIG="${PWD}"/../test/memory/memory_map/$P.config ..;
make;
../test/memory/memory_map/memory_map.sh $P
done
@ -22,6 +22,6 @@ done
python3 ../test/memory/memory_map/memory_map_analysis.py ./memory_map.txt
# Launch stack analysis.
cmake -DTHIRDPARTY=ON -DMEMORY_PERFORMANCE=ON -DCLIENT_CONFIG="${PWD}"/../test/memory/consumption/performance_profile.config ..
cmake -DUCLIENT_MEMORY_TESTS=ON -DUCLIENT_CONFIG="${PWD}"/../test/memory/consumption/performance_profile.config ..
make
../test/memory/consumption/stack_usage.sh

View File

@ -31,8 +31,11 @@ if(NOT PROFILE_SERIAL_TRANSPORT)
else()
set(SRCS SerialComm.cpp)
add_executable(${PROJECT_NAME} ${SRCS})
set_common_compile_options(${PROJECT_NAME})
if(MSVC OR MSVC_IDE)
target_compile_options(${PROJECT_NAME} PRIVATE /wd4996)
endif()
@ -43,15 +46,25 @@ else()
DEPENDENCIES
microxrcedds_client
)
target_link_libraries(${PROJECT_NAME} microxrcedds_client ${GTEST_BOTH_LIBRARIES})
target_link_libraries(${PROJECT_NAME}
PRIVATE
microxrcedds_client
${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}
PRIVATE
${GTEST_INCLUDE_DIRS}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED YES
CXX_STANDARD
11
CXX_STANDARD_REQUIRED
YES
)
endif()

View File

@ -5,7 +5,9 @@ macro(unitary_test TEST_NAME TEST_SOURCE)
set(SRCS ${TEST_SOURCE})
add_executable(${TEST_NAME} ${TEST_SOURCE})
set_common_compile_options(${TEST_NAME})
if(MSVC OR MSVC_IDE)
target_compile_options(${TEST_NAME} PRIVATE /wd4996)
endif()
@ -15,7 +17,13 @@ macro(unitary_test TEST_NAME TEST_SOURCE)
get_target_property(CLIENT_INCLUDES microxrcedds_client INCLUDE_DIRECTORIES)
include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/../../src)
target_link_libraries(${TEST_NAME} microcdr ${GTEST_BOTH_LIBRARIES})
target_link_libraries(${TEST_NAME}
PRIVATE
microcdr
${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
target_include_directories(${TEST_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}
@ -25,9 +33,12 @@ macro(unitary_test TEST_NAME TEST_SOURCE)
)
set_target_properties(${TEST_NAME} PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED YES
CXX_STANDARD
11
CXX_STANDARD_REQUIRED
YES
)
endmacro()
unitary_test(StreamId session/streams/StreamId.cpp)

View File

@ -19,6 +19,7 @@ extern "C"
#include <c/core/session/submessage.c>
#include <c/core/session/session_info.c>
#include <c/core/session/read_access.c>
#include <c/core/session/write_access.c>
#include <c/util/time.c>
@ -35,6 +36,7 @@ extern "C"
#define MTU 64
#define HISTORY 4
#define OFFSET 4
#define DATA_PAYLOAD_SIZE 4
class SessionTest : public testing::Test
@ -223,7 +225,13 @@ public:
static void on_topic_func (struct uxrSession* session, uxrObjectId object_id, uint16_t request_id,
uxrStreamId stream_id, struct ucdrBuffer* ub, void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) ub; (void) args;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) args;
if (std::string("ReadUint64") == ::testing::UnitTest::GetInstance()->current_test_info()->name())
{
uint64_t data;
ucdr_deserialize_uint64_t(ub, &data);
EXPECT_EQ(data, UINT64_MAX);
}
}
static void on_time_func (struct uxrSession* session, int64_t current_timestamp, int64_t transmit_timestamp,
@ -439,3 +447,55 @@ TEST_F(SessionTest, FragmentationInfoLastFragment)
FragmentationInfo info = on_get_fragmentation_info(frag_header.data());
EXPECT_EQ(LAST_FRAGMENT, info);
}
TEST_F(SessionTest, ReadUint64)
{
uxr_set_topic_callback(&session, on_topic_func, nullptr);
std::array<uint8_t, 32> buffer;
ucdrBuffer ub;
ucdr_init_buffer(&ub, buffer.data(), buffer.size());
uxr_serialize_message_header(&ub, session.info.id, UXR_NONE_STREAM, 0x00, session.info.key);
uxr_serialize_submessage_header(
&ub,
SUBMESSAGE_ID_DATA,
UCDR_MACHINE_ENDIANNESS,
DATA_PAYLOAD_SIZE + sizeof(uint64_t));
DATA_Payload_Data payload{};
uxr_serialize_DATA_Payload_Data(&ub, &payload);
ub.last_data_size = 8; // reset buffer alignment.
ucdr_serialize_uint64_t(&ub, UINT64_MAX);
ucdr_init_buffer(&ub, buffer.data(), size_t(ub.iterator - ub.init));
read_message(&session, &ub);
}
TEST_F(SessionTest, WriteUint64)
{
ucdrBuffer written_ub;
uxrStreamId output_reliable = uxr_stream_id(0, UXR_RELIABLE_STREAM, UXR_OUTPUT_STREAM);
uxrObjectId datawriter_id = uxr_object_id(0x01, UXR_DATAWRITER_ID);
uxr_prepare_output_stream(&session, output_reliable, datawriter_id, &written_ub, sizeof(uint64_t));
ucdr_serialize_uint64_t(&written_ub, UINT64_MAX);
ucdrBuffer expected_ub;
ucdr_init_buffer(&expected_ub, written_ub.init, size_t(written_ub.iterator - written_ub.init));
uxr_run_session_time(&session, 1);
uint8_t session_id; uint8_t stream_id; uint16_t seq_num; uint8_t key[4];
uxr_deserialize_message_header(&expected_ub, &session_id, &stream_id, &seq_num, key);
uint8_t id; uint8_t flags; uint16_t lenght;
uxr_deserialize_submessage_header(&expected_ub, &id, &flags, &lenght);
WRITE_DATA_Payload_Data payload;
uxr_deserialize_WRITE_DATA_Payload_Data(&expected_ub, &payload);
expected_ub.last_data_size = 8; // reset buffer alignment.
uint64_t data;
ucdr_deserialize_uint64_t(&expected_ub, &data);
EXPECT_EQ(data, UINT64_MAX);
}