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