test_socket_node.cpp
Go to the documentation of this file.
1 
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <netinet/tcp.h>
29 #include <gtest/gtest.h>
30 
31 #include <ros/ros.h>
32 #include "nmea_msgs/Sentence.h"
33 
34 
35 int g_argc;
36 char** g_argv;
37 
38 class NMEASocketTest : public testing::Test
39 {
40  public:
44  const char *mock_sentence;
47 
48  NMEASocketTest() : mock_sentence("$JUST,a,test*00"), total_received(0)
49  {
50  ros::init(g_argc, g_argv, "test_socket_node");
51  n = new ros::NodeHandle();
52  tx = n->advertise<nmea_msgs::Sentence>("nmea_sentence_out", 5);
53  rx = n->subscribe("nmea_sentence", 1, &NMEASocketTest::_rx_callback, this);
54  }
55 
56  void connect(int* sockfd)
57  {
58  *sockfd = socket(AF_INET, SOCK_STREAM, 0);
59 
60  struct sockaddr_in serv_addr;
61  memset(&serv_addr, '0', sizeof(serv_addr));
62  serv_addr.sin_addr.s_addr = 0x0100007F; // 127.0.0.1
63  serv_addr.sin_family = AF_INET;
64  serv_addr.sin_port = htons(29500);
65 
66  ASSERT_EQ(0, ::connect(*sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)));
67  }
68 
69  void disconnect(int* sockfd)
70  {
71  close(*sockfd);
72  }
73 
75  {
76  delete n;
77  }
78 
79  void _rx_callback(const nmea_msgs::SentenceConstPtr& msg) {
80  ROS_INFO_STREAM("Received: [" << msg->sentence << "]");
81  total_received++;
82  last_received = msg;
83  }
84 };
85 
86 
87 TEST_F(NMEASocketTest, basic_rx_test)
88 {
89  int dev;
90  connect(&dev);
91 
92  // Time for publisher and subscriber to link up.
93  ros::Duration(1.0).sleep();
94 
95  char buffer[40];
96  int len = sprintf(buffer, "%s%s", mock_sentence, "\r\n");
97  EXPECT_EQ(len, write(dev, buffer, len));
98 
99  // Time for message to arrive.
100  ros::Duration(0.1).sleep();
101  ros::spinOnce();
102 
103  ASSERT_TRUE(NULL != last_received);
104  ASSERT_EQ(1, total_received);
105  ASSERT_STREQ(mock_sentence, last_received->sentence.c_str());
106  disconnect(&dev);
107 }
108 
109 
110 TEST_F(NMEASocketTest, multi_rx_test)
111 {
112  const int num_devs = 5;
113  const int msgs_per_dev = 10;
114  int devs[num_devs], i;
115 
116  for (i = 0; i < num_devs; i++) {
117  connect(&devs[i]);
118  }
119 
120  // Time for publishers and subscribers to link up.
121  ros::Duration(2.0).sleep();
122 
123  for (int m = 0; m < msgs_per_dev; m++) {
124  for (i = 0; i < num_devs; i++) {
125  char buffer[40];
126  int len = sprintf(buffer, "$MSG,blah,%d,%d*00%s", i, m, "\r\n");
127  ROS_INFO("Sending msg #%d on dev #%d: [%s]", m, i, buffer);
128  EXPECT_EQ(len, write(devs[i], buffer, len));
129 
130  // TODO: Understand better why this sleep and spin are necessary here; seems like they shouldn't be.
131  ros::Duration(0.01).sleep();
132  ros::spinOnce();
133  }
134  }
135 
136  // Time for final messages to arrive.
137  ros::Duration(0.1).sleep();
138  ros::spinOnce();
139 
140  EXPECT_EQ(num_devs * msgs_per_dev, total_received);
141 
142  for (i = 0; i < num_devs; i++) {
143  disconnect(&(devs[i]));
144  }
145 }
146 
147 
148 TEST_F(NMEASocketTest, basic_tx_test)
149 {
150  int dev;
151  connect(&dev);
152 
153  // Time for publisher and subscriber to link up.
154  ros::Duration(1.0).sleep();
155 
156  nmea_msgs::Sentence msg;
157  msg.sentence = mock_sentence;
158  tx.publish(msg);
159 
160  // If this fails, GoogleTest will kill it after 60s.
161  char buffer[40];
162  ASSERT_EQ(strlen(mock_sentence), read(dev, buffer, strlen(mock_sentence)));
163 
164  ASSERT_STREQ(mock_sentence, buffer);
165 
166  disconnect(&dev);
167 }
168 
169 
170 int main(int argc, char **argv)
171 {
172  testing::InitGoogleTest(&argc, argv);
173  g_argc = argc;
174  g_argv = argv;
175  return RUN_ALL_TESTS();
176 }
int g_argc
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
boost::shared_ptr< nmea_msgs::Sentence const > last_received
const char * mock_sentence
bool sleep() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void _rx_callback(const nmea_msgs::SentenceConstPtr &msg)
void disconnect(int *sockfd)
ros::Publisher tx
TEST_F(NMEASocketTest, basic_rx_test)
ros::NodeHandle * n
#define ROS_INFO(...)
int main(int argc, char **argv)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void connect(int *sockfd)
#define ROS_INFO_STREAM(args)
char ** g_argv
ROSCPP_DECL void spinOnce()
ros::Subscriber rx


nmea_comms
Author(s): Mike Purvis
autogenerated on Mon Aug 5 2019 03:53:18