summaryrefslogtreecommitdiff
path: root/priv/templates
diff options
context:
space:
mode:
Diffstat (limited to 'priv/templates')
-rw-r--r--priv/templates/ctsuite.erl167
-rw-r--r--priv/templates/ctsuite.template2
-rw-r--r--priv/templates/simplenode.nodetool62
-rwxr-xr-xpriv/templates/simplenode.runner23
4 files changed, 244 insertions, 10 deletions
diff --git a/priv/templates/ctsuite.erl b/priv/templates/ctsuite.erl
new file mode 100644
index 0000000..33a8fac
--- /dev/null
+++ b/priv/templates/ctsuite.erl
@@ -0,0 +1,167 @@
+%% common_test suite for {{testmod}}
+
+-module({{testmod}}_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+%%--------------------------------------------------------------------
+%% Function: suite() -> Info
+%%
+%% Info = [tuple()]
+%% List of key/value pairs.
+%%
+%% Description: Returns list of tuples to set default properties
+%% for the suite.
+%%
+%% Note: The suite/0 function is only meant to be used to return
+%% default data values, not perform any other operations.
+%%--------------------------------------------------------------------
+suite() -> [{timetrap, {seconds, 20}}].
+
+%%--------------------------------------------------------------------
+%% Function: groups() -> [Group]
+%%
+%% Group = {GroupName,Properties,GroupsAndTestCases}
+%% GroupName = atom()
+%% The name of the group.
+%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]
+%% Group properties that may be combined.
+%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]
+%% TestCase = atom()
+%% The name of a test case.
+%% Shuffle = shuffle | {shuffle,Seed}
+%% To get cases executed in random order.
+%% Seed = {integer(),integer(),integer()}
+%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
+%% repeat_until_any_ok | repeat_until_any_fail
+%% To get execution of cases repeated.
+%% N = integer() | forever
+%%
+%% Description: Returns a list of test case group definitions.
+%%--------------------------------------------------------------------
+groups() -> [].
+
+%%--------------------------------------------------------------------
+%% Function: all() -> GroupsAndTestCases
+%%
+%% GroupsAndTestCases = [{group,GroupName} | TestCase]
+%% GroupName = atom()
+%% Name of a test case group.
+%% TestCase = atom()
+%% Name of a test case.
+%%
+%% Description: Returns the list of groups and test cases that
+%% are to be executed.
+%%
+%% NB: By default, we export all 1-arity user defined functions
+%%--------------------------------------------------------------------
+all() ->
+ [ {exports, Functions} | _ ] = ?MODULE:module_info(),
+ [ FName || {FName, _} <- lists:filter(
+ fun ({module_info,_}) -> false;
+ ({all,_}) -> false;
+ ({init_per_suite,1}) -> false;
+ ({end_per_suite,1}) -> false;
+ ({_,1}) -> true;
+ ({_,_}) -> false
+ end, Functions)].
+
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the suite.
+%%
+%% Description: Initialization before the suite.
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
+%%
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Cleanup after the suite.
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% GroupName = atom()
+%% Name of the test case group that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding configuration data for the group.
+%% Reason = term()
+%% The reason for skipping all test cases and subgroups in the group.
+%%
+%% Description: Initialization before each test case group.
+%%--------------------------------------------------------------------
+init_per_group(_group, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+%%
+%% GroupName = atom()
+%% Name of the test case group that is finished.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding configuration data for the group.
+%%
+%% Description: Cleanup after each test case group.
+%%--------------------------------------------------------------------
+end_per_group(_group, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+%%
+%% TestCase = atom()
+%% Name of the test case that is about to run.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for skipping the test case.
+%%
+%% Description: Initialization before each test case.
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_testcase(TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+%%
+%% TestCase = atom()
+%% Name of the test case that is finished.
+%% Config0 = Config1 = [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Reason = term()
+%% The reason for failing the test case.
+%%
+%% Description: Cleanup after each test case.
+%%--------------------------------------------------------------------
+end_per_testcase(TestCase, Config) ->
+ Config.
+
+test_{{testmod}}() ->
+ [{userdata,[{doc,"Testing the {{testmod}} module"}]}].
+
+test_{{testmod}}(_Config) ->
+ {skip,"Not implemented."}.
diff --git a/priv/templates/ctsuite.template b/priv/templates/ctsuite.template
new file mode 100644
index 0000000..b7de337
--- /dev/null
+++ b/priv/templates/ctsuite.template
@@ -0,0 +1,2 @@
+{variables, [{testmod, "mymodule"}]}.
+{template, "ctsuite.erl", "test/{{testmod}}_SUITE.erl"}.
diff --git a/priv/templates/simplenode.nodetool b/priv/templates/simplenode.nodetool
index 971f983..eb08fa4 100644
--- a/priv/templates/simplenode.nodetool
+++ b/priv/templates/simplenode.nodetool
@@ -1,4 +1,5 @@
-%% -*- erlang -*-
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
%% -------------------------------------------------------------------
%%
%% nodetool: Helper Script for interacting with live nodes
@@ -6,6 +7,7 @@
%% -------------------------------------------------------------------
main(Args) ->
+ ok = start_epmd(),
%% Extract the args
{RestArgs, TargetNode} = process_args(Args, [], undefined),
@@ -30,7 +32,8 @@ main(Args) ->
["reboot"] ->
io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]);
["rpc", Module, Function | RpcArgs] ->
- case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], 60000) of
+ case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
+ [RpcArgs], 60000) of
ok ->
ok;
{badrpc, Reason} ->
@@ -39,6 +42,15 @@ main(Args) ->
_ ->
halt(1)
end;
+ ["rpcterms", Module, Function, ArgsAsString] ->
+ case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
+ consult(ArgsAsString), 60000) of
+ {badrpc, Reason} ->
+ io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
+ halt(1);
+ Other ->
+ io:format("~p\n", [Other])
+ end;
Other ->
io:format("Other: ~p\n", [Other]),
io:format("Usage: nodetool {ping|stop|restart|reboot}\n")
@@ -62,6 +74,27 @@ process_args([Arg | Rest], Acc, Opts) ->
process_args(Rest, [Arg | Acc], Opts).
+start_epmd() ->
+ [] = os:cmd(epmd_path() ++ " -daemon"),
+ ok.
+
+epmd_path() ->
+ ErtsBinDir = filename:dirname(escript:script_name()),
+ Name = "epmd",
+ case os:find_executable(Name, ErtsBinDir) of
+ false ->
+ case os:find_executable(Name) of
+ false ->
+ io:format("Could not find epmd.~n"),
+ halt(1);
+ GlobalEpmd ->
+ GlobalEpmd
+ end;
+ Epmd ->
+ Epmd
+ end.
+
+
nodename(Name) ->
case string:tokens(Name, "@") of
[_Node, _Host] ->
@@ -78,3 +111,28 @@ append_node_suffix(Name, Suffix) ->
[Node] ->
list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
end.
+
+
+%%
+%% Given a string or binary, parse it into a list of terms, ala file:consult/0
+%%
+consult(Str) when is_list(Str) ->
+ consult([], Str, []);
+consult(Bin) when is_binary(Bin)->
+ consult([], binary_to_list(Bin), []).
+
+consult(Cont, Str, Acc) ->
+ case erl_scan:tokens(Cont, Str, 0) of
+ {done, Result, Remaining} ->
+ case Result of
+ {ok, Tokens, _} ->
+ {ok, Term} = erl_parse:parse_term(Tokens),
+ consult([], Remaining, [Term | Acc]);
+ {eof, _Other} ->
+ lists:reverse(Acc);
+ {error, Info, _} ->
+ {error, Info}
+ end;
+ {more, Cont1} ->
+ consult(Cont1, eof, Acc)
+ end.
diff --git a/priv/templates/simplenode.runner b/priv/templates/simplenode.runner
index cfde552..18fa951 100755
--- a/priv/templates/simplenode.runner
+++ b/priv/templates/simplenode.runner
@@ -7,6 +7,7 @@ RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd)
RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*}
RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc
RUNNER_LOG_DIR=$RUNNER_BASE_DIR/log
+# Note the trailing slash on $PIPE_DIR/
PIPE_DIR=/tmp/$RUNNER_BASE_DIR/
RUNNER_USER=
@@ -58,10 +59,10 @@ case "$1" in
echo "Node is already running!"
exit 1
fi
- export HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start"
+ HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start"
+ export HEART_COMMAND
mkdir -p $PIPE_DIR
- # Note the trailing slash on $PIPE_DIR/
- $ERTS_PATH/run_erl -daemon $PIPE_DIR/ $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1
+ $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console" 2>&1
;;
stop)
@@ -70,16 +71,16 @@ case "$1" in
Linux|Darwin|FreeBSD|DragonFly|NetBSD|OpenBSD)
# PID COMMAND
PID=`ps ax -o pid= -o command=|\
- grep "$RUNNER_BASE_DIR/.*/[b]eam"|cut -d' ' -f1`
+ grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $1}'`
;;
SunOS)
# PID COMMAND
PID=`ps -ef -o pid= -o args=|\
- grep "$RUNNER_BASE_DIR/.*/[b]eam"|cut -d' ' -f1`
+ grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $1}'`
;;
CYGWIN*)
# UID PID PPID TTY STIME COMMAND
- PID=`ps -efW|grep "$RUNNER_BASE_DIR/.*/[b]eam"|cut -d' ' -f2`
+ PID=`ps -efW|grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $2}'`
;;
esac
$NODETOOL stop
@@ -116,13 +117,19 @@ case "$1" in
$ERTS_PATH/to_erl $PIPE_DIR
;;
- console)
+ console|console_clean)
+ # .boot file typically just $SCRIPT (ie, the app name)
+ # however, for debugging, sometimes start_clean.boot is useful:
+ case "$1" in
+ console) BOOTFILE=$SCRIPT ;;
+ console_clean) BOOTFILE=start_clean ;;
+ esac
# Setup beam-required vars
ROOTDIR=$RUNNER_BASE_DIR
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
EMU=beam
PROGNAME=`echo $0 | sed 's/.*\\///'`
- CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT -embedded -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
+ CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -embedded -config $RUNNER_ETC_DIR/app.config -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
export EMU
export ROOTDIR
export BINDIR