Getting closer to understanding why test coverage appears so poor, part 2
This commit is contained in:
parent
342a972543
commit
da2bad564f
1 changed files with 48 additions and 25 deletions
|
@ -24,6 +24,7 @@
|
||||||
-include("machi.hrl").
|
-include("machi.hrl").
|
||||||
|
|
||||||
-define(MGR, machi_chain_manager).
|
-define(MGR, machi_chain_manager).
|
||||||
|
-define(D(X), io:format(user, "~s ~p\n", [??X, X])).
|
||||||
|
|
||||||
-export([]).
|
-export([]).
|
||||||
|
|
||||||
|
@ -129,11 +130,20 @@ extract_upi_transitions([P1, P2|T]) ->
|
||||||
Trans = {P1#projection.upi, P2#projection.upi},
|
Trans = {P1#projection.upi, P2#projection.upi},
|
||||||
[Trans|extract_upi_transitions([P2|T])].
|
[Trans|extract_upi_transitions([P2|T])].
|
||||||
|
|
||||||
|
find_common_prefix([], _) ->
|
||||||
|
[];
|
||||||
|
find_common_prefix(_, []) ->
|
||||||
|
[];
|
||||||
|
find_common_prefix([H|L1], [H|L2]) ->
|
||||||
|
[H|find_common_prefix(L1, L2)];
|
||||||
|
find_common_prefix(_, _) ->
|
||||||
|
[].
|
||||||
|
|
||||||
calc_projection_test_() ->
|
calc_projection_test_() ->
|
||||||
{timeout, 60,
|
{timeout, 60,
|
||||||
fun() ->
|
fun() ->
|
||||||
%% Nodes = [a,b,c,d],
|
%% Nodes = [a,b,c,d],
|
||||||
Nodes = [a,b],
|
Nodes = [a,b,c],
|
||||||
Cs = combinations(Nodes),
|
Cs = combinations(Nodes),
|
||||||
Combos = lists:sort([{UPI1, UPI2} || UPI1 <- Cs, UPI2 <- Cs]),
|
Combos = lists:sort([{UPI1, UPI2} || UPI1 <- Cs, UPI2 <- Cs]),
|
||||||
timer:sleep(500),
|
timer:sleep(500),
|
||||||
|
@ -143,14 +153,14 @@ calc_projection_test_() ->
|
||||||
[], PsUPI1, Nodes -- PsUPI1, []),
|
[], PsUPI1, Nodes -- PsUPI1, []),
|
||||||
P2 = ?MGR:make_projection(3, 2, <<>>, HdNd, Nodes,
|
P2 = ?MGR:make_projection(3, 2, <<>>, HdNd, Nodes,
|
||||||
[], PsUPI2, Nodes -- PsUPI2, []),
|
[], PsUPI2, Nodes -- PsUPI2, []),
|
||||||
Res = case (catch projection_transition_is_sane(P1, P2)) of
|
Res = case projection_transition_is_sane(P1, P2) of
|
||||||
true -> true;
|
true -> true;
|
||||||
_ -> false
|
_ -> false
|
||||||
end,
|
end,
|
||||||
{Res, UPI1, UPI2}
|
{Res, PsUPI1, PsUPI2}
|
||||||
end || HdNd <- Nodes,
|
end || HdNd <- Nodes,
|
||||||
{UPI1,UPI2} <- Combos,
|
{UPI1,UPI2} <- Combos,
|
||||||
%% We assume that the author appears in any
|
%% We assume that the author appears in any UPI list
|
||||||
UPI1 /= [],
|
UPI1 /= [],
|
||||||
UPI2 /= [],
|
UPI2 /= [],
|
||||||
%% HdNd is the author for all of these
|
%% HdNd is the author for all of these
|
||||||
|
@ -159,30 +169,24 @@ calc_projection_test_() ->
|
||||||
lists:member(HdNd, UPI2),
|
lists:member(HdNd, UPI2),
|
||||||
PsUPI1 <- perms(UPI1),
|
PsUPI1 <- perms(UPI1),
|
||||||
PsUPI2 <- perms(UPI2)],
|
PsUPI2 <- perms(UPI2)],
|
||||||
%% HeadNode = hd(Nodes),
|
|
||||||
OKs = [begin
|
OKs = [begin
|
||||||
{UPI1,UPI2}
|
{UPI1,UPI2}
|
||||||
end || {true, UPI1, UPI2} <- Rs],
|
end || {true, UPI1, UPI2} <- Rs],
|
||||||
%% not sets:is_disjoint(sets:from_list(UPI1),
|
|
||||||
%% sets:from_list(UPI2))
|
|
||||||
%% orelse UPI1 == [] orelse UPI2 == []],
|
|
||||||
io:format(user, "OKs = ~p\n", [lists:usort(OKs)]),
|
io:format(user, "OKs = ~p\n", [lists:usort(OKs)]),
|
||||||
%% OKs = [{UPI1,UPI2} || {true, UPI1, UPI2} <- Rs,
|
|
||||||
%% not sets:is_disjoint(sets:from_list(UPI1),
|
|
||||||
%% sets:from_list(UPI2))],
|
|
||||||
Tab = ets:new(count, [public, set, {keypos, 1}]),
|
Tab = ets:new(count, [public, set, {keypos, 1}]),
|
||||||
[ets:insert(Tab, {Transition, 0}) || Transition <- OKs],
|
[ets:insert(Tab, {Transition, 0}) || Transition <- OKs],
|
||||||
true = eqc:quickcheck(
|
true = eqc:quickcheck(
|
||||||
eqc:numtests(500, ?QC_OUT(prop_calc_projection(Nodes, Tab)))),
|
eqc:numtests(3500,
|
||||||
|
?QC_OUT(prop_calc_projection(Nodes, Tab)))),
|
||||||
NotCounted = [Transition || {Transition, 0} <- ets:tab2list(Tab)],
|
NotCounted = [Transition || {Transition, 0} <- ets:tab2list(Tab)],
|
||||||
Counted = [X || {_, N}=X <- ets:tab2list(Tab),
|
_Counted = [X || {_, N}=X <- ets:tab2list(Tab),
|
||||||
N > 0],
|
N > 0],
|
||||||
timer:sleep(100),
|
timer:sleep(100),
|
||||||
io:format(user, "OKs length = ~p\n", [length(OKs)]),
|
io:format(user, "\tNotCounted = ~p\n", [NotCounted]),
|
||||||
io:format(user, "Transitions hit = ~p\n", [length(OKs) - length(NotCounted)]),
|
io:format(user, "\tOKs length = ~p\n", [length(OKs)]),
|
||||||
io:format(user, "Transitions = ~p\n", [lists:sort(Counted)]),
|
io:format(user, "\tTransitions hit = ~p\n", [length(OKs) - length(NotCounted)]),
|
||||||
io:format(user, "NotCounted length = ~p\n", [length(NotCounted)]),
|
%% io:format(user, "\tTransitions = ~p\n", [lists:sort(_Counted)]),
|
||||||
io:format(user, "NotCounted = ~p\n", [NotCounted]),
|
io:format(user, "\tNotCounted length = ~p\n", [length(NotCounted)]),
|
||||||
ok
|
ok
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
|
@ -265,16 +269,15 @@ projection_transition_is_sane(
|
||||||
true = lists:member(AuthorServer2, UPI_list2 ++ Repairing_list2),
|
true = lists:member(AuthorServer2, UPI_list2 ++ Repairing_list2),
|
||||||
|
|
||||||
%% Additions to the UPI chain may only be at the tail
|
%% Additions to the UPI chain may only be at the tail
|
||||||
UPI_common_prefix =
|
UPI_common_prefix = find_common_prefix(UPI_list1, UPI_list2),
|
||||||
lists:takewhile(fun(X) -> sets:is_element(X, UPIS2) end, UPI_list1),
|
|
||||||
if UPI_common_prefix == [] ->
|
if UPI_common_prefix == [] ->
|
||||||
if UPI_list1 == [] orelse UPI_list2 == [] ->
|
if UPI_list1 == [] orelse UPI_list2 == [] ->
|
||||||
%% If the common prefix is empty, then one of the inputs
|
%% If the common prefix is empty, then one of the
|
||||||
%% must be empty.
|
%% inputs must be empty.
|
||||||
true;
|
true;
|
||||||
true ->
|
true ->
|
||||||
%% Otherwise, we have a case of UPI changing from one
|
%% Otherwise, we have a case of UPI changing from
|
||||||
%% of these two situations:
|
%% one of these two situations:
|
||||||
%%
|
%%
|
||||||
%% UPI_list1 -> UPI_list2
|
%% UPI_list1 -> UPI_list2
|
||||||
%% [d,c,b,a] -> [c,a]
|
%% [d,c,b,a] -> [c,a]
|
||||||
|
@ -380,6 +383,26 @@ fail2_smoke_test() ->
|
||||||
|
|
||||||
true.
|
true.
|
||||||
|
|
||||||
|
fail3_smoke_test() ->
|
||||||
|
Nodes = [a,b],
|
||||||
|
UPI1 = [a,b],
|
||||||
|
UPI2 = [b,a],
|
||||||
|
[begin
|
||||||
|
PsUPI1 = UPI1,
|
||||||
|
PsUPI2 = UPI2,
|
||||||
|
P1 = ?MGR:make_projection(2, 1, <<>>, HdNd, Nodes,
|
||||||
|
[], PsUPI1, Nodes -- PsUPI1, []),
|
||||||
|
P2 = ?MGR:make_projection(3, 2, <<>>, HdNd, Nodes,
|
||||||
|
[], PsUPI2, Nodes -- PsUPI2, []),
|
||||||
|
Res = case projection_transition_is_sane(P1, P2) of
|
||||||
|
true -> true;
|
||||||
|
_ -> false
|
||||||
|
end,
|
||||||
|
{Res, HdNd, PsUPI1, PsUPI2} = {false, HdNd, PsUPI1, PsUPI2}
|
||||||
|
end || HdNd <- Nodes],
|
||||||
|
|
||||||
|
true.
|
||||||
|
|
||||||
%% aaa_smoke_test() ->
|
%% aaa_smoke_test() ->
|
||||||
%% L = [a,b,c,d],
|
%% L = [a,b,c,d],
|
||||||
%% Cs = combinations(L),
|
%% Cs = combinations(L),
|
||||||
|
@ -391,7 +414,7 @@ fail2_smoke_test() ->
|
||||||
%% [], X, L -- X, []),
|
%% [], X, L -- X, []),
|
||||||
%% P2 = ?MGR:make_projection(3, 2, <<>>, a, L,
|
%% P2 = ?MGR:make_projection(3, 2, <<>>, a, L,
|
||||||
%% [], Y, L -- Y, []),
|
%% [], Y, L -- Y, []),
|
||||||
%% Res = case (catch projection_transition_is_sane(P1, P2)) of
|
%% Res = case projection_transition_is_sane(P1, P2) of
|
||||||
%% true -> true;
|
%% true -> true;
|
||||||
%% _ -> false
|
%% _ -> false
|
||||||
%% end,
|
%% end,
|
||||||
|
|
Loading…
Reference in a new issue