Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/network/diffTest.cc @ 1008

Last change on this file since 1008 was 1008, checked in by dumenim, 16 years ago

changed some comments and catched some return values and maybe some stuff we have to unchange

File size: 19.2 KB
Line 
1#include "enet/enet.h"
2#include "Orxonox.h"
3#include "NetworkPrereqs.h"
4#include "PacketTypes.h"
5#include "GameStateManager.h"
6#include "Synchronisable.h"
7#include "GameStateClient.h"
8#include "iostream"
9#include "core/CoreIncludes.h"
10#include "time.h"
11#include "ConnectionManager.h"
12#include "ClientInformation.h"
13#include <boost/thread/thread.hpp>
14#include <boost/bind.hpp>
15#include "util/Sleep.h"
16
17using namespace network;
18
19void printData( unsigned char* data, int length ) {
20  for ( int i=0; i<length; i++ )
21    std::cout << (int)data[i] << " ";
22  std::cout << std::endl;
23}
24
25void printGameStateCompressed( GameStateCompressed* gc ) {
26  //std::cout << "=================================================" << std::endl;
27  std::cout << "GameStateCompressed id:\t\t" << gc->id << std::endl;
28  std::cout << "GameStateCompressed normsize:\t" << gc->normsize << std::endl;
29  std::cout << "GameStateCompressed compsize:\t" << gc->compsize << std::endl;
30  std::cout << "GameStateCompressed diffed:\t" << gc->diffed << std::endl;
31  //std::cout << "GameState data:\t" << gc->data << std::endl;
32  std::cout << "GameStateCompressed compressing rate:\t" << 100.0-((100.0/(gc->normsize))*(gc->compsize)) << "%" << std::endl;
33  std::cout << "=================================================" << std::endl;
34  return;
35}
36
37bool compareData( GameState* g1, GameState* g2 ) {
38  if ( g1->id != g2->id ) {
39    std::cout << "\t--> GameStates are not comparable -> not same id" << std::endl;
40    return 1;
41  }
42  else if ( g1->size != g2->size ) {
43    std::cout << "\t--> GameStates are not the same size!!" << std::endl;
44    std::cout << g1->size << " != " << g2->size << std::endl;
45  }
46  int length = g1->size;
47  for ( int i=0; i<length; i++ ) {
48    if ( g1->data[i] != g2->data[i] ) {
49      std::cout << "\t--> data of both GameStates are not identical" << std::endl;
50      return false;
51    }
52  }
53  std::cout << "\t--> GameStates are identical (compareData)" << std::endl;
54  return true;
55}
56
57bool compareGameStates( GameState* g1, GameState* g2 ) {
58  if ( g1->id != g2->id ) {
59    std::cout << "\t==> GameState id's not identical (GameStateCompare)" << std::endl;
60  }
61  if( g1->size != g2->size ) {
62    std::cout << "\t==> GameState sizes are not identical (GameStateCompare)" << std::endl;
63    return false;
64  }
65  else if ( g1->diffed != g2->diffed ) {
66    std::cout << "\t==> GameState diffed params not identical (GameStateCompare)" << std::endl;
67    return false;
68  }
69  else if ( !compareData( g1, g2 ) ) {
70    std::cout << "\t==> GameState data are not identical (GameStateCompare)" << std::endl;
71    return false;
72  }
73  std::cout << "\t==> GameStates are identical (GameStateCompare)" << std::endl;
74  return true;
75}
76
77void printGameState( GameState* gstate ) {
78  //std::cout << "=================================================" << std::endl;
79  std::cout << "GameState id:\t\t" << gstate->id << std::endl;
80  std::cout << "GameState size:\t\t" << gstate->size << std::endl;
81  std::cout << "GameState diffed:\t" << gstate->diffed << std::endl;
82  //std::cout << "GameState data:\t" << gstate->data << std::endl;
83  std::cout << "=================================================" << std::endl;
84  return;
85}
86
87unsigned char* createData( int length, int mode ) {
88  char* data = new char[ length ];
89  if ( mode == 1 ) {
90    for ( int i=0; i<length; i++ )
91      data[i] = (char)(i%255);
92  }
93  else if ( mode == 2 ) {
94    for ( int i=0; i<length; i++ ) {
95      if ( i%98 == 0 ) data[i] = (char)(i%255);
96      else data[i] = (char)0;
97    }
98  }
99  else if ( mode == 3 ) {
100    for ( int i=0; i<length; i++ ){
101      data[i] = (char)(rand()%255);
102    }
103  }
104  else if ( mode == 4 ) {
105    for ( int i=0; i<length; i++ ){
106      data[i] = (char)(rand()%127);
107    }
108  }
109
110  //printData( data, length ); 
111
112  unsigned char* dat = (unsigned char*)data;
113  return dat;
114}
115
116GameState* changeGameStateABit( GameState* a, int mode ) {
117  int length = a->size;
118  GameState* b = new GameState;
119  b->id = a->id;
120  b->diffed = a->diffed;
121
122  if ( mode == 1 ) {
123    b->data = new unsigned char[length];
124    b->size = a->size;
125    for ( int i=0; i<length; i++ ) {
126      if ( i%10 == 0 ) b->data[i] = rand()%255;
127      else b->data[i] = a->data[i];
128    }
129  }
130  else if ( mode == 2 ) {
131    b->data = new unsigned char[length];
132    b->size = length;
133    for ( int i=0; i<length; i++ ) {
134      if ( i%(rand()%((length)/11)) == 0 ) b->data[i] = rand()%255;
135      else b->data[i] = a->data[i];
136    }
137  }
138  else if ( mode == 3 ) {
139    int s = length + (rand()%(length));
140    b->data = new unsigned char[s];
141    b->size = s;
142    for ( int i=0; i<length; i++ ) {
143      if ( i%10 == 0 ) b->data[i] = rand()%255;
144      else b->data[i] = a->data[i];
145    }
146    for( int i=length; i<s; i++ ) {
147      b->data[i] = rand()%255;
148    }
149  }
150  else if ( mode == 4 ) {
151    int s = length + (rand()%(length));
152    b->data = new unsigned char[s];
153    b->size = s;
154    for ( int i=0; i<length; i++ ) {
155      if ( i%(rand()%(length)) == 0 ) b->data[i] = rand()%255;
156      else b->data[i] = a->data[i];
157    }
158    for( int i=length; i<s; i++ ) {
159      b->data[i] = rand()%255;
160    }
161  }
162    else if ( mode == 5 ) {
163    int s = (length)/2;
164    b->data = new unsigned char[s];
165    b->size = s;
166    for ( int i=0; i<s; i++ ) {
167      if ( i%10 == 0 ) b->data[i] = rand()%255;
168      else b->data[i] = a->data[i];
169    }
170  }
171
172  return b;
173}
174
175void testCompression( int size, int mode ) {
176  std::cout << "testing compression with: size = " << size << " ,mode = " << mode << std::endl; 
177  GameStateClient* g_client;
178  GameStateManager* g_manager;;
179 
180  GameState* g_new = new GameState;
181  GameState* g_old = new GameState;
182  GameStateCompressed* gc = new GameStateCompressed;
183 
184  g_old->data = createData( size, mode );
185  g_old->size = size;
186  g_old->id = 0;
187  g_old->diffed = false;
188  printGameState( g_old );
189 
190  gc = g_manager->testCompress( g_old );
191  printGameStateCompressed( gc );
192
193  g_new = g_client->testDecompress( gc );
194  printGameState( g_new );
195
196  compareGameStates( g_new, g_old );
197
198  return;
199}
200
201void testDifferentiation( int size, int modeCreateData, int modeChangeData ) {
202  std::cout << "testing diff with: size = " << size << " modeCreateData = " 
203            << modeCreateData << " modeChangeData = " << modeChangeData << std::endl; 
204  GameStateClient* g_client;
205  GameStateManager* g_manager;
206 
207  GameState* g_undiff1 = new GameState;
208  GameState* g_undiff2 = new GameState;
209  GameState* g_diffed;
210  GameState* g_result;
211
212  g_undiff1->data = createData( size, modeCreateData );
213  g_undiff1->size = size;
214  g_undiff1->id = 1;
215  g_undiff1->diffed = false;
216  printGameState( g_undiff1 );
217
218  g_undiff2 = changeGameStateABit( g_undiff1, modeChangeData );
219  printGameState( g_undiff2 );
220
221  if( !compareData( g_undiff1, g_undiff2 ) ) std::cout << " BUT THAT'S HOW IT HAS TO BE" << std::endl;
222
223  //printData( g_undiff1->data, g_undiff1->size );
224  //printData( g_undiff2->data, g_undiff2->size );
225 
226  g_diffed = g_manager->testDiff( g_undiff1, g_undiff2 );
227  printGameState( g_diffed );
228  //printData( g_diffed->data, g_diffed->size );
229 
230  g_result = g_client->testUndiff( g_undiff1, g_diffed );
231  compareGameStates( g_result, g_undiff2 );
232
233  return;
234}
235
236void testCompressWithDiff( int size, int modeCreateData, int modeChangeData ) {
237  std::cout << "testing CompressWithDiff with: size = " << size << " modeCreateData = " 
238            << modeCreateData << " modeChangeData = " << modeChangeData << std::endl; 
239  GameStateClient* g_client;
240  GameStateManager* g_manager;;
241 
242  GameStateCompressed* gc = new GameStateCompressed;
243  GameStateCompressed* g_compressedNoDiff;
244  GameState* g_undiff1 = new GameState;
245  GameState* g_undiff2 = new GameState;
246  GameState* g_diffed;
247  GameState* g_resultDiffed;
248  GameState* g_resultUndiffed;
249
250  g_undiff1->data = createData( size, modeCreateData );
251  g_undiff1->size = size;
252  g_undiff1->id = 1;
253  g_undiff1->diffed = false;
254 
255  std::cout << "---First generated Gamestate" << std::endl;
256  printGameState( g_undiff1 );
257
258  g_undiff2 = changeGameStateABit( g_undiff1, modeChangeData );
259  std::cout << "---First gererated Gamestate with some changes ev. longer" << std::endl;
260  printGameState( g_undiff2 ); 
261
262  if( !compareData( g_undiff1, g_undiff2 ) ) std::cout << " BUT THAT'S HOW IT HAS TO BE" << std::endl;
263
264  g_diffed = g_manager->testDiff( g_undiff1, g_undiff2 );
265  std::cout << "---Diffed Gamestate not compressed" << std::endl;
266  printGameState( g_diffed );
267
268  gc = g_manager->testCompress( g_diffed );
269  std::cout << "---Diffed Gamestate compressed" << std::endl;
270  printGameStateCompressed( gc );
271
272  g_compressedNoDiff = g_manager->testCompress( g_undiff2 );
273  std::cout << "---Same not Diffed Gamestate compressen" << std::endl;
274  printGameStateCompressed( g_compressedNoDiff ); 
275
276  g_resultDiffed = g_client->testDecompress( gc );
277  std::cout << "---Diffed Gamestate of above uncompressed" << std::endl;
278  printGameState( g_resultDiffed );
279
280  std::cout << "---Diffed Gamestates before compressed and after uncompress comparsion" << std::endl;
281  compareGameStates( g_resultDiffed, g_diffed );
282 
283  g_resultUndiffed = g_client->testUndiff( g_undiff1, g_resultDiffed );
284  std::cout << "---New Gamestate of pseudo Server compared with new gamestate that Client gets" << std::endl;
285  compareGameStates( g_resultUndiffed, g_undiff2 );
286
287  return; 
288}
289
290void printClientObjectMapping( ConnectionManager* cmanager, int clients ) {
291  std::map<int, int>::iterator iter;
292  std::map<int, int> clientsmap = cmanager->testGetClientsShip();   
293  for( iter = clientsmap.begin(); iter != clientsmap.end(); iter++ ) {
294    std::cout << "clientID: " << iter->first << "\t-> objectID: " << iter->second << std::endl;
295  }
296  return;
297}
298
299bool is( int a[], int b, int size ) {
300  for ( int i=0; i<size; i++ ) {
301    if ( a[i] == b ) return true;
302  }
303  return false;
304}
305
306void testClientObjectMapping( int clients ) {
307  ConnectionManager* cmanager = new ConnectionManager();
308  int shift = 2;
309  std::cout << "create a map length [clients]" << std::endl;
310  for ( int i=0; i<clients; i++ ) {
311    cmanager->testAddClientsShipID( i, i+shift );
312  }
313  printClientObjectMapping( cmanager, clients );
314 
315  std::cout << "get random client's ship id" << std::endl;
316  int id;
317  for ( int i=0; i<(clients/3); i++ ) {
318    id = rand()%clients;
319    std::cout << "client: " << id << "\t-> ship: " << cmanager->testGetClientsShipID( id ) << std::endl; 
320  }
321
322  std::cout <<"get random ship's client id" << std::endl;
323  for ( int i=0; i<(clients/3); i++ ) {
324    id = (rand()%clients)+shift;
325    std::cout << "ship:   " << id << "\t-> client: " << cmanager->testGetObjectsClientID( id ) << std::endl; 
326  }
327
328  std::cout << "delete random client from map" << std::endl;
329  int deleted[clients/3];
330  for ( int i=0; i<(clients/3); i++ ) {
331    id = rand()%clients;
332    if ( !is( deleted, id, clients/3 ) ) {
333      std::cout << "delete client " << id << std::endl;
334      cmanager->testDeleteClientsIDReg( id ); 
335    }
336    deleted[i] = id;
337  }
338  std::cout << "resulting list:" << std::endl;
339  printClientObjectMapping( cmanager, clients-(clients/3));
340 
341  std::cout << "delete random object from map" << std::endl;
342  int jap = 0;
343  while( jap < 3 ) {
344    id = (rand()%clients) + shift;
345    if ( !is( deleted, id, clients/3 ) ) {
346      std::cout << "delete object: " << id << std::endl;
347      cmanager->testDeleteObjectIDReg( id );
348      jap++;
349    }
350  }
351  std::cout << "resulting list:" << std::endl;
352  printClientObjectMapping( cmanager, clients-(clients/3)-3);
353}
354
355bool addClientTest( ENetEvent* event, ClientInformation*& head ) {
356  ClientInformation *temp = head->insertBack(new ClientInformation);
357  if(temp->prev()->head) {
358    temp->prev()->setID(0);
359    temp->setID(1);
360  }
361  else
362    temp->setID(temp->prev()->getID()+1);
363  temp->setPeer(event->peer);
364  std::cout << "added client id: " << temp->getID() << std::endl;
365
366  temp->setSynched(true);
367  return true;
368}
369
370void printClientInformationBox( ClientInformation* box ) {
371  std::cout << "ClientList: id: " << box->getID() << "\t";
372  std::cout << "g_id: " << box->getGamestateID() << " \t";
373  std::cout << "synched: " << box->getSynched() << "\t";
374  std::cout << "is head: " << box->head << std::endl;
375}
376
377void printClientInformationList( ClientInformation* list ) {
378  printClientInformationBox( list );
379  list = list->next();
380 
381  while( list != 0 ) {
382    printClientInformationBox( list );
383    list = list->next();
384  }
385  return;
386}
387
388void testClientInformation( int numberOfClients ) {
389  ClientInformation* head = new ClientInformation( true );
390  ConnectionManager* connectionManager;
391  ENetEvent event;
392 
393  for ( int i=0; i<numberOfClients; i++ ) {
394    if ( !addClientTest( &event, head ) ) {
395      std::cout << "addClientTest didn't work with: " << i << std::endl;
396    }
397  }
398  std::cout << "(now id should be synched, since that works and this is test of list, this step is left out)" << std::endl;
399
400  printClientInformationList( head );
401
402  std::cout << "remove some clients" << std::endl;
403  if ( head->removeClient( numberOfClients/3 ) ) std::cout << "client " << numberOfClients/3 << " removed" << std::endl;
404  else std::cout << "could not remove client: " << numberOfClients/3 << std::endl;
405  if ( head->removeClient( numberOfClients ) ) std::cout << "client " << numberOfClients << " removed" << std::endl;
406  else std::cout << "could not remove client: " << numberOfClients << std::endl;
407  if ( head->removeClient( 1 ) ) std::cout << "client " << 1 << " removed" << std::endl;
408  else std::cout << "could not remove client: " << 1 << std::endl;
409  if ( head->removeClient( 1 ) ) std::cout << "client " << 1 << " removed a second time" << std::endl;
410  else std::cout << "could not remove client: " << 1 << std::endl;
411  if ( head->removeClient( numberOfClients + 100 ) ) std::cout << "client " << numberOfClients + 100 << " removed a second time" << std::endl;
412  else std::cout << "could not remove client: " << numberOfClients + 100 << std::endl;
413
414  printClientInformationList( head );
415 
416  std::cout << "try to find some clients with findClient(..., false)" << std::endl;
417  ClientInformation* temp = head->findClient( 2 );
418  printClientInformationBox( temp );
419  temp = head->findClient( numberOfClients/3 );
420  printClientInformationBox( temp );
421  temp = head->findClient( 0 );
422  printClientInformationBox( temp );
423  temp = head->findClient( 8 );
424  printClientInformationBox( temp );
425
426  std::cout << "find the same, output should be identical with above but with findClient(..., TRUE)" << std::endl;
427  temp = head->findClient( 2, true );
428  printClientInformationBox( temp );
429  temp = head->findClient( numberOfClients/3, true );
430  printClientInformationBox( temp );
431  temp = head->findClient( 0, true );
432  printClientInformationBox( temp );
433  temp = head->findClient( 8, true );
434  printClientInformationBox( temp );
435
436  std::cout << "test setGamestateID" << std::endl;
437  temp->setGamestateID( 8 );
438  printClientInformationBox( temp );
439
440  std::cout << "test insertAfter() and insertBefore()" << std::endl;
441  ClientInformation* newInfo = new ClientInformation;
442  ClientInformation* toool = new ClientInformation;
443  newInfo->setGamestateID( 200 );
444  newInfo->setID( numberOfClients+2);
445  newInfo->setSynched( true );
446  newInfo->setPeer( NULL );
447  toool->setGamestateID( 199 );
448  toool->setID( numberOfClients+1);
449  toool->setSynched( true );
450  toool->setPeer( NULL );
451
452  //never use the same ClientInformation box in this situation
453  //-> results in endless loop
454  temp->insertAfter( newInfo );
455  temp->insertBefore( toool );
456
457  printClientInformationList( head );
458  return;
459}
460
461//### following stuff is to test buffer, took from PacketBufferTestExt.cc ###
462
463void write(PacketBuffer *test){
464  ENetEvent event;
465  ENetPacket *packet;
466  if(test->isEmpty())
467    std::cout << "buffer is empty" << std::endl;
468  for(int i=0; i<10; i++){
469    std::string temp = "packet ";
470    packet = enet_packet_create("packet", strlen("packet ")+1,
471      ENET_PACKET_FLAG_RELIABLE);
472    std::cout << i << ": pushing " << packet->data << std::endl;
473    event.packet=packet;
474    test->push(&event);
475    if(i==5)
476      usleep(200000);
477  }
478  test->setClosed(true);
479  return;
480}
481
482void read(PacketBuffer *test){
483  //test->print();
484  // exit if the queue is closed and empty
485  while(!test->isClosed() || !test->isEmpty()){
486    // only pop if the queue isn't empty
487    while(!test->isEmpty()){
488      std::cout << "We popped the value " << test->pop()->data << std::endl;
489    }
490  }
491  return;
492}
493
494void testPacketBuffer() {
495  PacketBuffer test = PacketBuffer();
496  boost::thread thrd1(boost::bind(&write, &test));
497  boost::thread thrd2(boost::bind(&read, &test));
498
499  thrd1.join();
500  thrd2.join();
501  return;
502}
503
504//### end packetbuffer test stuff ###
505
506void displayModes() {
507  std::cout << "mode datalength: length of data array to create" << std::endl;
508  std::cout << "mode Data:" << std::endl;
509  std::cout << "\t-1 -> array[length] with numbers length%255" << std::endl;
510  std::cout << "\t-2 -> array[length] with numbers length%255, every %98 is != 0" << std::endl;
511  std::cout << "\t-3 -> array[length] with random numbers (-126:127) no modulo zeros" << std::endl;
512  std::cout << "\t-4 -> array[length] with random numbers (0:127) no modulo zeros" << std::endl;
513  std::cout << "---------------------------------------------------------------------------------" << std::endl;
514  std::cout << "mode Change:" << std::endl;
515  std::cout << "\t-1 -> every %10 == 0 index is different from original" << std::endl;
516  std::cout << "\t-2 -> every %(rand()%(length/11)) is different from original" << std::endl;
517  std::cout << "\t-3 -> every %10 == 0 index is different and randomly longer till 2xlonger" << std::endl;
518  std::cout << "\t-4 -> random differences and randomly longer" << std::endl;
519  std::cout << "\t-5 -> only half as long and ever %10 == 0 index is different" << std::endl;
520}
521
522int main( int argc, char* argv[] ) {
523  int a,b,c;
524  std::string dec = "nothing";
525  std::cout << "############### START TEST (quit q) ###############" << std::endl;
526  std::cout << "possible tests: " << std::endl;
527  std::cout << "displayModes:\t\t modes" << std::endl;
528  std::cout << "testCompression:\t tc [datalength] [mode Data]" << std::endl;
529  std::cout << "testDifferentiation:\t td [datalength] [mode Data] [mode Change]" << std::endl;
530  std::cout << "testCompressWithDiff:\t tcd [datalength] [mode Data] [mode Change]" << std::endl;
531  std::cout << "testClientObjectMapping: tcom [#clients]" << std::endl;
532  std::cout << "testClientInformation:\t tci [#clients] (call with >10)" << std::endl;
533  std::cout << "testPacketBuffer:\t tbuf (comment address assignements in PacketBuffer.cc!)" << std::endl;
534  while ( dec.compare("q") != 0 ) {
535    std::cin >> dec;
536    if ( dec.compare("tc") == 0 ) {
537      std::cin >> a; std::cin >> b;
538      testCompression( a, b );
539    }
540    else if ( dec.compare("td") == 0 ) {
541      std::cin>> a; std::cin >> b; std::cin >> c;
542      testDifferentiation( a, b, c );
543    }
544    else if ( dec.compare("tcd") == 0 ) {
545      std::cin>> a; std::cin >> b; std::cin >> c;
546      testCompressWithDiff( a, b, c );
547    }
548    else if ( dec.compare("modes") == 0 )
549      displayModes();
550    else if ( dec.compare("tcom") == 0 ) {
551      std::cin>> a;
552      testClientObjectMapping( a );
553    }
554    else if ( dec.compare("tci") == 0 ) {
555      std::cin >> a;
556      testClientInformation( a );
557    } 
558    else if ( dec.compare("tbuf") == 0 ) {
559      testPacketBuffer();
560    }   
561    std::cout << "################## END ONE TURN ##################@" << std::endl;
562  }
563  return 0;
564}
565/**
566int main() {
567  std::cout << "############### START TEST (quit q) ###############" << std::endl;
568  testClientInformation( 10 );
569}*/
Note: See TracBrowser for help on using the repository browser.