blob: 6c99ceb739ebb4fcd1a9dc5de0fbf77ebdba1f3e [file] [log] [blame]
% 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.
-module(couch_bt_engine_compactor_tests).
-include_lib("couch/include/couch_eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
-define(DELAY, 100).
-define(WAIT_DELAY_COUNT, 50).
setup() ->
DbName = ?tempdb(),
{ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
ok = couch_db:close(Db),
create_docs(DbName),
DbName.
teardown(DbName) when is_binary(DbName) ->
couch_server:delete(DbName, [?ADMIN_CTX]),
ok.
compaction_resume_test_() ->
{
setup,
fun test_util:start_couch/0,
fun test_util:stop_couch/1,
{
foreach,
fun setup/0,
fun teardown/1,
[
fun compaction_resume/1
]
}
}.
compaction_resume(DbName) ->
?_test(begin
check_db_validity(DbName),
compact_db(DbName),
check_db_validity(DbName),
% Force an error when copying document ids
with_mecked_emsort(fun() ->
compact_db(DbName)
end),
check_db_validity(DbName),
compact_db(DbName),
check_db_validity(DbName)
end).
check_db_validity(DbName) ->
couch_util:with_db(DbName, fun(Db) ->
?assertEqual({ok, 3}, couch_db:get_doc_count(Db)),
?assertEqual(3, couch_db:count_changes_since(Db, 0))
end).
with_mecked_emsort(Fun) ->
meck:new(couch_emsort, [passthrough]),
meck:expect(couch_emsort, iter, fun(_) -> erlang:error(kaboom) end),
try
Fun()
after
meck:unload()
end.
create_docs(DbName) ->
couch_util:with_db(DbName, fun(Db) ->
Doc1 = couch_doc:from_json_obj({[
{<<"_id">>, <<"doc1">>},
{<<"value">>, 1}
]}),
Doc2 = couch_doc:from_json_obj({[
{<<"_id">>, <<"doc2">>},
{<<"value">>, 2}
]}),
Doc3 = couch_doc:from_json_obj({[
{<<"_id">>, <<"doc3">>},
{<<"value">>, 3}
]}),
{ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]),
couch_db:ensure_full_commit(Db)
end).
compact_db(DbName) ->
couch_util:with_db(DbName, fun(Db) ->
{ok, _} = couch_db:start_compact(Db)
end),
wait_db_compact_done(DbName, ?WAIT_DELAY_COUNT).
wait_db_compact_done(_DbName, 0) ->
Failure = [
{module, ?MODULE},
{line, ?LINE},
{reason, "DB compaction failed to finish"}
],
erlang:error({assertion_failed, Failure});
wait_db_compact_done(DbName, N) ->
IsDone = couch_util:with_db(DbName, fun(Db) ->
not is_pid(couch_db:get_compactor_pid(Db))
end),
if IsDone -> ok; true ->
timer:sleep(?DELAY),
wait_db_compact_done(DbName, N - 1)
end.