libmoost
|
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()