summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar.app.src1
-rw-r--r--src/rebar_prv_common_test.erl175
2 files changed, 176 insertions, 0 deletions
diff --git a/src/rebar.app.src b/src/rebar.app.src
index a23c246..c41ad92 100644
--- a/src/rebar.app.src
+++ b/src/rebar.app.src
@@ -37,6 +37,7 @@
rebar_prv_upgrade,
rebar_prv_release,
rebar_prv_version,
+ rebar_prv_common_test,
rebar_prv_help,
rebar_prv_test_deps]}
]}
diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl
new file mode 100644
index 0000000..37d1920
--- /dev/null
+++ b/src/rebar_prv_common_test.erl
@@ -0,0 +1,175 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+
+-module(rebar_prv_common_test).
+
+-behaviour(rebar_provider).
+
+-export([init/1,
+ format_error/2,
+ do/1]).
+
+-include("rebar.hrl").
+
+-define(PROVIDER, ct).
+-define(DEPS, [compile]).
+
+%% ===================================================================
+%% Public API
+%% ===================================================================
+
+-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
+init(State) ->
+ Provider = providers:create([{name, ?PROVIDER},
+ {module, ?MODULE},
+ {deps, ?DEPS},
+ {bare, false},
+ {example, "rebar ct"},
+ {short_desc, "Run Common Tests"},
+ {desc, ""},
+ {opts, ct_opts(State)}]),
+ State1 = rebar_state:add_provider(State, Provider),
+ {ok, State1}.
+
+-spec do(rebar_state:t()) -> {ok, rebar_state:t()}.
+do(State) ->
+ Opts = build_options(State),
+ ct:run_test(Opts),
+ {ok, State}.
+
+-spec format_error(any(), rebar_state:t()) -> {iolist(), rebar_state:t()}.
+format_error(Reason, State) ->
+ {io_lib:format("~p", [Reason]), State}.
+
+ct_opts(State) ->
+ DefaultTestDir = filename:join([rebar_state:dir(State), "test"]),
+ DefaultLogsDir = filename:join([rebar_state:dir(State), "logs"]),
+ [{dir, undefined, "dir", {string, DefaultTestDir}, help(dir)}, %% dir
+ {suite, undefined, "suite", string, help(suite)}, %% comma-seperated list
+ {group, undefined, "group", string, help(group)}, %% comma-seperated list
+ {testcase, undefined, "case", string, help(testcase)}, %% comma-seperated list
+ {spec, undefined, "spec", string, help(spec)}, %% comma-seperated list
+ {join_specs, undefined, "join_specs", boolean, help(join_specs)}, %% Boolean
+ {label, undefined, "label", string, help(label)}, %% String
+ {config, undefined, "config", string, help(config)}, %% comma-seperated list
+ {userconfig, undefined, "userconfig", string, help(userconfig)}, %% [{CallbackMod, CfgStrings}] | {CallbackMod, CfgStrings}
+ {allow_user_terms, undefined, "allow_user_terms", boolean, help(allow_user_terms)}, %% Bool
+ {logdir, undefined, "logdir", {string, DefaultLogsDir}, help(logdir)}, %% string
+ {logopts, undefined, "logopts", string, help(logopts)}, %% enum, no_nl | no_src
+ {verbosity, undefined, "verbosity", string, help(verbosity)}, %% Integer OR [{Category, VLevel}]
+ {silent_connections, undefined, "silent_connections", string,
+ help(silent_connections)}, % all OR %% comma-seperated list
+ {stylesheet, undefined, "stylesheet", string, help(stylesheet)}, %% file
+ {cover, undefined, "cover", string, help(cover)}, %% file
+ {cover_stop, undefined, "cover_stop", boolean, help(cover_stop)}, %% Boolean
+ {event_handler, undefined, "event_handler", string, help(event_handler)}, %% EH | [EH] WHERE EH atom() | {atom(), InitArgs} | {[atom()], InitArgs}
+ {include, undefined, "include", string, help(include)},
+ {abort_if_missing_suites, undefined, "abort_if_missing_suites", {boolean, true},
+ help(abort_if_missing_suites)}, %% boolean
+ {multiply_timetraps, undefined, "multiply_timetraps", integer,
+ help(multiply_timetraps)}, %% integer
+ {scale_timetraps, undefined, "scale_timetraps", boolean, help(scale_timetraps)}, %% Boolean
+ {create_priv_dir, undefined, "create_priv_dir", string, help(create_priv_dir)}, %% enum: auto_per_run | auto_per_tc | manual_per_tc
+ {repeat, undefined, "repeat", integer, help(repeat)}, %% integer
+ {duration, undefined, "duration", string, help(duration)}, % format: HHMMSS
+ {until, undefined, "until", string, help(until)}, %% format: YYMoMoDD[HHMMSS]
+ {force_stop, undefined, "force_stop", string, help(force_stop)}, % enum: skip_rest, bool
+ {basic_html, undefined, "basic_html", boolean, help(basic_html)}, %% Booloean
+ {ct_hooks, undefined, "ct_hooks", string, help(ct_hooks)} %% List: [CTHModule | {CTHModule, CTHInitArgs}] where CTHModule is atom CthInitArgs is term
+ ].
+
+help(dir) ->
+ "Test folder (default: test/)";
+help(suite) ->
+ "List of test suites to run";
+help(group) ->
+ "List of test groups to run";
+help(testcase) ->
+ "List of test cases to run";
+help(spec) ->
+ "List of test specs to run";
+help(join_specs) ->
+ ""; %% ??
+help(label) ->
+ "Test label";
+help(config) ->
+ "List of config files";
+help(allow_user_terms) ->
+ ""; %% ??
+help(logdir) ->
+ "Log folder";
+help(logopts) ->
+ ""; %% ??
+help(verbosity) ->
+ "Verbosity";
+help(silent_connections) ->
+ ""; %% ??
+help(stylesheet) ->
+ "Stylesheet to use for test results";
+help(cover) ->
+ "Cover file to use";
+help(cover_stop) ->
+ ""; %% ??
+help(event_handler) ->
+ "Event handlers to attach to the runner";
+help(include) ->
+ "Include folder";
+help(abort_if_missing_suites) ->
+ "Abort if suites are missing";
+help(multiply_timetraps) ->
+ ""; %% ??
+help(scale_timetraps) ->
+ ""; %% ??
+help(create_priv_dir) ->
+ ""; %% ??
+help(repeat) ->
+ "How often to repeat tests";
+help(duration) ->
+ "Max runtime (format: HHMMSS)";
+help(until) ->
+ "Run until (format: HHMMSS)";
+help(force_stop) ->
+ "Force stop after time";
+help(basic_html) ->
+ "Show basic HTML";
+help(ct_hooks) ->
+ "";
+help(userconfig) ->
+ "".
+
+build_options(State) ->
+ Arguments = rebar_state:command_args(State),
+ Opts = parse_args(Arguments, []),
+ lists:keymerge(1, Opts, defaults(State)).
+
+defaults(State) ->
+ Logdir = filename:join([rebar_state:dir(State), "logs"]),
+ ok = ensure_logdir(Logdir),
+ Testdir = filename:join([rebar_state:dir(State), "test"]),
+ ok = ensure_testdir(Testdir),
+ [{dir, Testdir},
+ {logdir, Logdir}].
+
+parse_args([], Opts) ->
+ Opts;
+parse_args([Pair|Rest], Opts) ->
+ [Key, Val] = string:tokens(Pair, "="),
+ Key0 = list_to_atom(Key),
+ parse_args(Rest, [{Key0, string:tokens(Val, " ")}|Opts]).
+
+ensure_logdir(Logdir) ->
+ case ec_file:is_dir(Logdir) of
+ true ->
+ ok;
+ false ->
+ ec_file:mkdir_path(Logdir)
+ end.
+
+ensure_testdir(Testdir) ->
+ case ec_file:is_dir(Testdir) of
+ false ->
+ ?INFO("Test directory ~s does not exist:\n",
+ [Testdir]),
+ ?FAIL;
+ _ -> ok
+ end.