LCOV - code coverage report
Current view: top level - src/bindings/io/test - test_idle.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 103 106 97.2 %
Date: 2019-09-12 12:28:41 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Tests for I/O bindings
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #include <stdio.h>
      11             : #include <stdlib.h>
      12             : #include <string.h>
      13             : 
      14             : #include <kdbhelper.h>
      15             : #include <tests.h>
      16             : 
      17             : #include "test.h"
      18             : #include <kdbio.h>
      19             : #include <kdbiotest.h>
      20             : 
      21             : #define IDLE_TEST_INTERVAL 1
      22             : #define IDLE_TEST_CONTROL_TIMES 3
      23             : #define IDLE_DIFF_WARNING_THRESHOLD 5
      24             : #define IDLE_DIFF_ERROR_THRESHOLD (IDLE_DIFF_WARNING_THRESHOLD * 100)
      25             : 
      26             : ElektraIoTestSuiteStop testStop;
      27             : 
      28             : int testCallbackCalled;
      29             : struct timespec testCallbackTimeStarted;
      30             : struct timespec testCallbackTimeCalled;
      31             : 
      32             : int testUpdateEnabledControlCalled;
      33             : int testUpdateEnabledProbeCalled;
      34             : ElektraIoIdleOperation * testUpdateEnabledIdleProbe;
      35             : ElektraIoInterface * testUpdateEnabledBinding;
      36             : 
      37             : int testRemoveControlCalled;
      38             : int testRemoveProbeCalled;
      39             : ElektraIoIdleOperation * testRemoveIdleProbe;
      40             : ElektraIoInterface * testRemoveBinding;
      41             : 
      42           0 : static void testIdleBasicsCallback (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
      43             : {
      44           0 :         yield_error ("should not be called");
      45           0 : }
      46             : 
      47           6 : static void testIdleBasics (ElektraIoTestSuiteCreateBinding createBinding)
      48             : {
      49           6 :         ElektraIoIdleOperation * idleOp = elektraIoNewIdleOperation (0, testIdleBasicsCallback, NULL);
      50             : 
      51           6 :         ElektraIoInterface * binding = createBinding ();
      52           6 :         succeed_if (elektraIoBindingAddIdle (binding, idleOp), "addIdle did not succeed");
      53           6 :         succeed_if (elektraIoBindingAddIdle (binding, idleOp) == 0, "addIdle: should not be able to reassign operation to a binding");
      54             : 
      55           6 :         elektraIoIdleSetEnabled (idleOp, 1);
      56           6 :         succeed_if (elektraIoBindingUpdateIdle (idleOp), "updateIdle did not succeed");
      57             : 
      58           6 :         succeed_if (elektraIoBindingRemoveIdle (idleOp), "removeIdle did not succeed");
      59             : 
      60           6 :         succeed_if (elektraIoBindingAddIdle (binding, idleOp), "addIdle: should be able to assign operation after removal");
      61           6 :         succeed_if (elektraIoBindingRemoveIdle (idleOp), "removeIdle did not succeed");
      62           6 :         elektraIoBindingCleanup (binding);
      63           6 :         elektraFree (idleOp);
      64           6 : }
      65             : 
      66           6 : static void testIdleShouldCallbackImmediatelyProbe (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
      67             : {
      68           6 :         testCallbackCalled = 1;
      69           6 :         elektraIoTestSuiteUtilGetCurrentTime (&testCallbackTimeCalled);
      70           6 :         testStop ();
      71           6 : }
      72             : 
      73           6 : static void testIdleShouldCallbackImmediately (ElektraIoTestSuiteCreateBinding createBinding, ElektraIoTestSuiteStart start,
      74             :                                                ElektraIoTestSuiteStop stop)
      75             : {
      76           6 :         ElektraIoIdleOperation * idleOp = elektraIoNewIdleOperation (1, testIdleShouldCallbackImmediatelyProbe, NULL);
      77             : 
      78           6 :         ElektraIoInterface * binding = createBinding ();
      79           6 :         elektraIoBindingAddIdle (binding, idleOp);
      80             : 
      81           6 :         testStop = stop;
      82           6 :         testCallbackCalled = 0;
      83             : 
      84           6 :         elektraIoTestSuiteUtilGetCurrentTime (&testCallbackTimeStarted);
      85             : 
      86           6 :         start ();
      87             : 
      88           6 :         succeed_if (testCallbackCalled, "callback was not called");
      89             : 
      90           6 :         long diff = elektraIoTestSuiteUtilGetTimeDifference (testCallbackTimeStarted, testCallbackTimeCalled);
      91           6 :         int deviation = labs (IDLE_TEST_INTERVAL - diff);
      92           6 :         if (deviation > IDLE_DIFF_WARNING_THRESHOLD)
      93             :         {
      94           2 :                 printf ("testIdleShouldCallbackImmediately (warning): measured %ldms, expected %dms - deviation %dms.\n", diff,
      95             :                         IDLE_TEST_INTERVAL, deviation);
      96             :         }
      97           6 :         succeed_if (deviation <= IDLE_DIFF_ERROR_THRESHOLD, "idle timing not within error threshold");
      98             : 
      99           6 :         elektraIoBindingRemoveIdle (idleOp);
     100           6 :         elektraIoBindingCleanup (binding);
     101           6 :         elektraFree (idleOp);
     102           6 : }
     103             : 
     104          18 : static void testIdleShouldUpdateEnabledControl (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
     105             : {
     106          18 :         testUpdateEnabledControlCalled++;
     107             : 
     108             :         // Disable probe operation on second run
     109          18 :         if (testUpdateEnabledProbeCalled == IDLE_TEST_CONTROL_TIMES - 1)
     110             :         {
     111          10 :                 elektraIoIdleSetEnabled (testUpdateEnabledIdleProbe, 0);
     112          10 :                 elektraIoBindingUpdateIdle (testUpdateEnabledIdleProbe);
     113             :         }
     114             : 
     115             :         // Stop test when control limit was reached or probe was called twice
     116          18 :         if (testUpdateEnabledControlCalled == IDLE_TEST_CONTROL_TIMES || testUpdateEnabledProbeCalled > 2)
     117             :         {
     118           6 :                 testStop ();
     119             :         }
     120          18 : }
     121             : 
     122          12 : static void testIdleShouldUpdateEnabledProbe (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
     123             : {
     124          12 :         testUpdateEnabledProbeCalled++;
     125          12 : }
     126             : 
     127           6 : static void testIdleShouldUpdateEnabled (ElektraIoTestSuiteCreateBinding createBinding, ElektraIoTestSuiteStart start,
     128             :                                          ElektraIoTestSuiteStop stop)
     129             : {
     130           6 :         ElektraIoIdleOperation * idleControl = elektraIoNewIdleOperation (1, testIdleShouldUpdateEnabledControl, NULL);
     131             : 
     132           6 :         ElektraIoIdleOperation * idleProbe = elektraIoNewIdleOperation (1, testIdleShouldUpdateEnabledProbe, NULL);
     133             : 
     134           6 :         ElektraIoInterface * binding = createBinding ();
     135           6 :         elektraIoBindingAddIdle (binding, idleControl);
     136           6 :         elektraIoBindingAddIdle (binding, idleProbe);
     137             : 
     138           6 :         testStop = stop;
     139           6 :         testUpdateEnabledControlCalled = 0; // IDLE_TEST_CONTROL_TIMES;
     140           6 :         testUpdateEnabledProbeCalled = 0;
     141           6 :         testUpdateEnabledIdleProbe = idleProbe;
     142           6 :         testUpdateEnabledBinding = binding;
     143             : 
     144           6 :         start ();
     145             : 
     146           6 :         succeed_if (testUpdateEnabledProbeCalled > 0 && testUpdateEnabledProbeCalled <= 2, "idle callback was not disabled");
     147           6 :         succeed_if (testUpdateEnabledControlCalled == IDLE_TEST_CONTROL_TIMES,
     148             :                     "idle control callback was not called required amount of times");
     149             : 
     150           6 :         elektraIoBindingRemoveIdle (idleControl);
     151           6 :         elektraIoBindingRemoveIdle (idleProbe);
     152           6 :         elektraIoBindingCleanup (binding);
     153           6 :         elektraFree (idleControl);
     154           6 :         elektraFree (idleProbe);
     155           6 : }
     156             : 
     157          18 : static void testIdleShouldRemoveControl (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
     158             : {
     159          18 :         testRemoveControlCalled++;
     160             : 
     161             :         // Remove probe operation on first run
     162          18 :         if (testRemoveControlCalled == IDLE_TEST_CONTROL_TIMES - 1)
     163             :         {
     164           6 :                 elektraIoBindingRemoveIdle (testRemoveIdleProbe);
     165             :         }
     166             : 
     167          18 :         if (testRemoveControlCalled == IDLE_TEST_CONTROL_TIMES || testRemoveProbeCalled > 2)
     168             :         {
     169           6 :                 testStop ();
     170             :         }
     171          18 : }
     172             : 
     173          10 : static void testIdleShouldRemoveProbe (ElektraIoIdleOperation * idleOp ELEKTRA_UNUSED)
     174             : {
     175          10 :         testRemoveProbeCalled++;
     176          10 : }
     177             : 
     178           6 : static void testIdleShouldRemove (ElektraIoTestSuiteCreateBinding createBinding, ElektraIoTestSuiteStart start, ElektraIoTestSuiteStop stop)
     179             : {
     180           6 :         ElektraIoIdleOperation * idleControl = elektraIoNewIdleOperation (1, testIdleShouldRemoveControl, NULL);
     181             : 
     182           6 :         ElektraIoIdleOperation * idleProbe = elektraIoNewIdleOperation (1, testIdleShouldRemoveProbe, NULL);
     183             : 
     184           6 :         ElektraIoInterface * binding = createBinding ();
     185           6 :         elektraIoBindingAddIdle (binding, idleControl);
     186           6 :         elektraIoBindingAddIdle (binding, idleProbe);
     187             : 
     188           6 :         testStop = stop;
     189           6 :         testRemoveControlCalled = 0;
     190           6 :         testRemoveProbeCalled = 0;
     191           6 :         testRemoveIdleProbe = idleProbe;
     192           6 :         testRemoveBinding = binding;
     193             : 
     194           6 :         start ();
     195             : 
     196           6 :         succeed_if (testRemoveProbeCalled > 0 && testRemoveProbeCalled <= 2, "idle callback was not removed");
     197             : 
     198           6 :         succeed_if (testRemoveControlCalled == IDLE_TEST_CONTROL_TIMES, "idle control callback was not called required amount of times");
     199             : 
     200           6 :         elektraIoBindingRemoveIdle (idleControl);
     201           6 :         elektraIoBindingCleanup (binding);
     202           6 :         elektraFree (idleControl);
     203           6 :         elektraFree (idleProbe);
     204           6 : }
     205             : 
     206             : 
     207             : /**
     208             :  * Test idle functions of the I/O binding returned by createBinding.
     209             :  * Requires the following operations: Idle
     210             :  *
     211             :  * @param createBinding binding creation function
     212             :  * @param start         starts I/O operations
     213             :  * @param stop          stops I/O operations
     214             :  */
     215           6 : void elektraIoTestSuiteIdle (ElektraIoTestSuiteCreateBinding createBinding, ElektraIoTestSuiteStart start, ElektraIoTestSuiteStop stop)
     216             : {
     217           6 :         printf ("test idle\n");
     218             : 
     219           6 :         testIdleBasics (createBinding);
     220             : 
     221           6 :         testIdleShouldCallbackImmediately (createBinding, start, stop);
     222             : 
     223           6 :         testIdleShouldUpdateEnabled (createBinding, start, stop);
     224             : 
     225           6 :         testIdleShouldRemove (createBinding, start, stop);
     226           6 : }

Generated by: LCOV version 1.13