Testing cleanup from Daniel Agar

This commit is contained in:
Lorenz Meier
2016-07-29 13:49:14 +02:00
parent 99aa5f49fc
commit 6ab9dc0acf
56 changed files with 1930 additions and 3416 deletions
+36 -91
View File
@@ -1,9 +1,5 @@
cmake_minimum_required(VERSION 2.8)
include(CMakeForceCompiler)
#CMAKE_FORCE_C_COMPILER(clang Clang)
#CMAKE_FORCE_CXX_COMPILER(clang++ Clang)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(-Qunused-arguments )
endif()
@@ -14,28 +10,16 @@ endif()
project(unittests)
enable_testing()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -std=gnu99 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -g -fno-exceptions -fno-rtti -fno-threadsafe-statics")
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-exceptions -fno-rtti -fno-threadsafe-statics -D__CUSTOM_FILE_IO__ -D__PX4_UNIT_TESTS -g -Wall -Werror")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fno-exceptions -fno-rtti -fno-threadsafe-statics -D__CUSTOM_FILE_IO__ -D__PX4_UNIT_TESTS -g -Wall -Werror")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare -Wno-unused-but-set-variable")
set(GTEST_DIR ${CMAKE_SOURCE_DIR}/googletest)
add_subdirectory(${GTEST_DIR})
include_directories(${GTEST_DIR}/include)
set(PX4_SRC ${CMAKE_SOURCE_DIR}/../src)
set(PX4_SITL_BUILD ${PX4_SRC}/../build_posix_sitl_test)
set(PX4_SITL_BUILD ${PX4_SRC}/../build_posix_sitl_default)
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${PX4_SITL_BUILD}/src)
@@ -52,38 +36,27 @@ include_directories(${PX4_SRC}/modules/uORB)
include_directories(${PX4_SRC}/platforms)
include_directories(${PX4_SRC}/platforms/posix/include)
include_directories(${PX4_SRC}/platforms/posix/px4_layer)
include_directories(${PX4_SRC}/platforms/posix/work_queue)
add_definitions(-D__CUSTOM_FILE_IO__)
add_definitions(-D__EXPORT=)
add_definitions(-D__PX4_POSIX)
add_definitions(-D__PX4_TESTS)
add_definitions(-D__PX4_UNIT_TESTS)
add_definitions(-D_UNIT_TEST=)
add_definitions(-DERROR=-1)
add_definitions(-Dmain_t=int)
add_definitions(-Dnoreturn_function=)
add_definitions(-DOK=0)
# check
add_custom_target(check
COMMAND ${CMAKE_CTEST_COMMAND} -j2 --output-on-failure
WORKING_DIR ${CMAKE_BINARY_DIR}
USES_TERMINAL)
function(add_gtest)
foreach(test_name ${ARGN})
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries(${test_name} gtest_main pthread px4_platform)
add_definitions(-D__PX4_DARWIN)
else()
target_link_libraries(${test_name} gtest_main pthread rt px4_platform)
add_definitions(-D__PX4_LINUX)
endif()
add_test(NAME ${test_name} COMMAND ${test_name} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
add_dependencies(check ${test_name})
endforeach()
endfunction()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_definitions(-D__PX4_DARWIN)
else()
add_definitions(-D__PX4_LINUX)
endif()
add_library(px4_platform
${PX4_SITL_BUILD}/src/modules/param/px4_parameters.c
${PX4_SITL_BUILD}/src/modules/param/px4_parameters.c
${PX4_SRC}/drivers/device/device_posix.cpp
${PX4_SRC}/drivers/device/i2c_posix.cpp
${PX4_SRC}/drivers/device/ringbuffer.cpp
@@ -112,8 +85,30 @@ add_library(px4_platform
${PX4_SRC}/platforms/posix/work_queue/work_lock.c
${PX4_SRC}/platforms/posix/work_queue/work_queue.c
${PX4_SRC}/platforms/posix/work_queue/work_thread.c
)
target_include_directories(px4_platform PUBLIC ${PX4_SRC}/platforms)
)
target_include_directories(px4_platform PUBLIC ${PX4_SRC}/platforms)
target_include_directories(px4_platform PUBLIC ${PX4_SRC}/platforms/posix/include)
target_include_directories(px4_platform PUBLIC ${PX4_SRC}/platforms/posix/work_queue)
# check
add_custom_target(check
COMMAND ${CMAKE_CTEST_COMMAND} -j2 --output-on-failure
WORKING_DIR ${CMAKE_BINARY_DIR}
USES_TERMINAL)
# add_gtest
function(add_gtest)
foreach(test_name ${ARGN})
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries(${test_name} gtest_main pthread px4_platform)
else()
target_link_libraries(${test_name} gtest_main pthread rt px4_platform)
endif()
add_test(NAME ${test_name} COMMAND ${test_name} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
add_dependencies(check ${test_name})
endforeach()
endfunction()
#######################################################################
@@ -122,59 +117,9 @@ target_include_directories(px4_platform PUBLIC ${PX4_SRC}/platforms)
# add_executable(example_test example_test.cpp)
# add_gtest(example_test)
# autodeclination_test
add_executable(autodeclination_test autodeclination_test.cpp ${PX4_SRC}/lib/geo_lookup/geo_mag_declination.c)
add_gtest(autodeclination_test)
# mixer_test
add_custom_command(OUTPUT ${PX4_SRC}/modules/systemlib/mixer/mixer_multirotor.generated.h
COMMAND ${PX4_SRC}/modules/systemlib/mixer/multi_tables.py > ${PX4_SRC}/modules/systemlib/mixer/mixer_multirotor.generated.h)
add_executable(mixer_test mixer_test.cpp
${PX4_SRC}/modules/systemlib/mixer/mixer.cpp
${PX4_SRC}/modules/systemlib/mixer/mixer_group.cpp
${PX4_SRC}/modules/systemlib/mixer/mixer_load.c
${PX4_SRC}/modules/systemlib/mixer/mixer_multirotor.cpp
${PX4_SRC}/modules/systemlib/mixer/mixer_multirotor.generated.h
${PX4_SRC}/modules/systemlib/mixer/mixer_simple.cpp
${PX4_SRC}/modules/systemlib/pwm_limit/pwm_limit.c
${PX4_SRC}/systemcmds/tests/test_mixer.cpp)
add_gtest(mixer_test)
# conversion_test
add_executable(conversion_test conversion_test.cpp ${PX4_SRC}/systemcmds/tests/test_conv.cpp)
add_gtest(conversion_test)
# sbus2_test
add_executable(sbus2_test sbus2_test.cpp
${PX4_SRC}/lib/rc/sbus.c)
add_gtest(sbus2_test)
# DSM test
add_executable(dsm_test dsm_test.cpp
${PX4_SRC}/lib/rc/dsm.c)
add_gtest(dsm_test)
# st24_test
add_executable(rc_input_test st24_test.cpp sumd_test.cpp
${PX4_SRC}/lib/rc/st24.c
${PX4_SRC}/lib/rc/sumd.c)
add_gtest(rc_input_test)
# sf0x_test
add_executable(sf0x_test sf0x_test.cpp
${PX4_SRC}/drivers/sf0x/sf0x_parser.cpp)
add_gtest(sf0x_test)
# param_test
add_executable(param_test param_test.cpp uorb_stub.cpp
${PX4_SRC}/modules/systemlib/bson/tinybson.c
${PX4_SRC}/modules/systemlib/param/param.c)
target_link_libraries(param_test ${PX4_SITL_BUILD}/libmsg_gen.a)
add_gtest(param_test)
# param_shmem_test
#add_executable(param_shmem_test param_test.cpp uorb_stub.cpp
# ${PX4_SRC}/modules/systemlib/bson/tinybson.c
# ${PX4_SRC}/modules/systemlib/param/param_shmem.c)
#add_gtest(param_shmem_test)
-18
View File
@@ -1,18 +0,0 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <drivers/drv_hrt.h>
#include <geo/geo.h>
#include <px4iofirmware/px4io.h>
#include <systemlib/err.h>
#include <systemlib/mixer/mixer.h>
#include "gtest/gtest.h"
TEST(AutoDeclinationTest, AutoDeclination)
{
ASSERT_NEAR(get_mag_declination(47.0, 8.0), 0.6, 0.5) << "declination differs more than 1 degree";
}
-10
View File
@@ -1,10 +0,0 @@
#include <systemlib/mixer/mixer.h>
#include <systemlib/err.h>
#include "../../src/systemcmds/tests/tests.h"
#include "gtest/gtest.h"
TEST(ConversionTest, quad_w_main)
{
ASSERT_EQ(test_conv(0, NULL), 0) << "Conversion test failed";
}
-14
View File
@@ -1,14 +0,0 @@
close all;
clear all;
M = importdata('px4io_v1.3.csv');
voltage = M.data(:, 1);
counts = M.data(:, 2);
plot(counts, voltage, 'b*-', 'LineWidth', 2, 'MarkerSize', 15);
coeffs = polyfit(counts, voltage, 1);
fittedC = linspace(min(counts), max(counts), 500);
fittedV = polyval(coeffs, fittedC);
hold on
plot(fittedC, fittedV, 'r-', 'LineWidth', 3);
slope = coeffs(1)
y_intersection = coeffs(2)
-70
View File
@@ -1,70 +0,0 @@
voltage, counts
4.3, 950
4.4, 964
4.5, 986
4.6, 1009
4.7, 1032
4.8, 1055
4.9, 1078
5.0, 1101
5.2, 1124
5.3, 1148
5.4, 1171
5.5, 1195
6.0, 1304
6.1, 1329
6.2, 1352
7.0, 1517
7.1, 1540
7.2, 1564
7.3, 1585
7.4, 1610
7.5, 1636
8.0, 1728
8.1, 1752
8.2, 1755
8.3, 1798
8.4, 1821
9.0, 1963
9.1, 1987
9.3, 2010
9.4, 2033
10.0, 2174
10.1, 2198
10.2, 2221
10.3, 2245
10.4, 2268
11.0, 2385
11.1, 2409
11.2, 2432
11.3, 2456
11.4, 2480
11.5, 2502
11.6, 2526
11.7, 2550
11.8, 2573
11.9, 2597
12.0, 2621
12.1, 2644
12.3, 2668
12.4, 2692
12.5, 2716
12.6, 2737
12.7, 2761
13.0, 2832
13.5, 2950
13.6, 2973
14.1, 3068
14.2, 3091
14.7, 3209
15.0, 3280
15.1, 3304
15.5, 3374
15.6, 3397
15.7, 3420
16.0, 3492
16.1, 3514
16.2, 3538
16.9, 3680
17.0, 3704
17.1, 3728
1 voltage counts
2 4.3 950
3 4.4 964
4 4.5 986
5 4.6 1009
6 4.7 1032
7 4.8 1055
8 4.9 1078
9 5.0 1101
10 5.2 1124
11 5.3 1148
12 5.4 1171
13 5.5 1195
14 6.0 1304
15 6.1 1329
16 6.2 1352
17 7.0 1517
18 7.1 1540
19 7.2 1564
20 7.3 1585
21 7.4 1610
22 7.5 1636
23 8.0 1728
24 8.1 1752
25 8.2 1755
26 8.3 1798
27 8.4 1821
28 9.0 1963
29 9.1 1987
30 9.3 2010
31 9.4 2033
32 10.0 2174
33 10.1 2198
34 10.2 2221
35 10.3 2245
36 10.4 2268
37 11.0 2385
38 11.1 2409
39 11.2 2432
40 11.3 2456
41 11.4 2480
42 11.5 2502
43 11.6 2526
44 11.7 2550
45 11.8 2573
46 11.9 2597
47 12.0 2621
48 12.1 2644
49 12.3 2668
50 12.4 2692
51 12.5 2716
52 12.6 2737
53 12.7 2761
54 13.0 2832
55 13.5 2950
56 13.6 2973
57 14.1 3068
58 14.2 3091
59 14.7 3209
60 15.0 3280
61 15.1 3304
62 15.5 3374
63 15.6 3397
64 15.7 3420
65 16.0 3492
66 16.1 3514
67 16.2 3538
68 16.9 3680
69 17.0 3704
70 17.1 3728
-74
View File
@@ -1,74 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "../../src/systemcmds/tests/tests.h"
#include <drivers/drv_hrt.h>
// Enable DSM parser output
#define DSM_DEBUG
#include <rc/dsm.h>
#include <systemlib/err.h>
#include <systemlib/mixer/mixer.h>
#include "gtest/gtest.h"
TEST(DSMTest, DSM)
{
const char *filepath = "testdata/dsm_x_data.txt";
FILE *fp;
fp = fopen(filepath, "rt");
ASSERT_TRUE(fp);
warnx("loading data from: %s", filepath);
float f;
unsigned x;
int ret;
// Trash the first 20 lines
for (unsigned i = 0; i < 20; i++) {
char buf[200];
(void)fgets(buf, sizeof(buf), fp);
}
// Init the parser
uint8_t frame[20];
uint16_t rc_values[18];
uint16_t num_values;
bool dsm_11_bit;
unsigned dsm_frame_drops = 0;
uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);
int rate_limiter = 0;
unsigned last_drop = 0;
while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
ASSERT_GT(ret, 0);
frame[0] = x;
unsigned len = 1;
// Pipe the data into the parser
bool result = dsm_parse(f*1e6, &frame[0], len, rc_values, &num_values,
&dsm_11_bit, &dsm_frame_drops, max_channels);
if (result) {
warnx("decoded packet with %d channels and %s encoding:", num_values, (dsm_11_bit) ? "11 bit" : "10 bit");
for (unsigned i = 0; i < num_values; i++) {
printf("chan #%u:\t%d\n", i, (int)rc_values[i]);
}
}
if (last_drop != (dsm_frame_drops)) {
warnx("frame dropped, now #%d", (dsm_frame_drops));
last_drop = dsm_frame_drops;
}
rate_limiter++;
}
ASSERT_EQ(ret, EOF);
}
-12
View File
@@ -1,12 +0,0 @@
#include <systemlib/mixer/mixer.h>
#include <systemlib/err.h>
#include "../../src/systemcmds/tests/tests.h"
#include "gtest/gtest.h"
TEST(MixerTest, Mixer)
{
const char *args[] = {"empty", "../ROMFS/px4fmu_test/mixers/IO_pass.mix", "../ROMFS/px4fmu_test/mixers/quad_test.mix"};
ASSERT_EQ(test_mixer(3, (char **)args), 0) << "IO_pass.mix failed";
}
-89
View File
@@ -1,89 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "../../src/systemcmds/tests/tests.h"
#include <drivers/drv_hrt.h>
// Enable S.BUS parser output
#define SBUS_DEBUG
#include <rc/sbus.h>
#include <systemlib/err.h>
#include <systemlib/mixer/mixer.h>
#include "gtest/gtest.h"
TEST(SBUS2Test, SBUS2)
{
const char *filepath = "testdata/sbus2_r7008SB.txt";
FILE *fp;
fp = fopen(filepath, "rt");
ASSERT_TRUE(fp);
warnx("loading data from: %s", filepath);
// if (argc < 2)
// errx(1, "Need a filename for the input file");
int byte_offset = 7;
// if (argc > 2) {
// char* end;
// byte_offset = strtol(argv[2],&end,10);
// }
warnx("RUNNING TEST WITH BYTE OFFSET OF: %d", byte_offset);
float f;
unsigned x;
int ret;
// Trash the first 20 lines
for (unsigned i = 0; i < 20; i++) {
char buf[200];
(void)fgets(buf, sizeof(buf), fp);
}
// Init the parser
uint8_t frame[SBUS_BUFFER_SIZE];
uint16_t rc_values[18];
uint16_t num_values;
unsigned sbus_frame_drops = 0;
unsigned sbus_frame_resets = 0;
bool sbus_failsafe;
bool sbus_frame_drop;
uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);
int rate_limiter = 0;
unsigned last_drop = 0;
while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
ASSERT_GT(ret, 0);
frame[0] = x;
unsigned len = 1;
// Pipe the data into the parser
hrt_abstime now = hrt_absolute_time();
// if (rate_limiter % byte_offset == 0) {
bool result = sbus_parse(now, &frame[0], len, rc_values, &num_values,
&sbus_failsafe, &sbus_frame_drop, &sbus_frame_drops, max_channels);
if (result) {
//warnx("decoded packet");
}
// }
if (last_drop != (sbus_frame_drops + sbus_frame_resets)) {
warnx("frame dropped, now #%d", (sbus_frame_drops + sbus_frame_resets));
last_drop = sbus_frame_drops + sbus_frame_resets;
}
rate_limiter++;
}
ASSERT_EQ(ret, EOF);
}
-60
View File
@@ -1,60 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <drivers/drv_hrt.h>
#include <drivers/sf0x/sf0x_parser.h>
#include <systemlib/err.h>
#include "gtest/gtest.h"
TEST(SF0XTest, SF0X)
{
const char _LINE_MAX = 20;
char _linebuf[_LINE_MAX];
_linebuf[0] = '\0';
const char *lines[] = {"0.01\r\n",
"0.02\r\n",
"0.03\r\n",
"0.04\r\n",
"0",
".",
"0",
"5",
"\r",
"\n",
"0",
"3\r",
"\n"
"\r\n",
"0.06",
"\r\n"
};
enum SF0X_PARSE_STATE state = SF0X_PARSE_STATE0_UNSYNC;
float dist_m;
char _parserbuf[_LINE_MAX];
unsigned _parsebuf_index = 0;
for (unsigned l = 0; l < sizeof(lines) / sizeof(lines[0]); l++) {
//printf("\n%s", _linebuf);
int parse_ret;
for (int i = 0; i < strlen(lines[l]); i++) {
parse_ret = sf0x_parser(lines[l][i], _parserbuf, &_parsebuf_index, &state, &dist_m);
if (parse_ret == 0) {
//printf("\nparsed: %f %s\n", dist_m, (parse_ret == 0) ? "OK" : "");
}
}
//printf("%s", lines[l]);
}
warnx("test finished");
}
-63
View File
@@ -1,63 +0,0 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <systemlib/err.h>
#include <drivers/drv_hrt.h>
#include <rc/st24.h>
#include "../../src/systemcmds/tests/tests.h"
#include "gtest/gtest.h"
TEST(ST24Test, ST24)
{
const char *filepath = "testdata/st24_data.txt";
//warnx("loading data from: %s", filepath);
FILE *fp;
fp = fopen(filepath, "rt");
ASSERT_TRUE(fp);
float f;
unsigned x;
int ret;
// Trash the first 20 lines
for (unsigned i = 0; i < 20; i++) {
char buf[200];
(void)fgets(buf, sizeof(buf), fp);
}
float last_time = 0;
while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
if (((f - last_time) * 1000 * 1000) > 3000) {
// warnx("FRAME RESET\n\n");
}
uint8_t b = static_cast<uint8_t>(x);
last_time = f;
// Pipe the data into the parser
//hrt_abstime now = hrt_absolute_time();
uint8_t rssi;
uint8_t rx_count;
uint16_t channel_count;
uint16_t channels[20];
if (!st24_decode(b, &rssi, &rx_count, &channel_count, channels, sizeof(channels) / sizeof(channels[0]))) {
//warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);
for (unsigned i = 0; i < channel_count; i++) {
//int16_t val = channels[i];
//warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
}
}
}
ASSERT_EQ(EOF, ret);
}
-63
View File
@@ -1,63 +0,0 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <systemlib/err.h>
#include <drivers/drv_hrt.h>
#include <rc/sumd.h>
#include "../../src/systemcmds/tests/tests.h"
#include "gtest/gtest.h"
TEST(SUMDTest, SUMD)
{
const char *filepath = "testdata/sumd_data.txt";
//warnx("loading data from: %s", filepath);
FILE *fp;
fp = fopen(filepath, "rt");
//ASSERT_TRUE(fp);
float f;
unsigned x;
int ret;
// Trash the first 20 lines
for (unsigned i = 0; i < 20; i++) {
char buf[200];
(void)fgets(buf, sizeof(buf), fp);
}
float last_time = 0;
while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
if (((f - last_time) * 1000 * 1000) > 3000) {
// warnx("FRAME RESET\n\n");
}
uint8_t b = static_cast<uint8_t>(x);
last_time = f;
// Pipe the data into the parser
//hrt_abstime now = hrt_absolute_time();
uint8_t rssi;
uint8_t rx_count;
uint16_t channel_count;
uint16_t channels[32];
if (!sumd_decode(b, &rssi, &rx_count, &channel_count, channels, 32)) {
//warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);
for (unsigned i = 0; i < channel_count; i++) {
//int16_t val = channels[i];
//warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
}
}
}
ASSERT_EQ(EOF, ret);
}
-1106
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-18019
View File
File diff suppressed because it is too large Load Diff
-14472
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -19,5 +19,3 @@ int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void
{
return 0;
}
@@ -1,211 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "uORBCommunicatorMock.hpp"
#include "uORB/uORB.h"
#include "uORBGtestTopics.hpp"
#include "px4_log.h"
#include <string.h>
#include "uORBManager.hpp"
#define LOG_TAG "uORBCommunicatorMock.cpp"
uORB_test::uORBCommunicatorMock::uORBCommunicatorMock()
: _rx_handler( nullptr )
{
/*
_sub_topicA_copy_fd = orb_subscribe( ORB_ID( topicA_copy ), (void*)&_sub_semaphore );
_sub_topicB_copy_fd = orb_subscribe( ORB_ID( topicB_copy), nullptr );
*/
_topic_translation_map[ "topicA" ] = "topicA_copy";
_topic_translation_map[ "topicB" ] = "topicB_copy";
_topic_translation_map[ "topicA_copy" ] = "topicA";
_topic_translation_map[ "topicB_copy" ] = "topicB";
}
int16_t uORB_test::uORBCommunicatorMock::add_subscription
(
const char * messageName,
int32_t msgRateInHz
)
{
int16_t rc = 0;
PX4_INFO( "got add_subscription for msg[%s] rate[%d]", messageName, msgRateInHz );
_msgCounters[messageName]._add_subscriptionCount++;
/*
int16_t rc = -1;
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
rc = _rx_handler->process_add_subscription
(
_topic_translation_map[messageName],
msgRateInHz
);
}
}
*/
return rc;
}
int16_t uORB_test::uORBCommunicatorMock::remove_subscription
(
const char * messageName
)
{
int16_t rc = 0;
PX4_INFO( "got remove_subscription for msg[%s]", messageName );
_msgCounters[messageName]._remove_subscriptionCount++;
/*
int16_t rc = -1;
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
rc = _rx_handler->process_remove_subscription
(
_topic_translation_map[messageName]
);
}
}
*/
return rc;
}
int16_t uORB_test::uORBCommunicatorMock::register_handler
(
uORBCommunicator::IChannelRxHandler* handler
)
{
int16_t rc = 0;
_rx_handler = handler;
return rc;
}
int16_t uORB_test::uORBCommunicatorMock::send_message
(
const char * messageName,
int32_t length,
uint8_t* data
)
{
int16_t rc = 0;
PX4_INFO( "send_message for msg[%s] datalen[%d]", messageName, length );
if( uORB::Manager::get_instance()->is_remote_subscriber_present( messageName ) )
{
_msgCounters[messageName]._send_messageCount++;
if( strcmp(messageName, "topicA") == 0 )
{
memcpy( &_topicAData, (void*)data, length );
}
else if( strcmp(messageName, "topicB") == 0 )
{
memcpy( &_topicBData, (void*)data, length );
}
else
{
//EPRINTF( "error messageName[%s] is not supported", messageName );
}
}
/*
int16_t rc = -1;
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
rc = _rx_handler->process_received_message
( _topic_translation_map[messageName], length, data );
}
}
*/
return rc;
}
bool uORB_test::uORBCommunicatorMock::get_remote_topicA_data
(
struct orb_topic_A* data
)
{
bool rc = false;
memcpy( data, &_topicAData, sizeof(_topicAData) );
rc = true;
/*
if( orb_copy(ORB_ID(topicA_copy), _sub_topicA_copy_fd, data) == OK )
{
rc = true;
}
*/
return rc;
}
bool uORB_test::uORBCommunicatorMock::get_remote_topicB_data
(
struct orb_topic_B* data
)
{
bool rc = false;
memcpy( data, &_topicBData, sizeof(_topicBData) );
rc = true;
/*
if( orb_copy(ORB_ID(topicB_copy), _sub_topicB_copy_fd, data) == OK )
{
rc = true;
}
*/
return rc;
}
void uORB_test::uORBCommunicatorMock::reset_counters()
{
InterfaceCounters resetCounter;
resetCounter._add_subscriptionCount = 0;
resetCounter._remove_subscriptionCount = 0;
resetCounter._send_messageCount = 0;
std::map<std::string, InterfaceCounters>::iterator it;
for( it = _msgCounters.begin(); it != _msgCounters.end(); ++it )
{
it->second = resetCounter;
}
}
uORB_test::uORBCommunicatorMock::InterfaceCounters uORB_test::uORBCommunicatorMock::get_interface_counters(const char * messageName )
{
return _msgCounters[ messageName ];
}
@@ -1,140 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef _uORBCommunicatorMock_hpp_
#define _uORBCommunicatorMock_hpp_
#include "uORB/uORBCommunicator.hpp"
#include "uORBGtestTopics.hpp"
#include <map>
#include <string>
#include <set>
namespace uORB_test
{
class uORBCommunicatorMock;
}
class uORB_test::uORBCommunicatorMock : public uORBCommunicator::IChannel
{
public:
//counters to track how many times the iterface is called from
// uorb.
typedef struct
{
int64_t _add_subscriptionCount;
int64_t _remove_subscriptionCount;
int64_t _send_messageCount;
}InterfaceCounters;
uORBCommunicatorMock();
/**
* @brief Interface to notify the remote entity of interest of a
* subscription for a message.
*
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @param msgRate
* The max rate at which the subscriber can accept the messages.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t add_subscription( const char *messageName, int32_t msgRateInHz );
/**
* @brief Interface to notify the remote entity of removal of a subscription
*
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not necessarily mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t remove_subscription( const char * messageName );
/**
* Register Message Handler. This is internal for the IChannel implementer*
*/
virtual int16_t register_handler( uORBCommunicator::IChannelRxHandler* handler );
/**
* @brief Sends the data message over the communication link.
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @param length
* The length of the data buffer to be sent.
* @param data
* The actual data to be sent.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t send_message( const char * messageName, int32_t length, uint8_t* data);
uORBCommunicator::IChannelRxHandler* get_rx_handler()
{
return _rx_handler;
}
bool get_remote_topicA_data( struct orb_topic_A* data );
bool get_remote_topicB_data( struct orb_topic_B* data );
void reset_counters();
InterfaceCounters get_interface_counters( const char * messageName );
private:
uORBCommunicator::IChannelRxHandler* _rx_handler;
//int _sub_topicA_copy_fd;
//int _sub_topicB_copy_fd;
std::map<std::string, std::string> _topic_translation_map;
struct orb_topic_A _topicAData;
struct orb_topic_B _topicBData;
std::map<std::string, InterfaceCounters> _msgCounters;
};
#endif /* _uORBCommunicatorMock_test_hpp_ */
@@ -1,138 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "uORBCommunicatorMockLoopback.hpp"
#include "uORB/uORB.h"
#include "uORBGtestTopics.hpp"
#include "uORBManager.hpp"
#include <string.h>
#include "px4_log.h"
#define LOG_TAG "uORBCommunicatorMockLoopback.cpp"
uORB_test::uORBCommunicatorMockLoopback::uORBCommunicatorMockLoopback()
: _rx_handler( nullptr )
{
//_sub_topicA_clone_fd = orb_subscribe( ORB_ID( topicA_clone ), (void*)&_sub_semaphore );
//_sub_topicB_clone_fd = orb_subscribe( ORB_ID( topicB_clone ), nullptr );
_topic_translation_map[ "topicA" ] = "topicA_clone";
_topic_translation_map[ "topicB" ] = "topicB_clone";
_topic_translation_map[ "topicA_clone" ] = "topicA";
_topic_translation_map[ "topicB_clone" ] = "topicB";
}
int16_t uORB_test::uORBCommunicatorMockLoopback::add_subscription
(
const char * messageName,
int32_t msgRateInHz
)
{
int16_t rc = -1;
PX4_INFO( "got add_subscription for msg[%s] rate[%d]", messageName, msgRateInHz );
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
rc = _rx_handler->process_add_subscription
(
_topic_translation_map[messageName].c_str(),
msgRateInHz
);
}
}
return rc;
}
int16_t uORB_test::uORBCommunicatorMockLoopback::remove_subscription
(
const char * messageName
)
{
int16_t rc = -1;
PX4_INFO( "got remove_subscription for msg[%s]", messageName );
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
rc = _rx_handler->process_remove_subscription
(
_topic_translation_map[messageName].c_str()
);
}
}
return rc;
}
int16_t uORB_test::uORBCommunicatorMockLoopback::register_handler
(
uORBCommunicator::IChannelRxHandler* handler
)
{
int16_t rc = 0;
_rx_handler = handler;
return rc;
}
int16_t uORB_test::uORBCommunicatorMockLoopback::send_message
(
const char * messageName,
int32_t length,
uint8_t* data
)
{
int16_t rc = -1;
PX4_INFO( "send_message for msg[%s] datalen[%d]", messageName, length );
if( _rx_handler )
{
if( _topic_translation_map.find( messageName ) != _topic_translation_map.end() )
{
if( uORB::Manager::get_instance()->is_remote_subscriber_present( _topic_translation_map[messageName].c_str() ) )
{
rc = _rx_handler->process_received_message
( _topic_translation_map[messageName].c_str(), length, data );
PX4_INFO( "[uORBCommunicatorMockLoopback::send_message] return from[topic(%s)] _rx_handler->process_received_message[%d]", messageName, rc );
}
else
{
// this is eqvuilanet of not sending the message to the remote.
rc = 0;
}
}
}
return rc;
}
@@ -1,133 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef _uORBCommunicatorMockLoopback_hpp_
#define _uORBCommunicatorMockLoopback_hpp_
#include "uORB/uORBCommunicator.hpp"
#include "uORBGtestTopics.hpp"
#include <map>
#include <string>
#include <set>
namespace uORB_test
{
class uORBCommunicatorMockLoopback;
}
class uORB_test::uORBCommunicatorMockLoopback : public uORBCommunicator::IChannel
{
public:
uORBCommunicatorMockLoopback();
/**
* @brief Interface to notify the remote entity of interest of a
* subscription for a message.
*
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @param msgRate
* The max rate at which the subscriber can accept the messages.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t add_subscription( const char * messageName, int32_t msgRateInHz );
/**
* @brief Interface to notify the remote entity of removal of a subscription
*
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not necessarily mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t remove_subscription( const char * messageName );
/**
* Register Message Handler. This is internal for the IChannel implementer*
*/
virtual int16_t register_handler( uORBCommunicator::IChannelRxHandler* handler );
/**
* @brief Sends the data message over the communication link.
* @param messageName
* This represents the uORB message name; This message name should be
* globally unique.
* @param length
* The length of the data buffer to be sent.
* @param data
* The actual data to be sent.
* @return
* 0 = success; This means the messages is successfully sent to the receiver
* Note: This does not mean that the receiver as received it.
* otherwise = failure.
*/
virtual int16_t send_message( const char * messageName, int32_t length, uint8_t* data);
uORBCommunicator::IChannelRxHandler* get_rx_handler()
{
return _rx_handler;
}
/*
bool get_remote_topicA_data( struct orb_topic_A* data );
bool get_remote_topicB_data( struct orb_topic_B* data );
*/
private:
uORBCommunicator::IChannelRxHandler* _rx_handler;
/*
int _sub_topicA_clone_fd;
int _sub_topicB_clone_fd;
pal::Semaphore _sub_semaphore;
*/
std::map<std::string, std::string> _topic_translation_map;
/*
struct orb_topic_A _topicAData;
struct orb_topic_B _topicBData;
*/
};
#endif /* _uORBCommunicatorMockLoopback_hpp_ */
@@ -1,483 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "uORBCommunicatorMock.hpp"
#include "uORBCommunicatorMockLoopback.hpp"
#include "gtest/gtest.h"
#include "uORB.h"
#include "uORBManager.hpp"
#include "uORBGtestTopics.hpp"
#include "uORBDevices.hpp"
#include "px4_log.h"
#include <errno.h>
#define LOG_TAG "uORBCommunicator_gtests.cpp"
namespace px4
{
void init_once();
}
namespace uORB_test
{
class uORBCommunicatorTest : public ::testing::Test
{
public:
uORBCommunicatorTest() :
_masterDevice( nullptr )
{
px4::init_once();
// create the Master Device and initialize it
_masterDevice = new uORB::DeviceMaster(uORB::PUBSUB);
if( _masterDevice != nullptr )
{
_masterDevice->init();
}
// get the uORB::Manager and set the mock instance
// explicitly.
uORB::Manager::get_instance()->set_uorb_communicator( &_comm_channel );
}
protected:
uORB_test::uORBCommunicatorMock _comm_channel;
struct orb_topic_A _topicA;
struct orb_topic_B _topicB;
orb_advert_t _pub_ptr;
int _sub_fd;
uORB::DeviceMaster* _masterDevice;
};
//================= Unit tests for add_subscription ===================
// this test will validate if the uORB calls the "add_subscription"
// method if there is atleast one subscriber in the local system.
//=====================================================================
TEST_F( uORBCommunicatorTest, add_subscription_case1 )
{
// case 1: add subscription should not be called if there are no
// internal subscriber and only a publisher.
// Steps:
// 0. reset the interface counters.
// 1. advertize a topic
// 2. check to see if add_subscription is called.
// the count should be zero.
//step 0.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._add_subscriptionCount, 0 );
//step 1.
_topicA.val = 1;
ASSERT_NE( ( _pub_ptr = orb_advertise(ORB_ID(topicA), &_topicA) ), nullptr ) << "Failed to advertize uORB Topic orb_topic_A: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
//step 2.
c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._add_subscriptionCount, 0 );
}
TEST_F( uORBCommunicatorTest, add_subscription_case2 )
{
// case 1: add subscription should not be called if there is atleast one
// internal subscriber and only a publisher.
// Steps:
// 0. reset the interface counters.
// 1. advertize a topic
// 2. Add in internal subscriber.
// 3. check to see if add_subscription is called.
// the count should be 1.
// 4. unsubscribe the topic
//step 0.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._add_subscriptionCount, 0 );
//step 1.
_topicA.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicA), &_topicA);
PX4_INFO( "[uORBCommunicatorTest.add_subscription_case2] orb_advertize(topicA) returncode:(%p)", _pub_ptr );
ASSERT_TRUE( ( _pub_ptr != nullptr ) ) << "Failed to advertize uORB Topic orb_topic_A: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
// step 2
ASSERT_NE( ( _sub_fd = orb_subscribe(ORB_ID(topicA) ) ) , -1 ) << "Subscribe failed: %d" << errno;
PX4_INFO( "subscribe fd: %d", _sub_fd );
//step 3.
c = _comm_channel.get_interface_counters( "topicA" );
PX4_INFO( "interface counter for topicA: %d", (int)c._add_subscriptionCount );
ASSERT_EQ( c._add_subscriptionCount, 1 );
//step 4.
PX4_INFO( "Before unsubscribe for Topic A" );
ASSERT_EQ( orb_unsubscribe( _sub_fd ), OK );
PX4_INFO( "After unsubscribe for Topic A" );
}
//============ unit tests for remove_subscribtion =======
TEST_F( uORBCommunicatorTest, remove_subscribtion )
{
// remove subscription should be called if there after a subscription is removed.
// Steps:
// 0. reset the interface counters.
// 1. advertize a topic
// 2. Add in internal subscriber.
// 3. unsubscribe the topic
// 4. check the remove_subsciption counter it should be 1.
//step 0.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._remove_subscriptionCount, 0 );
//step 1.
// step 1.
_topicA.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicA), &_topicA);
PX4_INFO( "[uORBCommunicatorTest.remove_subscribtion] orb_advertize(topicA) returncode:(%p)", _pub_ptr );
ASSERT_TRUE( ( _pub_ptr != nullptr ) ) << "Failed to advertize uORB Topic orb_topic_A: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._remove_subscriptionCount, 0 );
// step 2
ASSERT_NE( ( _sub_fd = orb_subscribe(ORB_ID(topicA) )), -1 ); // << "Subscribe failed: " << _sub_fd << "errono: " << errno;
PX4_INFO( "subscribe fd: %d", _sub_fd );
c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._remove_subscriptionCount, 0 );
//step 3.
ASSERT_EQ( orb_unsubscribe( _sub_fd ), OK );
//step 4.
c = _comm_channel.get_interface_counters( "topicA" );
ASSERT_EQ( c._remove_subscriptionCount, 1 );
}
//============ unit tests for send_message =======
TEST_F(uORBCommunicatorTest, send_message_case1 )
{
// Case1: send message should not be called when a topic is advertized
// and there are no remote remote subscribers.
// Steps:
// 0. reset the interface counters.
// 1. advertize a topic
// 2. check to see that the send message counter is 0.
//step 0.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicA_sndmsg" );
ASSERT_EQ( c._send_messageCount, 0 );
//step 1.
ORB_DEFINE( topicA_sndmsg, struct orb_topic_A, nullptr, "TOPICA_SNDMSG:int16_t val;" );
_topicA.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicA_sndmsg ), &_topicA );
ASSERT_TRUE( ( _pub_ptr != nullptr ) ) << "Failed to advertize uORB Topic topicA_sndmsg: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
c = _comm_channel.get_interface_counters( "topicA_sndmsg" );
ASSERT_EQ( c._send_messageCount, 0 );
}
TEST_F(uORBCommunicatorTest, send_message_case2 )
{
// Case2: send message should be called when a topic is advertized
// and there are remote remote subscribers.
// Steps:
// 0. reset the interface counters.
// 1. Add a remote subscriber by calling the "process_add_subscription"
// 2. advertize a topic
// 3. check to see that the send message counter is 1 and check the value.
// 4. publish new data.
// 5. check to see that send_msg is incremented by 1 and check the value.
// 6. remove remote subscriber by calling the "process_remove_subscription"
// 7. publish new data.
// 8. check to see the sndmessage counter, it should not increment.
//step 0.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 0 );
//step 1.
uORBCommunicator::IChannelRxHandler* rx_handler = _comm_channel.get_rx_handler();
// add a local subsciber to avoid the issue of creating a node for the first time
// remote.
ASSERT_NE( ( _sub_fd = orb_subscribe(ORB_ID(topicB) ) ), -1 ) << "Subscribe failed for topicB: %d" << errno;
PX4_INFO( "subscribe fd: %d", _sub_fd );
ASSERT_EQ( rx_handler->process_add_subscription( "topicB", 1 ), 0 );
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 0 );
// step 2.
_topicB.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicB), &_topicB);
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
ASSERT_TRUE( _pub_ptr != nullptr ) << "Failed to advertize uORB Topic topicB: errno: " << errno;
//step 3.
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 1 );
struct orb_topic_B test_val;
_comm_channel.get_remote_topicB_data( &test_val );
ASSERT_EQ( test_val.val, 1 );
//step 4. publish new data.
_topicB.val = 2;
ASSERT_EQ( orb_publish( ORB_ID(topicB), _pub_ptr, &_topicB), OK );
//step 5.
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 2 );
_comm_channel.get_remote_topicB_data( &test_val );
ASSERT_EQ( test_val.val, 2 );
// step 6.
ASSERT_EQ( rx_handler->process_remove_subscription( "topicB" ), 0 );
ASSERT_EQ( orb_unsubscribe( _sub_fd ), OK );
//step 7. publish new data.
_topicB.val = 5;
ASSERT_EQ( orb_publish( ORB_ID(topicB), _pub_ptr, &_topicB), OK );
//step 8.
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 2 );
_comm_channel.get_remote_topicB_data( &test_val );
ASSERT_EQ( test_val.val, 2 );
}
//========== UNIT tests to verify the process_receive_message interface
//========== of rx handler.
TEST_F( uORBCommunicatorTest, rx_handler_rcv_data_case1 )
{
// this will mimic the process of calling the process_receive_message
// from remote and verify that the local subscribers got it
// are the steps.
// 1. clear the counters.
// 2. advertize a topic
// 3. add a local subscriber.
// 4. call process_receive_message.
// 5. check to see that the subscriber got the data and the message is not sent back
// by looking at the counter for snd message.
//step 1.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 0 );
// step 2.
_topicB.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicB), &_topicB);
ASSERT_TRUE( _pub_ptr != nullptr ) << "Failed to advertize uORB Topic topicB: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
// step 3.
ASSERT_NE( ( _sub_fd = orb_subscribe(ORB_ID(topicB)) ), -1 ) << "Subscribe failed for topicB: %d" << errno;
PX4_INFO( "subscribe fd: %d", _sub_fd );
//step 4.
uORBCommunicator::IChannelRxHandler* rx_handler = _comm_channel.get_rx_handler();
struct orb_topic_B testVal;
testVal.val = 10;
ASSERT_EQ( rx_handler->process_received_message( "topicB", sizeof( testVal ), (uint8_t*)(&testVal) ), 0 );
// step 5. check the values.
struct orb_topic_B receivedVal;
ASSERT_EQ( orb_copy(ORB_ID(topicB), _sub_fd, &receivedVal), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( testVal.val, receivedVal.val )
<< "copy(1) mismatch: " << testVal.val
<< " expected " << receivedVal.val;
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 0 );
// cleanup.
ASSERT_EQ( orb_unsubscribe( _sub_fd ), OK );
}
TEST_F( uORBCommunicatorTest, rx_handler_rcv_data_case2 )
{
// this will mimic the process of calling the process_receive_message
// from remote and verify that the local subscribers got it
// and also the message is send back to the remote. The following
// are the steps.
// 1. clear the counters.
// 2. advertize a topic
// 3. add a local subscriber.
// 4. add remote subscriber by calling the "process_add_subscription.
// 5. call process_receive_message.
// 6. check to see that the subscriber got the data and the message is not sent back
// by looking at the counter for snd message.
//step 1.
_comm_channel.reset_counters();
uORB_test::uORBCommunicatorMock::InterfaceCounters c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 0 );
// step 2.
_topicB.val = 1;
_pub_ptr = orb_advertise(ORB_ID(topicB), &_topicB);
ASSERT_TRUE( _pub_ptr != nullptr ) << "Failed to advertize uORB Topic topicB: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)_pub_ptr );
// step 3.
ASSERT_NE( ( _sub_fd = orb_subscribe(ORB_ID(topicB)) ), -1 ) << "Subscribe failed for topicB: %d" << errno;
PX4_INFO( "subscribe fd: %d", _sub_fd );
//step 4.
uORBCommunicator::IChannelRxHandler* rx_handler = _comm_channel.get_rx_handler();
ASSERT_EQ( rx_handler->process_add_subscription( "topicB", 1 ), 0 );
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 1 );
//step 5.
struct orb_topic_B testVal;
testVal.val = 15;
ASSERT_EQ( rx_handler->process_received_message( "topicB", sizeof( testVal ), (uint8_t*)(&testVal) ), 0 );
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 1 );
// step 6. check the values.
struct orb_topic_B receivedVal;
ASSERT_EQ( orb_copy(ORB_ID(topicB), _sub_fd, &receivedVal), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( testVal.val, receivedVal.val )
<< "copy(1) mismatch: " << testVal.val
<< " expected " << receivedVal.val;
c = _comm_channel.get_interface_counters( "topicB" );
ASSERT_EQ( c._send_messageCount, 1 );
// cleanup.
ASSERT_EQ( orb_unsubscribe( _sub_fd ), OK );
}
TEST_F( uORBCommunicatorTest, Loopback )
{
// create the loopback instance.
uORB_test::uORBCommunicatorMockLoopback _comm_channel_loopback;
//intiailize the uorb to remove the node map entries;
//orb_initialize();
//set the communucation channel interface.
uORB::Manager::get_instance()->set_uorb_communicator( &_comm_channel_loopback );
// now for the actual test.
orb_advert_t pub_topicA_ptr;
int sub_topicA_fd;
int sub_topicAClone_fd;
struct orb_topic_A topicA;
struct orb_topic_A topicAClone;
struct orb_topic_A topicALocal;
// step 1.
topicA.val = 10;
pub_topicA_ptr = orb_advertise(ORB_ID(topicA), &topicA);
PX4_INFO( "[uORBCommunicatorTest.Loopback]orb_advertize(topicA) return code:(%p)", pub_topicA_ptr );
ASSERT_TRUE( pub_topicA_ptr != nullptr ) << "Failed to advertize uORB Topic orb_topic_A: errno: " << errno;
PX4_INFO( "publist handle: 0x%08lx", (unsigned long)pub_topicA_ptr );
// step 2.
ASSERT_NE( ( sub_topicA_fd = orb_subscribe(ORB_ID(topicA)) ), -1 ) << "Subscribe failed: %d" << errno;
PX4_INFO( "subscribe fd: %d", sub_topicA_fd );
// step 3. check to see that the subscriber got a value of 10.
ASSERT_EQ( orb_copy(ORB_ID(topicA), sub_topicA_fd, &topicALocal), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( topicA.val, topicALocal.val )
<< "copy(1) mismatch: " << topicA.val
<< " expected " << topicALocal.val;
// subscribe a remote subscriber.
ASSERT_NE( ( sub_topicAClone_fd = orb_subscribe(ORB_ID(topicA_clone)) ), -1 ) << "Subscribe failed: %d" << errno;
PX4_INFO( "subscribe fd: %d", sub_topicAClone_fd );
ASSERT_EQ( orb_copy(ORB_ID(topicA_clone), sub_topicAClone_fd, &topicAClone), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( topicA.val, topicAClone.val )
<< "copy(1) mismatch: " << topicA.val
<< " expected " << topicAClone.val;
// publish a new data and check to see that the data is received on the remote.
topicA.val = 15;
ASSERT_EQ( orb_publish( ORB_ID(topicA), pub_topicA_ptr, &topicA), OK );
// check to see that the subscriber got a new value.
ASSERT_EQ( orb_copy(ORB_ID(topicA), sub_topicA_fd, &topicALocal), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( topicA.val, topicALocal.val )
<< "copy(1) mismatch: " << topicA.val
<< " expected " << topicALocal.val;
ASSERT_EQ( orb_copy(ORB_ID(topicA_clone), sub_topicAClone_fd, &topicAClone), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( topicA.val, topicAClone.val )
<< "copy(1) mismatch: " << topicA.val
<< " expected " << topicAClone.val;
// remove the remote subscriber and make sure that the data is not received,
ASSERT_EQ( orb_unsubscribe( sub_topicAClone_fd ), OK );
// publish a new data and check to see that the data is received on local this should not crash.
topicA.val = 20;
ASSERT_EQ( orb_publish( ORB_ID(topicA), pub_topicA_ptr, &topicA), OK );
// check to see that the subscriber got a new value.
ASSERT_EQ( orb_copy(ORB_ID(topicA), sub_topicA_fd, &topicALocal), OK ) << "copy(1) failed: " << errno;
ASSERT_EQ( topicA.val, topicALocal.val )
<< "copy(1) mismatch: " << topicA.val
<< " expected " << topicALocal.val;
//remove the local subscriber as well and publish new data; system should not crash.
ASSERT_EQ( orb_unsubscribe( sub_topicA_fd ), OK );
// publish a new data; this should not crash.
topicA.val = 25;
ASSERT_EQ( orb_publish( ORB_ID(topicA), pub_topicA_ptr, &topicA), OK );
}
}
@@ -1,58 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef _uORBGtestTopics_hpp_
#define _uORBGtestTopics_hpp_
#include "uORB/uORB.h"
namespace uORB_test
{
struct orb_topic_A
{
int16_t val;
};
struct orb_topic_B
{
int16_t val;
};
ORB_DEFINE(topicA, struct orb_topic_A, nullptr, "TOPICA:int16 val;");
ORB_DEFINE(topicB, struct orb_topic_B, nullptr, "TOPICB:int16 val;");
ORB_DEFINE(topicA_clone, struct orb_topic_A, nullptr, "TOPICA_CLONE:int16 val;";
ORB_DEFINE(topicB_clone, struct orb_topic_B, nullptr, "TOPICB_CLONE:int16 val;");
}
#endif // _UnitTest_uORBTopics_hpp_