RetroShare/libretroshare/src/tests/pqi/pqiqos_test.cc
csoler 0ed60eaf86 merge of QoS branch into trunk
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4588 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2011-09-04 20:01:30 +00:00

192 lines
4.4 KiB
C++

#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() ;
}