DroppedConnectionConvertTest.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "DroppedConnectionConvertTest.h"
  11. /*
  12. Description:
  13. Tests silently dropping multiple instances of RakNet. This is used to test that lost connections are detected properly.
  14. Randomly tests the timout detections to see if the connections are dropped.
  15. Success conditions:
  16. Clients connect and reconnect normally and do not have an extra connection.
  17. Random timout detection passes.
  18. Failure conditions:
  19. Client has more than one connection.
  20. Client unable to reconnect.
  21. Connect function fails and there is no pending operation and there is no current connection with server.
  22. Random timout detection fails.
  23. */
  24. static const int NUMBER_OF_CLIENTS=9;
  25. int DroppedConnectionConvertTest::RunTest(DataStructures::List<RakString> params,bool isVerbose,bool noPauses)
  26. {
  27. RakPeerInterface *server;
  28. RakPeerInterface *clients[NUMBER_OF_CLIENTS];
  29. unsigned index, connectionCount;
  30. SystemAddress serverID;
  31. Packet *p;
  32. unsigned short numberOfSystems;
  33. unsigned short numberOfSystems2;
  34. int sender;
  35. // Buffer for input (an ugly hack to keep *nix happy)
  36. // char buff[256];
  37. // Used to refer to systems. We already know the IP
  38. unsigned short serverPort = 20000;
  39. serverID.binaryAddress=inet_addr("127.0.0.1");
  40. serverID.port=serverPort;
  41. server=RakPeerInterface::GetInstance();
  42. destroyList.Clear(false,_FILE_AND_LINE_);
  43. destroyList.Push(server,_FILE_AND_LINE_);
  44. // server->InitializeSecurity(0,0,0,0);
  45. SocketDescriptor socketDescriptor(serverPort,0);
  46. server->Startup(NUMBER_OF_CLIENTS, &socketDescriptor, 1);
  47. server->SetMaximumIncomingConnections(NUMBER_OF_CLIENTS);
  48. server->SetTimeoutTime(2000,UNASSIGNED_SYSTEM_ADDRESS);
  49. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  50. {
  51. clients[index]=RakPeerInterface::GetInstance();
  52. destroyList.Push(clients[index],_FILE_AND_LINE_);
  53. SocketDescriptor socketDescriptor2(serverPort+1+index,0);
  54. clients[index]->Startup(1, &socketDescriptor2, 1);
  55. if (clients[index]->Connect("127.0.0.1", serverPort, 0, 0)!=CONNECTION_ATTEMPT_STARTED)
  56. {
  57. DebugTools::ShowError("Connect function failed.",!noPauses && isVerbose,__LINE__,__FILE__);
  58. return 2;
  59. }
  60. clients[index]->SetTimeoutTime(5000,UNASSIGNED_SYSTEM_ADDRESS);
  61. RakSleep(1000);
  62. if (isVerbose)
  63. printf("%i. ", index);
  64. }
  65. TimeMS entryTime=GetTimeMS();//Loop entry time
  66. int seed = 12345;
  67. if (isVerbose)
  68. printf("Using seed %i\n", seed);
  69. seedMT(seed);//specify seed to keep execution path the same.
  70. int randomTest;
  71. bool dropTest=false;
  72. RakTimer timeoutWaitTimer(1000);
  73. while (GetTimeMS()-entryTime<30000)//run for 30 seconds.
  74. {
  75. // User input
  76. randomTest=randomMT() %4;
  77. if(dropTest)
  78. {
  79. server->GetConnectionList(0, &numberOfSystems);
  80. numberOfSystems2=numberOfSystems;
  81. connectionCount=0;
  82. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  83. {
  84. clients[index]->GetConnectionList(0, &numberOfSystems);
  85. if (numberOfSystems>1)
  86. {
  87. if (isVerbose)
  88. {
  89. printf("Client %i has %i connections\n", index, numberOfSystems);
  90. DebugTools::ShowError("Client has more than one connection",!noPauses && isVerbose,__LINE__,__FILE__);
  91. return 1;
  92. }
  93. }
  94. if (numberOfSystems==1)
  95. {
  96. connectionCount++;
  97. }
  98. }
  99. if (connectionCount!=numberOfSystems2)
  100. {
  101. if (isVerbose)
  102. DebugTools::ShowError("Timeout on dropped clients not detected",!noPauses && isVerbose,__LINE__,__FILE__);
  103. return 3;
  104. }
  105. }
  106. dropTest=false;
  107. switch(randomTest)
  108. {
  109. case 0:
  110. {
  111. index = randomMT() % NUMBER_OF_CLIENTS;
  112. clients[index]->GetConnectionList(0, &numberOfSystems);
  113. clients[index]->CloseConnection(serverID, false,0);
  114. if (numberOfSystems==0)
  115. {
  116. if (isVerbose)
  117. printf("Client %i silently closing inactive connection.\n",index);
  118. }
  119. else
  120. {
  121. if (isVerbose)
  122. printf("Client %i silently closing active connection.\n",index);
  123. }
  124. }
  125. break;
  126. case 1:
  127. {
  128. index = randomMT() % NUMBER_OF_CLIENTS;
  129. clients[index]->GetConnectionList(0, &numberOfSystems);
  130. if(!CommonFunctions::ConnectionStateMatchesOptions (clients[index],serverID,true,true,true,true) )//Are we connected or is there a pending operation ?
  131. {
  132. if (clients[index]->Connect("127.0.0.1", serverPort, 0, 0)!=CONNECTION_ATTEMPT_STARTED)
  133. {
  134. DebugTools::ShowError("Connect function failed.",!noPauses && isVerbose,__LINE__,__FILE__);
  135. return 2;
  136. }
  137. }
  138. if (numberOfSystems==0)
  139. {
  140. if (isVerbose)
  141. printf("Client %i connecting to same existing connection.\n",index);
  142. }
  143. else
  144. {
  145. if (isVerbose)
  146. printf("Client %i connecting to closed connection.\n",index);
  147. }
  148. }
  149. break;
  150. case 2:
  151. {
  152. if (isVerbose)
  153. printf("Randomly connecting and disconnecting each client\n");
  154. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  155. {
  156. if (NUMBER_OF_CLIENTS==1 || (randomMT()%2)==0)
  157. {
  158. if (clients[index]->IsActive())
  159. {
  160. int randomTest2=randomMT() %2;
  161. if (randomTest2)
  162. clients[index]->CloseConnection(serverID, false, 0);
  163. else
  164. clients[index]->CloseConnection(serverID, true, 0);
  165. }
  166. }
  167. else
  168. {
  169. if(!CommonFunctions::ConnectionStateMatchesOptions (clients[index],serverID,true,true,true,true) )//Are we connected or is there a pending operation ?
  170. {
  171. if (clients[index]->Connect("127.0.0.1", serverPort, 0, 0)!=CONNECTION_ATTEMPT_STARTED)
  172. {
  173. DebugTools::ShowError("Connect function failed.",!noPauses && isVerbose,__LINE__,__FILE__);
  174. return 2;
  175. }
  176. }
  177. }
  178. }
  179. }
  180. break;
  181. case 3:
  182. {
  183. if (isVerbose)
  184. printf("Testing if clients dropped after timeout.\n");
  185. timeoutWaitTimer.Start();
  186. //Wait half the timeout time, the other half after receive so we don't drop all connections only missing ones, Active ait so the threads run on linux
  187. while (!timeoutWaitTimer.IsExpired())
  188. {
  189. RakSleep(50);
  190. }
  191. dropTest=true;
  192. }
  193. break;
  194. default:
  195. // Ignore anything else
  196. break;
  197. }
  198. server->GetConnectionList(0, &numberOfSystems);
  199. numberOfSystems2=numberOfSystems;
  200. if (isVerbose)
  201. printf("The server thinks %i clients are connected.\n", numberOfSystems);
  202. connectionCount=0;
  203. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  204. {
  205. clients[index]->GetConnectionList(0, &numberOfSystems);
  206. if (numberOfSystems>1)
  207. {
  208. if (isVerbose)
  209. {
  210. printf("Client %i has %i connections\n", index, numberOfSystems);
  211. DebugTools::ShowError("Client has more than one connection",!noPauses && isVerbose,__LINE__,__FILE__);
  212. return 1;
  213. }
  214. }
  215. if (numberOfSystems==1)
  216. {
  217. connectionCount++;
  218. }
  219. }
  220. if (isVerbose)
  221. printf("%i clients are actually connected.\n", connectionCount);
  222. if (isVerbose)
  223. printf("server->NumberOfConnections==%i.\n", server->NumberOfConnections());
  224. //}
  225. // Parse messages
  226. while (1)
  227. {
  228. p = server->Receive();
  229. sender=NUMBER_OF_CLIENTS;
  230. if (p==0)
  231. {
  232. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  233. {
  234. p = clients[index]->Receive();
  235. if (p!=0)
  236. {
  237. sender=index;
  238. break;
  239. }
  240. }
  241. }
  242. if (p)
  243. {
  244. switch (p->data[0])
  245. {
  246. case ID_CONNECTION_REQUEST_ACCEPTED:
  247. if (isVerbose)
  248. printf("%i: %ID_CONNECTION_REQUEST_ACCEPTED from %i.\n",sender, p->systemAddress.port);
  249. break;
  250. case ID_DISCONNECTION_NOTIFICATION:
  251. // Connection lost normally
  252. if (isVerbose)
  253. printf("%i: ID_DISCONNECTION_NOTIFICATION from %i.\n",sender, p->systemAddress.port);
  254. break;
  255. case ID_NEW_INCOMING_CONNECTION:
  256. // Somebody connected. We have their IP now
  257. if (isVerbose)
  258. printf("%i: ID_NEW_INCOMING_CONNECTION from %i.\n",sender, p->systemAddress.port);
  259. break;
  260. case ID_CONNECTION_LOST:
  261. // Couldn't deliver a reliable packet - i.e. the other system was abnormally
  262. // terminated
  263. if (isVerbose)
  264. printf("%i: ID_CONNECTION_LOST from %i.\n",sender, p->systemAddress.port);
  265. break;
  266. case ID_NO_FREE_INCOMING_CONNECTIONS:
  267. if (isVerbose)
  268. printf("%i: ID_NO_FREE_INCOMING_CONNECTIONS from %i.\n",sender, p->systemAddress.port);
  269. break;
  270. default:
  271. // Ignore anything else
  272. break;
  273. }
  274. }
  275. else
  276. break;
  277. if (sender==NUMBER_OF_CLIENTS)
  278. server->DeallocatePacket(p);
  279. else
  280. clients[sender]->DeallocatePacket(p);
  281. }
  282. if (dropTest)
  283. {
  284. //Trigger the timeout if no recieve
  285. timeoutWaitTimer.Start();
  286. while (!timeoutWaitTimer.IsExpired())
  287. {
  288. RakSleep(50);
  289. }
  290. }
  291. // 11/29/05 - No longer necessary since I added the keepalive
  292. /*
  293. // Have everyone send a reliable packet so dropped connections are noticed.
  294. ch=255;
  295. server->Send((char*)&ch, 1, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
  296. for (index=0; index < NUMBER_OF_CLIENTS; index++)
  297. clients[index]->Send((char*)&ch, 1, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
  298. */
  299. // Sleep so this loop doesn't take up all the CPU time
  300. RakSleep(10);
  301. }
  302. return 0;
  303. }
  304. RakString DroppedConnectionConvertTest::GetTestName()
  305. {
  306. return "DroppedConnectionConvertTest";
  307. }
  308. RakString DroppedConnectionConvertTest::ErrorCodeToString(int errorCode)
  309. {
  310. switch (errorCode)
  311. {
  312. case 0:
  313. return "No error";
  314. break;
  315. case 1:
  316. return "Client has more than one connection";
  317. break;
  318. case 2:
  319. return "Connect failed";
  320. break;
  321. case 3:
  322. return "Timeout not detected";
  323. break;
  324. default:
  325. return "Undefined Error";
  326. }
  327. }
  328. void DroppedConnectionConvertTest::DestroyPeers()
  329. {
  330. int theSize=destroyList.Size();
  331. for (int i=0; i < theSize; i++)
  332. RakPeerInterface::DestroyInstance(destroyList[i]);
  333. }
  334. DroppedConnectionConvertTest::DroppedConnectionConvertTest(void)
  335. {
  336. }
  337. DroppedConnectionConvertTest::~DroppedConnectionConvertTest(void)
  338. {
  339. }
粤ICP备19079148号