integrationtest_ros_scanner_node.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2020 Pilz GmbH & Co. KG
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with this program. If not, see <https://www.gnu.org/licenses/>.
15 
16 #include <gtest/gtest.h>
24 #include "psen_scan/mock_scanner.h"
25 #include <boost/thread.hpp>
26 
27 using namespace psen_scan;
28 using ::testing::DoAll;
29 using ::testing::Return;
30 using ::testing::Throw;
31 
32 namespace psen_scan_test
33 {
34 class ros_scanner_node_test : public ::testing::Test
35 {
36 protected:
37  void SetUp() override
38  {
39  node1_Scanner_test = std::unique_ptr<MockScanner>(new MockScanner());
41  laser_scan_fake->measures_.push_back(1);
43  laser_scan_error_1->measures_.push_back(1);
44  laser_scan_error_1->measures_.push_back(2);
46  laser_scan_error_2->measures_.push_back(1);
47  laser_scan_error_3 = new LaserScan(PSENscanInternalAngle(10), PSENscanInternalAngle(2), PSENscanInternalAngle(1));
48  laser_scan_error_3->measures_.push_back(1);
49  }
50 
51  void TearDown() override
52  {
53  delete laser_scan_fake;
54  delete laser_scan_error_1;
55  delete laser_scan_error_2;
56  delete laser_scan_error_3;
57  }
58 
60  std::unique_ptr<MockScanner> node1_Scanner_test;
65 };
66 
67 ACTION(ROS_SHUTDOWN)
68 {
69  sleep(1);
70  ros::shutdown();
71 }
72 
74 {
75 public:
76  TestSubscriber(const ros::NodeHandle& nh, const std::string& topic) : receivedMessage_(0), ready_(false), nh_(nh)
77  {
78  sub_ = nh_.subscribe(topic,
79  1000,
80  &TestSubscriber::callback,
81  this,
82  ros::TransportHints().reliable().tcp().tcpNoDelay().udp().unreliable());
83  }
84 
85  void spin()
86  {
87  while (sub_.getNumPublishers() < 1)
88  {
89  ros::spinOnce();
90  }
91  ready_ = true;
92  ros::spin();
93  }
94 
95  void callback(const sensor_msgs::LaserScan::ConstPtr& newMessage)
96  {
97  receivedMessage_++;
98  message_ = *newMessage;
99  }
100 
102  bool ready_;
106 };
107 
108 TEST_F(ros_scanner_node_test, processingLoop_skip_eq_zero)
109 {
110  EXPECT_CALL(*(node1_Scanner_test), start()).Times(1);
111 
112  EXPECT_CALL(*(node1_Scanner_test), stop()).Times(1);
113 
114  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
115  .Times(1)
116  .WillOnce(DoAll(ROS_SHUTDOWN(), Return(*laser_scan_fake)));
117 
118  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
119  .Times(504)
120  .WillRepeatedly(Return(*laser_scan_fake))
121  .RetiresOnSaturation();
122 
123  ROSScannerNode ros_scanner_node(node1_nh_test,
124  "node1_topic",
125  "node1_frame",
126  0, // every frame
127  Degree(137.5),
128  std::move(node1_Scanner_test));
129 
130  TestSubscriber test_sub(node1_nh_test, "node1_topic");
132  spinner.start();
133 
134  ros_scanner_node.processingLoop();
135 
136  spinner.stop();
137 
138  EXPECT_EQ(504, test_sub.receivedMessage_);
139 }
140 
141 TEST_F(ros_scanner_node_test, processingLoop_skip_eq_one)
142 {
143  ros::start();
144  EXPECT_CALL(*(node1_Scanner_test), start()).Times(1);
145 
146  EXPECT_CALL(*(node1_Scanner_test), stop()).Times(1);
147 
148  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
149  .Times(1)
150  .WillOnce(DoAll(ROS_SHUTDOWN(), Return(*laser_scan_fake)));
151 
152  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
153  .Times(504)
154  .WillRepeatedly(Return(*laser_scan_fake))
155  .RetiresOnSaturation();
156 
157  ROSScannerNode ros_scanner_node(node1_nh_test,
158  "node1_topic",
159  "node1_frame",
160  1, // every other frame
161  Degree(137.5),
162  std::move(node1_Scanner_test));
163 
164  TestSubscriber test_sub(node1_nh_test, "node1_topic");
166  spinner.start();
167 
168  ros_scanner_node.processingLoop();
169  spinner.stop();
170 
171  EXPECT_EQ(252, test_sub.receivedMessage_);
172 }
173 
174 TEST_F(ros_scanner_node_test, processingLoop_skip_eq_99)
175 {
176  ros::start();
177  EXPECT_CALL(*(node1_Scanner_test), start()).Times(1);
178 
179  EXPECT_CALL(*(node1_Scanner_test), stop()).Times(1);
180 
181  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
182  .Times(1)
183  .WillOnce(DoAll(ROS_SHUTDOWN(), Return(*laser_scan_fake)));
184 
185  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
186  .Times(504)
187  .WillRepeatedly(Return(*laser_scan_fake))
188  .RetiresOnSaturation();
189 
190  ROSScannerNode ros_scanner_node(node1_nh_test,
191  "node1_topic",
192  "node1_frame",
193  99, // every hundredth frame
194  Degree(137.5),
195  std::move(node1_Scanner_test));
196 
197  TestSubscriber test_sub(node1_nh_test, "node1_topic");
199  spinner.start();
200 
201  ros_scanner_node.processingLoop();
202  spinner.stop();
203 
204  EXPECT_EQ(5, test_sub.receivedMessage_);
205 }
206 
207 TEST_F(ros_scanner_node_test, processingLoop_exception_catching)
208 {
209  ros::start();
210  EXPECT_CALL(*(node1_Scanner_test), start()).Times(1);
211 
212  EXPECT_CALL(*(node1_Scanner_test), getCompleteScan())
213  .Times(5)
214  .WillOnce(Throw(CoherentMonitoringFramesException("")))
215  .WillOnce(Throw(ParseMonitoringFrameException("")))
216  .WillOnce(Throw(DiagnosticInformationException("")))
217  .WillOnce(Throw(BuildROSMessageException("")))
218  .WillOnce(Throw(FetchMonitoringFrameException("")));
219 
220  ROSScannerNode ros_scanner_node(
221  node1_nh_test, "node1_topic", "node1_frame", 0, Degree(137.5), std::move(node1_Scanner_test));
222 
223  TestSubscriber test_sub(node1_nh_test, "node1_topic");
225  spinner.start();
226 
227  ASSERT_THROW(ros_scanner_node.processingLoop(), FetchMonitoringFrameException);
228  spinner.stop();
229 
230  EXPECT_EQ(0, test_sub.receivedMessage_);
231 }
232 
233 TEST_F(ros_scanner_node_test, buildROSMessage)
234 {
235  ROSScannerNode ros_scanner_node(
236  node1_nh_test, "node1_topic", "node1_frame", 0, Degree(137.5), std::move(node1_Scanner_test));
237 
238  ros_scanner_node.buildRosMessage(*laser_scan_fake);
239  EXPECT_THROW(ros_scanner_node.buildRosMessage(*laser_scan_error_1), BuildROSMessageException);
240  EXPECT_THROW(ros_scanner_node.buildRosMessage(*laser_scan_error_2), BuildROSMessageException);
241  EXPECT_THROW(ros_scanner_node.buildRosMessage(*laser_scan_error_3), BuildROSMessageException);
242 }
243 
245 {
246  EXPECT_THROW(new ROSScannerNode(node1_nh_test,
247  "node1_topic",
248  "node1_frame",
249  0,
250  Degree(137.5),
251  nullptr // This throws exception
252  ),
254 }
255 } // namespace psen_scan_test
256 
257 int main(int argc, char** argv)
258 {
259  ros::init(argc, argv, "integrationtest_ros_scanner_node");
260  ros::NodeHandle nh; // keep one nh to avoid
261  testing::InitGoogleTest(&argc, argv);
262 
263  int ret = RUN_ALL_TESTS();
264  ros::shutdown();
265  return ret;
266 }
int main(int argc, char **argv)
ROSCPP_DECL void start()
Class implements a ROS-Node for the PSENscan safety laser scanner.
Class to model angles in degrees from user&#39;s perspective.
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Class to hold the data for one laserscan without depencies to ROS.
Definition: laserscan.h:29
struct psen_scan::LaserScan LaserScan
Class to hold the data for one laserscan without depencies to ROS.
void spinner()
TEST_F(ros_scanner_node_test, constructor)
ROSCPP_DECL void spin()
sensor_msgs::LaserScan buildRosMessage(const LaserScan &laserscan)
Creates a ROS message from an LaserScan, which contains one scanning round.
TestSubscriber(const ros::NodeHandle &nh, const std::string &topic)
void callback(const sensor_msgs::LaserScan::ConstPtr &newMessage)
ROSCPP_DECL void shutdown()
Class to model angles in PSENscan internal format (tenth of degrees)
void processingLoop()
endless loop for processing incoming UDP data from the laser scanner
ROSCPP_DECL void spinOnce()


psen_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:16:20