From 10fd753c9f28782fdca9c4d785f59d5e7c17c61c Mon Sep 17 00:00:00 2001 From: Ahmed Omar Date: Mon, 9 May 2011 17:23:36 +0200 Subject: [PATCH] Refactored the test. Now nodes are configurable, in split.cfg, also timeouts. 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. --- test/config/split.cfg | 3 + test/run.sh | 2 +- test/unsplit_SUITE.erl | 145 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 test/config/split.cfg create mode 100644 test/unsplit_SUITE.erl diff --git a/test/config/split.cfg b/test/config/split.cfg new file mode 100644 index 0000000..5ac7d95 --- /dev/null +++ b/test/config/split.cfg @@ -0,0 +1,3 @@ +{nodes, [cn1, cn2]}. +{disconnect_time, 4000}. +{unsplit_timeout, 50000}. diff --git a/test/run.sh b/test/run.sh index 223df90..e9d4a2f 100755 --- a/test/run.sh +++ b/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 diff --git a/test/unsplit_SUITE.erl b/test/unsplit_SUITE.erl new file mode 100644 index 0000000..5cc28bd --- /dev/null +++ b/test/unsplit_SUITE.erl @@ -0,0 +1,145 @@ +%%% @doc +%%% Test suite for unsplit +%%% @copyright Nimbuzz B.V. +%%% @author Ahmed Omar +-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). +