LCOV - code coverage report
Current view: directory - testsuite - test_format.cc (source / functions) Found Hit Coverage
Test: STX CBTreeDB Testsuite Lines: 86 71 82.6 %
Date: 2010-04-14 Functions: 19 13 68.4 %

       1                 : // -*- mode: c++; fill-column: 79 -*-
       2                 : // $Id: test_format.cc 2 2010-04-14 07:34:58Z tb $
       3                 : 
       4                 : /*
       5                 :  * STX Constant B-Tree Database Template Classes v0.7.0
       6                 :  * Copyright (C) 2010 Timo Bingmann
       7                 :  *
       8                 :  * This library is free software; you can redistribute it and/or modify it
       9                 :  * under the terms of the GNU Lesser General Public License as published by the
      10                 :  * Free Software Foundation; either version 2.1 of the License, or (at your
      11                 :  * option) any later version.
      12                 :  *
      13                 :  * This library is distributed in the hope that it will be useful, but WITHOUT
      14                 :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15                 :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
      16                 :  * for more details.
      17                 :  *
      18                 :  * You should have received a copy of the GNU Lesser General Public License
      19                 :  * along with this library; if not, write to the Free Software Foundation,
      20                 :  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21                 :  */
      22                 : 
      23                 : /*
      24                 :  * Freeze database format. Two databases are frozen and included with
      25                 :  * this test case. Both class configurations are reproduced and the
      26                 :  * same items inserted. The resulting databases are compared against
      27                 :  * the frozen database files, both Writer and WriterSequential must
      28                 :  * produce databases equal to the frozen reference files. Also test
      29                 :  * error checking in Open() by attempting to load incompatible files.
      30                 :  */
      31                 : 
      32                 : #define CBTREEDB_SELF_VERIFY
      33                 : #include "stx-cbtreedb.h"
      34                 : 
      35                 : #include <iostream>
      36                 : #include <sstream>
      37                 : #include <fstream>
      38                 : #include <assert.h>
      39                 : #include <stdlib.h>
      40                 : 
      41                 : static const unsigned int items = 10000;
      42                 : 
      43                 : template <typename cbtreedb>
      44               2 : void run_test_random(const std::string& dbname)
      45                 : {
      46               2 :     std::cout << "Creating test database using random writer." << std::endl;
      47                 : 
      48               2 :     typename cbtreedb::Writer writer;
      49               2 :     writer.SetSignature("cbtestdb");
      50                 : 
      51           20004 :     for(unsigned int i = 0; i <= items; ++i)
      52                 :     {
      53           20002 :         writer.Add(2*i, &i, sizeof(i));
      54                 :     }
      55                 : 
      56                 :     // write new database into string object
      57                 : 
      58               2 :     std::ostringstream testdb;
      59               2 :     writer.Write(testdb);
      60                 : 
      61               2 :     std::string testdbstr = testdb.str();
      62                 :     // std::cout << "dbsize " << testdbstr.size() << std::endl;
      63                 : 
      64                 :     // read reference database from file
      65                 :       
      66               2 :     std::string refdbstr;
      67                 : 
      68                 :     {
      69               2 :         std::ifstream ifdb((AM_TOP_SRCDIR "/testsuite/" + dbname).c_str());
      70                 : 
      71               2 :         if (!ifdb.good()) {
      72               0 :             ifdb.open(("testsuite/" + dbname).c_str());
      73                 :         }
      74                 : 
      75                 :         char buffer[32*1024];
      76              10 :         do
      77                 :         {
      78              10 :             ifdb.read(buffer, sizeof(buffer));
      79              12 :             refdbstr.append(buffer, ifdb.gcount());
      80                 :         }
      81                 :         while ( ifdb.good() && !ifdb.eof() );
      82                 :     }
      83                 : 
      84                 :     // compare reference db and created db
      85                 : 
      86               2 :     if (testdbstr != refdbstr)
      87                 :     {
      88               0 :         std::cout << "Reference database does not match!" << std::endl;
      89                 : 
      90               0 :         std::ofstream ofdb((dbname + "-new").c_str());
      91               0 :         ofdb << testdbstr;
      92               0 :         ofdb.close();
      93                 : 
      94               0 :         assert( testdbstr == refdbstr );
      95                 :     }
      96               2 : }
      97                 : 
      98                 : template <typename cbtreedb>
      99               2 : void run_test_sequential(const std::string& dbname)
     100                 : {
     101               2 :     std::cout << "Creating test database using sequential writer." << std::endl;
     102                 : 
     103               2 :     typename cbtreedb::WriterSequential writer;
     104               2 :     writer.SetSignature("cbtestdb");
     105                 : 
     106           20004 :     for(unsigned int i = 0; i <= items; ++i)
     107                 :     {
     108                 :         // phase 1: declare key and valuesize mappings.
     109           20002 :         writer.Add(2*i, sizeof(i));
     110                 :     }
     111                 : 
     112               2 :     std::ostringstream testdb;
     113                 :     
     114               2 :     writer.WriteHeader(testdb); // write header and btree
     115                 : 
     116           20004 :     for(unsigned int i = 0; i <= items; ++i)
     117                 :     {
     118                 :         // phase 2: write value objects
     119           20002 :         writer.WriteValue(2*i, &i, sizeof(i));
     120                 :     }
     121                 : 
     122               2 :     writer.WriteFinalize();
     123                 : 
     124               2 :     std::string testdbstr = testdb.str();
     125                 :     // std::cout << "dbsize " << testdbstr.size() << std::endl;
     126                 : 
     127                 :     // read reference database from file
     128                 :       
     129               2 :     std::string refdbstr;
     130                 : 
     131                 :     {
     132               2 :         std::ifstream ifdb((AM_TOP_SRCDIR "/testsuite/" + dbname).c_str());
     133                 : 
     134               2 :         if (!ifdb.good()) {
     135               0 :             ifdb.open(("testsuite/" + dbname).c_str());
     136                 :         }
     137                 : 
     138                 :         char buffer[32*1024];
     139              10 :         do
     140                 :         {
     141              10 :             ifdb.read(buffer, sizeof(buffer));
     142              12 :             refdbstr.append(buffer, ifdb.gcount());
     143                 :         }
     144                 :         while ( ifdb.good() && !ifdb.eof() );
     145                 :     }
     146                 : 
     147                 :     // compare reference db and created db
     148                 : 
     149               2 :     if (testdbstr != refdbstr)
     150                 :     {
     151               0 :         std::cout << "Reference database does not match!" << std::endl;
     152                 : 
     153               0 :         std::ofstream ofdb((dbname + "-new").c_str());
     154               0 :         ofdb << testdbstr;
     155               0 :         ofdb.close();
     156                 : 
     157               0 :         assert( testdbstr == refdbstr );
     158                 :     }
     159               2 : }
     160                 : 
     161                 : template <typename cbtreedb>
     162               8 : void run_test_open(const std::string& dbname, const std::string& expectederrorstring)
     163                 : {
     164                 :     // read database from file
     165                 :       
     166               8 :     std::string dbstr;
     167                 : 
     168                 :     {
     169               8 :         std::ifstream ifdb((AM_TOP_SRCDIR "/testsuite/" + dbname).c_str());
     170                 : 
     171               8 :         if (!ifdb.good()) {
     172               0 :             ifdb.open(("testsuite/" + dbname).c_str());
     173                 :         }
     174                 : 
     175                 :         char buffer[32*1024];
     176              40 :         do
     177                 :         {
     178              40 :             ifdb.read(buffer, sizeof(buffer));
     179              48 :             dbstr.append(buffer, ifdb.gcount());
     180                 :         }
     181                 :         while ( ifdb.good() && !ifdb.eof() );
     182                 :     }
     183                 : 
     184               8 :     assert(dbstr.size());
     185                 :     // std::cout << "dbsize " << dbstr.size() << std::endl;
     186                 : 
     187                 :     // create reader object
     188                 : 
     189               8 :     typename cbtreedb::Reader reader;
     190               8 :     reader.SetSignature("cbtestdb");
     191                 : 
     192               8 :     typename cbtreedb::PageCache cache(128);
     193               8 :     reader.SetPageCache(&cache);
     194                 : 
     195               8 :     std::istringstream testdb(dbstr);
     196               8 :     std::string errorstring;
     197                 : 
     198               8 :     if (! reader.Open(testdb,&errorstring) )
     199                 :     {
     200               6 :         if (errorstring != expectederrorstring)
     201                 :         {
     202               0 :             std::cout << "Open errorstring mismatched: " << std::endl
     203                 :                       << "Got: " << errorstring << std::endl
     204                 :                       << "Expected: " << expectederrorstring << std::endl;
     205               0 :             abort();            
     206                 :         }
     207               6 :         return;
     208                 :     }
     209                 : 
     210               2 :     assert( reader.Verify() );
     211               2 :     assert( reader.Size() == items+1 );
     212                 : }
     213                 : 
     214               1 : int main()
     215                 : {
     216                 :     // check binary format compatibility with two common configurations
     217                 : 
     218               1 :     run_test_random< stx::CBTreeDB<uint32_t, std::less<uint32_t>, 1024> >("test_format1.db");
     219               2 :     run_test_sequential< stx::CBTreeDB<uint32_t, std::less<uint32_t>, 1024> >("test_format1.db");
     220                 : 
     221               2 :     run_test_random< stx::CBTreeDB<uint64_t, std::less<uint64_t>, 2048> >("test_format2.db");
     222               2 :     run_test_sequential< stx::CBTreeDB<uint64_t, std::less<uint64_t>, 2048> >("test_format2.db");
     223                 : 
     224                 :     // check error when opening database with wrong configurations
     225                 : 
     226                 :     run_test_open< stx::CBTreeDB<uint32_t, std::less<uint32_t>, 1024> >
     227               2 :         ("test_format1.db", "");
     228                 : 
     229                 :     run_test_open< stx::CBTreeDB<uint32_t, std::less<uint32_t>, 2048> >
     230               2 :         ("test_format1.db", "Database not compatible with this reader: page sizes mismatch.");
     231                 : 
     232                 :     run_test_open< stx::CBTreeDB<uint64_t, std::less<uint64_t>, 1024> >
     233               2 :         ("test_format1.db", "Database not compatible with this reader: key sizes mismatch.");
     234                 : 
     235                 :     run_test_open< stx::CBTreeDB<uint32_t, std::greater<uint32_t>, 1024> >
     236               2 :         ("test_format1.db", "Database not compatible with this reader: root keys order mismatches.");
     237                 : 
     238                 : 
     239                 :     run_test_open< stx::CBTreeDB<uint64_t, std::less<uint64_t>, 2048> >
     240               2 :         ("test_format2.db", "");
     241                 : 
     242                 :     run_test_open< stx::CBTreeDB<uint64_t, std::less<uint64_t>, 1024> >
     243               2 :         ("test_format2.db", "Database not compatible with this reader: page sizes mismatch.");
     244                 : 
     245                 :     run_test_open< stx::CBTreeDB<uint32_t, std::less<uint32_t>, 2048> >
     246               2 :         ("test_format2.db", "Database not compatible with this reader: key sizes mismatch.");
     247                 : 
     248                 :     run_test_open< stx::CBTreeDB<uint64_t, std::greater<uint64_t>, 2048> >
     249               2 :         ("test_format2.db", "Database not compatible with this reader: root keys order mismatches.");
     250                 : 
     251               1 :     return 0;
     252               3 : }

Generated by: LCOV version 1.7