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]).