Skip to content

Commit

Permalink
Refactored the test. Now nodes are configurable, in split.cfg, also t…
Browse files Browse the repository at this point in the history
…imeouts. The test now will start two ct_slave nodes and run mnesia and unsplit there. The drawback for that, we don't get code coverage. One problem needs to be solved, how to know that unsplit is done with fixing the table.
  • Loading branch information
spawnthink committed May 9, 2011
1 parent a8af385 commit 10fd753
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
3 changes: 3 additions & 0 deletions test/config/split.cfg
@@ -0,0 +1,3 @@
{nodes, [cn1, cn2]}.
{disconnect_time, 4000}.
{unsplit_timeout, 50000}.
2 changes: 1 addition & 1 deletion test/run.sh
@@ -1,6 +1,6 @@
!# /bin/sh
cd ../src; make; cd -;
run_test -pa ../ebin -include ../src/ -dir $PWD -cover config/cover.conf -logdir $PWD/log;
run_test -pa ../ebin -include ../src/ -config config/split.cfg -dir $PWD -repeat ${1-1} -cover config/cover.conf -logdir $PWD/log;
rm *.beam;
cd ../src; make clean

145 changes: 145 additions & 0 deletions test/unsplit_SUITE.erl
@@ -0,0 +1,145 @@
%%% @doc
%%% Test suite for unsplit
%%% @copyright Nimbuzz B.V.
%%% @author Ahmed Omar <omar@nimbuzz.nl>
-module(unsplit_SUITE).
%%% @end
-include_lib("eunit/include/eunit.hrl").
%%% Include files
-include_lib("common_test/include/ct.hrl").

%%% External exports
-compile(export_all).
-define(ERL_FLAGS, "-kernel dist_auto_connect once -pa ../../ -pa ../../../ebin/").
-define(TABLE, test1).
-define(NODES, ['mn1@localhost', 'mn2@localhost']).
-define(DISCONNECT_TIME, 4000).
-define(UNSPLIT_TIMEOUT, 5000).
-record(?TABLE,{key,modified=erlang:now(),value}).
%%% Macros

all() ->
[split1].


init_per_suite(Conf) ->
Nodes = ct:get_config(nodes, ?NODES),
DisconnectTime = ct:get_config(disconnect_time, ?DISCONNECT_TIME),
UnsplitTimeout = ct:get_config(unsplit_timeout, ?UNSPLIT_TIMEOUT),
Host = get_host(),
StartNode = fun(Node)->
ct:print("starting node ~p, on host ~p ~n",[Node, Host]),
{ok, NodeName} = ct_slave:start(Host, Node,
[{erl_flags,
?ERL_FLAGS}]),
NodeName
end,

NodeNames = lists:map(StartNode, Nodes),
[{disconnect_time, DisconnectTime},
{unsplit_timeout, UnsplitTimeout},
{nodes, NodeNames}|Conf].

end_per_suite(_Conf) ->
Nodes = ct:get_config(nodes,?NODES),
Host = get_host(),
StopNode = fun(Node)->
{ok, _NodeName} = ct_slave:stop(Host, Node)
end,
lists:map(StopNode, Nodes),
ok.

init_per_testcase(Case, Conf) ->
ct:print("Test case ~p started", [Case]),
init_nodes(get_conf(nodes, Conf)),
Conf.

end_per_testcase(Case, Conf) ->
ct:print("Test case ~p finished", [Case]),
terminate_nodes(get_conf(nodes, Conf)),
Conf.

split1()->
[{userdata, [{doc, "Tests split network of 2 nodes"}]}].
split1(Conf)->
DisconnectTime = get_conf(disconnect_time, Conf),
UnsplitTimeout = get_conf(unsplit_timeout, Conf),
Nodes = [M, S|_Rest] = get_conf(nodes, Conf),
ct:print("Initial table size~n"),
print_table_size(Nodes, ?TABLE),
ct:print("inserting records~n"),
{atomic, ok} = write(M, [#?TABLE{key=1, value=a}, #?TABLE{key=2, value=a}]),
print_table_size(Nodes, ?TABLE),
ct:print("disconnecting nodes~n"),
disconnect(M, S),
ct:print("inserting records on one node, while the other one is disconnected~n"),
{atomic, ok} = write(M, [#?TABLE{key=3, value=b}, #?TABLE{key=4, value=b}]),
print_table_size(Nodes, ?TABLE),
timer:sleep(DisconnectTime),
ct:print("reconnecting nodes~n"),
connect(S, M),
timer:sleep(UnsplitTimeout),
print_table_size(Nodes, ?TABLE),
true = compare_table_size(Nodes, ?TABLE).


compare_table_size([Node1, Node2|_], Table)->
table_size(Node1, Table) == table_size(Node2, Table).

table_size(Node, Table)->
rpc:call(Node, mnesia, table_info,[Table, size]).

print_table_size([M,S|_], Table)->
ct:print("master size = ~p~n",[table_size(M, Table)]),
ct:print("slave size = ~p~n",[table_size(S, Table)]).

get_conf(Key, Conf)->
proplists:get_value(Key, Conf).


terminate_nodes(Nodes)->
Terminate = fun(Node)->
rpc:call(Node, application, stop, [unsplit]),
rpc:call(Node, mnesia, stop,[]),
rpc:call(Node, application, stop, [sasl])
end,
lists:foreach(Terminate, Nodes).


init_nodes(Nodes)->
Init = fun(Node)->
rpc:call(Node, mnesia, delete_schema,[Node]),
rpc:call(Node, application, start, [sasl]),
rpc:call(Node, mnesia, start,[]),
rpc:call(Node, application, start, [unsplit]),
rpc:call(Node, mnesia, create_schema, [Nodes]),
rpc:call(Node, mnesia, change_config, [extra_db_nodes, Nodes--[Node]]),
rpc:call(Node, mnesia, delete_table, [?TABLE]),
rpc:call(Node, mnesia, create_table, [?TABLE,
[{ram_copies,Nodes},
{attributes,[key,modified,value]},
{user_properties,
[{unsplit_method,{unsplit_lib,last_modified,[]}}]}]])
end,
lists:foreach(Init, Nodes).

disconnect(Master, Slave)->
rpc:call(Master, erlang, disconnect_node, [Slave]).
connect(Master, Slave)->
rpc:call(Master, net_kernel, connect_node, [Slave]).

write(Node, Records)->
rpc:call(Node, ?MODULE, write, [Records]).

write(Records)->
Trans = fun()->
lists:foreach(fun(Record)->
mnesia:write(Record)
end, Records)
end,
mnesia:transaction(Trans).

get_host()->
{ok, HostS} = inet:gethostname(),
list_to_atom(HostS).

0 comments on commit 10fd753

Please sign in to comment.