merge of QoS branch into trunk

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4588 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2011-09-04 20:01:30 +00:00
parent 663ce50630
commit 0ed60eaf86
23 changed files with 734 additions and 337 deletions

View file

@ -1,5 +1,7 @@
RS_TOP_DIR = ../..
DHT_TOP_DIR = ../../../../libbitdht/src/
##### Define any flags that are needed for this section #######
###############################################################
@ -10,6 +12,7 @@ include $(RS_TOP_DIR)/tests/scripts/config.mk
# Generic Test Harnesses.
TESTOBJ = conn_harness.o ppg_harness.o
TESTOBJ += pqiqos_test.o
TESTOBJ += net_test.o dht_test.o net_test1.o netiface_test.o dht_test.o
TESTOBJ += pkt_test.o pqiarchive_test.o pqiperson_test.o
TESTOBJ += extaddrfinder_test.o dnsresolver_test.o pqiipset_test.o
@ -17,7 +20,8 @@ TESTOBJ += p3connmgr_reset_test.o p3connmgr_connect_test.o
#conn_test.o
TESTS = net_test net_test1 netiface_test pqiarchive_test pqiperson_test dnsresolver_test extaddrfinder_test
TESTS += pqiipset_test
TESTS += pqiipset_test
TESTS += pqiqos_test
TESTS += p3connmgr_reset_test p3connmgr_connect_test
#TESTS = p3connmgr_test1
@ -51,10 +55,13 @@ pqiarchive_test: pqiarchive_test.o pkt_test.o
$(CC) $(CFLAGS) -o pqiarchive_test pkt_test.o pqiarchive_test.o $(LIBS)
pqiperson_test: pqiperson_test.o testconnect.o
$(CC) $(CFLAGS) -o pqiperson_test pqiperson_test.o testconnect.o $(LIBS)
$(CC) $(CFLAGS) -o pqiperson_test pqiperson_test.o testconnect.o $(LIBS) -lstdc++
extaddrfinder_test: extaddrfinder_test.o
$(CC) $(CFLAGS) -o extaddrfinder_test extaddrfinder_test.o $(LIBS)
$(CC) $(CFLAGS) -DEXTADDRSEARCH_DEBUG=1 -o extaddrfinder_test extaddrfinder_test.o $(LIBS)
pqiqos_test: pqiqos_test.o
$(CC) $(CFLAGS) -o pqiqos_test pqiqos_test.o $(LIBS)
dnsresolver_test: dnsresolver_test.o
$(CC) $(CFLAGS) -o dnsresolver_test dnsresolver_test.o $(LIBS)

View file

@ -0,0 +1,191 @@
#include "util/utest.h"
#include <iostream>
#include <math.h>
#include <stdint.h>
#include "serialiser/rsserial.h"
#include "util/rsrandom.h"
#include "pqi/pqiqos.h"
INITTEST();
// Class of RsItem with ids to check order
//
class testRawItem: public RsItem
{
public:
testRawItem()
: RsItem(0,0,0), _id(_static_id++)
{
}
virtual void clear() {}
virtual std::ostream& print(std::ostream& o, uint16_t) { return o ; }
static const uint32_t rs_rawitem_size = 10 ;
static uint64_t _static_id ;
uint64_t _id ;
};
uint64_t testRawItem::_static_id = 1;
int main()
{
float alpha = 3 ;
int nb_levels = 10 ;
//////////////////////////////////////////////
// 1 - Test consistency of output and order //
//////////////////////////////////////////////
{
pqiQoS qos(nb_levels,alpha) ;
// 0 - Fill the queue with fake RsItem.
//
static const uint32_t pushed_items = 10000 ;
for(uint32_t i=0;i<pushed_items;++i)
{
RsItem *item = new testRawItem ;
item->setPriorityLevel(i % nb_levels) ;
qos.in_rsItem(item) ;
}
std::cerr << "QOS is filled with: " << std::endl;
qos.print() ;
// 1 - checks that all items eventually got out in the same order for
// items of equal priority
//
uint32_t poped = 0;
std::vector<uint64_t> last_ids(nb_levels,0) ;
while(testRawItem *item = static_cast<testRawItem*>(qos.out_rsItem()))
{
CHECK(last_ids[item->priority_level()] < item->_id) ;
last_ids[item->priority_level()] = item->_id ;
delete item, ++poped ;
}
std::cerr << "Push " << pushed_items << " items, poped " << poped << std::endl;
if(pushed_items != poped)
{
std::cerr << "Queues are: " << std::endl;
qos.print() ;
}
CHECK(pushed_items == poped) ;
}
//////////////////////////////////////////////////
// 2 - tests proportionality //
//////////////////////////////////////////////////
{
// Now we feed the QoS, and check that items get out with probability proportional
// to the priority
//
pqiQoS qos(nb_levels,alpha) ;
std::cerr << "Feeding 10^6 packets to the QoS service." << std::endl;
for(int i=0;i<1000000;++i)
{
if(i%10000 == 0)
{
fprintf(stderr,"%1.2f %% completed.\r",i/(float)1000000*100.0f) ;
fflush(stderr) ;
}
testRawItem *item = new testRawItem ;
switch(i%5)
{
case 0: item->setPriorityLevel( 1 ) ; break ;
case 1: item->setPriorityLevel( 4 ) ; break ;
case 2: item->setPriorityLevel( 6 ) ; break ;
case 3: item->setPriorityLevel( 7 ) ; break ;
case 4: item->setPriorityLevel( 8 ) ; break ;
}
qos.in_rsItem(item) ;
}
// Now perform stats on outputs for the 10000 first elements
std::vector<int> hist(nb_levels,0) ;
for(uint32_t i=0;i<10000;++i)
{
RsItem *item = qos.out_rsItem() ;
hist[item->priority_level()]++ ;
delete item ;
}
std::cerr << "Histogram: " ;
for(uint32_t i=0;i<hist.size();++i)
std::cerr << hist[i] << " " ;
std::cerr << std::endl;
}
///////////////////////////////////////////////////////////////////////////////////
// 3 - Now do a test with a thread filling the queue and another getting from it //
///////////////////////////////////////////////////////////////////////////////////
{
pqiQoS qos(nb_levels,alpha) ;
static const time_t duration = 60 ;
static const int average_packet_load = 10000 ;
time_t start = time(NULL) ;
time_t now ;
while( (now = time(NULL)) < duration+start )
{
float in_out_ratio = 1.0f;// - 0.3*cos( (now-start)*M_PI ) ; // out over in
// feed a random number of packets in
uint32_t in_packets = RSRandom::random_u32() % average_packet_load ;
uint32_t out_packets = (uint32_t)((RSRandom::random_u32() % average_packet_load)*in_out_ratio) ;
for(uint32_t i=0;i<in_packets;++i)
{
testRawItem *item = new testRawItem ;
item->setPriorityLevel(i%nb_levels) ;
qos.in_rsItem(item) ;
}
// pop a random number of packets out
std::vector<uint64_t> last_ids(nb_levels,0) ;
for(uint32_t i=0;i<out_packets;++i)
{
testRawItem *item = static_cast<testRawItem*>(qos.out_rsItem()) ;
if(item == NULL)
{
std::cerr << "Null output !" << std::endl;
break ;
}
CHECK(last_ids[item->priority_level()] < item->_id) ;
last_ids[item->priority_level()] = item->_id ;
delete item ;
}
// print some info
static time_t last = 0 ;
if(now > last)
{
qos.print() ;
last = now ;
}
}
}
FINALREPORT("pqiqos_test");
return TESTRESULT() ;
}