You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/03/04 07:40:12 UTC
[couchdb] branch shard-split updated: [fixup|fabric_ring] add tests
for fabric_ring
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch shard-split
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/shard-split by this push:
new ba77fb1 [fixup|fabric_ring] add tests for fabric_ring
ba77fb1 is described below
commit ba77fb19766f5835f018030668ae2a1f44b8f2c8
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Mon Mar 4 02:40:01 2019 -0500
[fixup|fabric_ring] add tests for fabric_ring
---
src/fabric/src/fabric_ring.erl | 117 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/src/fabric/src/fabric_ring.erl b/src/fabric/src/fabric_ring.erl
index ac9bdbd..5a6ed1d 100644
--- a/src/fabric/src/fabric_ring.erl
+++ b/src/fabric/src/fabric_ring.erl
@@ -212,6 +212,123 @@ get_shard_replacements_test() ->
?assertEqual(Expect, Res).
+handle_response_basic_test() ->
+ Shard1 = mk_shard("n1", [0, 1]),
+ Shard2 = mk_shard("n1", [2, ?RING_END]),
+
+ Workers1 = fabric_dict:init([Shard1, Shard2], nil),
+
+ Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+ ?assertMatch({ok, {_, _}}, Result1),
+ {ok, {Workers2, Responses1}} = Result1,
+ ?assertEqual(fabric_dict:erase(Shard1, Workers1), Workers2),
+ ?assertEqual([{{0, 1}, Shard1, 42}], Responses1),
+
+ Result2 = handle_response(Shard2, 43, Workers2, Responses1, undefined),
+ ?assertEqual({stop, [{Shard1, 42}, {Shard2, 43}]}, Result2).
+
+
+handle_response_test_multiple_copies_test() ->
+ Shard1 = mk_shard("n1", [0, 1]),
+ Shard2 = mk_shard("n2", [0, 1]),
+ Shard3 = mk_shard("n1", [2, ?RING_END]),
+
+ Workers1 = fabric_dict:init([Shard1, Shard2, Shard3], nil),
+
+ Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+ ?assertMatch({ok, {_, _}}, Result1),
+ {ok, {Workers2, Responses1}} = Result1,
+
+ Result2 = handle_response(Shard2, 43, Workers2, Responses1, undefined),
+ ?assertMatch({ok, {_, _}}, Result2),
+ {ok, {Workers3, Responses2}} = Result2,
+
+ Result3 = handle_response(Shard3, 44, Workers3, Responses2, undefined),
+ % Use the value (42) to distinguish between [0, 1] copies. In reality
+ % they should have the same value but here we need to assert that copy
+ % that responded first is included in the ring.
+ ?assertEqual({stop, [{Shard1, 42}, {Shard3, 44}]}, Result3).
+
+
+handle_response_test_backtracking_test() ->
+ Shard1 = mk_shard("n1", [0, 5]),
+ Shard2 = mk_shard("n1", [10, ?RING_END]),
+ Shard3 = mk_shard("n2", [2, ?RING_END]),
+ Shard4 = mk_shard("n3", [0, 1]),
+
+ Workers1 = fabric_dict:init([Shard1, Shard2, Shard3, Shard3], nil),
+
+ Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+ ?assertMatch({ok, {_, _}}, Result1),
+ {ok, {Workers2, Responses1}} = Result1,
+
+ Result2 = handle_response(Shard2, 43, Workers2, Responses1, undefined),
+ ?assertMatch({ok, {_, _}}, Result2),
+ {ok, {Workers3, Responses2}} = Result2,
+
+ Result3 = handle_response(Shard3, 44, Workers3, Responses2, undefined),
+ ?assertMatch({ok, {_, _}}, Result3),
+ {ok, {Workers4, Responses3}} = Result3,
+
+ Result4 = handle_response(Shard4, 45, Workers4, Responses3, undefined),
+ ?assertEqual({stop, [{Shard4, 45}, {Shard3, 44}]}, Result4).
+
+
+handle_error_test() ->
+ Shard1 = mk_shard("n1", [0, 5]),
+ Shard2 = mk_shard("n1", [10, ?RING_END]),
+ Shard3 = mk_shard("n2", [2, ?RING_END]),
+ Shard4 = mk_shard("n3", [0, 1]),
+
+ Workers1 = fabric_dict:init([Shard1, Shard2, Shard3, Shard4], nil),
+
+ Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+ ?assertMatch({ok, {_, _}}, Result1),
+ {ok, {Workers2, Responses1}} = Result1,
+
+ Result2 = handle_error(Shard2, Workers2, Responses1),
+ ?assertMatch({ok, _}, Result2),
+ {ok, Workers3} = Result2,
+ ?assertEqual(fabric_dict:erase(Shard2, Workers2), Workers3),
+
+ Result3 = handle_response(Shard3, 44, Workers3, Responses1, undefined),
+ ?assertMatch({ok, {_, _}}, Result3),
+ {ok, {Workers4, Responses3}} = Result3,
+
+ ?assertEqual(error, handle_error(Shard4, Workers4, Responses3)).
+
+
+node_down_test() ->
+ Shard1 = mk_shard("n1", [0, 5]),
+ Shard2 = mk_shard("n1", [10, ?RING_END]),
+ Shard3 = mk_shard("n2", [2, ?RING_END]),
+ Shard4 = mk_shard("n3", [0, 1]),
+
+ Workers1 = fabric_dict:init([Shard1, Shard2, Shard3, Shard4], nil),
+
+ Result1 = handle_response(Shard1, 42, Workers1, [], undefined),
+ ?assertMatch({ok, {_, _}}, Result1),
+ {ok, {Workers2, Responses1}} = Result1,
+
+ Result2 = handle_response(Shard2, 43, Workers2, Responses1, undefined),
+ ?assertMatch({ok, {_, _}}, Result2),
+ {ok, {Workers3, Responses2}} = Result2,
+
+ Result3 = node_down(n1, Workers3, Responses2),
+ ?assertMatch({ok, _}, Result3),
+ {ok, Workers4} = Result3,
+ ?assertEqual([{Shard3, nil}, {Shard4, nil}], Workers4),
+
+ Result4 = handle_response(Shard3, 44, Workers4, Responses2, undefined),
+ ?assertMatch({ok, {_, _}}, Result4),
+ {ok, {Workers5, Responses3}} = Result4,
+
+ % Note: Shard3 was already processed, it's ok if n2 went down after
+ ?assertEqual({ok, [{Shard4, nil}]}, node_down(n2, Workers5, Responses3)),
+
+ ?assertEqual(error, node_down(n3, Workers5, Responses3)).
+
+
mk_cnts(Ranges) ->
Shards = lists:map(fun mk_shard/1, Ranges),
orddict:from_list([{Shard,nil} || Shard <- Shards]).