libmoost
/home/mhx/git/github/libmoost/test/kvds/ikvds.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 // Include boost test framework required headers
00029 #include <boost/test/unit_test.hpp>
00030 #include <boost/test/test_tools.hpp>
00031 
00032 // Include CRT/STL required header(s)
00033 #include <stdexcept>
00034 #include <vector>
00035 #include <set>
00036 
00037 #include <boost/cstdint.hpp>
00038 
00039 #include "../../include/moost/testing/test_directory_creator.hpp"
00040 
00041 // Include thrift headers
00042 
00043 // Include application required header(s)
00044 #include "../../include/moost/kvds.hpp"
00045 
00046 // Imported required namespace(s)
00047 using boost::uint32_t;
00048 using namespace moost::kvds;
00049 using namespace moost::testing;
00050 
00051 // Name the test suite
00052 BOOST_AUTO_TEST_SUITE( ikvdsTest )
00053 
00054 // Define the test fixture
00055 struct Fixture
00056 {
00057    test_directory_creator tdc;
00058 
00059    // C_tor
00060    Fixture()
00061    {
00062    }
00063 
00064    // D_tor
00065    ~Fixture()
00066    {
00067    }
00068 };
00069 
00070 class IKvdsTester
00071 {
00072    // NB. We use BOOST_REQUIRE since each test is dependent on the previous one working.
00073    //     This is to avoid having to re-populate the datastore for each test (save time).
00074 
00075    typedef IKvds kvds_type;
00076 
00077    static uint32_t const val0_mask = 0xF1E2D3C4;
00078    static uint32_t const val1_mask = 0x12345678;
00079 
00080 
00081    void test_get_noexist(kvds_type & kvds)
00082    {
00083       // These should ALL fail.
00084       uint32_t val_get = 0;
00085       size_t val_get_size = sizeof(val_get);
00086 
00087       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00088       {
00089          for(uint32_t val_put = 1 ; val_put != 0 ; val_put <<= 1)
00090          {
00091             BOOST_REQUIRE(!kvds.get(&key, sizeof(key), &val_get, val_get_size));
00092          }
00093       }
00094    }
00095 
00096    void test_siz(kvds_type & kvds, size_t const cnt, bool const bExists = true)
00097    {
00098       size_t const size = sizeof(uint32_t) * cnt;
00099 
00100       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00101       {
00102          size_t vsize;
00103          BOOST_REQUIRE(bExists == kvds.siz(&key, sizeof(key), vsize));
00104 
00105          if(bExists)
00106          {
00107             BOOST_REQUIRE(size == vsize);
00108          }
00109       }
00110    }
00111 
00112    void test_add_cnt_get(kvds_type & kvds)
00113    {
00114       uint32_t const val_add_mask = val1_mask;
00115       boost::uint64_t ecnt = 0;
00116 
00117       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00118       {
00119          uint32_t const val_add = key ^ val_add_mask;
00120          uint32_t val_get = 0;
00121          size_t val_get_size1 = sizeof(val_get);
00122          size_t val_get_size2 = sizeof(val_get) + 2;
00123          size_t val_get_size3 = 1;
00124 
00125          boost::uint64_t cnt = 0;
00126          BOOST_REQUIRE(kvds.cnt(cnt));
00127          BOOST_REQUIRE(ecnt == cnt);
00128          BOOST_REQUIRE(kvds.add(&key, sizeof(key), &val_add, sizeof(val_add)));
00129          BOOST_REQUIRE(kvds.cnt(cnt));
00130          BOOST_REQUIRE(++ecnt == cnt);
00131 
00132          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size1));
00133          BOOST_REQUIRE(sizeof(val_get) == val_get_size1);
00134          BOOST_REQUIRE(val_add == val_get);
00135 
00136          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size2));
00137          BOOST_REQUIRE(sizeof(val_get) == val_get_size2);
00138          BOOST_REQUIRE(val_add == val_get);
00139 
00140          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size3));
00141          BOOST_REQUIRE(1 == val_get_size3);
00142          BOOST_REQUIRE(val_add == val_get);
00143       }
00144    }
00145 
00146    void test_put_cnt_get(kvds_type & kvds, bool bCheckCnt = true)
00147    {
00148       uint32_t const val_put_mask = val0_mask;
00149       boost::uint64_t ecnt = 0;
00150 
00151       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00152       {
00153          uint32_t const val_put = key ^ val_put_mask;
00154          uint32_t val_get = 0;
00155          size_t val_get_size1 = sizeof(val_get);
00156          size_t val_get_size2 = sizeof(val_get) + 2;
00157          size_t val_get_size3 = 1;
00158 
00159          BOOST_REQUIRE(kvds.put(&key, sizeof(key), &val_put, sizeof(val_put)));
00160 
00161          if(bCheckCnt)
00162          {
00163             boost::uint64_t cnt = 0;
00164             BOOST_REQUIRE(kvds.cnt(cnt));
00165             BOOST_REQUIRE(++ecnt == cnt);
00166          }
00167 
00168          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size1));
00169          BOOST_REQUIRE(sizeof(val_get) == val_get_size1);
00170          BOOST_REQUIRE(val_put == val_get);
00171 
00172          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size2));
00173          BOOST_REQUIRE(sizeof(val_get) == val_get_size2);
00174          BOOST_REQUIRE(val_put == val_get);
00175 
00176          BOOST_REQUIRE(kvds.get(&key, sizeof(key), &val_get, val_get_size3));
00177          BOOST_REQUIRE(1 == val_get_size3);
00178          BOOST_REQUIRE(val_put == val_get);
00179       }
00180    }
00181 
00182    void test_add_all(kvds_type & kvds)
00183    {
00184       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00185       {
00186          uint32_t const val_add = key ^ val1_mask;
00187          uint32_t val_get[2] = { 0 };
00188          size_t val_get_size = sizeof(val_get);
00189 
00190          BOOST_REQUIRE(kvds.add(&key, sizeof(key), &val_add, sizeof(val_add)));
00191          BOOST_REQUIRE(kvds.all(&key, sizeof(key), &val_get, val_get_size));
00192          BOOST_REQUIRE(sizeof(val_get) == val_get_size);
00193          BOOST_REQUIRE((key ^ val0_mask) == val_get[0]);
00194          BOOST_REQUIRE((key ^ val1_mask) == val_get[1]);
00195       }
00196    }
00197 
00198    void test_beg_nxt_end(kvds_type & kvds)
00199    {
00200       uint32_t key = 0;
00201       size_t key_size = sizeof(key);
00202 
00203       // Not called beg() yet so this should signal end!
00204       BOOST_REQUIRE(kvds.end());
00205       BOOST_REQUIRE(!kvds.nxt(&key, key_size));
00206       BOOST_REQUIRE(0 == key_size);
00207 
00208       // Keys come out in no particular order, so we need
00209       // to build a set of keys we expect to see
00210       std::set<uint32_t> keySet;
00211 
00212       // Build a set of all they keys we expect to see
00213       for(key = 1 ; key != 0 ; key <<= 1)
00214       {
00215          keySet.insert(key);
00216       }
00217 
00218       BOOST_REQUIRE(kvds.beg());
00219       for(uint32_t cnt = 1 ; cnt != 0 ; cnt <<= 1)
00220       {
00221          for(int testcase = 0; testcase < 2 ; ++testcase)
00222          {
00223             BOOST_REQUIRE(!kvds.end());
00224 
00225             switch(testcase)
00226             {
00227             case 0: // Key too small, this should NOT progress the iterator
00228                {
00229                   key_size = 0;
00230                   BOOST_REQUIRE(!kvds.end());
00231                   BOOST_REQUIRE(!kvds.nxt(&key, key_size));
00232                   BOOST_REQUIRE(sizeof(key) == key_size);
00233                }
00234                break;
00235             case 1: // This should work and progress the iterator
00236                {
00237                   // This should work and progress the iterator
00238                   key_size = sizeof(key);
00239                   BOOST_REQUIRE(!kvds.end());
00240                   BOOST_REQUIRE(kvds.nxt(&key, key_size));
00241                   BOOST_REQUIRE(sizeof(key) == key_size);
00242                   BOOST_REQUIRE(keySet.find(key) != keySet.end());
00243 
00244                   // Found it now remove it, we shouldn't see it again
00245                   keySet.erase(key);
00246                }
00247                break;
00248             default:
00249                throw std::runtime_error("Unknown test case for test_beg_nxt_end()");
00250             }
00251          }
00252       }
00253 
00254       // We should now be at the end of the iteration
00255       // Not called beg() yet so this should signal end!
00256       BOOST_REQUIRE(kvds.end());
00257       BOOST_REQUIRE(!kvds.nxt(&key, key_size));
00258       BOOST_REQUIRE(0 == key_size);
00259 
00260       // We populated out keySet with all the keys we expected
00261       // to see if there are any left something when wrong
00262       BOOST_REQUIRE(keySet.empty());
00263    }
00264 
00265    void test_get_all(kvds_type & kvds)
00266    {
00267       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00268       {
00269          for(int testcase = 0 ; testcase < 4 ; ++testcase)
00270          {
00271             uint32_t val_all[2] = { 0 };
00272             size_t val_all_size = sizeof(val_all);
00273 
00274             switch(testcase)
00275             {
00276             case 0 : // key not found
00277                {
00278                   uint32_t badkey = ~key;
00279                   BOOST_REQUIRE(!kvds.all(&badkey, sizeof(badkey), &val_all, val_all_size));
00280                   BOOST_REQUIRE(0 == val_all_size);
00281                }
00282                break;
00283             case 1 : // key found but value too small
00284                {
00285                   uint32_t bad_val_all[1] = { 0 };
00286                   val_all_size = sizeof(bad_val_all);
00287                   BOOST_REQUIRE(!kvds.all(&key, sizeof(key), &bad_val_all, val_all_size));
00288                   BOOST_REQUIRE(sizeof(val_all) == val_all_size);
00289                }
00290                break;
00291             case 2 : // key found and value correct size
00292                {
00293                   BOOST_REQUIRE(kvds.all(&key, sizeof(key), &val_all, val_all_size));
00294                   BOOST_REQUIRE(sizeof(val_all) == val_all_size);
00295                   BOOST_REQUIRE((key ^ val0_mask) == val_all[0]);
00296                   BOOST_REQUIRE((key ^ val1_mask) == val_all[1]);
00297                }
00298                break;
00299             case 3 : // key found but value larger than required
00300                {
00301                   uint32_t good_val_all[3] = { 0 };
00302                   val_all_size = sizeof(good_val_all);
00303                   BOOST_REQUIRE(kvds.all(&key, sizeof(key), &good_val_all, val_all_size));
00304                   BOOST_REQUIRE(sizeof(val_all) == val_all_size);
00305                   BOOST_REQUIRE((key ^ val0_mask) == good_val_all[0]);
00306                   BOOST_REQUIRE((key ^ val1_mask) == good_val_all[1]);
00307                }
00308                break;
00309             default:
00310                throw std::runtime_error("Unknown test case for test_get_all()");
00311             }
00312          }
00313       }
00314    }
00315 
00316    void test_xst_del(kvds_type & kvds)
00317    {
00318       for(uint32_t key = 1 ; key != 0 ; key <<= 1)
00319       {
00320          BOOST_REQUIRE(kvds.xst(&key, sizeof(key)));
00321          BOOST_REQUIRE(kvds.del(&key, sizeof(key)));
00322          BOOST_REQUIRE(!kvds.xst(&key, sizeof(key)));
00323       }
00324    }
00325 
00326    void test_nil(kvds_type & kvds, bool const nil = true)
00327    {
00328       bool isnil = false;
00329       BOOST_REQUIRE(kvds.nil(isnil));
00330       BOOST_REQUIRE(isnil == nil);
00331    }
00332 
00333    void test_clr_nil(kvds_type & kvds)
00334    {
00335       BOOST_REQUIRE(kvds.clr());
00336 
00337       bool isnil = false;
00338       BOOST_REQUIRE(kvds.nil(isnil));
00339       BOOST_REQUIRE(isnil);
00340    }
00341 
00342    void test_put_add_get(kvds_type & kvds)
00343    {
00344       uint32_t key = {0xF0F0F0F0};
00345       uint32_t put_vals[] = {0x29292929, 0xABABABAB};
00346 
00347       BOOST_REQUIRE(kvds.put(&key, sizeof(key), &put_vals[0], sizeof(put_vals[0])));
00348 
00349       uint32_t get_val = 0;
00350       size_t get_val_size = sizeof(get_val);
00351 
00352       BOOST_REQUIRE(kvds.get(&key, sizeof(key), &get_val, get_val_size));
00353       BOOST_REQUIRE(sizeof(get_val) == get_val_size);
00354       BOOST_REQUIRE(get_val == put_vals[0]);
00355 
00356       BOOST_REQUIRE(kvds.add(&key, sizeof(key), &put_vals[1], sizeof(put_vals[2])));
00357 
00358       uint32_t all_vals[2] = { 0 };
00359       size_t all_val_size = sizeof(all_vals);
00360 
00361       BOOST_REQUIRE(kvds.all(&key, sizeof(key), all_vals, all_val_size));
00362       BOOST_REQUIRE(sizeof(all_vals) == all_val_size);
00363       BOOST_REQUIRE(all_vals[0] == put_vals[0]);
00364       BOOST_REQUIRE(all_vals[1] == put_vals[1]);
00365    }
00366 
00367 public:
00368 
00369    void operator()(kvds_type & kvds)
00370    {
00371       // Since tests are dependent on each other to build up the
00372       // datastore if any test fails we fail them all.
00373       // All tests MUST be run in the order presented!
00374 
00375       test_nil(kvds);
00376       test_siz(kvds, 0, false);
00377       test_put_add_get(kvds);
00378       test_clr_nil(kvds);
00379       test_get_noexist(kvds);
00380       test_add_cnt_get(kvds);
00381       test_nil(kvds, false);
00382       test_put_cnt_get(kvds, false);
00383       test_nil(kvds, false);
00384       test_clr_nil(kvds);
00385       test_put_cnt_get(kvds);
00386       test_nil(kvds, false);
00387       test_siz(kvds, 1);
00388       test_add_all(kvds);
00389       test_nil(kvds, false);
00390       test_siz(kvds, 2);
00391       test_get_all(kvds);
00392       test_beg_nxt_end(kvds);
00393       test_xst_del(kvds);
00394    }
00395 };
00396 
00397 
00398 BOOST_FIXTURE_TEST_CASE( test_kvds_bbt, Fixture )
00399 {
00400    KvdsBbt kvds;
00401    kvds.open(tdc.GetFilePath("KvdsBbt").c_str());
00402    IKvdsTester()(kvds);
00403 }
00404 
00405 BOOST_FIXTURE_TEST_CASE( test_kvds_bht, Fixture )
00406 {
00407    KvdsBht kvds;
00408    kvds.open(tdc.GetFilePath("KvdsBht").c_str());
00409    IKvdsTester()(kvds);
00410 }
00411 
00412 BOOST_FIXTURE_TEST_CASE( test_kvds_page_store_intrinsic_pagemap, Fixture )
00413 {
00414    KvdsPageStore<KvdsPageMapIntrinsicKey<uint32_t> > kvds;
00415    kvds.open(tdc.GetFilePath("KvdsPageStore").c_str());
00416    IKvdsTester()(kvds);
00417 }
00418 
00419 BOOST_FIXTURE_TEST_CASE( test_kvds_page_store_nonintrinsic_pagemap, Fixture )
00420 {
00421    KvdsPageStore<KvdsPageMapNonIntrinsicKey<> > kvds;
00422    kvds.open(tdc.GetFilePath("KvdsPageStore").c_str());
00423    IKvdsTester()(kvds);
00424 }
00425 
00426 BOOST_FIXTURE_TEST_CASE( test_kvds_page_store_intrinsic_shared_pagemap, Fixture )
00427 {
00428    KvdsPageStore<KvdsPageMapShared<KvdsPageMapIntrinsicKey<uint32_t> > >kvds;
00429    kvds.open(tdc.GetFilePath("KvdsPageStore").c_str());
00430    IKvdsTester()(kvds);
00431 }
00432 
00433 BOOST_FIXTURE_TEST_CASE( test_kvds_page_store_nonintrinsic_shared_pagemap, Fixture )
00434 {
00435    KvdsPageStore<KvdsPageMapShared <KvdsPageMapNonIntrinsicKey<> > >kvds;
00436    kvds.open(tdc.GetFilePath("KvdsPageStore").c_str());
00437    IKvdsTester()(kvds);
00438 }
00439 
00440 BOOST_FIXTURE_TEST_CASE( test_kvds_tch, Fixture )
00441 {
00442    KvdsTch kvds;
00443    kvds.open(tdc.GetFilePath("KvdsTch").c_str());
00444    IKvdsTester()(kvds);
00445 }
00446 
00447 BOOST_FIXTURE_TEST_CASE( test_kvds_kch, Fixture )
00448 {
00449    KvdsKch kvds;
00450    kvds.open(tdc.GetFilePath("KvdsKch").c_str());
00451    IKvdsTester()(kvds);
00452 }
00453 
00454 BOOST_FIXTURE_TEST_CASE( test_kvds_mem_map, Fixture )
00455 {
00456    KvdsMemMap kvds;
00457    // This test doesn't need opening :)
00458    IKvdsTester()(kvds);
00459 }
00460 
00461 // Define end of test suite
00462 BOOST_AUTO_TEST_SUITE_END()