1*9507f98cSAndroid Build Coastguard Worker // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2*9507f98cSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*9507f98cSAndroid Build Coastguard Worker // found in the LICENSE file. See the AUTHORS file for names of contributors.
4*9507f98cSAndroid Build Coastguard Worker
5*9507f98cSAndroid Build Coastguard Worker #include "gtest/gtest.h"
6*9507f98cSAndroid Build Coastguard Worker #include "db/log_reader.h"
7*9507f98cSAndroid Build Coastguard Worker #include "db/log_writer.h"
8*9507f98cSAndroid Build Coastguard Worker #include "leveldb/env.h"
9*9507f98cSAndroid Build Coastguard Worker #include "util/coding.h"
10*9507f98cSAndroid Build Coastguard Worker #include "util/crc32c.h"
11*9507f98cSAndroid Build Coastguard Worker #include "util/random.h"
12*9507f98cSAndroid Build Coastguard Worker
13*9507f98cSAndroid Build Coastguard Worker namespace leveldb {
14*9507f98cSAndroid Build Coastguard Worker namespace log {
15*9507f98cSAndroid Build Coastguard Worker
16*9507f98cSAndroid Build Coastguard Worker // Construct a string of the specified length made out of the supplied
17*9507f98cSAndroid Build Coastguard Worker // partial string.
BigString(const std::string & partial_string,size_t n)18*9507f98cSAndroid Build Coastguard Worker static std::string BigString(const std::string& partial_string, size_t n) {
19*9507f98cSAndroid Build Coastguard Worker std::string result;
20*9507f98cSAndroid Build Coastguard Worker while (result.size() < n) {
21*9507f98cSAndroid Build Coastguard Worker result.append(partial_string);
22*9507f98cSAndroid Build Coastguard Worker }
23*9507f98cSAndroid Build Coastguard Worker result.resize(n);
24*9507f98cSAndroid Build Coastguard Worker return result;
25*9507f98cSAndroid Build Coastguard Worker }
26*9507f98cSAndroid Build Coastguard Worker
27*9507f98cSAndroid Build Coastguard Worker // Construct a string from a number
NumberString(int n)28*9507f98cSAndroid Build Coastguard Worker static std::string NumberString(int n) {
29*9507f98cSAndroid Build Coastguard Worker char buf[50];
30*9507f98cSAndroid Build Coastguard Worker std::snprintf(buf, sizeof(buf), "%d.", n);
31*9507f98cSAndroid Build Coastguard Worker return std::string(buf);
32*9507f98cSAndroid Build Coastguard Worker }
33*9507f98cSAndroid Build Coastguard Worker
34*9507f98cSAndroid Build Coastguard Worker // Return a skewed potentially long string
RandomSkewedString(int i,Random * rnd)35*9507f98cSAndroid Build Coastguard Worker static std::string RandomSkewedString(int i, Random* rnd) {
36*9507f98cSAndroid Build Coastguard Worker return BigString(NumberString(i), rnd->Skewed(17));
37*9507f98cSAndroid Build Coastguard Worker }
38*9507f98cSAndroid Build Coastguard Worker
39*9507f98cSAndroid Build Coastguard Worker class LogTest : public testing::Test {
40*9507f98cSAndroid Build Coastguard Worker public:
LogTest()41*9507f98cSAndroid Build Coastguard Worker LogTest()
42*9507f98cSAndroid Build Coastguard Worker : reading_(false),
43*9507f98cSAndroid Build Coastguard Worker writer_(new Writer(&dest_)),
44*9507f98cSAndroid Build Coastguard Worker reader_(new Reader(&source_, &report_, true /*checksum*/,
45*9507f98cSAndroid Build Coastguard Worker 0 /*initial_offset*/)) {}
46*9507f98cSAndroid Build Coastguard Worker
~LogTest()47*9507f98cSAndroid Build Coastguard Worker ~LogTest() {
48*9507f98cSAndroid Build Coastguard Worker delete writer_;
49*9507f98cSAndroid Build Coastguard Worker delete reader_;
50*9507f98cSAndroid Build Coastguard Worker }
51*9507f98cSAndroid Build Coastguard Worker
ReopenForAppend()52*9507f98cSAndroid Build Coastguard Worker void ReopenForAppend() {
53*9507f98cSAndroid Build Coastguard Worker delete writer_;
54*9507f98cSAndroid Build Coastguard Worker writer_ = new Writer(&dest_, dest_.contents_.size());
55*9507f98cSAndroid Build Coastguard Worker }
56*9507f98cSAndroid Build Coastguard Worker
Write(const std::string & msg)57*9507f98cSAndroid Build Coastguard Worker void Write(const std::string& msg) {
58*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(!reading_) << "Write() after starting to read";
59*9507f98cSAndroid Build Coastguard Worker writer_->AddRecord(Slice(msg));
60*9507f98cSAndroid Build Coastguard Worker }
61*9507f98cSAndroid Build Coastguard Worker
WrittenBytes() const62*9507f98cSAndroid Build Coastguard Worker size_t WrittenBytes() const { return dest_.contents_.size(); }
63*9507f98cSAndroid Build Coastguard Worker
Read()64*9507f98cSAndroid Build Coastguard Worker std::string Read() {
65*9507f98cSAndroid Build Coastguard Worker if (!reading_) {
66*9507f98cSAndroid Build Coastguard Worker reading_ = true;
67*9507f98cSAndroid Build Coastguard Worker source_.contents_ = Slice(dest_.contents_);
68*9507f98cSAndroid Build Coastguard Worker }
69*9507f98cSAndroid Build Coastguard Worker std::string scratch;
70*9507f98cSAndroid Build Coastguard Worker Slice record;
71*9507f98cSAndroid Build Coastguard Worker if (reader_->ReadRecord(&record, &scratch)) {
72*9507f98cSAndroid Build Coastguard Worker return record.ToString();
73*9507f98cSAndroid Build Coastguard Worker } else {
74*9507f98cSAndroid Build Coastguard Worker return "EOF";
75*9507f98cSAndroid Build Coastguard Worker }
76*9507f98cSAndroid Build Coastguard Worker }
77*9507f98cSAndroid Build Coastguard Worker
IncrementByte(int offset,int delta)78*9507f98cSAndroid Build Coastguard Worker void IncrementByte(int offset, int delta) {
79*9507f98cSAndroid Build Coastguard Worker dest_.contents_[offset] += delta;
80*9507f98cSAndroid Build Coastguard Worker }
81*9507f98cSAndroid Build Coastguard Worker
SetByte(int offset,char new_byte)82*9507f98cSAndroid Build Coastguard Worker void SetByte(int offset, char new_byte) {
83*9507f98cSAndroid Build Coastguard Worker dest_.contents_[offset] = new_byte;
84*9507f98cSAndroid Build Coastguard Worker }
85*9507f98cSAndroid Build Coastguard Worker
ShrinkSize(int bytes)86*9507f98cSAndroid Build Coastguard Worker void ShrinkSize(int bytes) {
87*9507f98cSAndroid Build Coastguard Worker dest_.contents_.resize(dest_.contents_.size() - bytes);
88*9507f98cSAndroid Build Coastguard Worker }
89*9507f98cSAndroid Build Coastguard Worker
FixChecksum(int header_offset,int len)90*9507f98cSAndroid Build Coastguard Worker void FixChecksum(int header_offset, int len) {
91*9507f98cSAndroid Build Coastguard Worker // Compute crc of type/len/data
92*9507f98cSAndroid Build Coastguard Worker uint32_t crc = crc32c::Value(&dest_.contents_[header_offset + 6], 1 + len);
93*9507f98cSAndroid Build Coastguard Worker crc = crc32c::Mask(crc);
94*9507f98cSAndroid Build Coastguard Worker EncodeFixed32(&dest_.contents_[header_offset], crc);
95*9507f98cSAndroid Build Coastguard Worker }
96*9507f98cSAndroid Build Coastguard Worker
ForceError()97*9507f98cSAndroid Build Coastguard Worker void ForceError() { source_.force_error_ = true; }
98*9507f98cSAndroid Build Coastguard Worker
DroppedBytes() const99*9507f98cSAndroid Build Coastguard Worker size_t DroppedBytes() const { return report_.dropped_bytes_; }
100*9507f98cSAndroid Build Coastguard Worker
ReportMessage() const101*9507f98cSAndroid Build Coastguard Worker std::string ReportMessage() const { return report_.message_; }
102*9507f98cSAndroid Build Coastguard Worker
103*9507f98cSAndroid Build Coastguard Worker // Returns OK iff recorded error message contains "msg"
MatchError(const std::string & msg) const104*9507f98cSAndroid Build Coastguard Worker std::string MatchError(const std::string& msg) const {
105*9507f98cSAndroid Build Coastguard Worker if (report_.message_.find(msg) == std::string::npos) {
106*9507f98cSAndroid Build Coastguard Worker return report_.message_;
107*9507f98cSAndroid Build Coastguard Worker } else {
108*9507f98cSAndroid Build Coastguard Worker return "OK";
109*9507f98cSAndroid Build Coastguard Worker }
110*9507f98cSAndroid Build Coastguard Worker }
111*9507f98cSAndroid Build Coastguard Worker
WriteInitialOffsetLog()112*9507f98cSAndroid Build Coastguard Worker void WriteInitialOffsetLog() {
113*9507f98cSAndroid Build Coastguard Worker for (int i = 0; i < num_initial_offset_records_; i++) {
114*9507f98cSAndroid Build Coastguard Worker std::string record(initial_offset_record_sizes_[i],
115*9507f98cSAndroid Build Coastguard Worker static_cast<char>('a' + i));
116*9507f98cSAndroid Build Coastguard Worker Write(record);
117*9507f98cSAndroid Build Coastguard Worker }
118*9507f98cSAndroid Build Coastguard Worker }
119*9507f98cSAndroid Build Coastguard Worker
StartReadingAt(uint64_t initial_offset)120*9507f98cSAndroid Build Coastguard Worker void StartReadingAt(uint64_t initial_offset) {
121*9507f98cSAndroid Build Coastguard Worker delete reader_;
122*9507f98cSAndroid Build Coastguard Worker reader_ = new Reader(&source_, &report_, true /*checksum*/, initial_offset);
123*9507f98cSAndroid Build Coastguard Worker }
124*9507f98cSAndroid Build Coastguard Worker
CheckOffsetPastEndReturnsNoRecords(uint64_t offset_past_end)125*9507f98cSAndroid Build Coastguard Worker void CheckOffsetPastEndReturnsNoRecords(uint64_t offset_past_end) {
126*9507f98cSAndroid Build Coastguard Worker WriteInitialOffsetLog();
127*9507f98cSAndroid Build Coastguard Worker reading_ = true;
128*9507f98cSAndroid Build Coastguard Worker source_.contents_ = Slice(dest_.contents_);
129*9507f98cSAndroid Build Coastguard Worker Reader* offset_reader = new Reader(&source_, &report_, true /*checksum*/,
130*9507f98cSAndroid Build Coastguard Worker WrittenBytes() + offset_past_end);
131*9507f98cSAndroid Build Coastguard Worker Slice record;
132*9507f98cSAndroid Build Coastguard Worker std::string scratch;
133*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(!offset_reader->ReadRecord(&record, &scratch));
134*9507f98cSAndroid Build Coastguard Worker delete offset_reader;
135*9507f98cSAndroid Build Coastguard Worker }
136*9507f98cSAndroid Build Coastguard Worker
CheckInitialOffsetRecord(uint64_t initial_offset,int expected_record_offset)137*9507f98cSAndroid Build Coastguard Worker void CheckInitialOffsetRecord(uint64_t initial_offset,
138*9507f98cSAndroid Build Coastguard Worker int expected_record_offset) {
139*9507f98cSAndroid Build Coastguard Worker WriteInitialOffsetLog();
140*9507f98cSAndroid Build Coastguard Worker reading_ = true;
141*9507f98cSAndroid Build Coastguard Worker source_.contents_ = Slice(dest_.contents_);
142*9507f98cSAndroid Build Coastguard Worker Reader* offset_reader =
143*9507f98cSAndroid Build Coastguard Worker new Reader(&source_, &report_, true /*checksum*/, initial_offset);
144*9507f98cSAndroid Build Coastguard Worker
145*9507f98cSAndroid Build Coastguard Worker // Read all records from expected_record_offset through the last one.
146*9507f98cSAndroid Build Coastguard Worker ASSERT_LT(expected_record_offset, num_initial_offset_records_);
147*9507f98cSAndroid Build Coastguard Worker for (; expected_record_offset < num_initial_offset_records_;
148*9507f98cSAndroid Build Coastguard Worker ++expected_record_offset) {
149*9507f98cSAndroid Build Coastguard Worker Slice record;
150*9507f98cSAndroid Build Coastguard Worker std::string scratch;
151*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(offset_reader->ReadRecord(&record, &scratch));
152*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(initial_offset_record_sizes_[expected_record_offset],
153*9507f98cSAndroid Build Coastguard Worker record.size());
154*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(initial_offset_last_record_offsets_[expected_record_offset],
155*9507f98cSAndroid Build Coastguard Worker offset_reader->LastRecordOffset());
156*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ((char)('a' + expected_record_offset), record.data()[0]);
157*9507f98cSAndroid Build Coastguard Worker }
158*9507f98cSAndroid Build Coastguard Worker delete offset_reader;
159*9507f98cSAndroid Build Coastguard Worker }
160*9507f98cSAndroid Build Coastguard Worker
161*9507f98cSAndroid Build Coastguard Worker private:
162*9507f98cSAndroid Build Coastguard Worker class StringDest : public WritableFile {
163*9507f98cSAndroid Build Coastguard Worker public:
Close()164*9507f98cSAndroid Build Coastguard Worker Status Close() override { return Status::OK(); }
Flush()165*9507f98cSAndroid Build Coastguard Worker Status Flush() override { return Status::OK(); }
Sync()166*9507f98cSAndroid Build Coastguard Worker Status Sync() override { return Status::OK(); }
Append(const Slice & slice)167*9507f98cSAndroid Build Coastguard Worker Status Append(const Slice& slice) override {
168*9507f98cSAndroid Build Coastguard Worker contents_.append(slice.data(), slice.size());
169*9507f98cSAndroid Build Coastguard Worker return Status::OK();
170*9507f98cSAndroid Build Coastguard Worker }
171*9507f98cSAndroid Build Coastguard Worker
172*9507f98cSAndroid Build Coastguard Worker std::string contents_;
173*9507f98cSAndroid Build Coastguard Worker };
174*9507f98cSAndroid Build Coastguard Worker
175*9507f98cSAndroid Build Coastguard Worker class StringSource : public SequentialFile {
176*9507f98cSAndroid Build Coastguard Worker public:
StringSource()177*9507f98cSAndroid Build Coastguard Worker StringSource() : force_error_(false), returned_partial_(false) {}
178*9507f98cSAndroid Build Coastguard Worker
Read(size_t n,Slice * result,char * scratch)179*9507f98cSAndroid Build Coastguard Worker Status Read(size_t n, Slice* result, char* scratch) override {
180*9507f98cSAndroid Build Coastguard Worker EXPECT_TRUE(!returned_partial_) << "must not Read() after eof/error";
181*9507f98cSAndroid Build Coastguard Worker
182*9507f98cSAndroid Build Coastguard Worker if (force_error_) {
183*9507f98cSAndroid Build Coastguard Worker force_error_ = false;
184*9507f98cSAndroid Build Coastguard Worker returned_partial_ = true;
185*9507f98cSAndroid Build Coastguard Worker return Status::Corruption("read error");
186*9507f98cSAndroid Build Coastguard Worker }
187*9507f98cSAndroid Build Coastguard Worker
188*9507f98cSAndroid Build Coastguard Worker if (contents_.size() < n) {
189*9507f98cSAndroid Build Coastguard Worker n = contents_.size();
190*9507f98cSAndroid Build Coastguard Worker returned_partial_ = true;
191*9507f98cSAndroid Build Coastguard Worker }
192*9507f98cSAndroid Build Coastguard Worker *result = Slice(contents_.data(), n);
193*9507f98cSAndroid Build Coastguard Worker contents_.remove_prefix(n);
194*9507f98cSAndroid Build Coastguard Worker return Status::OK();
195*9507f98cSAndroid Build Coastguard Worker }
196*9507f98cSAndroid Build Coastguard Worker
Skip(uint64_t n)197*9507f98cSAndroid Build Coastguard Worker Status Skip(uint64_t n) override {
198*9507f98cSAndroid Build Coastguard Worker if (n > contents_.size()) {
199*9507f98cSAndroid Build Coastguard Worker contents_.clear();
200*9507f98cSAndroid Build Coastguard Worker return Status::NotFound("in-memory file skipped past end");
201*9507f98cSAndroid Build Coastguard Worker }
202*9507f98cSAndroid Build Coastguard Worker
203*9507f98cSAndroid Build Coastguard Worker contents_.remove_prefix(n);
204*9507f98cSAndroid Build Coastguard Worker
205*9507f98cSAndroid Build Coastguard Worker return Status::OK();
206*9507f98cSAndroid Build Coastguard Worker }
207*9507f98cSAndroid Build Coastguard Worker
208*9507f98cSAndroid Build Coastguard Worker Slice contents_;
209*9507f98cSAndroid Build Coastguard Worker bool force_error_;
210*9507f98cSAndroid Build Coastguard Worker bool returned_partial_;
211*9507f98cSAndroid Build Coastguard Worker };
212*9507f98cSAndroid Build Coastguard Worker
213*9507f98cSAndroid Build Coastguard Worker class ReportCollector : public Reader::Reporter {
214*9507f98cSAndroid Build Coastguard Worker public:
ReportCollector()215*9507f98cSAndroid Build Coastguard Worker ReportCollector() : dropped_bytes_(0) {}
Corruption(size_t bytes,const Status & status)216*9507f98cSAndroid Build Coastguard Worker void Corruption(size_t bytes, const Status& status) override {
217*9507f98cSAndroid Build Coastguard Worker dropped_bytes_ += bytes;
218*9507f98cSAndroid Build Coastguard Worker message_.append(status.ToString());
219*9507f98cSAndroid Build Coastguard Worker }
220*9507f98cSAndroid Build Coastguard Worker
221*9507f98cSAndroid Build Coastguard Worker size_t dropped_bytes_;
222*9507f98cSAndroid Build Coastguard Worker std::string message_;
223*9507f98cSAndroid Build Coastguard Worker };
224*9507f98cSAndroid Build Coastguard Worker
225*9507f98cSAndroid Build Coastguard Worker // Record metadata for testing initial offset functionality
226*9507f98cSAndroid Build Coastguard Worker static size_t initial_offset_record_sizes_[];
227*9507f98cSAndroid Build Coastguard Worker static uint64_t initial_offset_last_record_offsets_[];
228*9507f98cSAndroid Build Coastguard Worker static int num_initial_offset_records_;
229*9507f98cSAndroid Build Coastguard Worker
230*9507f98cSAndroid Build Coastguard Worker StringDest dest_;
231*9507f98cSAndroid Build Coastguard Worker StringSource source_;
232*9507f98cSAndroid Build Coastguard Worker ReportCollector report_;
233*9507f98cSAndroid Build Coastguard Worker bool reading_;
234*9507f98cSAndroid Build Coastguard Worker Writer* writer_;
235*9507f98cSAndroid Build Coastguard Worker Reader* reader_;
236*9507f98cSAndroid Build Coastguard Worker };
237*9507f98cSAndroid Build Coastguard Worker
238*9507f98cSAndroid Build Coastguard Worker size_t LogTest::initial_offset_record_sizes_[] = {
239*9507f98cSAndroid Build Coastguard Worker 10000, // Two sizable records in first block
240*9507f98cSAndroid Build Coastguard Worker 10000,
241*9507f98cSAndroid Build Coastguard Worker 2 * log::kBlockSize - 1000, // Span three blocks
242*9507f98cSAndroid Build Coastguard Worker 1,
243*9507f98cSAndroid Build Coastguard Worker 13716, // Consume all but two bytes of block 3.
244*9507f98cSAndroid Build Coastguard Worker log::kBlockSize - kHeaderSize, // Consume the entirety of block 4.
245*9507f98cSAndroid Build Coastguard Worker };
246*9507f98cSAndroid Build Coastguard Worker
247*9507f98cSAndroid Build Coastguard Worker uint64_t LogTest::initial_offset_last_record_offsets_[] = {
248*9507f98cSAndroid Build Coastguard Worker 0,
249*9507f98cSAndroid Build Coastguard Worker kHeaderSize + 10000,
250*9507f98cSAndroid Build Coastguard Worker 2 * (kHeaderSize + 10000),
251*9507f98cSAndroid Build Coastguard Worker 2 * (kHeaderSize + 10000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
252*9507f98cSAndroid Build Coastguard Worker 2 * (kHeaderSize + 10000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize +
253*9507f98cSAndroid Build Coastguard Worker kHeaderSize + 1,
254*9507f98cSAndroid Build Coastguard Worker 3 * log::kBlockSize,
255*9507f98cSAndroid Build Coastguard Worker };
256*9507f98cSAndroid Build Coastguard Worker
257*9507f98cSAndroid Build Coastguard Worker // LogTest::initial_offset_last_record_offsets_ must be defined before this.
258*9507f98cSAndroid Build Coastguard Worker int LogTest::num_initial_offset_records_ =
259*9507f98cSAndroid Build Coastguard Worker sizeof(LogTest::initial_offset_last_record_offsets_) / sizeof(uint64_t);
260*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,Empty)261*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, Empty) { ASSERT_EQ("EOF", Read()); }
262*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadWrite)263*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadWrite) {
264*9507f98cSAndroid Build Coastguard Worker Write("foo");
265*9507f98cSAndroid Build Coastguard Worker Write("bar");
266*9507f98cSAndroid Build Coastguard Worker Write("");
267*9507f98cSAndroid Build Coastguard Worker Write("xxxx");
268*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("foo", Read());
269*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("bar", Read());
270*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", Read());
271*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("xxxx", Read());
272*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
273*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read()); // Make sure reads at eof work
274*9507f98cSAndroid Build Coastguard Worker }
275*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ManyBlocks)276*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ManyBlocks) {
277*9507f98cSAndroid Build Coastguard Worker for (int i = 0; i < 100000; i++) {
278*9507f98cSAndroid Build Coastguard Worker Write(NumberString(i));
279*9507f98cSAndroid Build Coastguard Worker }
280*9507f98cSAndroid Build Coastguard Worker for (int i = 0; i < 100000; i++) {
281*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(NumberString(i), Read());
282*9507f98cSAndroid Build Coastguard Worker }
283*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
284*9507f98cSAndroid Build Coastguard Worker }
285*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,Fragmentation)286*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, Fragmentation) {
287*9507f98cSAndroid Build Coastguard Worker Write("small");
288*9507f98cSAndroid Build Coastguard Worker Write(BigString("medium", 50000));
289*9507f98cSAndroid Build Coastguard Worker Write(BigString("large", 100000));
290*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("small", Read());
291*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("medium", 50000), Read());
292*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("large", 100000), Read());
293*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
294*9507f98cSAndroid Build Coastguard Worker }
295*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,MarginalTrailer)296*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, MarginalTrailer) {
297*9507f98cSAndroid Build Coastguard Worker // Make a trailer that is exactly the same length as an empty record.
298*9507f98cSAndroid Build Coastguard Worker const int n = kBlockSize - 2 * kHeaderSize;
299*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", n));
300*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());
301*9507f98cSAndroid Build Coastguard Worker Write("");
302*9507f98cSAndroid Build Coastguard Worker Write("bar");
303*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("foo", n), Read());
304*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", Read());
305*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("bar", Read());
306*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
307*9507f98cSAndroid Build Coastguard Worker }
308*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,MarginalTrailer2)309*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, MarginalTrailer2) {
310*9507f98cSAndroid Build Coastguard Worker // Make a trailer that is exactly the same length as an empty record.
311*9507f98cSAndroid Build Coastguard Worker const int n = kBlockSize - 2 * kHeaderSize;
312*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", n));
313*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());
314*9507f98cSAndroid Build Coastguard Worker Write("bar");
315*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("foo", n), Read());
316*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("bar", Read());
317*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
318*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
319*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
320*9507f98cSAndroid Build Coastguard Worker }
321*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ShortTrailer)322*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ShortTrailer) {
323*9507f98cSAndroid Build Coastguard Worker const int n = kBlockSize - 2 * kHeaderSize + 4;
324*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", n));
325*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
326*9507f98cSAndroid Build Coastguard Worker Write("");
327*9507f98cSAndroid Build Coastguard Worker Write("bar");
328*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("foo", n), Read());
329*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", Read());
330*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("bar", Read());
331*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
332*9507f98cSAndroid Build Coastguard Worker }
333*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,AlignedEof)334*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, AlignedEof) {
335*9507f98cSAndroid Build Coastguard Worker const int n = kBlockSize - 2 * kHeaderSize + 4;
336*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", n));
337*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
338*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("foo", n), Read());
339*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
340*9507f98cSAndroid Build Coastguard Worker }
341*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,OpenForAppend)342*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, OpenForAppend) {
343*9507f98cSAndroid Build Coastguard Worker Write("hello");
344*9507f98cSAndroid Build Coastguard Worker ReopenForAppend();
345*9507f98cSAndroid Build Coastguard Worker Write("world");
346*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("hello", Read());
347*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("world", Read());
348*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
349*9507f98cSAndroid Build Coastguard Worker }
350*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,RandomRead)351*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, RandomRead) {
352*9507f98cSAndroid Build Coastguard Worker const int N = 500;
353*9507f98cSAndroid Build Coastguard Worker Random write_rnd(301);
354*9507f98cSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
355*9507f98cSAndroid Build Coastguard Worker Write(RandomSkewedString(i, &write_rnd));
356*9507f98cSAndroid Build Coastguard Worker }
357*9507f98cSAndroid Build Coastguard Worker Random read_rnd(301);
358*9507f98cSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
359*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(RandomSkewedString(i, &read_rnd), Read());
360*9507f98cSAndroid Build Coastguard Worker }
361*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
362*9507f98cSAndroid Build Coastguard Worker }
363*9507f98cSAndroid Build Coastguard Worker
364*9507f98cSAndroid Build Coastguard Worker // Tests of all the error paths in log_reader.cc follow:
365*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadError)366*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadError) {
367*9507f98cSAndroid Build Coastguard Worker Write("foo");
368*9507f98cSAndroid Build Coastguard Worker ForceError();
369*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
370*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize, DroppedBytes());
371*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("read error"));
372*9507f98cSAndroid Build Coastguard Worker }
373*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,BadRecordType)374*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, BadRecordType) {
375*9507f98cSAndroid Build Coastguard Worker Write("foo");
376*9507f98cSAndroid Build Coastguard Worker // Type is stored in header[6]
377*9507f98cSAndroid Build Coastguard Worker IncrementByte(6, 100);
378*9507f98cSAndroid Build Coastguard Worker FixChecksum(0, 3);
379*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
380*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(3, DroppedBytes());
381*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("unknown record type"));
382*9507f98cSAndroid Build Coastguard Worker }
383*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,TruncatedTrailingRecordIsIgnored)384*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, TruncatedTrailingRecordIsIgnored) {
385*9507f98cSAndroid Build Coastguard Worker Write("foo");
386*9507f98cSAndroid Build Coastguard Worker ShrinkSize(4); // Drop all payload as well as a header byte
387*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
388*9507f98cSAndroid Build Coastguard Worker // Truncated last record is ignored, not treated as an error.
389*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
390*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
391*9507f98cSAndroid Build Coastguard Worker }
392*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,BadLength)393*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, BadLength) {
394*9507f98cSAndroid Build Coastguard Worker const int kPayloadSize = kBlockSize - kHeaderSize;
395*9507f98cSAndroid Build Coastguard Worker Write(BigString("bar", kPayloadSize));
396*9507f98cSAndroid Build Coastguard Worker Write("foo");
397*9507f98cSAndroid Build Coastguard Worker // Least significant size byte is stored in header[4].
398*9507f98cSAndroid Build Coastguard Worker IncrementByte(4, 1);
399*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("foo", Read());
400*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(kBlockSize, DroppedBytes());
401*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("bad record length"));
402*9507f98cSAndroid Build Coastguard Worker }
403*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,BadLengthAtEndIsIgnored)404*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, BadLengthAtEndIsIgnored) {
405*9507f98cSAndroid Build Coastguard Worker Write("foo");
406*9507f98cSAndroid Build Coastguard Worker ShrinkSize(1);
407*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
408*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
409*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
410*9507f98cSAndroid Build Coastguard Worker }
411*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ChecksumMismatch)412*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ChecksumMismatch) {
413*9507f98cSAndroid Build Coastguard Worker Write("foo");
414*9507f98cSAndroid Build Coastguard Worker IncrementByte(0, 10);
415*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
416*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(10, DroppedBytes());
417*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("checksum mismatch"));
418*9507f98cSAndroid Build Coastguard Worker }
419*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,UnexpectedMiddleType)420*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, UnexpectedMiddleType) {
421*9507f98cSAndroid Build Coastguard Worker Write("foo");
422*9507f98cSAndroid Build Coastguard Worker SetByte(6, kMiddleType);
423*9507f98cSAndroid Build Coastguard Worker FixChecksum(0, 3);
424*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
425*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(3, DroppedBytes());
426*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("missing start"));
427*9507f98cSAndroid Build Coastguard Worker }
428*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,UnexpectedLastType)429*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, UnexpectedLastType) {
430*9507f98cSAndroid Build Coastguard Worker Write("foo");
431*9507f98cSAndroid Build Coastguard Worker SetByte(6, kLastType);
432*9507f98cSAndroid Build Coastguard Worker FixChecksum(0, 3);
433*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
434*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(3, DroppedBytes());
435*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("missing start"));
436*9507f98cSAndroid Build Coastguard Worker }
437*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,UnexpectedFullType)438*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, UnexpectedFullType) {
439*9507f98cSAndroid Build Coastguard Worker Write("foo");
440*9507f98cSAndroid Build Coastguard Worker Write("bar");
441*9507f98cSAndroid Build Coastguard Worker SetByte(6, kFirstType);
442*9507f98cSAndroid Build Coastguard Worker FixChecksum(0, 3);
443*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("bar", Read());
444*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
445*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(3, DroppedBytes());
446*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("partial record without end"));
447*9507f98cSAndroid Build Coastguard Worker }
448*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,UnexpectedFirstType)449*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, UnexpectedFirstType) {
450*9507f98cSAndroid Build Coastguard Worker Write("foo");
451*9507f98cSAndroid Build Coastguard Worker Write(BigString("bar", 100000));
452*9507f98cSAndroid Build Coastguard Worker SetByte(6, kFirstType);
453*9507f98cSAndroid Build Coastguard Worker FixChecksum(0, 3);
454*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(BigString("bar", 100000), Read());
455*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
456*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(3, DroppedBytes());
457*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("OK", MatchError("partial record without end"));
458*9507f98cSAndroid Build Coastguard Worker }
459*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,MissingLastIsIgnored)460*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, MissingLastIsIgnored) {
461*9507f98cSAndroid Build Coastguard Worker Write(BigString("bar", kBlockSize));
462*9507f98cSAndroid Build Coastguard Worker // Remove the LAST block, including header.
463*9507f98cSAndroid Build Coastguard Worker ShrinkSize(14);
464*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
465*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
466*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
467*9507f98cSAndroid Build Coastguard Worker }
468*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,PartialLastIsIgnored)469*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, PartialLastIsIgnored) {
470*9507f98cSAndroid Build Coastguard Worker Write(BigString("bar", kBlockSize));
471*9507f98cSAndroid Build Coastguard Worker // Cause a bad record length in the LAST block.
472*9507f98cSAndroid Build Coastguard Worker ShrinkSize(1);
473*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
474*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
475*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
476*9507f98cSAndroid Build Coastguard Worker }
477*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,SkipIntoMultiRecord)478*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, SkipIntoMultiRecord) {
479*9507f98cSAndroid Build Coastguard Worker // Consider a fragmented record:
480*9507f98cSAndroid Build Coastguard Worker // first(R1), middle(R1), last(R1), first(R2)
481*9507f98cSAndroid Build Coastguard Worker // If initial_offset points to a record after first(R1) but before first(R2)
482*9507f98cSAndroid Build Coastguard Worker // incomplete fragment errors are not actual errors, and must be suppressed
483*9507f98cSAndroid Build Coastguard Worker // until a new first or full record is encountered.
484*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", 3 * kBlockSize));
485*9507f98cSAndroid Build Coastguard Worker Write("correct");
486*9507f98cSAndroid Build Coastguard Worker StartReadingAt(kBlockSize);
487*9507f98cSAndroid Build Coastguard Worker
488*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("correct", Read());
489*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("", ReportMessage());
490*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(0, DroppedBytes());
491*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
492*9507f98cSAndroid Build Coastguard Worker }
493*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ErrorJoinsRecords)494*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ErrorJoinsRecords) {
495*9507f98cSAndroid Build Coastguard Worker // Consider two fragmented records:
496*9507f98cSAndroid Build Coastguard Worker // first(R1) last(R1) first(R2) last(R2)
497*9507f98cSAndroid Build Coastguard Worker // where the middle two fragments disappear. We do not want
498*9507f98cSAndroid Build Coastguard Worker // first(R1),last(R2) to get joined and returned as a valid record.
499*9507f98cSAndroid Build Coastguard Worker
500*9507f98cSAndroid Build Coastguard Worker // Write records that span two blocks
501*9507f98cSAndroid Build Coastguard Worker Write(BigString("foo", kBlockSize));
502*9507f98cSAndroid Build Coastguard Worker Write(BigString("bar", kBlockSize));
503*9507f98cSAndroid Build Coastguard Worker Write("correct");
504*9507f98cSAndroid Build Coastguard Worker
505*9507f98cSAndroid Build Coastguard Worker // Wipe the middle block
506*9507f98cSAndroid Build Coastguard Worker for (int offset = kBlockSize; offset < 2 * kBlockSize; offset++) {
507*9507f98cSAndroid Build Coastguard Worker SetByte(offset, 'x');
508*9507f98cSAndroid Build Coastguard Worker }
509*9507f98cSAndroid Build Coastguard Worker
510*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("correct", Read());
511*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("EOF", Read());
512*9507f98cSAndroid Build Coastguard Worker const size_t dropped = DroppedBytes();
513*9507f98cSAndroid Build Coastguard Worker ASSERT_LE(dropped, 2 * kBlockSize + 100);
514*9507f98cSAndroid Build Coastguard Worker ASSERT_GE(dropped, 2 * kBlockSize);
515*9507f98cSAndroid Build Coastguard Worker }
516*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadStart)517*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadStart) { CheckInitialOffsetRecord(0, 0); }
518*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadSecondOneOff)519*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadSecondOneOff) { CheckInitialOffsetRecord(1, 1); }
520*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadSecondTenThousand)521*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadSecondTenThousand) { CheckInitialOffsetRecord(10000, 1); }
522*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadSecondStart)523*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadSecondStart) { CheckInitialOffsetRecord(10007, 1); }
524*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadThirdOneOff)525*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadThirdOneOff) { CheckInitialOffsetRecord(10008, 2); }
526*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadThirdStart)527*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadThirdStart) { CheckInitialOffsetRecord(20014, 2); }
528*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadFourthOneOff)529*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadFourthOneOff) { CheckInitialOffsetRecord(20015, 3); }
530*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadFourthFirstBlockTrailer)531*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadFourthFirstBlockTrailer) {
532*9507f98cSAndroid Build Coastguard Worker CheckInitialOffsetRecord(log::kBlockSize - 4, 3);
533*9507f98cSAndroid Build Coastguard Worker }
534*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadFourthMiddleBlock)535*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadFourthMiddleBlock) {
536*9507f98cSAndroid Build Coastguard Worker CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
537*9507f98cSAndroid Build Coastguard Worker }
538*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadFourthLastBlock)539*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadFourthLastBlock) {
540*9507f98cSAndroid Build Coastguard Worker CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
541*9507f98cSAndroid Build Coastguard Worker }
542*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadFourthStart)543*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadFourthStart) {
544*9507f98cSAndroid Build Coastguard Worker CheckInitialOffsetRecord(
545*9507f98cSAndroid Build Coastguard Worker 2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
546*9507f98cSAndroid Build Coastguard Worker 3);
547*9507f98cSAndroid Build Coastguard Worker }
548*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadInitialOffsetIntoBlockPadding)549*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadInitialOffsetIntoBlockPadding) {
550*9507f98cSAndroid Build Coastguard Worker CheckInitialOffsetRecord(3 * log::kBlockSize - 3, 5);
551*9507f98cSAndroid Build Coastguard Worker }
552*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadEnd)553*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadEnd) { CheckOffsetPastEndReturnsNoRecords(0); }
554*9507f98cSAndroid Build Coastguard Worker
TEST_F(LogTest,ReadPastEnd)555*9507f98cSAndroid Build Coastguard Worker TEST_F(LogTest, ReadPastEnd) { CheckOffsetPastEndReturnsNoRecords(5); }
556*9507f98cSAndroid Build Coastguard Worker
557*9507f98cSAndroid Build Coastguard Worker } // namespace log
558*9507f98cSAndroid Build Coastguard Worker } // namespace leveldb
559*9507f98cSAndroid Build Coastguard Worker
main(int argc,char ** argv)560*9507f98cSAndroid Build Coastguard Worker int main(int argc, char** argv) {
561*9507f98cSAndroid Build Coastguard Worker testing::InitGoogleTest(&argc, argv);
562*9507f98cSAndroid Build Coastguard Worker return RUN_ALL_TESTS();
563*9507f98cSAndroid Build Coastguard Worker }
564