Ignore:
Timestamp:
Mar 7, 2014, 5:09:37 PM (11 years ago)
Author:
hock@…
Message:

TEST_F(SystemQueueTest, MultipleCalls)

A bit more complicated than it should be, but the SystemQueue can't tell reliably whether it is empty or not.

Thefore another test, that fails, is added and disabled: TEST_F(SystemQueueTest, DISABLED_Threading)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tests/SystemQueue-tests.cc

    r12750 r12751  
    7373public:
    7474
     75// sleep time when waiting for the system queue (max total / each step)
     76#define MAX_WAIT 100  // microseconds
     77#define SLEEP_TIME 10  // microseconds
     78
    7579    SystemQueueTest() :
    76         checkmark(false)
     80        checkmark(false),
     81        last_ordered_call(0)
    7782    {
    7883    }
     
    8186    {
    8287        checkmark = true;
    83 //         cout << "Hallo Mario ^^" << endl;
     88    }
     89   
     90    void LongRunner()
     91    {
     92        usleep( MAX_WAIT / 2 );
     93       
     94        checkmark = true;
     95    }
     96   
     97   
     98    /// wait for the checkmark to be set by a SystemQueue call, (but not too long!)
     99    void wait_for_checkmark(int max_wait = MAX_WAIT)
     100    {
     101        for ( int i = 0; i < max_wait / SLEEP_TIME; i++)
     102        {
     103            if ( checkmark )
     104                break;
     105           
     106            cout << "/// sleeping for " << SLEEP_TIME << " microseconds ..." << endl;
     107            usleep(SLEEP_TIME);
     108        }
     109    }
     110
     111    /// call that checks wheather it was performed in order
     112    void OrderedCall(int num)
     113    {
     114        // check ordering
     115        EXPECT_EQ( num, last_ordered_call + 1);
     116       
     117        last_ordered_call = num;
     118    }
     119   
     120    /// like OrderedCall, but calls itself to test nested calls
     121    void NestedOrderedCall(int from, int to)
     122    {
     123        // check ordering
     124        OrderedCall(from);
     125       
     126        // nested call
     127        if ( from < to )
     128        {
     129            SystemQueue::instance().scheduleCall(
     130                boost::bind(&SystemQueueTest::NestedOrderedCall,
     131                            this,
     132                            from+1,
     133                            to)
     134            );
     135        }
     136        else
     137        {
     138            /// XXX because the current/old SystemQueue does not pass the Threading test,
     139            /// we have to signal, that when all nested calls are finished,
     140            /// so we need to set the checkmark here..
     141           
     142            checkmark = true;
     143        }
    84144    }
    85145
    86146    bool checkmark;
     147    int last_ordered_call;
    87148};
    88149
     150
     151/**
     152 *  schedule a call and test whether it is actually performed by the SystemQueue
     153 */
    89154TEST_F(SystemQueueTest, ScheduleCall)
    90155{
    91     #define MAX_WAIT 100  // microseconds
    92     #define SLEEP_TIME 10  // microseconds
    93 
    94156    SystemQueue& sysq = SystemQueue::instance();
    95157    checkmark = false;  // just to be sure..
     
    102164        boost::bind(&SystemQueueTest::Check, this)
    103165    );
    104    
    105     // wait for the event to happen, (but not too long!)
    106     for ( int i = 0; i < MAX_WAIT / SLEEP_TIME; i++)
    107     {
    108         if ( checkmark )
    109             break;
    110        
    111         cout << "/// sleeping for " << SLEEP_TIME << " microseconds ..." << endl;
    112         usleep(SLEEP_TIME);
    113     }
    114    
    115     // stop
    116     sysq.cancel();
    117    
    118     EXPECT_TRUE( checkmark ) << "Function was called within " << MAX_WAIT << " microseconds.";   
    119 }
    120 
     166
     167    // wait for the event to happen
     168    wait_for_checkmark(MAX_WAIT);
     169   
     170    // stop
     171    sysq.cancel();
     172   
     173    EXPECT_TRUE( checkmark ) << "Function was not called within " << MAX_WAIT << " microseconds.";
     174}
     175
     176
     177/**
     178 *  This test actually tests two things [sorry, but it's hard to test them separately!]
     179 *
     180 *  - first: the SystemQueue should not consider itself empty, while an event is processed
     181 *  - second: SystemQueue events should be processed in parallel to the main thread
     182 *
     183 *  NOTE: The timings here are not obvious, maybe they have to be adjusted on very slow machines
     184 *
     185 *  NOTE: !! The current/old SystemQueue does NOT pass this test!!
     186 *
     187 *    That's also why we need the unhandy wait_for_checkmark function,
     188 *    instead a wait_until_empty function.
     189 */
     190TEST_F(SystemQueueTest, DISABLED_Threading)
     191{
     192    SystemQueue& sysq = SystemQueue::instance();
     193    checkmark = false;  // just to be sure..
     194   
     195    // start
     196    sysq.run();
     197   
     198    // scheduleCall
     199    sysq.scheduleCall(
     200        boost::bind(&SystemQueueTest::LongRunner, this)
     201    );
     202   
     203    // SystemQueue must not be empty as long as the event is not finished
     204    if ( sysq.isEmpty() )
     205    {
     206        // assert that this test is actually meaningful
     207        ASSERT_FALSE( checkmark )
     208            << "NOTE: This is not necessarily a bug, maybe the timing just have to adjusted. Try to increase MAX_WAIT.";
     209
     210        EXPECT_TRUE( ! sysq.isEmpty() || checkmark );
     211    }
     212
     213    // wait for the event to finish
     214    wait_for_checkmark(MAX_WAIT);
     215
     216    // stop
     217    sysq.cancel();
     218
     219    // even the long-runner should finally finish
     220    EXPECT_TRUE( checkmark ) << "Function has not finished within " << MAX_WAIT << " microseconds.";
     221}
     222
     223/**
     224 *  schedule multiple calls
     225 *
     226 *  each call must be performed, in the correct order
     227 *
     228 *  NOTE: The nested calls are not necessarily in order with calls scheduled from the main thread,
     229 *  that's fine, therefore we make sure the nested calls are done, before scheduling new ones.
     230 */
     231TEST_F(SystemQueueTest, MultipleCalls)
     232{
     233    SystemQueue& sysq = SystemQueue::instance();
     234   
     235    // start
     236    sysq.run();
     237
     238    sysq.scheduleCall( boost::bind(&SystemQueueTest::OrderedCall, this, 1) );
     239    sysq.scheduleCall( boost::bind(&SystemQueueTest::OrderedCall, this, 2) );
     240    sysq.scheduleCall( boost::bind(&SystemQueueTest::NestedOrderedCall, this, 3, 5) );
     241   
     242    // make sure all nested calls are done
     243    wait_for_checkmark(MAX_WAIT);  // XXX should be "wait_until_empty() ...."
     244
     245    checkmark = false;
     246    sysq.scheduleCall( boost::bind(&SystemQueueTest::OrderedCall, this, 6) );
     247   
     248    // XXX same here...  [ wait_until_empty() ]
     249    sysq.scheduleCall( boost::bind(&SystemQueueTest::Check, this) );
     250    wait_for_checkmark(MAX_WAIT);
     251   
     252    // evaluation
     253    EXPECT_EQ( 6, last_ordered_call);
     254   
     255    // stop
     256    sysq.cancel();
     257}
     258
     259
     260
     261/**
     262 *  This subclass has some special member functions suitable for timing tests
     263 */
     264class SystemQueueTimingTest :
     265        public SystemQueueTest
     266{
     267public:
     268   
     269};
     270
     271
     272TEST_F(SystemQueueTimingTest, MultipleCalls)  /* TODO different name..? */
     273{
     274   
     275}
     276
Note: See TracChangeset for help on using the changeset viewer.