Home | History | Annotate | Download | only in memenv
      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 "helpers/memenv/memenv.h"
      6 
      7 #include "db/db_impl.h"
      8 #include "leveldb/db.h"
      9 #include "leveldb/env.h"
     10 #include "util/testharness.h"
     11 #include <string>
     12 #include <vector>
     13 
     14 namespace leveldb {
     15 
     16 class MemEnvTest {
     17  public:
     18   Env* env_;
     19 
     20   MemEnvTest()
     21       : env_(NewMemEnv(Env::Default())) {
     22   }
     23   ~MemEnvTest() {
     24     delete env_;
     25   }
     26 };
     27 
     28 TEST(MemEnvTest, Basics) {
     29   uint64_t file_size;
     30   WritableFile* writable_file;
     31   std::vector<std::string> children;
     32 
     33   ASSERT_OK(env_->CreateDir("/dir"));
     34 
     35   // Check that the directory is empty.
     36   ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
     37   ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
     38   ASSERT_OK(env_->GetChildren("/dir", &children));
     39   ASSERT_EQ(0, children.size());
     40 
     41   // Create a file.
     42   ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
     43   delete writable_file;
     44 
     45   // Check that the file exists.
     46   ASSERT_TRUE(env_->FileExists("/dir/f"));
     47   ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
     48   ASSERT_EQ(0, file_size);
     49   ASSERT_OK(env_->GetChildren("/dir", &children));
     50   ASSERT_EQ(1, children.size());
     51   ASSERT_EQ("f", children[0]);
     52 
     53   // Write to the file.
     54   ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
     55   ASSERT_OK(writable_file->Append("abc"));
     56   delete writable_file;
     57 
     58   // Check for expected size.
     59   ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
     60   ASSERT_EQ(3, file_size);
     61 
     62   // Check that renaming works.
     63   ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
     64   ASSERT_OK(env_->RenameFile("/dir/f", "/dir/g"));
     65   ASSERT_TRUE(!env_->FileExists("/dir/f"));
     66   ASSERT_TRUE(env_->FileExists("/dir/g"));
     67   ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
     68   ASSERT_EQ(3, file_size);
     69 
     70   // Check that opening non-existent file fails.
     71   SequentialFile* seq_file;
     72   RandomAccessFile* rand_file;
     73   ASSERT_TRUE(!env_->NewSequentialFile("/dir/non_existent", &seq_file).ok());
     74   ASSERT_TRUE(!seq_file);
     75   ASSERT_TRUE(!env_->NewRandomAccessFile("/dir/non_existent", &rand_file).ok());
     76   ASSERT_TRUE(!rand_file);
     77 
     78   // Check that deleting works.
     79   ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
     80   ASSERT_OK(env_->DeleteFile("/dir/g"));
     81   ASSERT_TRUE(!env_->FileExists("/dir/g"));
     82   ASSERT_OK(env_->GetChildren("/dir", &children));
     83   ASSERT_EQ(0, children.size());
     84   ASSERT_OK(env_->DeleteDir("/dir"));
     85 }
     86 
     87 TEST(MemEnvTest, ReadWrite) {
     88   WritableFile* writable_file;
     89   SequentialFile* seq_file;
     90   RandomAccessFile* rand_file;
     91   Slice result;
     92   char scratch[100];
     93 
     94   ASSERT_OK(env_->CreateDir("/dir"));
     95 
     96   ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
     97   ASSERT_OK(writable_file->Append("hello "));
     98   ASSERT_OK(writable_file->Append("world"));
     99   delete writable_file;
    100 
    101   // Read sequentially.
    102   ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
    103   ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
    104   ASSERT_EQ(0, result.compare("hello"));
    105   ASSERT_OK(seq_file->Skip(1));
    106   ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
    107   ASSERT_EQ(0, result.compare("world"));
    108   ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
    109   ASSERT_EQ(0, result.size());
    110   ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.
    111   ASSERT_OK(seq_file->Read(1000, &result, scratch));
    112   ASSERT_EQ(0, result.size());
    113   delete seq_file;
    114 
    115   // Random reads.
    116   ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
    117   ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
    118   ASSERT_EQ(0, result.compare("world"));
    119   ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
    120   ASSERT_EQ(0, result.compare("hello"));
    121   ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
    122   ASSERT_EQ(0, result.compare("d"));
    123 
    124   // Too high offset.
    125   ASSERT_TRUE(!rand_file->Read(1000, 5, &result, scratch).ok());
    126   delete rand_file;
    127 }
    128 
    129 TEST(MemEnvTest, Locks) {
    130   FileLock* lock;
    131 
    132   // These are no-ops, but we test they return success.
    133   ASSERT_OK(env_->LockFile("some file", &lock));
    134   ASSERT_OK(env_->UnlockFile(lock));
    135 }
    136 
    137 TEST(MemEnvTest, Misc) {
    138   std::string test_dir;
    139   ASSERT_OK(env_->GetTestDirectory(&test_dir));
    140   ASSERT_TRUE(!test_dir.empty());
    141 
    142   WritableFile* writable_file;
    143   ASSERT_OK(env_->NewWritableFile("/a/b", &writable_file));
    144 
    145   // These are no-ops, but we test they return success.
    146   ASSERT_OK(writable_file->Sync());
    147   ASSERT_OK(writable_file->Flush());
    148   ASSERT_OK(writable_file->Close());
    149   delete writable_file;
    150 }
    151 
    152 TEST(MemEnvTest, LargeWrite) {
    153   const size_t kWriteSize = 300 * 1024;
    154   char* scratch = new char[kWriteSize * 2];
    155 
    156   std::string write_data;
    157   for (size_t i = 0; i < kWriteSize; ++i) {
    158     write_data.append(1, static_cast<char>(i));
    159   }
    160 
    161   WritableFile* writable_file;
    162   ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
    163   ASSERT_OK(writable_file->Append("foo"));
    164   ASSERT_OK(writable_file->Append(write_data));
    165   delete writable_file;
    166 
    167   SequentialFile* seq_file;
    168   Slice result;
    169   ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
    170   ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
    171   ASSERT_EQ(0, result.compare("foo"));
    172 
    173   size_t read = 0;
    174   std::string read_data;
    175   while (read < kWriteSize) {
    176     ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch));
    177     read_data.append(result.data(), result.size());
    178     read += result.size();
    179   }
    180   ASSERT_TRUE(write_data == read_data);
    181   delete seq_file;
    182   delete [] scratch;
    183 }
    184 
    185 TEST(MemEnvTest, DBTest) {
    186   Options options;
    187   options.create_if_missing = true;
    188   options.env = env_;
    189   DB* db;
    190 
    191   const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
    192   const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")};
    193 
    194   ASSERT_OK(DB::Open(options, "/dir/db", &db));
    195   for (size_t i = 0; i < 3; ++i) {
    196     ASSERT_OK(db->Put(WriteOptions(), keys[i], vals[i]));
    197   }
    198 
    199   for (size_t i = 0; i < 3; ++i) {
    200     std::string res;
    201     ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
    202     ASSERT_TRUE(res == vals[i]);
    203   }
    204 
    205   Iterator* iterator = db->NewIterator(ReadOptions());
    206   iterator->SeekToFirst();
    207   for (size_t i = 0; i < 3; ++i) {
    208     ASSERT_TRUE(iterator->Valid());
    209     ASSERT_TRUE(keys[i] == iterator->key());
    210     ASSERT_TRUE(vals[i] == iterator->value());
    211     iterator->Next();
    212   }
    213   ASSERT_TRUE(!iterator->Valid());
    214   delete iterator;
    215 
    216   DBImpl* dbi = reinterpret_cast<DBImpl*>(db);
    217   ASSERT_OK(dbi->TEST_CompactMemTable());
    218 
    219   for (size_t i = 0; i < 3; ++i) {
    220     std::string res;
    221     ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
    222     ASSERT_TRUE(res == vals[i]);
    223   }
    224 
    225   delete db;
    226 }
    227 
    228 }  // namespace leveldb
    229 
    230 int main(int argc, char** argv) {
    231   return leveldb::test::RunAllTests();
    232 }
    233