LCOV - code coverage report
Current view: top level - tests/ctest - test_opmphm_predictor.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 140 141 99.3 %
Date: 2019-09-12 12:28:41 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see doc/LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #include <opmphmpredictor.c>
      10             : #include <tests_internal.h>
      11             : 
      12           2 : void test_internal_basic (void)
      13             : {
      14           2 :         OpmphmPredictor * op = opmphmPredictorNew ();
      15           2 :         exit_if_fail (op, "opmphmPredictorNew");
      16           2 :         succeed_if (!op->history, "history init");
      17           2 :         succeed_if (!op->lookupCount, "lookupCount init");
      18           2 :         succeed_if (!op->ksSize, "lookupCount init");
      19           2 :         succeed_if (op->size, "size init");
      20         256 :         for (size_t i = 0; i < op->size; ++i)
      21             :         {
      22         256 :                 succeed_if (!op->patternTable[i], "patternTable init");
      23             :         }
      24           2 :         opmphmPredictorDel (op);
      25           2 : }
      26             : 
      27           2 : void test_internal_nochange (void)
      28             : {
      29           2 :         OpmphmPredictor * op = opmphmPredictorNew ();
      30           2 :         exit_if_fail (op, "opmphmPredictorNew");
      31           2 :         const size_t n = 1000;
      32           2 :         succeed_if (!opmphmPredictor (op, n), "first prediction");
      33           2 :         succeed_if (op->lookupCount == 1, "lookupCount");
      34       36000 :         for (size_t i = 1; i < opmphmPredictorWorthOpmphm (n) * 3; ++i)
      35             :         {
      36             :                 // no opmphm
      37       35998 :                 succeed_if (!opmphmPredictorIncCountBinarySearch (op, n), "binary search usage");
      38       35998 :                 succeed_if (op->lookupCount == i + 1, "lookupCount");
      39             :         }
      40             :         // switch to opmphm
      41           2 :         succeed_if (opmphmPredictorIncCountBinarySearch (op, n), "hash usage");
      42           2 :         succeed_if (op->lookupCount == opmphmPredictorWorthOpmphm (n) * 3 + 1, "lookupCount");
      43           2 :         opmphmPredictorDel (op);
      44           2 : }
      45             : 
      46             : /**
      47             :  * @brief Switches the internal states of the OpmphmPredictor and checks switch.
      48             :  *
      49             :  * @param oldState old State
      50             :  * @param newState new State
      51             :  * @param op the OpmphmPredictor
      52             :  * @param n number of elements
      53             :  */
      54          18 : static void test_internal_change_whitebox_set_to_state (uint8_t oldState, uint8_t newState, OpmphmPredictor * op, size_t n)
      55             : {
      56             :         size_t setLookupCount;
      57          18 :         if (oldState == 0 && newState == 0)
      58             :         {
      59             :                 // not worth hashing
      60           4 :                 setLookupCount = opmphmPredictorWorthOpmphm (n);
      61             :         }
      62          14 :         else if (oldState == 3 && newState == 3)
      63             :         {
      64             :                 // worth hashing
      65           2 :                 setLookupCount = opmphmPredictorWorthOpmphm (n) + 1;
      66             :         }
      67          12 :         else if (oldState + 1 == newState)
      68             :         {
      69             :                 // worth hashing
      70           6 :                 setLookupCount = opmphmPredictorWorthOpmphm (n) + 1;
      71             :         }
      72           6 :         else if (oldState == newState + 1)
      73             :         {
      74             :                 // not worth hashing
      75           6 :                 setLookupCount = opmphmPredictorWorthOpmphm (n);
      76             :         }
      77             :         else
      78             :         {
      79           0 :                 exit_if_fail (0, "wrong usage");
      80             :         }
      81             :         /*
      82             :          * Set every entry in pattern table to state
      83             :          */
      84        9234 :         for (uint16_t testHistory = 0; testHistory <= opmphmPredictorHistoryMask; ++testHistory)
      85             :         {
      86        9216 :                 op->history = testHistory;
      87             :                 // set not worth to hash
      88        9216 :                 op->lookupCount = setLookupCount;
      89             :                 // between state 1 and 2 is the prediction reulst transition, and patterns interfere, thus no check
      90        9216 :                 if (!((oldState == 1 && newState == 2) || (oldState == 2 && newState == 1)))
      91             :                 {
      92        7168 :                         if (newState < 2)
      93             :                         {
      94        4096 :                                 succeed_if (!opmphmPredictor (op, n), "binary search usage");
      95             :                         }
      96             :                         else
      97             :                         {
      98        3072 :                                 succeed_if (opmphmPredictor (op, n), "hash usage");
      99             :                         }
     100             :                 }
     101             :                 else
     102             :                 {
     103             :                         // no ckeck
     104        2048 :                         opmphmPredictor (op, n);
     105             :                 }
     106        9216 :                 succeed_if (op->lookupCount == 1, "lookupCount");
     107             :         }
     108             :         // test pattern
     109        2304 :         for (size_t i = 0; i < op->size; ++i)
     110             :         {
     111        2304 :                 if (newState == 0)
     112             :                 {
     113         768 :                         succeed_if (op->patternTable[i] == 0x0, "patternTable state 0"); // 0x0 is 00000000 all 4 states per byte to 0
     114             :                 }
     115        1536 :                 else if (newState == 1)
     116             :                 {
     117         512 :                         succeed_if (op->patternTable[i] == 0x55, "patternTable state 1"); // 0x55 is 01010101 all 4 states  per byte to 1
     118             :                 }
     119        1024 :                 else if (newState == 2)
     120             :                 {
     121         512 :                         succeed_if (op->patternTable[i] == 0xAA, "patternTable state 2"); // 0xAA is 10101010 all 4 states per byte to 2
     122             :                 }
     123         512 :                 else if (newState == 3)
     124             :                 {
     125         512 :                         succeed_if (op->patternTable[i] == 0xFF, "patternTable state 3"); // 0xFF is 11111111 all 4 states per byte to 3
     126             :                 }
     127             :         }
     128          18 : }
     129             : 
     130             : 
     131           2 : void test_internal_change_whitebox (void)
     132             : {
     133           2 :         OpmphmPredictor * op = opmphmPredictorNew ();
     134           2 :         exit_if_fail (op, "opmphmPredictorNew");
     135           2 :         const size_t n = 1000;
     136             :         // inform predictor about size
     137           2 :         op->ksSize = n;
     138             :         // start state is 0
     139           2 :         test_internal_change_whitebox_set_to_state (0, 0, op, n);
     140           2 :         test_internal_change_whitebox_set_to_state (0, 1, op, n);
     141           2 :         test_internal_change_whitebox_set_to_state (1, 2, op, n);
     142           2 :         test_internal_change_whitebox_set_to_state (2, 3, op, n);
     143           2 :         test_internal_change_whitebox_set_to_state (3, 3, op, n);
     144           2 :         test_internal_change_whitebox_set_to_state (3, 2, op, n);
     145           2 :         test_internal_change_whitebox_set_to_state (2, 1, op, n);
     146           2 :         test_internal_change_whitebox_set_to_state (1, 0, op, n);
     147           2 :         test_internal_change_whitebox_set_to_state (0, 0, op, n);
     148             : 
     149           2 :         opmphmPredictorDel (op);
     150           2 : }
     151             : 
     152             : 
     153           2 : void test_ks_flag (void)
     154             : {
     155           2 :         KeySet * ks = ksNew (10, KS_END);
     156           2 :         succeed_if (ks->flags & KS_FLAG_NAME_CHANGE, "flag not set at fresh ks");
     157             : 
     158           2 :         KeySet * copy = ksDup (ks);
     159           2 :         exit_if_fail (copy, "copy");
     160           2 :         succeed_if (copy->flags & KS_FLAG_NAME_CHANGE, "flag not set at copy ks");
     161           2 :         ksDel (copy);
     162             : 
     163           2 :         copy = ksDeepDup (ks);
     164           2 :         exit_if_fail (copy, "copy");
     165           2 :         succeed_if (copy->flags & KS_FLAG_NAME_CHANGE, "flag not set at copy ks");
     166           2 :         ksDel (copy);
     167             : 
     168           2 :         copy = ksNew (0, KS_END);
     169           2 :         succeed_if (ksCopy (copy, ks) == 1, "copy");
     170           2 :         succeed_if (copy->flags & KS_FLAG_NAME_CHANGE, "flag not set at copy ks");
     171           2 :         ksDel (copy);
     172             : 
     173           2 :         ksDel (ks);
     174           2 : }
     175             : 
     176             : 
     177           2 : void test_ks (void)
     178             : {
     179             :         Key * found;
     180             : 
     181             :         // create keyset just under opmphmPredictorActionLimit
     182           2 :         KeySet * ks = ksNew (opmphmPredictorActionLimit, KS_END);
     183             :         char name[11]; // "/test" + "10000" + "\0"
     184        1200 :         for (size_t i = 0; i < opmphmPredictorActionLimit; ++i)
     185             :         {
     186        1198 :                 snprintf (name, 11, "/test%zu", i);
     187        1198 :                 succeed_if (ksAppendKey (ks, keyNew (name, KEY_END)) > 0, "ksAppendKey failed");
     188             :         }
     189             : 
     190             :         // predictor under limit
     191           2 :         found = ksLookupByName (ks, "/test0", KDB_O_NONE);
     192           2 :         succeed_if (found, "key found");
     193           2 :         exit_if_fail (!ks->opmphmPredictor, "predictor here");
     194             : 
     195             :         // append to be over opmphmPredictorActionLimit
     196           2 :         snprintf (name, 11, "/test%zu", opmphmPredictorActionLimit);
     197           2 :         succeed_if (ksAppendKey (ks, keyNew (name, KEY_END)) > 0, "ksAppendKey failed");
     198             : 
     199             :         // predictor over limit
     200           2 :         found = ksLookupByName (ks, "/test0", KDB_O_NOCASCADING);
     201           2 :         succeed_if (found, "key found");
     202           2 :         exit_if_fail (ks->opmphmPredictor, "predictor not here");
     203             : 
     204             :         // overrule with binary search
     205           2 :         found = ksLookupByName (ks, "/test0", KDB_O_BINSEARCH | KDB_O_NOCASCADING);
     206           2 :         succeed_if (found, "key found");
     207             : 
     208           2 :         succeed_if (ks->opmphmPredictor->lookupCount == 1, "predictor touched");
     209           2 :         succeed_if (ks->opmphmPredictor->history == 0, "predictor touched");
     210             : 
     211             :         // overrule with OPMPHM
     212           2 :         found = ksLookupByName (ks, "/test0", KDB_O_OPMPHM);
     213           2 :         succeed_if (found, "key found");
     214             : 
     215           2 :         succeed_if (ks->opmphmPredictor->lookupCount == 1, "predictor touched");
     216           2 :         succeed_if (ks->opmphmPredictor->history == 0, "predictor touched");
     217             : 
     218             :         // use predictor again
     219           2 :         found = ksLookupByName (ks, "/test0", KDB_O_NONE | KDB_O_NOCASCADING);
     220           2 :         succeed_if (found, "key found");
     221           2 :         succeed_if (ks->opmphmPredictor->lookupCount == 2, "predictor not touched");
     222             : 
     223             :         // copy
     224           2 :         KeySet * copy = ksDup (ks);
     225           2 :         exit_if_fail (copy, "copy");
     226           2 :         succeed_if (copy->opmphmPredictor->lookupCount == ks->opmphmPredictor->lookupCount, "copy predictor lookupCount");
     227           2 :         succeed_if (copy->opmphmPredictor->history == ks->opmphmPredictor->history, "copy predictor history");
     228           2 :         succeed_if (copy->opmphmPredictor->ksSize == ks->opmphmPredictor->ksSize, "copy predictor ksSize");
     229           2 :         ksDel (copy);
     230             : 
     231           2 :         copy = ksDeepDup (ks);
     232           2 :         exit_if_fail (copy, "copy");
     233           2 :         succeed_if (copy->opmphmPredictor->lookupCount == ks->opmphmPredictor->lookupCount, "copy predictor lookupCount");
     234           2 :         succeed_if (copy->opmphmPredictor->history == ks->opmphmPredictor->history, "copy predictor history");
     235           2 :         succeed_if (copy->opmphmPredictor->ksSize == ks->opmphmPredictor->ksSize, "copy predictor ksSize");
     236           2 :         ksDel (copy);
     237             : 
     238           2 :         copy = ksNew (0, KS_END);
     239           2 :         succeed_if (ksCopy (copy, ks) == 1, "copy");
     240           2 :         succeed_if (copy->opmphmPredictor->lookupCount == ks->opmphmPredictor->lookupCount, "copy predictor lookupCount");
     241           2 :         succeed_if (copy->opmphmPredictor->history == ks->opmphmPredictor->history, "copy predictor history");
     242           2 :         succeed_if (copy->opmphmPredictor->ksSize == ks->opmphmPredictor->ksSize, "copy predictor ksSize");
     243           2 :         ksDel (copy);
     244             : 
     245           2 :         ksDel (ks);
     246           2 : }
     247             : 
     248             : 
     249           2 : int main (int argc, char ** argv)
     250             : {
     251           2 :         printf ("OPMPHM PREDICTOR      TESTS\n");
     252           2 :         printf ("==================\n\n");
     253             : 
     254           2 :         init (argc, argv);
     255             : 
     256           2 :         test_internal_basic ();
     257           2 :         test_internal_nochange ();
     258           2 :         test_internal_change_whitebox ();
     259           2 :         test_ks_flag ();
     260           2 :         test_ks ();
     261             : 
     262           2 :         print_result ("test_opmphm_predictor");
     263             : 
     264           2 :         return nbError;
     265             : }

Generated by: LCOV version 1.13