1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 5 #include "leveldb/db.h" 6 7 #include "db/memtable.h" 8 #include "db/write_batch_internal.h" 9 #include "leveldb/env.h" 10 #include "util/logging.h" 11 #include "util/testharness.h" 12 13 namespace leveldb { 14 15 static std::string PrintContents(WriteBatch* b) { 16 InternalKeyComparator cmp(BytewiseComparator()); 17 MemTable* mem = new MemTable(cmp); 18 mem->Ref(); 19 std::string state; 20 Status s = WriteBatchInternal::InsertInto(b, mem); 21 Iterator* iter = mem->NewIterator(); 22 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 23 ParsedInternalKey ikey; 24 ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey)); 25 switch (ikey.type) { 26 case kTypeValue: 27 state.append("Put("); 28 state.append(ikey.user_key.ToString()); 29 state.append(", "); 30 state.append(iter->value().ToString()); 31 state.append(")"); 32 break; 33 case kTypeDeletion: 34 state.append("Delete("); 35 state.append(ikey.user_key.ToString()); 36 state.append(")"); 37 break; 38 } 39 state.append("@"); 40 state.append(NumberToString(ikey.sequence)); 41 } 42 delete iter; 43 if (!s.ok()) { 44 state.append("ParseError()"); 45 } 46 mem->Unref(); 47 return state; 48 } 49 50 class WriteBatchTest { }; 51 52 TEST(WriteBatchTest, Empty) { 53 WriteBatch batch; 54 ASSERT_EQ("", PrintContents(&batch)); 55 ASSERT_EQ(0, WriteBatchInternal::Count(&batch)); 56 } 57 58 TEST(WriteBatchTest, Multiple) { 59 WriteBatch batch; 60 batch.Put(Slice("foo"), Slice("bar")); 61 batch.Delete(Slice("box")); 62 batch.Put(Slice("baz"), Slice("boo")); 63 WriteBatchInternal::SetSequence(&batch, 100); 64 ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch)); 65 ASSERT_EQ(3, WriteBatchInternal::Count(&batch)); 66 ASSERT_EQ("Put(baz, boo)@102" 67 "Delete(box)@101" 68 "Put(foo, bar)@100", 69 PrintContents(&batch)); 70 } 71 72 TEST(WriteBatchTest, Corruption) { 73 WriteBatch batch; 74 batch.Put(Slice("foo"), Slice("bar")); 75 batch.Delete(Slice("box")); 76 WriteBatchInternal::SetSequence(&batch, 200); 77 Slice contents = WriteBatchInternal::Contents(&batch); 78 WriteBatchInternal::SetContents(&batch, 79 Slice(contents.data(),contents.size()-1)); 80 ASSERT_EQ("Put(foo, bar)@200" 81 "ParseError()", 82 PrintContents(&batch)); 83 } 84 85 } 86 87 int main(int argc, char** argv) { 88 return leveldb::test::RunAllTests(); 89 } 90