2015-02-17 00:40:34 +01:00
# include "../../../../implementations/onblocks/datanodestore/DataLeafNode.h"
# include "../../../../implementations/onblocks/datanodestore/DataInnerNode.h"
# include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h"
2015-03-12 15:18:10 +01:00
# include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
2015-02-17 00:40:34 +01:00
# include <google/gtest/gtest.h>
2014-12-10 17:59:45 +01:00
2015-02-17 00:40:34 +01:00
# include "messmer/cpp-utils/pointer.h"
2015-01-22 23:37:03 +01:00
2015-02-17 00:40:34 +01:00
# include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
# include "messmer/blockstore/implementations/testfake/FakeBlock.h"
# include "../../../testutils/DataBlockFixture.h"
2014-12-10 17:59:45 +01:00
using : : testing : : Test ;
using : : testing : : WithParamInterface ;
using : : testing : : Values ;
2014-12-13 18:47:31 +01:00
using : : testing : : Combine ;
2014-12-10 17:59:45 +01:00
using std : : unique_ptr ;
using std : : make_unique ;
using std : : string ;
2015-03-04 21:56:48 +01:00
//TODO Split into multiple files
2015-02-17 00:40:34 +01:00
using cpputils : : dynamic_pointer_move ;
2015-01-22 23:37:03 +01:00
2014-12-10 17:59:45 +01:00
using blockstore : : BlockStore ;
using blockstore : : Data ;
2014-12-13 19:17:08 +01:00
using blockstore : : Key ;
2014-12-11 01:31:21 +01:00
using blockstore : : testfake : : FakeBlockStore ;
2014-12-10 17:59:45 +01:00
using namespace blobstore ;
using namespace blobstore : : onblocks ;
2014-12-13 19:17:08 +01:00
using namespace blobstore : : onblocks : : datanodestore ;
2014-12-10 17:59:45 +01:00
2014-12-10 22:55:02 +01:00
# define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type"
2014-12-10 17:59:45 +01:00
class DataLeafNodeTest : public Test {
public :
2015-02-25 22:30:48 +01:00
static constexpr uint32_t BLOCKSIZE_BYTES = 1024 ;
2015-03-04 21:56:48 +01:00
static constexpr DataNodeLayout LAYOUT = DataNodeLayout ( BLOCKSIZE_BYTES ) ;
2015-02-25 22:30:48 +01:00
2014-12-11 00:20:23 +01:00
DataLeafNodeTest ( ) :
2014-12-13 17:43:02 +01:00
_blockStore ( make_unique < FakeBlockStore > ( ) ) ,
blockStore ( _blockStore . get ( ) ) ,
2015-02-25 22:30:48 +01:00
nodeStore ( make_unique < DataNodeStore > ( std : : move ( _blockStore ) , BLOCKSIZE_BYTES ) ) ,
randomData ( nodeStore - > layout ( ) . maxBytesPerLeaf ( ) ) ,
ZEROES ( nodeStore - > layout ( ) . maxBytesPerLeaf ( ) ) ,
2014-12-13 17:43:02 +01:00
leaf ( nodeStore - > createNewLeafNode ( ) ) {
2014-12-11 00:20:23 +01:00
ZEROES . FillWithZeroes ( ) ;
2015-02-25 22:30:48 +01:00
DataBlockFixture dataFixture ( nodeStore - > layout ( ) . maxBytesPerLeaf ( ) ) ;
2014-12-10 17:59:45 +01:00
std : : memcpy ( randomData . data ( ) , dataFixture . data ( ) , randomData . size ( ) ) ;
}
2015-03-04 20:58:39 +01:00
Data loadData ( const DataLeafNode & leaf ) {
Data data ( leaf . numBytes ( ) ) ;
leaf . read ( data . data ( ) , 0 , leaf . numBytes ( ) ) ;
return data ;
}
2014-12-10 17:59:45 +01:00
Key WriteDataToNewLeafBlockAndReturnKey ( ) {
2014-12-13 17:43:02 +01:00
auto newleaf = nodeStore - > createNewLeafNode ( ) ;
newleaf - > resize ( randomData . size ( ) ) ;
2015-03-04 20:58:39 +01:00
newleaf - > write ( randomData . data ( ) , 0 , randomData . size ( ) ) ;
2014-12-13 17:43:02 +01:00
return newleaf - > key ( ) ;
2014-12-10 17:59:45 +01:00
}
2014-12-11 00:20:23 +01:00
void FillLeafBlockWithData ( ) {
2015-01-24 00:54:27 +01:00
FillLeafBlockWithData ( leaf . get ( ) ) ;
}
void FillLeafBlockWithData ( DataLeafNode * leaf_to_fill ) {
leaf_to_fill - > resize ( randomData . size ( ) ) ;
2015-03-04 20:58:39 +01:00
leaf_to_fill - > write ( randomData . data ( ) , 0 , randomData . size ( ) ) ;
2014-12-11 00:20:23 +01:00
}
2015-01-22 23:37:03 +01:00
unique_ptr < DataLeafNode > LoadLeafNode ( const Key & key ) {
2014-12-13 17:43:02 +01:00
auto leaf = nodeStore - > load ( key ) ;
2015-01-22 23:37:03 +01:00
return dynamic_pointer_move < DataLeafNode > ( leaf ) ;
2014-12-10 17:59:45 +01:00
}
2014-12-13 17:43:02 +01:00
void ResizeLeaf ( const Key & key , size_t size ) {
2015-01-22 23:37:03 +01:00
auto leaf = LoadLeafNode ( key ) ;
2014-12-13 17:43:02 +01:00
EXPECT_IS_PTR_TYPE ( DataLeafNode , leaf . get ( ) ) ;
leaf - > resize ( size ) ;
}
2015-01-24 00:54:27 +01:00
Key CreateLeafWithDataConvertItToInnerNodeAndReturnKey ( ) {
auto leaf = nodeStore - > createNewLeafNode ( ) ;
FillLeafBlockWithData ( leaf . get ( ) ) ;
auto child = nodeStore - > createNewLeafNode ( ) ;
unique_ptr < DataInnerNode > converted = DataNode : : convertToNewInnerNode ( std : : move ( leaf ) , * child ) ;
return converted - > key ( ) ;
}
2015-01-24 01:59:42 +01:00
unique_ptr < DataLeafNode > CopyLeafNode ( const DataLeafNode & node ) {
auto copied = nodeStore - > createNewNodeAsCopyFrom ( node ) ;
return dynamic_pointer_move < DataLeafNode > ( copied ) ;
}
2015-02-20 19:46:52 +01:00
Key InitializeLeafGrowAndReturnKey ( ) {
2015-04-25 00:08:29 +02:00
auto leaf = DataLeafNode : : InitializeNewNode ( blockStore - > create ( Data ( BLOCKSIZE_BYTES ) ) ) ;
2015-02-20 19:46:52 +01:00
leaf - > resize ( 5 ) ;
return leaf - > key ( ) ;
}
2014-12-13 17:43:02 +01:00
unique_ptr < BlockStore > _blockStore ;
BlockStore * blockStore ;
unique_ptr < DataNodeStore > nodeStore ;
2015-02-25 22:30:48 +01:00
Data ZEROES ;
Data randomData ;
2014-12-13 17:58:11 +01:00
unique_ptr < DataLeafNode > leaf ;
2014-12-10 17:59:45 +01:00
} ;
2015-02-25 22:30:48 +01:00
constexpr uint32_t DataLeafNodeTest : : BLOCKSIZE_BYTES ;
2015-03-04 21:56:48 +01:00
constexpr DataNodeLayout DataLeafNodeTest : : LAYOUT ;
2015-02-25 22:30:48 +01:00
2015-02-27 14:32:28 +01:00
TEST_F ( DataLeafNodeTest , CorrectKeyReturnedAfterInitialization ) {
2015-04-25 00:08:29 +02:00
auto block = blockStore - > create ( Data ( BLOCKSIZE_BYTES ) ) ;
2015-02-27 14:32:28 +01:00
Key key = block - > key ( ) ;
auto node = DataLeafNode : : InitializeNewNode ( std : : move ( block ) ) ;
EXPECT_EQ ( key , node - > key ( ) ) ;
}
TEST_F ( DataLeafNodeTest , CorrectKeyReturnedAfterLoading ) {
2015-04-25 00:08:29 +02:00
auto block = blockStore - > create ( Data ( BLOCKSIZE_BYTES ) ) ;
2015-02-27 14:32:28 +01:00
Key key = block - > key ( ) ;
DataLeafNode : : InitializeNewNode ( std : : move ( block ) ) ;
auto loaded = nodeStore - > load ( key ) ;
EXPECT_EQ ( key , loaded - > key ( ) ) ;
}
2014-12-13 17:58:11 +01:00
TEST_F ( DataLeafNodeTest , InitializesCorrectly ) {
2015-04-25 00:08:29 +02:00
auto leaf = DataLeafNode : : InitializeNewNode ( blockStore - > create ( Data ( BLOCKSIZE_BYTES ) ) ) ;
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( 0u , leaf - > numBytes ( ) ) ;
2014-12-13 17:58:11 +01:00
}
TEST_F ( DataLeafNodeTest , ReinitializesCorrectly ) {
2015-02-20 19:46:52 +01:00
auto key = InitializeLeafGrowAndReturnKey ( ) ;
auto leaf = DataLeafNode : : InitializeNewNode ( blockStore - > load ( key ) ) ;
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( 0u , leaf - > numBytes ( ) ) ;
2014-12-10 17:59:45 +01:00
}
2015-01-22 23:37:03 +01:00
TEST_F ( DataLeafNodeTest , ReadWrittenDataAfterReloadingBlock ) {
2014-12-10 17:59:45 +01:00
Key key = WriteDataToNewLeafBlockAndReturnKey ( ) ;
2015-01-22 23:37:03 +01:00
auto loaded = LoadLeafNode ( key ) ;
2014-12-10 17:59:45 +01:00
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( randomData . size ( ) , loaded - > numBytes ( ) ) ;
2015-03-04 20:58:39 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( randomData . data ( ) , loadData ( * loaded ) . data ( ) , randomData . size ( ) ) ) ;
2014-12-10 17:59:45 +01:00
}
2014-12-10 22:55:02 +01:00
TEST_F ( DataLeafNodeTest , NewLeafNodeHasSizeZero ) {
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( 0u , leaf - > numBytes ( ) ) ;
2014-12-10 22:55:02 +01:00
}
TEST_F ( DataLeafNodeTest , NewLeafNodeHasSizeZero_AfterLoading ) {
2014-12-13 17:43:02 +01:00
Key key = nodeStore - > createNewLeafNode ( ) - > key ( ) ;
2015-01-22 23:37:03 +01:00
auto leaf = LoadLeafNode ( key ) ;
2014-12-10 22:55:02 +01:00
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( 0u , leaf - > numBytes ( ) ) ;
2014-12-10 22:55:02 +01:00
}
2014-12-13 17:43:02 +01:00
class DataLeafNodeSizeTest : public DataLeafNodeTest , public WithParamInterface < unsigned int > {
public :
Key CreateLeafResizeItAndReturnKey ( ) {
auto leaf = nodeStore - > createNewLeafNode ( ) ;
leaf - > resize ( GetParam ( ) ) ;
return leaf - > key ( ) ;
}
} ;
2015-02-25 22:30:48 +01:00
INSTANTIATE_TEST_CASE_P ( DataLeafNodeSizeTest , DataLeafNodeSizeTest , Values ( 0 , 1 , 5 , 16 , 32 , 512 , DataNodeLayout ( DataLeafNodeTest : : BLOCKSIZE_BYTES ) . maxBytesPerLeaf ( ) ) ) ;
2014-12-10 23:34:36 +01:00
TEST_P ( DataLeafNodeSizeTest , ResizeNode_ReadSizeImmediately ) {
leaf - > resize ( GetParam ( ) ) ;
2015-01-22 23:37:03 +01:00
EXPECT_EQ ( GetParam ( ) , leaf - > numBytes ( ) ) ;
2014-12-10 23:34:36 +01:00
}
TEST_P ( DataLeafNodeSizeTest , ResizeNode_ReadSizeAfterLoading ) {
2014-12-13 17:43:02 +01:00
Key key = CreateLeafResizeItAndReturnKey ( ) ;
2015-01-22 23:37:03 +01:00
auto leaf = LoadLeafNode ( key ) ;
EXPECT_EQ ( GetParam ( ) , leaf - > numBytes ( ) ) ;
2014-12-10 23:34:36 +01:00
}
2014-12-11 00:20:23 +01:00
TEST_F ( DataLeafNodeTest , SpaceIsZeroFilledWhenGrowing ) {
leaf - > resize ( randomData . size ( ) ) ;
2015-03-04 20:58:39 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( ZEROES . data ( ) , loadData ( * leaf ) . data ( ) , randomData . size ( ) ) ) ;
2014-12-11 00:20:23 +01:00
}
TEST_F ( DataLeafNodeTest , SpaceGetsZeroFilledWhenShrinkingAndRegrowing ) {
FillLeafBlockWithData ( ) ;
// resize it smaller and then back to original size
uint32_t smaller_size = randomData . size ( ) - 100 ;
leaf - > resize ( smaller_size ) ;
leaf - > resize ( randomData . size ( ) ) ;
//Check that the space was filled with zeroes
2015-03-04 20:58:39 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( ZEROES . data ( ) , ( ( uint8_t * ) loadData ( * leaf ) . data ( ) ) + smaller_size , 100 ) ) ;
2014-12-11 00:20:23 +01:00
}
TEST_F ( DataLeafNodeTest , DataGetsZeroFilledWhenShrinking ) {
2014-12-13 17:43:02 +01:00
Key key = WriteDataToNewLeafBlockAndReturnKey ( ) ;
2014-12-11 00:20:23 +01:00
uint32_t smaller_size = randomData . size ( ) - 100 ;
2014-12-13 17:43:02 +01:00
{
//At first, we expect there to be random data in the underlying data block
auto block = blockStore - > load ( key ) ;
2015-02-25 22:30:48 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( ( char * ) randomData . data ( ) + smaller_size , ( uint8_t * ) block - > data ( ) + DataNodeLayout : : HEADERSIZE_BYTES + smaller_size , 100 ) ) ;
2014-12-13 17:43:02 +01:00
}
2014-12-11 00:20:23 +01:00
//After shrinking, we expect there to be zeroes in the underlying data block
2014-12-13 17:43:02 +01:00
ResizeLeaf ( key , smaller_size ) ;
{
2015-01-22 23:37:03 +01:00
auto block = blockStore - > load ( key ) ;
2015-02-25 22:30:48 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( ZEROES . data ( ) , ( uint8_t * ) block - > data ( ) + DataNodeLayout : : HEADERSIZE_BYTES + smaller_size , 100 ) ) ;
2014-12-13 17:43:02 +01:00
}
2014-12-11 00:20:23 +01:00
}
2015-01-22 23:37:03 +01:00
TEST_F ( DataLeafNodeTest , ShrinkingDoesntDestroyValidDataRegion ) {
FillLeafBlockWithData ( ) ;
uint32_t smaller_size = randomData . size ( ) - 100 ;
leaf - > resize ( smaller_size ) ;
//Check that the remaining data region is unchanged
2015-03-04 20:58:39 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( randomData . data ( ) , loadData ( * leaf ) . data ( ) , smaller_size ) ) ;
2015-01-22 23:37:03 +01:00
}
2015-01-24 00:54:27 +01:00
TEST_F ( DataLeafNodeTest , ConvertToInternalNode ) {
auto child = nodeStore - > createNewLeafNode ( ) ;
Key leaf_key = leaf - > key ( ) ;
unique_ptr < DataInnerNode > converted = DataNode : : convertToNewInnerNode ( std : : move ( leaf ) , * child ) ;
EXPECT_EQ ( 1u , converted - > numChildren ( ) ) ;
EXPECT_EQ ( child - > key ( ) , converted - > getChild ( 0 ) - > key ( ) ) ;
EXPECT_EQ ( leaf_key , converted - > key ( ) ) ;
}
TEST_F ( DataLeafNodeTest , ConvertToInternalNodeZeroesOutChildrenRegion ) {
Key key = CreateLeafWithDataConvertItToInnerNodeAndReturnKey ( ) ;
auto block = blockStore - > load ( key ) ;
2015-02-25 22:30:48 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( ZEROES . data ( ) , ( uint8_t * ) block - > data ( ) + DataNodeLayout : : HEADERSIZE_BYTES + sizeof ( DataInnerNode : : ChildEntry ) , nodeStore - > layout ( ) . maxBytesPerLeaf ( ) - sizeof ( DataInnerNode : : ChildEntry ) ) ) ;
2015-01-24 00:54:27 +01:00
}
2015-01-24 01:59:42 +01:00
TEST_F ( DataLeafNodeTest , CopyingCreatesANewLeaf ) {
auto copied = CopyLeafNode ( * leaf ) ;
EXPECT_NE ( leaf - > key ( ) , copied - > key ( ) ) ;
}
TEST_F ( DataLeafNodeTest , CopyEmptyLeaf ) {
auto copied = CopyLeafNode ( * leaf ) ;
EXPECT_EQ ( leaf - > numBytes ( ) , copied - > numBytes ( ) ) ;
}
TEST_F ( DataLeafNodeTest , CopyDataLeaf ) {
FillLeafBlockWithData ( ) ;
auto copied = CopyLeafNode ( * leaf ) ;
EXPECT_EQ ( leaf - > numBytes ( ) , copied - > numBytes ( ) ) ;
2015-03-04 20:58:39 +01:00
EXPECT_EQ ( 0 , std : : memcmp ( loadData ( * leaf ) . data ( ) , loadData ( * copied ) . data ( ) , leaf - > numBytes ( ) ) ) ;
//Test that they have different data regions (changing the original one doesn't change the copy)
char data = ' \0 ' ;
leaf - > write ( & data , 0 , 1 ) ;
EXPECT_EQ ( data , * ( char * ) loadData ( * leaf ) . data ( ) ) ;
EXPECT_NE ( data , * ( char * ) loadData ( * copied ) . data ( ) ) ;
2015-01-24 01:59:42 +01:00
}
2015-01-22 23:37:03 +01:00
2014-12-13 18:47:31 +01:00
struct DataRange {
DataRange ( size_t leafsize_ , off_t offset_ , size_t count_ ) : leafsize ( leafsize_ ) , offset ( offset_ ) , count ( count_ ) { }
size_t leafsize ;
off_t offset ;
size_t count ;
} ;
class DataLeafNodeDataTest : public DataLeafNodeTest , public WithParamInterface < DataRange > {
public :
Data foregroundData ;
Data backgroundData ;
DataLeafNodeDataTest ( ) : foregroundData ( GetParam ( ) . count ) , backgroundData ( GetParam ( ) . leafsize ) {
DataBlockFixture _foregroundData ( GetParam ( ) . count ) ;
DataBlockFixture _backgroundData ( GetParam ( ) . leafsize ) ;
std : : memcpy ( foregroundData . data ( ) , _foregroundData . data ( ) , foregroundData . size ( ) ) ;
std : : memcpy ( backgroundData . data ( ) , _backgroundData . data ( ) , backgroundData . size ( ) ) ;
}
void EXPECT_DATA_EQ ( const Data & expected , const Data & actual ) {
EXPECT_EQ ( expected . size ( ) , actual . size ( ) ) ;
EXPECT_EQ ( 0 , std : : memcmp ( expected . data ( ) , actual . data ( ) , expected . size ( ) ) ) ;
}
Key CreateLeafWriteToItAndReturnKey ( const Data & to_write ) {
auto newleaf = nodeStore - > createNewLeafNode ( ) ;
newleaf - > resize ( GetParam ( ) . leafsize ) ;
2015-03-04 21:56:48 +01:00
newleaf - > write ( to_write . data ( ) , GetParam ( ) . offset , GetParam ( ) . count ) ;
2014-12-13 18:47:31 +01:00
return newleaf - > key ( ) ;
}
2015-03-04 21:56:48 +01:00
void EXPECT_DATA_READS_AS ( const Data & expected , const DataLeafNode & leaf , off_t offset , size_t count ) {
2014-12-13 18:47:31 +01:00
Data read ( count ) ;
2015-03-04 21:56:48 +01:00
leaf . read ( read . data ( ) , offset , count ) ;
2014-12-13 18:47:31 +01:00
EXPECT_DATA_EQ ( expected , read ) ;
}
2015-03-04 21:56:48 +01:00
void EXPECT_DATA_READS_AS_OUTSIDE_OF ( const Data & expected , const DataLeafNode & leaf , off_t start , size_t count ) {
2014-12-13 18:47:31 +01:00
Data begin ( start ) ;
Data end ( GetParam ( ) . leafsize - count - start ) ;
std : : memcpy ( begin . data ( ) , expected . data ( ) , start ) ;
std : : memcpy ( end . data ( ) , ( uint8_t * ) expected . data ( ) + start + count , end . size ( ) ) ;
EXPECT_DATA_READS_AS ( begin , leaf , 0 , start ) ;
EXPECT_DATA_READS_AS ( end , leaf , start + count , end . size ( ) ) ;
}
2015-03-04 21:56:48 +01:00
void EXPECT_DATA_IS_ZEROES_OUTSIDE_OF ( const DataLeafNode & leaf , off_t start , size_t count ) {
2014-12-13 18:47:31 +01:00
Data ZEROES ( GetParam ( ) . leafsize ) ;
ZEROES . FillWithZeroes ( ) ;
EXPECT_DATA_READS_AS_OUTSIDE_OF ( ZEROES , leaf , start , count ) ;
}
} ;
INSTANTIATE_TEST_CASE_P ( DataLeafNodeDataTest , DataLeafNodeDataTest , Values (
2015-03-04 21:56:48 +01:00
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) , 0 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) ) , // full size leaf, access beginning to end
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) , 100 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 200 ) , // full size leaf, access middle to middle
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) , 0 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 ) , // full size leaf, access beginning to middle
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) , 100 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 ) , // full size leaf, access middle to end
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 , 0 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 ) , // non-full size leaf, access beginning to end
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 , 100 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 300 ) , // non-full size leaf, access middle to middle
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 , 0 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 200 ) , // non-full size leaf, access beginning to middle
DataRange ( DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 100 , 100 , DataLeafNodeTest : : LAYOUT . maxBytesPerLeaf ( ) - 200 ) // non-full size leaf, access middle to end
2014-12-13 18:47:31 +01:00
) ) ;
TEST_P ( DataLeafNodeDataTest , WriteAndReadImmediately ) {
leaf - > resize ( GetParam ( ) . leafsize ) ;
2015-03-04 21:56:48 +01:00
leaf - > write ( this - > foregroundData . data ( ) , GetParam ( ) . offset , GetParam ( ) . count ) ;
2014-12-13 18:47:31 +01:00
EXPECT_DATA_READS_AS ( this - > foregroundData , * leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
EXPECT_DATA_IS_ZEROES_OUTSIDE_OF ( * leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
}
TEST_P ( DataLeafNodeDataTest , WriteAndReadAfterLoading ) {
Key key = CreateLeafWriteToItAndReturnKey ( this - > foregroundData ) ;
2015-03-04 21:56:48 +01:00
auto loaded_leaf = LoadLeafNode ( key ) ;
2014-12-13 18:47:31 +01:00
EXPECT_DATA_READS_AS ( this - > foregroundData , * loaded_leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
EXPECT_DATA_IS_ZEROES_OUTSIDE_OF ( * loaded_leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
}
TEST_P ( DataLeafNodeDataTest , OverwriteAndRead ) {
leaf - > resize ( GetParam ( ) . leafsize ) ;
2015-03-04 21:56:48 +01:00
leaf - > write ( this - > backgroundData . data ( ) , 0 , GetParam ( ) . leafsize ) ;
leaf - > write ( this - > foregroundData . data ( ) , GetParam ( ) . offset , GetParam ( ) . count ) ;
2014-12-13 18:47:31 +01:00
EXPECT_DATA_READS_AS ( this - > foregroundData , * leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
EXPECT_DATA_READS_AS_OUTSIDE_OF ( this - > backgroundData , * leaf , GetParam ( ) . offset , GetParam ( ) . count ) ;
}