"Fossies" - the Fresh Open Source Software Archive

Member "vnstat-2.9/tests/database_tests.c" (16 Jan 2022, 24850 Bytes) of package /linux/misc/vnstat-2.9.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. See also the latest Fossies "Diffs" side-by-side code changes report for "database_tests.c": 2.8_vs_2.9.

    1 #include "common.h"
    2 #include "vnstat_tests.h"
    3 #include "database_tests.h"
    4 #include "dbaccess.h"
    5 #include "ifinfo.h"
    6 #include "dbsql.h"
    7 #include "dbshow.h"
    8 #include "dbxml.h"
    9 #include "dbjson.h"
   10 #include "cfg.h"
   11 #include "ibw.h"
   12 #include "fs.h"
   13 
   14 int writedb(DATA *data, const char *iface, const char *dirname, int newdb);
   15 int backupdb(const char *current, const char *backup);
   16 
   17 START_TEST(initdb_activates_database)
   18 {
   19     DATA data;
   20     initdb(&data);
   21     ck_assert_int_eq(data.active, 1);
   22 }
   23 END_TEST
   24 
   25 START_TEST(readdb_with_empty_file)
   26 {
   27     DATA data;
   28     disable_logprints();
   29     ck_assert_int_eq(clean_testdbdir(), 1);
   30     ck_assert_int_eq(create_zerosize_dbfile("existingdb"), 1);
   31     ck_assert_int_eq(readdb(&data, "existingdb", TESTDBDIR, 0), -1);
   32 }
   33 END_TEST
   34 
   35 START_TEST(readdb_with_empty_file_and_backup)
   36 {
   37     DATA data;
   38     disable_logprints();
   39     ck_assert_int_eq(clean_testdbdir(), 1);
   40     ck_assert_int_eq(create_zerosize_dbfile("existingdb"), 1);
   41     ck_assert_int_eq(create_zerosize_dbfile(".existingdb"), 1);
   42     ck_assert_int_eq(readdb(&data, "existingdb", TESTDBDIR, 0), -1);
   43 }
   44 END_TEST
   45 
   46 START_TEST(readdb_with_nonexisting_file)
   47 {
   48     DATA data;
   49     disable_logprints();
   50     strcpy(data.interface, "none");
   51     ck_assert_int_eq(clean_testdbdir(), 1);
   52     ck_assert_int_eq(readdb(&data, "existingdb", TESTDBDIR, 0), 1);
   53     ck_assert_str_eq(data.interface, "existingdb");
   54     ck_assert_str_eq(data.nick, "existingdb");
   55 }
   56 END_TEST
   57 
   58 START_TEST(readdb_with_existing_dbfile)
   59 {
   60     DATA data;
   61     initdb(&data);
   62     disable_logprints();
   63     strcpy(data.interface, "ethtest");
   64     ck_assert_int_eq(clean_testdbdir(), 1);
   65     ck_assert_int_eq(writedb(&data, "ethtest", TESTDBDIR, 1), 1);
   66     ck_assert_int_eq(check_dbfile_exists("ethtest", sizeof(DATA)), 1);
   67 
   68     strcpy(data.interface, "none");
   69     ck_assert_int_eq(readdb(&data, "ethtest", TESTDBDIR, 0), 0);
   70     ck_assert_str_eq(data.interface, "ethtest");
   71 }
   72 END_TEST
   73 
   74 START_TEST(readdb_with_existing_dbfile_and_max_name_length)
   75 {
   76     DATA data;
   77     initdb(&data);
   78     disable_logprints();
   79     strcpy(data.interface, "1234567890123456789012345678901");
   80     ck_assert_int_eq(clean_testdbdir(), 1);
   81     ck_assert_int_eq(writedb(&data, "1234567890123456789012345678901", TESTDBDIR, 1), 1);
   82     ck_assert_int_eq(check_dbfile_exists("1234567890123456789012345678901", sizeof(DATA)), 1);
   83 
   84     strcpy(data.interface, "none");
   85     ck_assert_int_eq(readdb(&data, "1234567890123456789012345678901", TESTDBDIR, 0), 0);
   86     ck_assert_str_eq(data.interface, "1234567890123456789012345678901");
   87 }
   88 END_TEST
   89 
   90 START_TEST(readdb_with_existing_dbfile_with_rename)
   91 {
   92     DATA data;
   93     initdb(&data);
   94     disable_logprints();
   95     strcpy(data.interface, "ethtest");
   96     strcpy(data.nick, "ethtest");
   97     ck_assert_int_eq(clean_testdbdir(), 1);
   98     ck_assert_int_eq(writedb(&data, "ethtest2", TESTDBDIR, 1), 1);
   99     ck_assert_int_eq(check_dbfile_exists("ethtest2", sizeof(DATA)), 1);
  100 
  101     strcpy(data.interface, "none");
  102     strcpy(data.nick, "none");
  103     ck_assert_int_eq(readdb(&data, "ethtest2", TESTDBDIR, 0), 0);
  104     ck_assert_str_eq(data.interface, "ethtest2");
  105     ck_assert_str_eq(data.nick, "ethtest2");
  106 }
  107 END_TEST
  108 
  109 START_TEST(readdb_with_existing_dbfile_and_over_max_name_length)
  110 {
  111     DATA data;
  112     initdb(&data);
  113     disable_logprints();
  114     strcpy(data.interface, "dummy");
  115     strcpy(data.nick, "dummy");
  116     ck_assert_int_eq(clean_testdbdir(), 1);
  117     ck_assert_int_eq(writedb(&data, "1234567890123456789012345678901XX", TESTDBDIR, 1), 1);
  118     ck_assert_int_eq(check_dbfile_exists("1234567890123456789012345678901XX", sizeof(DATA)), 1);
  119 
  120     strcpy(data.interface, "none");
  121     strcpy(data.nick, "none");
  122     ck_assert_int_eq(readdb(&data, "1234567890123456789012345678901XX", TESTDBDIR, 0), 0);
  123     ck_assert_str_eq(data.interface, "1234567890123456789012345678901");
  124     ck_assert_str_eq(data.nick, "1234567890123456789012345678901");
  125 }
  126 END_TEST
  127 
  128 START_TEST(validatedb_with_initdb)
  129 {
  130     DATA data;
  131     initdb(&data);
  132     strcpy(data.interface, "ethtest");
  133     ck_assert_int_eq(validatedb(&data), 1);
  134 }
  135 END_TEST
  136 
  137 START_TEST(validatedb_with_invalid_totals)
  138 {
  139     DATA data;
  140     initdb(&data);
  141     suppress_output();
  142     strcpy(data.interface, "ethtest");
  143     data.day[0].rx++;
  144     ck_assert_int_eq(validatedb(&data), 0);
  145 }
  146 END_TEST
  147 
  148 START_TEST(validatedb_with_top10_use)
  149 {
  150     DATA data;
  151     initdb(&data);
  152     suppress_output();
  153     strcpy(data.interface, "ethtest");
  154     data.top10[0].used = 1;
  155     data.top10[1].used = 1;
  156     data.top10[2].used = 1;
  157     data.top10[5].used = 1;
  158     ck_assert_int_eq(validatedb(&data), 0);
  159 }
  160 END_TEST
  161 
  162 START_TEST(database_outputs_do_not_crash)
  163 {
  164     int ret, i;
  165 
  166     ret = db_open_rw(1);
  167     ck_assert_int_eq(ret, 1);
  168     ret = db_addinterface("something");
  169     ck_assert_int_eq(ret, 1);
  170 
  171     for (i = 1; i < 100; i++) {
  172         ret = db_addtraffic_dated("something", (uint64_t)i * 1234, (uint64_t)i * 2345, (uint64_t)i * 85000);
  173         ck_assert_int_eq(ret, 1);
  174     }
  175 
  176     ret = db_setupdated("something", (time_t)i * 85000);
  177     ck_assert_int_eq(ret, 1);
  178 
  179     suppress_output();
  180 
  181     for (i = 0; i <= 4; i++) {
  182         cfg.ostyle = i;
  183         showdb("something", 0, "", "");
  184         showdb("something", 1, "", "");
  185         showdb("something", 2, "", "");
  186         showdb("something", 3, "", "");
  187         showdb("something", 4, "", "");
  188         showdb("something", 5, "", "");
  189         showdb("something", 6, "", "");
  190         showdb("something", 7, "", "");
  191         showdb("something", 8, "", "");
  192         showdb("something", 9, "", "");
  193         showdb("something", 10, "", "");
  194         showdb("something", 11, "", "");
  195         showdb("something", 12, "", "");
  196         showdb("nothing", 0, "", "");
  197     }
  198 
  199     xmlheader();
  200     showxml("something", 'd', "", "");
  201     showxml("something", 'm', "", "");
  202     showxml("something", 't', "", "");
  203     showxml("something", 'h', "", "");
  204     showxml("something", 'y', "", "");
  205     showxml("something", 'f', "", "");
  206     showxml("something", 'a', "", "");
  207     showxml("nothing", 'a', "", "");
  208     xmlfooter();
  209 
  210     jsonheader();
  211     showjson("something", 0, 'd', "", "");
  212     showjson("something", 0, 'm', "", "");
  213     showjson("something", 0, 't', "", "");
  214     showjson("something", 0, 'h', "", "");
  215     showjson("something", 0, 'y', "", "");
  216     showjson("something", 0, 'f', "", "");
  217     showjson("something", 1, 'a', "", "");
  218     showjson("nothing", 0, 'a', "", "");
  219     jsonfooter();
  220 
  221     ret = db_close();
  222     ck_assert_int_eq(ret, 1);
  223 }
  224 END_TEST
  225 
  226 START_TEST(database_outputs_do_not_crash_without_traffic)
  227 {
  228     int ret, i;
  229 
  230     ret = db_open_rw(1);
  231     ck_assert_int_eq(ret, 1);
  232     ret = db_addinterface("something");
  233     ck_assert_int_eq(ret, 1);
  234 
  235     ret = db_addtraffic_dated("something", 0, 0, 85000);
  236     ck_assert_int_eq(ret, 1);
  237 
  238     ret = db_setupdated("something", 85000);
  239     ck_assert_int_eq(ret, 1);
  240 
  241     suppress_output();
  242 
  243     for (i = 0; i <= 4; i++) {
  244         cfg.ostyle = i;
  245         showdb("something", 0, "", "");
  246         showdb("something", 1, "", "");
  247         showdb("something", 2, "", "");
  248         showdb("something", 3, "", "");
  249         showdb("something", 4, "", "");
  250         showdb("something", 5, "", "");
  251         showdb("something", 6, "", "");
  252         showdb("something", 7, "", "");
  253         showdb("something", 8, "", "");
  254         showdb("something", 9, "", "");
  255         showdb("something", 10, "", "");
  256         showdb("something", 11, "", "");
  257         showdb("something", 12, "", "");
  258         showdb("nothing", 0, "", "");
  259     }
  260 
  261     xmlheader();
  262     showxml("something", 'd', "", "");
  263     showxml("something", 'm', "", "");
  264     showxml("something", 't', "", "");
  265     showxml("something", 'h', "", "");
  266     showxml("something", 'y', "", "");
  267     showxml("something", 'f', "", "");
  268     showxml("something", 'a', "", "");
  269 
  270     xmlfooter();
  271 
  272     jsonheader();
  273     showjson("something", 0, 'd', "", "");
  274     showjson("something", 0, 'm', "", "");
  275     showjson("something", 0, 't', "", "");
  276     showjson("something", 0, 'h', "", "");
  277     showjson("something", 0, 'y', "", "");
  278     showjson("something", 0, 'f', "", "");
  279     showjson("something", 1, 'a', "", "");
  280     showjson("nothing", 0, 'a', "", "");
  281     jsonfooter();
  282 
  283     ret = db_close();
  284     ck_assert_int_eq(ret, 1);
  285 }
  286 END_TEST
  287 
  288 START_TEST(database_outputs_do_not_crash_without_data)
  289 {
  290     int ret, i;
  291 
  292     ret = db_open_rw(1);
  293     ck_assert_int_eq(ret, 1);
  294     ret = db_addinterface("something");
  295     ck_assert_int_eq(ret, 1);
  296 
  297     suppress_output();
  298 
  299     for (i = 0; i <= 4; i++) {
  300         cfg.ostyle = i;
  301         showdb("something", 0, "", "");
  302         showdb("something", 1, "", "");
  303         showdb("something", 2, "", "");
  304         showdb("something", 3, "", "");
  305         showdb("something", 4, "", "");
  306         showdb("something", 5, "", "");
  307         showdb("something", 6, "", "");
  308         showdb("something", 7, "", "");
  309         showdb("something", 8, "", "");
  310         showdb("something", 9, "", "");
  311         showdb("something", 10, "", "");
  312         showdb("something", 11, "", "");
  313         showdb("something", 12, "", "");
  314         showdb("nothing", 0, "", "");
  315     }
  316 
  317     xmlheader();
  318     showxml("something", 'd', "", "");
  319     showxml("something", 'm', "", "");
  320     showxml("something", 't', "", "");
  321     showxml("something", 'h', "", "");
  322     showxml("something", 'y', "", "");
  323     showxml("something", 'f', "", "");
  324     showxml("something", 'a', "", "");
  325 
  326     xmlfooter();
  327 
  328     jsonheader();
  329     showjson("something", 0, 'd', "", "");
  330     showjson("something", 0, 'm', "", "");
  331     showjson("something", 0, 't', "", "");
  332     showjson("something", 0, 'h', "", "");
  333     showjson("something", 0, 'y', "", "");
  334     showjson("something", 0, 'f', "", "");
  335     showjson("something", 1, 'a', "", "");
  336     showjson("nothing", 0, 'a', "", "");
  337     jsonfooter();
  338 
  339     ret = db_close();
  340     ck_assert_int_eq(ret, 1);
  341 }
  342 END_TEST
  343 
  344 START_TEST(database_outputs_do_not_crash_without_data_if_totals_are_wrong)
  345 {
  346     int ret, i;
  347 
  348     ret = db_open_rw(1);
  349     ck_assert_int_eq(ret, 1);
  350     ret = db_addinterface("something");
  351     ck_assert_int_eq(ret, 1);
  352 
  353     ret = db_settotal("something", 42, 84);
  354     ck_assert_int_eq(ret, 1);
  355 
  356     ret = db_setupdated("something", 85000);
  357     ck_assert_int_eq(ret, 1);
  358 
  359     suppress_output();
  360 
  361     for (i = 0; i <= 4; i++) {
  362         cfg.ostyle = i;
  363         showdb("something", 0, "", "");
  364         showdb("something", 1, "", "");
  365         showdb("something", 2, "", "");
  366         showdb("something", 3, "", "");
  367         showdb("something", 4, "", "");
  368         showdb("something", 5, "", "");
  369         showdb("something", 6, "", "");
  370         showdb("something", 7, "", "");
  371         showdb("something", 8, "", "");
  372         showdb("something", 9, "", "");
  373         showdb("something", 10, "", "");
  374         showdb("something", 11, "", "");
  375         showdb("something", 12, "", "");
  376         showdb("nothing", 0, "", "");
  377     }
  378 
  379     xmlheader();
  380     showxml("something", 'd', "", "");
  381     showxml("something", 'm', "", "");
  382     showxml("something", 't', "", "");
  383     showxml("something", 'h', "", "");
  384     showxml("something", 'y', "", "");
  385     showxml("something", 'f', "", "");
  386     showxml("something", 'a', "", "");
  387 
  388     xmlfooter();
  389 
  390     jsonheader();
  391     showjson("something", 0, 'd', "", "");
  392     showjson("something", 0, 'm', "", "");
  393     showjson("something", 0, 't', "", "");
  394     showjson("something", 0, 'h', "", "");
  395     showjson("something", 0, 'y', "", "");
  396     showjson("something", 0, 'f', "", "");
  397     showjson("something", 1, 'a', "", "");
  398     showjson("nothing", 0, 'a', "", "");
  399     jsonfooter();
  400 
  401     ret = db_close();
  402     ck_assert_int_eq(ret, 1);
  403 }
  404 END_TEST
  405 
  406 START_TEST(showbar_with_zero_len_is_nothing)
  407 {
  408     int len;
  409     suppress_output();
  410     len = showbar(1, 2, 3, 0);
  411     ck_assert_int_eq(len, 0);
  412 }
  413 END_TEST
  414 
  415 START_TEST(showbar_with_zero_max)
  416 {
  417     int len;
  418     suppress_output();
  419     len = showbar(0, 0, 0, 10);
  420     ck_assert_int_eq(len, 0);
  421 }
  422 END_TEST
  423 
  424 START_TEST(showbar_with_big_max_and_small_numbers)
  425 {
  426     int len;
  427     suppress_output();
  428     len = showbar(1, 2, 1000, 10);
  429     ck_assert_int_eq(len, 0);
  430 }
  431 END_TEST
  432 
  433 START_TEST(showbar_with_all_rx)
  434 {
  435     int pipe, len;
  436     char buffer[512];
  437     memset(&buffer, '\0', sizeof(buffer));
  438 
  439     cfg.rxchar[0] = 'r';
  440     cfg.txchar[0] = 't';
  441     pipe = pipe_output();
  442     len = showbar(1, 0, 1, 10);
  443     ck_assert_int_eq(len, 10);
  444     fflush(stdout);
  445 
  446     len = (int)read(pipe, buffer, 512);
  447     ck_assert_str_eq(buffer, "  rrrrrrrrrr");
  448 }
  449 END_TEST
  450 
  451 START_TEST(showbar_with_all_tx)
  452 {
  453     int pipe, len;
  454     char buffer[512];
  455     memset(&buffer, '\0', sizeof(buffer));
  456 
  457     cfg.rxchar[0] = 'r';
  458     cfg.txchar[0] = 't';
  459     pipe = pipe_output();
  460     len = showbar(0, 1, 1, 10);
  461     ck_assert_int_eq(len, 10);
  462     fflush(stdout);
  463 
  464     len = (int)read(pipe, buffer, 512);
  465     ck_assert_str_eq(buffer, "  tttttttttt");
  466 }
  467 END_TEST
  468 
  469 START_TEST(showbar_with_half_and_half)
  470 {
  471     int pipe, len;
  472     char buffer[512];
  473     memset(&buffer, '\0', sizeof(buffer));
  474 
  475     cfg.rxchar[0] = 'r';
  476     cfg.txchar[0] = 't';
  477     pipe = pipe_output();
  478     len = showbar(1, 1, 2, 10);
  479     ck_assert_int_eq(len, 10);
  480     fflush(stdout);
  481 
  482     len = (int)read(pipe, buffer, 512);
  483     ck_assert_str_eq(buffer, "  rrrrrttttt");
  484 }
  485 END_TEST
  486 
  487 START_TEST(showbar_with_one_tenth)
  488 {
  489     int pipe, len;
  490     char buffer[512];
  491     memset(&buffer, '\0', sizeof(buffer));
  492 
  493     cfg.rxchar[0] = 'r';
  494     cfg.txchar[0] = 't';
  495     pipe = pipe_output();
  496     len = showbar(1, 9, 10, 10);
  497     ck_assert_int_eq(len, 10);
  498     fflush(stdout);
  499 
  500     len = (int)read(pipe, buffer, 512);
  501     ck_assert_str_eq(buffer, "  rttttttttt");
  502 }
  503 END_TEST
  504 
  505 START_TEST(showbar_with_small_rx_shows_all_tx)
  506 {
  507     int pipe, len;
  508     char buffer[512];
  509     memset(&buffer, '\0', sizeof(buffer));
  510 
  511     cfg.rxchar[0] = 'r';
  512     cfg.txchar[0] = 't';
  513     pipe = pipe_output();
  514     len = showbar(1, 1000, 1001, 10);
  515     ck_assert_int_eq(len, 10);
  516     fflush(stdout);
  517 
  518     len = (int)read(pipe, buffer, 512);
  519     ck_assert_str_eq(buffer, "  tttttttttt");
  520 }
  521 END_TEST
  522 
  523 START_TEST(showbar_with_max_smaller_than_real_max)
  524 {
  525     int len;
  526     suppress_output();
  527     len = showbar(1, 2, 1, 10);
  528     ck_assert_int_eq(len, 0);
  529 }
  530 END_TEST
  531 
  532 START_TEST(showbar_with_half_and_half_of_half)
  533 {
  534     int pipe, len;
  535     char buffer[512];
  536     memset(&buffer, '\0', sizeof(buffer));
  537 
  538     cfg.rxchar[0] = 'r';
  539     cfg.txchar[0] = 't';
  540     pipe = pipe_output();
  541     len = showbar(1, 1, 4, 12);
  542     ck_assert_int_eq(len, 6);
  543     fflush(stdout);
  544 
  545     len = (int)read(pipe, buffer, 512);
  546     ck_assert_str_eq(buffer, "  rrrttt");
  547 }
  548 END_TEST
  549 
  550 START_TEST(importlegacydb_does_not_overwrite_existing_interface_data)
  551 {
  552     int ret;
  553     disable_logprints();
  554 
  555     ret = db_open_rw(1);
  556     ck_assert_int_eq(ret, 1);
  557     ret = db_addinterface("ethtest");
  558     ck_assert_int_eq(ret, 1);
  559 
  560     ret = importlegacydb("ethtest", TESTDBDIR);
  561     ck_assert_int_eq(ret, 0);
  562 
  563     ret = db_close();
  564     ck_assert_int_eq(ret, 1);
  565 }
  566 END_TEST
  567 
  568 START_TEST(importlegacydb_can_detect_when_database_read_fails)
  569 {
  570     int ret;
  571     disable_logprints();
  572 
  573     ret = db_open_rw(1);
  574     ck_assert_int_eq(ret, 1);
  575     ret = db_addinterface("ethsomethingelse");
  576     ck_assert_int_eq(ret, 1);
  577 
  578     ck_assert_int_eq(clean_testdbdir(), 1);
  579     ck_assert_int_eq(create_zerosize_dbfile("ethtest"), 1);
  580     ck_assert_int_eq(create_zerosize_dbfile(".ethtest"), 1);
  581 
  582     ret = importlegacydb("ethtest", TESTDBDIR);
  583     ck_assert_int_eq(ret, 0);
  584 
  585     ret = db_close();
  586     ck_assert_int_eq(ret, 1);
  587 }
  588 END_TEST
  589 
  590 START_TEST(importlegacydb_can_import_legacy_database)
  591 {
  592     int ret, i;
  593     DATA data;
  594     interfaceinfo info;
  595     dbdatalist *datalist = NULL, *datalist_i = NULL;
  596     dbdatalistinfo datainfo;
  597 
  598     initdb(&data);
  599     disable_logprints();
  600 
  601     ret = db_open_rw(1);
  602     ck_assert_int_eq(ret, 1);
  603     ret = db_addinterface("ethsomethingelse");
  604     ck_assert_int_eq(ret, 1);
  605     ret = (int)db_getinterfacecount();
  606     ck_assert_int_eq(ret, 1);
  607 
  608     strcpy(data.interface, "ethtest");
  609     strcpy(data.nick, "still testing");
  610     data.totalrx = 123123123;
  611     data.totaltx = 321321321;
  612     data.totalrxk = 1;
  613     data.totaltxk = 2;
  614     data.currx = 456;
  615     data.curtx = 654;
  616     for (i = 0; i < 24; i++) {
  617         data.hour[i].date = 788911200 + 3600 * i;
  618         data.hour[i].rx = (uint64_t)(12 * (i + 1));
  619         data.hour[i].tx = (uint64_t)(23 * (i + 1));
  620     }
  621     for (i = 0; i < 30; i++) {
  622         data.day[i].date = 788911200 + 86400 * (29 - i);
  623         data.day[i].used = 1;
  624         data.day[i].rx = (uint64_t)(34 * i);
  625         data.day[i].tx = (uint64_t)(45 * i);
  626     }
  627     for (i = 0; i < 12; i++) {
  628         data.month[i].month = 788911200 + 2678400 * (11 - i);
  629         data.month[i].used = 1;
  630         data.month[i].rx = (uint64_t)(56 * i);
  631         data.month[i].tx = (uint64_t)(67 * i);
  632     }
  633     for (i = 0; i < 10; i++) {
  634         data.top10[i].date = 788911200 + 86400 * i;
  635         data.top10[i].used = 1;
  636         data.top10[i].rx = (uint64_t)(89 * (9 - i + 1));
  637         data.top10[i].tx = (uint64_t)(90 * (9 - i + 1));
  638     }
  639 
  640     ck_assert_int_eq(clean_testdbdir(), 1);
  641     ck_assert_int_eq(writedb(&data, "ethtest", TESTDBDIR, 1), 1);
  642     ck_assert_int_eq(check_dbfile_exists("ethtest", sizeof(DATA)), 1);
  643 
  644     ret = importlegacydb("ethtest", TESTDBDIR);
  645     ck_assert_int_eq(ret, 1);
  646 
  647     ret = (int)db_getinterfacecount();
  648     ck_assert_int_eq(ret, 2);
  649 
  650     ret = (int)db_getinterfacecountbyname("ethtest");
  651     ck_assert_int_eq(ret, 1);
  652 
  653     ret = db_getinterfaceinfo("ethtest", &info);
  654     ck_assert_int_eq(ret, 1);
  655 
  656     ck_assert_str_eq(info.alias, data.nick);
  657     ck_assert_int_eq(info.active, data.active);
  658     ck_assert_int_eq(info.rxtotal, (data.totalrx * 1024 * 1024) + (uint64_t)(data.totalrxk * 1024));
  659     ck_assert_int_eq(info.txtotal, (data.totaltx * 1024 * 1024) + (uint64_t)(data.totaltxk * 1024));
  660     ck_assert_int_eq(info.rxcounter, data.currx);
  661     ck_assert_int_eq(info.txcounter, data.curtx);
  662     ck_assert_int_ge(info.created, data.created);
  663     ck_assert_int_ge(info.updated, data.lastupdated);
  664 
  665     ret = db_getdata(&datalist, &datainfo, "ethtest", "day", 0);
  666     ck_assert_int_eq(ret, 1);
  667     ck_assert_int_eq(datainfo.count, 30);
  668     datalist_i = datalist;
  669     i = 29;
  670     while (datalist_i != NULL) {
  671         ck_assert_int_eq(datalist_i->rx, data.day[i].rx * 1024 * 1024);
  672         ck_assert_int_eq(datalist_i->tx, data.day[i].tx * 1024 * 1024);
  673         datalist_i = datalist_i->next;
  674         i--;
  675     }
  676     dbdatalistfree(&datalist);
  677 
  678     ret = db_getdata(&datalist, &datainfo, "ethtest", "month", 0);
  679     ck_assert_int_eq(ret, 1);
  680     ck_assert_int_eq(datainfo.count, 12);
  681     datalist_i = datalist;
  682     i = 11;
  683     while (datalist_i != NULL) {
  684         ck_assert_int_eq(datalist_i->rx, data.month[i].rx * 1024 * 1024);
  685         ck_assert_int_eq(datalist_i->tx, data.month[i].tx * 1024 * 1024);
  686         datalist_i = datalist_i->next;
  687         i--;
  688     }
  689     dbdatalistfree(&datalist);
  690 
  691     ret = db_getdata(&datalist, &datainfo, "ethtest", "hour", 0);
  692     ck_assert_int_eq(ret, 1);
  693     ck_assert_int_eq(datainfo.count, 24);
  694     datalist_i = datalist;
  695     i = 0;
  696     while (datalist_i != NULL) {
  697         ck_assert_int_eq(datalist_i->rx, data.hour[i].rx * 1024);
  698         ck_assert_int_eq(datalist_i->tx, data.hour[i].tx * 1024);
  699         datalist_i = datalist_i->next;
  700         i++;
  701     }
  702     dbdatalistfree(&datalist);
  703 
  704     ret = db_getdata(&datalist, &datainfo, "ethtest", "top", 0);
  705     ck_assert_int_eq(ret, 1);
  706     ck_assert_int_eq(datainfo.count, 10);
  707     datalist_i = datalist;
  708     i = 0;
  709     while (datalist_i != NULL) {
  710         ck_assert_int_eq(datalist_i->rx, data.top10[i].rx * 1024 * 1024);
  711         ck_assert_int_eq(datalist_i->tx, data.top10[i].tx * 1024 * 1024);
  712         datalist_i = datalist_i->next;
  713         i++;
  714     }
  715     dbdatalistfree(&datalist);
  716 
  717     ret = db_close();
  718     ck_assert_int_eq(ret, 1);
  719 }
  720 END_TEST
  721 
  722 
  723 START_TEST(showalert_shows_nothing_with_none_type)
  724 {
  725     int ret;
  726 
  727     defaultcfg();
  728 
  729     ret = db_open_rw(1);
  730     ck_assert_int_eq(ret, 1);
  731 
  732     ret = db_addinterface("something");
  733     ck_assert_int_eq(ret, 1);
  734 
  735     ret = db_addtraffic("something", 100, 200);
  736     ck_assert_int_eq(ret, 1);
  737 
  738     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_None, AC_Total, 42);
  739     ck_assert_int_eq(ret, 0);
  740 
  741     ret = db_close();
  742     ck_assert_int_eq(ret, 1);
  743 }
  744 END_TEST
  745 
  746 START_TEST(showalert_can_alert_on_limit_and_show_things)
  747 {
  748     int ret;
  749 
  750     defaultcfg();
  751     suppress_output();
  752 
  753     ret = db_open_rw(1);
  754     ck_assert_int_eq(ret, 1);
  755 
  756     ret = db_addinterface("something");
  757     ck_assert_int_eq(ret, 1);
  758 
  759     ret = db_setalias("something", "anything");
  760     ck_assert_int_eq(ret, 1);
  761 
  762     ret = db_addtraffic("something", 100, 200);
  763     ck_assert_int_eq(ret, 1);
  764 
  765     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Hour, AC_Total, 250);
  766     ck_assert_int_eq(ret, 1);
  767 
  768     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Day, AC_Total, 250);
  769     ck_assert_int_eq(ret, 1);
  770 
  771     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Month, AC_Total, 250);
  772     ck_assert_int_eq(ret, 1);
  773 
  774     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 250);
  775     ck_assert_int_eq(ret, 1);
  776 
  777     ret = db_close();
  778     ck_assert_int_eq(ret, 1);
  779 }
  780 END_TEST
  781 
  782 START_TEST(showalert_limit_and_conditions_matter)
  783 {
  784     int ret;
  785 
  786     defaultcfg();
  787     suppress_output();
  788 
  789     ret = db_open_rw(1);
  790     ck_assert_int_eq(ret, 1);
  791 
  792     ret = db_addinterface("something");
  793     ck_assert_int_eq(ret, 1);
  794 
  795     ret = db_addtraffic("something", 100, 200);
  796     ck_assert_int_eq(ret, 1);
  797 
  798     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 100);
  799     ck_assert_int_eq(ret, 1);
  800 
  801     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 280);
  802     ck_assert_int_eq(ret, 1);
  803 
  804     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 350);
  805     ck_assert_int_eq(ret, 0);
  806 
  807     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_Total, 300);
  808     ck_assert_int_eq(ret, 0);
  809 
  810     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 80);
  811     ck_assert_int_eq(ret, 1);
  812 
  813     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_RX, 150);
  814     ck_assert_int_eq(ret, 0);
  815 
  816     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 180);
  817     ck_assert_int_eq(ret, 1);
  818 
  819     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 250);
  820     ck_assert_int_eq(ret, 0);
  821 
  822     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 350);
  823     ck_assert_int_eq(ret, 0);
  824 
  825     ret = showalert("something", AO_Always_Output, AE_Exit_1_On_Limit, AT_Year, AC_TX, 200);
  826     ck_assert_int_eq(ret, 0);
  827 
  828     ret = db_close();
  829     ck_assert_int_eq(ret, 1);
  830 }
  831 END_TEST
  832 
  833 void add_database_tests(Suite *s)
  834 {
  835     TCase *tc_db = tcase_create("Database");
  836     tcase_add_checked_fixture(tc_db, setup, teardown);
  837     tcase_add_unchecked_fixture(tc_db, setup, teardown);
  838     tcase_add_test(tc_db, initdb_activates_database);
  839     tcase_add_test(tc_db, readdb_with_empty_file);
  840     tcase_add_test(tc_db, readdb_with_empty_file_and_backup);
  841     tcase_add_test(tc_db, readdb_with_nonexisting_file);
  842     tcase_add_test(tc_db, readdb_with_existing_dbfile);
  843     tcase_add_test(tc_db, readdb_with_existing_dbfile_and_max_name_length);
  844     tcase_add_test(tc_db, readdb_with_existing_dbfile_with_rename);
  845     tcase_add_test(tc_db, readdb_with_existing_dbfile_and_over_max_name_length);
  846     tcase_add_test(tc_db, validatedb_with_initdb);
  847     tcase_add_test(tc_db, validatedb_with_invalid_totals);
  848     tcase_add_test(tc_db, validatedb_with_top10_use);
  849     tcase_add_test(tc_db, database_outputs_do_not_crash);
  850     tcase_add_test(tc_db, database_outputs_do_not_crash_without_traffic);
  851     tcase_add_test(tc_db, database_outputs_do_not_crash_without_data);
  852     tcase_add_test(tc_db, database_outputs_do_not_crash_without_data_if_totals_are_wrong);
  853     tcase_add_test(tc_db, showbar_with_zero_len_is_nothing);
  854     tcase_add_test(tc_db, showbar_with_zero_max);
  855     tcase_add_test(tc_db, showbar_with_big_max_and_small_numbers);
  856     tcase_add_test(tc_db, showbar_with_all_rx);
  857     tcase_add_test(tc_db, showbar_with_all_tx);
  858     tcase_add_test(tc_db, showbar_with_half_and_half);
  859     tcase_add_test(tc_db, showbar_with_one_tenth);
  860     tcase_add_test(tc_db, showbar_with_small_rx_shows_all_tx);
  861     tcase_add_test(tc_db, showbar_with_max_smaller_than_real_max);
  862     tcase_add_test(tc_db, showbar_with_half_and_half_of_half);
  863     tcase_add_test(tc_db, importlegacydb_does_not_overwrite_existing_interface_data);
  864     tcase_add_test(tc_db, importlegacydb_can_detect_when_database_read_fails);
  865     tcase_add_test(tc_db, importlegacydb_can_import_legacy_database);
  866     tcase_add_test(tc_db, showalert_shows_nothing_with_none_type);
  867     tcase_add_test(tc_db, showalert_can_alert_on_limit_and_show_things);
  868     tcase_add_test(tc_db, showalert_limit_and_conditions_matter);
  869     suite_add_tcase(s, tc_db);
  870 }
  871 
  872 int writedb(DATA *data, const char *iface, const char *dirname, int newdb)
  873 {
  874     FILE *testdb;
  875     char file[512], backup[512];
  876 
  877     snprintf(file, 512, "%s/%s", dirname, iface);
  878     snprintf(backup, 512, "%s/.%s", dirname, iface);
  879 
  880     /* try to make backup of old data if this isn't a new database */
  881     if (!newdb && !backupdb(file, backup)) {
  882         snprintf(errorstring, 1024, "Unable to create database backup \"%s\".", backup);
  883         printe(PT_Error);
  884         return 0;
  885     }
  886 
  887     /* make sure version stays correct */
  888     data->version = LEGACYDBVERSION;
  889 
  890     if ((testdb = fopen(file, "w")) == NULL) {
  891         snprintf(errorstring, 1024, "Unable to open database \"%s\" for writing: %s", file, strerror(errno));
  892         printe(PT_Error);
  893         return 0;
  894     }
  895 
  896     /* update timestamp when not merging */
  897     if (newdb != 2) {
  898         data->lastupdated = time(NULL);
  899     }
  900 
  901     if (fwrite(data, sizeof(DATA), 1, testdb) == 0) {
  902         snprintf(errorstring, 1024, "Unable to write database \"%s\": %s", file, strerror(errno));
  903         printe(PT_Error);
  904         fclose(testdb);
  905         return 0;
  906     } else {
  907         if (debug) {
  908             printf("db: Database \"%s\" saved.\n", file);
  909         }
  910         fclose(testdb);
  911         if ((newdb) && (noexit == 0)) {
  912             snprintf(errorstring, 1024, "-> A new database has been created.");
  913             printe(PT_Info);
  914         }
  915     }
  916 
  917     return 1;
  918 }
  919 
  920 int backupdb(const char *current, const char *backup)
  921 {
  922     FILE *bf;
  923     int c, b, bytes;
  924     char buffer[512];
  925 
  926     /* from */
  927     if ((c = open(current, O_RDONLY)) == -1) {
  928         return 0;
  929     }
  930 
  931     /* to, fopen() in order to get file mode bits correctly */
  932     if ((bf = fopen(backup, "w")) == NULL) {
  933         close(c);
  934         return 0;
  935     }
  936     b = fileno(bf);
  937 
  938     /* copy data */
  939     while ((bytes = (int)read(c, buffer, sizeof(buffer))) > 0) {
  940         if (write(b, buffer, (size_t)bytes) < 0) {
  941             close(c);
  942             fclose(bf);
  943             return 0;
  944         }
  945     }
  946 
  947     close(c);
  948     fclose(bf);
  949 
  950     return 1;
  951 }