2015-04-06 05:16:20 +00:00
|
|
|
%% -------------------------------------------------------------------
|
|
|
|
%%
|
|
|
|
%% Machi: a small village of replicated files
|
|
|
|
%%
|
|
|
|
%% Copyright (c) 2014 Basho Technologies, Inc. All Rights Reserved.
|
|
|
|
%%
|
|
|
|
%% This file is provided to you 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(machi_chain_manager1_test).
|
|
|
|
|
|
|
|
-include("machi.hrl").
|
|
|
|
-include("machi_projection.hrl").
|
|
|
|
|
|
|
|
-define(MGR, machi_chain_manager1).
|
|
|
|
|
|
|
|
-define(D(X), io:format(user, "~s ~p\n", [??X, X])).
|
|
|
|
-define(Dw(X), io:format(user, "~s ~w\n", [??X, X])).
|
2015-04-06 11:07:39 +00:00
|
|
|
-define(FLU_C, machi_flu1_client).
|
|
|
|
-define(FLU_PC, machi_proxy_flu1_client).
|
2015-04-06 05:16:20 +00:00
|
|
|
|
|
|
|
-export([]).
|
|
|
|
|
|
|
|
-ifdef(TEST).
|
|
|
|
|
|
|
|
-ifdef(EQC).
|
|
|
|
-include_lib("eqc/include/eqc.hrl").
|
|
|
|
%% -include_lib("eqc/include/eqc_statem.hrl").
|
|
|
|
-define(QC_OUT(P),
|
|
|
|
eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)).
|
|
|
|
-endif.
|
|
|
|
|
|
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
|
-compile(export_all).
|
|
|
|
|
2015-07-02 15:59:04 +00:00
|
|
|
%% @doc Create a summary report of all of the *private* projections of
|
|
|
|
%% each of the FLUs in the chain, and create a summary for each
|
|
|
|
%% epoch number.
|
|
|
|
%%
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
%% Report format: list({EpochNumber:non_neg_integer(), Report:rpt()})
|
|
|
|
%% rpt(): {'ok_disjoint', unique_upi_repair_lists()} |
|
|
|
|
%% {'bummer_NOT_DISJOINT', {flat(), summaries()}
|
|
|
|
%% unique_upi_repair_lists(): list(upi_and_repair_lists_concatenated())
|
|
|
|
%% flat(): debugging term; any duplicate in this list is an invalid FLU.
|
2015-07-07 14:03:14 +00:00
|
|
|
%% summaries(): list({FLU, ProjectionSummary:string() | 'not_in_this_epoch'})
|
2015-07-02 15:59:04 +00:00
|
|
|
%%
|
2015-06-02 09:10:45 +00:00
|
|
|
%% Example:
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
%%
|
|
|
|
%% [{1,{ok_disjoint,[[a,b,c]]}},
|
|
|
|
%% {4,{ok_disjoint,[[a,b,c]]}},
|
|
|
|
%% {6,{ok_disjoint,[[a,b,c]]}},
|
|
|
|
%% {16,{ok_disjoint,[[a,b,c]]}},
|
|
|
|
%% {22,{ok_disjoint,[[b]]}},
|
|
|
|
%% {1174,
|
|
|
|
%% {bummer_NOT_DISJOINT,{[a,a,b],
|
|
|
|
%% [{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
|
|
|
|
%% {b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
|
|
|
|
%% ...]
|
2015-06-02 09:10:45 +00:00
|
|
|
|
2015-04-06 05:16:20 +00:00
|
|
|
unanimous_report(Namez) ->
|
|
|
|
UniquePrivateEs =
|
|
|
|
lists:usort(lists:flatten(
|
2015-04-09 12:32:04 +00:00
|
|
|
[element(2, ?FLU_PC:list_all_projections(FLU, private)) ||
|
2015-04-06 05:16:20 +00:00
|
|
|
{_FLUName, FLU} <- Namez])),
|
2015-07-02 15:59:04 +00:00
|
|
|
[{Epoch, unanimous_report(Epoch, Namez)} || Epoch <- UniquePrivateEs,
|
|
|
|
Epoch /= 0].
|
2015-04-06 05:16:20 +00:00
|
|
|
|
|
|
|
unanimous_report(Epoch, Namez) ->
|
2015-07-02 15:59:04 +00:00
|
|
|
FLU_Projs = [{FLUName,
|
|
|
|
case ?FLU_PC:read_projection(FLU, private, Epoch) of
|
|
|
|
{ok, T} ->
|
2015-09-04 08:17:49 +00:00
|
|
|
T;
|
2015-07-02 15:59:04 +00:00
|
|
|
_Else ->
|
|
|
|
not_in_this_epoch
|
|
|
|
end} || {FLUName, FLU} <- Namez],
|
2015-07-03 10:21:41 +00:00
|
|
|
unanimous_report2(FLU_Projs).
|
2015-07-02 15:59:04 +00:00
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
unanimous_report2(FLU_Projs) ->
|
2015-07-02 15:59:04 +00:00
|
|
|
ProjsSumms = [{FLU, if is_tuple(P) ->
|
|
|
|
Summ = machi_projection:make_summary(P),
|
|
|
|
lists:flatten(io_lib:format("~w", [Summ]));
|
|
|
|
is_atom(P) ->
|
|
|
|
P
|
|
|
|
end} || {FLU, P} <- FLU_Projs],
|
2015-04-06 05:16:20 +00:00
|
|
|
UPI_R_Sums = [{Proj#projection_v1.upi, Proj#projection_v1.repairing,
|
|
|
|
Proj#projection_v1.epoch_csum} ||
|
2015-07-02 15:59:04 +00:00
|
|
|
{_FLUname, Proj} <- FLU_Projs,
|
2015-04-06 05:16:20 +00:00
|
|
|
is_record(Proj, projection_v1)],
|
|
|
|
UniqueUPIs = lists:usort([UPI || {UPI, _Repairing, _CSum} <- UPI_R_Sums]),
|
2015-07-07 14:03:14 +00:00
|
|
|
if length(UniqueUPIs) =< 1 ->
|
|
|
|
{ok_disjoint, UniqueUPIs};
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
true ->
|
2015-07-07 14:03:14 +00:00
|
|
|
Flat = lists:flatten(UniqueUPIs),
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
case lists:usort(Flat) == lists:sort(Flat) of
|
|
|
|
true ->
|
2015-07-07 14:03:14 +00:00
|
|
|
{ok_disjoint, UniqueUPIs};
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
false ->
|
|
|
|
{bummer_NOT_DISJOINT, {lists:sort(Flat), ProjsSumms}}
|
|
|
|
end
|
|
|
|
end.
|
2015-04-06 05:16:20 +00:00
|
|
|
|
|
|
|
all_reports_are_disjoint(Report) ->
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
case [X || {_Epoch, Tuple}=X <- Report,
|
|
|
|
element(1, Tuple) /= ok_disjoint] of
|
|
|
|
[] ->
|
|
|
|
true;
|
|
|
|
Else ->
|
|
|
|
Else
|
|
|
|
end.
|
2015-04-06 05:16:20 +00:00
|
|
|
|
|
|
|
-ifndef(PULSE).
|
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
simple_chain_state_transition_is_sane_test_() ->
|
2015-07-07 09:32:04 +00:00
|
|
|
{timeout, 60, fun() -> simple_chain_state_transition_is_sane_test2() end}.
|
2015-07-03 10:21:41 +00:00
|
|
|
|
|
|
|
simple_chain_state_transition_is_sane_test2() ->
|
2015-07-02 15:59:04 +00:00
|
|
|
%% All: A list of all FLUS for a particular test
|
|
|
|
%% UPI1: some combination of All that represents UPI1
|
|
|
|
%% Repair1: Some combination of (All -- UP1) that represents Repairing1
|
2015-07-03 10:21:41 +00:00
|
|
|
%% ... then we test check_simple_chain_state_transition_is_sane() with all
|
2015-07-02 15:59:04 +00:00
|
|
|
%% possible UPI1 and Repair1.
|
2015-07-03 10:21:41 +00:00
|
|
|
[true = check_simple_chain_state_transition_is_sane(UPI1, Repair1) ||
|
2015-07-02 15:59:04 +00:00
|
|
|
%% The five elements below runs on my MacBook Pro in about 4.8 seconds
|
|
|
|
%% All <- [ [a], [a,b], [a,b,c], [a,b,c,d], [a,b,c,d,e] ],
|
2015-07-07 09:32:04 +00:00
|
|
|
%% For elements on the same MBP is about 0.15 seconds.
|
2015-07-02 15:59:04 +00:00
|
|
|
All <- [ [a], [a,b], [a,b,c], [a,b,c,d] ],
|
2015-07-03 10:21:41 +00:00
|
|
|
UPI1 <- machi_util:combinations(All),
|
|
|
|
Repair1 <- machi_util:combinations(All -- UPI1)].
|
2015-07-02 15:59:04 +00:00
|
|
|
|
|
|
|
%% Given a UPI1 and Repair1 list, we calculate all possible good UPI2
|
|
|
|
%% lists. For all good {UPI1, Repair1} -> UPI2 transitions, then the
|
|
|
|
%% simple_chain_state_transition_is_sane() function must be true. For
|
|
|
|
%% all other UPI2 transitions, simple_chain_state_transition_is_sane()
|
|
|
|
%% must be false.
|
|
|
|
%%
|
|
|
|
%% We include adding an extra possible participant, 'bogus', to the
|
|
|
|
%% list of all possible UPI2 transitions, just to demonstrate that
|
|
|
|
%% adding an extra element/participant/thingie is never sane.
|
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
check_simple_chain_state_transition_is_sane([], []) ->
|
2015-07-02 15:59:04 +00:00
|
|
|
true;
|
2015-07-03 10:21:41 +00:00
|
|
|
check_simple_chain_state_transition_is_sane(UPI1, Repair1) ->
|
|
|
|
Good_UPI2s = [ X ++ Y || X <- machi_util:ordered_combinations(UPI1),
|
|
|
|
Y <- machi_util:ordered_combinations(Repair1)],
|
|
|
|
All_UPI2s = machi_util:combinations(lists:usort(UPI1 ++ Repair1) ++
|
|
|
|
[bogus]),
|
2015-07-02 15:59:04 +00:00
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
[true = ?MGR:simple_chain_state_transition_is_sane(UPI1, Repair1, UPI2) ||
|
2015-07-02 15:59:04 +00:00
|
|
|
UPI2 <- Good_UPI2s],
|
2015-07-03 10:21:41 +00:00
|
|
|
[false = ?MGR:simple_chain_state_transition_is_sane(UPI1, Repair1, UPI2) ||
|
2015-07-02 15:59:04 +00:00
|
|
|
UPI2 <- (All_UPI2s -- Good_UPI2s)],
|
|
|
|
|
|
|
|
true.
|
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
-ifdef(EQC).
|
|
|
|
|
2015-07-07 09:32:04 +00:00
|
|
|
%% This QuickCheck property is crippled: because the old chain state
|
|
|
|
%% transition check, chain_mgr_legacy:projection_transition_is_sane(),
|
|
|
|
%% is so buggy and the new check is (apparently) so much better, I
|
|
|
|
%% have changed the ?WHENFAIL() criteria to check for either agreement
|
|
|
|
%% _or_ a case where the legacy check says true but the new check says
|
|
|
|
%% false.
|
|
|
|
%%
|
|
|
|
%% On my MacBook Pro, less than 1000 tests are required to find at
|
|
|
|
%% least one problem case for the legacy check that the new check is
|
|
|
|
%% correct for. Running for two seconds can do about 3,500 test
|
|
|
|
%% cases.
|
|
|
|
|
|
|
|
compare_eqc_setup_test_() ->
|
|
|
|
%% Silly QuickCheck can take a long time to start up, check its
|
|
|
|
%% license, etcetc.
|
|
|
|
%% machi_chain_manager1_test: compare_eqc_setup_test...[1.788 s] ok
|
|
|
|
{timeout, 30,
|
|
|
|
fun() -> eqc:quickcheck(eqc:testing_time(0.1, true)) end}.
|
|
|
|
|
|
|
|
-define(COMPARE_TIMEOUT, 1.2).
|
|
|
|
%% -define(COMPARE_TIMEOUT, 4.8).
|
|
|
|
|
|
|
|
compare_legacy_with_v2_chain_transition_check1_test() ->
|
|
|
|
eqc:quickcheck(
|
|
|
|
?QC_OUT(
|
|
|
|
eqc:testing_time(
|
|
|
|
?COMPARE_TIMEOUT,
|
|
|
|
prop_compare_legacy_with_v2_chain_transition_check(primitive)))).
|
|
|
|
|
|
|
|
compare_legacy_with_v2_chain_transition_check2_test() ->
|
|
|
|
eqc:quickcheck(
|
|
|
|
?QC_OUT(
|
|
|
|
eqc:testing_time(
|
|
|
|
?COMPARE_TIMEOUT,
|
|
|
|
prop_compare_legacy_with_v2_chain_transition_check(primitive)))).
|
|
|
|
|
2015-07-03 14:37:36 +00:00
|
|
|
prop_compare_legacy_with_v2_chain_transition_check() ->
|
WIP: 1st part of moving old chain state transtion code to new
Ha, famous last words, amirite?
%% The chain sequence/order checks at the bottom of this function aren't
%% as easy-to-read as they ought to be. However, I'm moderately confident
%% that it isn't buggy. TODO: refactor them for clarity.
So, now machi_chain_manager1:projection_transition_is_sane() is using
newer, far less buggy code to make sanity decisions.
TODO: Add support for Retrospective mode. TODO is it really needed?
Examples of how the old code sucks and the new code sucks less.
138> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxxx..x.xxxxxx..x.x....x..xx........................................................Failed! After 69 tests.
[a,b,c]
{c,[a,b,c],[c,b],b,[b,a],[b,a,c]}
Old_res ([335,192,166,160,153,139]): true
New_res: false (why line [1936])
Shrinking xxxxxxxxxxxx.xxxxxxx.xxx.xxxxxxxxxxxxxxxxx(3 times)
[a,b,c]
%% {Author1,UPI1, Repair1,Author2,UPI2, Repair2} %%
{c, [a,b,c],[], a, [b,a],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: we've swapped order of a & b, which is bad.
139> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxx..x...xx..........xxx..x..............x......x............................................(x10)...(x1)........Failed! After 120 tests.
[b,c,a]
{c,[c,a],[c],a,[a,b],[b,a]}
Old_res ([335,192,185,160,153,123]): true
New_res: false (why line [1936])
Shrinking xx.xxxxxx.x.xxxxxxxx.xxxxxxxxxxx(4 times)
[b,a,c]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{a, [c], [], c, [c,b],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: b wasn't repairing in the previous state.
150> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxx....x...xxxxx..xx.....x.......xxx..x.......xxx...................x................x......(x10).....(x1)........xFailed! After 130 tests.
[c,a,b]
{b,[c],[b,a,c],c,[c,a,b],[b]}
Old_res ([335,214,185,160,153,147]): true
New_res: false (why line [1936])
Shrinking xxxx.x.xxx.xxxxxxx.xxxxxxxxx(4 times)
[c,b,a]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{c, [c], [a,b], c, [c,b,a],[]}
Old_res ([335,328,185,160,153,111]): true
New_res: false (why line [1981,1679])
false
Old code is wrong: a & b were repairing but UPI2 has a & b in the wrong order.
2015-07-03 15:01:54 +00:00
|
|
|
prop_compare_legacy_with_v2_chain_transition_check(primitive).
|
|
|
|
|
|
|
|
prop_compare_legacy_with_v2_chain_transition_check(Style) ->
|
2015-07-03 10:21:41 +00:00
|
|
|
%% ?FORALL(All, nonempty(list([a,b,c,d,e])),
|
2015-07-07 09:32:04 +00:00
|
|
|
?FORALL(All, non_empty(some([a,b,c,d])),
|
2015-07-03 10:21:41 +00:00
|
|
|
?FORALL({Author1, UPI1, Repair1x, Author2, UPI2, Repair2x},
|
|
|
|
{elements(All),some(All),some(All),elements(All),some(All),some(All)},
|
|
|
|
?IMPLIES(length(lists:usort(UPI1 ++ Repair1x)) > 0 andalso
|
|
|
|
length(lists:usort(UPI2 ++ Repair2x)) > 0,
|
|
|
|
begin
|
|
|
|
MembersDict = orddict:from_list([{X, #p_srvr{name=X}} || X <- All]),
|
|
|
|
Repair1 = Repair1x -- UPI1,
|
|
|
|
Down1 = All -- (UPI1 ++ Repair1),
|
|
|
|
Repair2 = Repair2x -- UPI2,
|
|
|
|
Down2 = All -- (UPI2 ++ Repair2),
|
|
|
|
P1 = machi_projection:new(1, Author1, MembersDict,
|
|
|
|
Down1, UPI1, Repair1, []),
|
|
|
|
P2 = machi_projection:new(2, Author2, MembersDict,
|
|
|
|
Down2, UPI2, Repair2, []),
|
2015-07-03 14:37:36 +00:00
|
|
|
Old_res = chain_mgr_legacy:projection_transition_is_sane(
|
2015-07-03 10:21:41 +00:00
|
|
|
P1, P2, Author1, false),
|
|
|
|
Old_p = case Old_res of true -> true;
|
|
|
|
_ -> false
|
|
|
|
end,
|
WIP: 1st part of moving old chain state transtion code to new
Ha, famous last words, amirite?
%% The chain sequence/order checks at the bottom of this function aren't
%% as easy-to-read as they ought to be. However, I'm moderately confident
%% that it isn't buggy. TODO: refactor them for clarity.
So, now machi_chain_manager1:projection_transition_is_sane() is using
newer, far less buggy code to make sanity decisions.
TODO: Add support for Retrospective mode. TODO is it really needed?
Examples of how the old code sucks and the new code sucks less.
138> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxxx..x.xxxxxx..x.x....x..xx........................................................Failed! After 69 tests.
[a,b,c]
{c,[a,b,c],[c,b],b,[b,a],[b,a,c]}
Old_res ([335,192,166,160,153,139]): true
New_res: false (why line [1936])
Shrinking xxxxxxxxxxxx.xxxxxxx.xxx.xxxxxxxxxxxxxxxxx(3 times)
[a,b,c]
%% {Author1,UPI1, Repair1,Author2,UPI2, Repair2} %%
{c, [a,b,c],[], a, [b,a],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: we've swapped order of a & b, which is bad.
139> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxx..x...xx..........xxx..x..............x......x............................................(x10)...(x1)........Failed! After 120 tests.
[b,c,a]
{c,[c,a],[c],a,[a,b],[b,a]}
Old_res ([335,192,185,160,153,123]): true
New_res: false (why line [1936])
Shrinking xx.xxxxxx.x.xxxxxxxx.xxxxxxxxxxx(4 times)
[b,a,c]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{a, [c], [], c, [c,b],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: b wasn't repairing in the previous state.
150> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxx....x...xxxxx..xx.....x.......xxx..x.......xxx...................x................x......(x10).....(x1)........xFailed! After 130 tests.
[c,a,b]
{b,[c],[b,a,c],c,[c,a,b],[b]}
Old_res ([335,214,185,160,153,147]): true
New_res: false (why line [1936])
Shrinking xxxx.x.xxx.xxxxxxx.xxxxxxxxx(4 times)
[c,b,a]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{c, [c], [a,b], c, [c,b,a],[]}
Old_res ([335,328,185,160,153,111]): true
New_res: false (why line [1981,1679])
false
Old code is wrong: a & b were repairing but UPI2 has a & b in the wrong order.
2015-07-03 15:01:54 +00:00
|
|
|
case Style of
|
|
|
|
primitive ->
|
|
|
|
New_res = ?MGR:chain_state_transition_is_sane(
|
2015-09-11 08:32:52 +00:00
|
|
|
Author1, UPI1, Repair1, Author2, UPI2, Author2),
|
2015-07-07 09:32:04 +00:00
|
|
|
New_p = case New_res of true -> true;
|
|
|
|
_ -> false
|
|
|
|
end;
|
WIP: 1st part of moving old chain state transtion code to new
Ha, famous last words, amirite?
%% The chain sequence/order checks at the bottom of this function aren't
%% as easy-to-read as they ought to be. However, I'm moderately confident
%% that it isn't buggy. TODO: refactor them for clarity.
So, now machi_chain_manager1:projection_transition_is_sane() is using
newer, far less buggy code to make sanity decisions.
TODO: Add support for Retrospective mode. TODO is it really needed?
Examples of how the old code sucks and the new code sucks less.
138> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxxx..x.xxxxxx..x.x....x..xx........................................................Failed! After 69 tests.
[a,b,c]
{c,[a,b,c],[c,b],b,[b,a],[b,a,c]}
Old_res ([335,192,166,160,153,139]): true
New_res: false (why line [1936])
Shrinking xxxxxxxxxxxx.xxxxxxx.xxx.xxxxxxxxxxxxxxxxx(3 times)
[a,b,c]
%% {Author1,UPI1, Repair1,Author2,UPI2, Repair2} %%
{c, [a,b,c],[], a, [b,a],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: we've swapped order of a & b, which is bad.
139> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxx..x...xx..........xxx..x..............x......x............................................(x10)...(x1)........Failed! After 120 tests.
[b,c,a]
{c,[c,a],[c],a,[a,b],[b,a]}
Old_res ([335,192,185,160,153,123]): true
New_res: false (why line [1936])
Shrinking xx.xxxxxx.x.xxxxxxxx.xxxxxxxxxxx(4 times)
[b,a,c]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{a, [c], [], c, [c,b],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: b wasn't repairing in the previous state.
150> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxx....x...xxxxx..xx.....x.......xxx..x.......xxx...................x................x......(x10).....(x1)........xFailed! After 130 tests.
[c,a,b]
{b,[c],[b,a,c],c,[c,a,b],[b]}
Old_res ([335,214,185,160,153,147]): true
New_res: false (why line [1936])
Shrinking xxxx.x.xxx.xxxxxxx.xxxxxxxxx(4 times)
[c,b,a]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{c, [c], [a,b], c, [c,b,a],[]}
Old_res ([335,328,185,160,153,111]): true
New_res: false (why line [1981,1679])
false
Old code is wrong: a & b were repairing but UPI2 has a & b in the wrong order.
2015-07-03 15:01:54 +00:00
|
|
|
whole ->
|
|
|
|
New_res = machi_chain_manager1:projection_transition_is_sane(
|
|
|
|
P1, P2, Author1, false),
|
|
|
|
New_p = case New_res of true -> true;
|
2015-07-07 09:32:04 +00:00
|
|
|
_ -> false
|
WIP: 1st part of moving old chain state transtion code to new
Ha, famous last words, amirite?
%% The chain sequence/order checks at the bottom of this function aren't
%% as easy-to-read as they ought to be. However, I'm moderately confident
%% that it isn't buggy. TODO: refactor them for clarity.
So, now machi_chain_manager1:projection_transition_is_sane() is using
newer, far less buggy code to make sanity decisions.
TODO: Add support for Retrospective mode. TODO is it really needed?
Examples of how the old code sucks and the new code sucks less.
138> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxxx..x.xxxxxx..x.x....x..xx........................................................Failed! After 69 tests.
[a,b,c]
{c,[a,b,c],[c,b],b,[b,a],[b,a,c]}
Old_res ([335,192,166,160,153,139]): true
New_res: false (why line [1936])
Shrinking xxxxxxxxxxxx.xxxxxxx.xxx.xxxxxxxxxxxxxxxxx(3 times)
[a,b,c]
%% {Author1,UPI1, Repair1,Author2,UPI2, Repair2} %%
{c, [a,b,c],[], a, [b,a],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: we've swapped order of a & b, which is bad.
139> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxx..x...xx..........xxx..x..............x......x............................................(x10)...(x1)........Failed! After 120 tests.
[b,c,a]
{c,[c,a],[c],a,[a,b],[b,a]}
Old_res ([335,192,185,160,153,123]): true
New_res: false (why line [1936])
Shrinking xx.xxxxxx.x.xxxxxxxx.xxxxxxxxxxx(4 times)
[b,a,c]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{a, [c], [], c, [c,b],[]}
Old_res ([338,185,160,153,147]): true
New_res: false (why line [1936])
false
Old code is wrong: b wasn't repairing in the previous state.
150> eqc:quickcheck(eqc:testing_time(10, machi_chain_manager1_test:prop_compare_legacy_with_v2_chain_transition_check(whole))).
xxxxxxxxxxx....x...xxxxx..xx.....x.......xxx..x.......xxx...................x................x......(x10).....(x1)........xFailed! After 130 tests.
[c,a,b]
{b,[c],[b,a,c],c,[c,a,b],[b]}
Old_res ([335,214,185,160,153,147]): true
New_res: false (why line [1936])
Shrinking xxxx.x.xxx.xxxxxxx.xxxxxxxxx(4 times)
[c,b,a]
%% {Author1,UPI1,Repair1,Author2,UPI2, Repair2} %%
{c, [c], [a,b], c, [c,b,a],[]}
Old_res ([335,328,185,160,153,111]): true
New_res: false (why line [1981,1679])
false
Old code is wrong: a & b were repairing but UPI2 has a & b in the wrong order.
2015-07-03 15:01:54 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
(catch ets:insert(count,
|
|
|
|
{{Author1, UPI1, Repair1, Author2, UPI2, Repair2}, true})),
|
2015-07-03 14:37:36 +00:00
|
|
|
?WHENFAIL(io:format(user,
|
2015-07-07 09:32:04 +00:00
|
|
|
"Old_res: ~p/~p (~p)\nNew_res: ~p/~p (why line ~P)\n",
|
|
|
|
[Old_p, Old_res, catch get(why1),
|
|
|
|
New_p, New_res, catch get(why2), 30]),
|
|
|
|
%% Old_p == New_p)
|
|
|
|
Old_p == New_p orelse (Old_p == true andalso New_p == false))
|
2015-07-03 10:21:41 +00:00
|
|
|
end))).
|
|
|
|
|
2015-07-03 14:37:36 +00:00
|
|
|
some(L) ->
|
|
|
|
?LET(L2, list(oneof(L)),
|
|
|
|
dedupe(L2)).
|
|
|
|
|
|
|
|
dedupe(L) ->
|
|
|
|
dedupe(L, []).
|
|
|
|
|
|
|
|
dedupe([H|T], Seen) ->
|
|
|
|
case lists:member(H, Seen) of
|
|
|
|
false ->
|
|
|
|
[H|dedupe(T, [H|Seen])];
|
|
|
|
true ->
|
|
|
|
dedupe(T, Seen)
|
|
|
|
end;
|
|
|
|
dedupe([], _) ->
|
|
|
|
[].
|
|
|
|
|
|
|
|
make_prop_ets() ->
|
|
|
|
ets:new(count, [named_table, set, public]).
|
|
|
|
|
2015-07-03 10:21:41 +00:00
|
|
|
-endif. % EQC
|
2015-04-06 05:16:20 +00:00
|
|
|
|
2015-12-10 06:57:35 +00:00
|
|
|
make_advance_fun(FitList, FLUList, MgrList, Num) ->
|
|
|
|
fun() ->
|
|
|
|
[begin
|
|
|
|
[catch machi_fitness:trigger_early_adjustment(Fit, Tgt) ||
|
|
|
|
Fit <- FitList,
|
|
|
|
Tgt <- FLUList ],
|
|
|
|
[catch ?MGR:trigger_react_to_env(Mgr) || Mgr <- MgrList],
|
|
|
|
ok
|
|
|
|
end || _ <- lists:seq(1, Num)]
|
|
|
|
end.
|
|
|
|
|
2015-04-06 11:07:39 +00:00
|
|
|
smoke0_test() ->
|
2015-04-06 05:16:20 +00:00
|
|
|
{ok, _} = machi_partition_simulator:start_link({1,2,3}, 50, 50),
|
|
|
|
Host = "localhost",
|
|
|
|
TcpPort = 6623,
|
|
|
|
{ok, FLUa} = machi_flu1:start_link([{a,TcpPort,"./data.a"}]),
|
2015-05-17 07:18:30 +00:00
|
|
|
Pa = #p_srvr{name=a, address=Host, port=TcpPort},
|
2015-04-09 08:13:38 +00:00
|
|
|
Members_Dict = machi_projection:make_members_dict([Pa]),
|
2015-04-06 11:07:39 +00:00
|
|
|
%% Egadz, more racing on startup, yay. TODO fix.
|
|
|
|
timer:sleep(1),
|
|
|
|
{ok, FLUaP} = ?FLU_PC:start_link(Pa),
|
2015-04-09 08:13:38 +00:00
|
|
|
{ok, M0} = ?MGR:start_link(a, Members_Dict, [{active_mode, false}]),
|
2015-04-06 05:16:20 +00:00
|
|
|
try
|
|
|
|
pong = ?MGR:ping(M0)
|
|
|
|
after
|
|
|
|
ok = ?MGR:stop(M0),
|
2015-04-06 11:07:39 +00:00
|
|
|
ok = machi_flu1:stop(FLUa),
|
|
|
|
ok = ?FLU_PC:quit(FLUaP),
|
2015-04-06 05:16:20 +00:00
|
|
|
ok = machi_partition_simulator:stop()
|
|
|
|
end.
|
|
|
|
|
2015-10-21 05:31:41 +00:00
|
|
|
smoke1_test_() ->
|
|
|
|
{timeout, 1*60, fun() -> smoke1_test2() end}.
|
|
|
|
|
|
|
|
smoke1_test2() ->
|
2015-04-06 05:16:20 +00:00
|
|
|
machi_partition_simulator:start_link({1,2,3}, 100, 0),
|
2015-04-09 05:44:58 +00:00
|
|
|
TcpPort = 62777,
|
|
|
|
FluInfo = [{a,TcpPort+0,"./data.a"}, {b,TcpPort+1,"./data.b"}, {c,TcpPort+2,"./data.c"}],
|
|
|
|
P_s = [#p_srvr{name=Name, address="localhost", port=Port} ||
|
|
|
|
{Name,Port,_Dir} <- FluInfo],
|
2015-04-09 08:13:38 +00:00
|
|
|
|
|
|
|
[machi_flu1_test:clean_up_data_dir(Dir) || {_,_,Dir} <- FluInfo],
|
2015-04-09 05:44:58 +00:00
|
|
|
FLUs = [element(2, machi_flu1:start_link([{Name,Port,Dir}])) ||
|
|
|
|
{Name,Port,Dir} <- FluInfo],
|
|
|
|
MembersDict = machi_projection:make_members_dict(P_s),
|
2015-04-09 08:13:38 +00:00
|
|
|
{ok, M0} = ?MGR:start_link(a, MembersDict, [{active_mode,false}]),
|
2015-04-06 05:16:20 +00:00
|
|
|
try
|
2015-04-09 05:44:58 +00:00
|
|
|
{ok, P1} = ?MGR:test_calc_projection(M0, false),
|
2015-05-08 07:53:10 +00:00
|
|
|
% DERP! Check for race with manager's proxy vs. proj listener
|
2015-10-21 05:31:41 +00:00
|
|
|
ok = lists:foldl(
|
|
|
|
fun(_, {_,{true,[{c,ok},{b,ok},{a,ok}]}}) ->
|
|
|
|
ok; % Short-circuit remaining attempts
|
|
|
|
(_, ok) ->
|
|
|
|
ok; % Skip remaining!
|
|
|
|
(_, _Else) ->
|
|
|
|
timer:sleep(10),
|
|
|
|
?MGR:test_write_public_projection(M0, P1)
|
|
|
|
end, not_ok, lists:seq(1, 1000)),
|
|
|
|
%% Writing the exact same projection multiple times returns ok:
|
|
|
|
%% no change!
|
|
|
|
{_,{true,[{c,ok},{b,ok},{a,ok}]}} = ?MGR:test_write_public_projection(M0, P1),
|
2015-04-06 05:16:20 +00:00
|
|
|
{unanimous, P1, Extra1} = ?MGR:test_read_latest_public_projection(M0, false),
|
|
|
|
|
|
|
|
ok
|
|
|
|
after
|
|
|
|
ok = ?MGR:stop(M0),
|
2015-04-09 05:44:58 +00:00
|
|
|
[ok = machi_flu1:stop(X) || X <- FLUs],
|
2015-04-06 05:16:20 +00:00
|
|
|
ok = machi_partition_simulator:stop()
|
|
|
|
end.
|
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
nonunanimous_setup_and_fix_test_() ->
|
|
|
|
os:cmd("rm -f /tmp/moomoo.*"),
|
|
|
|
{timeout, 1*60, fun() -> nonunanimous_setup_and_fix_test2() end}.
|
|
|
|
|
|
|
|
nonunanimous_setup_and_fix_test2() ->
|
2015-12-08 07:29:56 +00:00
|
|
|
error_logger:tty(false),
|
2015-04-06 05:16:20 +00:00
|
|
|
machi_partition_simulator:start_link({1,2,3}, 100, 0),
|
2015-04-09 08:13:38 +00:00
|
|
|
TcpPort = 62877,
|
2015-12-07 12:52:27 +00:00
|
|
|
FluInfo = [{a,TcpPort+0,"./data.a"}, {b,TcpPort+1,"./data.b"},
|
|
|
|
{c,TcpPort+2,"./data.c"}],
|
2015-04-09 08:13:38 +00:00
|
|
|
P_s = [#p_srvr{name=Name, address="localhost", port=Port} ||
|
|
|
|
{Name,Port,_Dir} <- FluInfo],
|
|
|
|
|
|
|
|
[machi_flu1_test:clean_up_data_dir(Dir) || {_,_,Dir} <- FluInfo],
|
2015-09-11 08:52:40 +00:00
|
|
|
{ok, SupPid} = machi_flu_sup:start_link(),
|
2015-12-08 05:50:16 +00:00
|
|
|
Opts = [{active_mode, false}, {initial_wedged, true}],
|
2015-12-10 06:57:35 +00:00
|
|
|
ChainName = my_little_chain,
|
2015-09-11 08:52:40 +00:00
|
|
|
[{ok,_}=machi_flu_psup:start_flu_package(Name, Port, Dir, Opts) ||
|
2015-04-09 08:13:38 +00:00
|
|
|
{Name,Port,Dir} <- FluInfo],
|
2015-12-07 12:52:27 +00:00
|
|
|
Proxies = [Proxy_a, Proxy_b, Proxy_c] =
|
2015-04-09 08:13:38 +00:00
|
|
|
[element(2,?FLU_PC:start_link(P)) || P <- P_s],
|
2015-12-07 12:52:27 +00:00
|
|
|
%% MembersDict = machi_projection:make_members_dict(P_s),
|
|
|
|
MembersDict = machi_projection:make_members_dict(lists:sublist(P_s, 2)),
|
|
|
|
Mgrs = [Ma,Mb,Mc] = [a_chmgr, b_chmgr, c_chmgr],
|
2015-12-08 05:50:16 +00:00
|
|
|
MgrProxies = [{Ma, Proxy_a}, {Mb, Proxy_b}, {Mc, Proxy_c}],
|
2015-12-10 06:57:35 +00:00
|
|
|
Advance = make_advance_fun([a_fitness,b_fitness,c_fitness],
|
|
|
|
[a,b,c],
|
|
|
|
[Mgr || {Mgr,_Proxy} <- MgrProxies],
|
|
|
|
3),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(Ma, ChainName, 0, ap_mode,
|
|
|
|
MembersDict, []),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(Mb, ChainName, 0, ap_mode,
|
|
|
|
MembersDict, []),
|
2015-04-06 05:16:20 +00:00
|
|
|
try
|
|
|
|
{ok, P1} = ?MGR:test_calc_projection(Ma, false),
|
|
|
|
|
2015-04-09 08:13:38 +00:00
|
|
|
P1a = machi_projection:update_checksum(
|
|
|
|
P1#projection_v1{down=[b], upi=[a], dbg=[{hackhack, ?LINE}]}),
|
|
|
|
P1b = machi_projection:update_checksum(
|
|
|
|
P1#projection_v1{author_server=b, creation_time=now(),
|
|
|
|
down=[a], upi=[b], dbg=[{hackhack, ?LINE}]}),
|
|
|
|
%% Scribble different projections
|
|
|
|
ok = ?FLU_PC:write_projection(Proxy_a, public, P1a),
|
|
|
|
ok = ?FLU_PC:write_projection(Proxy_b, public, P1b),
|
2015-04-06 05:16:20 +00:00
|
|
|
|
2015-04-09 08:47:43 +00:00
|
|
|
%% ?D(x),
|
2015-07-02 05:44:47 +00:00
|
|
|
{not_unanimous,_,_}=_XX = ?MGR:test_read_latest_public_projection(
|
|
|
|
Ma, false),
|
2015-04-09 08:47:43 +00:00
|
|
|
%% ?Dw(_XX),
|
2015-07-02 05:44:47 +00:00
|
|
|
{not_unanimous,_,_}=_YY = ?MGR:test_read_latest_public_projection(
|
|
|
|
Ma, true),
|
2015-04-06 05:16:20 +00:00
|
|
|
%% The read repair here doesn't automatically trigger the creation of
|
|
|
|
%% a new projection (to try to create a unanimous projection). So
|
|
|
|
%% we expect nothing to change when called again.
|
2015-07-02 05:44:47 +00:00
|
|
|
{not_unanimous,_,_}=_YY = ?MGR:test_read_latest_public_projection(
|
|
|
|
Ma, true),
|
2015-04-06 05:16:20 +00:00
|
|
|
|
2015-07-03 07:18:40 +00:00
|
|
|
{now_using, _, EpochNum_a} = ?MGR:trigger_react_to_env(Ma),
|
|
|
|
{no_change, _, EpochNum_a} = ?MGR:trigger_react_to_env(Ma),
|
2015-04-09 08:47:43 +00:00
|
|
|
{unanimous,P2,_E2} = ?MGR:test_read_latest_public_projection(Ma, false),
|
2015-04-09 08:13:38 +00:00
|
|
|
{ok, P2pa} = ?FLU_PC:read_latest_projection(Proxy_a, private),
|
2015-04-06 05:16:20 +00:00
|
|
|
P2 = P2pa#projection_v1{dbg2=[]},
|
|
|
|
|
2015-09-11 08:52:40 +00:00
|
|
|
%% Poke FLUb to react ... should be using the same private proj
|
|
|
|
%% as FLUa.
|
|
|
|
{now_using, _, EpochNum_a} = ?MGR:trigger_react_to_env(Mb),
|
2015-04-09 08:13:38 +00:00
|
|
|
{ok, P2pb} = ?FLU_PC:read_latest_projection(Proxy_b, private),
|
2015-04-06 05:16:20 +00:00
|
|
|
P2 = P2pb#projection_v1{dbg2=[]},
|
|
|
|
|
2015-12-07 12:52:27 +00:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("\nSTEP: Add a 3rd member to the chain.\n", []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
|
|
|
MembersDict3 = machi_projection:make_members_dict(P_s),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(
|
2015-12-10 06:57:35 +00:00
|
|
|
Ma, ChainName, EpochNum_a, ap_mode, MembersDict3, []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
Advance(),
|
2015-12-07 12:52:27 +00:00
|
|
|
{_, _, TheEpoch_3} = ?MGR:trigger_react_to_env(Ma),
|
|
|
|
{_, _, TheEpoch_3} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
{_, _, TheEpoch_3} = ?MGR:trigger_react_to_env(Mc),
|
|
|
|
[{ok, #projection_v1{upi=[a,b], repairing=[c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- Proxies],
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Remove 'a' from the chain.\n", []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
|
|
|
MembersDict4 = machi_projection:make_members_dict(tl(P_s)),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(
|
2015-12-10 06:57:35 +00:00
|
|
|
Mb, ChainName, TheEpoch_3, ap_mode, MembersDict4, []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
Advance(),
|
|
|
|
{ok, {true, _}} = ?FLU_PC:wedge_status(Proxy_a),
|
2015-12-07 12:52:27 +00:00
|
|
|
{_, _, TheEpoch_4} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
{_, _, TheEpoch_4} = ?MGR:trigger_react_to_env(Mc),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- tl(Proxies)],
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Add a to the chain again (a is running).\n", []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
|
|
|
MembersDict5 = machi_projection:make_members_dict(P_s),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(
|
2015-12-10 06:57:35 +00:00
|
|
|
Mb, ChainName, TheEpoch_4, ap_mode, MembersDict5, []),
|
2015-12-07 12:52:27 +00:00
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
Advance(),
|
2015-12-07 12:52:27 +00:00
|
|
|
{_, _, TheEpoch_5} = ?MGR:trigger_react_to_env(Ma),
|
|
|
|
{_, _, TheEpoch_5} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
{_, _, TheEpoch_5} = ?MGR:trigger_react_to_env(Mc),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[a,c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- Proxies],
|
2015-09-07 06:38:23 +00:00
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Stop a while a chain member, advance b&c.\n", []),
|
2015-12-08 05:50:16 +00:00
|
|
|
|
|
|
|
ok = machi_flu_psup:stop_flu_package(a),
|
|
|
|
Advance(),
|
|
|
|
{_, _, TheEpoch_6} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
{_, _, TheEpoch_6} = ?MGR:trigger_react_to_env(Mc),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- tl(Proxies)],
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Remove 'a' from the chain.\n", []),
|
2015-12-08 05:50:16 +00:00
|
|
|
|
|
|
|
MembersDict7 = machi_projection:make_members_dict(tl(P_s)),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(
|
2015-12-10 06:57:35 +00:00
|
|
|
Mb, ChainName, TheEpoch_6, ap_mode, MembersDict7, []),
|
2015-12-08 05:50:16 +00:00
|
|
|
|
|
|
|
Advance(),
|
|
|
|
{_, _, TheEpoch_7} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
{_, _, TheEpoch_7} = ?MGR:trigger_react_to_env(Mc),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- tl(Proxies)],
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Start a, advance.\n", []),
|
2015-12-08 05:50:16 +00:00
|
|
|
|
|
|
|
[{ok,_}=machi_flu_psup:start_flu_package(Name, Port, Dir, Opts) ||
|
|
|
|
{Name,Port,Dir} <- [hd(FluInfo)]],
|
|
|
|
Advance(),
|
|
|
|
{ok, {true, _}} = ?FLU_PC:wedge_status(Proxy_a),
|
|
|
|
{ok, {false, EpochID_8}} = ?FLU_PC:wedge_status(Proxy_b),
|
|
|
|
{ok, {false, EpochID_8}} = ?FLU_PC:wedge_status(Proxy_c),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[c]}} =
|
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- tl(Proxies)],
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Stop a, delete a's data, leave it stopped\n", []),
|
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
ok = machi_flu_psup:stop_flu_package(a),
|
|
|
|
Advance(),
|
|
|
|
{_,_,Dir_a} = hd(FluInfo),
|
|
|
|
[machi_flu1_test:clean_up_data_dir(Dir) || {_,_,Dir} <- [hd(FluInfo)]],
|
|
|
|
{ok, {false, _}} = ?FLU_PC:wedge_status(Proxy_b),
|
|
|
|
{ok, {false, _}} = ?FLU_PC:wedge_status(Proxy_c),
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Add a to the chain again (a is stopped).\n", []),
|
2015-12-08 05:50:16 +00:00
|
|
|
|
|
|
|
MembersDict9 = machi_projection:make_members_dict(P_s),
|
|
|
|
{_, _, TheEpoch_9} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
ok = machi_chain_manager1:set_chain_members(
|
2015-12-10 06:57:35 +00:00
|
|
|
Mb, ChainName, TheEpoch_9, ap_mode, MembersDict9, []),
|
2015-12-08 05:50:16 +00:00
|
|
|
Advance(),
|
|
|
|
{_, _, TheEpoch_9b} = ?MGR:trigger_react_to_env(Mb),
|
|
|
|
true = (TheEpoch_9b > TheEpoch_9),
|
2015-12-08 06:27:47 +00:00
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2015-12-08 07:29:56 +00:00
|
|
|
io:format("STEP: Start a, and it joins like it ought to\n", []),
|
2015-12-08 06:27:47 +00:00
|
|
|
|
2015-12-08 05:50:16 +00:00
|
|
|
[{ok,_}=machi_flu_psup:start_flu_package(Name, Port, Dir, Opts) ||
|
|
|
|
{Name,Port,Dir} <- [hd(FluInfo)]],
|
|
|
|
Advance(),
|
2015-12-08 06:27:47 +00:00
|
|
|
{ok, {false, {TheEpoch10,_}}} = ?FLU_PC:wedge_status(Proxy_a),
|
|
|
|
{ok, {false, {TheEpoch10,_}}} = ?FLU_PC:wedge_status(Proxy_b),
|
|
|
|
{ok, {false, {TheEpoch10,_}}} = ?FLU_PC:wedge_status(Proxy_c),
|
|
|
|
[{ok, #projection_v1{upi=[b], repairing=[c,a]}} =
|
2015-12-08 05:50:16 +00:00
|
|
|
?FLU_PC:read_latest_projection(Pxy, private) || Pxy <- Proxies],
|
2015-04-06 05:16:20 +00:00
|
|
|
ok
|
|
|
|
after
|
2015-09-11 08:52:40 +00:00
|
|
|
exit(SupPid, normal),
|
2015-04-09 08:13:38 +00:00
|
|
|
[ok = ?FLU_PC:quit(X) || X <- Proxies],
|
2015-12-08 07:29:56 +00:00
|
|
|
ok = machi_partition_simulator:stop(),
|
|
|
|
error_logger:tty(true)
|
2015-04-06 05:16:20 +00:00
|
|
|
end.
|
|
|
|
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
unanimous_report_test() ->
|
2015-07-02 15:59:04 +00:00
|
|
|
TcpPort = 63877,
|
|
|
|
FluInfo = [{a,TcpPort+0,"./data.a"}, {b,TcpPort+1,"./data.b"}],
|
|
|
|
P_s = [#p_srvr{name=Name, address="localhost", port=Port} ||
|
|
|
|
{Name,Port,_Dir} <- FluInfo],
|
|
|
|
MembersDict = machi_projection:make_members_dict(P_s),
|
|
|
|
|
|
|
|
E5 = 5,
|
|
|
|
UPI5 = [a,b],
|
|
|
|
Rep5 = [],
|
2015-07-10 06:04:50 +00:00
|
|
|
Report5 = [UPI5],
|
2015-07-02 15:59:04 +00:00
|
|
|
P5 = machi_projection:new(E5, a, MembersDict, [], UPI5, Rep5, []),
|
2015-07-10 06:04:50 +00:00
|
|
|
{ok_disjoint, Report5} =
|
2015-07-03 10:21:41 +00:00
|
|
|
unanimous_report2([{a, P5}, {b, P5}]),
|
2015-07-10 06:04:50 +00:00
|
|
|
{ok_disjoint, Report5} =
|
2015-07-03 10:21:41 +00:00
|
|
|
unanimous_report2([{a, not_in_this_epoch}, {b, P5}]),
|
2015-07-10 06:04:50 +00:00
|
|
|
{ok_disjoint, Report5} =
|
2015-07-03 10:21:41 +00:00
|
|
|
unanimous_report2([{a, P5}, {b, not_in_this_epoch}]),
|
2015-07-02 15:59:04 +00:00
|
|
|
|
|
|
|
UPI5_b = [a],
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
Rep5_b = [],
|
|
|
|
P5_b = machi_projection:new(E5, b, MembersDict, [b], UPI5_b, Rep5_b, []),
|
|
|
|
{bummer_NOT_DISJOINT, _} = unanimous_report2([{a, P5}, {b, P5_b}]),
|
2015-07-07 09:32:04 +00:00
|
|
|
|
|
|
|
UPI5_c = [b],
|
|
|
|
Rep5_c = [a],
|
|
|
|
P5_c = machi_projection:new(E5, b, MembersDict, [], UPI5_c, Rep5_c, []),
|
|
|
|
{bummer_NOT_DISJOINT, _} =
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
unanimous_report2([{a, P5}, {b, P5_c}]),
|
|
|
|
|
|
|
|
P_s3 = [#p_srvr{name=Name, address="localhost", port=Port} ||
|
|
|
|
{Name,Port,_Dir} <- FluInfo ++ [{c,TcpPort+0,"./data.c"}]],
|
|
|
|
MembersDict3 = machi_projection:make_members_dict(P_s3),
|
|
|
|
|
|
|
|
UPI5_d = [c],
|
|
|
|
Rep5_d = [a],
|
2015-07-10 06:04:50 +00:00
|
|
|
Report5d = [UPI5, UPI5_d],
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
P5_d = machi_projection:new(E5, b, MembersDict3, [b], UPI5_d, Rep5_d, []),
|
2015-07-10 06:04:50 +00:00
|
|
|
{ok_disjoint, Report5d} = unanimous_report2([{a, P5}, {b, P5_d}]),
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
|
|
|
|
UPI5_e = [b],
|
|
|
|
Rep5_e = [c],
|
2015-07-10 06:04:50 +00:00
|
|
|
Report5be = [UPI5_b, UPI5_e],
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
P5_e = machi_projection:new(E5, b, MembersDict3, [a], UPI5_e, Rep5_e, []),
|
|
|
|
{bummer_NOT_DISJOINT, _} = unanimous_report2([{a, P5}, {b, P5_e}]),
|
2015-07-10 06:04:50 +00:00
|
|
|
{ok_disjoint, Report5be} = unanimous_report2([{a, P5_b}, {b, P5_e}]),
|
2015-07-02 15:59:04 +00:00
|
|
|
|
WIP: major fixups to the chmgr state transition checking (more below)
So, the PULSE test is failing, which is good. However, I believe
that the failures are all due to the model now being *too strict*.
The model is now catching failures which are now benign, I think.
{bummer_NOT_DISJOINT,{[a,b,b,c,d],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1546},{author,c},{upi,[c]},{repair,[b]},{down,[a,d]},{d,[{ps,[{a,c},{c,a},{a,d},{b,d},{c,d}]},{nodes_up,[b,c]}]},{d2,[]}]"},
{d,"[{epoch,1546},{author,d},{upi,[d]},{repair,[a,b]},{down,[c]},{d,[{ps,[{c,b},{d,c}]},{nodes_up,[a,b,d]}]},{d2,[]}]"}]}}},
In this and all other examples, the UPIs are disjoint but the
repairs are not disjoint. I believe the model ought to be
ignoring the repair list.
{bummer_NOT_DISJOINT,{[a,a,b],
[{a,"[{epoch,1174},{author,a},{upi,[a]},{repair,[]},{down,[b]},{d,[{ps,[{a,b},{b,a}]},{nodes_up,[a]}]},{d2,[]}]"},
{b,"[{epoch,1174},{author,b},{upi,[b]},{repair,[a]},{down,[]},{d,[{ps,[]},{nodes_up,[a,b]}]},{d2,[]}]"}]}}},
or
{bummer_NOT_DISJOINT,{[c,c,e],
[{a,not_in_this_epoch},
{b,not_in_this_epoch},
{c,"[{epoch,1388},{author,c},{upi,[c]},{repair,[]},{down,[a,b,d,e]},{d,[{ps,[{a,b},{a,c},{c,a},{a,d},{d,a},{e,a},{c,b},{b,e},{e,b},{c,d},{e,c},{e,d}]},{nodes_up,[c]}]},{d2,[]}]"},
{d,not_in_this_epoch},
{e,"[{epoch,1388},{author,e},{upi,[e]},{repair,[c]},{down,[a,b,d]},{d,[{ps,[{a,b},{b,a},{a,c},{c,a},{a,d},{d,a},{a,e},{e,a},{b,c},{c,b},{b,d},{b,e},{e,b},{c,d},{d,c},{d,e},{e,d}]},{nodes_up,[c,e]}]},{d2,[]}]"}]}}},
2015-07-07 13:11:19 +00:00
|
|
|
ok.
|
2015-07-02 15:59:04 +00:00
|
|
|
|
2015-06-02 13:13:15 +00:00
|
|
|
-endif. % !PULSE
|
2015-04-06 05:16:20 +00:00
|
|
|
-endif. % TEST
|