diff --git a/test/SIM_test_varserv/RUN_test/manual_test.py b/test/SIM_test_varserv/RUN_test/manual_test.py index 7e8050a7..982de3ce 100644 --- a/test/SIM_test_varserv/RUN_test/manual_test.py +++ b/test/SIM_test_varserv/RUN_test/manual_test.py @@ -13,7 +13,7 @@ def main(): trick.var_server_create_tcp_socket('localhost', 49000) trick.var_server_create_udp_socket('', 48000) - # trick.var_server_create_multicast_socket('224.10.10.10','', 47000) + trick.var_server_create_multicast_socket('224.10.10.10','', 47000) # trick.exec_set_terminate_time(100000.0) @@ -23,7 +23,7 @@ def main(): # Start the test client after everything has been initialized (hopefully) # trick.add_read(1.0, command) - trick.sim_control_panel_set_enabled(True) + # trick.sim_control_panel_set_enabled(True) if __name__ == "__main__": diff --git a/test/SIM_test_varserv/RUN_test/unit_test.py b/test/SIM_test_varserv/RUN_test/unit_test.py index 1f1231e3..bfdd413a 100644 --- a/test/SIM_test_varserv/RUN_test/unit_test.py +++ b/test/SIM_test_varserv/RUN_test/unit_test.py @@ -13,7 +13,7 @@ def main(): trick.var_server_create_tcp_socket('localhost', 49000) trick.var_server_create_udp_socket('', 48000) - # trick.var_server_create_multicast_socket('224.10.10.10','', 47000) + trick.var_server_create_multicast_socket('224.10.10.10','', 47000) trick.exec_set_terminate_time(1000.0) diff --git a/test/SIM_test_varserv/models/test_client/test_client.cpp b/test/SIM_test_varserv/models/test_client/test_client.cpp index 80de986d..4c714be3 100644 --- a/test/SIM_test_varserv/models/test_client/test_client.cpp +++ b/test/SIM_test_varserv/models/test_client/test_client.cpp @@ -12,7 +12,7 @@ #include #include #include - +#include #include #include "trick/var_binary_parser.hh" @@ -44,14 +44,20 @@ class Socket { return -1; } + int value = 1; + if (setsockopt(_socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &value, (socklen_t) sizeof(value)) < 0) { + std::cout << "init_multicast: Socket option failed" << std::endl; + return -1; + } + + if (setsockopt(_socket_fd, SOL_SOCKET, SO_REUSEPORT, (char *) &value, sizeof(value)) < 0) { + perror("setsockopt: reuseport"); + } + struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); // convert to weird network byte format - - if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) { - std::cout << "Invalid address/ Address not supported" << std::endl; - return -1; - } + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); tries = 0; int connection_status; @@ -75,8 +81,7 @@ class Socket { _port = port; int tries = 0; - while ((_socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 && tries < max_retries) tries++; - + _socket_fd = socket(AF_INET, SOCK_DGRAM, 0); if (_socket_fd < 0) { std::cout << "init_multicast: Socket open failed" << std::endl; return -1; @@ -88,6 +93,10 @@ class Socket { return -1; } + if (setsockopt(_socket_fd, SOL_SOCKET, SO_REUSEPORT, (char *) &value, sizeof(value)) < 0) { + perror("setsockopt: reuseport"); + } + struct ip_mreq mreq; // Use setsockopt() to request that the kernel join a multicast group mreq.imr_multiaddr.s_addr = inet_addr(_hostname.c_str()); @@ -100,9 +109,10 @@ class Socket { struct sockaddr_in sockin ; - // Set up destination address + // Set up local interface + // We must bind to the multicast address sockin.sin_family = AF_INET; - sockin.sin_addr.s_addr = htonl(INADDR_ANY); + sockin.sin_addr.s_addr = inet_addr(_hostname.c_str()); sockin.sin_port = htons(_port); if ( bind(_socket_fd, (struct sockaddr *) &sockin, (socklen_t) sizeof(sockin)) < 0 ) { @@ -110,6 +120,14 @@ class Socket { return -1; } + char loopch = 1; + + if(setsockopt(_socket_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch)) < 0) + { + perror("Setting IP_MULTICAST_LOOP error"); + return -1; + } + _initialized = true; return 0; } @@ -132,6 +150,7 @@ class Socket { std::string receive () { char buffer[SOCKET_BUF_SIZE]; + int numBytes = recv(_socket_fd, buffer, SOCKET_BUF_SIZE, 0); if (numBytes < 0) { } else if (numBytes < SOCKET_BUF_SIZE) { @@ -191,7 +210,6 @@ class Socket { int _socket_fd; bool _initialized; bool _multicast_socket; - }; class VariableServerTest : public ::testing::Test { @@ -267,12 +285,42 @@ class VariableServerTestAltListener : public ::testing::Test { static int numSession; }; +#ifndef __APPLE__ +class VariableServerTestMulticast : public ::testing::Test { + protected: + VariableServerTestMulticast() { + socket_status = socket.init("", 47000, SOCK_DGRAM); + multicast_listener.init_multicast("224.10.10.10", 47000); + + if (socket_status == 0) { + std::stringstream request; + request << "trick.var_set_client_tag(\"multicast_VSTest"; + request << numSession++; + request << "\") \n"; + + socket << request.str(); + } + } + ~VariableServerTestMulticast() { + socket.close(); + multicast_listener.close(); + } + + Socket socket; + Socket multicast_listener; + + int socket_status; + + static int numSession; +}; +int VariableServerTestMulticast::numSession = 0; +#endif + int VariableServerTest::numSession = 0; int VariableServerUDPTest::numSession = 0; int VariableServerTestAltListener::numSession = 0; - /**********************************************************/ /* Helpful constants and functions */ /**********************************************************/ @@ -345,6 +393,97 @@ void load_checkpoint (Socket& socket, const std::string& checkpoint_name) { socket << "trick.var_unpause()\n"; } +/*****************************************/ +/* Multicast Test */ +/*****************************************/ + +#ifndef __APPLE__ + +TEST_F (VariableServerTestMulticast, Strings) { + if (socket_status != 0) { + FAIL(); + } + + std::string reply; + socket << "trick.var_send_once(\"vsx.vst.o\")\n"; + std::string expected("5\tYou will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings. I arrived here yesterday, and my first task is to assure my dear sister of my welfare and increasing confidence in the success of my undertaking."); + + multicast_listener >> reply; + + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0); + + expected = std::string("5\tI am already far north of London, and as I walk in the streets of Petersburgh, I feel a cold northern breeze play upon my cheeks, which braces my nerves and fills me with delight. Do you understand this feeling?"); + socket << "trick.var_send_once(\"vsx.vst.p\")\n"; + + multicast_listener >> reply; + + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0); +} + + +TEST_F (VariableServerTestMulticast, AddRemove) { + if (socket_status != 0) { + FAIL(); + } + + std::string reply; + std::string expected; + + int max_tries = 3; + int tries = 0; + + socket << "trick.var_add(\"vsx.vst.c\")\n"; + multicast_listener >> reply; + expected = std::string("0 -1234"); + + tries = 0; + while (strcmp_IgnoringWhiteSpace(reply, expected) != 0 && tries++ < max_tries) { + multicast_listener >> reply; + } + + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0) << "Expected: " << expected << "\tAcutal: " << reply; + + multicast_listener >> reply; + tries = 0; + while (strcmp_IgnoringWhiteSpace(reply, expected) != 0 && tries++ < max_tries) { + multicast_listener >> reply; + } + + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0) << "Expected: " << expected << "\tAcutal: " << reply; + + socket << "trick.var_add(\"vsx.vst.m\")\n"; + multicast_listener >> reply; + expected = std::string("0 -1234 1"); + tries = 0; + while (strcmp_IgnoringWhiteSpace(reply, expected) != 0 && tries++ < max_tries) { + multicast_listener >> reply; + } + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0) << "Expected: " << expected << "\tAcutal: " << reply; + + socket << "trick.var_remove(\"vsx.vst.m\")\n"; + multicast_listener >> reply; + expected = std::string("0 -1234"); + tries = 0; + while (strcmp_IgnoringWhiteSpace(reply, expected) != 0 && tries++ < max_tries) { + multicast_listener >> reply; + } + + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0) << "Expected: " << expected << "\tAcutal: " << reply; + + socket << "trick.var_add(\"vsx.vst.n\")\n"; + multicast_listener >> reply; + expected = std::string("0 -1234 0,1,2,3,4"); + tries = 0; + while (strcmp_IgnoringWhiteSpace(reply, expected) != 0 && tries++ < max_tries) { + multicast_listener >> reply; + } + EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0) << "Expected: " << expected << "\tAcutal: " << reply; + + socket << "trick.var_exit()\n"; +} + +#endif + /************************************/ /* UDP Tests */ /************************************/ @@ -1527,4 +1666,4 @@ int main(int argc, char **argv) { socket << "trick.stop() \n"; return result; -} \ No newline at end of file +}