Skip to content

Commit faf39b0

Browse files
YusukeKatoShotaAk
andcommitted
Add unit tests (#52)
* Use pointer for SerialPort instance instead of inheritance * Add test using fakeit * Install git comand in indsutrial_ci * Refactoring * Update CI * Use AFTER_SETUP_TARGET_WORKSPACE * driverインスタンスのメンバ変数のテストを追加 * バイナリデータが読み込まれたことを確認するテストを追加 * ASCIIデータが読み込まれたことを確認するテストを追加 * バイナリでもASCIIでもないデータが読み込まれたことを確認するテストを追加 * テストが通る状態に修正 --------- Co-authored-by: ShotaAk <s.aoki@rt-net.jp>
1 parent 94f1714 commit faf39b0

File tree

6 files changed

+224
-23
lines changed

6 files changed

+224
-23
lines changed

.github/workflows/industrial_ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
env:
18-
- { ROS_DISTRO: humble, ROS_REPO: ros }
18+
- { ROS_DISTRO: humble, ROS_REPO: ros, AFTER_SETUP_TARGET_WORKSPACE: 'apt update && apt install -y git' }
1919

2020
runs-on: ubuntu-latest
2121
steps:

CMakeLists.txt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,25 @@ install(DIRECTORY
8282
DESTINATION share/${PROJECT_NAME}/
8383
)
8484

85-
#if(BUILD_TESTING)
85+
if(BUILD_TESTING)
8686
# find_package(ament_lint_auto REQUIRED)
8787
# ament_lint_auto_find_test_dependencies()
88-
#endif()
88+
Set(FETCHCONTENT_QUIET FALSE)
89+
include(FetchContent)
90+
FetchContent_Declare(
91+
fakeit
92+
GIT_REPOSITORY https://github.com/eranpeer/FakeIt
93+
GIT_TAG 2.4.0
94+
GIT_PROGRESS TRUE)
95+
FetchContent_MakeAvailable(fakeit)
96+
97+
find_package(ament_cmake_gtest)
98+
ament_add_gtest(test_driver test/test_driver.cpp src/rt_usb_9axisimu_driver.cpp)
99+
target_include_directories(test_driver PRIVATE ${fakeit_SOURCE_DIR}/single_header/gtest)
100+
ament_target_dependencies(test_driver
101+
rclcpp
102+
sensor_msgs
103+
)
104+
endif()
89105

90106
ament_package()

include/rt_usb_9axisimu_driver/rt_usb_9axisimu.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,23 +178,23 @@ class SerialPort
178178
{
179179
}
180180

181-
~SerialPort()
181+
virtual ~SerialPort()
182182
{
183183
closeSerialPort();
184184
}
185185

186-
void setPort(const char * port)
186+
virtual void setPort(const char * port)
187187
{
188188
port_name_ = port;
189189
}
190190

191-
bool openPort(const char * port)
191+
virtual bool openPort(const char * port)
192192
{
193193
port_name_ = port;
194194
return openSerialPort();
195195
}
196196

197-
bool openSerialPort()
197+
virtual bool openSerialPort()
198198
{
199199
int fd = 0;
200200

@@ -221,7 +221,7 @@ class SerialPort
221221
return fd > 0;
222222
}
223223

224-
void closeSerialPort()
224+
virtual void closeSerialPort()
225225
{
226226
if (port_fd_ > 0) {
227227
tcsetattr(port_fd_, TCSANOW, &old_settings_);
@@ -230,7 +230,7 @@ class SerialPort
230230
}
231231
}
232232

233-
int readFromDevice(unsigned char * buf, unsigned int buf_len)
233+
virtual int readFromDevice(unsigned char * buf, unsigned int buf_len)
234234
{
235235
if (port_fd_ < 0) {
236236
return -1;
@@ -239,7 +239,7 @@ class SerialPort
239239
return read(port_fd_, buf, buf_len);
240240
}
241241

242-
int writeToDevice(unsigned char * data, unsigned int data_len)
242+
virtual int writeToDevice(unsigned char * data, unsigned int data_len)
243243
{
244244
if (port_fd_ < 0) {
245245
return -1;

include/rt_usb_9axisimu_driver/rt_usb_9axisimu_driver.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,10 @@
4444
#include "sensor_msgs/msg/magnetic_field.hpp"
4545
#include "std_msgs/msg/float64.hpp"
4646

47-
class RtUsb9axisimuRosDriver : public rt_usb_9axisimu::SerialPort
47+
class RtUsb9axisimuRosDriver
4848
{
4949
private:
50-
// ros::NodeHandle nh_;
51-
52-
// ros::Publisher imu_data_raw_pub_;
53-
// ros::Publisher imu_mag_pub_;
54-
// ros::Publisher imu_temperature_pub_;
50+
std::unique_ptr<rt_usb_9axisimu::SerialPort> serial_port_;
5551

5652
rt_usb_9axisimu::SensorData sensor_data_;
5753

@@ -85,6 +81,7 @@ class RtUsb9axisimuRosDriver : public rt_usb_9axisimu::SerialPort
8581

8682
public:
8783
explicit RtUsb9axisimuRosDriver(std::string serialport);
84+
RtUsb9axisimuRosDriver(std::unique_ptr<rt_usb_9axisimu::SerialPort> serial_port);
8885
~RtUsb9axisimuRosDriver();
8986

9087
void setImuFrameIdName(std::string frame_id);

src/rt_usb_9axisimu_driver.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ bool RtUsb9axisimuRosDriver::readBinaryData(void)
9999
unsigned char read_data_buf[256];
100100

101101
has_refreshed_imu_data_ = false;
102-
int read_data_size = readFromDevice(read_data_buf,
102+
int read_data_size = serial_port_->readFromDevice(read_data_buf,
103103
consts.IMU_BIN_DATA_SIZE - imu_binary_data_buffer.size());
104104

105105
if(read_data_size == 0){ // The device was unplugged.
@@ -158,7 +158,7 @@ bool RtUsb9axisimuRosDriver::readAsciiData(void)
158158
has_refreshed_imu_data_ = false;
159159
imu_data_oneline_buf.clear();
160160

161-
int data_size_of_buf = readFromDevice(imu_data_buf, sizeof(imu_data_buf));
161+
int data_size_of_buf = serial_port_->readFromDevice(imu_data_buf, sizeof(imu_data_buf));
162162

163163
if (data_size_of_buf <= 0) {
164164
return false; // Raise communication error
@@ -205,8 +205,16 @@ bool RtUsb9axisimuRosDriver::readAsciiData(void)
205205
}
206206

207207
RtUsb9axisimuRosDriver::RtUsb9axisimuRosDriver(std::string port = "")
208-
: rt_usb_9axisimu::SerialPort(port.c_str())
209208
{
209+
serial_port_ = std::make_unique<rt_usb_9axisimu::SerialPort>(port.c_str());
210+
has_completed_format_check_ = false;
211+
data_format_ = DataFormat::NONE;
212+
has_refreshed_imu_data_ = false;
213+
}
214+
215+
RtUsb9axisimuRosDriver::RtUsb9axisimuRosDriver(std::unique_ptr<rt_usb_9axisimu::SerialPort> serial_port)
216+
{
217+
serial_port_ = std::move(serial_port);
210218
has_completed_format_check_ = false;
211219
data_format_ = DataFormat::NONE;
212220
has_refreshed_imu_data_ = false;
@@ -223,7 +231,7 @@ void RtUsb9axisimuRosDriver::setImuFrameIdName(std::string frame_id)
223231

224232
void RtUsb9axisimuRosDriver::setImuPortName(std::string port)
225233
{
226-
setPort(port.c_str());
234+
serial_port_->setPort(port.c_str());
227235
}
228236

229237
void RtUsb9axisimuRosDriver::setImuStdDev(
@@ -238,12 +246,12 @@ void RtUsb9axisimuRosDriver::setImuStdDev(
238246
bool RtUsb9axisimuRosDriver::startCommunication()
239247
{
240248
// returns serial port open status
241-
return openSerialPort();
249+
return serial_port_->openSerialPort();
242250
}
243251

244252
void RtUsb9axisimuRosDriver::stopCommunication(void)
245253
{
246-
closeSerialPort();
254+
serial_port_->closeSerialPort();
247255
has_completed_format_check_ = false;
248256
data_format_ = DataFormat::NONE;
249257
has_refreshed_imu_data_ = false;
@@ -253,7 +261,7 @@ void RtUsb9axisimuRosDriver::checkDataFormat(void)
253261
{
254262
if (data_format_ == DataFormat::NONE) {
255263
unsigned char data_buf[256];
256-
int data_size_of_buf = readFromDevice(data_buf, consts.IMU_BIN_DATA_SIZE);
264+
int data_size_of_buf = serial_port_->readFromDevice(data_buf, consts.IMU_BIN_DATA_SIZE);
257265
if (data_size_of_buf == consts.IMU_BIN_DATA_SIZE) {
258266
if (isBinarySensorData(data_buf)) {
259267
data_format_ = DataFormat::BINARY;

test/test_driver.cpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* test_driver.cpp
3+
*
4+
* License: BSD-3-Clause
5+
*
6+
* Copyright (c) 2015-2023 RT Corporation <support@rt-net.jp>
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright
15+
* notice, this list of conditions and the following disclaimer in the
16+
* documentation and/or other materials provided with the distribution.
17+
* 3. Neither the name of RT Corporation nor the names of its
18+
* contributors may be used to endorse or promote products derived from
19+
* this software without specific prior written permission.
20+
*
21+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*/
33+
34+
#include <array>
35+
#include <string>
36+
#include <gtest/gtest.h>
37+
#include "fakeit.hpp"
38+
#include "rt_usb_9axisimu_driver/rt_usb_9axisimu_driver.hpp"
39+
#include "rt_usb_9axisimu_driver/rt_usb_9axisimu.hpp"
40+
41+
using fakeit::Mock;
42+
using fakeit::When;
43+
using rt_usb_9axisimu::SerialPort;
44+
45+
Mock<SerialPort> create_serial_port_mock(void) {
46+
Mock<SerialPort> mock;
47+
When(Method(mock, setPort)).AlwaysReturn();
48+
When(Method(mock, openPort)).AlwaysReturn(true);
49+
When(Method(mock, openSerialPort)).AlwaysReturn(true);
50+
When(Method(mock, closeSerialPort)).AlwaysReturn();
51+
When(Method(mock, readFromDevice)).AlwaysReturn(0);
52+
When(Method(mock, writeToDevice)).AlwaysReturn(0);
53+
return mock;
54+
}
55+
56+
TEST(TestDriver, startCommunication)
57+
{
58+
// Expect the startCommunication method to be called twice and return true then false
59+
auto mock = create_serial_port_mock();
60+
When(Method(mock, openSerialPort)).Return(true, false); // Return true then false
61+
62+
RtUsb9axisimuRosDriver driver(
63+
std::unique_ptr<SerialPort>(&mock.get()));
64+
65+
EXPECT_TRUE(driver.startCommunication());
66+
EXPECT_FALSE(driver.startCommunication());
67+
}
68+
69+
TEST(TestDriver, initialize_member_variables)
70+
{
71+
// Expect member variables of the driver instance to be initialised
72+
auto mock = create_serial_port_mock();
73+
74+
RtUsb9axisimuRosDriver driver(
75+
std::unique_ptr<SerialPort>(&mock.get()));
76+
77+
EXPECT_FALSE(driver.hasCompletedFormatCheck());
78+
EXPECT_FALSE(driver.hasBinaryDataFormat());
79+
EXPECT_FALSE(driver.hasAsciiDataFormat());
80+
EXPECT_FALSE(driver.hasRefreshedImuData());
81+
}
82+
83+
TEST(TestDriver, checkDataFormat_Binary)
84+
{
85+
// Expect to check correctly when read data in binary format
86+
auto mock = create_serial_port_mock();
87+
88+
When(Method(mock, readFromDevice)).Do([](
89+
unsigned char* buf, unsigned int buf_size) {
90+
rt_usb_9axisimu::Consts consts;
91+
unsigned char dummy_bin_imu_data[consts.IMU_BIN_DATA_SIZE] = {0};
92+
dummy_bin_imu_data[consts.IMU_BIN_HEADER_R] = 0x52; // R
93+
dummy_bin_imu_data[consts.IMU_BIN_HEADER_T] = 0x54; // T
94+
for(int i = 0; i < consts.IMU_BIN_DATA_SIZE; i++) {
95+
buf[i] = dummy_bin_imu_data[i];
96+
}
97+
buf_size = consts.IMU_BIN_DATA_SIZE;
98+
return buf_size;
99+
});
100+
101+
RtUsb9axisimuRosDriver driver(
102+
std::unique_ptr<SerialPort>(&mock.get()));
103+
104+
driver.checkDataFormat();
105+
106+
EXPECT_TRUE(driver.hasCompletedFormatCheck());
107+
EXPECT_TRUE(driver.hasBinaryDataFormat());
108+
EXPECT_FALSE(driver.hasAsciiDataFormat());
109+
}
110+
111+
TEST(TestDriver, checkDataFormat_ASCII)
112+
{
113+
// Expect to check correctly when read data in ASCII format
114+
auto mock = create_serial_port_mock();
115+
116+
When(Method(mock, readFromDevice)).Do([](
117+
unsigned char* buf, unsigned int buf_size) {
118+
rt_usb_9axisimu::Consts consts;
119+
std::array<std::string, consts.IMU_ASCII_DATA_SIZE> dummy_ascii_imu_data;
120+
dummy_ascii_imu_data[consts.IMU_ASCII_TIMESTAMP] = "0";
121+
dummy_ascii_imu_data[consts.IMU_ASCII_GYRO_X] = "0.000000";
122+
dummy_ascii_imu_data[consts.IMU_ASCII_GYRO_Y] = "0.000000";
123+
dummy_ascii_imu_data[consts.IMU_ASCII_GYRO_Z] = "0.000000";
124+
dummy_ascii_imu_data[consts.IMU_ASCII_ACC_X] = "0.000000";
125+
dummy_ascii_imu_data[consts.IMU_ASCII_ACC_Y] = "0.000000";
126+
dummy_ascii_imu_data[consts.IMU_ASCII_ACC_Z] = "0.000000";
127+
dummy_ascii_imu_data[consts.IMU_ASCII_MAG_X] = "0.000000";
128+
dummy_ascii_imu_data[consts.IMU_ASCII_MAG_Y] = "0.000000";
129+
dummy_ascii_imu_data[consts.IMU_ASCII_MAG_Z] = "0.000000";
130+
dummy_ascii_imu_data[consts.IMU_ASCII_TEMP] = "0.000000";
131+
std::string str = "";
132+
std::string split_char = ",";
133+
for(int i = 0; i < consts.IMU_ASCII_DATA_SIZE; i++) {
134+
str += dummy_ascii_imu_data[i];
135+
if(i != consts.IMU_ASCII_DATA_SIZE - 1) str += split_char;
136+
}
137+
for(int i = 0; i < int(str.length()); i++) {
138+
buf[i] = str[i];
139+
}
140+
buf_size = consts.IMU_BIN_DATA_SIZE;
141+
return buf_size;
142+
});
143+
144+
RtUsb9axisimuRosDriver driver(
145+
std::unique_ptr<SerialPort>(&mock.get()));
146+
147+
driver.checkDataFormat();
148+
driver.checkDataFormat();
149+
150+
EXPECT_TRUE(driver.hasCompletedFormatCheck());
151+
EXPECT_TRUE(driver.hasAsciiDataFormat());
152+
EXPECT_FALSE(driver.hasBinaryDataFormat());
153+
}
154+
155+
TEST(TestDriver, checkDataFormat_not_Binary_or_ASCII)
156+
{
157+
// Expect to check correctly when read data in not Binary or ASCII format
158+
auto mock = create_serial_port_mock();
159+
160+
When(Method(mock, readFromDevice)).Do([](
161+
unsigned char* buf, unsigned int buf_size) {
162+
rt_usb_9axisimu::Consts consts;
163+
unsigned char dummy_data_not_binary_or_ascii[] =
164+
"dummy_data_not_binary_or_ascii";
165+
for(int i = 0; i < int(sizeof(dummy_data_not_binary_or_ascii)); i++) {
166+
buf[i] = dummy_data_not_binary_or_ascii[i];
167+
}
168+
buf_size = consts.IMU_BIN_DATA_SIZE;
169+
return buf_size;
170+
});
171+
172+
RtUsb9axisimuRosDriver driver(
173+
std::unique_ptr<SerialPort>(&mock.get()));
174+
175+
driver.checkDataFormat();
176+
177+
EXPECT_FALSE(driver.hasCompletedFormatCheck());
178+
EXPECT_FALSE(driver.hasBinaryDataFormat());
179+
EXPECT_FALSE(driver.hasAsciiDataFormat());
180+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy