Bläddra i källkod

Merge pull request #966 from talentdeficit/ct_root_suites

allow ct suites to be specified at root of project (or root of app)
pull/993/head
Fred Hebert 9 år sedan
förälder
incheckning
956e43a862
3 ändrade filer med 127 tillägg och 4 borttagningar
  1. +29
    -3
      src/rebar_prv_common_test.erl
  2. +4
    -0
      src/rebar_prv_compile.erl
  3. +94
    -1
      test/rebar_ct_SUITE.erl

+ 29
- 3
src/rebar_prv_common_test.erl Visa fil

@ -340,7 +340,7 @@ test_dirs(State, Apps, Opts) ->
{Suites, Dir} when is_integer(hd(Dir)) ->
set_compile_dirs(State, Apps, join(Suites, Dir));
{Suites, [Dir]} when is_integer(hd(Dir)) ->
set_compile_dirs(State, Apps, join(Suites, Dir));
set_compile_dirs(State, Apps, join(Suites, Dir));
{_Suites, _Dirs} -> {error, "Only a single directory may be specified when specifying suites"}
end.
@ -375,6 +375,17 @@ find_suite_dirs(Suites) ->
maybe_inject_test_dir(State, AppAcc, [App|Rest], Dir) ->
case rebar_file_utils:path_from_ancestor(Dir, rebar_app_info:dir(App)) of
{ok, []} ->
%% normal operation involves copying the entire directory a
%% suite exists in but if the suite is in the app root directory
%% the current compiler tries to compile all subdirs including priv
%% instead copy only files ending in `.erl' and directories
%% ending in `_SUITE_data' into the `_build/PROFILE/extras' dir
{ok, RelAppDir} = rebar_file_utils:path_from_ancestor(rebar_app_info:dir(App), rebar_state:dir(State)),
ExtrasDir = filename:join([rebar_dir:base_dir(State), "extras", RelAppDir]),
ok = copy_bare_suites(Dir, ExtrasDir),
Opts = inject_test_dir(rebar_state:opts(State), ExtrasDir),
{rebar_state:opts(State, Opts), AppAcc};
{ok, Path} ->
Opts = inject_test_dir(rebar_app_info:opts(App), Path),
{State, AppAcc ++ [rebar_app_info:opts(App, Opts)] ++ Rest};
@ -384,8 +395,15 @@ maybe_inject_test_dir(State, AppAcc, [App|Rest], Dir) ->
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};
%% normal operation involves copying the entire directory a
%% suite exists in but if the suite is in the root directory
%% that results in a loop as we copy `_build' into itself
%% instead copy only files ending in `.erl' and directories
%% ending in `_SUITE_data' in the `_build/PROFILE/extras' dir
ExtrasDir = filename:join([rebar_dir:base_dir(State), "extras"]),
ok = copy_bare_suites(Dir, ExtrasDir),
Opts = inject_test_dir(rebar_state:opts(State), ExtrasDir),
{rebar_state:opts(State, Opts), AppAcc};
{ok, Path} ->
Opts = inject_test_dir(rebar_state:opts(State), Path),
{rebar_state:opts(State, Opts), AppAcc};
@ -393,6 +411,14 @@ maybe_inject_test_dir(State, AppAcc, [], Dir) ->
{State, AppAcc}
end.
copy_bare_suites(From, To) ->
filelib:ensure_dir(filename:join([To, "dummy.txt"])),
SrcFiles = rebar_utils:find_files(From, ".*\\.[e|h]rl\$", false),
DataDirs = lists:filter(fun filelib:is_dir/1,
filelib:wildcard(filename:join([From, "*_SUITE_data"]))),
ok = rebar_file_utils:cp_r(SrcFiles, To),
rebar_file_utils:cp_r(DataDirs, To).
inject_test_dir(Opts, Dir) ->
%% append specified test targets to app defined `extra_src_dirs`
ExtraSrcDirs = rebar_opts:get(Opts, extra_src_dirs, []),

+ 4
- 0
src/rebar_prv_compile.erl Visa fil

@ -217,6 +217,10 @@ copy(OldAppDir, AppDir, Dir) ->
%% TODO: use ec_file:copy/2 to do this, it preserves timestamps and
%% may prevent recompilation of files in extra dirs
copy(Source, Source) ->
%% allow users to specify a directory in _build as a directory
%% containing additional source/tests
ok;
copy(Source, Target) ->
%% important to do this so no files are copied onto themselves
%% which truncates them to zero length on some platforms

