summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2018-05-23 12:32:48 -0500
committerjiangph <jiangph@cn.ibm.com>2018-08-21 09:11:30 +0800
commitaea2833fec6611aeafdccd5e39979259ced9950d (patch)
treec602b316f6d1ac5894381c96a84a04777ff18509
parentbb27d5ebb02a1034bf4e0b5c33c1ba3189d5f9b1 (diff)
downloadcouchdb-aea2833fec6611aeafdccd5e39979259ced9950d.tar.gz
Update fabric_doc_open eunit tests
Modernize and fix the eunit tests in fabric_doc_open.erl
-rw-r--r--src/fabric/src/fabric_doc_open.erl631
1 files changed, 310 insertions, 321 deletions
diff --git a/src/fabric/src/fabric_doc_open.erl b/src/fabric/src/fabric_doc_open.erl
index 9c45bd9f3..93f73a821 100644
--- a/src/fabric/src/fabric_doc_open.erl
+++ b/src/fabric/src/fabric_doc_open.erl
@@ -174,85 +174,84 @@ format_reply(not_found, _) ->
format_reply(Else, _) ->
Else.
-is_r_met_test() ->
- Workers0 = [],
- Workers1 = [nil],
- Workers2 = [nil,nil],
-
- % Successful cases
-
- ?assertEqual(
- {true, foo},
- is_r_met([], [fabric_util:kv(foo,2)], 2)
- ),
-
- ?assertEqual(
- {true, foo},
- is_r_met([], [fabric_util:kv(foo,3)], 2)
- ),
-
- ?assertEqual(
- {true, foo},
- is_r_met([], [fabric_util:kv(foo,1)], 1)
- ),
-
- ?assertEqual(
- {true, foo},
- is_r_met([], [fabric_util:kv(foo,2), fabric_util:kv(bar,1)], 2)
- ),
-
- ?assertEqual(
- {true, bar},
- is_r_met([], [fabric_util:kv(bar,1), fabric_util:kv(bar,2)], 2)
- ),
-
- ?assertEqual(
- {true, bar},
- is_r_met([], [fabric_util:kv(bar,2), fabric_util:kv(foo,1)], 2)
- ),
-
- % Not met, but wait for more messages
-
- ?assertEqual(
- wait_for_more,
- is_r_met(Workers2, [fabric_util:kv(foo,1)], 2)
- ),
-
- ?assertEqual(
- wait_for_more,
- is_r_met(Workers2, [fabric_util:kv(foo,2)], 3)
- ),
-
- ?assertEqual(
- wait_for_more,
- is_r_met(Workers2, [fabric_util:kv(foo,1), fabric_util:kv(bar,1)], 2)
- ),
-
- % Not met, bail out
-
- ?assertEqual(
- no_more_workers,
- is_r_met(Workers0, [fabric_util:kv(foo,1)], 2)
- ),
-
- ?assertEqual(
- no_more_workers,
- is_r_met(Workers1, [fabric_util:kv(foo,1)], 2)
- ),
-
- ?assertEqual(
- no_more_workers,
- is_r_met(Workers1, [fabric_util:kv(foo,1), fabric_util:kv(bar,1)], 2)
- ),
-
- ?assertEqual(
- no_more_workers,
- is_r_met(Workers1, [fabric_util:kv(foo,2)], 3)
- ),
-
- ok.
-
-handle_message_down_test() ->
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+
+setup() ->
+ meck:new([
+ couch_log,
+ couch_stats,
+ fabric,
+ fabric_util,
+ mem3,
+ rexi,
+ rexi_monitor
+ ], [passthrough]).
+
+
+teardown(_) ->
+ meck:unload().
+
+
+open_doc_test_() ->
+ {
+ foreach,
+ fun setup/0,
+ fun teardown/1,
+ [
+ t_is_r_met(),
+ t_handle_message_down(),
+ t_handle_message_exit(),
+ t_handle_message_reply(),
+ t_read_repair(),
+ t_handle_response_quorum_met(),
+ 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_handle_message_down() ->
Node0 = 'foo@localhost',
Node1 = 'bar@localhost',
Down0 = {rexi_DOWN, nil, {nil, Node0}, nil},
@@ -261,279 +260,269 @@ handle_message_down_test() ->
Worker1 = #shard{node=Node1},
Workers1 = Workers0 ++ [Worker1],
- % Stop when no more workers are left
- ?assertEqual(
- {stop, #acc{workers=[]}},
- handle_message(Down0, nil, #acc{workers=Workers0})
- ),
+ ?_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})
- ),
+ % 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]})
- ),
+ % A second DOWN removes the remaining workers
+ ?assertEqual(
+ {stop, #acc{workers=[]}},
+ handle_message(Down1, nil, #acc{workers=[Worker1]})
+ )
+ end).
- ok.
-handle_message_exit_test() ->
+t_handle_message_exit() ->
Exit = {rexi_EXIT, nil},
Worker0 = #shard{ref=erlang:make_ref()},
Worker1 = #shard{ref=erlang:make_ref()},
- % 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]})
- ),
+ ?_test(begin
+ % Only removes the specified worker
+ ?assertEqual(
+ {ok, #acc{workers=[Worker1]}},
+ handle_message(Exit, Worker0, #acc{workers=[Worker0, Worker1]})
+ ),
- % We bail if it was the last worker
- ?assertEqual(
- {stop, #acc{workers=[]}},
- handle_message(Exit, Worker0, #acc{workers=[Worker0]})
- ),
+ ?assertEqual(
+ {ok, #acc{workers=[Worker0]}},
+ handle_message(Exit, Worker1, #acc{workers=[Worker0, Worker1]})
+ ),
- ok.
+ % We bail if it was the last worker
+ ?assertEqual(
+ {stop, #acc{workers=[]}},
+ handle_message(Exit, Worker0, #acc{workers=[Worker0]})
+ )
+ end).
-handle_message_reply_test() ->
- start_meck_(),
- meck:expect(rexi, kill, fun(_, _) -> ok end),
+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 that we continue when we haven't met R yet
- ?assertEqual(
- {ok, Acc0#acc{
- workers=[Worker0, Worker1],
- replies=[fabric_util:kv(foo,1)]
- }},
- handle_message(foo, Worker2, Acc0)
- ),
-
- ?assertEqual(
- {ok, Acc0#acc{
- workers=[Worker0, Worker1],
- replies=[fabric_util:kv(bar,1), fabric_util:kv(foo,1)]
- }},
- handle_message(bar, Worker2, Acc0#acc{
- replies=[fabric_util:kv(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.
-
- ?assertEqual(
- {stop, Acc0#acc{workers=[],replies=[fabric_util:kv(foo,1)]}},
- handle_message(foo, Worker0, Acc0#acc{workers=[Worker0]})
- ),
-
- ?assertEqual(
- {stop, Acc0#acc{
- workers=[],
- replies=[fabric_util:kv(bar,1), fabric_util:kv(foo,1)]
- }},
- handle_message(bar, Worker0, Acc0#acc{
- workers=[Worker0],
- replies=[fabric_util:kv(foo,1)]
- })
- ),
-
- % Check that when R is met we stop with a new state and
- % a q_reply.
-
- ?assertEqual(
- {stop, Acc0#acc{
- workers=[],
- replies=[fabric_util:kv(foo,2)],
- state=r_met,
- q_reply=foo
- }},
- handle_message(foo, Worker1, Acc0#acc{
- workers=[Worker0, Worker1],
- replies=[fabric_util:kv(foo,1)]
- })
- ),
-
- ?assertEqual(
- {stop, Acc0#acc{
- workers=[],
- r=1,
- replies=[fabric_util:kv(foo,1)],
- state=r_met,
- q_reply=foo
- }},
- handle_message(foo, Worker0, Acc0#acc{r=1})
- ),
-
- ?assertEqual(
- {stop, Acc0#acc{
- workers=[],
- replies=[fabric_util:kv(bar,1), fabric_util:kv(foo,2)],
- state=r_met,
- q_reply=foo
- }},
- handle_message(foo, Worker0, Acc0#acc{
- workers=[Worker0],
- replies=[fabric_util:kv(bar,1), fabric_util:kv(foo,1)]
- })
- ),
-
- stop_meck_(),
- ok.
-
-read_repair_test() ->
- start_meck_(),
- meck:expect(couch_log, notice, fun(_, _) -> ok end),
- meck:expect(couch_stats, increment_counter, fun(_) -> ok end),
-
+ ?_test(begin
+ meck:expect(rexi, kill, 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_read_repair() ->
Foo1 = {ok, #doc{revs = {1,[<<"foo">>]}}},
Foo2 = {ok, #doc{revs = {2,[<<"foo2">>,<<"foo">>]}}},
NFM = {not_found, missing},
- % 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(begin
+ meck:expect(couch_log, notice, fun(_, _) -> ok end),
+ meck:expect(couch_stats, increment_counter, fun(_) -> ok end),
- % Test when we have nothing but errors
+ % 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)),
- Acc2 = #acc{replies=[fabric_util:kv(NFM, 1)]},
- ?assertEqual(NFM, read_repair(Acc2)),
+ 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)),
- Acc3 = #acc{replies=[fabric_util:kv(NFM,1), fabric_util:kv(foo,2)]},
- ?assertEqual(NFM, read_repair(Acc3)),
+ % Test when we have nothing but errors
+ Acc2 = #acc{replies=[fabric_util:kv(NFM, 1)]},
+ ?assertEqual(NFM, read_repair(Acc2)),
- Acc4 = #acc{replies=[fabric_util:kv(foo,1), fabric_util:kv(bar,1)]},
- ?assertEqual(bar, read_repair(Acc4)),
+ Acc3 = #acc{replies=[fabric_util:kv(NFM,1), fabric_util:kv(foo,2)]},
+ ?assertEqual(NFM, read_repair(Acc3)),
- stop_meck_(),
- ok.
+ Acc4 = #acc{replies=[fabric_util:kv(foo,1), fabric_util:kv(bar,1)]},
+ ?assertEqual(bar, read_repair(Acc4))
+ end).
-handle_response_quorum_met_test() ->
- start_meck_(),
- 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),
+t_handle_response_quorum_met() ->
Foo1 = {ok, #doc{revs = {1,[<<"foo">>]}}},
Foo2 = {ok, #doc{revs = {2,[<<"foo2">>,<<"foo">>]}}},
Bar1 = {ok, #doc{revs = {1,[<<"bar">>]}}},
- BasicOkAcc = #acc{
- state=r_met,
- replies=[fabric_util:kv(Foo1,2)],
- q_reply=Foo1
- },
- ?assertEqual(Foo1, handle_response(BasicOkAcc)),
+ ?_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),
- WithAncestorsAcc = #acc{
- 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{
- 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{
- 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.
-
- stop_meck_(),
- ok.
-
-get_doc_info_test() ->
- start_meck_(),
- meck:new([mem3, rexi_monitor, fabric_util]),
- 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)),
-
- meck:unload([mem3, rexi_monitor, fabric_util]),
- stop_meck_().
-
-start_meck_() ->
- meck:new([couch_log, rexi, fabric, couch_stats]).
-
-stop_meck_() ->
- meck:unload([couch_log, rexi, fabric, couch_stats]).
+ BasicOkAcc = #acc{
+ state=r_met,
+ replies=[fabric_util:kv(Foo1,2)],
+ q_reply=Foo1
+ },
+ ?assertEqual(Foo1, handle_response(BasicOkAcc)),
+
+ WithAncestorsAcc = #acc{
+ 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{
+ 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{
+ 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).
+
+-endif. \ No newline at end of file