1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be
3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors.
4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/log_reader.h"
6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/log_writer.h"
7fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/env.h"
8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/coding.h"
9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/crc32c.h"
10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/random.h"
11179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/testharness.h"
12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb {
14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace log {
15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Construct a string of the specified length made out of the supplied
17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// partial string.
18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string BigString(const std::string& partial_string, size_t n) {
19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  std::string result;
20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  while (result.size() < n) {
21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    result.append(partial_string);
22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  result.resize(n);
24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return result;
25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Construct a string from a number
28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string NumberString(int n) {
29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  char buf[50];
30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  snprintf(buf, sizeof(buf), "%d.", n);
31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return std::string(buf);
32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Return a skewed potentially long string
35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string RandomSkewedString(int i, Random* rnd) {
36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return BigString(NumberString(i), rnd->Skewed(17));
37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass LogTest {
40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private:
41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  class StringDest : public WritableFile {
42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org   public:
43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    std::string contents_;
44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual Status Close() { return Status::OK(); }
46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual Status Flush() { return Status::OK(); }
47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual Status Sync() { return Status::OK(); }
48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual Status Append(const Slice& slice) {
49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      contents_.append(slice.data(), slice.size());
50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return Status::OK();
51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  };
53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  class StringSource : public SequentialFile {
55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org   public:
56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Slice contents_;
57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool force_error_;
58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool returned_partial_;
59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    StringSource() : force_error_(false), returned_partial_(false) { }
60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual Status Read(size_t n, Slice* result, char* scratch) {
62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ASSERT_TRUE(!returned_partial_) << "must not Read() after eof/error";
63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (force_error_) {
65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        force_error_ = false;
66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        returned_partial_ = true;
67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return Status::Corruption("read error");
68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (contents_.size() < n) {
71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        n = contents_.size();
72179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        returned_partial_ = true;
73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      *result = Slice(contents_.data(), n);
75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      contents_.remove_prefix(n);
76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return Status::OK();
77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
78a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
79c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org    virtual Status Skip(uint64_t n) {
80a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      if (n > contents_.size()) {
81a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        contents_.clear();
82a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        return Status::NotFound("in-memory file skipepd past end");
83a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      }
84a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
85a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      contents_.remove_prefix(n);
86a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
87a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      return Status::OK();
88a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    }
89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  };
90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  class ReportCollector : public Reader::Reporter {
92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org   public:
93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    size_t dropped_bytes_;
94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    std::string message_;
95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ReportCollector() : dropped_bytes_(0) { }
97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    virtual void Corruption(size_t bytes, const Status& status) {
98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      dropped_bytes_ += bytes;
99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      message_.append(status.ToString());
100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  };
102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  StringDest dest_;
104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  StringSource source_;
105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ReportCollector report_;
106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  bool reading_;
107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Writer writer_;
108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Reader reader_;
109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
110a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  // Record metadata for testing initial offset functionality
111a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  static size_t initial_offset_record_sizes_[];
112a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  static uint64_t initial_offset_last_record_offsets_[];
113a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
114179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public:
115179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  LogTest() : reading_(false),
116179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org              writer_(&dest_),
117a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org              reader_(&source_, &report_, true/*checksum*/,
118a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                      0/*initial_offset*/) {
119179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
120179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
121179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void Write(const std::string& msg) {
122179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ASSERT_TRUE(!reading_) << "Write() after starting to read";
123179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    writer_.AddRecord(Slice(msg));
124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  size_t WrittenBytes() const {
127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return dest_.contents_.size();
128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
129179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  std::string Read() {
131179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (!reading_) {
132179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      reading_ = true;
133179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      source_.contents_ = Slice(dest_.contents_);
134179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
135179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    std::string scratch;
136179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Slice record;
137179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (reader_.ReadRecord(&record, &scratch)) {
138179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return record.ToString();
139179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    } else {
140179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return "EOF";
141179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
142179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
143179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
144179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void IncrementByte(int offset, int delta) {
145179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    dest_.contents_[offset] += delta;
146179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
147179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
148179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void SetByte(int offset, char new_byte) {
149179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    dest_.contents_[offset] = new_byte;
150179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
151179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
152179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void ShrinkSize(int bytes) {
153179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    dest_.contents_.resize(dest_.contents_.size() - bytes);
154179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
155179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
156179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void FixChecksum(int header_offset, int len) {
157179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Compute crc of type/len/data
158179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    uint32_t crc = crc32c::Value(&dest_.contents_[header_offset+6], 1 + len);
159179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    crc = crc32c::Mask(crc);
160179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    EncodeFixed32(&dest_.contents_[header_offset], crc);
161179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
162179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
163179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void ForceError() {
164179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    source_.force_error_ = true;
165179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
166179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
167179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  size_t DroppedBytes() const {
168179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return report_.dropped_bytes_;
169179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
170179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
171a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  std::string ReportMessage() const {
172a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    return report_.message_;
173a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  }
174a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
175179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Returns OK iff recorded error message contains "msg"
176179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  std::string MatchError(const std::string& msg) const {
177179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (report_.message_.find(msg) == std::string::npos) {
178179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return report_.message_;
179179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    } else {
180179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return "OK";
181179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
182179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
183a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
184a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  void WriteInitialOffsetLog() {
185a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    for (int i = 0; i < 4; i++) {
186a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      std::string record(initial_offset_record_sizes_[i],
187a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                         static_cast<char>('a' + i));
188a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      Write(record);
189a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    }
190a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  }
191a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
192a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  void CheckOffsetPastEndReturnsNoRecords(uint64_t offset_past_end) {
193a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    WriteInitialOffsetLog();
194a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    reading_ = true;
195a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    source_.contents_ = Slice(dest_.contents_);
196a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    Reader* offset_reader = new Reader(&source_, &report_, true/*checksum*/,
197a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                                       WrittenBytes() + offset_past_end);
198a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    Slice record;
199a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    std::string scratch;
200a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    ASSERT_TRUE(!offset_reader->ReadRecord(&record, &scratch));
201a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    delete offset_reader;
202a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  }
203a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
204a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  void CheckInitialOffsetRecord(uint64_t initial_offset,
205a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                                int expected_record_offset) {
206a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    WriteInitialOffsetLog();
207a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    reading_ = true;
208a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    source_.contents_ = Slice(dest_.contents_);
209a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    Reader* offset_reader = new Reader(&source_, &report_, true/*checksum*/,
210a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                                       initial_offset);
211a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    Slice record;
212a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    std::string scratch;
213a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    ASSERT_TRUE(offset_reader->ReadRecord(&record, &scratch));
214a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    ASSERT_EQ(initial_offset_record_sizes_[expected_record_offset],
215a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org              record.size());
216a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    ASSERT_EQ(initial_offset_last_record_offsets_[expected_record_offset],
217a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org              offset_reader->LastRecordOffset());
218a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    ASSERT_EQ((char)('a' + expected_record_offset), record.data()[0]);
219a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    delete offset_reader;
220a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  }
221a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
222179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org};
223179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
224a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgsize_t LogTest::initial_offset_record_sizes_[] =
225a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    {10000,  // Two sizable records in first block
226a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     10000,
227a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     2 * log::kBlockSize - 1000,  // Span three blocks
228a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     1};
229a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
230a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orguint64_t LogTest::initial_offset_last_record_offsets_[] =
231a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    {0,
232a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     kHeaderSize + 10000,
233a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     2 * (kHeaderSize + 10000),
234a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org     2 * (kHeaderSize + 10000) +
235a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org         (2 * log::kBlockSize - 1000) + 3 * kHeaderSize};
236a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
237a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
238179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, Empty) {
239179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
240179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
241179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
242179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ReadWrite) {
243179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
244179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("bar");
245179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("");
246179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("xxxx");
247179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("foo", Read());
248179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("bar", Read());
249179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("", Read());
250179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("xxxx", Read());
251179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
252179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());  // Make sure reads at eof work
253179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
254179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
255179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ManyBlocks) {
256179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (int i = 0; i < 100000; i++) {
257179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Write(NumberString(i));
258179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
259179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (int i = 0; i < 100000; i++) {
260179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ASSERT_EQ(NumberString(i), Read());
261179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
262179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
263179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
264179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
265179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, Fragmentation) {
266179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("small");
267179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("medium", 50000));
268179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("large", 100000));
269179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("small", Read());
270179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("medium", 50000), Read());
271179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("large", 100000), Read());
272179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
273179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
274179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
275179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, MarginalTrailer) {
276179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Make a trailer that is exactly the same length as an empty record.
277179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  const int n = kBlockSize - 2*kHeaderSize;
278179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("foo", n));
279179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());
280179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("");
281179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("bar");
282179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("foo", n), Read());
283179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("", Read());
284179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("bar", Read());
285179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
286179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
287179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
288a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, MarginalTrailer2) {
289a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  // Make a trailer that is exactly the same length as an empty record.
290a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  const int n = kBlockSize - 2*kHeaderSize;
291a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  Write(BigString("foo", n));
292a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes());
293a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  Write("bar");
294a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ(BigString("foo", n), Read());
295a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ("bar", Read());
296a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ("EOF", Read());
297a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ(0, DroppedBytes());
298a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ASSERT_EQ("", ReportMessage());
299a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
300a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
301179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ShortTrailer) {
302179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  const int n = kBlockSize - 2*kHeaderSize + 4;
303179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("foo", n));
304179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
305179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("");
306179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("bar");
307179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("foo", n), Read());
308179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("", Read());
309179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("bar", Read());
310179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
311179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
312179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
313179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, AlignedEof) {
314179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  const int n = kBlockSize - 2*kHeaderSize + 4;
315179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("foo", n));
316179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes());
317179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("foo", n), Read());
318179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
319179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
320179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
321179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, RandomRead) {
322179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  const int N = 500;
323179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Random write_rnd(301);
324179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (int i = 0; i < N; i++) {
325179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Write(RandomSkewedString(i, &write_rnd));
326179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
327179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Random read_rnd(301);
328179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (int i = 0; i < N; i++) {
329179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ASSERT_EQ(RandomSkewedString(i, &read_rnd), Read());
330179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
331179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
332179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
333179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
334179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Tests of all the error paths in log_reader.cc follow:
335179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
336179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ReadError) {
337179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
338179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ForceError();
339179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
340179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kBlockSize, DroppedBytes());
341179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("read error"));
342179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
343179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
344179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, BadRecordType) {
345179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
346179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Type is stored in header[6]
347179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  IncrementByte(6, 100);
348179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FixChecksum(0, 3);
349179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
350179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(3, DroppedBytes());
351179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("unknown record type"));
352179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
353179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
354179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, TruncatedTrailingRecord) {
355179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
356179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ShrinkSize(4);   // Drop all payload as well as a header byte
357179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
358179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kHeaderSize - 1, DroppedBytes());
359179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("truncated record at end of file"));
360179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
361179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
362179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, BadLength) {
363179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
364179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ShrinkSize(1);
365179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
366179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(kHeaderSize + 2, DroppedBytes());
367179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("bad record length"));
368179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
369179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
370179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ChecksumMismatch) {
371179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
372179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  IncrementByte(0, 10);
373179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
37484744ee8e3e568ca5b24eabf31be706d69d80c4djorlow@chromium.org  ASSERT_EQ(10, DroppedBytes());
375179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("checksum mismatch"));
376179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
377179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
378179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, UnexpectedMiddleType) {
379179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
380179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SetByte(6, kMiddleType);
381179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FixChecksum(0, 3);
382179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
383179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(3, DroppedBytes());
384179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("missing start"));
385179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
386179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
387179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, UnexpectedLastType) {
388179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
389179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SetByte(6, kLastType);
390179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FixChecksum(0, 3);
391179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
392179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(3, DroppedBytes());
393179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("missing start"));
394179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
395179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
396179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, UnexpectedFullType) {
397179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
398179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("bar");
399179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SetByte(6, kFirstType);
400179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FixChecksum(0, 3);
401179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("bar", Read());
402179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
403179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(3, DroppedBytes());
404179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("partial record without end"));
405179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
406179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
407179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, UnexpectedFirstType) {
408179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("foo");
409179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("bar", 100000));
410179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SetByte(6, kFirstType);
411179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FixChecksum(0, 3);
412179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(BigString("bar", 100000), Read());
413179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
414179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ(3, DroppedBytes());
415179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("OK", MatchError("partial record without end"));
416179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
417179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
418179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(LogTest, ErrorJoinsRecords) {
419179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Consider two fragmented records:
420179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  //    first(R1) last(R1) first(R2) last(R2)
421179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // where the middle two fragments disappear.  We do not want
422179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // first(R1),last(R2) to get joined and returned as a valid record.
423179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
424179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Write records that span two blocks
425179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("foo", kBlockSize));
426179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write(BigString("bar", kBlockSize));
427179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  Write("correct");
428179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
429179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Wipe the middle block
430179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (int offset = kBlockSize; offset < 2*kBlockSize; offset++) {
431179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    SetByte(offset, 'x');
432179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
433179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
434179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("correct", Read());
435179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_EQ("EOF", Read());
436179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  const int dropped = DroppedBytes();
437179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_LE(dropped, 2*kBlockSize + 100);
438179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ASSERT_GE(dropped, 2*kBlockSize);
439179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
440179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
441a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadStart) {
442a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(0, 0);
443a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
444a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
445a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadSecondOneOff) {
446a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(1, 1);
447a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
448a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
449a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadSecondTenThousand) {
450a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(10000, 1);
451a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
452a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
453a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadSecondStart) {
454a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(10007, 1);
455a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
456a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
457a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadThirdOneOff) {
458a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(10008, 2);
459a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
460a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
461a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadThirdStart) {
462a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(20014, 2);
463a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
464a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
465a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadFourthOneOff) {
466a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(20015, 3);
467a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
468a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
469a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadFourthFirstBlockTrailer) {
470a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(log::kBlockSize - 4, 3);
471a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
472a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
473a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadFourthMiddleBlock) {
474a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(log::kBlockSize + 1, 3);
475a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
476a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
477a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadFourthLastBlock) {
478a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(2 * log::kBlockSize + 1, 3);
479a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
480a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
481a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadFourthStart) {
482a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckInitialOffsetRecord(
483a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      2 * (kHeaderSize + 1000) + (2 * log::kBlockSize - 1000) + 3 * kHeaderSize,
484a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      3);
485a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
486a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
487a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadEnd) {
488a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckOffsetPastEndReturnsNoRecords(0);
489a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
490a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
491a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgTEST(LogTest, ReadPastEnd) {
492a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  CheckOffsetPastEndReturnsNoRecords(5);
493a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org}
494a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
49545b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace log
49645b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace leveldb
497179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
498179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgint main(int argc, char** argv) {
499179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return leveldb::test::RunAllTests();
500179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
501