This is an automated email from the ASF dual-hosted git repository. vatamane pushed a commit to branch merge-3.4.3 in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 77110bd9bcf11c3c976effba91eb295c2ed143ac Author: Jiahui Li <[email protected]> AuthorDate: Wed Mar 12 13:52:33 2025 -0500 Clean up `meck` functions in `fabric` - After upgrading `meck`, CI got errors about `context setup failed`. Cleaning up `meck` functions in `fabric` to fix this issue. ``` [2025-03-12T20:04:15.632Z] module 'fabric_view_map' [2025-03-12T20:04:16.552Z] fabric_view_map_meck_original:330: -handle_message_test_/0-fun-20- (t_handle_message_rexi_down)...[0.005 s] ok [2025-03-12T20:04:17.472Z] undefined [2025-03-12T20:04:17.472Z] *** context setup failed *** [2025-03-12T20:04:17.472Z] **in function persistent_term:get/1 [2025-03-12T20:04:17.472Z] called as get({cover,fabric_view_map_meck_original}) [2025-03-12T20:04:17.472Z] in call from fabric_view_map_meck_original:'-handle_message_test_/0-fun-23-'/0 [2025-03-12T20:04:17.472Z] **error:badarg ``` - Simplify tests with `?TDEF` and `?TDEF_FE` --- src/fabric/src/fabric.erl | 38 +- src/fabric/src/fabric_db_create.erl | 4 +- src/fabric/src/fabric_doc_open.erl | 711 +++++++++++------------ src/fabric/src/fabric_doc_open_revs.erl | 6 +- src/fabric/src/fabric_ring.erl | 3 +- src/fabric/src/fabric_streams.erl | 10 +- src/fabric/src/fabric_view_changes.erl | 3 +- src/fabric/test/eunit/fabric_db_create_tests.erl | 13 +- src/fabric/test/eunit/fabric_db_info_tests.erl | 1 - src/fabric/test/eunit/fabric_db_uuids_tests.erl | 1 - src/fabric/test/eunit/fabric_tests.erl | 1 + 11 files changed, 376 insertions(+), 415 deletions(-) diff --git a/src/fabric/src/fabric.erl b/src/fabric/src/fabric.erl index 93a71b035..7394a1978 100644 --- a/src/fabric/src/fabric.erl +++ b/src/fabric/src/fabric.erl @@ -761,7 +761,7 @@ set_namespace(NS, #mrargs{extra = Extra} = Args) -> Args#mrargs{extra = [{namespace, NS} | Extra]}. -ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). +-include_lib("couch/include/couch_eunit.hrl"). update_doc_test_() -> { @@ -770,18 +770,12 @@ update_doc_test_() -> setup, fun setup/0, fun teardown/1, - fun(Ctx) -> - [ - should_throw_conflict(Ctx) - ] - end + with([?TDEF(should_throw_conflict)]) } }. should_throw_conflict(Doc) -> - ?_test(begin - ?assertThrow(conflict, update_doc(<<"test-db">>, Doc, [])) - end). + ?assertThrow(conflict, update_doc(<<"test-db">>, Doc, [])). setup() -> Doc = #doc{ @@ -793,25 +787,13 @@ setup() -> meta = [] }, ok = application:ensure_started(config), - ok = meck:expect(mem3, shards, fun(_, _) -> [] end), - ok = meck:expect(mem3, quorum, fun(_) -> 1 end), - ok = meck:expect(rexi, cast, fun(_, _) -> ok end), - ok = meck:expect( - rexi_utils, - recv, - fun(_, _, _, _, _, _) -> - {ok, {error, [{Doc, conflict}]}} - end - ), - ok = meck:expect( - couch_util, - reorder_results, - fun(_, [{_, Res}], _) -> - [Res] - end - ), - ok = meck:expect(fabric_util, create_monitors, fun(_) -> ok end), - ok = meck:expect(rexi_monitor, stop, fun(_) -> ok end), + meck:expect(mem3, shards, fun(_, _) -> [] end), + meck:expect(mem3, quorum, fun(_) -> 1 end), + meck:expect(rexi, cast, fun(_, _) -> ok end), + meck:expect(rexi_utils, recv, fun(_, _, _, _, _, _) -> {ok, {error, [{Doc, conflict}]}} end), + meck:expect(couch_util, reorder_results, fun(_, [{_, Res}], _) -> [Res] end), + meck:expect(fabric_util, create_monitors, fun(_) -> ok end), + meck:expect(rexi_monitor, stop, fun(_) -> ok end), Doc. teardown(_) -> diff --git a/src/fabric/src/fabric_db_create.erl b/src/fabric/src/fabric_db_create.erl index 71375f5a8..f7c6e5402 100644 --- a/src/fabric/src/fabric_db_create.erl +++ b/src/fabric/src/fabric_db_create.erl @@ -221,7 +221,7 @@ db_exists_for_existing_db() -> Mock = fun(DbName) when is_binary(DbName) -> [#shard{dbname = DbName, range = [0, 100]}] end, - ok = meck:expect(mem3, shards, Mock), + meck:expect(mem3, shards, Mock), ?assertEqual(true, db_exists(<<"foobar">>)), ?assertEqual(true, meck:validate(mem3)). @@ -229,7 +229,7 @@ db_exists_for_missing_db() -> Mock = fun(DbName) -> erlang:error(database_does_not_exist, [DbName]) end, - ok = meck:expect(mem3, shards, Mock), + meck:expect(mem3, shards, Mock), ?assertEqual(false, db_exists(<<"foobar">>)), ?assertEqual(false, meck:validate(mem3)). diff --git a/src/fabric/src/fabric_doc_open.erl b/src/fabric/src/fabric_doc_open.erl index 3ad019039..4946a26bf 100644 --- a/src/fabric/src/fabric_doc_open.erl +++ b/src/fabric/src/fabric_doc_open.erl @@ -196,7 +196,7 @@ format_reply(Else, _) -> Else. -ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). +-include_lib("couch/include/couch_eunit.hrl"). -define(MECK_MODS, [ couch_log, @@ -230,67 +230,65 @@ open_doc_test_() -> fun setup/0, fun teardown/1, [ - t_is_r_met(), - t_handle_message_down(), - t_handle_message_exit(), - t_handle_message_reply(), - t_store_node_revs(), - t_read_repair(), - t_no_read_repair_for_replicator(), - t_handle_response_quorum_met(), - t_get_doc_info() + ?TDEF_FE(t_is_r_met), + ?TDEF_FE(t_handle_message_down), + ?TDEF_FE(t_handle_message_exit), + ?TDEF_FE(t_handle_message_reply), + ?TDEF_FE(t_store_node_revs), + ?TDEF_FE(t_read_repair), + ?TDEF_FE(t_no_read_repair_for_replicator), + ?TDEF_FE(t_handle_response_quorum_met), + ?TDEF_FE(t_get_doc_info) ] } }. -t_is_r_met() -> - ?_test(begin - Workers0 = [], - Workers1 = [nil], - Workers2 = [nil, nil], - - SuccessCases = [ - {{true, foo}, [fabric_util:kv(foo, 2)], 2}, - {{true, foo}, [fabric_util:kv(foo, 3)], 2}, - {{true, foo}, [fabric_util:kv(foo, 1)], 1}, - {{true, foo}, [fabric_util:kv(foo, 2), fabric_util:kv(bar, 1)], 2}, - {{true, bar}, [fabric_util:kv(bar, 1), fabric_util:kv(bar, 2)], 2}, - {{true, bar}, [fabric_util:kv(bar, 2), fabric_util:kv(foo, 1)], 2} - ], - lists:foreach( - fun({Expect, Replies, Q}) -> - ?assertEqual(Expect, is_r_met(Workers0, Replies, Q)) - end, - SuccessCases - ), - - WaitForMoreCases = [ - {[fabric_util:kv(foo, 1)], 2}, - {[fabric_util:kv(foo, 2)], 3}, - {[fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)], 2} - ], - lists:foreach( - fun({Replies, Q}) -> - ?assertEqual(wait_for_more, is_r_met(Workers2, Replies, Q)) - end, - WaitForMoreCases - ), - - FailureCases = [ - {Workers0, [fabric_util:kv(foo, 1)], 2}, - {Workers1, [fabric_util:kv(foo, 1)], 2}, - {Workers1, [fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)], 2}, - {Workers1, [fabric_util:kv(foo, 2)], 3} - ], - lists:foreach( - fun({Workers, Replies, Q}) -> - ?assertEqual(no_more_workers, is_r_met(Workers, Replies, Q)) - end, - FailureCases - ) - end). +t_is_r_met(_) -> + Workers0 = [], + Workers1 = [nil], + Workers2 = [nil, nil], + + SuccessCases = [ + {{true, foo}, [fabric_util:kv(foo, 2)], 2}, + {{true, foo}, [fabric_util:kv(foo, 3)], 2}, + {{true, foo}, [fabric_util:kv(foo, 1)], 1}, + {{true, foo}, [fabric_util:kv(foo, 2), fabric_util:kv(bar, 1)], 2}, + {{true, bar}, [fabric_util:kv(bar, 1), fabric_util:kv(bar, 2)], 2}, + {{true, bar}, [fabric_util:kv(bar, 2), fabric_util:kv(foo, 1)], 2} + ], + lists:foreach( + fun({Expect, Replies, Q}) -> + ?assertEqual(Expect, is_r_met(Workers0, Replies, Q)) + end, + SuccessCases + ), -t_handle_message_down() -> + WaitForMoreCases = [ + {[fabric_util:kv(foo, 1)], 2}, + {[fabric_util:kv(foo, 2)], 3}, + {[fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)], 2} + ], + lists:foreach( + fun({Replies, Q}) -> + ?assertEqual(wait_for_more, is_r_met(Workers2, Replies, Q)) + end, + WaitForMoreCases + ), + + FailureCases = [ + {Workers0, [fabric_util:kv(foo, 1)], 2}, + {Workers1, [fabric_util:kv(foo, 1)], 2}, + {Workers1, [fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)], 2}, + {Workers1, [fabric_util:kv(foo, 2)], 3} + ], + lists:foreach( + fun({Workers, Replies, Q}) -> + ?assertEqual(no_more_workers, is_r_met(Workers, Replies, Q)) + end, + FailureCases + ). + +t_handle_message_down(_) -> Node0 = 'foo@localhost', Node1 = 'bar@localhost', Down0 = {rexi_DOWN, nil, {nil, Node0}, nil}, @@ -299,141 +297,135 @@ t_handle_message_down() -> Worker1 = #shard{node = Node1}, Workers1 = Workers0 ++ [Worker1], - ?_test(begin - % Stop when no more workers are left - ?assertEqual( - {stop, #acc{workers = []}}, - handle_message(Down0, nil, #acc{workers = Workers0}) - ), - - % Continue when we have more workers - ?assertEqual( - {ok, #acc{workers = [Worker1]}}, - handle_message(Down0, nil, #acc{workers = Workers1}) - ), - - % A second DOWN removes the remaining workers - ?assertEqual( - {stop, #acc{workers = []}}, - handle_message(Down1, nil, #acc{workers = [Worker1]}) - ) - end). - -t_handle_message_exit() -> + % Stop when no more workers are left + ?assertEqual( + {stop, #acc{workers = []}}, + handle_message(Down0, nil, #acc{workers = Workers0}) + ), + + % Continue when we have more workers + ?assertEqual( + {ok, #acc{workers = [Worker1]}}, + handle_message(Down0, nil, #acc{workers = Workers1}) + ), + + % A second DOWN removes the remaining workers + ?assertEqual( + {stop, #acc{workers = []}}, + handle_message(Down1, nil, #acc{workers = [Worker1]}) + ). + +t_handle_message_exit(_) -> Exit = {rexi_EXIT, nil}, Worker0 = #shard{ref = erlang:make_ref()}, Worker1 = #shard{ref = erlang:make_ref()}, - ?_test(begin - % Only removes the specified worker - ?assertEqual( - {ok, #acc{workers = [Worker1]}}, - handle_message(Exit, Worker0, #acc{workers = [Worker0, Worker1]}) - ), - - ?assertEqual( - {ok, #acc{workers = [Worker0]}}, - handle_message(Exit, Worker1, #acc{workers = [Worker0, Worker1]}) - ), - - % We bail if it was the last worker - ?assertEqual( - {stop, #acc{workers = []}}, - handle_message(Exit, Worker0, #acc{workers = [Worker0]}) - ) - end). - -t_handle_message_reply() -> + % Only removes the specified worker + ?assertEqual( + {ok, #acc{workers = [Worker1]}}, + handle_message(Exit, Worker0, #acc{workers = [Worker0, Worker1]}) + ), + + ?assertEqual( + {ok, #acc{workers = [Worker0]}}, + handle_message(Exit, Worker1, #acc{workers = [Worker0, Worker1]}) + ), + + % We bail if it was the last worker + ?assertEqual( + {stop, #acc{workers = []}}, + handle_message(Exit, Worker0, #acc{workers = [Worker0]}) + ). + +t_handle_message_reply(_) -> Worker0 = #shard{ref = erlang:make_ref()}, Worker1 = #shard{ref = erlang:make_ref()}, Worker2 = #shard{ref = erlang:make_ref()}, Workers = [Worker0, Worker1, Worker2], Acc0 = #acc{workers = Workers, r = 2, replies = []}, - ?_test(begin - meck:expect(rexi, kill_all, fun(_) -> ok end), - - % Test that we continue when we haven't met R yet - ?assertMatch( - {ok, #acc{ - workers = [Worker0, Worker1], - replies = [{foo, {foo, 1}}] - }}, - handle_message(foo, Worker2, Acc0) - ), - - ?assertMatch( - {ok, #acc{ - workers = [Worker0, Worker1], - replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] - }}, - handle_message(bar, Worker2, Acc0#acc{ - replies = [{foo, {foo, 1}}] - }) - ), - - % Test that we don't get a quorum when R isn't met. q_reply - % isn't set and state remains unchanged and {stop, NewAcc} - % is returned. Bit subtle on the assertions here. - - ?assertMatch( - {stop, #acc{workers = [], replies = [{foo, {foo, 1}}]}}, - handle_message(foo, Worker0, Acc0#acc{workers = [Worker0]}) - ), - - ?assertMatch( - {stop, #acc{ - workers = [], - replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] - }}, - handle_message(bar, Worker0, Acc0#acc{ - workers = [Worker0], - replies = [{foo, {foo, 1}}] - }) - ), - - % Check that when R is met we stop with a new state and - % a q_reply. - - ?assertMatch( - {stop, #acc{ - workers = [], - replies = [{foo, {foo, 2}}], - state = r_met, - q_reply = foo - }}, - handle_message(foo, Worker1, Acc0#acc{ - workers = [Worker0, Worker1], - replies = [{foo, {foo, 1}}] - }) - ), - - ?assertEqual( - {stop, #acc{ - workers = [], - r = 1, - replies = [{foo, {foo, 1}}], - state = r_met, - q_reply = foo - }}, - handle_message(foo, Worker0, Acc0#acc{r = 1}) - ), - - ?assertMatch( - {stop, #acc{ - workers = [], - replies = [{bar, {bar, 1}}, {foo, {foo, 2}}], - state = r_met, - q_reply = foo - }}, - handle_message(foo, Worker0, Acc0#acc{ - workers = [Worker0], - replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] - }) - ) - end). - -t_store_node_revs() -> + meck:expect(rexi, kill_all, fun(_) -> ok end), + + % Test that we continue when we haven't met R yet + ?assertMatch( + {ok, #acc{ + workers = [Worker0, Worker1], + replies = [{foo, {foo, 1}}] + }}, + handle_message(foo, Worker2, Acc0) + ), + + ?assertMatch( + {ok, #acc{ + workers = [Worker0, Worker1], + replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] + }}, + handle_message(bar, Worker2, Acc0#acc{ + replies = [{foo, {foo, 1}}] + }) + ), + + % Test that we don't get a quorum when R isn't met. q_reply + % isn't set and state remains unchanged and {stop, NewAcc} + % is returned. Bit subtle on the assertions here. + + ?assertMatch( + {stop, #acc{workers = [], replies = [{foo, {foo, 1}}]}}, + handle_message(foo, Worker0, Acc0#acc{workers = [Worker0]}) + ), + + ?assertMatch( + {stop, #acc{ + workers = [], + replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] + }}, + handle_message(bar, Worker0, Acc0#acc{ + workers = [Worker0], + replies = [{foo, {foo, 1}}] + }) + ), + + % Check that when R is met we stop with a new state and + % a q_reply. + + ?assertMatch( + {stop, #acc{ + workers = [], + replies = [{foo, {foo, 2}}], + state = r_met, + q_reply = foo + }}, + handle_message(foo, Worker1, Acc0#acc{ + workers = [Worker0, Worker1], + replies = [{foo, {foo, 1}}] + }) + ), + + ?assertEqual( + {stop, #acc{ + workers = [], + r = 1, + replies = [{foo, {foo, 1}}], + state = r_met, + q_reply = foo + }}, + handle_message(foo, Worker0, Acc0#acc{r = 1}) + ), + + ?assertMatch( + {stop, #acc{ + workers = [], + replies = [{bar, {bar, 1}}, {foo, {foo, 2}}], + state = r_met, + q_reply = foo + }}, + handle_message(foo, Worker0, Acc0#acc{ + workers = [Worker0], + replies = [{bar, {bar, 1}}, {foo, {foo, 1}}] + }) + ). + +t_store_node_revs(_) -> W1 = #shard{node = w1, ref = erlang:make_ref()}, W2 = #shard{node = w2, ref = erlang:make_ref()}, W3 = #shard{node = w3, ref = erlang:make_ref()}, @@ -443,200 +435,189 @@ t_store_node_revs() -> InitAcc = #acc{workers = [W1, W2, W3], replies = [], r = 2}, - ?_test(begin - meck:expect(rexi, kill_all, fun(_) -> ok end), - - % Simple case - {ok, #acc{node_revs = NodeRevs1}} = handle_message(Foo1, W1, InitAcc), - ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs1), - - % Make sure we only hold the head rev - {ok, #acc{node_revs = NodeRevs2}} = handle_message(Foo2, W1, InitAcc), - ?assertEqual([{w1, [{2, <<"foo2">>}]}], NodeRevs2), - - % Make sure we don't capture anything on error - {ok, #acc{node_revs = NodeRevs3}} = handle_message(NFM, W1, InitAcc), - ?assertEqual([], NodeRevs3), - - % Make sure we accumulate node revs - Acc1 = InitAcc#acc{node_revs = [{w1, [{1, <<"foo">>}]}]}, - {ok, #acc{node_revs = NodeRevs4}} = handle_message(Foo2, W2, Acc1), - ?assertEqual( - [{w2, [{2, <<"foo2">>}]}, {w1, [{1, <<"foo">>}]}], - NodeRevs4 - ), - - % Make sure rexi_DOWN doesn't modify node_revs - Down = {rexi_DOWN, nil, {nil, w1}, nil}, - {ok, #acc{node_revs = NodeRevs5}} = handle_message(Down, W2, Acc1), - ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs5), - - % Make sure rexi_EXIT doesn't modify node_revs - Exit = {rexi_EXIT, reason}, - {ok, #acc{node_revs = NodeRevs6}} = handle_message(Exit, W2, Acc1), - ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs6), - - % Make sure an error doesn't remove any node revs - {ok, #acc{node_revs = NodeRevs7}} = handle_message(NFM, W2, Acc1), - ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs7), - - % Make sure we have all of our node_revs when meeting - % quorum - {ok, Acc2} = handle_message(Foo1, W1, InitAcc), - {ok, Acc3} = handle_message(Foo2, W2, Acc2), - {stop, Acc4} = handle_message(NFM, W3, Acc3), - ?assertEqual( - [{w2, [{2, <<"foo2">>}]}, {w1, [{1, <<"foo">>}]}], - Acc4#acc.node_revs - ) - end). - -t_read_repair() -> + meck:expect(rexi, kill_all, fun(_) -> ok end), + + % Simple case + {ok, #acc{node_revs = NodeRevs1}} = handle_message(Foo1, W1, InitAcc), + ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs1), + + % Make sure we only hold the head rev + {ok, #acc{node_revs = NodeRevs2}} = handle_message(Foo2, W1, InitAcc), + ?assertEqual([{w1, [{2, <<"foo2">>}]}], NodeRevs2), + + % Make sure we don't capture anything on error + {ok, #acc{node_revs = NodeRevs3}} = handle_message(NFM, W1, InitAcc), + ?assertEqual([], NodeRevs3), + + % Make sure we accumulate node revs + Acc1 = InitAcc#acc{node_revs = [{w1, [{1, <<"foo">>}]}]}, + {ok, #acc{node_revs = NodeRevs4}} = handle_message(Foo2, W2, Acc1), + ?assertEqual( + [{w2, [{2, <<"foo2">>}]}, {w1, [{1, <<"foo">>}]}], + NodeRevs4 + ), + + % Make sure rexi_DOWN doesn't modify node_revs + Down = {rexi_DOWN, nil, {nil, w1}, nil}, + {ok, #acc{node_revs = NodeRevs5}} = handle_message(Down, W2, Acc1), + ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs5), + + % Make sure rexi_EXIT doesn't modify node_revs + Exit = {rexi_EXIT, reason}, + {ok, #acc{node_revs = NodeRevs6}} = handle_message(Exit, W2, Acc1), + ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs6), + + % Make sure an error doesn't remove any node revs + {ok, #acc{node_revs = NodeRevs7}} = handle_message(NFM, W2, Acc1), + ?assertEqual([{w1, [{1, <<"foo">>}]}], NodeRevs7), + + % Make sure we have all of our node_revs when meeting + % quorum + {ok, Acc2} = handle_message(Foo1, W1, InitAcc), + {ok, Acc3} = handle_message(Foo2, W2, Acc2), + {stop, Acc4} = handle_message(NFM, W3, Acc3), + ?assertEqual( + [{w2, [{2, <<"foo2">>}]}, {w1, [{1, <<"foo">>}]}], + Acc4#acc.node_revs + ). + +t_read_repair(_) -> Foo1 = {ok, #doc{revs = {1, [<<"foo">>]}}}, Foo2 = {ok, #doc{revs = {2, [<<"foo2">>, <<"foo">>]}}}, NFM = {not_found, missing}, - ?_test(begin - meck:expect(couch_log, notice, fun(_, _) -> ok end), - meck:expect(couch_stats, increment_counter, fun(_) -> ok end), - - % Test when we have actual doc data to repair - meck:expect(fabric, update_docs, fun(_, [_], _) -> {ok, []} end), - Acc0 = #acc{ - dbname = <<"name">>, - replies = [fabric_util:kv(Foo1, 1)] - }, - ?assertEqual(Foo1, read_repair(Acc0)), - - meck:expect(fabric, update_docs, fun(_, [_, _], _) -> {ok, []} end), - Acc1 = #acc{ - dbname = <<"name">>, - replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Foo2, 1)] - }, - ?assertEqual(Foo2, read_repair(Acc1)), - - % Test when we have nothing but errors - Acc2 = #acc{replies = [fabric_util:kv(NFM, 1)]}, - ?assertEqual(NFM, read_repair(Acc2)), - - Acc3 = #acc{replies = [fabric_util:kv(NFM, 1), fabric_util:kv(foo, 2)]}, - ?assertEqual(NFM, read_repair(Acc3)), - - Acc4 = #acc{replies = [fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)]}, - ?assertEqual(bar, read_repair(Acc4)) - end). - -t_no_read_repair_for_replicator() -> + meck:expect(couch_log, notice, fun(_, _) -> ok end), + meck:expect(couch_stats, increment_counter, fun(_) -> ok end), + + % Test when we have actual doc data to repair + meck:expect(fabric, update_docs, fun(_, [_], _) -> {ok, []} end), + Acc0 = #acc{ + dbname = <<"name">>, + replies = [fabric_util:kv(Foo1, 1)] + }, + ?assertEqual(Foo1, read_repair(Acc0)), + + meck:expect(fabric, update_docs, fun(_, [_, _], _) -> {ok, []} end), + Acc1 = #acc{ + dbname = <<"name">>, + replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Foo2, 1)] + }, + ?assertEqual(Foo2, read_repair(Acc1)), + + % Test when we have nothing but errors + Acc2 = #acc{replies = [fabric_util:kv(NFM, 1)]}, + ?assertEqual(NFM, read_repair(Acc2)), + + Acc3 = #acc{replies = [fabric_util:kv(NFM, 1), fabric_util:kv(foo, 2)]}, + ?assertEqual(NFM, read_repair(Acc3)), + + Acc4 = #acc{replies = [fabric_util:kv(foo, 1), fabric_util:kv(bar, 1)]}, + ?assertEqual(bar, read_repair(Acc4)). + +t_no_read_repair_for_replicator(_) -> Foo1 = {ok, #doc{revs = {1, [<<"foo">>]}}}, - ?_test(begin - meck:expect(couch_log, notice, fun(_, _) -> ok end), - meck:expect(couch_stats, increment_counter, fun(_) -> ok end), - - % Test no read_repair took place - meck:reset(fabric), - Acc0 = #acc{ - dbname = <<"dbname1/_replicator">>, - replies = [fabric_util:kv(Foo1, 1)] - }, - ?assertEqual(Foo1, read_repair(Acc0)), - timer:sleep(100), - ?assertNot(meck:called(fabric, update_docs, ['_', '_', '_'])) - end). - -t_handle_response_quorum_met() -> + meck:expect(couch_log, notice, fun(_, _) -> ok end), + meck:expect(couch_stats, increment_counter, fun(_) -> ok end), + + % Test no read_repair took place + meck:reset(fabric), + Acc0 = #acc{ + dbname = <<"dbname1/_replicator">>, + replies = [fabric_util:kv(Foo1, 1)] + }, + ?assertEqual(Foo1, read_repair(Acc0)), + timer:sleep(100), + ?assertNot(meck:called(fabric, update_docs, ['_', '_', '_'])). + +t_handle_response_quorum_met(_) -> Foo1 = {ok, #doc{revs = {1, [<<"foo">>]}}}, Foo2 = {ok, #doc{revs = {2, [<<"foo2">>, <<"foo">>]}}}, Bar1 = {ok, #doc{revs = {1, [<<"bar">>]}}}, - ?_test(begin - meck:expect(couch_log, notice, fun(_, _) -> ok end), - meck:expect(fabric, update_docs, fun(_, _, _) -> {ok, []} end), - meck:expect(couch_stats, increment_counter, fun(_) -> ok end), + meck:expect(couch_log, notice, fun(_, _) -> ok end), + meck:expect(fabric, update_docs, fun(_, _, _) -> {ok, []} end), + meck:expect(couch_stats, increment_counter, fun(_) -> ok end), - BasicOkAcc = #acc{ - dbname = <<"dbname1">>, - state = r_met, - replies = [fabric_util:kv(Foo1, 2)], - q_reply = Foo1 - }, - ?assertEqual(Foo1, handle_response(BasicOkAcc)), + BasicOkAcc = #acc{ + dbname = <<"dbname1">>, + state = r_met, + replies = [fabric_util:kv(Foo1, 2)], + q_reply = Foo1 + }, + ?assertEqual(Foo1, handle_response(BasicOkAcc)), - WithAncestorsAcc = #acc{ - dbname = <<"dbname1">>, - state = r_met, - replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Foo2, 2)], - q_reply = Foo2 - }, - ?assertEqual(Foo2, handle_response(WithAncestorsAcc)), - - % This also checks when the quorum isn't the most recent - % revision. - DeeperWinsAcc = #acc{ - dbname = <<"dbname1">>, - state = r_met, - replies = [fabric_util:kv(Foo1, 2), fabric_util:kv(Foo2, 1)], - q_reply = Foo1 - }, - ?assertEqual(Foo2, handle_response(DeeperWinsAcc)), - - % Check that we return the proper doc based on rev - % (ie, pos is equal) - BiggerRevWinsAcc = #acc{ - dbname = <<"dbname1">>, - state = r_met, - replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Bar1, 2)], - q_reply = Bar1 - }, - ?assertEqual(Foo1, handle_response(BiggerRevWinsAcc)) - - % r_not_met is a proxy to read_repair so we rely on - % read_repair_test for those conditions. - end). - -t_get_doc_info() -> - ?_test(begin - meck:expect(fabric, update_docs, fun(_, _, _) -> {ok, []} end), - meck:expect(couch_stats, increment_counter, fun(_) -> ok end), - meck:expect(fabric_util, submit_jobs, fun(_, _, _) -> ok end), - meck:expect(fabric_util, create_monitors, fun(_) -> ok end), - meck:expect(rexi_monitor, stop, fun(_) -> ok end), - meck:expect(mem3, shards, fun(_, _) -> ok end), - meck:expect(mem3, n, fun(_) -> 3 end), - meck:expect(mem3, quorum, fun(_) -> 2 end), - - meck:expect(fabric_util, recv, fun(_, _, _, _) -> - {ok, #acc{state = r_not_met}} - end), - Rsp1 = fabric_doc_open:go("test", "one", [doc_info]), - ?assertEqual({error, quorum_not_met}, Rsp1), - - Rsp2 = fabric_doc_open:go("test", "one", [{doc_info, full}]), - ?assertEqual({error, quorum_not_met}, Rsp2), - - meck:expect(fabric_util, recv, fun(_, _, _, _) -> - {ok, #acc{state = r_met, q_reply = not_found}} - end), - MissingRsp1 = fabric_doc_open:go("test", "one", [doc_info]), - ?assertEqual({not_found, missing}, MissingRsp1), - MissingRsp2 = fabric_doc_open:go("test", "one", [{doc_info, full}]), - ?assertEqual({not_found, missing}, MissingRsp2), - - meck:expect(fabric_util, recv, fun(_, _, _, _) -> - A = #doc_info{}, - {ok, #acc{state = r_met, q_reply = {ok, A}}} - end), - {ok, Rec1} = fabric_doc_open:go("test", "one", [doc_info]), - ?assert(is_record(Rec1, doc_info)), - - meck:expect(fabric_util, recv, fun(_, _, _, _) -> - A = #full_doc_info{deleted = true}, - {ok, #acc{state = r_met, q_reply = {ok, A}}} - end), - Rsp3 = fabric_doc_open:go("test", "one", [{doc_info, full}]), - ?assertEqual({not_found, deleted}, Rsp3), - {ok, Rec2} = fabric_doc_open:go("test", "one", [{doc_info, full}, deleted]), - ?assert(is_record(Rec2, full_doc_info)) - end). + WithAncestorsAcc = #acc{ + dbname = <<"dbname1">>, + state = r_met, + replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Foo2, 2)], + q_reply = Foo2 + }, + ?assertEqual(Foo2, handle_response(WithAncestorsAcc)), + + % This also checks when the quorum isn't the most recent + % revision. + DeeperWinsAcc = #acc{ + dbname = <<"dbname1">>, + state = r_met, + replies = [fabric_util:kv(Foo1, 2), fabric_util:kv(Foo2, 1)], + q_reply = Foo1 + }, + ?assertEqual(Foo2, handle_response(DeeperWinsAcc)), + + % Check that we return the proper doc based on rev + % (ie, pos is equal) + BiggerRevWinsAcc = #acc{ + dbname = <<"dbname1">>, + state = r_met, + replies = [fabric_util:kv(Foo1, 1), fabric_util:kv(Bar1, 2)], + q_reply = Bar1 + }, + ?assertEqual(Foo1, handle_response(BiggerRevWinsAcc)). + +% r_not_met is a proxy to read_repair so we rely on +% read_repair_test for those conditions. +t_get_doc_info(_) -> + meck:expect(fabric, update_docs, fun(_, _, _) -> {ok, []} end), + meck:expect(couch_stats, increment_counter, fun(_) -> ok end), + meck:expect(fabric_util, submit_jobs, fun(_, _, _) -> ok end), + meck:expect(fabric_util, create_monitors, fun(_) -> ok end), + meck:expect(rexi_monitor, stop, fun(_) -> ok end), + meck:expect(mem3, shards, fun(_, _) -> ok end), + meck:expect(mem3, n, fun(_) -> 3 end), + meck:expect(mem3, quorum, fun(_) -> 2 end), + + meck:expect(fabric_util, recv, fun(_, _, _, _) -> + {ok, #acc{state = r_not_met}} + end), + Rsp1 = fabric_doc_open:go("test", "one", [doc_info]), + ?assertEqual({error, quorum_not_met}, Rsp1), + + Rsp2 = fabric_doc_open:go("test", "one", [{doc_info, full}]), + ?assertEqual({error, quorum_not_met}, Rsp2), + + meck:expect(fabric_util, recv, fun(_, _, _, _) -> + {ok, #acc{state = r_met, q_reply = not_found}} + end), + MissingRsp1 = fabric_doc_open:go("test", "one", [doc_info]), + ?assertEqual({not_found, missing}, MissingRsp1), + MissingRsp2 = fabric_doc_open:go("test", "one", [{doc_info, full}]), + ?assertEqual({not_found, missing}, MissingRsp2), + + meck:expect(fabric_util, recv, fun(_, _, _, _) -> + A = #doc_info{}, + {ok, #acc{state = r_met, q_reply = {ok, A}}} + end), + {ok, Rec1} = fabric_doc_open:go("test", "one", [doc_info]), + ?assert(is_record(Rec1, doc_info)), + + meck:expect(fabric_util, recv, fun(_, _, _, _) -> + A = #full_doc_info{deleted = true}, + {ok, #acc{state = r_met, q_reply = {ok, A}}} + end), + Rsp3 = fabric_doc_open:go("test", "one", [{doc_info, full}]), + ?assertEqual({not_found, deleted}, Rsp3), + {ok, Rec2} = fabric_doc_open:go("test", "one", [{doc_info, full}, deleted]), + ?assert(is_record(Rec2, full_doc_info)). -endif. diff --git a/src/fabric/src/fabric_doc_open_revs.erl b/src/fabric/src/fabric_doc_open_revs.erl index ff1948735..b0ff994b0 100644 --- a/src/fabric/src/fabric_doc_open_revs.erl +++ b/src/fabric/src/fabric_doc_open_revs.erl @@ -456,9 +456,9 @@ check_finish_quorum_newer(_) -> S0 = state0(all, false), {ok, S1} = handle_message({ok, [foo1(), bar1()]}, W1, S0), Expect = {stop, [bar1(), foo2()]}, - ok = meck:reset(fabric), + meck:reset(fabric), ?assertEqual(Expect, handle_message({ok, [foo2(), bar1()]}, W2, S1)), - ok = meck:wait(fabric, update_docs, '_', 5000), + meck:wait(fabric, update_docs, '_', 5000), ?assertMatch( [{_, {fabric, update_docs, [_, _, _]}, _}], meck:history(fabric) @@ -474,7 +474,7 @@ check_finish_quorum_replicator(_) -> S1 = S0#state{dbname = <<"foo/_replicator">>}, {ok, S2} = handle_message({ok, [foo1(), bar1()]}, W1, S1), Expect = {stop, [bar1(), foo2()]}, - ok = meck:reset(fabric), + meck:reset(fabric), ?assertEqual(Expect, handle_message({ok, [foo2(), bar1()]}, W2, S2)), timer:sleep(100), ?assertNot(meck:called(fabric, update_docs, ['_', '_', '_'])). diff --git a/src/fabric/src/fabric_ring.erl b/src/fabric/src/fabric_ring.erl index 3973892d4..c8ba5e466 100644 --- a/src/fabric/src/fabric_ring.erl +++ b/src/fabric/src/fabric_ring.erl @@ -631,8 +631,7 @@ handle_response_cleanup_callback_test_() -> setup() -> meck:new(rexi, [passthrough]), - meck:expect(rexi, kill_all, 1, ok), - ok. + meck:expect(rexi, kill_all, 1, ok). teardown(_) -> meck:unload(). diff --git a/src/fabric/src/fabric_streams.erl b/src/fabric/src/fabric_streams.erl index af2284f9f..2bc71a532 100644 --- a/src/fabric/src/fabric_streams.erl +++ b/src/fabric/src/fabric_streams.erl @@ -489,13 +489,13 @@ cleanup_called_on_error(_) -> ?assert(meck:called(fabric_util, cleanup, 1)). setup() -> - ok = meck:new(rexi_utils, [passthrough]), - ok = meck:new(config, [passthrough]), - ok = meck:new(fabric_util, [passthrough]), + meck:new(rexi_utils, [passthrough]), + meck:new(config, [passthrough]), + meck:new(fabric_util, [passthrough]), meck:expect(config, get, fun(_, _, Default) -> Default end), - ok = meck:expect(rexi, kill_all, fun(_) -> ok end), + meck:expect(rexi, kill_all, fun(_) -> ok end), % Speed up disconnect socket timeout for the test to 200 msec - ok = meck:expect(chttpd_util, mochiweb_client_req_check_msec, 0, 200). + meck:expect(chttpd_util, mochiweb_client_req_check_msec, 0, 200). teardown(_) -> meck:unload(). diff --git a/src/fabric/src/fabric_view_changes.erl b/src/fabric/src/fabric_view_changes.erl index 6bd571c0b..f6695f163 100644 --- a/src/fabric/src/fabric_view_changes.erl +++ b/src/fabric/src/fabric_view_changes.erl @@ -764,8 +764,7 @@ unpack_seq_setup() -> meck:new(fabric_view), meck:expect(mem3, get_shard, fun(_, _, _) -> {ok, #shard{}} end), meck:expect(mem3, shards, fun(_) -> [#shard{}] end), - meck:expect(fabric_ring, is_progress_possible, fun(_) -> true end), - ok. + meck:expect(fabric_ring, is_progress_possible, fun(_) -> true end). unpack_seqs_test_() -> { diff --git a/src/fabric/test/eunit/fabric_db_create_tests.erl b/src/fabric/test/eunit/fabric_db_create_tests.erl index 9d78d177d..1d7422e90 100644 --- a/src/fabric/test/eunit/fabric_db_create_tests.erl +++ b/src/fabric/test/eunit/fabric_db_create_tests.erl @@ -26,19 +26,20 @@ main_test_() -> }. setup() -> - test_util:start_couch([fabric]). + Ctx = test_util:start_couch([fabric]), + meck:new(mem3, [passthrough]), + meck:new(fabric_util, [passthrough]), + Ctx. teardown(Ctx) -> + meck:unload(), test_util:stop_couch(Ctx). t_handle_shard_doc_conflict(_) -> DbName = ?tempdb(), - meck:new(mem3, [passthrough]), - meck:new(fabric_util, [passthrough]), - ok = meck:sequence(mem3, shards, 1, [ + meck:sequence(mem3, shards, 1, [ fun(_) -> meck:raise(error, database_does_not_exist) end, [#shard{dbname = DbName}] ]), meck:expect(fabric_util, recv, 4, {error, conflict}), - ?assertEqual({error, file_exists}, fabric_db_create:go(DbName, [])), - meck:unload(). + ?assertEqual({error, file_exists}, fabric_db_create:go(DbName, [])). diff --git a/src/fabric/test/eunit/fabric_db_info_tests.erl b/src/fabric/test/eunit/fabric_db_info_tests.erl index 57313df50..e7df560a1 100644 --- a/src/fabric/test/eunit/fabric_db_info_tests.erl +++ b/src/fabric/test/eunit/fabric_db_info_tests.erl @@ -28,7 +28,6 @@ setup() -> test_util:start_couch([fabric]). teardown(Ctx) -> - meck:unload(), test_util:stop_couch(Ctx). t_update_seq_has_uuids(_) -> diff --git a/src/fabric/test/eunit/fabric_db_uuids_tests.erl b/src/fabric/test/eunit/fabric_db_uuids_tests.erl index 1042c7cd3..b406fb957 100644 --- a/src/fabric/test/eunit/fabric_db_uuids_tests.erl +++ b/src/fabric/test/eunit/fabric_db_uuids_tests.erl @@ -29,7 +29,6 @@ setup() -> test_util:start_couch([fabric]). teardown(Ctx) -> - meck:unload(), test_util:stop_couch(Ctx). t_can_get_shard_uuids(_) -> diff --git a/src/fabric/test/eunit/fabric_tests.erl b/src/fabric/test/eunit/fabric_tests.erl index 0b3f20a46..b2c235fd3 100644 --- a/src/fabric/test/eunit/fabric_tests.erl +++ b/src/fabric/test/eunit/fabric_tests.erl @@ -42,6 +42,7 @@ setup() -> {Ctx, DbName}. teardown({Ctx, DbName}) -> + meck:unload(), fabric:delete_db(DbName), test_util:stop_couch(Ctx).
