LCOV - code coverage report
Current view: top level - vcl/qa/cppunit - timer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 123 126 97.6 %
Date: 2015-06-13 12:38:46 Functions: 35 43 81.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : /*
      10             :  * Timers are evil beasties across platforms ...
      11             :  */
      12             : 
      13             : #include <test/bootstrapfixture.hxx>
      14             : 
      15             : #include <osl/thread.hxx>
      16             : #include <salhelper/thread.hxx>
      17             : 
      18             : #include <vcl/timer.hxx>
      19             : #include <vcl/idle.hxx>
      20             : #include <vcl/svapp.hxx>
      21             : #include "svdata.hxx"
      22             : #include "salinst.hxx"
      23             : 
      24             : // #define TEST_WATCHDOG
      25             : 
      26             : /// Avoid our timer tests just wedging the build if they fail.
      27           0 : class WatchDog : public osl::Thread
      28             : {
      29             :     sal_Int32 mnSeconds;
      30             : public:
      31           1 :     explicit WatchDog(sal_Int32 nSeconds) :
      32             :         Thread(),
      33           1 :         mnSeconds( nSeconds )
      34             :     {
      35           1 :         create();
      36           1 :     }
      37           1 :     virtual void SAL_CALL run() SAL_OVERRIDE
      38             :     {
      39             :         TimeValue aWait;
      40           1 :         aWait.Seconds = mnSeconds;
      41           1 :         aWait.Nanosec = 1000000; // +1ms
      42           1 :         osl::Thread::wait( aWait );
      43           0 :         CPPUNIT_ASSERT_MESSAGE("watchdog triggered", false);
      44           0 :     }
      45             : };
      46             : 
      47           1 : static WatchDog aWatchDog( 10 /* 10 secs should be enough */);
      48             : 
      49          12 : class TimerTest : public test::BootstrapFixture
      50             : {
      51             : public:
      52           6 :     TimerTest() : BootstrapFixture(true, false) {}
      53             : 
      54             :     void testIdleMainloop();
      55             :     void testIdle();
      56             : #ifdef TEST_WATCHDOG
      57             :     void testWatchdog();
      58             : #endif
      59             :     void testDurations();
      60             :     void testAutoTimer();
      61             :     void testRecursiveTimer();
      62             :     void testSlowTimerCallback();
      63             : 
      64           2 :     CPPUNIT_TEST_SUITE(TimerTest);
      65           1 :     CPPUNIT_TEST(testIdle);
      66           1 :     CPPUNIT_TEST(testIdleMainloop);
      67             : #ifdef TEST_WATCHDOG
      68             :     CPPUNIT_TEST(testWatchdog);
      69             : #endif
      70           1 :     CPPUNIT_TEST(testDurations);
      71           1 :     CPPUNIT_TEST(testAutoTimer);
      72           1 :     CPPUNIT_TEST(testRecursiveTimer);
      73           1 :     CPPUNIT_TEST(testSlowTimerCallback);
      74             : 
      75           5 :     CPPUNIT_TEST_SUITE_END();
      76             : };
      77             : 
      78             : #ifdef TEST_WATCHDOG
      79             : void TimerTest::testWatchdog()
      80             : {
      81             :     // out-wait the watchdog.
      82             :     TimeValue aWait;
      83             :     aWait.Seconds = 12;
      84             :     aWait.Nanosec = 0;
      85             :     osl::Thread::wait( aWait );
      86             : }
      87             : #endif
      88             : 
      89             : // --------------------------------------------------------------------
      90             : 
      91           2 : class IdleBool : public Idle
      92             : {
      93             :     bool &mrBool;
      94             : public:
      95           2 :     explicit IdleBool( bool &rBool ) :
      96           2 :         Idle(), mrBool( rBool )
      97             :     {
      98           2 :         SetPriority( SchedulerPriority::LOWEST );
      99           2 :         Start();
     100           2 :         mrBool = false;
     101           2 :     }
     102           2 :     virtual void Invoke() SAL_OVERRIDE
     103             :     {
     104           2 :         mrBool = true;
     105           2 :         Application::EndYield();
     106           2 :     }
     107             : };
     108             : 
     109           1 : void TimerTest::testIdle()
     110             : {
     111           1 :     bool bTriggered = false;
     112           1 :     IdleBool aTest( bTriggered );
     113           1 :     Scheduler::ProcessTaskScheduling(false);
     114           1 :     CPPUNIT_ASSERT_MESSAGE("idle triggered", bTriggered);
     115           1 : }
     116             : 
     117             : // tdf#91727
     118           1 : void TimerTest::testIdleMainloop()
     119             : {
     120           1 :     bool bTriggered = false;
     121           1 :     IdleBool aTest( bTriggered );
     122           6 :     while (!bTriggered)
     123             :     {
     124           4 :         ImplSVData* pSVData = ImplGetSVData();
     125             : 
     126             :         // can't test this via Application::Yield since this
     127             :         // also processes all tasks directly via the scheduler.
     128           4 :         pSVData->maAppData.mnDispatchLevel++;
     129           4 :         pSVData->mpDefInst->Yield( true, false );
     130           4 :         pSVData->maAppData.mnDispatchLevel--;
     131             :     }
     132           1 :     CPPUNIT_ASSERT_MESSAGE("mainloop idle triggered", bTriggered);
     133           1 : }
     134             : 
     135             : // --------------------------------------------------------------------
     136             : 
     137           4 : class TimerBool : public Timer
     138             : {
     139             :     bool &mrBool;
     140             : public:
     141           4 :     TimerBool( sal_uLong nMS, bool &rBool ) :
     142           4 :         Timer(), mrBool( rBool )
     143             :     {
     144           4 :         SetTimeout( nMS );
     145           4 :         Start();
     146           4 :         mrBool = false;
     147           4 :     }
     148           4 :     virtual void Invoke() SAL_OVERRIDE
     149             :     {
     150           4 :         mrBool = true;
     151           4 :         Application::EndYield();
     152           4 :     }
     153             : };
     154             : 
     155           1 : void TimerTest::testDurations()
     156             : {
     157             :     static const sal_uLong aDurations[] = { 0, 1, 500, 1000 };
     158           5 :     for (size_t i = 0; i < SAL_N_ELEMENTS( aDurations ); i++)
     159             :     {
     160           4 :         bool bDone = false;
     161           4 :         TimerBool aTimer( aDurations[i], bDone );
     162             :         // coverity[loop_top] - Application::Yield allows the timer to fire and toggle bDone
     163          19 :         while( !bDone )
     164             :         {
     165          11 :             Application::Yield();
     166             :         }
     167           4 :     }
     168           1 : }
     169             : 
     170             : // --------------------------------------------------------------------
     171             : 
     172           3 : class AutoTimerCount : public AutoTimer
     173             : {
     174             :     sal_Int32 &mrCount;
     175             : public:
     176           3 :     AutoTimerCount( sal_uLong nMS, sal_Int32 &rCount ) :
     177           3 :         AutoTimer(), mrCount( rCount )
     178             :     {
     179           3 :         SetTimeout( nMS );
     180           3 :         Start();
     181           3 :         mrCount = 0;
     182           3 :     }
     183         374 :     virtual void Invoke() SAL_OVERRIDE
     184             :     {
     185         374 :         mrCount++;
     186         374 :     }
     187             : };
     188             : 
     189           1 : void TimerTest::testAutoTimer()
     190             : {
     191           1 :     sal_Int32 nCount = 0;
     192           1 :     AutoTimerCount aCount(1, nCount);
     193        1071 :     while (nCount < 100) {
     194        1069 :         Application::Yield();
     195           1 :     }
     196           1 : }
     197             : 
     198             : // --------------------------------------------------------------------
     199             : 
     200           1 : class YieldTimer : public Timer
     201             : {
     202             : public:
     203           1 :     explicit YieldTimer( sal_uLong nMS ) : Timer()
     204             :     {
     205           1 :         SetTimeout( nMS );
     206           1 :         Start();
     207           1 :     }
     208           1 :     virtual void Invoke() SAL_OVERRIDE
     209             :     {
     210         101 :         for (int i = 0; i < 100; i++)
     211         100 :             Application::Yield();
     212           1 :     }
     213             : };
     214             : 
     215           1 : void TimerTest::testRecursiveTimer()
     216             : {
     217           1 :     sal_Int32 nCount = 0;
     218           1 :     YieldTimer aCount(5);
     219           2 :     AutoTimerCount aCountUp( 3, nCount );
     220             :     // coverity[loop_top] - Application::Yield allows the timer to fire and increment nCount
     221           5 :     while (nCount < 20)
     222           4 :         Application::Yield();
     223           1 : }
     224             : 
     225             : // --------------------------------------------------------------------
     226             : 
     227           1 : class SlowCallbackTimer : public Timer
     228             : {
     229             :     bool &mbSlow;
     230             : public:
     231           1 :     SlowCallbackTimer( sal_uLong nMS, bool &bBeenSlow ) :
     232           1 :         Timer(), mbSlow( bBeenSlow )
     233             :     {
     234           1 :         SetTimeout( nMS );
     235           1 :         Start();
     236           1 :         mbSlow = false;
     237           1 :     }
     238           1 :     virtual void Invoke() SAL_OVERRIDE
     239             :     {
     240             :         TimeValue aWait;
     241           1 :         aWait.Seconds = 1;
     242           1 :         aWait.Nanosec = 0;
     243           1 :         osl::Thread::wait( aWait );
     244           1 :         mbSlow = true;
     245           1 :     }
     246             : };
     247             : 
     248           1 : void TimerTest::testSlowTimerCallback()
     249             : {
     250           1 :     bool bBeenSlow = false;
     251           1 :     sal_Int32 nCount = 0;
     252           1 :     AutoTimerCount aHighFreq(1, nCount);
     253           2 :     SlowCallbackTimer aSlow(250, bBeenSlow);
     254             :     // coverity[loop_top] - Application::Yield allows the timer to fire and toggle bBeenSlow
     255         449 :     while (!bBeenSlow)
     256         447 :         Application::Yield();
     257             :     // coverity[loop_top] - Application::Yield allows the timer to fire and increment nCount
     258           2 :     while (nCount < 200)
     259           1 :         Application::Yield();
     260           1 : }
     261             : 
     262           1 : CPPUNIT_TEST_SUITE_REGISTRATION(TimerTest);
     263             : 
     264           4 : CPPUNIT_PLUGIN_IMPLEMENT();
     265             : 
     266             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11