@ -7,6 +7,7 @@
# include <vector>
# include <vector>
# include "rocksdb/env.h"
# include "rocksdb/env.h"
# include "rocksdb/utilities/env_registry.h"
# include "util/mock_env.h"
# include "util/mock_env.h"
# include "util/testharness.h"
# include "util/testharness.h"
@ -17,18 +18,61 @@ class EnvBasicTestWithParam : public testing::Test,
public :
public :
Env * env_ ;
Env * env_ ;
const EnvOptions soptions_ ;
const EnvOptions soptions_ ;
std : : string test_dir_ ;
EnvBasicTestWithParam ( ) { env_ = GetParam ( ) ; }
EnvBasicTestWithParam ( ) {
env_ = GetParam ( ) ;
test_dir_ = test : : TmpDir ( env_ ) + " /env_basic_test " ;
}
void SetUp ( ) {
env_ - > CreateDirIfMissing ( test_dir_ ) ;
std : : vector < std : : string > files ;
env_ - > GetChildren ( test_dir_ , & files ) ;
for ( const auto & file : files ) {
env_ - > DeleteFile ( test_dir_ + " / " + file ) ;
}
}
} ;
} ;
static std : : unique_ptr < Env > mock_env ( new MockEnv ( Env : : Default ( ) ) ) ;
static std : : unique_ptr < Env > mock_env ( new MockEnv ( Env : : Default ( ) ) ) ;
INSTANTIATE_TEST_CASE_P (
INSTANTIATE_TEST_CASE_P ( MockEnv , EnvBasicTestWithParam ,
MockEnv , EnvBasicTestWithParam ,
: : testing : : Values ( mock_env . get ( ) ) ) ;
: : testing : : Values ( mock_env . get ( ) ) ) ;
# ifndef ROCKSDB_LITE
# ifndef ROCKSDB_LITE
static std : : unique_ptr < Env > mem_env ( NewMemEnv ( Env : : Default ( ) ) ) ;
static std : : unique_ptr < Env > mem_env ( NewMemEnv ( Env : : Default ( ) ) ) ;
INSTANTIATE_TEST_CASE_P ( MemEnv , EnvBasicTestWithParam ,
INSTANTIATE_TEST_CASE_P ( MemEnv , EnvBasicTestWithParam ,
: : testing : : Values ( mem_env . get ( ) ) ) ;
: : testing : : Values ( mem_env . get ( ) ) ) ;
namespace {
// Returns a vector of 0 or 1 Env*, depending whether an Env is registered for
// TEST_ENV_URI.
//
// The purpose of returning an empty vector (instead of nullptr) is that gtest
// ValuesIn() will skip running tests when given an empty collection.
std : : vector < Env * > GetCustomEnvs ( ) {
static Env * custom_env ;
static std : : unique_ptr < Env > custom_env_guard ;
static bool init = false ;
if ( ! init ) {
init = true ;
const char * uri = getenv ( " TEST_ENV_URI " ) ;
if ( uri ! = nullptr ) {
custom_env = NewEnvFromUri ( uri , & custom_env_guard ) ;
}
}
std : : vector < Env * > res ;
if ( custom_env ! = nullptr ) {
res . emplace_back ( custom_env ) ;
}
return res ;
}
} // anonymous namespace
INSTANTIATE_TEST_CASE_P ( CustomEnv , EnvBasicTestWithParam ,
: : testing : : ValuesIn ( GetCustomEnvs ( ) ) ) ;
# endif // ROCKSDB_LITE
# endif // ROCKSDB_LITE
TEST_P ( EnvBasicTestWithParam , Basics ) {
TEST_P ( EnvBasicTestWithParam , Basics ) {
@ -36,60 +80,60 @@ TEST_P(EnvBasicTestWithParam, Basics) {
unique_ptr < WritableFile > writable_file ;
unique_ptr < WritableFile > writable_file ;
std : : vector < std : : string > children ;
std : : vector < std : : string > children ;
ASSERT_OK ( env_ - > CreateDir ( " /dir " ) ) ;
// Check that the directory is empty.
// Check that the directory is empty.
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( " /dir /non_existent" ) ) ;
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( test_dir_ + " /non_existent " ) ) ;
ASSERT_TRUE ( ! env_ - > GetFileSize ( " /dir /non_existent" , & file_size ) . ok ( ) ) ;
ASSERT_TRUE ( ! env_ - > GetFileSize ( test_dir_ + " /non_existent " , & file_size ) . ok ( ) ) ;
ASSERT_OK ( env_ - > GetChildren ( " /dir " , & children ) ) ;
ASSERT_OK ( env_ - > GetChildren ( test_dir_ , & children ) ) ;
ASSERT_EQ ( 0U , children . size ( ) ) ;
ASSERT_EQ ( 0U , children . size ( ) ) ;
// Create a file.
// Create a file.
ASSERT_OK ( env_ - > NewWritableFile ( " /dir /f" , & writable_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( test_dir_ + " /f " , & writable_file , soptions_ ) ) ;
writable_file . reset ( ) ;
writable_file . reset ( ) ;
// Check that the file exists.
// Check that the file exists.
ASSERT_OK ( env_ - > FileExists ( " /dir /f" ) ) ;
ASSERT_OK ( env_ - > FileExists ( test_dir_ + " /f " ) ) ;
ASSERT_OK ( env_ - > GetFileSize ( " /dir /f" , & file_size ) ) ;
ASSERT_OK ( env_ - > GetFileSize ( test_dir_ + " /f " , & file_size ) ) ;
ASSERT_EQ ( 0U , file_size ) ;
ASSERT_EQ ( 0U , file_size ) ;
ASSERT_OK ( env_ - > GetChildren ( " /dir " , & children ) ) ;
ASSERT_OK ( env_ - > GetChildren ( test_dir_ , & children ) ) ;
ASSERT_EQ ( 1U , children . size ( ) ) ;
ASSERT_EQ ( 1U , children . size ( ) ) ;
ASSERT_EQ ( " f " , children [ 0 ] ) ;
ASSERT_EQ ( " f " , children [ 0 ] ) ;
// Write to the file.
// Write to the file.
ASSERT_OK ( env_ - > NewWritableFile ( " /dir /f" , & writable_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( test_dir_ + " /f " , & writable_file , soptions_ ) ) ;
ASSERT_OK ( writable_file - > Append ( " abc " ) ) ;
ASSERT_OK ( writable_file - > Append ( " abc " ) ) ;
writable_file . reset ( ) ;
writable_file . reset ( ) ;
// Check for expected size.
// Check for expected size.
ASSERT_OK ( env_ - > GetFileSize ( " /dir /f" , & file_size ) ) ;
ASSERT_OK ( env_ - > GetFileSize ( test_dir_ + " /f " , & file_size ) ) ;
ASSERT_EQ ( 3U , file_size ) ;
ASSERT_EQ ( 3U , file_size ) ;
// Check that renaming works.
// Check that renaming works.
ASSERT_TRUE ( ! env_ - > RenameFile ( " /dir /non_existent" , " /dir /g" ) . ok ( ) ) ;
ASSERT_TRUE ( ! env_ - > RenameFile ( test_dir_ + " /non_existent " , " /g " ) . ok ( ) ) ;
ASSERT_OK ( env_ - > RenameFile ( " /dir /f" , " /dir /g" ) ) ;
ASSERT_OK ( env_ - > RenameFile ( test_dir_ + " /f " , test_dir_ + " /g " ) ) ;
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( " /dir /f" ) ) ;
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( test_dir_ + " /f " ) ) ;
ASSERT_OK ( env_ - > FileExists ( " /dir /g" ) ) ;
ASSERT_OK ( env_ - > FileExists ( test_dir_ + " /g " ) ) ;
ASSERT_OK ( env_ - > GetFileSize ( " /dir /g" , & file_size ) ) ;
ASSERT_OK ( env_ - > GetFileSize ( test_dir_ + " /g " , & file_size ) ) ;
ASSERT_EQ ( 3U , file_size ) ;
ASSERT_EQ ( 3U , file_size ) ;
// Check that opening non-existent file fails.
// Check that opening non-existent file fails.
unique_ptr < SequentialFile > seq_file ;
unique_ptr < SequentialFile > seq_file ;
unique_ptr < RandomAccessFile > rand_file ;
unique_ptr < RandomAccessFile > rand_file ;
ASSERT_TRUE ( ! env_ - > NewSequentialFile ( " /dir/non_existent " , & seq_file ,
ASSERT_TRUE ( ! env_ - > NewSequentialFile ( test_dir_ + " /non_existent " , & seq_file ,
soptions_ ) . ok ( ) ) ;
soptions_ )
. ok ( ) ) ;
ASSERT_TRUE ( ! seq_file ) ;
ASSERT_TRUE ( ! seq_file ) ;
ASSERT_TRUE ( ! env_ - > NewRandomAccessFile ( " /dir/non_existent " , & rand_file ,
ASSERT_TRUE ( ! env_ - > NewRandomAccessFile ( test_dir_ + " /non_existent " ,
soptions_ ) . ok ( ) ) ;
& rand_file , soptions_ )
. ok ( ) ) ;
ASSERT_TRUE ( ! rand_file ) ;
ASSERT_TRUE ( ! rand_file ) ;
// Check that deleting works.
// Check that deleting works.
ASSERT_TRUE ( ! env_ - > DeleteFile ( " /dir /non_existent" ) . ok ( ) ) ;
ASSERT_TRUE ( ! env_ - > DeleteFile ( test_dir_ + " /non_existent " ) . ok ( ) ) ;
ASSERT_OK ( env_ - > DeleteFile ( " /dir /g" ) ) ;
ASSERT_OK ( env_ - > DeleteFile ( test_dir_ + " /g " ) ) ;
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( " /dir /g" ) ) ;
ASSERT_EQ ( Status : : NotFound ( ) , env_ - > FileExists ( test_dir_ + " /g " ) ) ;
ASSERT_OK ( env_ - > GetChildren ( " /dir " , & children ) ) ;
ASSERT_OK ( env_ - > GetChildren ( test_dir_ , & children ) ) ;
ASSERT_EQ ( 0U , children . size ( ) ) ;
ASSERT_EQ ( 0U , children . size ( ) ) ;
ASSERT_OK ( env_ - > DeleteDir ( " /dir " ) ) ;
ASSERT_OK ( env_ - > DeleteDir ( test_dir_ ) ) ;
}
}
TEST_P ( EnvBasicTestWithParam , ReadWrite ) {
TEST_P ( EnvBasicTestWithParam , ReadWrite ) {
@ -99,15 +143,13 @@ TEST_P(EnvBasicTestWithParam, ReadWrite) {
Slice result ;
Slice result ;
char scratch [ 100 ] ;
char scratch [ 100 ] ;
ASSERT_OK ( env_ - > CreateDir ( " /dir " ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( test_dir_ + " /f " , & writable_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( " /dir/f " , & writable_file , soptions_ ) ) ;
ASSERT_OK ( writable_file - > Append ( " hello " ) ) ;
ASSERT_OK ( writable_file - > Append ( " hello " ) ) ;
ASSERT_OK ( writable_file - > Append ( " world " ) ) ;
ASSERT_OK ( writable_file - > Append ( " world " ) ) ;
writable_file . reset ( ) ;
writable_file . reset ( ) ;
// Read sequentially.
// Read sequentially.
ASSERT_OK ( env_ - > NewSequentialFile ( " /dir /f" , & seq_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewSequentialFile ( test_dir_ + " /f " , & seq_file , soptions_ ) ) ;
ASSERT_OK ( seq_file - > Read ( 5 , & result , scratch ) ) ; // Read "hello".
ASSERT_OK ( seq_file - > Read ( 5 , & result , scratch ) ) ; // Read "hello".
ASSERT_EQ ( 0 , result . compare ( " hello " ) ) ;
ASSERT_EQ ( 0 , result . compare ( " hello " ) ) ;
ASSERT_OK ( seq_file - > Skip ( 1 ) ) ;
ASSERT_OK ( seq_file - > Skip ( 1 ) ) ;
@ -120,7 +162,7 @@ TEST_P(EnvBasicTestWithParam, ReadWrite) {
ASSERT_EQ ( 0U , result . size ( ) ) ;
ASSERT_EQ ( 0U , result . size ( ) ) ;
// Random reads.
// Random reads.
ASSERT_OK ( env_ - > NewRandomAccessFile ( " /dir /f" , & rand_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewRandomAccessFile ( test_dir_ + " /f " , & rand_file , soptions_ ) ) ;
ASSERT_OK ( rand_file - > Read ( 6 , 5 , & result , scratch ) ) ; // Read "world".
ASSERT_OK ( rand_file - > Read ( 6 , 5 , & result , scratch ) ) ; // Read "world".
ASSERT_EQ ( 0 , result . compare ( " world " ) ) ;
ASSERT_EQ ( 0 , result . compare ( " world " ) ) ;
ASSERT_OK ( rand_file - > Read ( 0 , 5 , & result , scratch ) ) ; // Read "hello".
ASSERT_OK ( rand_file - > Read ( 0 , 5 , & result , scratch ) ) ; // Read "hello".
@ -135,8 +177,9 @@ TEST_P(EnvBasicTestWithParam, ReadWrite) {
TEST_P ( EnvBasicTestWithParam , Locks ) {
TEST_P ( EnvBasicTestWithParam , Locks ) {
FileLock * lock ;
FileLock * lock ;
// These are no-ops, but we test they return success.
// only test they return success.
ASSERT_OK ( env_ - > LockFile ( " some file " , & lock ) ) ;
// TODO(andrewkr): verify functionality
ASSERT_OK ( env_ - > LockFile ( test_dir_ + " lock_file " , & lock ) ) ;
ASSERT_OK ( env_ - > UnlockFile ( lock ) ) ;
ASSERT_OK ( env_ - > UnlockFile ( lock ) ) ;
}
}
@ -146,7 +189,7 @@ TEST_P(EnvBasicTestWithParam, Misc) {
ASSERT_TRUE ( ! test_dir . empty ( ) ) ;
ASSERT_TRUE ( ! test_dir . empty ( ) ) ;
unique_ptr < WritableFile > writable_file ;
unique_ptr < WritableFile > writable_file ;
ASSERT_OK ( env_ - > NewWritableFile ( " /a /b" , & writable_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( test_dir_ + " /b " , & writable_file , soptions_ ) ) ;
// These are no-ops, but we test they return success.
// These are no-ops, but we test they return success.
ASSERT_OK ( writable_file - > Sync ( ) ) ;
ASSERT_OK ( writable_file - > Sync ( ) ) ;
@ -165,14 +208,14 @@ TEST_P(EnvBasicTestWithParam, LargeWrite) {
}
}
unique_ptr < WritableFile > writable_file ;
unique_ptr < WritableFile > writable_file ;
ASSERT_OK ( env_ - > NewWritableFile ( " /dir /f" , & writable_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewWritableFile ( test_dir_ + " /f " , & writable_file , soptions_ ) ) ;
ASSERT_OK ( writable_file - > Append ( " foo " ) ) ;
ASSERT_OK ( writable_file - > Append ( " foo " ) ) ;
ASSERT_OK ( writable_file - > Append ( write_data ) ) ;
ASSERT_OK ( writable_file - > Append ( write_data ) ) ;
writable_file . reset ( ) ;
writable_file . reset ( ) ;
unique_ptr < SequentialFile > seq_file ;
unique_ptr < SequentialFile > seq_file ;
Slice result ;
Slice result ;
ASSERT_OK ( env_ - > NewSequentialFile ( " /dir /f" , & seq_file , soptions_ ) ) ;
ASSERT_OK ( env_ - > NewSequentialFile ( test_dir_ + " /f " , & seq_file , soptions_ ) ) ;
ASSERT_OK ( seq_file - > Read ( 3 , & result , scratch ) ) ; // Read "foo".
ASSERT_OK ( seq_file - > Read ( 3 , & result , scratch ) ) ; // Read "foo".
ASSERT_EQ ( 0 , result . compare ( " foo " ) ) ;
ASSERT_EQ ( 0 , result . compare ( " foo " ) ) ;