summaryrefslogtreecommitdiff
path: root/test/etap/011-file-headers.t
diff options
context:
space:
mode:
Diffstat (limited to 'test/etap/011-file-headers.t')
-rwxr-xr-xtest/etap/011-file-headers.t145
1 files changed, 0 insertions, 145 deletions
diff --git a/test/etap/011-file-headers.t b/test/etap/011-file-headers.t
deleted file mode 100755
index 4705f629..00000000
--- a/test/etap/011-file-headers.t
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./src/couchdb -sasl errlog_type error -boot start_sasl -noshell
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-filename() -> test_util:build_file("test/etap/temp.011").
-sizeblock() -> 4096. % Need to keep this in sync with couch_file.erl
-
-main(_) ->
- test_util:init_code_path(),
- {S1, S2, S3} = now(),
- random:seed(S1, S2, S3),
-
- etap:plan(17),
- case (catch test()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
- etap:bail()
- end,
- ok.
-
-test() ->
- {ok, Fd} = couch_file:open(filename(), [create,overwrite]),
-
- etap:is({ok, 0}, couch_file:bytes(Fd),
- "File should be initialized to contain zero bytes."),
-
- etap:is(ok, couch_file:write_header(Fd, {<<"some_data">>, 32}),
- "Writing a header succeeds."),
-
- {ok, Size1} = couch_file:bytes(Fd),
- etap:is_greater(Size1, 0,
- "Writing a header allocates space in the file."),
-
- etap:is({ok, {<<"some_data">>, 32}}, couch_file:read_header(Fd),
- "Reading the header returns what we wrote."),
-
- etap:is(ok, couch_file:write_header(Fd, [foo, <<"more">>]),
- "Writing a second header succeeds."),
-
- {ok, Size2} = couch_file:bytes(Fd),
- etap:is_greater(Size2, Size1,
- "Writing a second header allocates more space."),
-
- etap:is({ok, [foo, <<"more">>]}, couch_file:read_header(Fd),
- "Reading the second header does not return the first header."),
-
- % Delete the second header.
- ok = couch_file:truncate(Fd, Size1),
-
- etap:is({ok, {<<"some_data">>, 32}}, couch_file:read_header(Fd),
- "Reading the header after a truncation returns a previous header."),
-
- couch_file:write_header(Fd, [foo, <<"more">>]),
- etap:is({ok, Size2}, couch_file:bytes(Fd),
- "Rewriting the same second header returns the same second size."),
-
- ok = couch_file:close(Fd),
-
- % Now for the fun stuff. Try corrupting the second header and see
- % if we recover properly.
-
- % Destroy the 0x1 byte that marks a header
- check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) ->
- etap:isnt(Expect, couch_file:read_header(CouchFd),
- "Should return a different header before corruption."),
- file:pwrite(RawFd, HeaderPos, <<0>>),
- etap:is(Expect, couch_file:read_header(CouchFd),
- "Corrupting the byte marker should read the previous header.")
- end),
-
- % Corrupt the size.
- check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) ->
- etap:isnt(Expect, couch_file:read_header(CouchFd),
- "Should return a different header before corruption."),
- % +1 for 0x1 byte marker
- file:pwrite(RawFd, HeaderPos+1, <<10/integer>>),
- etap:is(Expect, couch_file:read_header(CouchFd),
- "Corrupting the size should read the previous header.")
- end),
-
- % Corrupt the MD5 signature
- check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) ->
- etap:isnt(Expect, couch_file:read_header(CouchFd),
- "Should return a different header before corruption."),
- % +5 = +1 for 0x1 byte and +4 for term size.
- file:pwrite(RawFd, HeaderPos+5, <<"F01034F88D320B22">>),
- etap:is(Expect, couch_file:read_header(CouchFd),
- "Corrupting the MD5 signature should read the previous header.")
- end),
-
- % Corrupt the data
- check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) ->
- etap:isnt(Expect, couch_file:read_header(CouchFd),
- "Should return a different header before corruption."),
- % +21 = +1 for 0x1 byte, +4 for term size and +16 for MD5 sig
- file:pwrite(RawFd, HeaderPos+21, <<"some data goes here!">>),
- etap:is(Expect, couch_file:read_header(CouchFd),
- "Corrupting the header data should read the previous header.")
- end),
-
- ok.
-
-check_header_recovery(CheckFun) ->
- {ok, Fd} = couch_file:open(filename(), [create,overwrite]),
- {ok, RawFd} = file:open(filename(), [read, write, raw, binary]),
-
- {ok, _} = write_random_data(Fd),
- ExpectHeader = {some_atom, <<"a binary">>, 756},
- ok = couch_file:write_header(Fd, ExpectHeader),
-
- {ok, HeaderPos} = write_random_data(Fd),
- ok = couch_file:write_header(Fd, {2342, <<"corruption! greed!">>}),
-
- CheckFun(Fd, RawFd, {ok, ExpectHeader}, HeaderPos),
-
- ok = file:close(RawFd),
- ok = couch_file:close(Fd),
- ok.
-
-write_random_data(Fd) ->
- write_random_data(Fd, 100 + random:uniform(1000)).
-
-write_random_data(Fd, 0) ->
- {ok, Bytes} = couch_file:bytes(Fd),
- {ok, (1 + Bytes div sizeblock()) * sizeblock()};
-write_random_data(Fd, N) ->
- Choices = [foo, bar, <<"bizzingle">>, "bank", ["rough", stuff]],
- Term = lists:nth(random:uniform(4) + 1, Choices),
- {ok, _} = couch_file:append_term(Fd, Term),
- write_random_data(Fd, N-1).
-