LCOV - code coverage report
Current view: top level - src/unittest - test_connection.cpp (source / functions) Hit Total Coverage
Test: report Lines: 7 180 3.9 %
Date: 2015-07-11 18:23:49 Functions: 4 13 30.8 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "test.h"
      21             : 
      22             : #include "log.h"
      23             : #include "socket.h"
      24             : #include "settings.h"
      25             : #include "util/serialize.h"
      26             : #include "network/connection.h"
      27             : 
      28           1 : class TestConnection : public TestBase {
      29             : public:
      30           1 :         TestConnection()
      31           1 :         {
      32             :                 if (INTERNET_SIMULATOR == false)
      33           1 :                         TestManager::registerTestModule(this);
      34           1 :         }
      35             : 
      36           0 :         const char *getName() { return "TestConnection"; }
      37             : 
      38             :         void runTests(IGameDef *gamedef);
      39             : 
      40             :         void testHelpers();
      41             :         void testConnectSendReceive();
      42             : };
      43             : 
      44           1 : static TestConnection g_test_instance;
      45             : 
      46           0 : void TestConnection::runTests(IGameDef *gamedef)
      47             : {
      48           0 :         TEST(testHelpers);
      49           0 :         TEST(testConnectSendReceive);
      50           0 : }
      51             : 
      52             : ////////////////////////////////////////////////////////////////////////////////
      53             : 
      54           0 : struct Handler : public con::PeerHandler
      55             : {
      56           0 :         Handler(const char *a_name)
      57           0 :         {
      58           0 :                 count = 0;
      59           0 :                 last_id = 0;
      60           0 :                 name = a_name;
      61           0 :         }
      62             : 
      63           0 :         void peerAdded(con::Peer *peer)
      64             :         {
      65           0 :                 infostream << "Handler(" << name << ")::peerAdded(): "
      66           0 :                         "id=" << peer->id << std::endl;
      67           0 :                 last_id = peer->id;
      68           0 :                 count++;
      69           0 :         }
      70             : 
      71           0 :         void deletingPeer(con::Peer *peer, bool timeout)
      72             :         {
      73           0 :                 infostream << "Handler(" << name << ")::deletingPeer(): "
      74           0 :                         "id=" << peer->id << ", timeout=" << timeout << std::endl;
      75           0 :                 last_id = peer->id;
      76           0 :                 count--;
      77           0 :         }
      78             : 
      79             :         s32 count;
      80             :         u16 last_id;
      81             :         const char *name;
      82             : };
      83             : 
      84           0 : void TestConnection::testHelpers()
      85             : {
      86             :         // Some constants for testing
      87           0 :         u32 proto_id = 0x12345678;
      88           0 :         u16 peer_id = 123;
      89           0 :         u8 channel = 2;
      90           0 :         SharedBuffer<u8> data1(1);
      91           0 :         data1[0] = 100;
      92           0 :         Address a(127,0,0,1, 10);
      93           0 :         const u16 seqnum = 34352;
      94             : 
      95             :         con::BufferedPacket p1 = con::makePacket(a, data1,
      96           0 :                         proto_id, peer_id, channel);
      97             :         /*
      98             :                 We should now have a packet with this data:
      99             :                 Header:
     100             :                         [0] u32 protocol_id
     101             :                         [4] u16 sender_peer_id
     102             :                         [6] u8 channel
     103             :                 Data:
     104             :                         [7] u8 data1[0]
     105             :         */
     106           0 :         UASSERT(readU32(&p1.data[0]) == proto_id);
     107           0 :         UASSERT(readU16(&p1.data[4]) == peer_id);
     108           0 :         UASSERT(readU8(&p1.data[6]) == channel);
     109           0 :         UASSERT(readU8(&p1.data[7]) == data1[0]);
     110             : 
     111             :         //infostream<<"initial data1[0]="<<((u32)data1[0]&0xff)<<std::endl;
     112             : 
     113           0 :         SharedBuffer<u8> p2 = con::makeReliablePacket(data1, seqnum);
     114             : 
     115             :         /*infostream<<"p2.getSize()="<<p2.getSize()<<", data1.getSize()="
     116             :                         <<data1.getSize()<<std::endl;
     117             :         infostream<<"readU8(&p2[3])="<<readU8(&p2[3])
     118             :                         <<" p2[3]="<<((u32)p2[3]&0xff)<<std::endl;
     119             :         infostream<<"data1[0]="<<((u32)data1[0]&0xff)<<std::endl;*/
     120             : 
     121           0 :         UASSERT(p2.getSize() == 3 + data1.getSize());
     122           0 :         UASSERT(readU8(&p2[0]) == TYPE_RELIABLE);
     123           0 :         UASSERT(readU16(&p2[1]) == seqnum);
     124           0 :         UASSERT(readU8(&p2[3]) == data1[0]);
     125           0 : }
     126             : 
     127             : 
     128           0 : void TestConnection::testConnectSendReceive()
     129             : {
     130           0 :         DSTACK("TestConnection::Run");
     131             : 
     132             :         /*
     133             :                 Test some real connections
     134             : 
     135             :                 NOTE: This mostly tests the legacy interface.
     136             :         */
     137             : 
     138           0 :         u32 proto_id = 0xad26846a;
     139             : 
     140           0 :         Handler hand_server("server");
     141           0 :         Handler hand_client("client");
     142             : 
     143           0 :         Address address(0, 0, 0, 0, 30001);
     144           0 :         Address bind_addr(0, 0, 0, 0, 30001);
     145             :         /*
     146             :          * Try to use the bind_address for servers with no localhost address
     147             :          * For example: FreeBSD jails
     148             :          */
     149           0 :         std::string bind_str = g_settings->get("bind_address");
     150             :         try {
     151           0 :                 bind_addr.Resolve(bind_str.c_str());
     152             : 
     153           0 :                 if (!bind_addr.isIPv6()) {
     154           0 :                         address = bind_addr;
     155             :                 }
     156           0 :         } catch (ResolveError &e) {
     157             :         }
     158             : 
     159           0 :         infostream << "** Creating server Connection" << std::endl;
     160           0 :         con::Connection server(proto_id, 512, 5.0, false, &hand_server);
     161           0 :         server.Serve(address);
     162             : 
     163           0 :         infostream << "** Creating client Connection" << std::endl;
     164           0 :         con::Connection client(proto_id, 512, 5.0, false, &hand_client);
     165             : 
     166           0 :         UASSERT(hand_server.count == 0);
     167           0 :         UASSERT(hand_client.count == 0);
     168             : 
     169           0 :         sleep_ms(50);
     170             : 
     171           0 :         Address server_address(127, 0, 0, 1, 30001);
     172           0 :         if (address != Address(0, 0, 0, 0, 30001)) {
     173           0 :                 server_address = bind_addr;
     174             :         }
     175             : 
     176           0 :         infostream << "** running client.Connect()" << std::endl;
     177           0 :         client.Connect(server_address);
     178             : 
     179           0 :         sleep_ms(50);
     180             : 
     181             :         // Client should not have added client yet
     182           0 :         UASSERT(hand_client.count == 0);
     183             : 
     184             :         try {
     185           0 :                 NetworkPacket pkt;
     186           0 :                 infostream << "** running client.Receive()" << std::endl;
     187           0 :                 client.Receive(&pkt);
     188           0 :                 infostream << "** Client received: peer_id=" << pkt.getPeerId()
     189           0 :                         << ", size=" << pkt.getSize() << std::endl;
     190           0 :         } catch (con::NoIncomingDataException &e) {
     191             :         }
     192             : 
     193             :         // Client should have added server now
     194           0 :         UASSERT(hand_client.count == 1);
     195           0 :         UASSERT(hand_client.last_id == 1);
     196             :         // Server should not have added client yet
     197           0 :         UASSERT(hand_server.count == 0);
     198             : 
     199           0 :         sleep_ms(100);
     200             : 
     201             :         try {
     202           0 :                 NetworkPacket pkt;
     203           0 :                 infostream << "** running server.Receive()" << std::endl;
     204           0 :                 server.Receive(&pkt);
     205           0 :                 infostream << "** Server received: peer_id=" << pkt.getPeerId()
     206           0 :                                 << ", size=" << pkt.getSize()
     207           0 :                                 << std::endl;
     208           0 :         } catch (con::NoIncomingDataException &e) {
     209             :                 // No actual data received, but the client has
     210             :                 // probably been connected
     211             :         }
     212             : 
     213             :         // Client should be the same
     214           0 :         UASSERT(hand_client.count == 1);
     215           0 :         UASSERT(hand_client.last_id == 1);
     216             :         // Server should have the client
     217           0 :         UASSERT(hand_server.count == 1);
     218           0 :         UASSERT(hand_server.last_id == 2);
     219             : 
     220             :         //sleep_ms(50);
     221             : 
     222           0 :         while (client.Connected() == false) {
     223             :                 try {
     224           0 :                         NetworkPacket pkt;
     225           0 :                         infostream << "** running client.Receive()" << std::endl;
     226           0 :                         client.Receive(&pkt);
     227           0 :                         infostream << "** Client received: peer_id=" << pkt.getPeerId()
     228           0 :                                 << ", size=" << pkt.getSize() << std::endl;
     229           0 :                 } catch (con::NoIncomingDataException &e) {
     230             :                 }
     231           0 :                 sleep_ms(50);
     232             :         }
     233             : 
     234           0 :         sleep_ms(50);
     235             : 
     236             :         try {
     237           0 :                 NetworkPacket pkt;
     238           0 :                 infostream << "** running server.Receive()" << std::endl;
     239           0 :                 server.Receive(&pkt);
     240           0 :                 infostream << "** Server received: peer_id=" << pkt.getPeerId()
     241           0 :                                 << ", size=" << pkt.getSize()
     242           0 :                                 << std::endl;
     243           0 :         } catch (con::NoIncomingDataException &e) {
     244             :         }
     245             : 
     246             :         /*
     247             :                 Simple send-receive test
     248             :         */
     249             :         {
     250           0 :                 NetworkPacket pkt;
     251           0 :                 pkt.putRawPacket((u8*) "Hello World !", 14, 0);
     252             : 
     253           0 :                 Buffer<u8> sentdata = pkt.oldForgePacket();
     254             : 
     255           0 :                 infostream<<"** running client.Send()"<<std::endl;
     256           0 :                 client.Send(PEER_ID_SERVER, 0, &pkt, true);
     257             : 
     258           0 :                 sleep_ms(50);
     259             : 
     260           0 :                 NetworkPacket recvpacket;
     261           0 :                 infostream << "** running server.Receive()" << std::endl;
     262           0 :                 server.Receive(&recvpacket);
     263           0 :                 infostream << "** Server received: peer_id=" << pkt.getPeerId()
     264           0 :                                 << ", size=" << pkt.getSize()
     265           0 :                                 << ", data=" << (const char*)pkt.getU8Ptr(0)
     266           0 :                                 << std::endl;
     267             : 
     268           0 :                 Buffer<u8> recvdata = pkt.oldForgePacket();
     269             : 
     270           0 :                 UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0);
     271             :         }
     272             : 
     273           0 :         u16 peer_id_client = 2;
     274             :         /*
     275             :                 Send a large packet
     276             :         */
     277             :         {
     278           0 :                 const int datasize = 30000;
     279           0 :                 NetworkPacket pkt(0, datasize);
     280           0 :                 for (u16 i=0; i<datasize; i++) {
     281           0 :                         pkt << (u8) i/4;
     282             :                 }
     283             : 
     284           0 :                 infostream << "Sending data (size=" << datasize << "):";
     285           0 :                 for (int i = 0; i < datasize && i < 20; i++) {
     286           0 :                         if (i % 2 == 0)
     287           0 :                                 infostream << " ";
     288             :                         char buf[10];
     289           0 :                         snprintf(buf, 10, "%.2X",
     290           0 :                                 ((int)((const char *)pkt.getU8Ptr(0))[i]) & 0xff);
     291           0 :                         infostream<<buf;
     292             :                 }
     293             :                 if (datasize > 20)
     294           0 :                         infostream << "...";
     295           0 :                 infostream << std::endl;
     296             : 
     297           0 :                 Buffer<u8> sentdata = pkt.oldForgePacket();
     298             : 
     299           0 :                 server.Send(peer_id_client, 0, &pkt, true);
     300             : 
     301             :                 //sleep_ms(3000);
     302             : 
     303           0 :                 Buffer<u8> recvdata;
     304           0 :                 infostream << "** running client.Receive()" << std::endl;
     305           0 :                 u16 peer_id = 132;
     306           0 :                 u16 size = 0;
     307           0 :                 bool received = false;
     308           0 :                 u32 timems0 = porting::getTimeMs();
     309           0 :                 for (;;) {
     310           0 :                         if (porting::getTimeMs() - timems0 > 5000 || received)
     311           0 :                                 break;
     312             :                         try {
     313           0 :                                 NetworkPacket pkt;
     314           0 :                                 client.Receive(&pkt);
     315           0 :                                 size = pkt.getSize();
     316           0 :                                 peer_id = pkt.getPeerId();
     317           0 :                                 recvdata = pkt.oldForgePacket();
     318           0 :                                 received = true;
     319           0 :                         } catch (con::NoIncomingDataException &e) {
     320             :                         }
     321           0 :                         sleep_ms(10);
     322             :                 }
     323           0 :                 UASSERT(received);
     324           0 :                 infostream << "** Client received: peer_id=" << peer_id
     325           0 :                         << ", size=" << size << std::endl;
     326             : 
     327           0 :                 infostream << "Received data (size=" << size << "): ";
     328           0 :                 for (int i = 0; i < size && i < 20; i++) {
     329           0 :                         if (i % 2 == 0)
     330           0 :                                 infostream << " ";
     331             :                         char buf[10];
     332           0 :                         snprintf(buf, 10, "%.2X", ((int)(recvdata[i])) & 0xff);
     333           0 :                         infostream << buf;
     334             :                 }
     335           0 :                 if (size > 20)
     336           0 :                         infostream << "...";
     337           0 :                 infostream << std::endl;
     338             : 
     339           0 :                 UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0);
     340           0 :                 UASSERT(peer_id == PEER_ID_SERVER);
     341             :         }
     342             : 
     343             :         // Check peer handlers
     344           0 :         UASSERT(hand_client.count == 1);
     345           0 :         UASSERT(hand_client.last_id == 1);
     346           0 :         UASSERT(hand_server.count == 1);
     347           0 :         UASSERT(hand_server.last_id == 2);
     348           3 : }

Generated by: LCOV version 1.11