@@ -79,7 +79,7 @@ class LogTest {
7979 virtual Status Skip (uint64_t n) {
8080 if (n > contents_.size ()) {
8181 contents_.clear ();
82- return Status::NotFound (" in-memory file skipepd past end" );
82+ return Status::NotFound (" in-memory file skipped past end" );
8383 }
8484
8585 contents_.remove_prefix (n);
@@ -105,7 +105,7 @@ class LogTest {
105105 ReportCollector report_;
106106 bool reading_;
107107 Writer* writer_;
108- Reader reader_;
108+ Reader* reader_;
109109
110110 // Record metadata for testing initial offset functionality
111111 static size_t initial_offset_record_sizes_[];
@@ -114,12 +114,13 @@ class LogTest {
114114 public:
115115 LogTest () : reading_(false ),
116116 writer_ (new Writer(&dest_)),
117- reader_(&source_, &report_, true /* checksum*/ ,
118- 0 /* initial_offset*/ ) {
117+ reader_(new Reader( &source_, &report_, true /* checksum*/ ,
118+ 0 /* initial_offset*/ )) {
119119 }
120120
121121 ~LogTest () {
122122 delete writer_;
123+ delete reader_;
123124 }
124125
125126 void ReopenForAppend () {
@@ -143,7 +144,7 @@ class LogTest {
143144 }
144145 std::string scratch;
145146 Slice record;
146- if (reader_. ReadRecord (&record, &scratch)) {
147+ if (reader_-> ReadRecord (&record, &scratch)) {
147148 return record.ToString ();
148149 } else {
149150 return " EOF" ;
@@ -198,6 +199,11 @@ class LogTest {
198199 }
199200 }
200201
202+ void StartReadingAt (uint64_t initial_offset) {
203+ delete reader_;
204+ reader_ = new Reader (&source_, &report_, true /* checksum*/ , initial_offset);
205+ }
206+
201207 void CheckOffsetPastEndReturnsNoRecords (uint64_t offset_past_end) {
202208 WriteInitialOffsetLog ();
203209 reading_ = true ;
@@ -227,7 +233,6 @@ class LogTest {
227233 ASSERT_EQ ((char )(' a' + expected_record_offset), record.data ()[0 ]);
228234 delete offset_reader;
229235 }
230-
231236};
232237
233238size_t LogTest::initial_offset_record_sizes_[] =
@@ -463,6 +468,22 @@ TEST(LogTest, PartialLastIsIgnored) {
463468 ASSERT_EQ (0 , DroppedBytes ());
464469}
465470
471+ TEST (LogTest, SkipIntoMultiRecord) {
472+ // Consider a fragmented record:
473+ // first(R1), middle(R1), last(R1), first(R2)
474+ // If initial_offset points to a record after first(R1) but before first(R2)
475+ // incomplete fragment errors are not actual errors, and must be suppressed
476+ // until a new first or full record is encountered.
477+ Write (BigString (" foo" , 3 *kBlockSize ));
478+ Write (" correct" );
479+ StartReadingAt (kBlockSize );
480+
481+ ASSERT_EQ (" correct" , Read ());
482+ ASSERT_EQ (" " , ReportMessage ());
483+ ASSERT_EQ (0 , DroppedBytes ());
484+ ASSERT_EQ (" EOF" , Read ());
485+ }
486+
466487TEST (LogTest, ErrorJoinsRecords) {
467488 // Consider two fragmented records:
468489 // first(R1) last(R1) first(R2) last(R2)
0 commit comments