+ 94
- 1
test/rebar_ct_SUITE.erl Visa fil

@ -17,6 +17,8 @@
multi_suite/1,
all_suite/1,
single_dir_and_single_suite/1,
suite_at_root/1,
suite_at_app_root/1,
data_dir_correct/1,
cmd_label/1,
cmd_config/1,
@ -72,7 +74,9 @@ groups() -> [{basic_app, [], [basic_app_default_dirs,
single_unmanaged_suite,
multi_suite,
all_suite,
single_dir_and_single_suite]},
single_dir_and_single_suite,
suite_at_root,
suite_at_app_root]},
{data_dirs, [], [data_dir_correct]},
{ct_opts, [], [cmd_label,
cmd_config,
@ -177,6 +181,22 @@ init_per_group(dirs_and_suites, Config) ->
ok = filelib:ensure_dir(Suite3),
ok = file:write_file(Suite3, test_suite("extras")),
Suite4 = filename:join([AppDir, "root_SUITE.erl"]),
ok = file:write_file(Suite4, test_suite("root")),
ok = file:write_file(filename:join([AppDir, "root_SUITE.hrl"]), <<>>),
ok = filelib:ensure_dir(filename:join([AppDir, "root_SUITE_data", "dummy.txt"])),
ok = file:write_file(filename:join([AppDir, "root_SUITE_data", "some_data.txt"]), <<>>),
Suite5 = filename:join([AppDir, "apps", Name2, "app_root_SUITE.erl"]),
ok = file:write_file(Suite5, test_suite("app_root")),
ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE.hrl"]), <<>>),
ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "dummy.txt"])),
ok = file:write_file(filename:join([AppDir, "apps", Name2, "app_root_SUITE_data", "some_data.txt"]), <<>>),
{ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return),
[{s, State}, {appnames, [Name1, Name2]}|C];
@ -603,6 +623,79 @@ single_dir_and_single_suite(Config) ->
Suite = proplists:get_value(suite, Opts),
["extra_SUITE"] = Suite.
suite_at_root(Config) ->
AppDir = ?config(apps, Config),
State = ?config(s, Config),
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, ["--suite=" ++ filename:join([AppDir, "root_SUITE"])]),
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
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),
Suite = proplists:get_value(suite, Opts),
Expected = filename:join([AppDir, "_build", "test", "extras", "root_SUITE"]),
[Expected] = Suite,
TestHrl = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.hrl"]),
true = filelib:is_file(TestHrl),
TestBeam = filename:join([AppDir, "_build", "test", "extras", "root_SUITE.beam"]),
true = filelib:is_file(TestBeam),
DataDir = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data"]),
true = filelib:is_dir(DataDir),
DataFile = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data", "some_data.txt"]),
true = filelib:is_file(DataFile).
suite_at_app_root(Config) ->
AppDir = ?config(apps, Config),
[_Name1, Name2] = ?config(appnames, Config),
State = ?config(s, Config),
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, ["--suite=" ++ filename:join([AppDir, "apps", Name2, "app_root_SUITE"])]),
State2 = rebar_state:command_parsed_args(State1, GetOptResult),
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),
Suite = proplists:get_value(suite, Opts),
Expected = filename:join([AppDir, "_build", "test", "extras", "apps", Name2, "app_root_SUITE"]),
[Expected] = Suite,
TestHrl = filename:join([AppDir, "_build", "test", "extras", "apps", Name2, "app_root_SUITE.hrl"]),
true = filelib:is_file(TestHrl),
TestBeam = filename:join([AppDir, "_build", "test", "extras", "apps", Name2, "app_root_SUITE.beam"]),
true = filelib:is_file(TestBeam),
DataDir = filename:join([AppDir, "_build", "test", "extras", "apps", Name2, "app_root_SUITE_data"]),
true = filelib:is_dir(DataDir),
DataFile = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data", "some_data.txt"]),
true = filelib:is_file(DataFile).
%% this test probably only fails when this suite is run via rebar3 with the --cover flag
data_dir_correct(Config) ->
DataDir = ?config(data_dir, Config),

Laddar…
Avbryt
Spara