diff options
author | Nick Vatamaniuc <vatamane@apache.org> | 2019-02-14 12:05:32 -0500 |
---|---|---|
committer | Nick Vatamaniuc <vatamane@apache.org> | 2019-02-15 16:42:43 -0500 |
commit | f3a98a134433a17f014ef8110282b537d0ac96f5 (patch) | |
tree | 34aa0ce5cee66ef13356cc1e5a3d2868e46d33d2 | |
parent | de3bec42d3f45e0e0316e5a3c558f1dd533a44c0 (diff) | |
download | couchdb-f3a98a134433a17f014ef8110282b537d0ac96f5.tar.gz |
Property tests for mem3_util:get_ring() function
-rw-r--r-- | src/mem3/src/mem3_util.erl | 8 | ||||
-rw-r--r-- | src/mem3/test/mem3_ring_prop_tests.erl | 84 |
2 files changed, 91 insertions, 1 deletions
diff --git a/src/mem3/src/mem3_util.erl b/src/mem3/src/mem3_util.erl index 8575e66b3..af30fb0d2 100644 --- a/src/mem3/src/mem3_util.erl +++ b/src/mem3/src/mem3_util.erl @@ -24,6 +24,7 @@ range_overlap/2, get_ring/1, get_ring/2, + get_ring/3, get_ring/4, non_overlapping_shards/1, non_overlapping_shards/3 @@ -411,10 +412,15 @@ non_overlapping_shards(Shards, Start, End) -> get_ring(Ranges) -> get_ring(Ranges, fun sort_ranges_fun/2, 0, ?RING_END). + get_ring(Ranges, SortFun) when is_function(SortFun, 2) -> get_ring(Ranges, SortFun, 0, ?RING_END). +get_ring(Ranges, Start, End) when is_integer(Start), is_integer(End), + Start >= 0, End >= 0, Start =< End -> + get_ring(Ranges, fun sort_ranges_fun/2, Start, End). + % Build a ring out of a list of possibly overlapping ranges. If a ring cannot % be built then [] is returned. Start and End supply a custom range such that % only intervals in that range will be considered. SortFun is a custom sorting @@ -423,7 +429,7 @@ get_ring(Ranges, SortFun) when is_function(SortFun, 2) -> % shortest ranges first (and thus have more total shards) or longer or any % other scheme. % -get_ring([], _SortFun, _Begin, _End) -> +get_ring([], _SortFun, _Start, _End) -> []; get_ring(Ranges, SortFun, Start, End) when is_function(SortFun, 2), is_integer(Start), is_integer(End), diff --git a/src/mem3/test/mem3_ring_prop_tests.erl b/src/mem3/test/mem3_ring_prop_tests.erl new file mode 100644 index 000000000..0fe6efb1f --- /dev/null +++ b/src/mem3/test/mem3_ring_prop_tests.erl @@ -0,0 +1,84 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(mem3_ring_prop_tests). + + +-include_lib("triq/include/triq.hrl"). +-triq(eunit). + +-compile(export_all). + + +% Properties + +prop_get_ring_with_connected_intervals() -> + ?FORALL({Start, End}, oneof(ranges()), + ?FORALL(Intervals, g_connected_intervals(Start, End), + mem3_util:get_ring(Intervals, Start, End) =/= [] + ) + ). + + +prop_get_ring_with_disconnected_intervals() -> + ?FORALL({Start, End}, oneof(ranges()), + ?FORALL(Intervals, g_disconnected_intervals(Start, End), + mem3_util:get_ring(Intervals, Start, End) =:= [] + ) + ). + + +% Generators + +ranges() -> + [{0,1}, {1, 10}, {0, 2 bsl 31 - 1}, {2 bsl 31 - 10, 2 bsl 31 - 1}]. + + +g_connected_intervals(Begin, End) -> + ?SIZED(Size, g_connected_intervals(Begin, End, 10 * Size)). + + +g_connected_intervals(Begin, End, Split) when Begin =< End -> + ?LET(N, choose(0, Split), + begin + if + N == 0 -> + [{Begin, End}]; + N > 0 -> + Ns = lists:seq(1, N - 1), + Bs = lists:usort([rand_range(Begin, End) || _ <- Ns]), + Es = [B - 1 || B <- Bs], + lists:zip([Begin] ++ Bs, Es ++ [End]) + end + end). + + +g_non_trivial_connected_intervals(Begin, End, Split) -> + ?SUCHTHAT(Connected, g_connected_intervals(Begin, End, Split), + length(Connected) > 1). + + +g_disconnected_intervals(Begin, End) -> + ?SIZED(Size, g_disconnected_intervals(Begin, End, Size)). + + +g_disconnected_intervals(Begin, End, Split) when Begin =< End -> + ?LET(Connected, g_non_trivial_connected_intervals(Begin, End, Split), + begin + I = triq_rnd:uniform(length(Connected)) - 1, + {Before, [_ | After]} = lists:split(I, Connected), + Before ++ After + end). + + +rand_range(B, E) -> + B + triq_rnd:uniform(E - B). |