Filter out not_found replies when #doc{} is found
There are places in the codebase which assume that the return from
open_revs is always a list with one element in it. Fix the regression
introduced in 9a1d0c5 by filtering out not_found replies when any of the
returns contains #doc{}.
COUCHDB-3026
diff --git a/src/fabric_doc_open_revs.erl b/src/fabric_doc_open_revs.erl
index 3534830..0924313 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, {ok, Reply}} ->
- {ok, Reply};
+ {ok, filter_reply(Reply)};
{timeout, #state{workers=DefunctWorkers}} ->
fabric_util:log_timeout(DefunctWorkers, "open_revs"),
{error, timeout};
@@ -230,7 +230,11 @@
dict_format_replies(Dict) ->
lists:sort([Reply || {_, {Reply, _}} <- Dict]).
-
+filter_reply(Replies) ->
+ case [{ok, Doc} || {ok, Doc} <- Replies] of
+ [] -> Replies;
+ Filtered -> Filtered
+ end.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
@@ -264,7 +268,9 @@
foo1() -> {ok, #doc{revs = {1, [<<"foo">>]}}}.
foo2() -> {ok, #doc{revs = {2, [<<"foo2">>, <<"foo">>]}}}.
+fooNF() -> {{not_found, missing}, {1,<<"foo">>}}.
bar1() -> {ok, #doc{revs = {1, [<<"bar">>]}}}.
+barNF() -> {{not_found, missing}, {1,<<"bar">>}}.
bazNF() -> {{not_found, missing}, {1,<<"baz">>}}.
baz1() -> {ok, #doc{revs = {1, [<<"baz">>]}}}.
@@ -287,7 +293,9 @@
check_latest_true(),
check_ancestor_counted_in_quorum(),
check_not_found_counts_for_descendant(),
- check_worker_error_skipped()
+ check_worker_error_skipped(),
+ check_not_found_replies_are_removed_when_doc_found(),
+ check_not_found_returned_when_doc_not_found()
]
}.
@@ -447,5 +455,19 @@
?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()],
+ ?assertEqual(Expect, filter_reply(Replies))
+ end).
+
+check_not_found_returned_when_doc_not_found() ->
+ ?_test(begin
+ Replies = [fooNF(), barNF(), bazNF()],
+ Expect = [fooNF(), barNF(), bazNF()],
+ ?assertEqual(Expect, filter_reply(Replies))
+ end).
+
-endif.