LCOV - code coverage report
Current view: top level - tests - catch_unique_number.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 46 46
Test Date: 2025-08-31 07:54:46 Functions: 100.0 % 2 2
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2011-2025  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/snapdev
       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 3 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
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : 
      19              : /** \file
      20              :  * \brief Verify the unique_number class.
      21              :  *
      22              :  * This file implements tests to verify that the unique_number implementation
      23              :  * works properly even when multiple processes use it simultaneously.
      24              :  */
      25              : 
      26              : // file being tested
      27              : //
      28              : #include    <snapdev/unique_number.h>
      29              : 
      30              : 
      31              : // self
      32              : //
      33              : #include    "catch_main.h"
      34              : 
      35              : 
      36              : // snapdev
      37              : //
      38              : #include    <snapdev/not_used.h>
      39              : 
      40              : 
      41              : 
      42              : // C++
      43              : //
      44              : #include    <random>
      45              : #include    <thread>
      46              : 
      47              : 
      48              : // last include
      49              : //
      50              : #include    <snapdev/poison.h>
      51              : 
      52              : 
      53              : 
      54              : // turn off pedantic for __int128
      55              : //
      56              : #pragma GCC diagnostic ignored "-Wpedantic"
      57              : 
      58              : 
      59              : namespace
      60              : {
      61              : 
      62              : 
      63              : 
      64              : 
      65              : } // no name namespace
      66              : 
      67              : 
      68              : 
      69            2 : CATCH_TEST_CASE("unique_number", "[number][file]")
      70              : {
      71            2 :     CATCH_START_SECTION("unique_number: verify unique number basic counter")
      72              :     {
      73            1 :         std::string const path(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
      74            1 :         std::string const filename(path + "/test-1.number");
      75              : 
      76            1 :         snapdev::NOT_USED(unlink(filename.c_str()));
      77              : 
      78          101 :         for(unsigned int n(1); n <= 100; ++n)
      79              :         {
      80          100 :             unsigned __int128 const number(snapdev::unique_number(filename));
      81          100 :             CATCH_REQUIRE(n == number);
      82              :         }
      83            1 :     }
      84            2 :     CATCH_END_SECTION()
      85              : 
      86            2 :     CATCH_START_SECTION("unique_number: verify unique number indexes")
      87              :     {
      88            1 :         std::random_device rd;
      89            1 :         std::mt19937 g(rd());
      90              : 
      91            1 :         std::string const path(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
      92            1 :         std::string const filename(path + "/test-2.number");
      93              : //std::cerr << "--- file: " << filename << "\n";
      94              : 
      95            1 :         snapdev::NOT_USED(unlink(filename.c_str()));
      96              : 
      97              :         // 100 indexes repeated 100 times
      98              :         //
      99              :         // that way we can shuffle all the indexes in order to count them
     100              :         // in different order
     101              :         //
     102            1 :         std::vector<unsigned int> indexes;
     103          101 :         for(unsigned int count(1); count <= 100; ++count)
     104              :         {
     105        10100 :             for(unsigned int idx(0); idx < 100; ++idx)
     106              :             {
     107        10000 :                 indexes.push_back(idx);
     108              :             }
     109              :         }
     110            1 :         std::shuffle(indexes.begin(), indexes.end(), g);
     111              : 
     112            3 :         std::vector<unsigned int> counters(100);
     113        10001 :         for(auto idx : indexes)
     114              :         {
     115        10000 :             unsigned __int128 const number(snapdev::unique_number(filename, idx));
     116        10000 :             ++counters[idx];
     117        10000 :             CATCH_REQUIRE(counters[idx] == number);
     118              :         }
     119            1 :     }
     120            2 :     CATCH_END_SECTION()
     121            2 : }
     122              : 
     123              : 
     124            3 : CATCH_TEST_CASE("unique_number_error", "[number][file][error]")
     125              : {
     126            3 :     CATCH_START_SECTION("unique_number_error: non-empty filename is required")
     127              :     {
     128            5 :         CATCH_REQUIRE_THROWS_MATCHES(
     129              :                   snapdev::unique_number(std::string())
     130              :                 , snapdev::path_missing
     131              :                 , Catch::Matchers::ExceptionMessage(
     132              :                           "unique_number_error: a counter filename must be specified when calling snapdev::unique_number."));
     133              :     }
     134            3 :     CATCH_END_SECTION()
     135              : 
     136            3 :     CATCH_START_SECTION("unique_number_error: index out of range")
     137              :     {
     138            1 :         std::string const path(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     139            1 :         std::string const filename(path + "/test-3.number");
     140              : 
     141          101 :         for(int index(-100); index < 0; ++index)
     142              :         {
     143          100 :             CATCH_REQUIRE_THROWS_MATCHES(
     144              :                       snapdev::unique_number(filename, index)
     145              :                     , snapdev::out_of_range
     146              :                     , Catch::Matchers::ExceptionMessage(
     147              :                               "unique_number_error: counter index in unique_number must be defined between 0 and "
     148              :                             + std::to_string(snapdev::COUNTER_MAXIMUM_INDEX - 1)
     149              :                             + " inclusive."));
     150              :         }
     151              : 
     152          101 :         for(int index(snapdev::COUNTER_MAXIMUM_INDEX); index < snapdev::COUNTER_MAXIMUM_INDEX + 100; ++index)
     153              :         {
     154          100 :             CATCH_REQUIRE_THROWS_MATCHES(
     155              :                       snapdev::unique_number(filename, index)
     156              :                     , snapdev::out_of_range
     157              :                     , Catch::Matchers::ExceptionMessage(
     158              :                               "unique_number_error: counter index in unique_number must be defined between 0 and "
     159              :                             + std::to_string(snapdev::COUNTER_MAXIMUM_INDEX - 1)
     160              :                             + " inclusive."));
     161              :         }
     162            1 :     }
     163            3 :     CATCH_END_SECTION()
     164              : 
     165            3 :     CATCH_START_SECTION("unique_number_error: file cannot be opened")
     166              :     {
     167            7 :         CATCH_REQUIRE_THROWS_MATCHES(
     168              :                   snapdev::unique_number("/this/wont/open/since/it/does/not/exist")
     169              :                 , snapdev::io_error
     170              :                 , Catch::Matchers::ExceptionMessage(
     171              :                           "unique_number_error: could not open unique_number file \"/this/wont/open/since/it/does/not/exist\"."));
     172              :     }
     173            3 :     CATCH_END_SECTION()
     174            3 : }
     175              : 
     176              : 
     177              : 
     178              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions