LCOV - code coverage report
Current view: top level - home/snapwebsites/snapcpp/snapwebsites/snapdatabase/tests - structure.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 131 134 97.8 %
Date: 2019-12-15 17:13:15 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2019  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/snapdatabase
       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             : // self
      21             : //
      22             : #include    "main.h"
      23             : 
      24             : 
      25             : // snapdatabase lib
      26             : //
      27             : #include    <snapdatabase/data/structure.h>
      28             : 
      29             : 
      30             : // advgetopt lib
      31             : //
      32             : #include    <advgetopt/options.h>
      33             : 
      34             : 
      35             : namespace
      36             : {
      37             : 
      38             : 
      39             : 
      40             : constexpr snapdatabase::struct_description_t g_description1[] =
      41             : {
      42             :     snapdatabase::define_description(
      43             :           snapdatabase::FieldName("magic")
      44             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
      45             :     ),
      46             :     snapdatabase::define_description(
      47             :           snapdatabase::FieldName("count")
      48             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
      49             :     ),
      50             :     snapdatabase::define_description(
      51             :           snapdatabase::FieldName("size")
      52             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
      53             :     ),
      54             :     snapdatabase::define_description(
      55             :           snapdatabase::FieldName("next")
      56             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_REFERENCE)
      57             :     ),
      58             :     snapdatabase::define_description(
      59             :           snapdatabase::FieldName("previous")
      60             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_REFERENCE)
      61             :     ),
      62             :     snapdatabase::end_descriptions()
      63             : };
      64             : 
      65             : 
      66             : 
      67             : constexpr snapdatabase::struct_description_t g_description2[] =
      68             : {
      69             :     snapdatabase::define_description(
      70             :           snapdatabase::FieldName("magic")
      71             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
      72             :     ),
      73             :     snapdatabase::define_description(
      74             :           snapdatabase::FieldName("flags")
      75             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
      76             :     ),
      77             :     snapdatabase::define_description(
      78             :           snapdatabase::FieldName("name")
      79             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_P8STRING)
      80             :     ),
      81             :     snapdatabase::define_description(
      82             :           snapdatabase::FieldName("size")
      83             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT64)
      84             :     ),
      85             :     snapdatabase::define_description(
      86             :           snapdatabase::FieldName("model")
      87             :         , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT16)
      88             :     ),
      89             :     snapdatabase::end_descriptions()
      90             : };
      91             : 
      92             : 
      93             : 
      94             : 
      95             : }
      96             : // no name namespace
      97             : 
      98             : 
      99           3 : CATCH_TEST_CASE("Structure Valid Version", "[structure] [version]")
     100             : {
     101           2 :     CATCH_START_SECTION("version conversion")
     102             :     {
     103         101 :         for(int n(0); n < 100; ++n)
     104             :         {
     105         100 :             int const major_version(rand() & 0xFFFF);
     106         100 :             int const minor_version(rand() & 0xFFFF);
     107             : 
     108         100 :             uint32_t const binary((major_version << 16) + minor_version);
     109             : 
     110         100 :             snapdatabase::version_t v1(major_version, minor_version);
     111         100 :             CATCH_REQUIRE(v1.get_major() == major_version);
     112         100 :             CATCH_REQUIRE(v1.get_minor() == minor_version);
     113         100 :             CATCH_REQUIRE(v1.to_binary() == binary);
     114             : 
     115         100 :             snapdatabase::version_t v2;
     116         100 :             CATCH_REQUIRE(v2.get_major() == 0);
     117         100 :             CATCH_REQUIRE(v2.get_minor() == 0);
     118         100 :             CATCH_REQUIRE(v2.is_null());
     119         100 :             CATCH_REQUIRE(v2 != v1);
     120         100 :             v2.from_binary(binary);
     121         100 :             CATCH_REQUIRE(v2.get_major() == major_version);
     122         100 :             CATCH_REQUIRE(v2.get_minor() == minor_version);
     123         100 :             CATCH_REQUIRE(v2.to_binary() == binary);
     124         100 :             CATCH_REQUIRE(v2 == v1);
     125             : 
     126         100 :             v2.next_revision();
     127             : 
     128         100 :             if(minor_version == 0xFFFF)
     129             :             {
     130           0 :                 CATCH_REQUIRE(v2.get_major() == major_version + 1);
     131           0 :                 CATCH_REQUIRE(v2.get_minor() == 0);
     132             :             }
     133             :             else
     134             :             {
     135         100 :                 CATCH_REQUIRE(v2.get_major() == major_version);
     136         100 :                 CATCH_REQUIRE(v2.get_minor() == minor_version + 1);
     137             :             }
     138             : 
     139         100 :             v2 = v1;
     140         100 :             int const new_major_version(rand() & 0xFFFF);
     141         100 :             v2.set_major(new_major_version);
     142         100 :             CATCH_REQUIRE(v2.get_major() == new_major_version);
     143         100 :             CATCH_REQUIRE(v2.get_minor() == minor_version);
     144         100 :             CATCH_REQUIRE(v2 != v1);
     145             : 
     146         100 :             int const new_minor_version(rand() & 0xFFFF);
     147         100 :             v2.set_minor(new_minor_version);
     148         100 :             CATCH_REQUIRE(v2.get_major() == new_major_version);
     149         100 :             CATCH_REQUIRE(v2.get_minor() == new_minor_version);
     150         100 :             CATCH_REQUIRE(v2 != v1);
     151             : 
     152         100 :             v2 = v1;
     153         100 :             CATCH_REQUIRE(v2.get_major() == major_version);
     154         100 :             CATCH_REQUIRE(v2.get_minor() == minor_version);
     155         100 :             CATCH_REQUIRE(v2.to_binary() == binary);
     156         100 :             CATCH_REQUIRE(v2 == v1);
     157             : 
     158         100 :             snapdatabase::version_t v3(v1);
     159         100 :             CATCH_REQUIRE_FALSE(v3.is_null());
     160         100 :             CATCH_REQUIRE(v3.get_major() == major_version);
     161         100 :             CATCH_REQUIRE(v3.get_minor() == minor_version);
     162         100 :             CATCH_REQUIRE(v3.to_binary() == binary);
     163         100 :             CATCH_REQUIRE(v3 == v1);
     164         100 :             CATCH_REQUIRE_FALSE(v3 > v1);
     165         100 :             CATCH_REQUIRE(v3 >= v1);
     166         100 :             CATCH_REQUIRE_FALSE(v3 < v1);
     167         100 :             CATCH_REQUIRE(v3 <= v1);
     168             : 
     169         200 :             std::string v3_str(v3.to_string());
     170         200 :             std::string version_str;
     171         100 :             version_str += std::to_string(major_version);
     172         100 :             version_str += '.';
     173         100 :             version_str += std::to_string(minor_version);
     174         100 :             CATCH_REQUIRE(v3_str == version_str);
     175             : 
     176         100 :             v3.next_branch();
     177         100 :             CATCH_REQUIRE(v3.get_major() == major_version + 1);
     178         100 :             CATCH_REQUIRE(v3.get_minor() == 0);
     179         100 :             CATCH_REQUIRE(v3.to_binary() == ((major_version + 1) << 16));
     180             :         }
     181             :     }
     182             :     CATCH_END_SECTION()
     183           1 : }
     184             : 
     185           3 : CATCH_TEST_CASE("Structure Overflown Version", "[structure] [version]")
     186             : {
     187           2 :     CATCH_START_SECTION("version overflow")
     188             :     {
     189         101 :         for(int n(0); n < 100; ++n)
     190             :         {
     191         100 :             int major_version(0);
     192         100 :             int minor_version(0);
     193          43 :             do
     194             :             {
     195         143 :                 major_version = rand() ^ rand() * 65536;
     196         143 :                 minor_version = rand() ^ rand() * 65536;
     197             :             }
     198             :             while(major_version < 65536
     199         143 :                && minor_version < 65536);
     200             : 
     201         100 :             CATCH_REQUIRE_THROWS_MATCHES(
     202             :                       snapdatabase::version_t(major_version, minor_version)
     203             :                     , snapdatabase::invalid_parameter
     204             :                     , Catch::Matchers::ExceptionMessage(
     205             :                               "snapdatabase_error: major/minor version must be between 0 and 65535 inclusive, "
     206             :                             + std::to_string(major_version)
     207             :                             + "."
     208             :                             + std::to_string(minor_version)
     209             :                             + " is incorrect."));
     210             :         }
     211             :     }
     212             :     CATCH_END_SECTION()
     213           1 : }
     214             : 
     215           3 : CATCH_TEST_CASE("Structure Overflow Version", "[structure] [version]")
     216             : {
     217           2 :     CATCH_START_SECTION("version compare")
     218             :     {
     219         101 :         for(int n(0); n < 100; ++n)
     220             :         {
     221         100 :             int major_version(rand() & 0xFFFF);
     222         100 :             int minor_version(rand() & 0xFFFF);
     223         100 :             int major_version2(rand() & 0xFFFF);
     224         100 :             while(major_version == major_version2)
     225             :             {
     226           0 :                 major_version2 = rand() & 0xFFFF;
     227             :             }
     228             : 
     229         100 :             snapdatabase::version_t v1(major_version, minor_version);
     230         100 :             snapdatabase::version_t v2(major_version2, minor_version);
     231         100 :             if(major_version < major_version2)
     232             :             {
     233          57 :                 CATCH_REQUIRE_FALSE(v1 == v2);
     234          57 :                 CATCH_REQUIRE(v1 != v2);
     235          57 :                 CATCH_REQUIRE(v1 < v2);
     236          57 :                 CATCH_REQUIRE(v1 <= v2);
     237          57 :                 CATCH_REQUIRE(v2 > v1);
     238          57 :                 CATCH_REQUIRE(v2 >= v1);
     239             :             }
     240             :             else
     241             :             {
     242          43 :                 CATCH_REQUIRE_FALSE(v1 == v2);
     243          43 :                 CATCH_REQUIRE(v1 != v2);
     244          43 :                 CATCH_REQUIRE(v1 > v2);
     245          43 :                 CATCH_REQUIRE(v1 >= v2);
     246          43 :                 CATCH_REQUIRE(v2 < v1);
     247          43 :                 CATCH_REQUIRE(v2 <= v1);
     248             :             }
     249             :         }
     250             :     }
     251             :     CATCH_END_SECTION()
     252           1 : }
     253             : 
     254             : 
     255           4 : CATCH_TEST_CASE("Structure", "[structure]")
     256             : {
     257           4 :     CATCH_START_SECTION("simple structure")
     258             :     {
     259           2 :         snapdatabase::structure::pointer_t description(std::make_shared<snapdatabase::structure>(g_description1));
     260             : 
     261           1 :         description->init_buffer();
     262             : 
     263           1 :         description->set_uinteger("magic", static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_BLOB));
     264             : 
     265           1 :         std::uint32_t count(123);
     266           1 :         description->set_uinteger("count", count);
     267             : 
     268           1 :         std::uint32_t size(900000);
     269           1 :         description->set_uinteger("size", size);
     270             : 
     271           1 :         snapdatabase::reference_t next(0xff00ff00ff00);
     272           1 :         description->set_uinteger("next", next);
     273             : 
     274           1 :         snapdatabase::reference_t previous(0xff11ff11ff11);
     275           1 :         description->set_uinteger("previous", previous);
     276             : 
     277           1 :         CATCH_REQUIRE(description->get_uinteger("magic") == static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_BLOB));
     278           1 :         CATCH_REQUIRE(description->get_uinteger("count") == count);
     279           1 :         CATCH_REQUIRE(description->get_uinteger("size") == size);
     280           1 :         CATCH_REQUIRE(description->get_uinteger("next") == next);
     281           1 :         CATCH_REQUIRE(description->get_uinteger("previous") == previous);
     282             :     }
     283             :     CATCH_END_SECTION()
     284             : 
     285           4 :     CATCH_START_SECTION("structure with a string")
     286             :     {
     287           2 :         snapdatabase::structure::pointer_t description(std::make_shared<snapdatabase::structure>(g_description2));
     288             : 
     289           1 :         description->init_buffer();
     290             : 
     291           1 :         description->set_uinteger("magic", static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_DATA));
     292             : 
     293           1 :         std::uint32_t flags(0x100105);
     294           1 :         description->set_uinteger("flags", flags);
     295             : 
     296           2 :         std::string const name("this is the name we want to include here");
     297           1 :         description->set_string("name", name);
     298             : 
     299           1 :         uint64_t size(1LL << 53);
     300           1 :         description->set_uinteger("size", size);
     301             : 
     302           1 :         uint16_t model(33);
     303           1 :         description->set_uinteger("model", model);
     304             : 
     305           1 :         CATCH_REQUIRE(description->get_uinteger("magic") == static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_DATA));
     306           1 :         CATCH_REQUIRE(description->get_uinteger("flags") == flags);
     307           1 :         CATCH_REQUIRE(description->get_string("name") == name);
     308           1 :         CATCH_REQUIRE(description->get_uinteger("size") == size);
     309           1 :         CATCH_REQUIRE(description->get_uinteger("model") == model);
     310             :     }
     311             :     CATCH_END_SECTION()
     312           8 : }
     313             : 
     314             : 
     315             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13