summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralisdair sullivan <alisdairsullivan@yahoo.ca>2015-10-15 19:58:42 -0700
committeralisdair sullivan <alisdair.sullivan@askuity.com>2015-11-01 18:54:57 -0800
commit19a3a96893ec8978233e2a815a61e26bfa86c4e0 (patch)
treece1057b9e1ba55079abf84deff5719c81a2a9d19
parent8fcfbfc4beb39e546559574b04312318f0b07740 (diff)
refactor `rebar_prv_common_test`
* remove partial support for ct `test_spec` until it can be done properly and warn if `test_spec` is present in test opts * use new compiler functionality to reduce complexity of provider * reduce command line options available to those that can be supported properly
-rw-r--r--src/rebar_prv_common_test.erl684
-rw-r--r--test/rebar_ct_SUITE.erl311
2 files changed, 455 insertions, 540 deletions
diff --git a/src/rebar_prv_common_test.erl b/src/rebar_prv_common_test.erl
index 32d4433..910a1ca 100644
--- a/src/rebar_prv_common_test.erl
+++ b/src/rebar_prv_common_test.erl
@@ -2,19 +2,21 @@
%% ex: ts=4 sw=4 et
-module(rebar_prv_common_test).
+
-behaviour(provider).
-export([init/1,
do/1,
format_error/1]).
%% exported for test purposes, consider private
--export([setup_ct/1]).
+-export([compile/2, prepare_tests/1, translate_paths/2]).
-include("rebar.hrl").
-include_lib("providers/include/providers.hrl").
-define(PROVIDER, ct).
--define(DEPS, [compile]).
+%% we need to modify app_info state before compile
+-define(DEPS, [lock]).
%% ===================================================================
%% Public API
@@ -31,12 +33,19 @@ init(State) ->
{desc, "Run Common Tests."},
{opts, ct_opts(State)},
{profiles, [test]}]),
- State1 = rebar_state:add_provider(State, Provider),
- State2 = rebar_state:add_to_profile(State1, test, test_state(State1)),
- {ok, State2}.
+ {ok, rebar_state:add_provider(State, Provider)}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
+ Tests = prepare_tests(State),
+ case compile(State, Tests) of
+ %% successfully compiled apps
+ {ok, S} -> do(S, Tests);
+ %% this should look like a compiler error, not a ct error
+ Error -> Error
+ end.
+
+do(State, Tests) ->
?INFO("Running Common Test suites...", []),
rebar_utils:update_code(rebar_state:code_paths(State, all_deps), [soft_purge]),
@@ -45,61 +54,308 @@ do(State) ->
Cwd = rebar_dir:get_cwd(),
rebar_hooks:run_all_hooks(Cwd, pre, ?PROVIDER, Providers, State),
- try run_test(State) of
- {ok, State1} = Result ->
- %% Run ct provider posthooks
- rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State1),
- rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
- Result;
- ?PRV_ERROR(_) = Error ->
+ case Tests of
+ {ok, T} ->
+ case run_tests(State, T) of
+ ok ->
+ %% Run ct provider posthooks
+ rebar_hooks:run_all_hooks(Cwd, post, ?PROVIDER, Providers, State),
+ rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
+ {ok, State};
+ Error ->
+ rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
+ Error
+ end;
+ Error ->
rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
Error
- catch
- throw:{error, Reason} ->
- rebar_utils:cleanup_code_path(rebar_state:code_paths(State, default)),
- ?PRV_ERROR(Reason)
+ end.
+
+run_tests(State, Opts) ->
+ T = translate_paths(State, Opts),
+ Opts1 = setup_logdir(State, T),
+ %% strip test spec if present
+ Opts2 = strip_test_spec(Opts1),
+ ?DEBUG("ct_opts ~p", [Opts2]),
+ {RawOpts, _} = rebar_state:command_parsed_args(State),
+ ok = maybe_write_coverdata(State),
+ case proplists:get_value(verbose, RawOpts, false) of
+ true -> run_test_verbose(Opts2);
+ false -> run_test_quiet(Opts2)
end.
-spec format_error(any()) -> iolist().
-format_error({multiple_dirs_and_suites, Opts}) ->
- io_lib:format("Multiple dirs declared alongside suite in opts: ~p", [Opts]);
-format_error({bad_dir_or_suite, Opts}) ->
- io_lib:format("Bad value for dir or suite in opts: ~p", [Opts]);
+format_error({error, Reason}) ->
+ io_lib:format("Error running tests:~n ~p", [Reason]);
+format_error({error_running_tests, Reason}) ->
+ format_error({error, Reason});
format_error({failures_running_tests, {Failed, AutoSkipped}}) ->
io_lib:format("Failures occured running tests: ~b", [Failed+AutoSkipped]);
-format_error({error_running_tests, Reason}) ->
- io_lib:format("Error running tests: ~p", [Reason]);
-format_error(suite_at_project_root) ->
- io_lib:format("Test suites can't be located in project root", []);
-format_error({error, Reason}) ->
- io_lib:format("Unknown error: ~p", [Reason]).
+format_error({multiple_errors, Errors}) ->
+ io_lib:format(lists:concat(["Error running tests:"] ++
+ lists:map(fun(Error) -> "~n " ++ Error end, Errors)), []).
%% ===================================================================
%% Internal functions
%% ===================================================================
-run_test(State) ->
- case setup_ct(State) of
- {error, {no_tests_specified, Opts}} ->
- ?WARN("No tests specified in opts: ~p", [Opts]),
- {ok, State};
- Opts ->
- Opts1 = setup_logdir(State, Opts),
- ?DEBUG("common test opts: ~p", [Opts1]),
- run_test(State, Opts1)
- end.
+prepare_tests(State) ->
+ %% command line test options
+ CmdOpts = opts(State),
+ %% rebar.config test options
+ CfgOpts = rebar_state:get(State, ct_tests, []),
+ ProjectApps = rebar_state:project_apps(State),
+ %% prioritize tests to run first trying any command line specified
+ %% tests falling back to tests specified in the config file finally
+ %% running a default set if no other tests are present
+ select_tests(State, ProjectApps, CmdOpts, CfgOpts).
-run_test(State, Opts) ->
+opts(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),
- ok = rebar_prv_cover:maybe_cover_compile(State, apps),
- Result = case proplists:get_value(verbose, RawOpts, false) of
- true -> run_test_verbose(Opts);
- false -> run_test_quiet(Opts)
+ %% filter out opts common_test doesn't know about and convert
+ %% to ct acceptable forms
+ transform_opts(RawOpts, []).
+
+transform_opts([], Acc) -> lists:reverse(Acc);
+transform_opts([{dir, Dirs}|Rest], Acc) ->
+ transform_opts(Rest, [{dir, split_string(Dirs)}|Acc]);
+transform_opts([{suite, Suites}|Rest], Acc) ->
+ transform_opts(Rest, [{suite, split_string(Suites)}|Acc]);
+transform_opts([{group, Groups}|Rest], Acc) ->
+ transform_opts(Rest, [{group, split_string(Groups)}|Acc]);
+transform_opts([{testcase, Cases}|Rest], Acc) ->
+ transform_opts(Rest, [{testcase, split_string(Cases)}|Acc]);
+transform_opts([{config, Configs}|Rest], Acc) ->
+ transform_opts(Rest, [{config, split_string(Configs)}|Acc]);
+transform_opts([{include, Includes}|Rest], Acc) ->
+ transform_opts(Rest, [{include, split_string(Includes)}|Acc]);
+transform_opts([{force_stop, "true"}|Rest], Acc) ->
+ transform_opts(Rest, [{force_stop, true}|Acc]);
+transform_opts([{force_stop, "false"}|Rest], Acc) ->
+ transform_opts(Rest, [{force_stop, false}|Acc]);
+transform_opts([{force_stop, "skip_rest"}|Rest], Acc) ->
+ transform_opts(Rest, [{force_stop, skip_rest}|Acc]);
+%% drop cover from opts, ct doesn't care about it
+transform_opts([{cover, _}|Rest], Acc) ->
+ transform_opts(Rest, Acc);
+%% drop verbose from opts, ct doesn't care about it
+transform_opts([{verbose, _}|Rest], Acc) ->
+ transform_opts(Rest, Acc);
+%% getopt should handle anything else
+transform_opts([Opt|Rest], Acc) ->
+ transform_opts(Rest, [Opt|Acc]).
+
+split_string(String) ->
+ string:tokens(String, [$,]).
+
+select_tests(State, ProjectApps, CmdOpts, CfgOpts) ->
+ Merged = lists:ukeymerge(1,
+ lists:ukeysort(1, CmdOpts),
+ lists:ukeysort(1, CfgOpts)),
+ %% make sure `dir` and/or `suite` from command line go in as
+ %% a pair overriding both `dir` and `suite` from config if
+ %% they exist
+ Opts = case {proplists:get_value(suite, CmdOpts), proplists:get_value(dir, CmdOpts)} of
+ {undefined, undefined} -> Merged;
+ {_Suite, undefined} -> lists:keydelete(dir, 1, Merged);
+ {undefined, _Dir} -> lists:keydelete(suite, 1, Merged);
+ {_Suite, _Dir} -> Merged
end,
- ok = rebar_prv_cover:maybe_write_coverdata(State, ?PROVIDER),
- case Result of
- ok -> {ok, State};
- Error -> Error
+ discover_tests(State, ProjectApps, Opts).
+
+discover_tests(State, ProjectApps, Opts) ->
+ case {proplists:get_value(suite, Opts), proplists:get_value(dir, Opts)} of
+ %% no dirs or suites defined, try using `$APP/test` and `$ROOT/test`
+ %% as suites
+ {undefined, undefined} -> {ok, [default_tests(State, ProjectApps)|Opts]};
+ {_, _} -> {ok, Opts}
+ end.
+
+default_tests(State, ProjectApps) ->
+ BareTest = filename:join([rebar_state:dir(State), "test"]),
+ F = fun(App) -> rebar_app_info:dir(App) == rebar_state:dir(State) end,
+ AppTests = application_dirs(ProjectApps, []),
+ case filelib:is_dir(BareTest) andalso not lists:any(F, ProjectApps) of
+ %% `test` dir at root of project is already scheduled to be
+ %% included or `test` does not exist
+ false -> {dir, AppTests};
+ %% need to add `test` dir at root to dirs to be included
+ true -> {dir, AppTests ++ [BareTest]}
+ end.
+
+application_dirs([], []) -> [];
+application_dirs([], Acc) -> lists:reverse(Acc);
+application_dirs([App|Rest], Acc) ->
+ TestDir = filename:join([rebar_app_info:dir(App), "test"]),
+ case filelib:is_dir(TestDir) of
+ true -> application_dirs(Rest, [TestDir|Acc]);
+ false -> application_dirs(Rest, Acc)
+ end.
+
+compile(State, {ok, Tests}) ->
+ %% inject `ct_first_files` and `ct_compile_opts` into the applications
+ %% to be compiled
+ case inject_ct_state(State, Tests) of
+ {ok, NewState} -> do_compile(NewState);
+ Error -> Error
+ end;
+%% maybe compile even in the face of errors?
+compile(_State, Error) -> Error.
+
+do_compile(State) ->
+ case rebar_prv_compile:do(State) of
+ %% successfully compiled apps
+ {ok, S} ->
+ ok = maybe_cover_compile(S),
+ {ok, S};
+ %% this should look like a compiler error, not an eunit error
+ Error -> Error
+ end.
+
+inject_ct_state(State, Tests) ->
+ Apps = rebar_state:project_apps(State),
+ ModdedApps = lists:map(fun(App) ->
+ NewOpts = inject(rebar_app_info:opts(App), State),
+ rebar_app_info:opts(App, NewOpts)
+ end, Apps),
+ NewOpts = inject(rebar_state:opts(State), State),
+ NewState = rebar_state:opts(State, NewOpts),
+ test_dirs(NewState, ModdedApps, Tests).
+
+inject(Opts, State) ->
+ %% append `ct_compile_opts` to app defined `erl_opts`
+ ErlOpts = rebar_opts:get(Opts, erl_opts, []),
+ CTOpts = rebar_state:get(State, ct_compile_opts, []),
+ NewErlOpts = CTOpts ++ ErlOpts,
+ %% append `ct_first_files` to app defined `erl_first_files`
+ FirstFiles = rebar_opts:get(Opts, erl_first_files, []),
+ CTFirstFiles = rebar_state:get(State, ct_first_files, []),
+ NewFirstFiles = CTFirstFiles ++ FirstFiles,
+ %% insert the new keys into the opts
+ lists:foldl(fun({K, V}, NewOpts) -> rebar_opts:set(NewOpts, K, V) end,
+ Opts,
+ [{erl_opts, NewErlOpts}, {erl_first_files, NewFirstFiles}]).
+
+test_dirs(State, Apps, Opts) ->
+ case {proplists:get_value(suite, Opts), proplists:get_value(dir, Opts)} of
+ {Suites, undefined} -> set_compile_dirs(State, Apps, {suite, Suites});
+ {undefined, Dirs} -> set_compile_dirs(State, Apps, {dir, Dirs});
+ {Suites, [Dir]} -> set_compile_dirs(State, Apps, join(Suites, Dir));
+ {_Suites, _Dirs} -> {error, "Only a single directory may be specified when specifying suites"}
+ end.
+
+join(Suites, Dir) ->
+ {suite, lists:map(fun(S) -> filename:join([Dir, S]) end, Suites)}.
+
+set_compile_dirs(State, Apps, {dir, Dir}) when is_integer(hd(Dir)) ->
+ %% single directory
+ %% insert `Dir` into an app if relative, or the base state if not
+ %% app relative but relative to the root or not at all if outside
+ %% project scope
+ {NewState, NewApps} = maybe_inject_test_dir(State, [], Apps, Dir),
+ {ok, rebar_state:project_apps(NewState, NewApps)};
+set_compile_dirs(State, Apps, {dir, Dirs}) ->
+ %% multiple directories
+ F = fun(Dir, {S, A}) -> maybe_inject_test_dir(S, [], A, Dir) end,
+ {NewState, NewApps} = lists:foldl(F, {State, Apps}, Dirs),
+ {ok, rebar_state:project_apps(NewState, NewApps)};
+set_compile_dirs(State, Apps, {suite, Suites}) ->
+ %% suites with dir component
+ Dirs = find_suite_dirs(Suites),
+ F = fun(Dir, {S, A}) -> maybe_inject_test_dir(S, [], A, Dir) end,
+ {NewState, NewApps} = lists:foldl(F, {State, Apps}, Dirs),
+ {ok, rebar_state:project_apps(NewState, NewApps)}.
+
+find_suite_dirs(Suites) ->
+ AllDirs = lists:map(fun(S) -> filename:dirname(filename:absname(S)) end, Suites),
+ %% eliminate duplicates
+ lists:usort(AllDirs).
+
+maybe_inject_test_dir(State, AppAcc, [App|Rest], Dir) ->
+ case rebar_file_utils:path_from_ancestor(Dir, rebar_app_info:dir(App)) of
+ {ok, Path} ->
+ Opts = inject_test_dir(rebar_app_info:opts(App), Path),
+ {State, AppAcc ++ [rebar_app_info:opts(App, Opts)] ++ Rest};
+ {error, badparent} ->
+ maybe_inject_test_dir(State, AppAcc ++ [App], Rest, Dir)
+ end;
+maybe_inject_test_dir(State, AppAcc, [], Dir) ->
+ case rebar_file_utils:path_from_ancestor(Dir, rebar_state:dir(State)) of
+ {ok, []} ->
+ ?WARN("Can't have suites in root of project dir, dropping from tests", []),
+ {State, AppAcc};
+ {ok, Path} ->
+ Opts = inject_test_dir(rebar_state:opts(State), Path),
+ {rebar_state:opts(State, Opts), AppAcc};
+ {error, badparent} ->
+ {State, AppAcc}
+ end.
+
+inject_test_dir(Opts, Dir) ->
+ %% append specified test targets to app defined `extra_src_dirs`
+ ExtraSrcDirs = rebar_opts:get(Opts, extra_src_dirs, []),
+ rebar_opts:set(Opts, extra_src_dirs, ExtraSrcDirs ++ [Dir]).
+
+translate_paths(State, Opts) ->
+ case {proplists:get_value(suite, Opts), proplists:get_value(dir, Opts)} of
+ {_Suites, undefined} -> translate_suites(State, Opts, []);
+ {undefined, _Dirs} -> translate_dirs(State, Opts, []);
+ %% both dirs and suites are defined, only translate dir paths
+ _ -> translate_dirs(State, Opts, [])
+ end.
+
+translate_dirs(_State, [], Acc) -> lists:reverse(Acc);
+translate_dirs(State, [{dir, Dir}|Rest], Acc) when is_integer(hd(Dir)) ->
+ %% single dir
+ Apps = rebar_state:project_apps(State),
+ translate_dirs(State, Rest, [{dir, translate(State, Apps, Dir)}|Acc]);
+translate_dirs(State, [{dir, Dirs}|Rest], Acc) ->
+ %% multiple dirs
+ Apps = rebar_state:project_apps(State),
+ NewDirs = {dir, lists:map(fun(Dir) -> translate(State, Apps, Dir) end, Dirs)},
+ translate_dirs(State, Rest, [NewDirs|Acc]);
+translate_dirs(State, [Test|Rest], Acc) ->
+ translate_dirs(State, Rest, [Test|Acc]).
+
+translate_suites(_State, [], Acc) -> lists:reverse(Acc);
+translate_suites(State, [{suite, Suite}|Rest], Acc) when is_integer(hd(Suite)) ->
+ %% single suite
+ Apps = rebar_state:project_apps(State),
+ translate_suites(State, Rest, [{suite, translate(State, Apps, Suite)}|Acc]);
+translate_suites(State, [{suite, Suites}|Rest], Acc) ->
+ %% multiple suites
+ Apps = rebar_state:project_apps(State),
+ NewSuites = {suite, lists:map(fun(Suite) -> translate(State, Apps, Suite) end, Suites)},
+ translate_suites(State, Rest, [NewSuites|Acc]);
+translate_suites(State, [Test|Rest], Acc) ->
+ translate_suites(State, Rest, [Test|Acc]).
+
+translate(State, [App|Rest], Path) ->
+ case rebar_file_utils:path_from_ancestor(Path, rebar_app_info:dir(App)) of
+ {ok, P} -> filename:join([rebar_app_info:out_dir(App), P]);
+ {error, badparent} -> translate(State, Rest, Path)
+ end;
+translate(State, [], Path) ->
+ case rebar_file_utils:path_from_ancestor(Path, rebar_state:dir(State)) of
+ {ok, P} -> filename:join([rebar_dir:base_dir(State), "extras", P]);
+ %% not relative, leave as is
+ {error, badparent} -> Path
+ end.
+
+setup_logdir(State, Opts) ->
+ Logdir = case proplists:get_value(logdir, Opts) of
+ undefined -> filename:join([rebar_dir:base_dir(State), "logs"]);
+ Dir -> Dir
+ end,
+ filelib:ensure_dir(filename:join([Logdir, "dummy.beam"])),
+ [{logdir, Logdir}|lists:keydelete(logdir, 1, Opts)].
+
+strip_test_spec(Opts) ->
+ case proplists:get_value(test_spec, Opts) of
+ undefined -> Opts;
+ _ ->
+ ?WARN("Test specs not supported", []),
+ lists:keydelete(test_spec, 1, Opts)
end.
run_test_verbose(Opts) -> handle_results(ct:run_test(Opts)).
@@ -171,272 +427,38 @@ format_skipped({0, 0}) ->
format_skipped({User, Auto}) ->
io_lib:format("Skipped ~p (~p, ~p) tests. ", [User+Auto, User, Auto]).
-test_state(State) ->
- TestOpts = case rebar_state:get(State, ct_compile_opts, []) of
- [] -> [];
- Opts -> [{erl_opts, Opts}]
- end,
- [first_files(State)|TestOpts].
-
-first_files(State) ->
- CTFirst = rebar_state:get(State, ct_first_files, []),
- {erl_first_files, CTFirst}.
-
-setup_ct(State) ->
- Opts = resolve_ct_opts(State),
- Opts1 = discover_tests(State, Opts),
- copy_and_compile_tests(State, Opts1).
-
-resolve_ct_opts(State) ->
- {RawOpts, _} = rebar_state:command_parsed_args(State),
- CmdOpts = transform_opts(RawOpts),
- CfgOpts = rebar_state:get(State, ct_opts, []),
- Merged = lists:ukeymerge(1,
- lists:ukeysort(1, CmdOpts),
- lists:ukeysort(1, CfgOpts)),
- %% make sure `dir` and/or `suite` from command line go in as
- %% a pair overriding both `dir` and `suite` from config if
- %% they exist
- case {proplists:get_value(suite, CmdOpts), proplists:get_value(dir, CmdOpts)} of
- {undefined, undefined} -> Merged;
- {_Suite, undefined} -> lists:keydelete(dir, 1, Merged);
- {undefined, _Dir} -> lists:keydelete(suite, 1, Merged);
- {_Suite, _Dir} -> Merged
- end.
-
-discover_tests(State, Opts) ->
- case proplists:get_value(spec, Opts) of
- undefined -> discover_dirs_and_suites(State, Opts);
- TestSpec -> discover_testspec(TestSpec, Opts)
- end.
-
-discover_dirs_and_suites(State, Opts) ->
- case {proplists:get_value(dir, Opts), proplists:get_value(suite, Opts)} of
- %% no dirs or suites defined, try using `$APP/test` and `$ROOT/test`
- %% as suites
- {undefined, undefined} -> test_dirs(State, Opts);
- %% no dirs defined
- {undefined, _} -> Opts;
- %% no suites defined
- {_, undefined} -> Opts;
- %% a single dir defined, this is ok
- {Dirs, Suites} when is_integer(hd(Dirs)), is_list(Suites) -> Opts;
- %% still a single dir defined, adjust to make acceptable to ct
- {[Dir], Suites} when is_integer(hd(Dir)), is_list(Suites) ->
- [{dir, Dir}|lists:keydelete(dir, 1, Opts)];
- %% multiple dirs and suites, error now to simplify later steps
- {_, _} -> throw({error, {multiple_dirs_and_suites, Opts}})
- end.
-
-discover_testspec(_TestSpec, Opts) ->
- lists:keydelete(auto_compile, 1, Opts).
-
-copy_and_compile_tests(State, Opts) ->
- %% possibly enable cover
+maybe_cover_compile(State) ->
{RawOpts, _} = rebar_state:command_parsed_args(State),
State1 = case proplists:get_value(cover, RawOpts, false) of
true -> rebar_state:set(State, cover_enabled, true);
false -> State
end,
- copy_and_compile_test_suites(State1, Opts).
-
-copy_and_compile_test_suites(State, Opts) ->
- case proplists:get_value(suite, Opts) of
- %% no suites, try dirs
- undefined -> copy_and_compile_test_dirs(State, Opts);
- Suites ->
- Dir = proplists:get_value(dir, Opts, undefined),
- AllSuites = join(Dir, Suites),
- Dirs = find_suite_dirs(AllSuites),
- lists:foreach(fun(S) ->
- NewPath = copy(State, S),
- compile_dir(State, NewPath)
- end, Dirs),
- NewSuites = lists:map(fun(S) -> retarget_path(State, S) end, AllSuites),
- [{suite, NewSuites}|lists:keydelete(suite, 1, Opts)]
- end.
-
-copy_and_compile_test_dirs(State, Opts) ->
- case proplists:get_value(dir, Opts) of
- undefined -> {error, {no_tests_specified, Opts}};
- %% dir is a single directory
- Dir when is_list(Dir), is_integer(hd(Dir)) ->
- NewPath = copy(State, Dir),
- [{dir, compile_dir(State, NewPath)}|lists:keydelete(dir, 1, Opts)];
- %% dir is a list of directories
- Dirs when is_list(Dirs) ->
- NewDirs = lists:map(fun(Dir) ->
- NewPath = copy(State, Dir),
- compile_dir(State, NewPath)
- end, Dirs),
- [{dir, NewDirs}|lists:keydelete(dir, 1, Opts)]
- end.
-
-join(undefined, Suites) -> Suites;
-join(Dir, Suites) when is_list(Dir), is_integer(hd(Dir)) ->
- lists:map(fun(S) -> filename:join([Dir, S]) end, Suites);
-%% multiple dirs or a bad dir argument, try to continue anyways
-join(_, Suites) -> Suites.
-
-find_suite_dirs(Suites) ->
- AllDirs = lists:map(fun(S) -> filename:dirname(filename:absname(S)) end, Suites),
- %% eliminate duplicates
- lists:usort(AllDirs).
-
-copy(State, Dir) ->
- From = reduce_path(Dir),
- retarget_path(State, From).
-
-compile_dir(State, Dir) ->
- NewState = replace_src_dirs(State, [filename:absname(Dir)]),
- ok = rebar_erlc_compiler:compile(rebar_state:opts(NewState), rebar_dir:base_dir(State), Dir),
- ok = maybe_cover_compile(State, Dir),
- Dir.
-
-retarget_path(State, Path) ->
- ProjectApps = rebar_state:project_apps(State),
- retarget_path(State, Path, ProjectApps).
-
-%% not relative to any apps in project, check to see it's relative to
-%% project root
-retarget_path(State, Path, []) ->
- case relative_path(reduce_path(Path), rebar_state:dir(State)) of
- {ok, NewPath} -> filename:join([rebar_dir:base_dir(State), NewPath]);
- %% not relative to project root, don't modify
- {error, not_relative} -> Path
- end;
-%% relative to current app, retarget to the same dir relative to
-%% the app's out_dir
-retarget_path(State, Path, [App|Rest]) ->
- case relative_path(reduce_path(Path), rebar_app_info:dir(App)) of
- {ok, NewPath} -> filename:join([rebar_app_info:out_dir(App), NewPath]);
- {error, not_relative} -> retarget_path(State, Path, Rest)
- end.
-
-relative_path(Target, To) ->
- relative_path1(filename:split(filename:absname(Target)),
- filename:split(filename:absname(To))).
-
-relative_path1([Part|Target], [Part|To]) -> relative_path1(Target, To);
-relative_path1([], []) -> {ok, ""};
-relative_path1(Target, []) -> {ok, filename:join(Target)};
-relative_path1(_, _) -> {error, not_relative}.
-
-reduce_path(Dir) -> reduce_path([], filename:split(filename:absname(Dir))).
-
-reduce_path([], []) -> filename:nativename("/");
-reduce_path(Acc, []) -> filename:join(lists:reverse(Acc));
-reduce_path(Acc, ["."|Rest]) -> reduce_path(Acc, Rest);
-reduce_path([_|Acc], [".."|Rest]) -> reduce_path(Acc, Rest);
-reduce_path([], [".."|Rest]) -> reduce_path([], Rest);
-reduce_path(Acc, [Component|Rest]) -> reduce_path([Component|Acc], Rest).
-
-replace_src_dirs(State, Dirs) ->
- %% replace any `src_dirs` with the test dirs
- ErlOpts = rebar_state:get(State, erl_opts, []),
- StrippedErlOpts = filter_src_dirs(ErlOpts),
- State1 = rebar_state:set(State, erl_opts, StrippedErlOpts),
- State2 = rebar_state:set(State1, src_dirs, []),
- rebar_state:set(State2, extra_src_dirs, Dirs).
+ rebar_prv_cover:maybe_cover_compile(State1).
-filter_src_dirs(ErlOpts) ->
- lists:filter(fun({src_dirs, _}) -> false; ({extra_src_dirs, _}) -> false; (_) -> true end, ErlOpts).
-
-test_dirs(State, Opts) ->
- BareTest = filename:join([rebar_state:dir(State), "test"]),
- F = fun(App) -> rebar_app_info:dir(App) == rebar_state:dir(State) end,
- TestApps = project_apps(State),
- case filelib:is_dir(BareTest) andalso not lists:any(F, TestApps) of
- %% `test` dir at root of project is already scheduled to be
- %% included or `test` does not exist
- false -> application_dirs(TestApps, Opts, []);
- %% need to add `test` dir at root to dirs to be included
- true -> application_dirs(TestApps, Opts, [BareTest])
- end.
-
-project_apps(State) ->
- filter_checkouts(rebar_state:project_apps(State)).
-
-filter_checkouts(Apps) -> filter_checkouts(Apps, []).
-
-filter_checkouts([], Acc) -> lists:reverse(Acc);
-filter_checkouts([App|Rest], Acc) ->
- case rebar_app_info:is_checkout(App) of
- true -> filter_checkouts(Rest, Acc);
- false -> filter_checkouts(Rest, [App|Acc])
- end.
-
-application_dirs([], Opts, []) -> Opts;
-application_dirs([], Opts, [Acc]) -> [{dir, Acc}|Opts];
-application_dirs([], Opts, Acc) -> [{dir, lists:reverse(Acc)}|Opts];
-application_dirs([App|Rest], Opts, Acc) ->
- TestDir = filename:join([rebar_app_info:dir(App), "test"]),
- case filelib:is_dir(TestDir) of
- true -> application_dirs(Rest, Opts, [TestDir|Acc]);
- false -> application_dirs(Rest, Opts, Acc)
- end.
-
-setup_logdir(State, Opts) ->
- Logdir = case proplists:get_value(logdir, Opts) of
- undefined -> filename:join([rebar_dir:base_dir(State), "logs"]);
- Dir -> Dir
- end,
- ensure_dir([Logdir]),
- [{logdir, Logdir}|lists:keydelete(logdir, 1, Opts)].
-
-ensure_dir([]) -> ok;
-ensure_dir([Dir|Rest]) ->
- case ec_file:is_dir(Dir) of
- true ->
- ok;
- false ->
- ec_file:mkdir_path(Dir)
- end,
- ensure_dir(Rest).
-
-maybe_cover_compile(State, Dir) ->
- {Opts, _} = rebar_state:command_parsed_args(State),
- State1 = case proplists:get_value(cover, Opts, false) of
+maybe_write_coverdata(State) ->
+ {RawOpts, _} = rebar_state:command_parsed_args(State),
+ State1 = case proplists:get_value(cover, RawOpts, false) of
true -> rebar_state:set(State, cover_enabled, true);
false -> State
end,
- rebar_prv_cover:maybe_cover_compile(State1, [Dir]).
+ rebar_prv_cover:maybe_write_coverdata(State1, ?PROVIDER).
ct_opts(_State) ->
[{dir, undefined, "dir", string, help(dir)}, %% comma-seperated list
{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, help(logdir)}, %% dir
- {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
+ {verbosity, undefined, "verbosity", integer, help(verbosity)}, %% Integer
{cover, $c, "cover", {boolean, false}, help(cover)},
- {cover_spec, undefined, "cover_spec", string, help(cover_spec)}, %% 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)}, % comma-seperated list
- {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
- {auto_compile, undefined, "auto_compile", {boolean, false}, help(auto_compile)},
{verbose, $v, "verbose", boolean, help(verbose)}
].
@@ -448,36 +470,26 @@ 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(label) ->
"Test label";
help(config) ->
"List of config files";
+help(allow_user_terms) ->
+ "Allow user defined config values in config files";
help(logdir) ->
"Log folder";
help(verbosity) ->
"Verbosity";
-help(stylesheet) ->
- "Stylesheet to use for test results";
help(cover) ->
"Generate cover data";
-help(cover_spec) ->
- "Cover file to use";
-help(event_handler) ->
- "Event handlers to attach to the runner";
help(include) ->
- "Include folder";
-help(abort_if_missing_suites) ->
- "Abort if suites are missing";
+ "Include folders";
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(verbose) ->
@@ -485,77 +497,3 @@ help(verbose) ->
help(_) ->
"".
-transform_opts(Opts) ->
- transform_opts(Opts, []).
-
-transform_opts([], Acc) -> Acc;
-%% drop `cover` and `verbose` so they're not passed as an option to common_test
-transform_opts([{cover, _}|Rest], Acc) ->
- transform_opts(Rest, Acc);
-transform_opts([{cover_spec, CoverSpec}|Rest], Acc) ->
- transform_opts(Rest, [{cover, CoverSpec}|Acc]);
-transform_opts([{verbose, _}|Rest], Acc) ->
- transform_opts(Rest, Acc);
-transform_opts([{ct_hooks, CtHooks}|Rest], Acc) ->
- transform_opts(Rest, [{ct_hooks, parse_term(CtHooks)}|Acc]);
-transform_opts([{force_stop, "skip_rest"}|Rest], Acc) ->
- transform_opts(Rest, [{force_stop, skip_rest}|Acc]);
-transform_opts([{force_stop, _}|Rest], Acc) ->
- transform_opts(Rest, [{force_stop, true}|Acc]);
-transform_opts([{repeat, Repeat}|Rest], Acc) ->
- transform_opts(Rest, [{repeat,
- ec_cnv:to_integer(Repeat)}|Acc]);
-transform_opts([{create_priv_dir, CreatePrivDir}|Rest], Acc) ->
- transform_opts(Rest, [{create_priv_dir,
- to_atoms(CreatePrivDir)}|Acc]);
-transform_opts([{multiply_timetraps, MultiplyTimetraps}|Rest], Acc) ->
- transform_opts(Rest, [{multiply_timetraps,
- ec_cnv:to_integer(MultiplyTimetraps)}|Acc]);
-transform_opts([{event_handler, EventHandler}|Rest], Acc) ->
- transform_opts(Rest, [{event_handler, parse_term(EventHandler)}|Acc]);
-transform_opts([{silent_connections, "all"}|Rest], Acc) ->
- transform_opts(Rest, [{silent_connections, all}|Acc]);
-transform_opts([{silent_connections, SilentConnections}|Rest], Acc) ->
- transform_opts(Rest, [{silent_connections,
- to_atoms(split_string(SilentConnections))}|Acc]);
-transform_opts([{verbosity, Verbosity}|Rest], Acc) ->
- transform_opts(Rest, [{verbosity, parse_term(Verbosity)}|Acc]);
-transform_opts([{logopts, LogOpts}|Rest], Acc) ->
- transform_opts(Rest, [{logopts, to_atoms(split_string(LogOpts))}|Acc]);
-transform_opts([{userconfig, UserConfig}|Rest], Acc) ->
- transform_opts(Rest, [{userconfig, parse_term(UserConfig)}|Acc]);
-transform_opts([{testcase, Testcase}|Rest], Acc) ->
- transform_opts(Rest, [{testcase, to_atoms(split_string(Testcase))}|Acc]);
-transform_opts([{group, Group}|Rest], Acc) -> % @TODO handle ""
- % Input is a list or an atom. It can also be a nested list.
- transform_opts(Rest, [{group, parse_term(Group)}|Acc]);
-transform_opts([{suite, Suite}|Rest], Acc) ->
- transform_opts(Rest, [{suite, split_string(Suite)}|Acc]);
-transform_opts([{Key, Val}|Rest], Acc) when is_list(Val) ->
- % Default to splitting a string on comma, that works fine for both flat
- % lists of which there are many and single-items.
- Val1 = case split_string(Val) of
- [Val2] ->
- Val2;
- Val2 ->
- Val2
- end,
- transform_opts(Rest, [{Key, Val1}|Acc]);
-transform_opts([{Key, Val}|Rest], Acc) ->
- transform_opts(Rest, [{Key, Val}|Acc]).
-
-to_atoms(List) ->
- lists:map(fun(X) -> list_to_atom(X) end, List).
-
-split_string(String) ->
- string:tokens(String, ",").
-
-parse_term(String) ->
- String1 = "[" ++ String ++ "].",
- {ok, Tokens, _} = erl_scan:string(String1),
- case erl_parse:parse_term(Tokens) of
- {ok, [Terms]} ->
- Terms;
- Term ->
- Term
- end.
diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl
index cdd3774..821a16e 100644
--- a/test/rebar_ct_SUITE.erl
+++ b/test/rebar_ct_SUITE.erl
@@ -17,7 +17,6 @@
multi_suite/1,
all_suite/1,
single_dir_and_single_suite/1,
- symlinked_dir_overwritten_fix/1,
data_dir_correct/1]).
-include_lib("common_test/include/ct.hrl").
@@ -39,8 +38,7 @@ groups() -> [{basic_app, [], [basic_app_default_dirs,
single_unmanaged_suite,
multi_suite,
all_suite,
- single_dir_and_single_suite,
- symlinked_dir_overwritten_fix]},
+ single_dir_and_single_suite]},
{data_dirs, [], [data_dir_correct]}].
init_per_group(basic_app, Config) ->
@@ -56,22 +54,14 @@ init_per_group(basic_app, Config) ->
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite(Name)),
- {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "compile"], return),
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
- LibDirs = rebar_dir:lib_dirs(State),
- State1 = rebar_app_discover:do(State, LibDirs),
-
- Providers = rebar_state:providers(State1),
- Namespace = rebar_state:namespace(State1),
- CommandProvider = providers:get_provider(ct, Providers, Namespace),
- GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec, []),
+ Tests = rebar_prv_common_test:prepare_tests(State),
+ {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- State2 = rebar_state:command_parsed_args(State1, GetOptResult),
-
- Result = rebar_prv_common_test:setup_ct(State2),
-
- [{result, Result}, {appnames, [Name]}|C];
+ [{result, Opts}, {appnames, [Name]}|C];
init_per_group(multi_app, Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_"),
@@ -99,22 +89,14 @@ init_per_group(multi_app, Config) ->
ok = filelib:ensure_dir(Suite3),
ok = file:write_file(Suite3, test_suite("extras")),
- {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "compile"], return),
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
- LibDirs = rebar_dir:lib_dirs(State),
- State1 = rebar_app_discover:do(State, LibDirs),
+ Tests = rebar_prv_common_test:prepare_tests(State),
+ {ok, NewState} = rebar_prv_common_test:compile(State, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Providers = rebar_state:providers(State1),
- Namespace = rebar_state:namespace(State1),
- CommandProvider = providers:get_provider(ct, Providers, Namespace),
- GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec, []),
-
- State2 = rebar_state:command_parsed_args(State1, GetOptResult),
-
- Result = rebar_prv_common_test:setup_ct(State2),
-
- [{result, Result}, {appnames, [Name1, Name2]}|C];
+ [{result, Opts}, {appnames, [Name1, Name2]}|C];
init_per_group(dirs_and_suites, Config) ->
C = rebar_test_utils:init_rebar_state(Config, "ct_"),
@@ -142,7 +124,9 @@ init_per_group(dirs_and_suites, Config) ->
ok = filelib:ensure_dir(Suite3),
ok = file:write_file(Suite3, test_suite("extras")),
- [{appnames, [Name1, Name2]}|C];
+ {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
+
+ [{s, State}, {appnames, [Name1, Name2]}|C];
init_per_group(_, Config) -> Config.
end_per_group(_Group, _Config) -> ok.
@@ -152,10 +136,10 @@ basic_app_default_dirs(Config) ->
[Name] = ?config(appnames, Config),
Result = ?config(result, Config),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name, "test"])),
+ Expect = filename:join([AppDir, "_build", "test", "lib", Name, "test"]),
Dir = proplists:get_value(dir, Result),
- Expect = Dir.
+ [Expect] = Dir.
basic_app_default_beams(Config) ->
AppDir = ?config(apps, Config),
@@ -178,7 +162,7 @@ multi_app_default_dirs(Config) ->
Expect1 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1, "test"])),
Expect2 = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name2, "test"])),
- Expect3 = filename:absname(filename:join([AppDir, "_build", "test", "test"])),
+ Expect3 = filename:absname(filename:join([AppDir, "_build", "test", "extras", "test"])),
Dirs = proplists:get_value(dir, Result),
true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Dirs)).
@@ -215,8 +199,7 @@ multi_app_default_beams(Config) ->
single_app_dir(Config) ->
AppDir = ?config(apps, Config),
[Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -233,17 +216,19 @@ single_app_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1, "test"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([AppDir, "_build", "test", "lib", Name1, "test"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_extra_dir(Config) ->
AppDir = ?config(apps, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -257,22 +242,24 @@ single_extra_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "test"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([AppDir, "_build", "test", "extras", "test"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_unmanaged_dir(Config) ->
PrivDir = ?config(priv_dir, Config),
+ State = ?config(s, Config),
Suite = filename:join([PrivDir, "unmanaged_dir", "unmanaged_dir_SUITE.erl"]),
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite("unmanaged_dir")),
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
-
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -285,18 +272,20 @@ single_unmanaged_dir(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = filename:absname(filename:join([PrivDir, "unmanaged_dir"])),
- Dir = proplists:get_value(dir, Result),
+ Expect = filename:join([PrivDir, "unmanaged_dir"]),
+ Dir = proplists:get_value(dir, Opts),
- Expect = Dir.
+ [Expect] = Dir.
single_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -314,24 +303,26 @@ single_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Suite = proplists:get_value(suite, Opts),
- Expect = Suite.
+ [Expect] = Suite.
single_extra_suite(Config) ->
AppDir = ?config(apps, Config),
[_Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -347,27 +338,30 @@ single_extra_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test",
+ "extra_SUITE"]),
+ Suite = proplists:get_value(suite, Opts),
- Expect = Suite.
+ [Expect] = Suite.
single_unmanaged_suite(Config) ->
PrivDir = ?config(priv_dir, Config),
[_Name1, _Name2] = ?config(appnames, Config),
+ State = ?config(s, Config),
Suite = filename:join([PrivDir, "unmanaged", "unmanaged_SUITE.erl"]),
ok = filelib:ensure_dir(Suite),
ok = file:write_file(Suite, test_suite("unmanaged")),
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
-
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -382,20 +376,22 @@ single_unmanaged_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
- Expect = [filename:absname(filename:join([PrivDir,
- "unmanaged",
- "unmanaged_SUITE"]))],
- SuitePath = proplists:get_value(suite, Result),
+ Expect = filename:join([PrivDir,
+ "unmanaged",
+ "unmanaged_SUITE"]),
+ SuitePath = proplists:get_value(suite, Opts),
- Expect = SuitePath.
+ [Expect] = SuitePath.
multi_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -417,31 +413,33 @@ multi_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect1 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"])),
- Expect2 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name2,
- "test",
- Name2 ++ "_SUITE"])),
- Suites = proplists:get_value(suite, Result),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Expect1 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Expect2 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name2,
+ "test",
+ Name2 ++ "_SUITE"]),
+ Suites = proplists:get_value(suite, Opts),
true = (lists:sort([Expect1, Expect2]) == lists:sort(Suites)).
all_suite(Config) ->
AppDir = ?config(apps, Config),
[Name1, Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -465,36 +463,39 @@ all_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect1 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name1,
- "test",
- Name1 ++ "_SUITE"])),
- Expect2 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "lib",
- Name2,
- "test",
- Name2 ++ "_SUITE"])),
- Expect3 = filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"])),
- Suites = proplists:get_value(suite, Result),
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Expect1 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name1,
+ "test",
+ Name1 ++ "_SUITE"]),
+ Expect2 = filename:join([AppDir,
+ "_build",
+ "test",
+ "lib",
+ Name2,
+ "test",
+ Name2 ++ "_SUITE"]),
+ Expect3 = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test",
+ "extra_SUITE"]),
+ Suites = proplists:get_value(suite, Opts),
true = (lists:sort([Expect1, Expect2, Expect3]) == lists:sort(Suites)).
single_dir_and_single_suite(Config) ->
AppDir = ?config(apps, Config),
[_Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
+ State = ?config(s, Config),
LibDirs = rebar_dir:lib_dirs(State),
State1 = rebar_app_discover:do(State, LibDirs),
@@ -509,45 +510,21 @@ single_dir_and_single_suite(Config) ->
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect = [filename:absname(filename:join([AppDir,
- "_build",
- "test",
- "test",
- "extra_SUITE"]))],
- Suite = proplists:get_value(suite, Result),
-
- Expect = Suite.
-
-symlinked_dir_overwritten_fix(Config) ->
- AppDir = ?config(apps, Config),
- [Name1, _Name2] = ?config(appnames, Config),
-
- {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return),
-
- LibDirs = rebar_dir:lib_dirs(State),
- State1 = rebar_app_discover:do(State, LibDirs),
-
- Providers = rebar_state:providers(State1),
- Namespace = rebar_state:namespace(State1),
- CommandProvider = providers:get_provider(ct, Providers, Namespace),
- GetOptSpec = providers:opts(CommandProvider),
- {ok, GetOptResult} = getopt:parse(GetOptSpec,
- ["--dir=" ++ filename:join([AppDir,
- "apps",
- Name1])]),
-
- State2 = rebar_state:command_parsed_args(State1, GetOptResult),
-
- Result = rebar_prv_common_test:setup_ct(State2),
-
- Expect = filename:absname(filename:join([AppDir, "_build", "test", "lib", Name1])),
- Dir = proplists:get_value(dir, Result),
-
- Expect = Dir,
-
- {ok, _} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return).
+ Tests = rebar_prv_common_test:prepare_tests(State2),
+ {ok, NewState} = rebar_prv_common_test:compile(State2, Tests),
+ {ok, T} = Tests,
+ Opts = rebar_prv_common_test:translate_paths(NewState, T),
+
+ Expect = filename:join([AppDir,
+ "_build",
+ "test",
+ "extras",
+ "test"]),
+ Dir = proplists:get_value(dir, Opts),
+ [Expect] = Dir,
+
+ Suite = proplists:get_value(suite, Opts),
+ ["extra_SUITE"] = Suite.
%% this test probably only fails when this suite is run via rebar3 with the --cover flag
data_dir_correct(Config) ->