LCOV - code coverage report
Current view: top level - tests - catch_stream.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 99 100 99.0 %
Date: 2022-10-29 13:59:13 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2006-2022  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/advgetopt
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License along
      17             : // with this program; if not, write to the Free Software Foundation, Inc.,
      18             : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             : 
      20             : // murmur3
      21             : //
      22             : #include    <murmur3/stream.h>
      23             : 
      24             : #include    <murmur3/murmur3.h>
      25             : 
      26             : 
      27             : // self
      28             : //
      29             : #include    "catch_main.h"
      30             : 
      31             : 
      32             : // snapdev
      33             : //
      34             : #include    <snapdev/file_contents.h>
      35             : #include    <snapdev/glob_to_list.h>
      36             : 
      37             : 
      38             : // C
      39             : //
      40             : #include    <sys/random.h>
      41             : 
      42             : 
      43             : // last include
      44             : //
      45             : #include    <snapdev/poison.h>
      46             : 
      47             : 
      48             : 
      49           5 : CATCH_TEST_CASE("stream_basic", "[stream][valid]")
      50             : {
      51           6 :     CATCH_START_SECTION("Verify small stream (Hello World!)")
      52             :     {
      53           1 :         murmur3::stream sum(123, 123);
      54             : 
      55           1 :         murmur3::seed_t seed1(0);
      56           1 :         murmur3::seed_t seed2(0);
      57           1 :         sum.get_seeds(seed1, seed2);
      58           1 :         CATCH_CHECK(seed1 == 123);
      59           1 :         CATCH_CHECK(seed2 == 123);
      60             : 
      61           2 :         std::string const hello_world("Hello, world!");
      62           1 :         sum.add_data(hello_world.c_str(), hello_world.length());
      63           1 :         CATCH_CHECK(sum.flush().to_string() == "8743acad421c8c73d373c3f5f19732fd");
      64             : 
      65           1 :         CATCH_CHECK(murmur3::sum(hello_world.c_str(), hello_world.length(), 123).to_string() == "8743acad421c8c73d373c3f5f19732fd");
      66             : 
      67             :         // verify the reset()
      68             :         //
      69           1 :         sum.reset();
      70             : 
      71           1 :         sum.add_data(hello_world.c_str(), hello_world.length());
      72           1 :         CATCH_CHECK(sum.flush().to_string() == "8743acad421c8c73d373c3f5f19732fd");
      73             : 
      74             :         // verify different seed
      75             :         //
      76           1 :         sum.reset(321);
      77             : 
      78           1 :         sum.add_data(hello_world.c_str(), hello_world.length());
      79           1 :         CATCH_CHECK(sum.flush().to_string() == "f86d4004ca47f42bb9546c7979200aee");
      80             : 
      81           1 :         CATCH_CHECK(murmur3::sum(hello_world.c_str(), hello_world.length(), 321).to_string() == "f86d4004ca47f42bb9546c7979200aee");
      82             :     }
      83             :     CATCH_END_SECTION()
      84             : 
      85           6 :     CATCH_START_SECTION("X28 stream")
      86             :     {
      87           1 :         murmur3::stream sum(123, 123);
      88             : 
      89           1 :         murmur3::seed_t seed1(0);
      90           1 :         murmur3::seed_t seed2(0);
      91           1 :         sum.get_seeds(seed1, seed2);
      92           1 :         CATCH_CHECK(seed1 == 123);
      93           1 :         CATCH_CHECK(seed2 == 123);
      94             : 
      95           2 :         std::string const x28("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
      96           1 :         sum.add_data(x28.c_str(), x28.length());
      97           1 :         CATCH_CHECK(sum.flush().to_string() == "becf7e04dbcf74637751664ef66e73e0");
      98             : 
      99           1 :         CATCH_CHECK(murmur3::sum(x28.c_str(), x28.length(), 123).to_string() == "becf7e04dbcf74637751664ef66e73e0");
     100             :     }
     101             :     CATCH_END_SECTION()
     102             : 
     103           6 :     CATCH_START_SECTION("Empty file stream")
     104             :     {
     105           1 :         murmur3::stream sum(123, 123);
     106             : 
     107           1 :         murmur3::seed_t seed1(0);
     108           1 :         murmur3::seed_t seed2(0);
     109           1 :         sum.get_seeds(seed1, seed2);
     110           1 :         CATCH_CHECK(seed1 == 123);
     111           1 :         CATCH_CHECK(seed2 == 123);
     112             : 
     113           2 :         std::string const empty("");
     114           1 :         sum.add_data(empty.c_str(), empty.length());
     115           1 :         CATCH_CHECK(sum.flush().to_string() == "4cd9597081679d1abd92f8784bace33d");
     116             : 
     117           1 :         CATCH_CHECK(murmur3::sum(empty.c_str(), empty.length(), 123).to_string() == "4cd9597081679d1abd92f8784bace33d");
     118             :     }
     119             :     CATCH_END_SECTION()
     120           3 : }
     121             : 
     122             : 
     123           5 : CATCH_TEST_CASE("stream_file", "[stream][valid]")
     124             : {
     125           6 :     CATCH_START_SECTION("Stream files")
     126             :     {
     127           2 :         snapdev::glob_to_list<std::list<snapdev::file>> glob;
     128           1 :         CATCH_REQUIRE(glob.read_path<
     129             :                  snapdev::glob_to_list_flag_t::GLOB_FLAG_IGNORE_ERRORS,
     130             :                  snapdev::glob_to_list_flag_t::GLOB_FLAG_PERIOD>("..."));
     131             : 
     132         208 :         for(auto const & f : glob)
     133             :         {
     134         207 :             if(!f.is_regular_file())
     135             :             {
     136             :                 // skip directories and special files
     137             :                 //
     138          85 :                 continue;
     139             :             }
     140         122 :             if(SNAP_CATCH2_NAMESPACE::g_verbose())
     141             :             {
     142           0 :                 std::cout << "-- testing with file \"" << f.filename() << "\".\n";
     143             :             }
     144             : 
     145         244 :             snapdev::file_contents file(f.filename());
     146         122 :             CATCH_REQUIRE(file.read_all());
     147         122 :             std::string const & contents(file.contents());
     148             : 
     149             :             // first compute the hash with the basic C function
     150             :             //
     151         122 :             std::uint32_t hash[4];
     152         122 :             MurmurHash3_x64_128(contents.c_str(), contents.length(), 0, hash);
     153         244 :             std::string c_hash(SNAP_CATCH2_NAMESPACE::hex128(hash));
     154             : 
     155             :             // second compute the same hash with the stream function 4Kb at
     156             :             // a time so we should hit all possible cases
     157             :             //
     158         122 :             constexpr std::size_t four_kb(1024 * 4);
     159         122 :             murmur3::stream sum(0);
     160         122 :             std::size_t const nblocks(contents.length() / four_kb);
     161         122 :             std::size_t const left_over(contents.length() % four_kb);
     162        3937 :             for(std::size_t b(0); b < nblocks; ++b)
     163             :             {
     164        3815 :                 sum.add_data(contents.c_str() + b * four_kb, four_kb);
     165             :             }
     166         122 :             if(left_over != 0)
     167             :             {
     168         122 :                 sum.add_data(contents.c_str() + nblocks * four_kb, left_over);
     169             :             }
     170             : 
     171         122 :             CATCH_CHECK(sum.flush().to_string() == c_hash);
     172             : 
     173             :             // test the helper function that computes the murmur3 of a file
     174             :             // using the streaming mechanism (to avoid loading the file in
     175             :             // memory all at once)
     176             :             //
     177         122 :             CATCH_CHECK(murmur3::sum(f.filename()).to_string() == c_hash);
     178             :         }
     179             :     }
     180             :     CATCH_END_SECTION()
     181             : 
     182           6 :     CATCH_START_SECTION("Stream 4Kb exactly (special case)")
     183             :     {
     184           1 :         constexpr std::size_t four_kb(1024 * 4);
     185           1 :         char buf[four_kb];
     186           1 :         getrandom(buf, sizeof(buf), 0);
     187             : 
     188             :         // first compute the hash with the basic C function
     189             :         //
     190           1 :         std::uint32_t hash[4];
     191           1 :         MurmurHash3_x64_128(buf, sizeof(buf), 0, hash);
     192           2 :         std::string c_hash(SNAP_CATCH2_NAMESPACE::hex128(hash));
     193             : 
     194             :         // second compute the same hash with the stream function 4Kb at
     195             :         // a time so we should hit all possible cases
     196             :         //
     197           1 :         murmur3::stream sum(0);
     198           1 :         sum.add_data(buf, sizeof(buf));
     199           1 :         CATCH_CHECK(sum.flush().to_string() == c_hash);
     200             : 
     201             :         // test the helper function that computes the murmur3 of a file
     202             :         // using the streaming mechanism (to avoid loading the file in
     203             :         // memory all at once)
     204             :         //
     205           2 :         std::string const tmp_dir(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     206           2 :         std::string const test_filename(tmp_dir + "/4kb.bin");
     207           2 :         std::ofstream out(test_filename);
     208           1 :         out.write(buf, sizeof(buf));
     209           1 :         CATCH_CHECK(murmur3::sum(test_filename).to_string() == c_hash);
     210             :     }
     211             :     CATCH_END_SECTION()
     212             : 
     213           6 :     CATCH_START_SECTION("Stream 0Kb to 4Kb (many special cases)")
     214             :     {
     215           1 :         constexpr std::size_t four_kb(1024 * 4);
     216        4097 :         for(std::size_t size(0); size < four_kb; ++size)
     217             :         {
     218        4096 :             char buf[size];
     219        4096 :             getrandom(buf, sizeof(buf), 0);
     220             : 
     221             :             // first compute the hash with the basic C function
     222             :             //
     223        4096 :             std::uint32_t hash[4];
     224        4096 :             MurmurHash3_x64_128(buf, sizeof(buf), 0, hash);
     225        8192 :             std::string c_hash(SNAP_CATCH2_NAMESPACE::hex128(hash));
     226             : 
     227             :             // second compute the same hash with the stream function 4Kb at
     228             :             // a time so we should hit all possible cases
     229             :             //
     230        4096 :             murmur3::stream sum(0);
     231        4096 :             sum.add_data(buf, sizeof(buf));
     232        4096 :             CATCH_CHECK(sum.flush().to_string() == c_hash);
     233             : 
     234             :             // test the helper function that computes the murmur3 of a file
     235             :             // using the streaming mechanism (to avoid loading the file in
     236             :             // memory all at once)
     237             :             //
     238        8192 :             std::string const tmp_dir(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     239        8192 :             std::string const test_filename(tmp_dir + "/" + std::to_string(size) + "_bytes.bin");
     240             :             {
     241        8192 :                 std::ofstream out(test_filename);
     242        4096 :                 out.write(buf, sizeof(buf));
     243             :             }
     244             : //std::cerr << "-- test with file [" << test_filename << "] -> " << murmur3::sum(test_filename).to_string() << "\n";
     245        4096 :             CATCH_CHECK(murmur3::sum(test_filename).to_string() == c_hash);
     246        4096 :         }
     247             :     }
     248             :     CATCH_END_SECTION()
     249           9 : }
     250             : 
     251             : 
     252             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13