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.
16 #include <boost/scoped_ptr.hpp>
18 #include "test/ObjectMap/KeyValueDBMemory.h"
19 #include "kv/KeyValueDB.h"
20 #include <sys/types.h>
21 #include "global/global_init.h"
22 #include "common/ceph_argparse.h"
23 #include "gtest/gtest.h"
29 class IteratorTest
: public ::testing::Test
32 boost::scoped_ptr
<KeyValueDB
> db
;
33 boost::scoped_ptr
<KeyValueDBMemory
> mock
;
35 void SetUp() override
{
36 ceph_assert(!store_path
.empty());
38 KeyValueDB
*db_ptr
= KeyValueDB::create(g_ceph_context
, "leveldb", store_path
);
39 ceph_assert(!db_ptr
->create_and_open(std::cerr
));
41 mock
.reset(new KeyValueDBMemory());
44 void TearDown() override
{ }
46 ::testing::AssertionResult
validate_db_clear(KeyValueDB
*store
) {
47 KeyValueDB::WholeSpaceIterator it
= store
->get_wholespace_iterator();
50 pair
<string
,string
> k
= it
->raw_key();
51 if (mock
->db
.count(k
)) {
52 return ::testing::AssertionFailure()
54 << " mock store count " << mock
->db
.count(k
)
55 << " key(" << k
.first
<< "," << k
.second
<< ")";
59 return ::testing::AssertionSuccess();
62 ::testing::AssertionResult
validate_db_match() {
63 KeyValueDB::WholeSpaceIterator it
= db
->get_wholespace_iterator();
66 pair
<string
, string
> k
= it
->raw_key();
67 if (!mock
->db
.count(k
)) {
68 return ::testing::AssertionFailure()
70 << " mock db.count() " << mock
->db
.count(k
)
71 << " key(" << k
.first
<< "," << k
.second
<< ")";
74 bufferlist it_bl
= it
->value();
75 bufferlist mock_bl
= mock
->db
[k
];
77 string it_val
= _bl_to_str(it_bl
);
78 string mock_val
= _bl_to_str(mock_bl
);
80 if (it_val
!= mock_val
) {
81 return ::testing::AssertionFailure()
83 << " key(" << k
.first
<< "," << k
.second
<< ")"
84 << " mismatch db value(" << it_val
<< ")"
85 << " mock value(" << mock_val
<< ")";
89 return ::testing::AssertionSuccess();
92 ::testing::AssertionResult
validate_iterator(
93 KeyValueDB::WholeSpaceIterator it
,
94 string expected_prefix
,
95 const string
&expected_key
,
96 const string
&expected_value
) {
98 return ::testing::AssertionFailure()
100 << " iterator not valid";
103 if (!it
->raw_key_is_prefixed(expected_prefix
)) {
104 return ::testing::AssertionFailure()
106 << " expected raw_key_is_prefixed() == TRUE"
110 if (it
->raw_key_is_prefixed("??__SomeUnexpectedValue__??")) {
111 return ::testing::AssertionFailure()
113 << " expected raw_key_is_prefixed() == FALSE"
117 pair
<string
,string
> key
= it
->raw_key();
119 if (expected_prefix
!= key
.first
) {
120 return ::testing::AssertionFailure()
122 << " expected prefix '" << expected_prefix
<< "'"
123 << " got prefix '" << key
.first
<< "'";
126 if (expected_key
!= it
->key()) {
127 return ::testing::AssertionFailure()
129 << " expected key '" << expected_key
<< "'"
130 << " got key '" << it
->key() << "'";
133 if (it
->key() != key
.second
) {
134 return ::testing::AssertionFailure()
136 << " key '" << it
->key() << "'"
138 << " pair key '" << key
.second
<< "'";
141 if (_bl_to_str(it
->value()) != expected_value
) {
142 return ::testing::AssertionFailure()
144 << " key '(" << key
.first
<< "," << key
.second
<< ")''"
145 << " expected value '" << expected_value
<< "'"
146 << " got value '" << _bl_to_str(it
->value()) << "'";
149 return ::testing::AssertionSuccess();
153 * Checks if each key in the queue can be forward sequentially read from
154 * the iterator iter. All keys must be present and be prefixed with prefix,
155 * otherwise the validation will fail.
157 * Assumes that each key value must be based on the key name and generated
160 void validate_prefix(KeyValueDB::WholeSpaceIterator iter
,
161 string
&prefix
, deque
<string
> &keys
) {
163 while (!keys
.empty()) {
164 ASSERT_TRUE(iter
->valid());
165 string expected_key
= keys
.front();
167 string expected_value
= _gen_val_str(expected_key
);
169 ASSERT_TRUE(validate_iterator(iter
, prefix
,
170 expected_key
, expected_value
));
176 * Checks if each key in the queue can be backward sequentially read from
177 * the iterator iter. All keys must be present and be prefixed with prefix,
178 * otherwise the validation will fail.
180 * Assumes that each key value must be based on the key name and generated
183 void validate_prefix_backwards(KeyValueDB::WholeSpaceIterator iter
,
184 string
&prefix
, deque
<string
> &keys
) {
186 while (!keys
.empty()) {
187 ASSERT_TRUE(iter
->valid());
188 string expected_key
= keys
.front();
190 string expected_value
= _gen_val_str(expected_key
);
192 ASSERT_TRUE(validate_iterator(iter
, prefix
,
193 expected_key
, expected_value
));
199 void clear(KeyValueDB
*store
) {
200 KeyValueDB::WholeSpaceIterator it
= store
->get_wholespace_iterator();
202 KeyValueDB::Transaction t
= store
->get_transaction();
203 while (it
->valid()) {
204 pair
<string
,string
> k
= it
->raw_key();
205 t
->rmkey(k
.first
, k
.second
);
208 store
->submit_transaction_sync(t
);
211 string
_bl_to_str(bufferlist val
) {
212 string
str(val
.c_str(), val
.length());
216 string
_gen_val_str(const string
&key
) {
218 ss
<< "##value##" << key
<< "##";
222 bufferlist
_gen_val(const string
&key
) {
224 bl
.append(_gen_val_str(key
));
228 void print_iterator(KeyValueDB::WholeSpaceIterator iter
) {
229 if (!iter
->valid()) {
230 std::cerr
<< __func__
<< " iterator is not valid; stop." << std::endl
;
235 while (iter
->valid()) {
236 pair
<string
,string
> k
= iter
->raw_key();
237 std::cerr
<< __func__
239 << " key (" << k
.first
<< "," << k
.second
<< ")"
240 << " value(" << _bl_to_str(iter
->value()) << ")" << std::endl
;
245 void print_db(KeyValueDB
*store
) {
246 KeyValueDB::WholeSpaceIterator it
= store
->get_wholespace_iterator();
252 // ------- Remove Keys / Remove Keys By Prefix -------
253 class RmKeysTest
: public IteratorTest
260 void init(KeyValueDB
*db
) {
261 KeyValueDB::Transaction tx
= db
->get_transaction();
263 tx
->set(prefix1
, "11", _gen_val("11"));
264 tx
->set(prefix1
, "12", _gen_val("12"));
265 tx
->set(prefix1
, "13", _gen_val("13"));
266 tx
->set(prefix2
, "21", _gen_val("21"));
267 tx
->set(prefix2
, "22", _gen_val("22"));
268 tx
->set(prefix2
, "23", _gen_val("23"));
269 tx
->set(prefix3
, "31", _gen_val("31"));
270 tx
->set(prefix3
, "32", _gen_val("32"));
271 tx
->set(prefix3
, "33", _gen_val("33"));
273 db
->submit_transaction_sync(tx
);
276 void SetUp() override
{
277 IteratorTest::SetUp();
279 prefix1
= "_PREFIX_1_";
280 prefix2
= "_PREFIX_2_";
281 prefix3
= "_PREFIX_3_";
284 ASSERT_TRUE(validate_db_clear(db
.get()));
286 ASSERT_TRUE(validate_db_match());
291 ASSERT_TRUE(validate_db_match());
294 void TearDown() override
{
295 IteratorTest::TearDown();
300 * Test the transaction's rmkeys behavior when we remove a given prefix
301 * from the beginning of the key space, or from the end of the key space,
302 * or even simply in the middle.
304 void RmKeysByPrefix(KeyValueDB
*store
) {
305 // remove prefix2 ; check if prefix1 remains, and then prefix3
306 KeyValueDB::Transaction tx
= store
->get_transaction();
307 // remove the prefix in the middle of the key space
308 tx
->rmkeys_by_prefix(prefix2
);
309 store
->submit_transaction_sync(tx
);
311 deque
<string
> key_deque
;
312 KeyValueDB::WholeSpaceIterator iter
= store
->get_wholespace_iterator();
313 iter
->seek_to_first();
316 key_deque
.push_back("11");
317 key_deque
.push_back("12");
318 key_deque
.push_back("13");
319 validate_prefix(iter
, prefix1
, key_deque
);
320 ASSERT_FALSE(HasFatalFailure());
323 ASSERT_TRUE(iter
->valid());
325 key_deque
.push_back("31");
326 key_deque
.push_back("32");
327 key_deque
.push_back("33");
328 validate_prefix(iter
, prefix3
, key_deque
);
329 ASSERT_FALSE(HasFatalFailure());
331 ASSERT_FALSE(iter
->valid());
334 ASSERT_TRUE(validate_db_clear(store
));
337 // remove prefix1 ; check if prefix2 and then prefix3 remain
338 tx
= store
->get_transaction();
339 // remove the prefix at the beginning of the key space
340 tx
->rmkeys_by_prefix(prefix1
);
341 store
->submit_transaction_sync(tx
);
343 iter
= store
->get_wholespace_iterator();
344 iter
->seek_to_first();
348 key_deque
.push_back("21");
349 key_deque
.push_back("22");
350 key_deque
.push_back("23");
351 validate_prefix(iter
, prefix2
, key_deque
);
352 ASSERT_FALSE(HasFatalFailure());
355 ASSERT_TRUE(iter
->valid());
357 key_deque
.push_back("31");
358 key_deque
.push_back("32");
359 key_deque
.push_back("33");
360 validate_prefix(iter
, prefix3
, key_deque
);
361 ASSERT_FALSE(HasFatalFailure());
363 ASSERT_FALSE(iter
->valid());
366 ASSERT_TRUE(validate_db_clear(store
));
369 // remove prefix3 ; check if prefix1 and then prefix2 remain
370 tx
= store
->get_transaction();
371 // remove the prefix at the end of the key space
372 tx
->rmkeys_by_prefix(prefix3
);
373 store
->submit_transaction_sync(tx
);
375 iter
= store
->get_wholespace_iterator();
376 iter
->seek_to_first();
380 key_deque
.push_back("11");
381 key_deque
.push_back("12");
382 key_deque
.push_back("13");
383 validate_prefix(iter
, prefix1
, key_deque
);
384 ASSERT_FALSE(HasFatalFailure());
387 ASSERT_TRUE(iter
->valid());
389 key_deque
.push_back("21");
390 key_deque
.push_back("22");
391 key_deque
.push_back("23");
392 validate_prefix(iter
, prefix2
, key_deque
);
393 ASSERT_FALSE(HasFatalFailure());
395 ASSERT_FALSE(iter
->valid());
399 * Test how the leveldb's whole-space iterator behaves when we remove
400 * keys from the store while iterating over them.
402 void RmKeysWhileIteratingSnapshot(KeyValueDB
*store
,
403 KeyValueDB::WholeSpaceIterator iter
) {
405 SCOPED_TRACE("RmKeysWhileIteratingSnapshot");
407 iter
->seek_to_first();
408 ASSERT_TRUE(iter
->valid());
410 KeyValueDB::Transaction t
= store
->get_transaction();
411 t
->rmkey(prefix1
, "11");
412 t
->rmkey(prefix1
, "12");
413 t
->rmkey(prefix2
, "23");
414 t
->rmkey(prefix3
, "33");
415 store
->submit_transaction_sync(t
);
417 deque
<string
> key_deque
;
420 key_deque
.push_back("11");
421 key_deque
.push_back("12");
422 key_deque
.push_back("13");
423 validate_prefix(iter
, prefix1
, key_deque
);
424 ASSERT_FALSE(HasFatalFailure());
428 key_deque
.push_back("21");
429 key_deque
.push_back("22");
430 key_deque
.push_back("23");
431 validate_prefix(iter
, prefix2
, key_deque
);
432 ASSERT_FALSE(HasFatalFailure());
436 key_deque
.push_back("31");
437 key_deque
.push_back("32");
438 key_deque
.push_back("33");
439 validate_prefix(iter
, prefix3
, key_deque
);
440 ASSERT_FALSE(HasFatalFailure());
443 ASSERT_FALSE(iter
->valid());
445 // make sure those keys were removed from the store
446 KeyValueDB::WholeSpaceIterator tmp_it
= store
->get_wholespace_iterator();
447 tmp_it
->seek_to_first();
448 ASSERT_TRUE(tmp_it
->valid());
451 key_deque
.push_back("13");
452 validate_prefix(tmp_it
, prefix1
, key_deque
);
453 ASSERT_FALSE(HasFatalFailure());
455 ASSERT_TRUE(tmp_it
->valid());
457 key_deque
.push_back("21");
458 key_deque
.push_back("22");
459 validate_prefix(tmp_it
, prefix2
, key_deque
);
460 ASSERT_FALSE(HasFatalFailure());
462 ASSERT_TRUE(tmp_it
->valid());
464 key_deque
.push_back("31");
465 key_deque
.push_back("32");
466 validate_prefix(tmp_it
, prefix3
, key_deque
);
467 ASSERT_FALSE(HasFatalFailure());
469 ASSERT_FALSE(tmp_it
->valid());
473 TEST_F(RmKeysTest
, RmKeysByPrefixLevelDB
)
475 SCOPED_TRACE("LevelDB");
476 RmKeysByPrefix(db
.get());
477 ASSERT_FALSE(HasFatalFailure());
480 TEST_F(RmKeysTest
, RmKeysByPrefixMockDB
)
482 SCOPED_TRACE("Mock DB");
483 RmKeysByPrefix(mock
.get());
484 ASSERT_FALSE(HasFatalFailure());
488 * If you refer to function RmKeysTest::RmKeysWhileIteratingSnapshot(),
489 * you will notice that we seek the iterator to the first key, and then
490 * we go on to remove several keys from the underlying store, including
491 * the first couple keys.
493 * We would expect that during this test, as soon as we removed the keys
494 * from the store, the iterator would get invalid, or cause some sort of
497 * Instead, the current version of leveldb handles it perfectly, by making
498 * the iterator to use a snapshot instead of the store's real state. This
499 * way, LevelDBStore's whole-space iterator will behave much like its own
500 * whole-space snapshot iterator.
502 * However, this particular behavior of the iterator hasn't been documented
503 * on leveldb, and we should assume that it can be changed at any point in
506 * Therefore, we keep this test, being exactly the same as the one for the
507 * whole-space snapshot iterator, as we currently assume they should behave
508 * identically. If this test fails, at some point, and the whole-space
509 * snapshot iterator passes, then it probably means that leveldb changed
510 * how its iterator behaves.
512 TEST_F(RmKeysTest
, RmKeysWhileIteratingLevelDB
)
514 SCOPED_TRACE("LevelDB -- WholeSpaceIterator");
515 RmKeysWhileIteratingSnapshot(db
.get(), db
->get_wholespace_iterator());
516 ASSERT_FALSE(HasFatalFailure());
519 TEST_F(RmKeysTest
, RmKeysWhileIteratingMockDB
)
521 std::cout
<< "There is no safe way to test key removal while iterating\n"
522 << "over the mock store without using snapshots" << std::endl
;
525 // ------- Set Keys / Update Values -------
526 class SetKeysTest
: public IteratorTest
532 void init(KeyValueDB
*db
) {
533 KeyValueDB::Transaction tx
= db
->get_transaction();
535 tx
->set(prefix1
, "aaa", _gen_val("aaa"));
536 tx
->set(prefix1
, "ccc", _gen_val("ccc"));
537 tx
->set(prefix1
, "eee", _gen_val("eee"));
538 tx
->set(prefix2
, "vvv", _gen_val("vvv"));
539 tx
->set(prefix2
, "xxx", _gen_val("xxx"));
540 tx
->set(prefix2
, "zzz", _gen_val("zzz"));
542 db
->submit_transaction_sync(tx
);
545 void SetUp() override
{
546 IteratorTest::SetUp();
548 prefix1
= "_PREFIX_1_";
549 prefix2
= "_PREFIX_2_";
552 ASSERT_TRUE(validate_db_clear(db
.get()));
554 ASSERT_TRUE(validate_db_match());
559 ASSERT_TRUE(validate_db_match());
562 void TearDown() override
{
563 IteratorTest::TearDown();
567 * Make sure that the iterator picks on new keys added if it hasn't yet
568 * iterated away from that position.
570 * This should only happen for the whole-space iterator when not using
571 * the snapshot version.
573 * We don't need to test the validity of all elements, but we do test
574 * inserting while moving from the first element to the last, using next()
575 * to move forward, and then we test the same behavior while iterating
576 * from the last element to the first, using prev() to move backwards.
578 void SetKeysWhileIterating(KeyValueDB
*store
,
579 KeyValueDB::WholeSpaceIterator iter
) {
580 iter
->seek_to_first();
581 ASSERT_TRUE(iter
->valid());
582 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "aaa",
583 _gen_val_str("aaa")));
585 ASSERT_TRUE(iter
->valid());
586 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "ccc",
587 _bl_to_str(_gen_val("ccc"))));
589 // insert new key 'ddd' after 'ccc' and before 'eee'
590 KeyValueDB::Transaction tx
= store
->get_transaction();
591 tx
->set(prefix1
, "ddd", _gen_val("ddd"));
592 store
->submit_transaction_sync(tx
);
595 ASSERT_TRUE(iter
->valid());
596 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "ddd",
597 _gen_val_str("ddd")));
599 iter
->seek_to_last();
600 ASSERT_TRUE(iter
->valid());
601 tx
= store
->get_transaction();
602 tx
->set(prefix2
, "yyy", _gen_val("yyy"));
603 store
->submit_transaction_sync(tx
);
606 ASSERT_TRUE(iter
->valid());
607 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
608 "yyy", _gen_val_str("yyy")));
612 * Make sure that the whole-space snapshot iterator does not pick on new keys
613 * added to the store since we created the iterator, thus guaranteeing
616 * We don't need to test the validity of all elements, but we do test
617 * inserting while moving from the first element to the last, using next()
618 * to move forward, and then we test the same behavior while iterating
619 * from the last element to the first, using prev() to move backwards.
621 void SetKeysWhileIteratingSnapshot(KeyValueDB
*store
,
622 KeyValueDB::WholeSpaceIterator iter
) {
623 iter
->seek_to_first();
624 ASSERT_TRUE(iter
->valid());
625 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "aaa",
626 _gen_val_str("aaa")));
628 ASSERT_TRUE(iter
->valid());
629 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "ccc",
630 _bl_to_str(_gen_val("ccc"))));
632 // insert new key 'ddd' after 'ccc' and before 'eee'
633 KeyValueDB::Transaction tx
= store
->get_transaction();
634 tx
->set(prefix1
, "ddd", _gen_val("ddd"));
635 store
->submit_transaction_sync(tx
);
638 ASSERT_TRUE(iter
->valid());
639 ASSERT_TRUE(validate_iterator(iter
, prefix1
, "eee",
640 _gen_val_str("eee")));
642 iter
->seek_to_last();
643 ASSERT_TRUE(iter
->valid());
644 tx
= store
->get_transaction();
645 tx
->set(prefix2
, "yyy", _gen_val("yyy"));
646 store
->submit_transaction_sync(tx
);
649 ASSERT_TRUE(iter
->valid());
650 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
651 "xxx", _gen_val_str("xxx")));
655 * Make sure that the whole-space iterator is able to read values changed on
656 * the store, even after we moved to the updated position.
658 * This should only be possible when not using the whole-space snapshot
659 * version of the iterator.
661 void UpdateValuesWhileIterating(KeyValueDB
*store
,
662 KeyValueDB::WholeSpaceIterator iter
) {
663 iter
->seek_to_first();
664 ASSERT_TRUE(iter
->valid());
665 ASSERT_TRUE(validate_iterator(iter
, prefix1
,
666 "aaa", _gen_val_str("aaa")));
668 KeyValueDB::Transaction tx
= store
->get_transaction();
669 tx
->set(prefix1
, "aaa", _gen_val("aaa_1"));
670 store
->submit_transaction_sync(tx
);
672 ASSERT_TRUE(validate_iterator(iter
, prefix1
,
673 "aaa", _gen_val_str("aaa_1")));
675 iter
->seek_to_last();
676 ASSERT_TRUE(iter
->valid());
677 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
678 "zzz", _gen_val_str("zzz")));
680 tx
= store
->get_transaction();
681 tx
->set(prefix2
, "zzz", _gen_val("zzz_1"));
682 store
->submit_transaction_sync(tx
);
684 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
685 "zzz", _gen_val_str("zzz_1")));
689 * Make sure that the whole-space iterator is able to read values changed on
690 * the store, even after we moved to the updated position.
692 * This should only be possible when not using the whole-space snapshot
693 * version of the iterator.
695 void UpdateValuesWhileIteratingSnapshot(
697 KeyValueDB::WholeSpaceIterator iter
) {
698 iter
->seek_to_first();
699 ASSERT_TRUE(iter
->valid());
700 ASSERT_TRUE(validate_iterator(iter
, prefix1
,
701 "aaa", _gen_val_str("aaa")));
703 KeyValueDB::Transaction tx
= store
->get_transaction();
704 tx
->set(prefix1
, "aaa", _gen_val("aaa_1"));
705 store
->submit_transaction_sync(tx
);
707 ASSERT_TRUE(validate_iterator(iter
, prefix1
,
708 "aaa", _gen_val_str("aaa")));
710 iter
->seek_to_last();
711 ASSERT_TRUE(iter
->valid());
712 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
713 "zzz", _gen_val_str("zzz")));
715 tx
= store
->get_transaction();
716 tx
->set(prefix2
, "zzz", _gen_val("zzz_1"));
717 store
->submit_transaction_sync(tx
);
719 ASSERT_TRUE(validate_iterator(iter
, prefix2
,
720 "zzz", _gen_val_str("zzz")));
722 // check those values were really changed in the store
723 KeyValueDB::WholeSpaceIterator tmp_iter
= store
->get_wholespace_iterator();
724 tmp_iter
->seek_to_first();
725 ASSERT_TRUE(tmp_iter
->valid());
726 ASSERT_TRUE(validate_iterator(tmp_iter
, prefix1
,
727 "aaa", _gen_val_str("aaa_1")));
728 tmp_iter
->seek_to_last();
729 ASSERT_TRUE(tmp_iter
->valid());
730 ASSERT_TRUE(validate_iterator(tmp_iter
, prefix2
,
731 "zzz", _gen_val_str("zzz_1")));
737 TEST_F(SetKeysTest
, DISABLED_SetKeysWhileIteratingLevelDB
)
739 SCOPED_TRACE("LevelDB: SetKeysWhileIteratingLevelDB");
740 SetKeysWhileIterating(db
.get(), db
->get_wholespace_iterator());
741 ASSERT_TRUE(HasFatalFailure());
744 TEST_F(SetKeysTest
, SetKeysWhileIteratingMockDB
)
746 SCOPED_TRACE("Mock DB: SetKeysWhileIteratingMockDB");
747 SetKeysWhileIterating(mock
.get(), mock
->get_wholespace_iterator());
748 ASSERT_FALSE(HasFatalFailure());
751 TEST_F(SetKeysTest
, DISABLED_UpdateValuesWhileIteratingLevelDB
)
753 SCOPED_TRACE("LevelDB: UpdateValuesWhileIteratingLevelDB");
754 UpdateValuesWhileIterating(db
.get(), db
->get_wholespace_iterator());
755 ASSERT_FALSE(HasFatalFailure());
758 TEST_F(SetKeysTest
, UpdateValuesWhileIteratingMockDB
)
760 SCOPED_TRACE("MockDB: UpdateValuesWhileIteratingMockDB");
761 UpdateValuesWhileIterating(mock
.get(), mock
->get_wholespace_iterator());
762 ASSERT_FALSE(HasFatalFailure());
765 class BoundsTest
: public IteratorTest
772 void init(KeyValueDB
*store
) {
773 KeyValueDB::Transaction tx
= store
->get_transaction();
775 tx
->set(prefix1
, "aaa", _gen_val("aaa"));
776 tx
->set(prefix1
, "ccc", _gen_val("ccc"));
777 tx
->set(prefix1
, "eee", _gen_val("eee"));
778 tx
->set(prefix2
, "vvv", _gen_val("vvv"));
779 tx
->set(prefix2
, "xxx", _gen_val("xxx"));
780 tx
->set(prefix2
, "zzz", _gen_val("zzz"));
781 tx
->set(prefix3
, "aaa", _gen_val("aaa"));
782 tx
->set(prefix3
, "mmm", _gen_val("mmm"));
783 tx
->set(prefix3
, "yyy", _gen_val("yyy"));
785 store
->submit_transaction_sync(tx
);
788 void SetUp() override
{
789 IteratorTest::SetUp();
791 prefix1
= "_PREFIX_1_";
792 prefix2
= "_PREFIX_2_";
793 prefix3
= "_PREFIX_4_";
796 ASSERT_TRUE(validate_db_clear(db
.get()));
798 ASSERT_TRUE(validate_db_match());
803 ASSERT_TRUE(validate_db_match());
806 void TearDown() override
{
807 IteratorTest::TearDown();
810 void LowerBoundWithEmptyKeyOnWholeSpaceIterator(
811 KeyValueDB::WholeSpaceIterator iter
) {
812 deque
<string
> key_deque
;
813 // see what happens when we have an empty key and try to get to the
814 // first available prefix
815 iter
->lower_bound(prefix1
, "");
816 ASSERT_TRUE(iter
->valid());
818 key_deque
.push_back("aaa");
819 key_deque
.push_back("ccc");
820 key_deque
.push_back("eee");
821 validate_prefix(iter
, prefix1
, key_deque
);
822 ASSERT_FALSE(HasFatalFailure());
823 ASSERT_TRUE(iter
->valid());
824 // if we got here without problems, then it is safe to assume the
825 // remaining prefixes are intact.
827 // see what happens when we have an empty key and try to get to the
828 // middle of the key-space
829 iter
->lower_bound(prefix2
, "");
830 ASSERT_TRUE(iter
->valid());
833 key_deque
.push_back("vvv");
834 key_deque
.push_back("xxx");
835 key_deque
.push_back("zzz");
836 validate_prefix(iter
, prefix2
, key_deque
);
837 ASSERT_FALSE(HasFatalFailure());
838 ASSERT_TRUE(iter
->valid());
839 // if we got here without problems, then it is safe to assume the
840 // remaining prefixes are intact.
842 // see what happens when we have an empty key and try to get to the
843 // last prefix on the key-space
844 iter
->lower_bound(prefix3
, "");
845 ASSERT_TRUE(iter
->valid());
848 key_deque
.push_back("aaa");
849 key_deque
.push_back("mmm");
850 key_deque
.push_back("yyy");
851 validate_prefix(iter
, prefix3
, key_deque
);
852 ASSERT_FALSE(HasFatalFailure());
853 ASSERT_FALSE(iter
->valid());
854 // we reached the end of the key_space, so the iterator should no longer
857 // see what happens when we look for an inexistent prefix, that will
858 // compare higher than the existing prefixes, with an empty key
859 // expected: reach the store's end; iterator becomes invalid
860 iter
->lower_bound("_PREFIX_9_", "");
861 ASSERT_FALSE(iter
->valid());
863 // see what happens when we look for an inexistent prefix, that will
864 // compare lower than the existing prefixes, with an empty key
865 // expected: find the first prefix; iterator is valid
866 iter
->lower_bound("_PREFIX_0_", "");
867 ASSERT_TRUE(iter
->valid());
869 key_deque
.push_back("aaa");
870 key_deque
.push_back("ccc");
871 key_deque
.push_back("eee");
872 validate_prefix(iter
, prefix1
, key_deque
);
873 ASSERT_FALSE(HasFatalFailure());
874 ASSERT_TRUE(iter
->valid());
876 // see what happens when we look for an empty prefix (that should compare
877 // lower than any existing prefixes)
878 // expected: find the first prefix; iterator is valid
879 iter
->lower_bound("", "");
880 ASSERT_TRUE(iter
->valid());
881 key_deque
.push_back("aaa");
882 key_deque
.push_back("ccc");
883 key_deque
.push_back("eee");
884 validate_prefix(iter
, prefix1
, key_deque
);
885 ASSERT_FALSE(HasFatalFailure());
886 ASSERT_TRUE(iter
->valid());
889 void LowerBoundWithEmptyPrefixOnWholeSpaceIterator(
890 KeyValueDB::WholeSpaceIterator iter
) {
891 deque
<string
> key_deque
;
892 // check for an empty prefix, with key 'aaa'. Since this key is shared
893 // among two different prefixes, it is relevant to check which will be
895 // expected: find key (prefix1, aaa); iterator is valid
896 iter
->lower_bound("", "aaa");
897 ASSERT_TRUE(iter
->valid());
899 key_deque
.push_back("aaa");
900 key_deque
.push_back("ccc");
901 key_deque
.push_back("eee");
902 validate_prefix(iter
, prefix1
, key_deque
);
903 ASSERT_FALSE(HasFatalFailure());
904 ASSERT_TRUE(iter
->valid());
905 // since we found prefix1, it is safe to assume that the remaining
906 // prefixes (prefix2 and prefix3) will follow
908 // any lower_bound operation with an empty prefix should always put the
909 // iterator in the first key in the key-space, despite what key is
910 // specified. This means that looking for ("","AAAAAAAAAA") should
911 // also position the iterator on (prefix1, aaa).
912 // expected: find key (prefix1, aaa); iterator is valid
913 iter
->lower_bound("", "AAAAAAAAAA");
914 ASSERT_TRUE(iter
->valid());
916 key_deque
.push_back("aaa");
917 key_deque
.push_back("ccc");
918 key_deque
.push_back("eee");
919 validate_prefix(iter
, prefix1
, key_deque
);
920 ASSERT_FALSE(HasFatalFailure());
921 ASSERT_TRUE(iter
->valid());
923 // note: this test is a duplicate of the one in the function above. Why?
924 // Well, because it also fits here (being its prefix empty), and one could
925 // very well run solely this test (instead of the whole battery) and would
926 // certainly expect this case to be tested.
928 // see what happens when we look for an empty prefix (that should compare
929 // lower than any existing prefixes)
930 // expected: find the first prefix; iterator is valid
931 iter
->lower_bound("", "");
932 ASSERT_TRUE(iter
->valid());
933 key_deque
.push_back("aaa");
934 key_deque
.push_back("ccc");
935 key_deque
.push_back("eee");
936 validate_prefix(iter
, prefix1
, key_deque
);
937 ASSERT_FALSE(HasFatalFailure());
938 ASSERT_TRUE(iter
->valid());
941 void LowerBoundOnWholeSpaceIterator(
942 KeyValueDB::WholeSpaceIterator iter
) {
943 deque
<string
> key_deque
;
944 // check that we find the first key in the store
945 // expected: find (prefix1, aaa); iterator is valid
946 iter
->lower_bound(prefix1
, "aaa");
947 ASSERT_TRUE(iter
->valid());
948 key_deque
.push_back("aaa");
949 validate_prefix(iter
, prefix1
, key_deque
);
950 ASSERT_FALSE(HasFatalFailure());
951 ASSERT_TRUE(iter
->valid());
953 // check that we find the last key in the store
954 // expected: find (prefix3, yyy); iterator is valid
955 iter
->lower_bound(prefix3
, "yyy");
956 ASSERT_TRUE(iter
->valid());
958 key_deque
.push_back("yyy");
959 validate_prefix(iter
, prefix3
, key_deque
);
960 ASSERT_FALSE(HasFatalFailure());
961 ASSERT_FALSE(iter
->valid());
963 // check that looking for non-existent prefix '_PREFIX_0_' will
964 // always result in the first value of prefix1 (prefix1,"aaa")
965 // expected: find (prefix1, aaa); iterator is valid
966 iter
->lower_bound("_PREFIX_0_", "AAAAA");
967 ASSERT_TRUE(iter
->valid());
969 key_deque
.push_back("aaa");
970 validate_prefix(iter
, prefix1
, key_deque
);
971 ASSERT_FALSE(HasFatalFailure());
972 ASSERT_TRUE(iter
->valid());
974 // check that looking for non-existent prefix '_PREFIX_3_' will
975 // always result in the first value of prefix3 (prefix4,"aaa")
976 // expected: find (prefix3, aaa); iterator is valid
977 iter
->lower_bound("_PREFIX_3_", "AAAAA");
978 ASSERT_TRUE(iter
->valid());
980 key_deque
.push_back("aaa");
981 validate_prefix(iter
, prefix3
, key_deque
);
982 ASSERT_FALSE(HasFatalFailure());
983 ASSERT_TRUE(iter
->valid());
985 // check that looking for non-existent prefix '_PREFIX_9_' will
986 // always result in an invalid iterator.
987 // expected: iterator is invalid
988 iter
->lower_bound("_PREFIX_9_", "AAAAA");
989 ASSERT_FALSE(iter
->valid());
992 void UpperBoundWithEmptyKeyOnWholeSpaceIterator(
993 KeyValueDB::WholeSpaceIterator iter
) {
994 deque
<string
> key_deque
;
995 // check that looking for (prefix1, "") will result in finding
996 // the first key in prefix1 (prefix1, "aaa")
997 // expected: find (prefix1, aaa); iterator is valid
998 iter
->upper_bound(prefix1
, "");
999 key_deque
.push_back("aaa");
1000 validate_prefix(iter
, prefix1
, key_deque
);
1001 ASSERT_FALSE(HasFatalFailure());
1002 ASSERT_TRUE(iter
->valid());
1004 // check that looking for (prefix2, "") will result in finding
1005 // the first key in prefix2 (prefix2, vvv)
1006 // expected: find (prefix2, aaa); iterator is valid
1007 iter
->upper_bound(prefix2
, "");
1008 key_deque
.push_back("vvv");
1009 validate_prefix(iter
, prefix2
, key_deque
);
1010 ASSERT_FALSE(HasFatalFailure());
1011 ASSERT_TRUE(iter
->valid());
1014 // check that looking for (prefix3, "") will result in finding
1015 // the first key in prefix3 (prefix3, aaa)
1016 // expected: find (prefix3, aaa); iterator is valid
1017 iter
->upper_bound(prefix3
, "");
1018 key_deque
.push_back("aaa");
1019 validate_prefix(iter
, prefix3
, key_deque
);
1020 ASSERT_FALSE(HasFatalFailure());
1021 ASSERT_TRUE(iter
->valid());
1023 // see what happens when we look for an inexistent prefix, that will
1024 // compare higher than the existing prefixes, with an empty key
1025 // expected: reach the store's end; iterator becomes invalid
1026 iter
->upper_bound("_PREFIX_9_", "");
1027 ASSERT_FALSE(iter
->valid());
1029 // see what happens when we look for an inexistent prefix, that will
1030 // compare lower than the existing prefixes, with an empty key
1031 // expected: find the first prefix; iterator is valid
1032 iter
->upper_bound("_PREFIX_0_", "");
1033 ASSERT_TRUE(iter
->valid());
1035 key_deque
.push_back("aaa");
1036 validate_prefix(iter
, prefix1
, key_deque
);
1037 ASSERT_FALSE(HasFatalFailure());
1038 ASSERT_TRUE(iter
->valid());
1040 // see what happens when we look for an empty prefix (that should compare
1041 // lower than any existing prefixes)
1042 // expected: find the first prefix; iterator is valid
1043 iter
->upper_bound("", "");
1044 ASSERT_TRUE(iter
->valid());
1045 key_deque
.push_back("aaa");
1046 validate_prefix(iter
, prefix1
, key_deque
);
1047 ASSERT_FALSE(HasFatalFailure());
1048 ASSERT_TRUE(iter
->valid());
1051 void UpperBoundWithEmptyPrefixOnWholeSpaceIterator(
1052 KeyValueDB::WholeSpaceIterator iter
) {
1053 deque
<string
> key_deque
;
1054 // check for an empty prefix, with key 'aaa'. Since this key is shared
1055 // among two different prefixes, it is relevant to check which will be
1057 // expected: find key (prefix1, aaa); iterator is valid
1058 iter
->upper_bound("", "aaa");
1059 ASSERT_TRUE(iter
->valid());
1060 key_deque
.push_back("aaa");
1061 key_deque
.push_back("ccc");
1062 key_deque
.push_back("eee");
1063 validate_prefix(iter
, prefix1
, key_deque
);
1064 ASSERT_FALSE(HasFatalFailure());
1065 ASSERT_TRUE(iter
->valid());
1067 // any upper_bound operation with an empty prefix should always put the
1068 // iterator in the first key whose prefix compares greater, despite the
1069 // key that is specified. This means that looking for ("","AAAAAAAAAA")
1070 // should position the iterator on (prefix1, aaa).
1071 // expected: find key (prefix1, aaa); iterator is valid
1072 iter
->upper_bound("", "AAAAAAAAAA");
1073 ASSERT_TRUE(iter
->valid());
1075 key_deque
.push_back("aaa");
1076 validate_prefix(iter
, prefix1
, key_deque
);
1077 ASSERT_FALSE(HasFatalFailure());
1078 ASSERT_TRUE(iter
->valid());
1080 // note: this test is a duplicate of the one in the function above. Why?
1081 // Well, because it also fits here (being its prefix empty), and one could
1082 // very well run solely this test (instead of the whole battery) and would
1083 // certainly expect this case to be tested.
1085 // see what happens when we look for an empty prefix (that should compare
1086 // lower than any existing prefixes)
1087 // expected: find the first prefix; iterator is valid
1088 iter
->upper_bound("", "");
1089 ASSERT_TRUE(iter
->valid());
1090 key_deque
.push_back("aaa");
1091 validate_prefix(iter
, prefix1
, key_deque
);
1092 ASSERT_FALSE(HasFatalFailure());
1093 ASSERT_TRUE(iter
->valid());
1096 void UpperBoundOnWholeSpaceIterator(
1097 KeyValueDB::WholeSpaceIterator iter
) {
1098 deque
<string
> key_deque
;
1099 // check that we find the second key in the store
1100 // expected: find (prefix1, ccc); iterator is valid
1101 iter
->upper_bound(prefix1
, "bbb");
1102 ASSERT_TRUE(iter
->valid());
1103 key_deque
.push_back("ccc");
1104 validate_prefix(iter
, prefix1
, key_deque
);
1105 ASSERT_FALSE(HasFatalFailure());
1106 ASSERT_TRUE(iter
->valid());
1108 // check that we find the last key in the store
1109 // expected: find (prefix3, yyy); iterator is valid
1110 iter
->upper_bound(prefix3
, "xxx");
1111 ASSERT_TRUE(iter
->valid());
1113 key_deque
.push_back("yyy");
1114 validate_prefix(iter
, prefix3
, key_deque
);
1115 ASSERT_FALSE(HasFatalFailure());
1116 ASSERT_FALSE(iter
->valid());
1118 // check that looking for non-existent prefix '_PREFIX_0_' will
1119 // always result in the first value of prefix1 (prefix1,"aaa")
1120 // expected: find (prefix1, aaa); iterator is valid
1121 iter
->upper_bound("_PREFIX_0_", "AAAAA");
1122 ASSERT_TRUE(iter
->valid());
1124 key_deque
.push_back("aaa");
1125 validate_prefix(iter
, prefix1
, key_deque
);
1126 ASSERT_FALSE(HasFatalFailure());
1127 ASSERT_TRUE(iter
->valid());
1129 // check that looking for non-existent prefix '_PREFIX_3_' will
1130 // always result in the first value of prefix3 (prefix3,"aaa")
1131 // expected: find (prefix3, aaa); iterator is valid
1132 iter
->upper_bound("_PREFIX_3_", "AAAAA");
1133 ASSERT_TRUE(iter
->valid());
1135 key_deque
.push_back("aaa");
1136 validate_prefix(iter
, prefix3
, key_deque
);
1137 ASSERT_FALSE(HasFatalFailure());
1138 ASSERT_TRUE(iter
->valid());
1140 // check that looking for non-existent prefix '_PREFIX_9_' will
1141 // always result in an invalid iterator.
1142 // expected: iterator is invalid
1143 iter
->upper_bound("_PREFIX_9_", "AAAAA");
1144 ASSERT_FALSE(iter
->valid());
1148 TEST_F(BoundsTest
, LowerBoundWithEmptyKeyOnWholeSpaceIteratorLevelDB
)
1150 SCOPED_TRACE("LevelDB: Lower Bound, Empty Key, Whole-Space Iterator");
1151 LowerBoundWithEmptyKeyOnWholeSpaceIterator(db
->get_wholespace_iterator());
1152 ASSERT_FALSE(HasFatalFailure());
1155 TEST_F(BoundsTest
, LowerBoundWithEmptyKeyOnWholeSpaceIteratorMockDB
)
1157 SCOPED_TRACE("MockDB: Lower Bound, Empty Key, Whole-Space Iterator");
1158 LowerBoundWithEmptyKeyOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1159 ASSERT_FALSE(HasFatalFailure());
1162 TEST_F(BoundsTest
, LowerBoundWithEmptyPrefixOnWholeSpaceIteratorLevelDB
)
1164 SCOPED_TRACE("LevelDB: Lower Bound, Empty Prefix, Whole-Space Iterator");
1165 LowerBoundWithEmptyPrefixOnWholeSpaceIterator(db
->get_wholespace_iterator());
1166 ASSERT_FALSE(HasFatalFailure());
1169 TEST_F(BoundsTest
, LowerBoundWithEmptyPrefixOnWholeSpaceIteratorMockDB
)
1171 SCOPED_TRACE("MockDB: Lower Bound, Empty Prefix, Whole-Space Iterator");
1172 LowerBoundWithEmptyPrefixOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1173 ASSERT_FALSE(HasFatalFailure());
1176 TEST_F(BoundsTest
, LowerBoundOnWholeSpaceIteratorLevelDB
)
1178 SCOPED_TRACE("LevelDB: Lower Bound, Whole-Space Iterator");
1179 LowerBoundOnWholeSpaceIterator(db
->get_wholespace_iterator());
1180 ASSERT_FALSE(HasFatalFailure());
1183 TEST_F(BoundsTest
, LowerBoundOnWholeSpaceIteratorMockDB
)
1185 SCOPED_TRACE("MockDB: Lower Bound, Whole-Space Iterator");
1186 LowerBoundOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1187 ASSERT_FALSE(HasFatalFailure());
1190 TEST_F(BoundsTest
, UpperBoundWithEmptyKeyOnWholeSpaceIteratorLevelDB
)
1192 SCOPED_TRACE("LevelDB: Upper Bound, Empty Key, Whole-Space Iterator");
1193 UpperBoundWithEmptyKeyOnWholeSpaceIterator(db
->get_wholespace_iterator());
1194 ASSERT_FALSE(HasFatalFailure());
1197 TEST_F(BoundsTest
, UpperBoundWithEmptyKeyOnWholeSpaceIteratorMockDB
)
1199 SCOPED_TRACE("MockDB: Upper Bound, Empty Key, Whole-Space Iterator");
1200 UpperBoundWithEmptyKeyOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1201 ASSERT_FALSE(HasFatalFailure());
1204 TEST_F(BoundsTest
, UpperBoundWithEmptyPrefixOnWholeSpaceIteratorLevelDB
)
1206 SCOPED_TRACE("LevelDB: Upper Bound, Empty Prefix, Whole-Space Iterator");
1207 UpperBoundWithEmptyPrefixOnWholeSpaceIterator(db
->get_wholespace_iterator());
1208 ASSERT_FALSE(HasFatalFailure());
1211 TEST_F(BoundsTest
, UpperBoundWithEmptyPrefixOnWholeSpaceIteratorMockDB
)
1213 SCOPED_TRACE("MockDB: Upper Bound, Empty Prefix, Whole-Space Iterator");
1214 UpperBoundWithEmptyPrefixOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1215 ASSERT_FALSE(HasFatalFailure());
1218 TEST_F(BoundsTest
, UpperBoundOnWholeSpaceIteratorLevelDB
)
1220 SCOPED_TRACE("LevelDB: Upper Bound, Whole-Space Iterator");
1221 UpperBoundOnWholeSpaceIterator(db
->get_wholespace_iterator());
1222 ASSERT_FALSE(HasFatalFailure());
1225 TEST_F(BoundsTest
, UpperBoundOnWholeSpaceIteratorMockDB
)
1227 SCOPED_TRACE("MockDB: Upper Bound, Whole-Space Iterator");
1228 UpperBoundOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1229 ASSERT_FALSE(HasFatalFailure());
1233 class SeeksTest
: public IteratorTest
1243 void init(KeyValueDB
*store
) {
1244 KeyValueDB::Transaction tx
= store
->get_transaction();
1246 tx
->set(prefix1
, "aaa", _gen_val("aaa"));
1247 tx
->set(prefix1
, "ccc", _gen_val("ccc"));
1248 tx
->set(prefix1
, "eee", _gen_val("eee"));
1249 tx
->set(prefix2
, "vvv", _gen_val("vvv"));
1250 tx
->set(prefix2
, "xxx", _gen_val("xxx"));
1251 tx
->set(prefix2
, "zzz", _gen_val("zzz"));
1252 tx
->set(prefix4
, "aaa", _gen_val("aaa"));
1253 tx
->set(prefix4
, "mmm", _gen_val("mmm"));
1254 tx
->set(prefix4
, "yyy", _gen_val("yyy"));
1256 store
->submit_transaction_sync(tx
);
1259 void SetUp() override
{
1260 IteratorTest::SetUp();
1262 prefix0
= "_PREFIX_0_";
1263 prefix1
= "_PREFIX_1_";
1264 prefix2
= "_PREFIX_2_";
1265 prefix3
= "_PREFIX_3_";
1266 prefix4
= "_PREFIX_4_";
1267 prefix5
= "_PREFIX_5_";
1270 ASSERT_TRUE(validate_db_clear(db
.get()));
1272 ASSERT_TRUE(validate_db_match());
1277 ASSERT_TRUE(validate_db_match());
1280 void TearDown() override
{
1281 IteratorTest::TearDown();
1285 void SeekToFirstOnWholeSpaceIterator(
1286 KeyValueDB::WholeSpaceIterator iter
) {
1287 iter
->seek_to_first();
1288 ASSERT_TRUE(iter
->valid());
1289 deque
<string
> key_deque
;
1290 key_deque
.push_back("aaa");
1291 key_deque
.push_back("ccc");
1292 key_deque
.push_back("eee");
1293 validate_prefix(iter
, prefix1
, key_deque
);
1294 ASSERT_FALSE(HasFatalFailure());
1295 ASSERT_TRUE(iter
->valid());
1298 void SeekToFirstWithPrefixOnWholeSpaceIterator(
1299 KeyValueDB::WholeSpaceIterator iter
) {
1300 deque
<string
> key_deque
;
1302 // if the prefix is empty, we must end up seeking to the first key.
1303 // expected: seek to (prefix1, aaa); iterator is valid
1304 iter
->seek_to_first("");
1305 ASSERT_TRUE(iter
->valid());
1306 key_deque
.push_back("aaa");
1307 validate_prefix(iter
, prefix1
, key_deque
);
1308 ASSERT_FALSE(HasFatalFailure());
1309 ASSERT_TRUE(iter
->valid());
1311 // try seeking to non-existent prefix that compares lower than the
1312 // first available prefix
1313 // expected: seek to (prefix1, aaa); iterator is valid
1314 iter
->seek_to_first(prefix0
);
1315 ASSERT_TRUE(iter
->valid());
1317 key_deque
.push_back("aaa");
1318 validate_prefix(iter
, prefix1
, key_deque
);
1319 ASSERT_FALSE(HasFatalFailure());
1320 ASSERT_TRUE(iter
->valid());
1322 // try seeking to non-existent prefix
1323 // expected: seek to (prefix4, aaa); iterator is valid
1324 iter
->seek_to_first(prefix3
);
1325 ASSERT_TRUE(iter
->valid());
1327 key_deque
.push_back("aaa");
1328 validate_prefix(iter
, prefix4
, key_deque
);
1329 ASSERT_FALSE(HasFatalFailure());
1330 ASSERT_TRUE(iter
->valid());
1332 // try seeking to non-existent prefix that compares greater than the
1333 // last available prefix
1334 // expected: iterator is invalid
1335 iter
->seek_to_first(prefix5
);
1336 ASSERT_FALSE(iter
->valid());
1338 // try seeking to the first prefix and make sure we end up in its first
1340 // expected: seek to (prefix1,aaa); iterator is valid
1341 iter
->seek_to_first(prefix1
);
1342 ASSERT_TRUE(iter
->valid());
1344 key_deque
.push_back("aaa");
1345 validate_prefix(iter
, prefix1
, key_deque
);
1346 ASSERT_FALSE(HasFatalFailure());
1347 ASSERT_TRUE(iter
->valid());
1349 // try seeking to the second prefix and make sure we end up in its
1351 // expected: seek to (prefix2,vvv); iterator is valid
1352 iter
->seek_to_first(prefix2
);
1353 ASSERT_TRUE(iter
->valid());
1355 key_deque
.push_back("vvv");
1356 validate_prefix(iter
, prefix2
, key_deque
);
1357 ASSERT_FALSE(HasFatalFailure());
1358 ASSERT_TRUE(iter
->valid());
1360 // try seeking to the last prefix and make sure we end up in its
1362 // expected: seek to (prefix4,aaa); iterator is valid
1363 iter
->seek_to_first(prefix4
);
1364 ASSERT_TRUE(iter
->valid());
1366 key_deque
.push_back("aaa");
1367 validate_prefix(iter
, prefix4
, key_deque
);
1368 ASSERT_FALSE(HasFatalFailure());
1369 ASSERT_TRUE(iter
->valid());
1372 void SeekToLastOnWholeSpaceIterator(
1373 KeyValueDB::WholeSpaceIterator iter
) {
1374 deque
<string
> key_deque
;
1375 iter
->seek_to_last();
1376 key_deque
.push_back("yyy");
1377 validate_prefix(iter
, prefix4
, key_deque
);
1378 ASSERT_FALSE(HasFatalFailure());
1379 ASSERT_FALSE(iter
->valid());
1382 void SeekToLastWithPrefixOnWholeSpaceIterator(
1383 KeyValueDB::WholeSpaceIterator iter
) {
1384 deque
<string
> key_deque
;
1386 // if the prefix is empty, we must end up seeking to last position
1387 // that has an empty prefix, or to the previous position to the first
1388 // position whose prefix compares higher than empty.
1389 // expected: iterator is invalid (because (prefix1,aaa) is the first
1390 // position that compared higher than an empty prefix)
1391 iter
->seek_to_last("");
1392 ASSERT_FALSE(iter
->valid());
1394 // try seeking to non-existent prefix that compares lower than the
1395 // first available prefix
1396 // expected: iterator is invalid (because (prefix1,aaa) is the first
1397 // position that compared higher than prefix0)
1398 iter
->seek_to_last(prefix0
);
1399 ASSERT_FALSE(iter
->valid());
1401 // try seeking to non-existent prefix
1402 // expected: seek to (prefix2, zzz); iterator is valid
1403 iter
->seek_to_last(prefix3
);
1404 ASSERT_TRUE(iter
->valid());
1406 key_deque
.push_back("zzz");
1407 validate_prefix(iter
, prefix2
, key_deque
);
1408 ASSERT_FALSE(HasFatalFailure());
1409 ASSERT_TRUE(iter
->valid());
1411 // try seeking to non-existent prefix that compares greater than the
1412 // last available prefix
1413 // expected: iterator is in the last position of the store;
1414 // i.e., (prefix4,yyy)
1415 iter
->seek_to_last(prefix5
);
1416 ASSERT_TRUE(iter
->valid());
1418 key_deque
.push_back("yyy");
1419 validate_prefix(iter
, prefix4
, key_deque
);
1420 ASSERT_FALSE(HasFatalFailure());
1421 ASSERT_FALSE(iter
->valid());
1423 // try seeking to the first prefix and make sure we end up in its last
1425 // expected: seek to (prefix1,eee); iterator is valid
1426 iter
->seek_to_last(prefix1
);
1427 ASSERT_TRUE(iter
->valid());
1429 key_deque
.push_back("eee");
1430 validate_prefix(iter
, prefix1
, key_deque
);
1431 ASSERT_FALSE(HasFatalFailure());
1432 ASSERT_TRUE(iter
->valid());
1434 // try seeking to the second prefix and make sure we end up in its
1436 // expected: seek to (prefix2,vvv); iterator is valid
1437 iter
->seek_to_last(prefix2
);
1438 ASSERT_TRUE(iter
->valid());
1440 key_deque
.push_back("zzz");
1441 validate_prefix(iter
, prefix2
, key_deque
);
1442 ASSERT_FALSE(HasFatalFailure());
1443 ASSERT_TRUE(iter
->valid());
1445 // try seeking to the last prefix and make sure we end up in its
1447 // expected: seek to (prefix4,aaa); iterator is valid
1448 iter
->seek_to_last(prefix4
);
1449 ASSERT_TRUE(iter
->valid());
1451 key_deque
.push_back("yyy");
1452 validate_prefix(iter
, prefix4
, key_deque
);
1453 ASSERT_FALSE(HasFatalFailure());
1454 ASSERT_FALSE(iter
->valid());
1458 TEST_F(SeeksTest
, SeekToFirstOnWholeSpaceIteratorLevelDB
) {
1459 SCOPED_TRACE("LevelDB: Seek To First, Whole Space Iterator");
1460 SeekToFirstOnWholeSpaceIterator(db
->get_wholespace_iterator());
1461 ASSERT_FALSE(HasFatalFailure());
1464 TEST_F(SeeksTest
, SeekToFirstOnWholeSpaceIteratorMockDB
) {
1465 SCOPED_TRACE("MockDB: Seek To First, Whole Space Iterator");
1466 SeekToFirstOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1467 ASSERT_FALSE(HasFatalFailure());
1470 TEST_F(SeeksTest
, SeekToFirstWithPrefixOnWholeSpaceIteratorLevelDB
) {
1471 SCOPED_TRACE("LevelDB: Seek To First, With Prefix, Whole Space Iterator");
1472 SeekToFirstWithPrefixOnWholeSpaceIterator(db
->get_wholespace_iterator());
1473 ASSERT_FALSE(HasFatalFailure());
1476 TEST_F(SeeksTest
, SeekToFirstWithPrefixOnWholeSpaceIteratorMockDB
) {
1477 SCOPED_TRACE("MockDB: Seek To First, With Prefix, Whole Space Iterator");
1478 SeekToFirstWithPrefixOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1479 ASSERT_FALSE(HasFatalFailure());
1482 TEST_F(SeeksTest
, SeekToLastOnWholeSpaceIteratorLevelDB
) {
1483 SCOPED_TRACE("LevelDB: Seek To Last, Whole Space Iterator");
1484 SeekToLastOnWholeSpaceIterator(db
->get_wholespace_iterator());
1485 ASSERT_FALSE(HasFatalFailure());
1488 TEST_F(SeeksTest
, SeekToLastOnWholeSpaceIteratorMockDB
) {
1489 SCOPED_TRACE("MockDB: Seek To Last, Whole Space Iterator");
1490 SeekToLastOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1491 ASSERT_FALSE(HasFatalFailure());
1494 TEST_F(SeeksTest
, SeekToLastWithPrefixOnWholeSpaceIteratorLevelDB
) {
1495 SCOPED_TRACE("LevelDB: Seek To Last, With Prefix, Whole Space Iterator");
1496 SeekToLastWithPrefixOnWholeSpaceIterator(db
->get_wholespace_iterator());
1497 ASSERT_FALSE(HasFatalFailure());
1500 TEST_F(SeeksTest
, SeekToLastWithPrefixOnWholeSpaceIteratorMockDB
) {
1501 SCOPED_TRACE("MockDB: Seek To Last, With Prefix, Whole Space Iterator");
1502 SeekToLastWithPrefixOnWholeSpaceIterator(mock
->get_wholespace_iterator());
1503 ASSERT_FALSE(HasFatalFailure());
1506 class KeySpaceIteration
: public IteratorTest
1511 void init(KeyValueDB
*store
) {
1512 KeyValueDB::Transaction tx
= store
->get_transaction();
1514 tx
->set(prefix1
, "aaa", _gen_val("aaa"));
1515 tx
->set(prefix1
, "vvv", _gen_val("vvv"));
1516 tx
->set(prefix1
, "zzz", _gen_val("zzz"));
1518 store
->submit_transaction_sync(tx
);
1521 void SetUp() override
{
1522 IteratorTest::SetUp();
1524 prefix1
= "_PREFIX_1_";
1527 ASSERT_TRUE(validate_db_clear(db
.get()));
1529 ASSERT_TRUE(validate_db_match());
1534 ASSERT_TRUE(validate_db_match());
1537 void TearDown() override
{
1538 IteratorTest::TearDown();
1541 void ForwardIteration(KeyValueDB::WholeSpaceIterator iter
) {
1542 deque
<string
> key_deque
;
1543 iter
->seek_to_first();
1544 key_deque
.push_back("aaa");
1545 key_deque
.push_back("vvv");
1546 key_deque
.push_back("zzz");
1547 validate_prefix(iter
, prefix1
, key_deque
);
1548 ASSERT_FALSE(HasFatalFailure());
1549 ASSERT_FALSE(iter
->valid());
1552 void BackwardIteration(KeyValueDB::WholeSpaceIterator iter
) {
1553 deque
<string
> key_deque
;
1554 iter
->seek_to_last();
1555 key_deque
.push_back("zzz");
1556 key_deque
.push_back("vvv");
1557 key_deque
.push_back("aaa");
1558 validate_prefix_backwards(iter
, prefix1
, key_deque
);
1559 ASSERT_FALSE(HasFatalFailure());
1560 ASSERT_FALSE(iter
->valid());
1564 TEST_F(KeySpaceIteration
, ForwardIterationLevelDB
)
1566 SCOPED_TRACE("LevelDB: Forward Iteration, Whole Space Iterator");
1567 ForwardIteration(db
->get_wholespace_iterator());
1568 ASSERT_FALSE(HasFatalFailure());
1571 TEST_F(KeySpaceIteration
, ForwardIterationMockDB
) {
1572 SCOPED_TRACE("MockDB: Forward Iteration, Whole Space Iterator");
1573 ForwardIteration(mock
->get_wholespace_iterator());
1574 ASSERT_FALSE(HasFatalFailure());
1577 TEST_F(KeySpaceIteration
, BackwardIterationLevelDB
)
1579 SCOPED_TRACE("LevelDB: Backward Iteration, Whole Space Iterator");
1580 BackwardIteration(db
->get_wholespace_iterator());
1581 ASSERT_FALSE(HasFatalFailure());
1584 TEST_F(KeySpaceIteration
, BackwardIterationMockDB
) {
1585 SCOPED_TRACE("MockDB: Backward Iteration, Whole Space Iterator");
1586 BackwardIteration(mock
->get_wholespace_iterator());
1587 ASSERT_FALSE(HasFatalFailure());
1590 class EmptyStore
: public IteratorTest
1593 void SetUp() override
{
1594 IteratorTest::SetUp();
1597 ASSERT_TRUE(validate_db_clear(db
.get()));
1599 ASSERT_TRUE(validate_db_match());
1602 void SeekToFirst(KeyValueDB::WholeSpaceIterator iter
) {
1603 // expected: iterator is invalid
1604 iter
->seek_to_first();
1605 ASSERT_FALSE(iter
->valid());
1608 void SeekToFirstWithPrefix(KeyValueDB::WholeSpaceIterator iter
) {
1609 // expected: iterator is invalid
1610 iter
->seek_to_first("prefix");
1611 ASSERT_FALSE(iter
->valid());
1614 void SeekToLast(KeyValueDB::WholeSpaceIterator iter
) {
1615 // expected: iterator is invalid
1616 iter
->seek_to_last();
1617 ASSERT_FALSE(iter
->valid());
1620 void SeekToLastWithPrefix(KeyValueDB::WholeSpaceIterator iter
) {
1621 // expected: iterator is invalid
1622 iter
->seek_to_last("prefix");
1623 ASSERT_FALSE(iter
->valid());
1626 void LowerBound(KeyValueDB::WholeSpaceIterator iter
) {
1627 // expected: iterator is invalid
1628 iter
->lower_bound("prefix", "");
1629 ASSERT_FALSE(iter
->valid());
1631 // expected: iterator is invalid
1632 iter
->lower_bound("", "key");
1633 ASSERT_FALSE(iter
->valid());
1635 // expected: iterator is invalid
1636 iter
->lower_bound("prefix", "key");
1637 ASSERT_FALSE(iter
->valid());
1640 void UpperBound(KeyValueDB::WholeSpaceIterator iter
) {
1641 // expected: iterator is invalid
1642 iter
->upper_bound("prefix", "");
1643 ASSERT_FALSE(iter
->valid());
1645 // expected: iterator is invalid
1646 iter
->upper_bound("", "key");
1647 ASSERT_FALSE(iter
->valid());
1649 // expected: iterator is invalid
1650 iter
->upper_bound("prefix", "key");
1651 ASSERT_FALSE(iter
->valid());
1655 TEST_F(EmptyStore
, SeekToFirstLevelDB
)
1657 SCOPED_TRACE("LevelDB: Empty Store, Seek To First");
1658 SeekToFirst(db
->get_wholespace_iterator());
1659 ASSERT_FALSE(HasFatalFailure());
1662 TEST_F(EmptyStore
, SeekToFirstMockDB
)
1664 SCOPED_TRACE("MockDB: Empty Store, Seek To First");
1665 SeekToFirst(mock
->get_wholespace_iterator());
1666 ASSERT_FALSE(HasFatalFailure());
1669 TEST_F(EmptyStore
, SeekToFirstWithPrefixLevelDB
)
1671 SCOPED_TRACE("LevelDB: Empty Store, Seek To First With Prefix");
1672 SeekToFirstWithPrefix(db
->get_wholespace_iterator());
1673 ASSERT_FALSE(HasFatalFailure());
1676 TEST_F(EmptyStore
, SeekToFirstWithPrefixMockDB
)
1678 SCOPED_TRACE("MockDB: Empty Store, Seek To First With Prefix");
1679 SeekToFirstWithPrefix(mock
->get_wholespace_iterator());
1680 ASSERT_FALSE(HasFatalFailure());
1683 TEST_F(EmptyStore
, SeekToLastLevelDB
)
1685 SCOPED_TRACE("LevelDB: Empty Store, Seek To Last");
1686 SeekToLast(db
->get_wholespace_iterator());
1687 ASSERT_FALSE(HasFatalFailure());
1690 TEST_F(EmptyStore
, SeekToLastMockDB
)
1692 SCOPED_TRACE("MockDB: Empty Store, Seek To Last");
1693 SeekToLast(mock
->get_wholespace_iterator());
1694 ASSERT_FALSE(HasFatalFailure());
1697 TEST_F(EmptyStore
, SeekToLastWithPrefixLevelDB
)
1699 SCOPED_TRACE("LevelDB: Empty Store, Seek To Last With Prefix");
1700 SeekToLastWithPrefix(db
->get_wholespace_iterator());
1701 ASSERT_FALSE(HasFatalFailure());
1704 TEST_F(EmptyStore
, SeekToLastWithPrefixMockDB
)
1706 SCOPED_TRACE("MockDB: Empty Store, Seek To Last With Prefix");
1707 SeekToLastWithPrefix(mock
->get_wholespace_iterator());
1708 ASSERT_FALSE(HasFatalFailure());
1711 TEST_F(EmptyStore
, LowerBoundLevelDB
)
1713 SCOPED_TRACE("LevelDB: Empty Store, Lower Bound");
1714 LowerBound(db
->get_wholespace_iterator());
1715 ASSERT_FALSE(HasFatalFailure());
1718 TEST_F(EmptyStore
, LowerBoundMockDB
)
1720 SCOPED_TRACE("MockDB: Empty Store, Lower Bound");
1721 LowerBound(mock
->get_wholespace_iterator());
1722 ASSERT_FALSE(HasFatalFailure());
1725 TEST_F(EmptyStore
, UpperBoundLevelDB
)
1727 SCOPED_TRACE("LevelDB: Empty Store, Upper Bound");
1728 UpperBound(db
->get_wholespace_iterator());
1729 ASSERT_FALSE(HasFatalFailure());
1732 TEST_F(EmptyStore
, UpperBoundMockDB
)
1734 SCOPED_TRACE("MockDB: Empty Store, Upper Bound");
1735 UpperBound(mock
->get_wholespace_iterator());
1736 ASSERT_FALSE(HasFatalFailure());
1740 int main(int argc
, char *argv
[])
1742 auto args
= argv_to_vec(argc
, argv
);
1744 auto cct
= global_init(NULL
, args
, CEPH_ENTITY_TYPE_CLIENT
, CODE_ENVIRONMENT_UTILITY
, CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
1745 common_init_finish(g_ceph_context
);
1746 ::testing::InitGoogleTest(&argc
, argv
);
1749 std::cerr
<< "Usage: " << argv
[0]
1750 << "[ceph_options] [gtest_options] <store_path>" << std::endl
;
1753 store_path
= string(argv
[1]);
1755 return RUN_ALL_TESTS();