@@ -79,7 +79,7 @@ class LogTest {
79
79
virtual Status Skip (uint64_t n) {
80
80
if (n > contents_.size ()) {
81
81
contents_.clear ();
82
- return Status::NotFound (" in-memory file skipepd past end" );
82
+ return Status::NotFound (" in-memory file skipped past end" );
83
83
}
84
84
85
85
contents_.remove_prefix (n);
@@ -105,7 +105,7 @@ class LogTest {
105
105
ReportCollector report_;
106
106
bool reading_;
107
107
Writer* writer_;
108
- Reader reader_;
108
+ Reader* reader_;
109
109
110
110
// Record metadata for testing initial offset functionality
111
111
static size_t initial_offset_record_sizes_[];
@@ -114,12 +114,13 @@ class LogTest {
114
114
public:
115
115
LogTest () : reading_(false ),
116
116
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*/ )) {
119
119
}
120
120
121
121
~LogTest () {
122
122
delete writer_;
123
+ delete reader_;
123
124
}
124
125
125
126
void ReopenForAppend () {
@@ -143,7 +144,7 @@ class LogTest {
143
144
}
144
145
std::string scratch;
145
146
Slice record;
146
- if (reader_. ReadRecord (&record, &scratch)) {
147
+ if (reader_-> ReadRecord (&record, &scratch)) {
147
148
return record.ToString ();
148
149
} else {
149
150
return " EOF" ;
@@ -198,6 +199,11 @@ class LogTest {
198
199
}
199
200
}
200
201
202
+ void StartReadingAt (uint64_t initial_offset) {
203
+ delete reader_;
204
+ reader_ = new Reader (&source_, &report_, true /* checksum*/ , initial_offset);
205
+ }
206
+
201
207
void CheckOffsetPastEndReturnsNoRecords (uint64_t offset_past_end) {
202
208
WriteInitialOffsetLog ();
203
209
reading_ = true ;
@@ -227,7 +233,6 @@ class LogTest {
227
233
ASSERT_EQ ((char )(' a' + expected_record_offset), record.data ()[0 ]);
228
234
delete offset_reader;
229
235
}
230
-
231
236
};
232
237
233
238
size_t LogTest::initial_offset_record_sizes_[] =
@@ -463,6 +468,22 @@ TEST(LogTest, PartialLastIsIgnored) {
463
468
ASSERT_EQ (0 , DroppedBytes ());
464
469
}
465
470
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
+
466
487
TEST (LogTest, ErrorJoinsRecords) {
467
488
// Consider two fragmented records:
468
489
// first(R1) last(R1) first(R2) last(R2)
0 commit comments