@ -13,6 +13,8 @@
# include "leveldb/merge_operator.h"
# include "leveldb/merge_operator.h"
# include "utilities/merge_operators.h"
# include "utilities/merge_operators.h"
# include "utilities/merge_operators/string_append/stringappend.h"
# include "utilities/merge_operators/string_append/stringappend.h"
# include "utilities/merge_operators/string_append/stringappend2.h"
# include "utilities/ttl/db_ttl.h"
# include "util/testharness.h"
# include "util/testharness.h"
# include "util/random.h"
# include "util/random.h"
@ -24,16 +26,24 @@ namespace leveldb {
const std : : string kDbName = " /tmp/mergetestdb " ;
const std : : string kDbName = " /tmp/mergetestdb " ;
// OpenDb opens a (possibly new) rocksdb database with a StringAppendOperator
// OpenDb opens a (possibly new) rocksdb database with a StringAppendOperator
std : : shared_ptr < DB > OpenDb ( StringAppendOperator * append_op ) {
std : : shared_ptr < DB > OpenNormalDb ( char delim_char ) {
DB * db ;
DB * db ;
Options options ;
Options options ;
options . create_if_missing = true ;
options . create_if_missing = true ;
options . merge_operator = append_op ;
options . merge_operator . reset ( new StringAppendOperator ( delim_char ) ) ;
Status s = DB : : Open ( options , kDbName , & db ) ;
ASSERT_OK ( DB : : Open ( options , kDbName , & db ) ) ;
if ( ! s . ok ( ) ) {
return std : : shared_ptr < DB > ( db ) ;
std : : cerr < < s . ToString ( ) < < std : : endl ;
assert ( false ) ;
}
}
// Open a TtlDB with a non-associative StringAppendTESTOperator
std : : shared_ptr < DB > OpenTtlDb ( char delim_char ) {
StackableDB * db ;
Options options ;
options . create_if_missing = true ;
options . merge_operator . reset ( new StringAppendTESTOperator ( delim_char ) ) ;
Status s ;
db = new DBWithTTL ( 123456 , options , kDbName , s , false ) ;
ASSERT_OK ( s ) ;
return std : : shared_ptr < DB > ( db ) ;
return std : : shared_ptr < DB > ( db ) ;
}
}
@ -66,7 +76,6 @@ class StringLists {
// Returns the list of strings associated with key (or "" if does not exist)
// Returns the list of strings associated with key (or "" if does not exist)
bool Get ( const std : : string & key , std : : string * const result ) {
bool Get ( const std : : string & key , std : : string * const result ) {
assert ( result ! = NULL ) ; // we should have a place to store the result
assert ( result ! = NULL ) ; // we should have a place to store the result
auto s = db_ - > Get ( get_option_ , key , result ) ;
auto s = db_ - > Get ( get_option_ , key , result ) ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
@ -86,6 +95,7 @@ class StringLists {
return false ;
return false ;
}
}
private :
private :
std : : shared_ptr < DB > db_ ;
std : : shared_ptr < DB > db_ ;
WriteOptions merge_option_ ;
WriteOptions merge_option_ ;
@ -93,14 +103,31 @@ class StringLists {
} ;
} ;
// The class for unit-testing
class StringAppendOperatorTest {
public :
StringAppendOperatorTest ( ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start each test with a fresh DB
}
typedef std : : shared_ptr < DB > ( * OpenFuncPtr ) ( char ) ;
// Allows user to open databases with different configurations.
// e.g.: Can open a DB or a TtlDB, etc.
static void SetOpenDbFunction ( OpenFuncPtr func ) {
OpenDb = func ;
}
protected :
static OpenFuncPtr OpenDb ;
} ;
StringAppendOperatorTest : : OpenFuncPtr StringAppendOperatorTest : : OpenDb = nullptr ;
// THE TEST CASES BEGIN HERE
// THE TEST CASES BEGIN HERE
class StringAppendOperatorTest { } ;
TEST ( StringAppendOperatorTest , IteratorTest ) {
TEST ( StringAppendOperatorTest , IteratorTest ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db_ = OpenDb ( ' , ' ) ;
StringAppendOperator append_op ( ' , ' ) ;
auto db_ = OpenDb ( & append_op ) ;
StringLists slists ( db_ ) ;
StringLists slists ( db_ ) ;
slists . Append ( " k1 " , " v1 " ) ;
slists . Append ( " k1 " , " v1 " ) ;
@ -193,10 +220,7 @@ TEST(StringAppendOperatorTest, IteratorTest) {
}
}
TEST ( StringAppendOperatorTest , SimpleTest ) {
TEST ( StringAppendOperatorTest , SimpleTest ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' , ' ) ;
StringAppendOperator append_op ( ' , ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " k1 " , " v1 " ) ;
slists . Append ( " k1 " , " v1 " ) ;
@ -211,10 +235,7 @@ TEST(StringAppendOperatorTest,SimpleTest) {
}
}
TEST ( StringAppendOperatorTest , SimpleDelimiterTest ) {
TEST ( StringAppendOperatorTest , SimpleDelimiterTest ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' | ' ) ;
StringAppendOperator append_op ( ' | ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " k1 " , " v1 " ) ;
slists . Append ( " k1 " , " v1 " ) ;
@ -227,10 +248,7 @@ TEST(StringAppendOperatorTest,SimpleDelimiterTest) {
}
}
TEST ( StringAppendOperatorTest , OneValueNoDelimiterTest ) {
TEST ( StringAppendOperatorTest , OneValueNoDelimiterTest ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' ! ' ) ;
StringAppendOperator append_op ( ' ! ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " random_key " , " single_val " ) ;
slists . Append ( " random_key " , " single_val " ) ;
@ -241,10 +259,7 @@ TEST(StringAppendOperatorTest,OneValueNoDelimiterTest) {
}
}
TEST ( StringAppendOperatorTest , VariousKeys ) {
TEST ( StringAppendOperatorTest , VariousKeys ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' \n ' ) ;
StringAppendOperator append_op ( ' \n ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " c " , " asdasd " ) ;
slists . Append ( " c " , " asdasd " ) ;
@ -270,10 +285,7 @@ TEST(StringAppendOperatorTest,VariousKeys) {
// Generate semi random keys/words from a small distribution.
// Generate semi random keys/words from a small distribution.
TEST ( StringAppendOperatorTest , RandomMixGetAppend ) {
TEST ( StringAppendOperatorTest , RandomMixGetAppend ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' ' ) ;
StringAppendOperator append_op ( ' ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
// Generate a list of random keys and values
// Generate a list of random keys and values
@ -299,9 +311,6 @@ TEST(StringAppendOperatorTest,RandomMixGetAppend) {
std : : string key = keys [ randomGen . Uniform ( ( int ) kKeyCount ) ] ;
std : : string key = keys [ randomGen . Uniform ( ( int ) kKeyCount ) ] ;
std : : string word = words [ randomGen . Uniform ( ( int ) kWordCount ) ] ;
std : : string word = words [ randomGen . Uniform ( ( int ) kWordCount ) ] ;
// Debug message.
//std::cout << (int)query << " " << key << " " << word << std::endl;
// Apply the query and any checks.
// Apply the query and any checks.
if ( query = = APPEND_OP ) {
if ( query = = APPEND_OP ) {
@ -327,10 +336,7 @@ TEST(StringAppendOperatorTest,RandomMixGetAppend) {
}
}
TEST ( StringAppendOperatorTest , BIGRandomMixGetAppend ) {
TEST ( StringAppendOperatorTest , BIGRandomMixGetAppend ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' ' ) ;
StringAppendOperator append_op ( ' ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
// Generate a list of random keys and values
// Generate a list of random keys and values
@ -356,9 +362,6 @@ TEST(StringAppendOperatorTest,BIGRandomMixGetAppend) {
std : : string key = keys [ randomGen . Uniform ( ( int ) kKeyCount ) ] ;
std : : string key = keys [ randomGen . Uniform ( ( int ) kKeyCount ) ] ;
std : : string word = words [ randomGen . Uniform ( ( int ) kWordCount ) ] ;
std : : string word = words [ randomGen . Uniform ( ( int ) kWordCount ) ] ;
// Debug message.
//std::cout << (int)query << " " << key << " " << word << std::endl;
//Apply the query and any checks.
//Apply the query and any checks.
if ( query = = APPEND_OP ) {
if ( query = = APPEND_OP ) {
@ -385,12 +388,9 @@ TEST(StringAppendOperatorTest,BIGRandomMixGetAppend) {
TEST ( StringAppendOperatorTest , PersistentVariousKeys ) {
TEST ( StringAppendOperatorTest , PersistentVariousKeys ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
// Perform the following operations in limited scope
// Perform the following operations in limited scope
{
{
StringAppendOperator append_op ( ' \n ' ) ;
auto db = OpenDb ( ' \n ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " c " , " asdasd " ) ;
slists . Append ( " c " , " asdasd " ) ;
@ -413,8 +413,7 @@ TEST(StringAppendOperatorTest,PersistentVariousKeys) {
// Reopen the database (the previous changes should persist / be remembered)
// Reopen the database (the previous changes should persist / be remembered)
{
{
StringAppendOperator append_op ( ' \n ' ) ;
auto db = OpenDb ( ' \n ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " c " , " bbnagnagsx " ) ;
slists . Append ( " c " , " bbnagnagsx " ) ;
@ -440,8 +439,7 @@ TEST(StringAppendOperatorTest,PersistentVariousKeys) {
// Reopen the database (the previous changes should persist / be remembered)
// Reopen the database (the previous changes should persist / be remembered)
{
{
StringAppendOperator append_op ( ' \n ' ) ;
auto db = OpenDb ( ' \n ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
// All changes should be on disk. This will test VersionSet Get()
// All changes should be on disk. This will test VersionSet Get()
@ -457,13 +455,9 @@ TEST(StringAppendOperatorTest,PersistentVariousKeys) {
}
}
TEST ( StringAppendOperatorTest , PersistentFlushAndCompaction ) {
TEST ( StringAppendOperatorTest , PersistentFlushAndCompaction ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
StringAppendOperator append_op ( ' \n ' ) ;
// Perform the following operations in limited scope
// Perform the following operations in limited scope
{
{
auto db = OpenDb ( & append_op ) ;
auto db = OpenDb ( ' \n ' ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
std : : string a , b , c ;
std : : string a , b , c ;
bool success ;
bool success ;
@ -509,7 +503,7 @@ TEST(StringAppendOperatorTest,PersistentFlushAndCompaction) {
// Reopen the database (the previous changes should persist / be remembered)
// Reopen the database (the previous changes should persist / be remembered)
{
{
auto db = OpenDb ( & append_op ) ;
auto db = OpenDb ( ' \n ' ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
std : : string a , b , c ;
std : : string a , b , c ;
@ -557,10 +551,7 @@ TEST(StringAppendOperatorTest,PersistentFlushAndCompaction) {
}
}
TEST ( StringAppendOperatorTest , SimpleTestNullDelimiter ) {
TEST ( StringAppendOperatorTest , SimpleTestNullDelimiter ) {
DestroyDB ( kDbName , Options ( ) ) ; // Start this test with a fresh DB
auto db = OpenDb ( ' \0 ' ) ;
StringAppendOperator append_op ( ' \0 ' ) ;
auto db = OpenDb ( & append_op ) ;
StringLists slists ( db ) ;
StringLists slists ( db ) ;
slists . Append ( " k1 " , " v1 " ) ;
slists . Append ( " k1 " , " v1 " ) ;
@ -582,10 +573,22 @@ TEST(StringAppendOperatorTest,SimpleTestNullDelimiter) {
ASSERT_EQ ( res , checker ) ;
ASSERT_EQ ( res , checker ) ;
}
}
} // namespace leveldb
} // namespace leveldb
int main ( int arc , char * * argv ) {
int main ( int arc , char * * argv ) {
// Run with regular database
{
fprintf ( stderr , " Running tests with regular db and operator. \n " ) ;
StringAppendOperatorTest : : SetOpenDbFunction ( & OpenNormalDb ) ;
leveldb : : test : : RunAllTests ( ) ;
leveldb : : test : : RunAllTests ( ) ;
}
// Run with TTL
{
fprintf ( stderr , " Running tests with ttl db and generic operator. \n " ) ;
StringAppendOperatorTest : : SetOpenDbFunction ( & OpenTtlDb ) ;
leveldb : : test : : RunAllTests ( ) ;
}
return 0 ;
return 0 ;
}
}