diff --git a/test/limestone/log/testdata.cpp b/test/limestone/log/testdata.cpp index 9011d90f..5fd24620 100644 --- a/test/limestone/log/testdata.cpp +++ b/test/limestone/log/testdata.cpp @@ -27,6 +27,18 @@ extern constexpr const std::string_view data_normal = // XXX: epoch footer... ""sv; +extern constexpr const std::string_view data_normal2 = + "\x02\xf0\x00\x00\x00\x00\x00\x00\x00" // marker_begin 0xf0 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1234" "vermajor" "verminor" "1234" // normal_entry + // XXX: epoch footer... + "\x02\xf1\x00\x00\x00\x00\x00\x00\x00" // marker_begin 0xf1 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1235" "vermajor" "verminor" "1235" // normal_entry + // XXX: epoch footer... + "\x02\x00\x01\x00\x00\x00\x00\x00\x00" // marker_begin 0x100 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1236" "vermajor" "verminor" "1236" // normal_entry + // XXX: epoch footer... + ""sv; + extern constexpr const std::string_view data_nondurable = "\x02\xff\x00\x00\x00\x00\x00\x00\x00" // marker_begin 0xff // XXX: epoch footer... @@ -34,6 +46,18 @@ extern constexpr const std::string_view data_nondurable = // XXX: epoch footer... ""sv; +extern constexpr const std::string_view data_repaired_nondurable = + "\x02\xf0\x00\x00\x00\x00\x00\x00\x00" // marker_begin 0xf0 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1234" "vermajor" "verminor" "1234" // normal_entry + // XXX: epoch footer... + "\x06\xf1\x00\x00\x00\x00\x00\x00\x00" // marker_invalidated_begin 0xf1 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1235" "vermajor" "verminor" "1235" // normal_entry + // XXX: epoch footer... + "\x02\x00\x01\x00\x00\x00\x00\x00\x00" // marker_begin 0x100 + "\x01\x04\x00\x00\x00\x04\x00\x00\x00" "storage1" "1236" "vermajor" "verminor" "1236" // normal_entry + // XXX: epoch footer... + ""sv; + extern constexpr const std::string_view data_zerofill = "\x02\xff\x00\x00\x00\x00\x00\x00\x00" // marker_begin 0xff // XXX: epoch footer... diff --git a/test/limestone/utils/dblogutil_test.cpp b/test/limestone/utils/dblogutil_test.cpp index a49159c7..f33bde85 100644 --- a/test/limestone/utils/dblogutil_test.cpp +++ b/test/limestone/utils/dblogutil_test.cpp @@ -24,7 +24,9 @@ extern std::string data_manifest(int persistent_format_version = 1); extern const std::string_view epoch_0x100_str; extern const std::string_view data_normal; +extern const std::string_view data_normal2; extern const std::string_view data_nondurable; +extern const std::string_view data_repaired_nondurable; extern const std::string_view data_zerofill; extern const std::string_view data_truncated_normal_entry; extern const std::string_view data_truncated_epoch_header; @@ -181,12 +183,26 @@ TEST_F(dblogutil_test, inspect_normal) { EXPECT_NE(out.find("\n" "status: OK"), out.npos); } +TEST_F(dblogutil_test, inspect_normal2) { + auto [rc, out] = inspect("pwal_0000", data_normal2); + EXPECT_EQ(rc, 0 << 8); + EXPECT_NE(out.find("\n" "status: OK"), out.npos); + EXPECT_NE(out.find("\n" "count-durable-wal-entries: 3"), out.npos); +} + TEST_F(dblogutil_test, inspect_nondurable) { auto [rc, out] = inspect("pwal_0000", data_nondurable); EXPECT_EQ(rc, 1 << 8); EXPECT_NE(out.find("\n" "status: auto-repairable"), out.npos); } +TEST_F(dblogutil_test, inspect_repaired_nondurable) { + auto [rc, out] = inspect("pwal_0000", data_repaired_nondurable); + EXPECT_EQ(rc, 0 << 8); + EXPECT_NE(out.find("\n" "status: OK"), out.npos); + EXPECT_NE(out.find("\n" "count-durable-wal-entries: 2"), out.npos); +} + TEST_F(dblogutil_test, inspect_zerofill) { auto [rc, out] = inspect("pwal_0000", data_zerofill); EXPECT_EQ(rc, 1 << 8); @@ -256,6 +272,15 @@ TEST_F(dblogutil_test, repairm_nondurable_detached) { EXPECT_EQ(data.substr(0, 9), orig_data.substr(0, 9)); // no change before mark } +TEST_F(dblogutil_test, repairm_repaired_nondurable) { + auto orig_data = data_repaired_nondurable; + auto [rc, out] = repairm("pwal_0000", orig_data); + EXPECT_EQ(rc, 0); + EXPECT_NE(out.find("\n" "status: OK"), out.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data, orig_data); // no change before repair +} + TEST_F(dblogutil_test, repairm_zerofill) { auto orig_data = data_zerofill; auto [rc, out, rc2, out2] = repairm_twice("pwal_0000", orig_data); @@ -385,4 +410,61 @@ TEST_F(dblogutil_test, repairc_zerofill) { EXPECT_EQ(data, orig_data.substr(0, 9)); // no change before cut } +TEST_F(dblogutil_test, repairc_truncated_normal_entry) { + auto orig_data = data_truncated_normal_entry; + auto [rc, out, rc2, out2] = repairc_twice("pwal_0000", orig_data); + EXPECT_EQ(rc, 0); + EXPECT_NE(out.find("\n" "status: repaired"), out.npos); + EXPECT_EQ(rc2, 0); + EXPECT_NE(out2.find("\n" "status: OK"), out2.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data.size(), 9); // cut + EXPECT_EQ(data, orig_data.substr(0, 9)); // no change before cut +} + +TEST_F(dblogutil_test, repairc_truncated_epoch_header) { + auto orig_data = data_truncated_epoch_header; + auto [rc, out, rc2, out2] = repairc_twice("pwal_0000", orig_data); + EXPECT_EQ(rc, 0); + EXPECT_NE(out.find("\n" "status: repaired"), out.npos); + EXPECT_EQ(rc2, 0); + EXPECT_NE(out2.find("\n" "status: OK"), out2.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data.size(), 50); // cut + EXPECT_EQ(data, orig_data.substr(0, 50)); // no change before cut +} + +TEST_F(dblogutil_test, repairc_truncated_invalidated_normal_entry) { + auto orig_data = data_truncated_invalidated_normal_entry; + auto [rc, out, rc2, out2] = repairc_twice("pwal_0000", orig_data); + EXPECT_EQ(rc, 0); + EXPECT_NE(out.find("\n" "status: repaired"), out.npos); + EXPECT_EQ(rc2, 0); + EXPECT_NE(out2.find("\n" "status: OK"), out2.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data.size(), 9); // cut + EXPECT_EQ(data, orig_data.substr(0, 9)); // no change before cut +} + +TEST_F(dblogutil_test, repairc_truncated_invalidated_epoch_header) { + auto orig_data = data_truncated_invalidated_epoch_header; + auto [rc, out, rc2, out2] = repairc_twice("pwal_0000", orig_data); + EXPECT_EQ(rc, 0); + EXPECT_NE(out.find("\n" "status: repaired"), out.npos); + EXPECT_EQ(rc2, 0); + EXPECT_NE(out2.find("\n" "status: OK"), out2.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data.size(), 50); // cut + EXPECT_EQ(data, orig_data.substr(0, 50)); // no change before cut +} + +TEST_F(dblogutil_test, repairc_allzero) { + auto orig_data = data_allzero; + auto [rc, out] = repairc("pwal_0000", orig_data); + EXPECT_EQ(rc, 1 << 8); + EXPECT_NE(out.find("\n" "status: unrepairable"), out.npos); + auto data = read_entire_file(list_dir()[0]); + EXPECT_EQ(data, orig_data); // no change before repair +} + } // namespace limestone::testing