00001
00026 #include <sys/socket.h>
00027 #include <netinet/in.h>
00028 #include <netinet/tcp.h>
00029 #include <gtest/gtest.h>
00030
00031 #include <ros/ros.h>
00032 #include "nmea_msgs/Sentence.h"
00033
00034
00035 int g_argc;
00036 char** g_argv;
00037
00038 class NMEASocketTest : public testing::Test
00039 {
00040 public:
00041 ros::NodeHandle* n;
00042 ros::Publisher tx;
00043 ros::Subscriber rx;
00044 const char *mock_sentence;
00045 boost::shared_ptr<nmea_msgs::Sentence const> last_received;
00046 int total_received;
00047
00048 NMEASocketTest() : mock_sentence("$JUST,a,test*00"), total_received(0)
00049 {
00050 ros::init(g_argc, g_argv, "test_socket_node");
00051 n = new ros::NodeHandle();
00052 tx = n->advertise<nmea_msgs::Sentence>("nmea_sentence_out", 5);
00053 rx = n->subscribe("nmea_sentence", 1, &NMEASocketTest::_rx_callback, this);
00054 }
00055
00056 void connect(int* sockfd)
00057 {
00058 *sockfd = socket(AF_INET, SOCK_STREAM, 0);
00059
00060 struct sockaddr_in serv_addr;
00061 memset(&serv_addr, '0', sizeof(serv_addr));
00062 serv_addr.sin_addr.s_addr = 0x0100007F;
00063 serv_addr.sin_family = AF_INET;
00064 serv_addr.sin_port = htons(29500);
00065
00066 ASSERT_EQ(0, ::connect(*sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)));
00067 }
00068
00069 void disconnect(int* sockfd)
00070 {
00071 close(*sockfd);
00072 }
00073
00074 ~NMEASocketTest()
00075 {
00076 delete n;
00077 }
00078
00079 void _rx_callback(const nmea_msgs::SentenceConstPtr& msg) {
00080 ROS_INFO_STREAM("Received: [" << msg->sentence << "]");
00081 total_received++;
00082 last_received = msg;
00083 }
00084 };
00085
00086
00087 TEST_F(NMEASocketTest, basic_rx_test)
00088 {
00089 int dev;
00090 connect(&dev);
00091
00092
00093 ros::Duration(1.0).sleep();
00094
00095 char buffer[40];
00096 int len = sprintf(buffer, "%s%s", mock_sentence, "\r\n");
00097 EXPECT_EQ(len, write(dev, buffer, len));
00098
00099
00100 ros::Duration(0.1).sleep();
00101 ros::spinOnce();
00102
00103 ASSERT_TRUE(NULL != last_received);
00104 ASSERT_EQ(1, total_received);
00105 ASSERT_STREQ(mock_sentence, last_received->sentence.c_str());
00106 disconnect(&dev);
00107 }
00108
00109
00110 TEST_F(NMEASocketTest, multi_rx_test)
00111 {
00112 const int num_devs = 5;
00113 const int msgs_per_dev = 10;
00114 int devs[num_devs], i;
00115
00116 for (i = 0; i < num_devs; i++) {
00117 connect(&devs[i]);
00118 }
00119
00120
00121 ros::Duration(2.0).sleep();
00122
00123 for (int m = 0; m < msgs_per_dev; m++) {
00124 for (i = 0; i < num_devs; i++) {
00125 char buffer[40];
00126 int len = sprintf(buffer, "$MSG,blah,%d,%d*00%s", i, m, "\r\n");
00127 ROS_INFO("Sending msg #%d on dev #%d: [%s]", m, i, buffer);
00128 EXPECT_EQ(len, write(devs[i], buffer, len));
00129
00130
00131 ros::Duration(0.01).sleep();
00132 ros::spinOnce();
00133 }
00134 }
00135
00136
00137 ros::Duration(0.1).sleep();
00138 ros::spinOnce();
00139
00140 EXPECT_EQ(num_devs * msgs_per_dev, total_received);
00141
00142 for (i = 0; i < num_devs; i++) {
00143 disconnect(&(devs[i]));
00144 }
00145 }
00146
00147
00148 TEST_F(NMEASocketTest, basic_tx_test)
00149 {
00150 int dev;
00151 connect(&dev);
00152
00153
00154 ros::Duration(1.0).sleep();
00155
00156 nmea_msgs::Sentence msg;
00157 msg.sentence = mock_sentence;
00158 tx.publish(msg);
00159
00160
00161 char buffer[40];
00162 ASSERT_EQ(strlen(mock_sentence), read(dev, buffer, strlen(mock_sentence)));
00163
00164 ASSERT_STREQ(mock_sentence, buffer);
00165
00166 disconnect(&dev);
00167 }
00168
00169
00170 int main(int argc, char **argv)
00171 {
00172 testing::InitGoogleTest(&argc, argv);
00173 g_argc = argc;
00174 g_argv = argv;
00175 return RUN_ALL_TESTS();
00176 }