mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
0ed60eaf86
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4588 b45a01b8-16f6-495d-af2f-9b41ad6348cc
192 lines
4.4 KiB
C++
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() ;
|
|
}
|
|
|
|
|