Merge remote branch 'cloudant:71693-fix-filter-out-not-found'
This closes #65
Signed-off-by: Eric Avdey <eiri@eiri.ca>
diff --git a/src/fabric_doc_open_revs.erl b/src/fabric_doc_open_revs.erl
index 663860a..8dad2c2 100644
--- a/src/fabric_doc_open_revs.erl
+++ b/src/fabric_doc_open_revs.erl
@@ -47,7 +47,7 @@
RexiMon = fabric_util:create_monitors(Workers),
try fabric_util:recv(Workers, #shard.ref, fun handle_message/3, State) of
{ok, Replies} ->
- {ok, filter_reply(Replies)};
+ {ok, Replies};
{timeout, #state{workers=DefunctWorkers}} ->
fabric_util:log_timeout(DefunctWorkers, "open_revs"),
{error, timeout};
@@ -214,7 +214,8 @@
tree_format_replies(Replies);
format_reply(false, Replies) ->
- dict_format_replies(Replies).
+ Filtered = filter_reply(Replies),
+ dict_format_replies(Filtered).
tree_format_replies(RevTree) ->
@@ -233,10 +234,19 @@
lists:sort([Reply || {_, {Reply, _}} <- Dict]).
filter_reply(Replies) ->
- case [{ok, Doc} || {ok, Doc} <- Replies] of
- [] -> Replies;
- Filtered -> Filtered
- end.
+ AllFoundRevs = lists:foldl(fun
+ ({{{not_found, missing}, _}, _}, Acc) ->
+ Acc;
+ ({{_, {Pos, [Rev | _]}}, _}, Acc) ->
+ [{Pos, Rev} | Acc]
+ end, [], Replies),
+ %% keep not_found replies only for the revs that don't also have doc reply
+ lists:filter(fun
+ ({{{not_found, missing}, Rev}, _}) ->
+ not lists:member(Rev, AllFoundRevs);
+ (_) ->
+ true
+ end, Replies).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
@@ -297,6 +307,7 @@
check_not_found_counts_for_descendant(),
check_worker_error_skipped(),
check_not_found_replies_are_removed_when_doc_found(),
+ check_not_found_returned_when_one_of_docs_not_found(),
check_not_found_returned_when_doc_not_found()
]
}.
@@ -457,19 +468,35 @@
?assertEqual(Expect, handle_message(Msg3, w2, S2))
end).
+
check_not_found_replies_are_removed_when_doc_found() ->
?_test(begin
- Replies = [foo1(), bar1(), bazNF()],
- Expect = [foo1(), bar1()],
+ Replies = replies_to_dict([foo1(), bar1(), fooNF()]),
+ Expect = replies_to_dict([foo1(), bar1()]),
+ ?assertEqual(Expect, filter_reply(Replies))
+ end).
+
+check_not_found_returned_when_one_of_docs_not_found() ->
+ ?_test(begin
+ Replies = replies_to_dict([foo1(), foo2(), barNF()]),
+ Expect = replies_to_dict([foo1(), foo2(), barNF()]),
?assertEqual(Expect, filter_reply(Replies))
end).
check_not_found_returned_when_doc_not_found() ->
?_test(begin
- Replies = [fooNF(), barNF(), bazNF()],
- Expect = [fooNF(), barNF(), bazNF()],
+ Replies = replies_to_dict([fooNF(), barNF(), bazNF()]),
+ Expect = replies_to_dict([fooNF(), barNF(), bazNF()]),
?assertEqual(Expect, filter_reply(Replies))
end).
+replies_to_dict(Replies) ->
+ [reply_to_element(R) || R <- Replies].
+
+reply_to_element({ok, #doc{revs = Revs}} = Reply) ->
+ {_, [Rev | _]} = Revs,
+ {{Rev, Revs}, {Reply, 1}};
+reply_to_element(Reply) ->
+ {Reply, {Reply, 1}}.
-endif.