Add unit test with bad write

If a partial write is made at the beginning,  the file was not being truncated.  Consequently writes would be accepted after it opens, and the those writes would be after the corruption so would never be read in the future.
This commit is contained in:
Martin Sumner 2018-09-27 15:26:45 +01:00
parent b15fef8cf6
commit 88e4cf2361

View file

@ -1266,6 +1266,8 @@ scan_over_file(Handle, Position, FilterFun, Output, LastKey) ->
case saferead_keyvalue(Handle) of case saferead_keyvalue(Handle) of
false -> false ->
leveled_log:log("CDB09", [Position]), leveled_log:log("CDB09", [Position]),
% Bring file back to that position
{ok, Position} = file:position(Handle, {bof, Position}),
{eof, Output}; {eof, Output};
{Key, ValueAsBin, KeyLength, ValueLength} -> {Key, ValueAsBin, KeyLength, ValueLength} ->
NewPosition = case Key of NewPosition = case Key of
@ -1315,7 +1317,7 @@ saferead_keyvalue(Handle) ->
case read_next_2_integers(Handle) of case read_next_2_integers(Handle) of
eof -> eof ->
false; false;
{KeyL, ValueL} -> {KeyL, ValueL} when is_integer(KeyL), is_integer(ValueL) ->
case safe_read_next_keybin(Handle, KeyL) of case safe_read_next_keybin(Handle, KeyL) of
false -> false ->
false; false;
@ -1327,7 +1329,9 @@ saferead_keyvalue(Handle) ->
% i.e. value with no CRC % i.e. value with no CRC
{Key, TrueValue, KeyL, ValueL} {Key, TrueValue, KeyL, ValueL}
end end
end end;
_ ->
false
end. end.
@ -1434,7 +1438,7 @@ extract_valueandsize(ValueAsBin) ->
%% Note that the endian_flip is required to make the file format compatible %% Note that the endian_flip is required to make the file format compatible
%% with CDB %% with CDB
read_next_2_integers(Handle) -> read_next_2_integers(Handle) ->
case file:read(Handle,?DWORD_SIZE) of case file:read(Handle, ?DWORD_SIZE) of
{ok, <<Int1:32,Int2:32>>} -> {ok, <<Int1:32,Int2:32>>} ->
{endian_flip(Int1), endian_flip(Int2)}; {endian_flip(Int1), endian_flip(Int2)};
ReadError -> ReadError ->
@ -2565,6 +2569,20 @@ get_positions_corruption_test() ->
ok = cdb_close(P3), ok = cdb_close(P3),
file:delete(F2). file:delete(F2).
badly_written_test() ->
F1 = "../test/badfirstwrite_test.pnd",
file:delete(F1),
{ok, Handle} = file:open(F1, ?WRITE_OPS),
ok = file:pwrite(Handle, 256 * ?DWORD_SIZE, <<1:8/integer>>),
ok = file:close(Handle),
{ok, P1} = cdb_open_writer(F1, #cdb_options{binary_mode=false}),
ok = cdb_put(P1, "Key100", "Value100"),
?assertMatch({"Key100", "Value100"}, cdb_get(P1, "Key100")),
ok = cdb_close(P1),
{ok, P2} = cdb_open_writer(F1, #cdb_options{binary_mode=false}),
?assertMatch({"Key100", "Value100"}, cdb_get(P2, "Key100")),
ok = cdb_close(P2),
file:delete(F1).
nonsense_coverage_test() -> nonsense_coverage_test() ->