1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2012 Inktank, Inc.
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
13 #include "include/memory.h"
17 #include <boost/scoped_ptr.hpp>
19 #include "test/ObjectMap/KeyValueDBMemory.h"
20 #include "kv/KeyValueDB.h"
21 #include <sys/types.h>
22 #include "global/global_init.h"
23 #include "common/ceph_argparse.h"
24 #include "gtest/gtest.h"
30 class IteratorTest : public ::testing::Test
33 boost::scoped_ptr<KeyValueDB> db;
34 boost::scoped_ptr<KeyValueDBMemory> mock;
36 void SetUp() override {
37 assert(!store_path.empty());
39 KeyValueDB *db_ptr = KeyValueDB::create(g_ceph_context, "leveldb", store_path);
40 assert(!db_ptr->create_and_open(std::cerr));
42 mock.reset(new KeyValueDBMemory());
45 void TearDown() override { }
47 ::testing::AssertionResult validate_db_clear(KeyValueDB *store) {
48 KeyValueDB::WholeSpaceIterator it = store->get_iterator();
51 pair<string,string> k = it->raw_key();
52 if (mock->db.count(k)) {
53 return ::testing::AssertionFailure()
55 << " mock store count " << mock->db.count(k)
56 << " key(" << k.first << "," << k.second << ")";
60 return ::testing::AssertionSuccess();
63 ::testing::AssertionResult validate_db_match() {
64 KeyValueDB::WholeSpaceIterator it = db->get_iterator();
67 pair<string, string> k = it->raw_key();
68 if (!mock->db.count(k)) {
69 return ::testing::AssertionFailure()
71 << " mock db.count() " << mock->db.count(k)
72 << " key(" << k.first << "," << k.second << ")";
75 bufferlist it_bl = it->value();
76 bufferlist mock_bl = mock->db[k];
78 string it_val = _bl_to_str(it_bl);
79 string mock_val = _bl_to_str(mock_bl);
81 if (it_val != mock_val) {
82 return ::testing::AssertionFailure()
84 << " key(" << k.first << "," << k.second << ")"
85 << " mismatch db value(" << it_val << ")"
86 << " mock value(" << mock_val << ")";
90 return ::testing::AssertionSuccess();
93 ::testing::AssertionResult validate_iterator(
94 KeyValueDB::WholeSpaceIterator it,
95 string expected_prefix,
97 string expected_value) {
99 return ::testing::AssertionFailure()
101 << " iterator not valid";
104 if (!it->raw_key_is_prefixed(expected_prefix)) {
105 return ::testing::AssertionFailure()
107 << " expected raw_key_is_prefixed() == TRUE"
111 if (it->raw_key_is_prefixed("??__SomeUnexpectedValue__??")) {
112 return ::testing::AssertionFailure()
114 << " expected raw_key_is_prefixed() == FALSE"
118 pair<string,string> key = it->raw_key();
120 if (expected_prefix != key.first) {
121 return ::testing::AssertionFailure()
123 << " expected prefix '" << expected_prefix << "'"
124 << " got prefix '" << key.first << "'";
127 if (expected_key != it->key()) {
128 return ::testing::AssertionFailure()
130 << " expected key '" << expected_key << "'"
131 << " got key '" << it->key() << "'";
134 if (it->key() != key.second) {
135 return ::testing::AssertionFailure()
137 << " key '" << it->key() << "'"
139 << " pair key '" << key.second << "'";
142 if (_bl_to_str(it->value()) != expected_value) {
143 return ::testing::AssertionFailure()
145 << " key '(" << key.first << "," << key.second << ")''"
146 << " expected value '" << expected_value << "'"
147 << " got value '" << _bl_to_str(it->value()) << "'";
150 return ::testing::AssertionSuccess();
154 * Checks if each key in the queue can be forward sequentially read from
155 * the iterator iter. All keys must be present and be prefixed with prefix,
156 * otherwise the validation will fail.
158 * Assumes that each key value must be based on the key name and generated
161 void validate_prefix(KeyValueDB::WholeSpaceIterator iter,
162 string &prefix, deque<string> &keys) {
164 while (!keys.empty()) {
165 ASSERT_TRUE(iter->valid());
166 string expected_key = keys.front();
168 string expected_value = _gen_val_str(expected_key);
170 ASSERT_TRUE(validate_iterator(iter, prefix,
171 expected_key, expected_value));
177 * Checks if each key in the queue can be backward sequentially read from
178 * the iterator iter. All keys must be present and be prefixed with prefix,
179 * otherwise the validation will fail.
181 * Assumes that each key value must be based on the key name and generated
184 void validate_prefix_backwards(KeyValueDB::WholeSpaceIterator iter,
185 string &prefix, deque<string> &keys) {
187 while (!keys.empty()) {
188 ASSERT_TRUE(iter->valid());
189 string expected_key = keys.front();
191 string expected_value = _gen_val_str(expected_key);
193 ASSERT_TRUE(validate_iterator(iter, prefix,
194 expected_key, expected_value));
200 void clear(KeyValueDB *store) {
201 KeyValueDB::WholeSpaceIterator it = store->get_iterator();
203 KeyValueDB::Transaction t = store->get_transaction();
204 while (it->valid()) {
205 pair<string,string> k = it->raw_key();
206 t->rmkey(k.first, k.second);
209 store->submit_transaction_sync(t);
212 string _bl_to_str(bufferlist val) {
213 string str(val.c_str(), val.length());
217 string _gen_val_str(string key) {
219 ss << "##value##" << key << "##";
223 bufferlist _gen_val(string key) {
225 bl.append(_gen_val_str(key));
229 void print_iterator(KeyValueDB::WholeSpaceIterator iter) {
230 if (!iter->valid()) {
231 std::cerr << __func__ << " iterator is not valid; stop." << std::endl;
236 while (iter->valid()) {
237 pair<string,string> k = iter->raw_key();
238 std::cerr << __func__
240 << " key (" << k.first << "," << k.second << ")"
241 << " value(" << _bl_to_str(iter->value()) << ")" << std::endl;
246 void print_db(KeyValueDB *store) {
247 KeyValueDB::WholeSpaceIterator it = store->get_iterator();
253 // ------- Remove Keys / Remove Keys By Prefix -------
254 class RmKeysTest : public IteratorTest
261 void init(KeyValueDB *db) {
262 KeyValueDB::Transaction tx = db->get_transaction();
264 tx->set(prefix1, "11", _gen_val("11"));
265 tx->set(prefix1, "12", _gen_val("12"));
266 tx->set(prefix1, "13", _gen_val("13"));
267 tx->set(prefix2, "21", _gen_val("21"));
268 tx->set(prefix2, "22", _gen_val("22"));
269 tx->set(prefix2, "23", _gen_val("23"));
270 tx->set(prefix3, "31", _gen_val("31"));
271 tx->set(prefix3, "32", _gen_val("32"));
272 tx->set(prefix3, "33", _gen_val("33"));
274 db->submit_transaction_sync(tx);
277 void SetUp() override {
278 IteratorTest::SetUp();
280 prefix1 = "_PREFIX_1_";
281 prefix2 = "_PREFIX_2_";
282 prefix3 = "_PREFIX_3_";
285 ASSERT_TRUE(validate_db_clear(db.get()));
287 ASSERT_TRUE(validate_db_match());
292 ASSERT_TRUE(validate_db_match());
295 void TearDown() override {
296 IteratorTest::TearDown();
301 * Test the transaction's rmkeys behavior when we remove a given prefix
302 * from the beginning of the key space, or from the end of the key space,
303 * or even simply in the middle.
305 void RmKeysByPrefix(KeyValueDB *store) {
306 // remove prefix2 ; check if prefix1 remains, and then prefix3
307 KeyValueDB::Transaction tx = store->get_transaction();
308 // remove the prefix in the middle of the key space
309 tx->rmkeys_by_prefix(prefix2);
310 store->submit_transaction_sync(tx);
312 deque<string> key_deque;
313 KeyValueDB::WholeSpaceIterator iter = store->get_iterator();
314 iter->seek_to_first();
317 key_deque.push_back("11");
318 key_deque.push_back("12");
319 key_deque.push_back("13");
320 validate_prefix(iter, prefix1, key_deque);
321 ASSERT_FALSE(HasFatalFailure());
324 ASSERT_TRUE(iter->valid());
326 key_deque.push_back("31");
327 key_deque.push_back("32");
328 key_deque.push_back("33");
329 validate_prefix(iter, prefix3, key_deque);
330 ASSERT_FALSE(HasFatalFailure());
332 ASSERT_FALSE(iter->valid());
335 ASSERT_TRUE(validate_db_clear(store));
338 // remove prefix1 ; check if prefix2 and then prefix3 remain
339 tx = store->get_transaction();
340 // remove the prefix at the beginning of the key space
341 tx->rmkeys_by_prefix(prefix1);
342 store->submit_transaction_sync(tx);
344 iter = store->get_iterator();
345 iter->seek_to_first();
349 key_deque.push_back("21");
350 key_deque.push_back("22");
351 key_deque.push_back("23");
352 validate_prefix(iter, prefix2, key_deque);
353 ASSERT_FALSE(HasFatalFailure());
356 ASSERT_TRUE(iter->valid());
358 key_deque.push_back("31");
359 key_deque.push_back("32");
360 key_deque.push_back("33");
361 validate_prefix(iter, prefix3, key_deque);
362 ASSERT_FALSE(HasFatalFailure());
364 ASSERT_FALSE(iter->valid());
367 ASSERT_TRUE(validate_db_clear(store));
370 // remove prefix3 ; check if prefix1 and then prefix2 remain
371 tx = store->get_transaction();
372 // remove the prefix at the end of the key space
373 tx->rmkeys_by_prefix(prefix3);
374 store->submit_transaction_sync(tx);
376 iter = store->get_iterator();
377 iter->seek_to_first();
381 key_deque.push_back("11");
382 key_deque.push_back("12");
383 key_deque.push_back("13");
384 validate_prefix(iter, prefix1, key_deque);
385 ASSERT_FALSE(HasFatalFailure());
388 ASSERT_TRUE(iter->valid());
390 key_deque.push_back("21");
391 key_deque.push_back("22");
392 key_deque.push_back("23");
393 validate_prefix(iter, prefix2, key_deque);
394 ASSERT_FALSE(HasFatalFailure());
396 ASSERT_FALSE(iter->valid());
400 * Test how the leveldb's whole-space iterator behaves when we remove
401 * keys from the store while iterating over them.
403 void RmKeysWhileIteratingSnapshot(KeyValueDB *store,
404 KeyValueDB::WholeSpaceIterator iter) {
406 SCOPED_TRACE("RmKeysWhileIteratingSnapshot");
408 iter->seek_to_first();
409 ASSERT_TRUE(iter->valid());
411 KeyValueDB::Transaction t = store->get_transaction();
412 t->rmkey(prefix1, "11");
413 t->rmkey(prefix1, "12");
414 t->rmkey(prefix2, "23");
415 t->rmkey(prefix3, "33");
416 store->submit_transaction_sync(t);
418 deque<string> key_deque;
421 key_deque.push_back("11");
422 key_deque.push_back("12");
423 key_deque.push_back("13");
424 validate_prefix(iter, prefix1, key_deque);
425 ASSERT_FALSE(HasFatalFailure());
429 key_deque.push_back("21");
430 key_deque.push_back("22");
431 key_deque.push_back("23");
432 validate_prefix(iter, prefix2, key_deque);
433 ASSERT_FALSE(HasFatalFailure());
437 key_deque.push_back("31");
438 key_deque.push_back("32");
439 key_deque.push_back("33");
440 validate_prefix(iter, prefix3, key_deque);
441 ASSERT_FALSE(HasFatalFailure());
444 ASSERT_FALSE(iter->valid());
446 // make sure those keys were removed from the store
447 KeyValueDB::WholeSpaceIterator tmp_it = store->get_iterator();
448 tmp_it->seek_to_first();
449 ASSERT_TRUE(tmp_it->valid());
452 key_deque.push_back("13");
453 validate_prefix(tmp_it, prefix1, key_deque);
454 ASSERT_FALSE(HasFatalFailure());
456 ASSERT_TRUE(tmp_it->valid());
458 key_deque.push_back("21");
459 key_deque.push_back("22");
460 validate_prefix(tmp_it, prefix2, key_deque);
461 ASSERT_FALSE(HasFatalFailure());
463 ASSERT_TRUE(tmp_it->valid());
465 key_deque.push_back("31");
466 key_deque.push_back("32");
467 validate_prefix(tmp_it, prefix3, key_deque);
468 ASSERT_FALSE(HasFatalFailure());
470 ASSERT_FALSE(tmp_it->valid());
474 TEST_F(RmKeysTest, RmKeysByPrefixLevelDB)
476 SCOPED_TRACE("LevelDB");
477 RmKeysByPrefix(db.get());
478 ASSERT_FALSE(HasFatalFailure());
481 TEST_F(RmKeysTest, RmKeysByPrefixMockDB)
483 SCOPED_TRACE("Mock DB");
484 RmKeysByPrefix(mock.get());
485 ASSERT_FALSE(HasFatalFailure());
489 * If you refer to function RmKeysTest::RmKeysWhileIteratingSnapshot(),
490 * you will notice that we seek the iterator to the first key, and then
491 * we go on to remove several keys from the underlying store, including
492 * the first couple keys.
494 * We would expect that during this test, as soon as we removed the keys
495 * from the store, the iterator would get invalid, or cause some sort of
498 * Instead, the current version of leveldb handles it perfectly, by making
499 * the iterator to use a snapshot instead of the store's real state. This
500 * way, LevelDBStore's whole-space iterator will behave much like its own
501 * whole-space snapshot iterator.
503 * However, this particular behavior of the iterator hasn't been documented
504 * on leveldb, and we should assume that it can be changed at any point in
507 * Therefore, we keep this test, being exactly the same as the one for the
508 * whole-space snapshot iterator, as we currently assume they should behave
509 * identically. If this test fails, at some point, and the whole-space
510 * snapshot iterator passes, then it probably means that leveldb changed
511 * how its iterator behaves.
513 TEST_F(RmKeysTest, RmKeysWhileIteratingLevelDB)
515 SCOPED_TRACE("LevelDB -- WholeSpaceIterator");
516 RmKeysWhileIteratingSnapshot(db.get(), db->get_iterator());
517 ASSERT_FALSE(HasFatalFailure());
520 TEST_F(RmKeysTest, RmKeysWhileIteratingMockDB)
522 std::cout << "There is no safe way to test key removal while iterating\n"
523 << "over the mock store without using snapshots" << std::endl;
526 // ------- Set Keys / Update Values -------
527 class SetKeysTest : public IteratorTest
533 void init(KeyValueDB *db) {
534 KeyValueDB::Transaction tx = db->get_transaction();
536 tx->set(prefix1, "aaa", _gen_val("aaa"));
537 tx->set(prefix1, "ccc", _gen_val("ccc"));
538 tx->set(prefix1, "eee", _gen_val("eee"));
539 tx->set(prefix2, "vvv", _gen_val("vvv"));
540 tx->set(prefix2, "xxx", _gen_val("xxx"));
541 tx->set(prefix2, "zzz", _gen_val("zzz"));
543 db->submit_transaction_sync(tx);
546 void SetUp() override {
547 IteratorTest::SetUp();
549 prefix1 = "_PREFIX_1_";
550 prefix2 = "_PREFIX_2_";
553 ASSERT_TRUE(validate_db_clear(db.get()));
555 ASSERT_TRUE(validate_db_match());
560 ASSERT_TRUE(validate_db_match());
563 void TearDown() override {
564 IteratorTest::TearDown();
568 * Make sure that the iterator picks on new keys added if it hasn't yet
569 * iterated away from that position.
571 * This should only happen for the whole-space iterator when not using
572 * the snapshot version.
574 * We don't need to test the validity of all elements, but we do test
575 * inserting while moving from the first element to the last, using next()
576 * to move forward, and then we test the same behavior while iterating
577 * from the last element to the first, using prev() to move backwards.
579 void SetKeysWhileIterating(KeyValueDB *store,
580 KeyValueDB::WholeSpaceIterator iter) {
581 iter->seek_to_first();
582 ASSERT_TRUE(iter->valid());
583 ASSERT_TRUE(validate_iterator(iter, prefix1, "aaa",
584 _gen_val_str("aaa")));
586 ASSERT_TRUE(iter->valid());
587 ASSERT_TRUE(validate_iterator(iter, prefix1, "ccc",
588 _bl_to_str(_gen_val("ccc"))));
590 // insert new key 'ddd' after 'ccc' and before 'eee'
591 KeyValueDB::Transaction tx = store->get_transaction();
592 tx->set(prefix1, "ddd", _gen_val("ddd"));
593 store->submit_transaction_sync(tx);
596 ASSERT_TRUE(iter->valid());
597 ASSERT_TRUE(validate_iterator(iter, prefix1, "ddd",
598 _gen_val_str("ddd")));
600 iter->seek_to_last();
601 ASSERT_TRUE(iter->valid());
602 tx = store->get_transaction();
603 tx->set(prefix2, "yyy", _gen_val("yyy"));
604 store->submit_transaction_sync(tx);
607 ASSERT_TRUE(iter->valid());
608 ASSERT_TRUE(validate_iterator(iter, prefix2,
609 "yyy", _gen_val_str("yyy")));
613 * Make sure that the whole-space snapshot iterator does not pick on new keys
614 * added to the store since we created the iterator, thus guaranteeing
617 * We don't need to test the validity of all elements, but we do test
618 * inserting while moving from the first element to the last, using next()
619 * to move forward, and then we test the same behavior while iterating
620 * from the last element to the first, using prev() to move backwards.
622 void SetKeysWhileIteratingSnapshot(KeyValueDB *store,
623 KeyValueDB::WholeSpaceIterator iter) {
624 iter->seek_to_first();
625 ASSERT_TRUE(iter->valid());
626 ASSERT_TRUE(validate_iterator(iter, prefix1, "aaa",
627 _gen_val_str("aaa")));
629 ASSERT_TRUE(iter->valid());
630 ASSERT_TRUE(validate_iterator(iter, prefix1, "ccc",
631 _bl_to_str(_gen_val("ccc"))));
633 // insert new key 'ddd' after 'ccc' and before 'eee'
634 KeyValueDB::Transaction tx = store->get_transaction();
635 tx->set(prefix1, "ddd", _gen_val("ddd"));
636 store->submit_transaction_sync(tx);
639 ASSERT_TRUE(iter->valid());
640 ASSERT_TRUE(validate_iterator(iter, prefix1, "eee",
641 _gen_val_str("eee")));
643 iter->seek_to_last();
644 ASSERT_TRUE(iter->valid());
645 tx = store->get_transaction();
646 tx->set(prefix2, "yyy", _gen_val("yyy"));
647 store->submit_transaction_sync(tx);
650 ASSERT_TRUE(iter->valid());
651 ASSERT_TRUE(validate_iterator(iter, prefix2,
652 "xxx", _gen_val_str("xxx")));
656 * Make sure that the whole-space iterator is able to read values changed on
657 * the store, even after we moved to the updated position.
659 * This should only be possible when not using the whole-space snapshot
660 * version of the iterator.
662 void UpdateValuesWhileIterating(KeyValueDB *store,
663 KeyValueDB::WholeSpaceIterator iter) {
664 iter->seek_to_first();
665 ASSERT_TRUE(iter->valid());
666 ASSERT_TRUE(validate_iterator(iter, prefix1,
667 "aaa", _gen_val_str("aaa")));
669 KeyValueDB::Transaction tx = store->get_transaction();
670 tx->set(prefix1, "aaa", _gen_val("aaa_1"));
671 store->submit_transaction_sync(tx);
673 ASSERT_TRUE(validate_iterator(iter, prefix1,
674 "aaa", _gen_val_str("aaa_1")));
676 iter->seek_to_last();
677 ASSERT_TRUE(iter->valid());
678 ASSERT_TRUE(validate_iterator(iter, prefix2,
679 "zzz", _gen_val_str("zzz")));
681 tx = store->get_transaction();
682 tx->set(prefix2, "zzz", _gen_val("zzz_1"));
683 store->submit_transaction_sync(tx);
685 ASSERT_TRUE(validate_iterator(iter, prefix2,
686 "zzz", _gen_val_str("zzz_1")));
690 * Make sure that the whole-space iterator is able to read values changed on
691 * the store, even after we moved to the updated position.
693 * This should only be possible when not using the whole-space snapshot
694 * version of the iterator.
696 void UpdateValuesWhileIteratingSnapshot(
698 KeyValueDB::WholeSpaceIterator iter) {
699 iter->seek_to_first();
700 ASSERT_TRUE(iter->valid());
701 ASSERT_TRUE(validate_iterator(iter, prefix1,
702 "aaa", _gen_val_str("aaa")));
704 KeyValueDB::Transaction tx = store->get_transaction();
705 tx->set(prefix1, "aaa", _gen_val("aaa_1"));
706 store->submit_transaction_sync(tx);
708 ASSERT_TRUE(validate_iterator(iter, prefix1,
709 "aaa", _gen_val_str("aaa")));
711 iter->seek_to_last();
712 ASSERT_TRUE(iter->valid());
713 ASSERT_TRUE(validate_iterator(iter, prefix2,
714 "zzz", _gen_val_str("zzz")));
716 tx = store->get_transaction();
717 tx->set(prefix2, "zzz", _gen_val("zzz_1"));
718 store->submit_transaction_sync(tx);
720 ASSERT_TRUE(validate_iterator(iter, prefix2,
721 "zzz", _gen_val_str("zzz")));
723 // check those values were really changed in the store
724 KeyValueDB::WholeSpaceIterator tmp_iter = store->get_iterator();
725 tmp_iter->seek_to_first();
726 ASSERT_TRUE(tmp_iter->valid());
727 ASSERT_TRUE(validate_iterator(tmp_iter, prefix1,
728 "aaa", _gen_val_str("aaa_1")));
729 tmp_iter->seek_to_last();
730 ASSERT_TRUE(tmp_iter->valid());
731 ASSERT_TRUE(validate_iterator(tmp_iter, prefix2,
732 "zzz", _gen_val_str("zzz_1")));
738 TEST_F(SetKeysTest, DISABLED_SetKeysWhileIteratingLevelDB)
740 SCOPED_TRACE("LevelDB: SetKeysWhileIteratingLevelDB");
741 SetKeysWhileIterating(db.get(), db->get_iterator());
742 ASSERT_TRUE(HasFatalFailure());
745 TEST_F(SetKeysTest, SetKeysWhileIteratingMockDB)
747 SCOPED_TRACE("Mock DB: SetKeysWhileIteratingMockDB");
748 SetKeysWhileIterating(mock.get(), mock->get_iterator());
749 ASSERT_FALSE(HasFatalFailure());
752 TEST_F(SetKeysTest, DISABLED_UpdateValuesWhileIteratingLevelDB)
754 SCOPED_TRACE("LevelDB: UpdateValuesWhileIteratingLevelDB");
755 UpdateValuesWhileIterating(db.get(), db->get_iterator());
756 ASSERT_FALSE(HasFatalFailure());
759 TEST_F(SetKeysTest, UpdateValuesWhileIteratingMockDB)
761 SCOPED_TRACE("MockDB: UpdateValuesWhileIteratingMockDB");
762 UpdateValuesWhileIterating(mock.get(), mock->get_iterator());
763 ASSERT_FALSE(HasFatalFailure());
766 class BoundsTest : public IteratorTest
773 void init(KeyValueDB *store) {
774 KeyValueDB::Transaction tx = store->get_transaction();
776 tx->set(prefix1, "aaa", _gen_val("aaa"));
777 tx->set(prefix1, "ccc", _gen_val("ccc"));
778 tx->set(prefix1, "eee", _gen_val("eee"));
779 tx->set(prefix2, "vvv", _gen_val("vvv"));
780 tx->set(prefix2, "xxx", _gen_val("xxx"));
781 tx->set(prefix2, "zzz", _gen_val("zzz"));
782 tx->set(prefix3, "aaa", _gen_val("aaa"));
783 tx->set(prefix3, "mmm", _gen_val("mmm"));
784 tx->set(prefix3, "yyy", _gen_val("yyy"));
786 store->submit_transaction_sync(tx);
789 void SetUp() override {
790 IteratorTest::SetUp();
792 prefix1 = "_PREFIX_1_";
793 prefix2 = "_PREFIX_2_";
794 prefix3 = "_PREFIX_4_";
797 ASSERT_TRUE(validate_db_clear(db.get()));
799 ASSERT_TRUE(validate_db_match());
804 ASSERT_TRUE(validate_db_match());
807 void TearDown() override {
808 IteratorTest::TearDown();
811 void LowerBoundWithEmptyKeyOnWholeSpaceIterator(
812 KeyValueDB::WholeSpaceIterator iter) {
813 deque<string> key_deque;
814 // see what happens when we have an empty key and try to get to the
815 // first available prefix
816 iter->lower_bound(prefix1, "");
817 ASSERT_TRUE(iter->valid());
819 key_deque.push_back("aaa");
820 key_deque.push_back("ccc");
821 key_deque.push_back("eee");
822 validate_prefix(iter, prefix1, key_deque);
823 ASSERT_FALSE(HasFatalFailure());
824 ASSERT_TRUE(iter->valid());
825 // if we got here without problems, then it is safe to assume the
826 // remaining prefixes are intact.
828 // see what happens when we have an empty key and try to get to the
829 // middle of the key-space
830 iter->lower_bound(prefix2, "");
831 ASSERT_TRUE(iter->valid());
834 key_deque.push_back("vvv");
835 key_deque.push_back("xxx");
836 key_deque.push_back("zzz");
837 validate_prefix(iter, prefix2, key_deque);
838 ASSERT_FALSE(HasFatalFailure());
839 ASSERT_TRUE(iter->valid());
840 // if we got here without problems, then it is safe to assume the
841 // remaining prefixes are intact.
843 // see what happens when we have an empty key and try to get to the
844 // last prefix on the key-space
845 iter->lower_bound(prefix3, "");
846 ASSERT_TRUE(iter->valid());
849 key_deque.push_back("aaa");
850 key_deque.push_back("mmm");
851 key_deque.push_back("yyy");
852 validate_prefix(iter, prefix3, key_deque);
853 ASSERT_FALSE(HasFatalFailure());
854 ASSERT_FALSE(iter->valid());
855 // we reached the end of the key_space, so the iterator should no longer
858 // see what happens when we look for an inexistent prefix, that will
859 // compare higher than the existing prefixes, with an empty key
860 // expected: reach the store's end; iterator becomes invalid
861 iter->lower_bound("_PREFIX_9_", "");
862 ASSERT_FALSE(iter->valid());
864 // see what happens when we look for an inexistent prefix, that will
865 // compare lower than the existing prefixes, with an empty key
866 // expected: find the first prefix; iterator is valid
867 iter->lower_bound("_PREFIX_0_", "");
868 ASSERT_TRUE(iter->valid());
870 key_deque.push_back("aaa");
871 key_deque.push_back("ccc");
872 key_deque.push_back("eee");
873 validate_prefix(iter, prefix1, key_deque);
874 ASSERT_FALSE(HasFatalFailure());
875 ASSERT_TRUE(iter->valid());
877 // see what happens when we look for an empty prefix (that should compare
878 // lower than any existing prefixes)
879 // expected: find the first prefix; iterator is valid
880 iter->lower_bound("", "");
881 ASSERT_TRUE(iter->valid());
882 key_deque.push_back("aaa");
883 key_deque.push_back("ccc");
884 key_deque.push_back("eee");
885 validate_prefix(iter, prefix1, key_deque);
886 ASSERT_FALSE(HasFatalFailure());
887 ASSERT_TRUE(iter->valid());
890 void LowerBoundWithEmptyPrefixOnWholeSpaceIterator(
891 KeyValueDB::WholeSpaceIterator iter) {
892 deque<string> key_deque;
893 // check for an empty prefix, with key 'aaa'. Since this key is shared
894 // among two different prefixes, it is relevant to check which will be
896 // expected: find key (prefix1, aaa); iterator is valid
897 iter->lower_bound("", "aaa");
898 ASSERT_TRUE(iter->valid());
900 key_deque.push_back("aaa");
901 key_deque.push_back("ccc");
902 key_deque.push_back("eee");
903 validate_prefix(iter, prefix1, key_deque);
904 ASSERT_FALSE(HasFatalFailure());
905 ASSERT_TRUE(iter->valid());
906 // since we found prefix1, it is safe to assume that the remaining
907 // prefixes (prefix2 and prefix3) will follow
909 // any lower_bound operation with an empty prefix should always put the
910 // iterator in the first key in the key-space, despite what key is
911 // specified. This means that looking for ("","AAAAAAAAAA") should
912 // also position the iterator on (prefix1, aaa).
913 // expected: find key (prefix1, aaa); iterator is valid
914 iter->lower_bound("", "AAAAAAAAAA");
915 ASSERT_TRUE(iter->valid());
917 key_deque.push_back("aaa");
918 key_deque.push_back("ccc");
919 key_deque.push_back("eee");
920 validate_prefix(iter, prefix1, key_deque);
921 ASSERT_FALSE(HasFatalFailure());
922 ASSERT_TRUE(iter->valid());
924 // note: this test is a duplicate of the one in the function above. Why?
925 // Well, because it also fits here (being its prefix empty), and one could
926 // very well run solely this test (instead of the whole battery) and would
927 // certainly expect this case to be tested.
929 // see what happens when we look for an empty prefix (that should compare
930 // lower than any existing prefixes)
931 // expected: find the first prefix; iterator is valid
932 iter->lower_bound("", "");
933 ASSERT_TRUE(iter->valid());
934 key_deque.push_back("aaa");
935 key_deque.push_back("ccc");
936 key_deque.push_back("eee");
937 validate_prefix(iter, prefix1, key_deque);
938 ASSERT_FALSE(HasFatalFailure());
939 ASSERT_TRUE(iter->valid());
942 void LowerBoundOnWholeSpaceIterator(
943 KeyValueDB::WholeSpaceIterator iter) {
944 deque<string> key_deque;
945 // check that we find the first key in the store
946 // expected: find (prefix1, aaa); iterator is valid
947 iter->lower_bound(prefix1, "aaa");
948 ASSERT_TRUE(iter->valid());
949 key_deque.push_back("aaa");
950 validate_prefix(iter, prefix1, key_deque);
951 ASSERT_FALSE(HasFatalFailure());
952 ASSERT_TRUE(iter->valid());
954 // check that we find the last key in the store
955 // expected: find (prefix3, yyy); iterator is valid
956 iter->lower_bound(prefix3, "yyy");
957 ASSERT_TRUE(iter->valid());
959 key_deque.push_back("yyy");
960 validate_prefix(iter, prefix3, key_deque);
961 ASSERT_FALSE(HasFatalFailure());
962 ASSERT_FALSE(iter->valid());
964 // check that looking for non-existent prefix '_PREFIX_0_' will
965 // always result in the first value of prefix1 (prefix1,"aaa")
966 // expected: find (prefix1, aaa); iterator is valid
967 iter->lower_bound("_PREFIX_0_", "AAAAA");
968 ASSERT_TRUE(iter->valid());
970 key_deque.push_back("aaa");
971 validate_prefix(iter, prefix1, key_deque);
972 ASSERT_FALSE(HasFatalFailure());
973 ASSERT_TRUE(iter->valid());
975 // check that looking for non-existent prefix '_PREFIX_3_' will
976 // always result in the first value of prefix3 (prefix4,"aaa")
977 // expected: find (prefix3, aaa); iterator is valid
978 iter->lower_bound("_PREFIX_3_", "AAAAA");
979 ASSERT_TRUE(iter->valid());
981 key_deque.push_back("aaa");
982 validate_prefix(iter, prefix3, key_deque);
983 ASSERT_FALSE(HasFatalFailure());
984 ASSERT_TRUE(iter->valid());
986 // check that looking for non-existent prefix '_PREFIX_9_' will
987 // always result in an invalid iterator.
988 // expected: iterator is invalid
989 iter->lower_bound("_PREFIX_9_", "AAAAA");
990 ASSERT_FALSE(iter->valid());
993 void UpperBoundWithEmptyKeyOnWholeSpaceIterator(
994 KeyValueDB::WholeSpaceIterator iter) {
995 deque<string> key_deque;
996 // check that looking for (prefix1, "") will result in finding
997 // the first key in prefix1 (prefix1, "aaa")
998 // expected: find (prefix1, aaa); iterator is valid
999 iter->upper_bound(prefix1, "");
1000 key_deque.push_back("aaa");
1001 validate_prefix(iter, prefix1, key_deque);
1002 ASSERT_FALSE(HasFatalFailure());
1003 ASSERT_TRUE(iter->valid());
1005 // check that looking for (prefix2, "") will result in finding
1006 // the first key in prefix2 (prefix2, vvv)
1007 // expected: find (prefix2, aaa); iterator is valid
1008 iter->upper_bound(prefix2, "");
1009 key_deque.push_back("vvv");
1010 validate_prefix(iter, prefix2, key_deque);
1011 ASSERT_FALSE(HasFatalFailure());
1012 ASSERT_TRUE(iter->valid());
1015 // check that looking for (prefix3, "") will result in finding
1016 // the first key in prefix3 (prefix3, aaa)
1017 // expected: find (prefix3, aaa); iterator is valid
1018 iter->upper_bound(prefix3, "");
1019 key_deque.push_back("aaa");
1020 validate_prefix(iter, prefix3, key_deque);
1021 ASSERT_FALSE(HasFatalFailure());
1022 ASSERT_TRUE(iter->valid());
1024 // see what happens when we look for an inexistent prefix, that will
1025 // compare higher than the existing prefixes, with an empty key
1026 // expected: reach the store's end; iterator becomes invalid
1027 iter->upper_bound("_PREFIX_9_", "");
1028 ASSERT_FALSE(iter->valid());
1030 // see what happens when we look for an inexistent prefix, that will
1031 // compare lower than the existing prefixes, with an empty key
1032 // expected: find the first prefix; iterator is valid
1033 iter->upper_bound("_PREFIX_0_", "");
1034 ASSERT_TRUE(iter->valid());
1036 key_deque.push_back("aaa");
1037 validate_prefix(iter, prefix1, key_deque);
1038 ASSERT_FALSE(HasFatalFailure());
1039 ASSERT_TRUE(iter->valid());
1041 // see what happens when we look for an empty prefix (that should compare
1042 // lower than any existing prefixes)
1043 // expected: find the first prefix; iterator is valid
1044 iter->upper_bound("", "");
1045 ASSERT_TRUE(iter->valid());
1046 key_deque.push_back("aaa");
1047 validate_prefix(iter, prefix1, key_deque);
1048 ASSERT_FALSE(HasFatalFailure());
1049 ASSERT_TRUE(iter->valid());
1052 void UpperBoundWithEmptyPrefixOnWholeSpaceIterator(
1053 KeyValueDB::WholeSpaceIterator iter) {
1054 deque<string> key_deque;
1055 // check for an empty prefix, with key 'aaa'. Since this key is shared
1056 // among two different prefixes, it is relevant to check which will be
1058 // expected: find key (prefix1, aaa); iterator is valid
1059 iter->upper_bound("", "aaa");
1060 ASSERT_TRUE(iter->valid());
1061 key_deque.push_back("aaa");
1062 key_deque.push_back("ccc");
1063 key_deque.push_back("eee");
1064 validate_prefix(iter, prefix1, key_deque);
1065 ASSERT_FALSE(HasFatalFailure());
1066 ASSERT_TRUE(iter->valid());
1068 // any upper_bound operation with an empty prefix should always put the
1069 // iterator in the first key whose prefix compares greater, despite the
1070 // key that is specified. This means that looking for ("","AAAAAAAAAA")
1071 // should position the iterator on (prefix1, aaa).
1072 // expected: find key (prefix1, aaa); iterator is valid
1073 iter->upper_bound("", "AAAAAAAAAA");
1074 ASSERT_TRUE(iter->valid());
1076 key_deque.push_back("aaa");
1077 validate_prefix(iter, prefix1, key_deque);
1078 ASSERT_FALSE(HasFatalFailure());
1079 ASSERT_TRUE(iter->valid());
1081 // note: this test is a duplicate of the one in the function above. Why?
1082 // Well, because it also fits here (being its prefix empty), and one could
1083 // very well run solely this test (instead of the whole battery) and would
1084 // certainly expect this case to be tested.
1086 // see what happens when we look for an empty prefix (that should compare
1087 // lower than any existing prefixes)
1088 // expected: find the first prefix; iterator is valid
1089 iter->upper_bound("", "");
1090 ASSERT_TRUE(iter->valid());
1091 key_deque.push_back("aaa");
1092 validate_prefix(iter, prefix1, key_deque);
1093 ASSERT_FALSE(HasFatalFailure());
1094 ASSERT_TRUE(iter->valid());
1097 void UpperBoundOnWholeSpaceIterator(
1098 KeyValueDB::WholeSpaceIterator iter) {
1099 deque<string> key_deque;
1100 // check that we find the second key in the store
1101 // expected: find (prefix1, ccc); iterator is valid
1102 iter->upper_bound(prefix1, "bbb");
1103 ASSERT_TRUE(iter->valid());
1104 key_deque.push_back("ccc");
1105 validate_prefix(iter, prefix1, key_deque);
1106 ASSERT_FALSE(HasFatalFailure());
1107 ASSERT_TRUE(iter->valid());
1109 // check that we find the last key in the store
1110 // expected: find (prefix3, yyy); iterator is valid
1111 iter->upper_bound(prefix3, "xxx");
1112 ASSERT_TRUE(iter->valid());
1114 key_deque.push_back("yyy");
1115 validate_prefix(iter, prefix3, key_deque);
1116 ASSERT_FALSE(HasFatalFailure());
1117 ASSERT_FALSE(iter->valid());
1119 // check that looking for non-existent prefix '_PREFIX_0_' will
1120 // always result in the first value of prefix1 (prefix1,"aaa")
1121 // expected: find (prefix1, aaa); iterator is valid
1122 iter->upper_bound("_PREFIX_0_", "AAAAA");
1123 ASSERT_TRUE(iter->valid());
1125 key_deque.push_back("aaa");
1126 validate_prefix(iter, prefix1, key_deque);
1127 ASSERT_FALSE(HasFatalFailure());
1128 ASSERT_TRUE(iter->valid());
1130 // check that looking for non-existent prefix '_PREFIX_3_' will
1131 // always result in the first value of prefix3 (prefix3,"aaa")
1132 // expected: find (prefix3, aaa); iterator is valid
1133 iter->upper_bound("_PREFIX_3_", "AAAAA");
1134 ASSERT_TRUE(iter->valid());
1136 key_deque.push_back("aaa");
1137 validate_prefix(iter, prefix3, key_deque);
1138 ASSERT_FALSE(HasFatalFailure());
1139 ASSERT_TRUE(iter->valid());
1141 // check that looking for non-existent prefix '_PREFIX_9_' will
1142 // always result in an invalid iterator.
1143 // expected: iterator is invalid
1144 iter->upper_bound("_PREFIX_9_", "AAAAA");
1145 ASSERT_FALSE(iter->valid());
1149 TEST_F(BoundsTest, LowerBoundWithEmptyKeyOnWholeSpaceIteratorLevelDB)
1151 SCOPED_TRACE("LevelDB: Lower Bound, Empty Key, Whole-Space Iterator");
1152 LowerBoundWithEmptyKeyOnWholeSpaceIterator(db->get_iterator());
1153 ASSERT_FALSE(HasFatalFailure());
1156 TEST_F(BoundsTest, LowerBoundWithEmptyKeyOnWholeSpaceIteratorMockDB)
1158 SCOPED_TRACE("MockDB: Lower Bound, Empty Key, Whole-Space Iterator");
1159 LowerBoundWithEmptyKeyOnWholeSpaceIterator(mock->get_iterator());
1160 ASSERT_FALSE(HasFatalFailure());
1163 TEST_F(BoundsTest, LowerBoundWithEmptyPrefixOnWholeSpaceIteratorLevelDB)
1165 SCOPED_TRACE("LevelDB: Lower Bound, Empty Prefix, Whole-Space Iterator");
1166 LowerBoundWithEmptyPrefixOnWholeSpaceIterator(db->get_iterator());
1167 ASSERT_FALSE(HasFatalFailure());
1170 TEST_F(BoundsTest, LowerBoundWithEmptyPrefixOnWholeSpaceIteratorMockDB)
1172 SCOPED_TRACE("MockDB: Lower Bound, Empty Prefix, Whole-Space Iterator");
1173 LowerBoundWithEmptyPrefixOnWholeSpaceIterator(mock->get_iterator());
1174 ASSERT_FALSE(HasFatalFailure());
1177 TEST_F(BoundsTest, LowerBoundOnWholeSpaceIteratorLevelDB)
1179 SCOPED_TRACE("LevelDB: Lower Bound, Whole-Space Iterator");
1180 LowerBoundOnWholeSpaceIterator(db->get_iterator());
1181 ASSERT_FALSE(HasFatalFailure());
1184 TEST_F(BoundsTest, LowerBoundOnWholeSpaceIteratorMockDB)
1186 SCOPED_TRACE("MockDB: Lower Bound, Whole-Space Iterator");
1187 LowerBoundOnWholeSpaceIterator(mock->get_iterator());
1188 ASSERT_FALSE(HasFatalFailure());
1191 TEST_F(BoundsTest, UpperBoundWithEmptyKeyOnWholeSpaceIteratorLevelDB)
1193 SCOPED_TRACE("LevelDB: Upper Bound, Empty Key, Whole-Space Iterator");
1194 UpperBoundWithEmptyKeyOnWholeSpaceIterator(db->get_iterator());
1195 ASSERT_FALSE(HasFatalFailure());
1198 TEST_F(BoundsTest, UpperBoundWithEmptyKeyOnWholeSpaceIteratorMockDB)
1200 SCOPED_TRACE("MockDB: Upper Bound, Empty Key, Whole-Space Iterator");
1201 UpperBoundWithEmptyKeyOnWholeSpaceIterator(mock->get_iterator());
1202 ASSERT_FALSE(HasFatalFailure());
1205 TEST_F(BoundsTest, UpperBoundWithEmptyPrefixOnWholeSpaceIteratorLevelDB)
1207 SCOPED_TRACE("LevelDB: Upper Bound, Empty Prefix, Whole-Space Iterator");
1208 UpperBoundWithEmptyPrefixOnWholeSpaceIterator(db->get_iterator());
1209 ASSERT_FALSE(HasFatalFailure());
1212 TEST_F(BoundsTest, UpperBoundWithEmptyPrefixOnWholeSpaceIteratorMockDB)
1214 SCOPED_TRACE("MockDB: Upper Bound, Empty Prefix, Whole-Space Iterator");
1215 UpperBoundWithEmptyPrefixOnWholeSpaceIterator(mock->get_iterator());
1216 ASSERT_FALSE(HasFatalFailure());
1219 TEST_F(BoundsTest, UpperBoundOnWholeSpaceIteratorLevelDB)
1221 SCOPED_TRACE("LevelDB: Upper Bound, Whole-Space Iterator");
1222 UpperBoundOnWholeSpaceIterator(db->get_iterator());
1223 ASSERT_FALSE(HasFatalFailure());
1226 TEST_F(BoundsTest, UpperBoundOnWholeSpaceIteratorMockDB)
1228 SCOPED_TRACE("MockDB: Upper Bound, Whole-Space Iterator");
1229 UpperBoundOnWholeSpaceIterator(mock->get_iterator());
1230 ASSERT_FALSE(HasFatalFailure());
1234 class SeeksTest : public IteratorTest
1244 void init(KeyValueDB *store) {
1245 KeyValueDB::Transaction tx = store->get_transaction();
1247 tx->set(prefix1, "aaa", _gen_val("aaa"));
1248 tx->set(prefix1, "ccc", _gen_val("ccc"));
1249 tx->set(prefix1, "eee", _gen_val("eee"));
1250 tx->set(prefix2, "vvv", _gen_val("vvv"));
1251 tx->set(prefix2, "xxx", _gen_val("xxx"));
1252 tx->set(prefix2, "zzz", _gen_val("zzz"));
1253 tx->set(prefix4, "aaa", _gen_val("aaa"));
1254 tx->set(prefix4, "mmm", _gen_val("mmm"));
1255 tx->set(prefix4, "yyy", _gen_val("yyy"));
1257 store->submit_transaction_sync(tx);
1260 void SetUp() override {
1261 IteratorTest::SetUp();
1263 prefix0 = "_PREFIX_0_";
1264 prefix1 = "_PREFIX_1_";
1265 prefix2 = "_PREFIX_2_";
1266 prefix3 = "_PREFIX_3_";
1267 prefix4 = "_PREFIX_4_";
1268 prefix5 = "_PREFIX_5_";
1271 ASSERT_TRUE(validate_db_clear(db.get()));
1273 ASSERT_TRUE(validate_db_match());
1278 ASSERT_TRUE(validate_db_match());
1281 void TearDown() override {
1282 IteratorTest::TearDown();
1286 void SeekToFirstOnWholeSpaceIterator(
1287 KeyValueDB::WholeSpaceIterator iter) {
1288 iter->seek_to_first();
1289 ASSERT_TRUE(iter->valid());
1290 deque<string> key_deque;
1291 key_deque.push_back("aaa");
1292 key_deque.push_back("ccc");
1293 key_deque.push_back("eee");
1294 validate_prefix(iter, prefix1, key_deque);
1295 ASSERT_FALSE(HasFatalFailure());
1296 ASSERT_TRUE(iter->valid());
1299 void SeekToFirstWithPrefixOnWholeSpaceIterator(
1300 KeyValueDB::WholeSpaceIterator iter) {
1301 deque<string> key_deque;
1303 // if the prefix is empty, we must end up seeking to the first key.
1304 // expected: seek to (prefix1, aaa); iterator is valid
1305 iter->seek_to_first("");
1306 ASSERT_TRUE(iter->valid());
1307 key_deque.push_back("aaa");
1308 validate_prefix(iter, prefix1, key_deque);
1309 ASSERT_FALSE(HasFatalFailure());
1310 ASSERT_TRUE(iter->valid());
1312 // try seeking to non-existent prefix that compares lower than the
1313 // first available prefix
1314 // expected: seek to (prefix1, aaa); iterator is valid
1315 iter->seek_to_first(prefix0);
1316 ASSERT_TRUE(iter->valid());
1318 key_deque.push_back("aaa");
1319 validate_prefix(iter, prefix1, key_deque);
1320 ASSERT_FALSE(HasFatalFailure());
1321 ASSERT_TRUE(iter->valid());
1323 // try seeking to non-existent prefix
1324 // expected: seek to (prefix4, aaa); iterator is valid
1325 iter->seek_to_first(prefix3);
1326 ASSERT_TRUE(iter->valid());
1328 key_deque.push_back("aaa");
1329 validate_prefix(iter, prefix4, key_deque);
1330 ASSERT_FALSE(HasFatalFailure());
1331 ASSERT_TRUE(iter->valid());
1333 // try seeking to non-existent prefix that compares greater than the
1334 // last available prefix
1335 // expected: iterator is invalid
1336 iter->seek_to_first(prefix5);
1337 ASSERT_FALSE(iter->valid());
1339 // try seeking to the first prefix and make sure we end up in its first
1341 // expected: seek to (prefix1,aaa); iterator is valid
1342 iter->seek_to_first(prefix1);
1343 ASSERT_TRUE(iter->valid());
1345 key_deque.push_back("aaa");
1346 validate_prefix(iter, prefix1, key_deque);
1347 ASSERT_FALSE(HasFatalFailure());
1348 ASSERT_TRUE(iter->valid());
1350 // try seeking to the second prefix and make sure we end up in its
1352 // expected: seek to (prefix2,vvv); iterator is valid
1353 iter->seek_to_first(prefix2);
1354 ASSERT_TRUE(iter->valid());
1356 key_deque.push_back("vvv");
1357 validate_prefix(iter, prefix2, key_deque);
1358 ASSERT_FALSE(HasFatalFailure());
1359 ASSERT_TRUE(iter->valid());
1361 // try seeking to the last prefix and make sure we end up in its
1363 // expected: seek to (prefix4,aaa); iterator is valid
1364 iter->seek_to_first(prefix4);
1365 ASSERT_TRUE(iter->valid());
1367 key_deque.push_back("aaa");
1368 validate_prefix(iter, prefix4, key_deque);
1369 ASSERT_FALSE(HasFatalFailure());
1370 ASSERT_TRUE(iter->valid());
1373 void SeekToLastOnWholeSpaceIterator(
1374 KeyValueDB::WholeSpaceIterator iter) {
1375 deque<string> key_deque;
1376 iter->seek_to_last();
1377 key_deque.push_back("yyy");
1378 validate_prefix(iter, prefix4, key_deque);
1379 ASSERT_FALSE(HasFatalFailure());
1380 ASSERT_FALSE(iter->valid());
1383 void SeekToLastWithPrefixOnWholeSpaceIterator(
1384 KeyValueDB::WholeSpaceIterator iter) {
1385 deque<string> key_deque;
1387 // if the prefix is empty, we must end up seeking to last position
1388 // that has an empty prefix, or to the previous position to the first
1389 // position whose prefix compares higher than empty.
1390 // expected: iterator is invalid (because (prefix1,aaa) is the first
1391 // position that compared higher than an empty prefix)
1392 iter->seek_to_last("");
1393 ASSERT_FALSE(iter->valid());
1395 // try seeking to non-existent prefix that compares lower than the
1396 // first available prefix
1397 // expected: iterator is invalid (because (prefix1,aaa) is the first
1398 // position that compared higher than prefix0)
1399 iter->seek_to_last(prefix0);
1400 ASSERT_FALSE(iter->valid());
1402 // try seeking to non-existent prefix
1403 // expected: seek to (prefix2, zzz); iterator is valid
1404 iter->seek_to_last(prefix3);
1405 ASSERT_TRUE(iter->valid());
1407 key_deque.push_back("zzz");
1408 validate_prefix(iter, prefix2, key_deque);
1409 ASSERT_FALSE(HasFatalFailure());
1410 ASSERT_TRUE(iter->valid());
1412 // try seeking to non-existent prefix that compares greater than the
1413 // last available prefix
1414 // expected: iterator is in the last position of the store;
1415 // i.e., (prefix4,yyy)
1416 iter->seek_to_last(prefix5);
1417 ASSERT_TRUE(iter->valid());
1419 key_deque.push_back("yyy");
1420 validate_prefix(iter, prefix4, key_deque);
1421 ASSERT_FALSE(HasFatalFailure());
1422 ASSERT_FALSE(iter->valid());
1424 // try seeking to the first prefix and make sure we end up in its last
1426 // expected: seek to (prefix1,eee); iterator is valid
1427 iter->seek_to_last(prefix1);
1428 ASSERT_TRUE(iter->valid());
1430 key_deque.push_back("eee");
1431 validate_prefix(iter, prefix1, key_deque);
1432 ASSERT_FALSE(HasFatalFailure());
1433 ASSERT_TRUE(iter->valid());
1435 // try seeking to the second prefix and make sure we end up in its
1437 // expected: seek to (prefix2,vvv); iterator is valid
1438 iter->seek_to_last(prefix2);
1439 ASSERT_TRUE(iter->valid());
1441 key_deque.push_back("zzz");
1442 validate_prefix(iter, prefix2, key_deque);
1443 ASSERT_FALSE(HasFatalFailure());
1444 ASSERT_TRUE(iter->valid());
1446 // try seeking to the last prefix and make sure we end up in its
1448 // expected: seek to (prefix4,aaa); iterator is valid
1449 iter->seek_to_last(prefix4);
1450 ASSERT_TRUE(iter->valid());
1452 key_deque.push_back("yyy");
1453 validate_prefix(iter, prefix4, key_deque);
1454 ASSERT_FALSE(HasFatalFailure());
1455 ASSERT_FALSE(iter->valid());
1459 TEST_F(SeeksTest, SeekToFirstOnWholeSpaceIteratorLevelDB) {
1460 SCOPED_TRACE("LevelDB: Seek To First, Whole Space Iterator");
1461 SeekToFirstOnWholeSpaceIterator(db->get_iterator());
1462 ASSERT_FALSE(HasFatalFailure());
1465 TEST_F(SeeksTest, SeekToFirstOnWholeSpaceIteratorMockDB) {
1466 SCOPED_TRACE("MockDB: Seek To First, Whole Space Iterator");
1467 SeekToFirstOnWholeSpaceIterator(mock->get_iterator());
1468 ASSERT_FALSE(HasFatalFailure());
1471 TEST_F(SeeksTest, SeekToFirstWithPrefixOnWholeSpaceIteratorLevelDB) {
1472 SCOPED_TRACE("LevelDB: Seek To First, With Prefix, Whole Space Iterator");
1473 SeekToFirstWithPrefixOnWholeSpaceIterator(db->get_iterator());
1474 ASSERT_FALSE(HasFatalFailure());
1477 TEST_F(SeeksTest, SeekToFirstWithPrefixOnWholeSpaceIteratorMockDB) {
1478 SCOPED_TRACE("MockDB: Seek To First, With Prefix, Whole Space Iterator");
1479 SeekToFirstWithPrefixOnWholeSpaceIterator(mock->get_iterator());
1480 ASSERT_FALSE(HasFatalFailure());
1483 TEST_F(SeeksTest, SeekToLastOnWholeSpaceIteratorLevelDB) {
1484 SCOPED_TRACE("LevelDB: Seek To Last, Whole Space Iterator");
1485 SeekToLastOnWholeSpaceIterator(db->get_iterator());
1486 ASSERT_FALSE(HasFatalFailure());
1489 TEST_F(SeeksTest, SeekToLastOnWholeSpaceIteratorMockDB) {
1490 SCOPED_TRACE("MockDB: Seek To Last, Whole Space Iterator");
1491 SeekToLastOnWholeSpaceIterator(mock->get_iterator());
1492 ASSERT_FALSE(HasFatalFailure());
1495 TEST_F(SeeksTest, SeekToLastWithPrefixOnWholeSpaceIteratorLevelDB) {
1496 SCOPED_TRACE("LevelDB: Seek To Last, With Prefix, Whole Space Iterator");
1497 SeekToLastWithPrefixOnWholeSpaceIterator(db->get_iterator());
1498 ASSERT_FALSE(HasFatalFailure());
1501 TEST_F(SeeksTest, SeekToLastWithPrefixOnWholeSpaceIteratorMockDB) {
1502 SCOPED_TRACE("MockDB: Seek To Last, With Prefix, Whole Space Iterator");
1503 SeekToLastWithPrefixOnWholeSpaceIterator(mock->get_iterator());
1504 ASSERT_FALSE(HasFatalFailure());
1507 class KeySpaceIteration : public IteratorTest
1512 void init(KeyValueDB *store) {
1513 KeyValueDB::Transaction tx = store->get_transaction();
1515 tx->set(prefix1, "aaa", _gen_val("aaa"));
1516 tx->set(prefix1, "vvv", _gen_val("vvv"));
1517 tx->set(prefix1, "zzz", _gen_val("zzz"));
1519 store->submit_transaction_sync(tx);
1522 void SetUp() override {
1523 IteratorTest::SetUp();
1525 prefix1 = "_PREFIX_1_";
1528 ASSERT_TRUE(validate_db_clear(db.get()));
1530 ASSERT_TRUE(validate_db_match());
1535 ASSERT_TRUE(validate_db_match());
1538 void TearDown() override {
1539 IteratorTest::TearDown();
1542 void ForwardIteration(KeyValueDB::WholeSpaceIterator iter) {
1543 deque<string> key_deque;
1544 iter->seek_to_first();
1545 key_deque.push_back("aaa");
1546 key_deque.push_back("vvv");
1547 key_deque.push_back("zzz");
1548 validate_prefix(iter, prefix1, key_deque);
1549 ASSERT_FALSE(HasFatalFailure());
1550 ASSERT_FALSE(iter->valid());
1553 void BackwardIteration(KeyValueDB::WholeSpaceIterator iter) {
1554 deque<string> key_deque;
1555 iter->seek_to_last();
1556 key_deque.push_back("zzz");
1557 key_deque.push_back("vvv");
1558 key_deque.push_back("aaa");
1559 validate_prefix_backwards(iter, prefix1, key_deque);
1560 ASSERT_FALSE(HasFatalFailure());
1561 ASSERT_FALSE(iter->valid());
1565 TEST_F(KeySpaceIteration, ForwardIterationLevelDB)
1567 SCOPED_TRACE("LevelDB: Forward Iteration, Whole Space Iterator");
1568 ForwardIteration(db->get_iterator());
1569 ASSERT_FALSE(HasFatalFailure());
1572 TEST_F(KeySpaceIteration, ForwardIterationMockDB) {
1573 SCOPED_TRACE("MockDB: Forward Iteration, Whole Space Iterator");
1574 ForwardIteration(mock->get_iterator());
1575 ASSERT_FALSE(HasFatalFailure());
1578 TEST_F(KeySpaceIteration, BackwardIterationLevelDB)
1580 SCOPED_TRACE("LevelDB: Backward Iteration, Whole Space Iterator");
1581 BackwardIteration(db->get_iterator());
1582 ASSERT_FALSE(HasFatalFailure());
1585 TEST_F(KeySpaceIteration, BackwardIterationMockDB) {
1586 SCOPED_TRACE("MockDB: Backward Iteration, Whole Space Iterator");
1587 BackwardIteration(mock->get_iterator());
1588 ASSERT_FALSE(HasFatalFailure());
1591 class EmptyStore : public IteratorTest
1594 void SetUp() override {
1595 IteratorTest::SetUp();
1598 ASSERT_TRUE(validate_db_clear(db.get()));
1600 ASSERT_TRUE(validate_db_match());
1603 void SeekToFirst(KeyValueDB::WholeSpaceIterator iter) {
1604 // expected: iterator is invalid
1605 iter->seek_to_first();
1606 ASSERT_FALSE(iter->valid());
1609 void SeekToFirstWithPrefix(KeyValueDB::WholeSpaceIterator iter) {
1610 // expected: iterator is invalid
1611 iter->seek_to_first("prefix");
1612 ASSERT_FALSE(iter->valid());
1615 void SeekToLast(KeyValueDB::WholeSpaceIterator iter) {
1616 // expected: iterator is invalid
1617 iter->seek_to_last();
1618 ASSERT_FALSE(iter->valid());
1621 void SeekToLastWithPrefix(KeyValueDB::WholeSpaceIterator iter) {
1622 // expected: iterator is invalid
1623 iter->seek_to_last("prefix");
1624 ASSERT_FALSE(iter->valid());
1627 void LowerBound(KeyValueDB::WholeSpaceIterator iter) {
1628 // expected: iterator is invalid
1629 iter->lower_bound("prefix", "");
1630 ASSERT_FALSE(iter->valid());
1632 // expected: iterator is invalid
1633 iter->lower_bound("", "key");
1634 ASSERT_FALSE(iter->valid());
1636 // expected: iterator is invalid
1637 iter->lower_bound("prefix", "key");
1638 ASSERT_FALSE(iter->valid());
1641 void UpperBound(KeyValueDB::WholeSpaceIterator iter) {
1642 // expected: iterator is invalid
1643 iter->upper_bound("prefix", "");
1644 ASSERT_FALSE(iter->valid());
1646 // expected: iterator is invalid
1647 iter->upper_bound("", "key");
1648 ASSERT_FALSE(iter->valid());
1650 // expected: iterator is invalid
1651 iter->upper_bound("prefix", "key");
1652 ASSERT_FALSE(iter->valid());
1656 TEST_F(EmptyStore, SeekToFirstLevelDB)
1658 SCOPED_TRACE("LevelDB: Empty Store, Seek To First");
1659 SeekToFirst(db->get_iterator());
1660 ASSERT_FALSE(HasFatalFailure());
1663 TEST_F(EmptyStore, SeekToFirstMockDB)
1665 SCOPED_TRACE("MockDB: Empty Store, Seek To First");
1666 SeekToFirst(mock->get_iterator());
1667 ASSERT_FALSE(HasFatalFailure());
1670 TEST_F(EmptyStore, SeekToFirstWithPrefixLevelDB)
1672 SCOPED_TRACE("LevelDB: Empty Store, Seek To First With Prefix");
1673 SeekToFirstWithPrefix(db->get_iterator());
1674 ASSERT_FALSE(HasFatalFailure());
1677 TEST_F(EmptyStore, SeekToFirstWithPrefixMockDB)
1679 SCOPED_TRACE("MockDB: Empty Store, Seek To First With Prefix");
1680 SeekToFirstWithPrefix(mock->get_iterator());
1681 ASSERT_FALSE(HasFatalFailure());
1684 TEST_F(EmptyStore, SeekToLastLevelDB)
1686 SCOPED_TRACE("LevelDB: Empty Store, Seek To Last");
1687 SeekToLast(db->get_iterator());
1688 ASSERT_FALSE(HasFatalFailure());
1691 TEST_F(EmptyStore, SeekToLastMockDB)
1693 SCOPED_TRACE("MockDB: Empty Store, Seek To Last");
1694 SeekToLast(mock->get_iterator());
1695 ASSERT_FALSE(HasFatalFailure());
1698 TEST_F(EmptyStore, SeekToLastWithPrefixLevelDB)
1700 SCOPED_TRACE("LevelDB: Empty Store, Seek To Last With Prefix");
1701 SeekToLastWithPrefix(db->get_iterator());
1702 ASSERT_FALSE(HasFatalFailure());
1705 TEST_F(EmptyStore, SeekToLastWithPrefixMockDB)
1707 SCOPED_TRACE("MockDB: Empty Store, Seek To Last With Prefix");
1708 SeekToLastWithPrefix(mock->get_iterator());
1709 ASSERT_FALSE(HasFatalFailure());
1712 TEST_F(EmptyStore, LowerBoundLevelDB)
1714 SCOPED_TRACE("LevelDB: Empty Store, Lower Bound");
1715 LowerBound(db->get_iterator());
1716 ASSERT_FALSE(HasFatalFailure());
1719 TEST_F(EmptyStore, LowerBoundMockDB)
1721 SCOPED_TRACE("MockDB: Empty Store, Lower Bound");
1722 LowerBound(mock->get_iterator());
1723 ASSERT_FALSE(HasFatalFailure());
1726 TEST_F(EmptyStore, UpperBoundLevelDB)
1728 SCOPED_TRACE("LevelDB: Empty Store, Upper Bound");
1729 UpperBound(db->get_iterator());
1730 ASSERT_FALSE(HasFatalFailure());
1733 TEST_F(EmptyStore, UpperBoundMockDB)
1735 SCOPED_TRACE("MockDB: Empty Store, Upper Bound");
1736 UpperBound(mock->get_iterator());
1737 ASSERT_FALSE(HasFatalFailure());
1741 int main(int argc, char *argv[])
1743 vector<const char*> args;
1744 argv_to_vec(argc, (const char **) argv, args);
1746 auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
1747 common_init_finish(g_ceph_context);
1748 ::testing::InitGoogleTest(&argc, argv);
1751 std::cerr << "Usage: " << argv[0]
1752 << "[ceph_options] [gtest_options] <store_path>" << std::endl;
1755 store_path = string(argv[1]);
1757 return RUN_ALL_TESTS();