1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/vdstestlib/cppunit/macros.h>
#include <vespa/memfilepersistence/memfile/shared_data_location_tracker.h>
namespace storage {
namespace memfile {
class SharedDataLocationTrackerTest : public CppUnit::TestFixture
{
public:
void headerIsPassedDownToCacheAccessor();
void bodyIsPassedDownToCacheAccessor();
void firstInvocationReturnsNewLocation();
void multipleInvocationsForSharedSlotReturnSameLocation();
CPPUNIT_TEST_SUITE(SharedDataLocationTrackerTest);
CPPUNIT_TEST(headerIsPassedDownToCacheAccessor);
CPPUNIT_TEST(bodyIsPassedDownToCacheAccessor);
CPPUNIT_TEST(firstInvocationReturnsNewLocation);
CPPUNIT_TEST(multipleInvocationsForSharedSlotReturnSameLocation);
CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION(SharedDataLocationTrackerTest);
namespace {
using Params = std::pair<Types::DocumentPart, DataLocation>;
constexpr auto HEADER = Types::HEADER;
constexpr auto BODY = Types::BODY;
/**
* A simple mock of a buffer cache which records all invocations
* and returns a location increasing by 100 for each invocation.
*/
struct MockBufferCacheCopier : BufferCacheCopier
{
// This is practically _screaming_ for GoogleMock.
std::vector<Params> invocations;
DataLocation doCopyFromSourceToLocal(
Types::DocumentPart part,
DataLocation sourceLocation) override
{
Params params(part, sourceLocation);
const size_t invocationsBefore = invocations.size();
invocations.push_back(params);
return DataLocation(invocationsBefore * 100,
invocationsBefore * 100 + 100);
}
};
}
void
SharedDataLocationTrackerTest::headerIsPassedDownToCacheAccessor()
{
MockBufferCacheCopier cache;
SharedDataLocationTracker tracker(cache, HEADER);
tracker.getOrCreateSharedLocation({0, 100});
CPPUNIT_ASSERT_EQUAL(size_t(1), cache.invocations.size());
CPPUNIT_ASSERT_EQUAL(Params(HEADER, {0, 100}), cache.invocations[0]);
}
void
SharedDataLocationTrackerTest::bodyIsPassedDownToCacheAccessor()
{
MockBufferCacheCopier cache;
SharedDataLocationTracker tracker(cache, BODY);
tracker.getOrCreateSharedLocation({0, 100});
CPPUNIT_ASSERT_EQUAL(size_t(1), cache.invocations.size());
CPPUNIT_ASSERT_EQUAL(Params(BODY, {0, 100}), cache.invocations[0]);
}
void
SharedDataLocationTrackerTest::firstInvocationReturnsNewLocation()
{
MockBufferCacheCopier cache;
SharedDataLocationTracker tracker(cache, HEADER);
// Auto-incrementing per cache copy invocation.
CPPUNIT_ASSERT_EQUAL(DataLocation(0, 100),
tracker.getOrCreateSharedLocation({500, 600}));
CPPUNIT_ASSERT_EQUAL(DataLocation(100, 200),
tracker.getOrCreateSharedLocation({700, 800}));
CPPUNIT_ASSERT_EQUAL(size_t(2), cache.invocations.size());
CPPUNIT_ASSERT_EQUAL(Params(HEADER, {500, 600}), cache.invocations[0]);
CPPUNIT_ASSERT_EQUAL(Params(HEADER, {700, 800}), cache.invocations[1]);
}
void
SharedDataLocationTrackerTest
::multipleInvocationsForSharedSlotReturnSameLocation()
{
MockBufferCacheCopier cache;
SharedDataLocationTracker tracker(cache, HEADER);
CPPUNIT_ASSERT_EQUAL(DataLocation(0, 100),
tracker.getOrCreateSharedLocation({500, 600}));
// Same source location, thus we can reuse the same destination location
// as well.
CPPUNIT_ASSERT_EQUAL(DataLocation(0, 100),
tracker.getOrCreateSharedLocation({500, 600}));
CPPUNIT_ASSERT_EQUAL(size_t(1), cache.invocations.size());
CPPUNIT_ASSERT_EQUAL(Params(HEADER, {500, 600}), cache.invocations[0]);
}
} // memfile
} // storage
|