"Fossies" - the Fresh Open Source Software Archive

Member "cfengine-3.15.4/tests/unit/lastseen_test.c" (7 Jun 2021, 19108 Bytes) of package /linux/misc/cfengine-3.15.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include <test.h>
    2 
    3 #include <cf3.defs.h>
    4 #include <dbm_api.h>
    5 #include <lastseen.h>
    6 #include <item_lib.h>
    7 #include <misc_lib.h>                                          /* xsnprintf */
    8 #include <known_dirs.h>
    9 
   10 
   11 char CFWORKDIR[CF_BUFSIZE];
   12 
   13 void UpdateLastSawHost(const char *hostkey, const char *address,
   14                        bool incoming, time_t timestamp);
   15 
   16 /* For abbreviation of tests. */
   17 #define IP1 "127.0.0.121"
   18 #define IP2 "127.0.0.122"
   19 #define IP3 "127.0.0.123"
   20 #define KEY1 "SHA=key1"
   21 #define KEY2 "SHA=key2"
   22 #define KEY3 "SHA=key3"
   23 #define ACC LAST_SEEN_ROLE_ACCEPT
   24 #define DBHasStr(dbh, s)    HasKeyDB(dbh, s, strlen(s)+1)
   25 #define DBPutStr(dbh, k, s) WriteDB(dbh, k, s, strlen(s)+1)
   26 char tmpbuf[CF_BUFSIZE];
   27 #define DBGetStr(dbh, s)    (ReadDB(dbh, s, tmpbuf, sizeof(tmpbuf)) ? tmpbuf : NULL)
   28 
   29 
   30 static void tests_setup(void)
   31 {
   32     static char env[] = /* Needs to be static for putenv() */
   33         "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/lastseen_test.XXXXXX";
   34 
   35     char *workdir = strchr(env, '=') + 1; /* start of the path */
   36     assert(workdir - 1 && workdir[0] == '/');
   37 
   38     mkdtemp(workdir);
   39     strlcpy(CFWORKDIR, workdir, CF_BUFSIZE);
   40     putenv(env);
   41     mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO));
   42 }
   43 
   44 static void tests_teardown(void)
   45 {
   46     char cmd[CF_BUFSIZE];
   47     xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", GetStateDir());
   48     system(cmd);
   49     xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", GetWorkDir());
   50     system(cmd);
   51 }
   52 
   53 
   54 static void setup(void)
   55 {
   56     char cmd[CF_BUFSIZE];
   57     xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'/*", GetStateDir());
   58     system(cmd);
   59 }
   60 
   61 static void test_newentry(void)
   62 {
   63     setup();
   64 
   65     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 666);
   66 
   67     DBHandle *db;
   68     OpenDB(&db, dbid_lastseen);
   69 
   70     KeyHostSeen q;
   71     assert_int_equal(ReadDB(db, "qiSHA-12345", &q, sizeof(q)), true);
   72 
   73     assert_int_equal(q.lastseen, 666);
   74     assert_double_close(q.Q.q, 0.0);
   75     assert_double_close(q.Q.dq, 0.0);
   76     assert_double_close(q.Q.expect, 0.0);
   77     assert_double_close(q.Q.var, 0.0);
   78 
   79     assert_int_equal(ReadDB(db, "qoSHA-12345", &q, sizeof(q)), false);
   80 
   81     char address[CF_BUFSIZE];
   82     assert_int_equal(ReadDB(db, "kSHA-12345", address, sizeof(address)), true);
   83     assert_string_equal(address, "127.0.0.64");
   84 
   85     char hostkey[CF_BUFSIZE];
   86     assert_int_equal(ReadDB(db, "a127.0.0.64", hostkey, sizeof(hostkey)), true);
   87     assert_string_equal(hostkey, "SHA-12345");
   88 
   89     CloseDB(db);
   90 }
   91 
   92 static void test_update(void)
   93 {
   94     setup();
   95 
   96     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
   97     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 1110);
   98 
   99     DBHandle *db;
  100     OpenDB(&db, dbid_lastseen);
  101 
  102     KeyHostSeen q;
  103     assert_int_equal(ReadDB(db, "qiSHA-12345", &q, sizeof(q)), true);
  104 
  105     assert_int_equal(q.lastseen, 1110);
  106     assert_double_close(q.Q.q, 555.0);
  107     assert_double_close(q.Q.dq, 555.0);
  108     assert_double_close(q.Q.expect, 222.0);
  109     assert_double_close(q.Q.var, 123210.0);
  110 
  111     CloseDB(db);
  112 }
  113 
  114 static void test_reverse_missing(void)
  115 {
  116     setup();
  117 
  118     /* Check that resolution return false */
  119     char result[CF_BUFSIZE];
  120     assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), false);
  121 }
  122 
  123 static void test_reverse_conflict(void)
  124 {
  125     setup();
  126 
  127     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
  128 
  129     /* Overwrite reverse entry with different one. */
  130     DBHandle *db;
  131     OpenDB(&db, dbid_lastseen);
  132     assert_int_equal(WriteDB(db, "a127.0.0.64", "SHA-98765", strlen("SHA-98765") + 1), true);
  133 
  134     /* Check that resolution returns the last forced entry and is not bothered
  135      * by the inconsistency (despite outputing a warning). */
  136     char result[CF_BUFSIZE];
  137     assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), true);
  138     assert_string_equal(result, "SHA-98765");
  139 
  140     /* Both entries still exist despite inconsistency. */
  141     assert_int_equal(DBHasStr(db, "a127.0.0.64"), true);
  142     assert_int_equal(DBHasStr(db, "kSHA-12345"), true);
  143     /* And the inconsistency (missing entry) is not auto-fixed... :-( */
  144     assert_int_equal(DBHasStr(db, "kSHA-98765"), false);
  145 
  146     CloseDB(db);
  147 }
  148 
  149 static void test_reverse_missing_forward(void)
  150 {
  151     setup();
  152 
  153     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
  154 
  155     DBHandle *db;
  156     OpenDB(&db, dbid_lastseen);
  157 
  158     assert_int_equal(DeleteDB(db, "kSHA-12345"), true);
  159 
  160     /* Check that resolution returns true despite the missing entry (a warning
  161      * should be printed though). */
  162     char result[CF_BUFSIZE];
  163     assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), true);
  164 
  165     /* Entry still exists despite inconsistency. */
  166     assert_int_equal(DBHasStr(db, "a127.0.0.64"), true);
  167     /* And the inconsistency was not auto-fixed, entry is still missing. :-( */
  168     assert_int_equal(DBHasStr(db, "kSHA-12345"), false);
  169 
  170     CloseDB(db);
  171 }
  172 
  173 static void test_remove(void)
  174 {
  175     setup();
  176 
  177     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
  178     UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556);
  179 
  180     //RemoveHostFromLastSeen("SHA-12345");
  181     DeleteDigestFromLastSeen("SHA-12345", NULL, 0, true);
  182 
  183     DBHandle *db;
  184     OpenDB(&db, dbid_lastseen);
  185 
  186     assert_int_equal(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1), false);
  187     assert_int_equal(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1), false);
  188     assert_int_equal(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1), false);
  189     assert_int_equal(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1), false);
  190 
  191     CloseDB(db);
  192 }
  193 
  194 static void test_remove_no_a_entry(void)
  195 {
  196     setup();
  197 
  198     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
  199     UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556);
  200 
  201     DBHandle *db;
  202     OpenDB(&db, dbid_lastseen);
  203 
  204     assert_true(DeleteDB(db, "a127.0.0.64"));
  205     assert_false(DeleteDigestFromLastSeen("SHA-12345", NULL, 0, true));
  206     assert_true(DeleteDigestFromLastSeen("SHA-12345", NULL, 0, false));
  207 
  208     assert_false(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1));
  209     assert_false(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1));
  210     assert_false(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1));
  211     assert_false(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1));
  212 
  213     CloseDB(db);
  214 }
  215 
  216 static void test_remove_ip(void)
  217 {
  218     setup();
  219 
  220     UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555);
  221     UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556);
  222 
  223     char digest[CF_BUFSIZE];
  224     DeleteIpFromLastSeen("127.0.0.64", digest, sizeof(digest));
  225 
  226     DBHandle *db;
  227     OpenDB(&db, dbid_lastseen);
  228 
  229     assert_int_equal(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1), false);
  230     assert_int_equal(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1), false);
  231     assert_int_equal(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1), false);
  232     assert_int_equal(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1), false);
  233 
  234     CloseDB(db);
  235 }
  236 
  237 
  238 /* These tests can't be multi-threaded anyway. */
  239 static DBHandle *DBH;
  240 
  241 static void begin()
  242 {
  243     bool b = OpenDB(&DBH, dbid_lastseen);
  244     assert_int_equal(b, true);
  245 
  246     //*state = db;
  247 }
  248 static void end()
  249 {
  250     CloseDB(DBH);
  251     DBH = NULL;
  252 
  253     char cmd[CF_BUFSIZE];
  254     xsnprintf(cmd, sizeof(cmd), "rm -rf '%s'/*", GetStateDir());
  255     system(cmd);
  256 }
  257 
  258 
  259 /**
  260  * ============== DB CONSISTENCY TESTS ===============
  261  *
  262  * @WARNING TO CODER: think twice before you change this test. Changing it to
  263  *          accommodate your needs means that you change what "consistent"
  264  *          lastseen database is. Lastseen consistency was transcribed as this
  265  *          test after a lot of late-hours pondering.
  266  *
  267  *          Are you sure you want to continue? (y/n)
  268  */
  269 
  270 
  271 /**
  272  * ===== CONSISTENT CASES =====
  273  *
  274  *
  275  * 1. Everything is as expected here.
  276  *
  277  * aIP1  -> KEY1
  278  * kKEY1 -> IP1
  279  * aIP2  -> KEY2
  280  * kKEY2 -> IP2
  281  *
  282  * consistent_1a: Fill lastseen DB using the lastseen.h API.
  283  * consistent_1b: Same, but fill lastseen DB directly by use of dbm_api.h API.
  284  *
  285  *
  286  * 2. A host connecting from IP1, then connects from IP2.
  287  *
  288  * aIP1  -> KEY1
  289  * aIP2  -> KEY1
  290  * kKEY1 -> IP2
  291  *
  292  * consistent_2a: lastseen.h API.
  293  * consistent_2b: dbm_api.h API.
  294  *
  295  *
  296  * 3. The host at IP1 gets reinstalled and changes key from KEY1 to KEY2.
  297  *
  298  * aIP1  -> KEY2
  299  * kKEY1 -> aIP1
  300  * kKEY2 -> aIP1
  301  *
  302  * consistent_3a: lastseen.h API.
  303  * consistent_3b: dbm_api.h API.
  304  *
  305  *
  306  * 4. Many hosts can use the same key - a mess, but consistent
  307  *    (usecase by Bas van der Vlies in scientific clusters).
  308  *
  309  * aIP1  -> KEY1
  310  * aIP2  -> KEY1
  311  * aIP3  -> KEY1
  312  * kKEY1 -> aIP1
  313  *
  314  *
  315  * 5. Host connects from IP1 with KEY1, then changes address to IP2 keeps the
  316  *    same key, later changes key to KEY2.
  317  *
  318  * aIP1  -> KEY1
  319  * aIP2  -> KEY2
  320  * kKEY1 -> aIP2
  321  * kKEY2 -> aIP2
  322  *
  323  *
  324  * 6. Similar to previous but can't occur unless somebody restores an old key
  325  *    on a host. Still the db should be considered consistent.
  326  *
  327  * aIP1  -> KEY1
  328  * aIP2  -> KEY1
  329  * kKEY1 -> aIP2
  330  * kKEY2 -> aIP2
  331  *
  332  *
  333  * 7. Similarly messed-up but not inconsistent state.
  334  *
  335  * aIP1  -> KEY1
  336  * aIP2  -> KEY1
  337  * kKEY1 -> aIP2
  338  * kKEY2 -> aIP1
  339  *
  340  *
  341  */
  342 
  343 /*  TODO assert the two DBs from "a" and "b" tests are exactly the same! */
  344 
  345 static void test_consistent_1a()
  346 {
  347     LastSaw1(IP1, KEY1, ACC);
  348     LastSaw1(IP2, KEY2, ACC);
  349 
  350     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  351     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY2);
  352     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP1);
  353     assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2);
  354 
  355     assert_int_equal(IsLastSeenCoherent(), true);
  356 }
  357 static void test_consistent_1b()
  358 {
  359     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  360     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true);
  361     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true);
  362     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true);
  363 
  364     assert_int_equal(IsLastSeenCoherent(), true);
  365 }
  366 static void test_consistent_2a()
  367 {
  368     LastSaw1(IP1, KEY1, ACC);
  369     LastSaw1(IP2, KEY1, ACC);
  370 
  371     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  372     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1);
  373     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2);
  374 
  375     assert_int_equal(IsLastSeenCoherent(), true);
  376 }
  377 static void test_consistent_2b()
  378 {
  379     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  380     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true);
  381     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  382 
  383     assert_int_equal(IsLastSeenCoherent(), true);
  384 }
  385 static void test_consistent_3a()
  386 {
  387     LastSaw1(IP1, KEY1, ACC);
  388     LastSaw1(IP1, KEY2, ACC);
  389 
  390     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY2);
  391     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP1);
  392     assert_string_equal(DBGetStr(DBH, "k"KEY2), IP1);
  393 
  394     assert_int_equal(IsLastSeenCoherent(), true);
  395 }
  396 static void test_consistent_3b()
  397 {
  398     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true);
  399     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true);
  400     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP1), true);
  401 
  402     assert_int_equal(IsLastSeenCoherent(), true);
  403 }
  404 static void test_consistent_4a()
  405 {
  406     LastSaw1(IP1, KEY1, ACC);
  407     LastSaw1(IP2, KEY1, ACC);
  408     LastSaw1(IP3, KEY1, ACC);
  409 
  410     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  411     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1);
  412     assert_string_equal(DBGetStr(DBH, "a"IP3), KEY1);
  413     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP3);
  414 
  415     assert_int_equal(IsLastSeenCoherent(), true);
  416 }
  417 static void test_consistent_4b()
  418 {
  419     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  420     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true);
  421     assert_int_equal(DBPutStr(DBH, "a"IP3, KEY1), true);
  422     /* Just a bit different than what the lastseen API created in the 4a case,
  423      * but still consistent. */
  424     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true);
  425 
  426     assert_int_equal(IsLastSeenCoherent(), true);
  427 }
  428 static void test_consistent_5a()
  429 {
  430     LastSaw1(IP1, KEY1, ACC);
  431     LastSaw1(IP2, KEY1, ACC);
  432     LastSaw1(IP2, KEY2, ACC);
  433 
  434     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  435     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY2);
  436     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2);
  437     assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2);
  438 
  439     assert_int_equal(IsLastSeenCoherent(), true);
  440 }
  441 static void test_consistent_5b()
  442 {
  443     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  444     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true);
  445     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  446     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true);
  447 
  448     assert_int_equal(IsLastSeenCoherent(), true);
  449 }
  450 static void test_consistent_6a()
  451 {
  452     LastSaw1(IP1, KEY1, ACC);                    /* initial bootstrap */
  453     LastSaw1(IP2, KEY1, ACC);                    /* move to new IP */
  454     LastSaw1(IP2, KEY2, ACC);                    /* issue new key */
  455     LastSaw1(IP2, KEY1, ACC);                    /* restore old key */
  456 
  457     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  458     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1);
  459     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2);
  460     assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2);
  461 
  462     assert_int_equal(IsLastSeenCoherent(), true);
  463 }
  464 static void test_consistent_6b()
  465 {
  466     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  467     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true);
  468     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  469     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true);
  470 
  471     assert_int_equal(IsLastSeenCoherent(), true);
  472 }
  473 /**
  474  * @NOTE I haven't been able to get the consistent_7 case with regular
  475  *       dbm_api.h calls. Maybe it should be considered inconsistent state of
  476  *       the db?
  477  */
  478 /*
  479 static void test_consistent_7a()
  480 {
  481     LastSaw1(IP2, KEY1, ACC);
  482     LastSaw1(IP1, KEY2, ACC);
  483     LastSaw1(IP2, KEY1, ACC);
  484     LastSaw1(IP1, KEY1, ACC);
  485 
  486     assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1);
  487     assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1);
  488     assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2);
  489     assert_string_equal(DBGetStr(DBH, "k"KEY2), IP1);
  490 
  491     assert_int_equal(IsLastSeenCoherent(), true);
  492 }
  493 */
  494 static void test_consistent_7b()
  495 {
  496     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  497     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true);
  498     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  499     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP1), true);
  500 
  501     assert_int_equal(IsLastSeenCoherent(), true);
  502 }
  503 
  504 
  505 /**
  506  * ===== INCONSISTENT CASES =====
  507  * Should never happen if our software is bug-free!
  508  *
  509  *
  510  * 1. KEY2 appears as a value but not "kKEY2" as a key.
  511  *
  512  * aIP1  -> KEY2
  513  *
  514  *
  515  * 2. Same case, a bit more complex example.
  516  *
  517  * aIP1  -> KEY1
  518  * aIP2  -> KEY2
  519  * aKEY1 -> IP1
  520  *
  521  *
  522  * 3. IP2 appears as a value but not "aIP2" as a key.
  523  *
  524  * kKEY1 -> IP2
  525  *
  526  *
  527  * 4. Same case, a bit more complex example.
  528  *
  529  * aIP1  -> KEY1
  530  * kKEY1 -> aIP1
  531  * kKEY2 -> aIP2
  532  *
  533  *
  534  * 5. The two previous cases at the same time!
  535  *
  536  * kKEY1 -> IP2
  537  * aIP1  -> KEY2
  538  *
  539  *
  540  * 6. Same, a bit more complex example.
  541  *
  542  * aIP1  -> KEY1
  543  * aIP3  -> KEY2
  544  * kKEY1 -> IP2
  545  * kKEY3 -> IP2
  546  *
  547  */
  548 
  549 static void test_inconsistent_1()
  550 {
  551     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true);
  552 
  553     assert_int_equal(IsLastSeenCoherent(), false);
  554 }
  555 static void test_inconsistent_2()
  556 {
  557     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  558     assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true);
  559     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true);
  560 
  561     assert_int_equal(IsLastSeenCoherent(), false);
  562 }
  563 static void test_inconsistent_3()
  564 {
  565     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  566 
  567     assert_int_equal(IsLastSeenCoherent(), false);
  568 }
  569 static void test_inconsistent_4()
  570 {
  571     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  572     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true);
  573     assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true);
  574 
  575     assert_int_equal(IsLastSeenCoherent(), false);
  576 }
  577 static void test_inconsistent_5()
  578 {
  579     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  580     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true);
  581 
  582     assert_int_equal(IsLastSeenCoherent(), false);
  583 }
  584 static void test_inconsistent_6()
  585 {
  586     assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true);
  587     assert_int_equal(DBPutStr(DBH, "a"IP3, KEY2), true);
  588     assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true);
  589     assert_int_equal(DBPutStr(DBH, "k"KEY3, IP2), true);
  590 
  591     assert_int_equal(IsLastSeenCoherent(), false);
  592 }
  593 
  594 
  595 
  596 /* TODO run lastseen consistency checks after every cf-serverd *acceptance*
  597  *      test, deployment test, and stress test! */
  598 
  599 
  600 
  601 int main()
  602 {
  603     tests_setup();
  604 
  605     const UnitTest tests[] =
  606         {
  607             unit_test(test_newentry),
  608             unit_test(test_update),
  609             unit_test(test_reverse_missing),
  610             unit_test(test_reverse_conflict),
  611             unit_test(test_reverse_missing_forward),
  612             unit_test(test_remove),
  613             unit_test(test_remove_no_a_entry),
  614             unit_test(test_remove_ip),
  615 
  616             unit_test_setup_teardown(test_consistent_1a, begin, end),
  617             unit_test_setup_teardown(test_consistent_1b, begin, end),
  618             unit_test_setup_teardown(test_consistent_2a, begin, end),
  619             unit_test_setup_teardown(test_consistent_2b, begin, end),
  620             unit_test_setup_teardown(test_consistent_3a, begin, end),
  621             unit_test_setup_teardown(test_consistent_3b, begin, end),
  622             unit_test_setup_teardown(test_consistent_4a, begin, end),
  623             unit_test_setup_teardown(test_consistent_4b, begin, end),
  624             unit_test_setup_teardown(test_consistent_5a, begin, end),
  625             unit_test_setup_teardown(test_consistent_5b, begin, end),
  626             unit_test_setup_teardown(test_consistent_6a, begin, end),
  627             unit_test_setup_teardown(test_consistent_6b, begin, end),
  628 //            unit_test_setup_teardown(test_consistent_7a, begin, end),
  629             unit_test_setup_teardown(test_consistent_7b, begin, end),
  630             unit_test_setup_teardown(test_inconsistent_1, begin, end),
  631             unit_test_setup_teardown(test_inconsistent_2, begin, end),
  632             unit_test_setup_teardown(test_inconsistent_3, begin, end),
  633             unit_test_setup_teardown(test_inconsistent_4, begin, end),
  634             unit_test_setup_teardown(test_inconsistent_5, begin, end),
  635             unit_test_setup_teardown(test_inconsistent_6, begin, end),
  636         };
  637 
  638     PRINT_TEST_BANNER();
  639     int ret = run_tests(tests);
  640 
  641     tests_teardown();
  642 
  643     return ret;
  644 }
  645 
  646 /* STUBS */
  647 
  648 void FatalError(ARG_UNUSED char *s, ...)
  649 {
  650     fail();
  651     exit(42);
  652 }
  653 
  654 HashMethod CF_DEFAULT_DIGEST;
  655 pthread_mutex_t *cft_output;
  656 char VIPADDRESS[CF_MAX_IP_LEN];
  657 RSA *PUBKEY;
  658 bool MINUSF;
  659 
  660 char *HashPrintSafe(ARG_UNUSED char *dst, ARG_UNUSED size_t dst_size,
  661                     ARG_UNUSED const unsigned char *digest,
  662                     ARG_UNUSED HashMethod type, ARG_UNUSED bool use_prefix)
  663 {
  664     fail();
  665 }
  666 
  667 void HashPubKey(ARG_UNUSED const RSA *key,
  668                 ARG_UNUSED unsigned char digest[EVP_MAX_MD_SIZE + 1],
  669                 ARG_UNUSED HashMethod type)
  670 {
  671     fail();
  672 }