diff options
author | Heinz N. Gies <heinz@licenser.net> | 2016-02-08 11:15:59 -0500 |
---|---|---|
committer | Heinz N. Gies <heinz@licenser.net> | 2016-02-08 11:15:59 -0500 |
commit | 2f563041cb248ba0cac27b92da5dcc3e7be27f80 (patch) | |
tree | e27ecaf59cfeb0e6406f1f4ce753842ff52855d5 /test | |
parent | 91c47db27a3c63fc04940c7c72433062dbadf042 (diff) | |
parent | 7fab47dfa05754242790a748bbd303ffe9703e5c (diff) |
Merge master
Diffstat (limited to 'test')
33 files changed, 1697 insertions, 222 deletions
diff --git a/test/rebar_as_SUITE.erl b/test/rebar_as_SUITE.erl index 99c7e30..0f37dc8 100644 --- a/test/rebar_as_SUITE.erl +++ b/test/rebar_as_SUITE.erl @@ -13,7 +13,8 @@ as_comma_then_space/1, as_dir_name/1, as_with_task_args/1, - warn_on_empty_profile/1]). + warn_on_empty_profile/1, + clean_as_profile/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -32,7 +33,7 @@ all() -> [as_basic, as_multiple_profiles, as_multiple_tasks, as_multiple_profiles_multiple_tasks, as_comma_placement, as_comma_then_space, as_dir_name, as_with_task_args, - warn_on_empty_profile]. + warn_on_empty_profile, clean_as_profile]. as_basic(Config) -> AppDir = ?config(apps, Config), @@ -166,3 +167,20 @@ warn_match(App, History) -> false end, History). + +clean_as_profile(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("clean_as_profile_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + rebar_test_utils:run_and_check(Config, + [], + ["as", "foo", "compile"], + {ok, [{app, Name, valid}]}), + + rebar_test_utils:run_and_check(Config, + [], + ["clean", "-a", "-p", "foo"], + {ok, [{app, Name, invalid}]}). diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 1c2c527..76a3de5 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -37,7 +37,10 @@ only_default_transitive_deps/1, clean_all/1, override_deps/1, - profile_override_deps/1]). + profile_override_deps/1, + deps_build_in_prod/1, + include_file_relative_to_working_directory/1, + include_file_in_src/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -58,7 +61,8 @@ all() -> deps_in_path, checkout_priority, highest_version_of_pkg_dep, parse_transform_test, erl_first_files_test, mib_test, umbrella_mib_first_test, only_default_transitive_deps, - clean_all, override_deps, profile_override_deps]. + clean_all, override_deps, profile_override_deps, deps_build_in_prod, + include_file_relative_to_working_directory, include_file_in_src]. groups() -> [{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]}, @@ -89,7 +93,7 @@ init_per_group(basic_app, Config) -> Name = rebar_test_utils:create_random_name("app1"), Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), - + [{app_names, [Name]}, {vsns, [Vsn]}|NewConfig]; init_per_group(release_apps, Config) -> @@ -103,7 +107,7 @@ init_per_group(release_apps, Config) -> Name2 = rebar_test_utils:create_random_name("relapp2_"), Vsn2 = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2, [kernel, stdlib]), - + [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig]; init_per_group(checkout_apps, Config) -> @@ -415,7 +419,7 @@ paths_basic_app(Config) -> [Vsn] = ?config(vsns, Config), {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return), - + code:add_paths(rebar_state:code_paths(State, all_deps)), ok = application:load(list_to_atom(Name)), Loaded = application:loaded_applications(), @@ -1018,11 +1022,14 @@ mib_test(Config) -> rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), - %% check a beam corresponding to the src in the extra src_dir exists in ebin + %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs PrivMibsDir = filename:join([AppDir, "_build", "default", "lib", Name, "priv", "mibs"]), true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])), - %% check the extra src_dir was linked into the _build dir + %% check a hrl corresponding to the mib in the mibs dir exists in include + true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])), + + %% check the mibs dir was linked into the _build dir true = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name, "mibs"])). umbrella_mib_first_test(Config) -> @@ -1065,11 +1072,14 @@ umbrella_mib_first_test(Config) -> rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), - %% check a beam corresponding to the src in the extra src_dir exists in ebin + %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs PrivMibsDir = filename:join([AppsDir, "_build", "default", "lib", Name, "priv", "mibs"]), true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])), - %% check the extra src_dir was linked into the _build dir + %% check a hrl corresponding to the mib in the mibs dir exists in include + true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])), + + %% check the mibs dir was linked into the _build dir true = filelib:is_dir(filename:join([AppsDir, "_build", "default", "lib", Name, "mibs"])). only_default_transitive_deps(Config) -> @@ -1167,3 +1177,91 @@ profile_override_deps(Config) -> {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]} ). +%% verify a deps prod profile is used +%% tested by checking prod hooks run and outputs to default profile dir for dep +%% and prod deps are installed for dep +deps_build_in_prod(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + GitDeps = rebar_test_utils:expand_deps(git, [{"asdf", "1.0.0", []}]), + PkgName = rebar_test_utils:create_random_name("pkg1_"), + {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps), + mock_git_resource:mock([{deps, SrcDeps}, + {config, [{profiles, [{prod, [{pre_hooks, [{compile, "echo whatsup > randomfile"}]}, + {deps, [list_to_atom(PkgName)]}]}]}]}]), + + mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]), + + Deps = rebar_test_utils:top_level_deps(GitDeps), + RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]), + {ok, RConf} = file:consult(RConfFile), + + %% Build with deps. + rebar_test_utils:run_and_check( + Config, RConf, ["compile"], + {ok, [{app, Name}, {dep, "asdf", <<"1.0.0">>}, {dep, PkgName}, + {file, filename:join([AppDir, "_build", "default", "lib", "asdf", "randomfile"])}]} + ). + +%% verify that the proper include path is defined +%% according the erlang doc which states: +%% If the filename File is absolute (possibly after variable substitution), +%% the include file with that name is included. Otherwise, the specified file +%% is searched for in the following directories, and in this order: +%% * The current working directory +%% * The directory where the module is being compiled +%% * The directories given by the include option +include_file_relative_to_working_directory(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + Src = <<"-module(test).\n" +"\n" +"-include(\"include/test.hrl\").\n" +"\n" +"test() -> ?TEST_MACRO.\n" +"\n">>, + Include = <<"-define(TEST_MACRO, test).\n">>, + + ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])), + ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src), + + ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])), + ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include), + + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["compile"], + {ok, [{app, Name}]}). + +include_file_in_src(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + Src = <<"-module(test).\n" +"\n" +"-include(\"test.hrl\").\n" +"\n" +"test() -> ?TEST_MACRO.\n" +"\n">>, + Include = <<"-define(TEST_MACRO, test).\n">>, + + ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])), + ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src), + + ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include), + + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["compile"], + {ok, [{app, Name}]}). diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index ba078c2..a838d7d 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -72,7 +72,7 @@ basic_extra_src_dirs(Config) -> Name = rebar_test_utils:create_random_name("cover_extra_"), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), ExtraSrc = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name]), @@ -86,8 +86,11 @@ basic_extra_src_dirs(Config) -> ["eunit", "--cover"], {ok, [{app, Name}]}), - Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))), - {file, _} = cover:is_compiled(Mod). + Mod = list_to_atom(Name), + {file, _} = cover:is_compiled(Mod), + + ExtraMod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))), + {file, _} = cover:is_compiled(ExtraMod). release_extra_src_dirs(Config) -> AppDir = ?config(apps, Config), @@ -120,10 +123,15 @@ release_extra_src_dirs(Config) -> ["eunit", "--cover"], {ok, [{app, Name1}, {app, Name2}]}), - Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))), + Mod1 = list_to_atom(Name1), {file, _} = cover:is_compiled(Mod1), - Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))), - {file, _} = cover:is_compiled(Mod2). + Mod2 = list_to_atom(Name2), + {file, _} = cover:is_compiled(Mod2), + + ExtraMod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))), + {file, _} = cover:is_compiled(ExtraMod1), + ExtraMod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))), + {file, _} = cover:is_compiled(ExtraMod2). root_extra_src_dirs(Config) -> AppDir = ?config(apps, Config), @@ -147,6 +155,11 @@ root_extra_src_dirs(Config) -> ["eunit", "--cover"], {ok, [{app, Name1}, {app, Name2}]}), + Mod1 = list_to_atom(Name1), + {file, _} = cover:is_compiled(Mod1), + Mod2 = list_to_atom(Name2), + {file, _} = cover:is_compiled(Mod2), + {file, _} = cover:is_compiled(extra). index_written(Config) -> diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index cdd3774..94ab690 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -17,15 +17,50 @@ multi_suite/1, all_suite/1, single_dir_and_single_suite/1, - symlinked_dir_overwritten_fix/1, - data_dir_correct/1]). + suite_at_root/1, + suite_at_app_root/1, + data_dir_correct/1, + cmd_label/1, + cmd_config/1, + cmd_allow_user_terms/1, + cmd_logdir/1, + cmd_logopts/1, + cmd_verbosity/1, + cmd_repeat/1, + cmd_duration/1, + cmd_until/1, + cmd_force_stop/1, + cmd_basic_html/1, + cmd_stylesheet/1, + cmd_decrypt_key/1, + cmd_decrypt_file/1, + cmd_abort_if_missing_suites/1, + cmd_multiply_timetraps/1, + cmd_scale_timetraps/1, + cmd_create_priv_dir/1, + cfg_opts/1, + cfg_arbitrary_opts/1, + cfg_test_spec/1, + cfg_atom_suites/1, + cover_compiled/1, + misspecified_ct_opts/1, + misspecified_ct_compile_opts/1, + misspecified_ct_first_files/1]). -include_lib("common_test/include/ct.hrl"). all() -> [{group, basic_app}, {group, multi_app}, {group, dirs_and_suites}, - {group, data_dirs}]. + {group, data_dirs}, + {group, ct_opts}, + {group, cover}, + cfg_opts, cfg_arbitrary_opts, + cfg_test_spec, + cfg_atom_suites, + misspecified_ct_opts, + misspecified_ct_compile_opts, + misspecified_ct_first_files]. groups() -> [{basic_app, [], [basic_app_default_dirs, basic_app_default_beams]}, @@ -40,8 +75,28 @@ groups() -> [{basic_app, [], [basic_app_default_dirs, multi_suite, all_suite, single_dir_and_single_suite, - symlinked_dir_overwritten_fix]}, - {data_dirs, [], [data_dir_correct]}]. + suite_at_root, + suite_at_app_root]}, + {data_dirs, [], [data_dir_correct]}, + {ct_opts, [], [cmd_label, + cmd_config, + cmd_allow_user_terms, + cmd_logdir, + cmd_logopts, + cmd_verbosity, + cmd_repeat, + cmd_duration, + cmd_until, + cmd_force_stop, + cmd_basic_html, + cmd_stylesheet, + cmd_decrypt_key, + cmd_decrypt_file, + cmd_abort_if_missing_suites, + cmd_multiply_timetraps, + cmd_scale_timetraps, + cmd_create_priv_dir]}, + {cover, [], [cover_compiled]}]. init_per_group(basic_app, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_"), @@ -56,22 +111,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, []), - - State2 = rebar_state:command_parsed_args(State1, GetOptResult), + 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), - 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 +146,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 +181,49 @@ init_per_group(dirs_and_suites, Config) -> ok = filelib:ensure_dir(Suite3), ok = file:write_file(Suite3, test_suite("extras")), - [{appnames, [Name1, Name2]}|C]; + 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]; +init_per_group(ct_opts, Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_opts"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return), + + [{result, State}|C]; +init_per_group(cover, Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_opts"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + {ok, State} = rebar_test_utils:run_and_check(C, [], ["as", "test", "lock"], return), + + [{result, State}, {name, Name}|C]; init_per_group(_, Config) -> Config. end_per_group(_Group, _Config) -> ok. @@ -152,10 +233,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 +259,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 +296,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 +313,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 +339,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 +369,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 +400,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 +435,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 +473,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 +510,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 +560,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,22 +607,62 @@ single_dir_and_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", - "test", - "extra_SUITE"]))], - Suite = proplists:get_value(suite, Result), + Expect = filename:join([AppDir, + "_build", + "test", + "extras", + "test"]), + Dir = proplists:get_value(dir, Opts), + [Expect] = Dir, - Expect = Suite. + Suite = proplists:get_value(suite, Opts), + ["extra_SUITE"] = Suite. -symlinked_dir_overwritten_fix(Config) -> +suite_at_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, "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). - {ok, State} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return), +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), @@ -533,28 +671,450 @@ symlinked_dir_overwritten_fix(Config) -> 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])]), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join([AppDir, "apps", Name2, "app_root_SUITE"])]), 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])), - Dir = proplists:get_value(dir, Result), + Suite = proplists:get_value(suite, Opts), + Expected = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE"]), + [Expected] = Suite, - Expect = Dir, + TestHrl = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.hrl"]), + true = filelib:is_file(TestHrl), - {ok, _} = rebar_test_utils:run_and_check(Config, [], ["as", "test", "compile"], return). + TestBeam = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE.beam"]), + true = filelib:is_file(TestBeam), + + DataDir = filename:join([AppDir, "_build", "test", "lib", Name2, "app_root_SUITE_data"]), + true = filelib:is_dir(DataDir), + + DataFile = filename:join([AppDir, "_build", "test", "lib", Name2, "app_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), Parts = filename:split(DataDir), + ct:pal(Parts), ["rebar_ct_SUITE_data","test","rebar","lib","test","_build"|_] = lists:reverse(Parts). +cmd_label(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--label=this_is_a_label"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({label, "this_is_a_label"}, TestOpts). + +cmd_config(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--config=config/foo,config/bar,config/baz"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({config, ["config/foo", "config/bar", "config/baz"]}, TestOpts). + +cmd_allow_user_terms(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--allow_user_terms=true"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({allow_user_terms, true}, TestOpts). + +cmd_logdir(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--logdir=/tmp/ct_logs"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({logdir, "/tmp/ct_logs"}, TestOpts). + +cmd_logopts(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--logopts=no_src,no_nl"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({logopts, [no_src, no_nl]}, TestOpts). + +cmd_verbosity(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--verbosity=43"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({verbosity, 43}, TestOpts). + +cmd_repeat(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--repeat=3"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({repeat, 3}, TestOpts). + +cmd_duration(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--duration=001500"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({duration, "001500"}, TestOpts). + +cmd_until(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--until=001500"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({until, "001500"}, TestOpts). + +cmd_force_stop(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--force_stop=skip_rest"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({force_stop, skip_rest}, TestOpts). + +cmd_basic_html(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--basic_html"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({basic_html, true}, TestOpts). + +cmd_stylesheet(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--stylesheet=resources/tests.css"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({stylesheet, "resources/tests.css"}, TestOpts). + +cmd_decrypt_key(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--decrypt_key==ac467e30"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({decrypt_key, "=ac467e30"}, TestOpts). + +cmd_decrypt_file(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--decrypt_file=../keyfile.pem"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts). + +cmd_abort_if_missing_suites(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--abort_if_missing_suites"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({abort_if_missing_suites, true}, TestOpts). + +cmd_multiply_timetraps(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--multiply_timetraps=3"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({multiply_timetraps, 3}, TestOpts). + +cmd_scale_timetraps(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--scale_timetraps"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({scale_timetraps, true}, TestOpts). + +cmd_create_priv_dir(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--create_priv_dir=manual_per_tc"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({create_priv_dir, manual_per_tc}, TestOpts). + +cfg_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_opts_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, [{label, "this_is_a_label"}, {decrypt_file, "../keyfile.pem"}]}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State), + + true = lists:member({label, "this_is_a_label"}, TestOpts), + true = lists:member({decrypt_file, "../keyfile.pem"}, TestOpts). + +%% allow even nonsensical opts to be passed to ct_run for futureproofing +cfg_arbitrary_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_arbitrary_opts_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_arbitrary_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, [{foo, 1}, {bar, 2}, {baz, 3}]}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State), + + true = lists:member({foo, 1}, TestOpts), + true = lists:member({bar, 2}, TestOpts), + true = lists:member({baz, 3}, TestOpts). + +cfg_test_spec(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_test_spec_opts_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_test_spec_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, [{test_spec, "spec/foo.spec"}]}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:prepare_tests(State), + + {badconfig, "Test specs not supported"} = Error. + +cfg_atom_suites(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, [{suite, [foo, bar, baz]}]}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State), + + true = lists:member({suite, ["foo", "bar", "baz"]}, TestOpts). + +cover_compiled(Config) -> + State = ?config(result, Config), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + {ok, GetOptResult} = getopt:parse(GetOptSpec, ["--cover"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + Tests = rebar_prv_common_test:prepare_tests(NewState), + {ok, _} = rebar_prv_common_test:compile(NewState, Tests), + + Name = ?config(name, Config), + Mod = list_to_atom(Name), + {file, _} = cover:is_compiled(Mod). + +misspecified_ct_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, {basic_html, false}}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:prepare_tests(State), + + {badconfig, {"Value `~p' of option `~p' must be a list", {{basic_html, false}, ct_opts}}} = Error. + +misspecified_ct_compile_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_compile_opts, {d, whatever}}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + Tests = rebar_prv_common_test:prepare_tests(State), + {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests), + + {badconfig, {"Value `~p' of option `~p' must be a list", {{d, whatever}, ct_compile_opts}}} = Error. + +misspecified_ct_first_files(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cfg_atom_suites_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_first_files, some_file}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + Tests = rebar_prv_common_test:prepare_tests(State), + {error, {rebar_prv_common_test, Error}} = rebar_prv_common_test:compile(State, Tests), + + {badconfig, {"Value `~p' of option `~p' must be a list", {some_file, ct_first_files}}} = Error. %% helper for generating test data test_suite(Name) -> diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index 31e02d9..22a4894 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/test/rebar_dialyzer_SUITE.erl @@ -69,7 +69,16 @@ update_base_plt(Config) -> ?assertEqual(ErtsFiles, BasePltFiles2), {ok, PltFiles} = plt_files(Plt), - ?assertEqual(ErtsFiles, PltFiles). + ?assertEqual(ErtsFiles, PltFiles), + + add_missing_file(BasePlt), + ok = file:delete(Plt), + + rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"], + {ok, [{app, Name}]}), + + {ok, BasePltFiles3} = plt_files(BasePlt), + ?assertEqual(ErtsFiles, BasePltFiles3). update_app_plt(Config) -> @@ -103,7 +112,15 @@ update_app_plt(Config) -> {ok, [{app, Name}]}), {ok, PltFiles3} = plt_files(Plt), - ?assertEqual(ErtsFiles, PltFiles3). + ?assertEqual(ErtsFiles, PltFiles3), + + add_missing_file(Plt), + + rebar_test_utils:run_and_check(Config, RebarConfig, ["dialyzer"], + {ok, [{app, Name}]}), + + {ok, PltFiles4} = plt_files(Plt), + ?assertEqual(ErtsFiles, PltFiles4). build_release_plt(Config) -> AppDir = ?config(apps, Config), @@ -211,6 +228,19 @@ alter_plt(Plt) -> {files, [code:which(dialyzer)]}]), ok. +add_missing_file(Plt) -> + Source = code:which(dialyzer), + Dest = filename:join(filename:dirname(Plt), "dialyzer.beam"), + {ok, _} = file:copy(Source, Dest), + _ = try + dialyzer:run([{analysis_type, plt_add}, + {init_plt, Plt}, + {files, [Dest]}]) + after + ok = file:delete(Dest) + end, + ok. + -spec merge_config(Config, Config) -> Config when Config :: [{term(), term()}]. merge_config(NewConfig, OldConfig) -> diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 526f827..1221db7 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -5,7 +5,7 @@ -export([default_src_dirs/1, default_extra_src_dirs/1, default_all_src_dirs/1]). -export([src_dirs/1, extra_src_dirs/1, all_src_dirs/1]). -export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]). --export([retarget_path/1]). +-export([retarget_path/1, alt_base_dir_abs/1, alt_base_dir_rel/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -15,7 +15,7 @@ all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs, src_dirs, extra_src_dirs, all_src_dirs, profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs, - retarget_path]. + retarget_path, alt_base_dir_abs, alt_base_dir_rel]. init_per_testcase(_, Config) -> C = rebar_test_utils:init_rebar_state(Config), @@ -124,4 +124,41 @@ retarget_path(Config) -> ?assertEqual(filename:join([BaseDir, "some_other_dir"]), rebar_dir:retarget_path(State, filename:join([rebar_dir:root_dir(State), "some_other_dir"]))), ?assertEqual("/somewhere/outside/the/project", - rebar_dir:retarget_path(State, "/somewhere/outside/the/project")).
\ No newline at end of file + rebar_dir:retarget_path(State, "/somewhere/outside/the/project")). + +alt_base_dir_abs(Config) -> + AltName = lists:flatten(io_lib:format("~p", [os:timestamp()])), + AltBaseDir = filename:join(?config(priv_dir, Config), AltName), + RebarConfig = [{base_dir, AltBaseDir}], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + + BaseDir = rebar_dir:base_dir(State), + ?assertEqual(filename:join(AltBaseDir, "default"), BaseDir), + + Name1 = ?config(app_one, Config), + Name2 = ?config(app_two, Config), + + ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name1, "ebin"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".app"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".beam"]))), + ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name2, "ebin"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".app"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".beam"]))). + +alt_base_dir_rel(Config) -> + AltName = lists:flatten(io_lib:format("~p", [os:timestamp()])), + AltBaseDir = filename:join("..", AltName), + RebarConfig = [{base_dir, AltBaseDir}], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + + BaseDir = rebar_dir:base_dir(State), + + Name1 = ?config(app_one, Config), + Name2 = ?config(app_two, Config), + + ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name1, "ebin"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".app"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name1, "ebin", Name1++".beam"]))), + ?assert(filelib:is_dir(filename:join([BaseDir, "lib", Name2, "ebin"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".app"]))), + ?assert(filelib:is_file(filename:join([BaseDir, "lib", Name2, "ebin", Name2++".beam"]))). diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 609be51..cb2c911 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -11,13 +11,19 @@ -export([single_file_arg/1, multi_file_arg/1, missing_file_arg/1]). -export([single_dir_arg/1, multi_dir_arg/1, missing_dir_arg/1]). -export([multiple_arg_composition/1, multiple_arg_errors/1]). +-export([misspecified_eunit_tests/1]). +-export([misspecified_eunit_compile_opts/1]). +-export([misspecified_eunit_first_files/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). all() -> - [{group, basic_app}, {group, multi_app}, {group, cmd_line_args}]. + [{group, basic_app}, {group, multi_app}, {group, cmd_line_args}, + misspecified_eunit_tests, + misspecified_eunit_compile_opts, + misspecified_eunit_first_files]. groups() -> [{basic_app, [sequence], [basic_app_compiles, {group, basic_app_results}]}, @@ -36,13 +42,10 @@ groups() -> init_per_suite(Config) -> PrivDir = ?config(priv_dir, Config), DataDir = ?config(data_dir, Config), - {ok, Cwd} = file:get_cwd(), - file:set_cwd(PrivDir), ok = ec_file:copy(filename:join([DataDir, "basic_app.zip"]), filename:join([PrivDir, "basic_app.zip"])), - {ok, _} = zip:extract(filename:join([PrivDir, "basic_app.zip"])), + {ok, _} = zip:extract(filename:join([PrivDir, "basic_app.zip"]), [{cwd, PrivDir}]), ok = ec_file:copy(filename:join([DataDir, "multi_app.zip"]), filename:join([PrivDir, "multi_app.zip"])), - {ok, _} = zip:extract(filename:join([PrivDir, "multi_app.zip"])), - file:set_cwd(Cwd), + {ok, _} = zip:extract(filename:join([PrivDir, "multi_app.zip"]), [{cwd, PrivDir}]), Config. init_per_group(basic_app, Config) -> @@ -153,7 +156,9 @@ basic_app_exports(_Config) -> basic_app_testset(Config) -> Result = ?config(result, Config), - {ok, [{application, basic_app}]} = rebar_prv_eunit:prepare_tests(Result). + Set = {ok, [{application, basic_app}, + {module, basic_app_tests_helper}]}, + Set = rebar_prv_eunit:prepare_tests(Result). @@ -205,12 +210,14 @@ multi_app_exports(_Config) -> %% check that the correct tests are schedule to run for project multi_app_testset(Config) -> - AppDir = ?config(apps, Config), Result = ?config(result, Config), - Set = {ok, [{application, multi_app_bar}, - {application, multi_app_baz}, - {dir, filename:join([AppDir, "test"])}]}, + Set = {ok, [{application, multi_app_baz}, + {application, multi_app_bar}, + {module, multi_app_bar_tests_helper}, + {module, multi_app_baz_tests_helper}, + {module, multi_app_tests}, + {module, multi_app_tests_helper}]}, Set = rebar_prv_eunit:prepare_tests(Result). @@ -268,7 +275,7 @@ missing_application_arg(Config) -> State = rebar_state:command_parsed_args(S, Args), Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Application `missing_app' not found in project."]}}}, - Error = rebar_prv_eunit:prepare_tests(State). + Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)). %% check that the --module cmd line opt generates the correct test set single_module_arg(Config) -> @@ -311,8 +318,11 @@ missing_module_arg(Config) -> {ok, Args} = getopt:parse(rebar_prv_eunit:eunit_opts(S), ["--module=missing_app"]), State = rebar_state:command_parsed_args(S, Args), + T = rebar_prv_eunit:prepare_tests(State), + Tests = rebar_prv_eunit:validate_tests(S, T), + Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}}, - Error = rebar_prv_eunit:prepare_tests(State). + Error = Tests. %% check that the --suite cmd line opt generates the correct test set single_suite_arg(Config) -> @@ -356,7 +366,7 @@ missing_suite_arg(Config) -> State = rebar_state:command_parsed_args(S, Args), Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Module `missing_app' not found in project."]}}}, - Error = rebar_prv_eunit:prepare_tests(State). + Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)). %% check that the --file cmd line opt generates the correct test set single_file_arg(Config) -> @@ -390,7 +400,7 @@ missing_file_arg(Config) -> State = rebar_state:command_parsed_args(S, Args), Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["File `" ++ Path ++"' not found."]}}}, - Error = rebar_prv_eunit:prepare_tests(State). + Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)). %% check that the --dir cmd line opt generates the correct test set single_dir_arg(Config) -> @@ -424,7 +434,7 @@ missing_dir_arg(Config) -> State = rebar_state:command_parsed_args(S, Args), Error = {error, {rebar_prv_eunit, {eunit_test_errors, ["Directory `" ++ Path ++"' not found."]}}}, - Error = rebar_prv_eunit:prepare_tests(State). + Error = rebar_prv_eunit:validate_tests(State, rebar_prv_eunit:prepare_tests(State)). %% check that multiple args are composed multiple_arg_composition(Config) -> @@ -470,11 +480,71 @@ multiple_arg_errors(Config) -> "--dir=" ++ DirPath]), State = rebar_state:command_parsed_args(S, Args), + T = rebar_prv_eunit:prepare_tests(State), + Tests = rebar_prv_eunit:validate_tests(S, T), + Expect = ["Application `missing_app' not found in project.", "Directory `" ++ DirPath ++ "' not found.", "File `" ++ FilePath ++ "' not found.", "Module `missing_app' not found in project.", "Module `missing_app' not found in project."], - {error, {rebar_prv_eunit, {eunit_test_errors, Expect}}} = rebar_prv_eunit:prepare_tests(State). + {error, {rebar_prv_eunit, {eunit_test_errors, Expect}}} = Tests. + +misspecified_eunit_tests(Config) -> + State = rebar_test_utils:init_rebar_state(Config, "basic_app_"), + + AppDir = ?config(apps, State), + PrivDir = ?config(priv_dir, State), + + AppDirs = ["src", "include", "test"], + + lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]), + filename:join([AppDir, F]), + [recursive]) end, AppDirs), + + BaseConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, [{d, eunit_compile_define}]}], + + RebarConfig = [{eunit_tests, {dir, "test"}}|BaseConfig], + + {error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return), + + {badconfig, {"Value `~p' of option `~p' must be a list", {{dir, "test"}, eunit_tests}}} = Error. + +misspecified_eunit_compile_opts(Config) -> + State = rebar_test_utils:init_rebar_state(Config, "basic_app_"), + + AppDir = ?config(apps, State), + PrivDir = ?config(priv_dir, State), + + AppDirs = ["src", "include", "test"], + + lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]), + filename:join([AppDir, F]), + [recursive]) end, AppDirs), + + RebarConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, {d, eunit_compile_define}}], + + {error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return), + + {badconfig, {"Value `~p' of option `~p' must be a list", {{d, eunit_compile_define}, eunit_compile_opts}}} = Error. + +misspecified_eunit_first_files(Config) -> + State = rebar_test_utils:init_rebar_state(Config, "basic_app_"), + + AppDir = ?config(apps, State), + PrivDir = ?config(priv_dir, State), + + AppDirs = ["src", "include", "test"], + + lists:foreach(fun(F) -> ec_file:copy(filename:join([PrivDir, "basic_app", F]), + filename:join([AppDir, F]), + [recursive]) end, AppDirs), + + BaseConfig = [{erl_opts, [{d, config_define}]}, {eunit_compile_opts, [{d, eunit_compile_define}]}], + + RebarConfig = [{eunit_first_files, some_file}|BaseConfig], + + {error, {rebar_prv_eunit, Error}} = rebar_test_utils:run_and_check(State, RebarConfig, ["eunit"], return), + {badconfig, {"Value `~p' of option `~p' must be a list", {some_file, eunit_first_files}}} = Error. diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index a061325..c1f85b3 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -97,10 +97,17 @@ path_from_ancestor(_Config) -> ?assertEqual({error, badparent}, rebar_file_utils:path_from_ancestor("/foo/bar/baz", "/foo/bar/baz/qux")). canonical_path(_Config) -> - ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/")), - ?assertEqual(filename:nativename("/"), rebar_file_utils:canonical_path("/../../..")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/bar/..")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/../foo")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/.")), - ?assertEqual("/foo", rebar_file_utils:canonical_path("/foo/./.")), - ?assertEqual("/foo/bar", rebar_file_utils:canonical_path("/foo/./bar")).
\ No newline at end of file + %% We find the root so that the name works both on unix-likes and + %% with Windows. + Root = case os:type() of + {win32, _} -> filename:nativename(filename:absname("/")); % C:\, with proper drive + _ -> "/" + end, + ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/")), + ?assertEqual(filename:nativename(Root), rebar_file_utils:canonical_path("/../../..")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/bar/..")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/../foo")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/.")), + ?assertEqual(Root ++ "foo", rebar_file_utils:canonical_path("/foo/./.")), + ?assertEqual(filename:nativename(Root ++ "foo/bar"), + rebar_file_utils:canonical_path("/foo/./bar")). diff --git a/test/rebar_new_SUITE.erl b/test/rebar_new_SUITE.erl index 3cee6f2..1971be6 100644 --- a/test/rebar_new_SUITE.erl +++ b/test/rebar_new_SUITE.erl @@ -6,9 +6,26 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -all() -> [app_git_user, app_hg_user, app_with_fallbacks]. +all() -> [app_git_user, app_hg_user, app_with_fallbacks, + app_with_flags1, app_with_flags2, plugin_tpl]. +init_per_testcase(plugin_tpl, Config) -> + application:load(rebar), + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + Name = rebar_test_utils:create_random_name("plugin_tpl"), + AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]), + ec_file:copy(filename:join([DataDir, "plugin_tpl"]), AppsDir, [recursive]), + Verbosity = rebar3:log_level(), + rebar_log:init(command_line, Verbosity), + GlobalDir = filename:join([DataDir, "cache"]), + State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])} + ,{global_rebar_dir, GlobalDir} + ,{root_dir, AppsDir}]), + mock_home_dir(DataDir), + mock_empty_escript_templates(), + [{apps, AppsDir}, {state, State}, {name, Name} | Config]; init_per_testcase(Case, Config0) -> Config = rebar_test_utils:init_rebar_state(Config0), Name = rebar_test_utils:create_random_name(atom_to_list(Case)), @@ -95,11 +112,60 @@ app_hg_user(Config) -> {filename:join(["src", Name++"_app.erl"]), [Name]} ]). +app_with_flags1(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check( + Config, [], + ["new", "test_app", "-f", Name], + {ok, []} + ), + validate_files( + Config, Name, + [{"LICENSE", []}, + {"README.md", []}, + {".gitignore", []}, + {"rebar.config", []}, + {filename:join(["src", Name++".app.src"]), [Name]}, + {filename:join(["src", Name++"_sup.erl"]), [Name]}, + {filename:join(["src", Name++"_app.erl"]), [Name]} + ]). + +app_with_flags2(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check( + Config, [], + ["new", "-f", "test_app", Name], + {ok, []} + ), + validate_files( + Config, Name, + [{"LICENSE", []}, + {"README.md", []}, + {".gitignore", []}, + {"rebar.config", []}, + {filename:join(["src", Name++".app.src"]), [Name]}, + {filename:join(["src", Name++"_sup.erl"]), [Name]}, + {filename:join(["src", Name++"_app.erl"]), [Name]} + ]). + +plugin_tpl(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check( + Config, [], + ["new", "-f", "tpl", Name], + {ok, []} + ), + Result = filename:join(["src", Name++".erl"]), % In CWD + {ok, Bin} = file:read_file(Result), + {match, _} = re:run(Bin, Name, [multiline,global]). + validate_files(_Config, Name, Checks) -> [begin Path = filename:join([Name, File]), + ct:pal("validating ~s for content", [Path]), {ok, Bin} = file:read_file(Path), [{match, _} = re:run(Bin, Pattern, [multiline,global]) || Pattern <- Patterns] end || {File, Patterns} <- Checks], ok. + diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl new file mode 100644 index 0000000..41588ab --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/LICENSE.dtl @@ -0,0 +1,29 @@ +Copyright (c) {{copyright_year}}, {{author_name}} <{{author_email}}>. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl new file mode 100644 index 0000000..5507536 --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/README.md.dtl @@ -0,0 +1,9 @@ +{{name}} +===== + +{{desc}} + +Build +----- + + $ rebar3 compile diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl new file mode 100644 index 0000000..83eb9a3 --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/app.erl.dtl @@ -0,0 +1,27 @@ +%%%------------------------------------------------------------------- +%% @doc {{name}} public API +%% @end +%%%------------------------------------------------------------------- + +-module({{name}}_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2 + ,stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + {{name}}_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template new file mode 100644 index 0000000..50998cc --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/bad_index.template @@ -0,0 +1,13 @@ +{description, "OTP Application"}. +{variables, [ + {name, "mylib", "Name of the OTP application"}, + {desc, "An OTP application", "Short description of the app"} +]}. +bad_term, +{template, "app.erl.dtl", "{{name}}/src/{{name}}_app.erl"}. +{template, "sup.erl.dtl", "{{name}}/src/{{name}}_sup.erl"}. +{template, "otp_app.app.src.dtl", "{{name}}/src/{{name}}.app.src"}. +{template, "rebar.config.dtl", "{{name}}/rebar.config"}. +{template, "gitignore.dtl", "{{name}}/.gitignore"}. +{template, "LICENSE.dtl", "{{name}}/LICENSE"}. +{template, "README.md.dtl", "{{name}}/README.md"}. diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl new file mode 100644 index 0000000..40a1d4f --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/gitignore.dtl @@ -0,0 +1,18 @@ +.rebar3 +_* +.eunit +*.o +*.beam +*.plt +*.swp +*.swo +.erlang.cookie +ebin +log +erl_crash.dump +.rebar +_rel +_deps +_plugins +_tdeps +logs diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl new file mode 100644 index 0000000..5188f56 --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/otp_app.app.src.dtl @@ -0,0 +1,12 @@ +{application, {{name}}, + [{description, "{{desc}}"} + ,{vsn, "0.1.0"} + ,{registered, []} + ,{mod, {'{{name}}_app', []}} + ,{applications, + [kernel + ,stdlib + ]} + ,{env,[]} + ,{modules, []} + ]}. diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl new file mode 100644 index 0000000..f618f3e --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/rebar.config.dtl @@ -0,0 +1,2 @@ +{erl_opts, [debug_info]}. +{deps, []}.
\ No newline at end of file diff --git a/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl new file mode 100644 index 0000000..a2e7209 --- /dev/null +++ b/test/rebar_new_SUITE_data/.rebar3/templates/bad_index/sup.erl.dtl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc {{name}} top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module({{name}}_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +-define(SERVER, ?MODULE). + +%%==================================================================== +%% API functions +%%==================================================================== + +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +%%==================================================================== +%% Supervisor callbacks +%%==================================================================== + +%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules} +init([]) -> + {ok, { {one_for_all, 0, 1}, []} }. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore new file mode 100644 index 0000000..a939dce --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/.gitignore @@ -0,0 +1,19 @@ +.rebar3 +_* +.eunit +*.o +*.beam +*.plt +*.swp +*.swo +.erlang.cookie +ebin +log +erl_crash.dump +.rebar +_rel +_deps +_plugins +_tdeps +logs +_build
\ No newline at end of file diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl new file mode 100644 index 0000000..9129961 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/module.erl.dtl @@ -0,0 +1,2 @@ +-module({{name}}). + diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template new file mode 100644 index 0000000..7fa4caf --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/priv/tpl.template @@ -0,0 +1,7 @@ +{description, "A basic template"}. +{variables, [ + {name, "mod", "Name of the module"} +]}. + +{dir, "test"}. +{template, "module.erl.dtl", "src/{{name}}.erl"}. diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config new file mode 100644 index 0000000..f618f3e --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/rebar.config @@ -0,0 +1,2 @@ +{erl_opts, [debug_info]}. +{deps, []}.
\ No newline at end of file diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src new file mode 100644 index 0000000..6c6d811 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.app.src @@ -0,0 +1,15 @@ +{application, 'tpl', + [{description, "A rebar plugin"}, + {vsn, "0.1.0"}, + {registered, []}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {contributors, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl new file mode 100644 index 0000000..529bcb8 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl.erl @@ -0,0 +1,8 @@ +-module('tpl'). + +-export([init/1]). + +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + {ok, State1} = 'tpl_prv':init(State), + {ok, State1}. diff --git a/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl new file mode 100644 index 0000000..c68ffa3 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/_checkouts/tpl/src/tpl_prv.erl @@ -0,0 +1,32 @@ +-module('tpl_prv'). + +-export([init/1, do/1, format_error/1]). + +-define(PROVIDER, 'tpl'). +-define(DEPS, [app_discovery]). + +%% =================================================================== +%% Public API +%% =================================================================== +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + Provider = providers:create([ + {name, ?PROVIDER}, % The 'user friendly' name of the task + {module, ?MODULE}, % The module implementation of the task + {bare, true}, % The task can be run by the user, always true + {deps, ?DEPS}, % The list of dependencies + {example, "rebar3 tpl"}, % How to use the plugin + {opts, []}, % list of options understood by the plugin + {short_desc, "A rebar plugin"}, + {desc, "A rebar plugin"} + ]), + {ok, rebar_state:add_provider(State, Provider)}. + + +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. +do(State) -> + {ok, State}. + +-spec format_error(any()) -> iolist(). +format_error(Reason) -> + io_lib:format("~p", [Reason]). diff --git a/test/rebar_new_SUITE_data/plugin_tpl/rebar.config b/test/rebar_new_SUITE_data/plugin_tpl/rebar.config new file mode 100644 index 0000000..74d1fc5 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/rebar.config @@ -0,0 +1,3 @@ +{erl_opts, [debug_info]}. +{deps, []}. +{plugins, [tpl]}. diff --git a/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src new file mode 100644 index 0000000..8f18874 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.app.src @@ -0,0 +1,15 @@ +{application, 'plugin_tpl', + [{description, "An OTP library"}, + {vsn, "0.1.0"}, + {registered, []}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {contributors, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl new file mode 100644 index 0000000..406bd97 --- /dev/null +++ b/test/rebar_new_SUITE_data/plugin_tpl/src/plugin_tpl.erl @@ -0,0 +1,13 @@ +-module('plugin_tpl'). + +%% API exports +-export([]). + +%%==================================================================== +%% API functions +%%==================================================================== + + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index b3201ad..9f19e0d 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -11,7 +11,8 @@ -define(good_checksum, <<"1C6CE379D191FBAB41B7905075E0BF87CBBE23C77CECE775C5A0B786B2244C35">>). all() -> [good_uncached, good_cached, badindexchk, badpkg, - bad_to_good, good_disconnect, bad_disconnect, pkgs_provider]. + bad_to_good, good_disconnect, bad_disconnect, pkgs_provider, + find_highest_matching]. init_per_suite(Config) -> application:start(meck), @@ -20,7 +21,19 @@ init_per_suite(Config) -> end_per_suite(_Config) -> application:stop(meck). -init_per_testcase(pkgs_provider, Config) -> +init_per_testcase(pkgs_provider=Name, Config) -> + %% Need to mock out a registry for this test now because it will try to update it automatically + Priv = ?config(priv_dir, Config), + Tid = ets:new(registry_table, [public]), + ets:insert_new(Tid, []), + CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]), + CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), + filelib:ensure_dir(filename:join([CacheDir, "registry"])), + ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])), + meck:new(rebar_packages, [passthrough]), + meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end), + meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end), + rebar_prv_update:hex_to_index(rebar_state:new()), Config; init_per_testcase(good_uncached=Name, Config0) -> Config = [{good_cache, false}, @@ -74,10 +87,13 @@ init_per_testcase(bad_disconnect=Name, Config0) -> meck:unload(httpc), meck:new(httpc, [passthrough, unsticky]), meck:expect(httpc, request, fun(_, _, _, _, _) -> {error, econnrefused} end), - Config. - -end_per_testcase(pkgs_provider, Config) -> Config; +init_per_testcase(Name, Config0) -> + Config = [{good_cache, false}, + {pkg, {<<"goodpkg">>, <<"1.0.0">>}} + | Config0], + mock_config(Name, Config). + end_per_testcase(_, Config) -> unmock_config(Config), Config. @@ -162,6 +178,16 @@ pkgs_provider(Config) -> {ok, []} ). +find_highest_matching(_Config) -> + State = rebar_state:new(), + {ok, Vsn} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"1.0.0">>, package_index, State), + ?assertEqual(<<"1.0.1">>, Vsn), + {ok, Vsn1} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"1.0">>, package_index, State), + ?assertEqual(<<"1.1.1">>, Vsn1), + {ok, Vsn2} = rebar_packages:find_highest_matching(<<"goodpkg">>, <<"2.0">>, package_index, State), + ?assertEqual(<<"2.0.0">>, Vsn2). + + %%%%%%%%%%%%%%% %%% Helpers %%% %%%%%%%%%%%%%%% @@ -172,10 +198,13 @@ mock_config(Name, Config) -> Tid = ets:new(registry_table, [public]), ets:insert_new(Tid, [ {<<"badindexchk">>,[[<<"1.0.0">>]]}, - {<<"goodpkg">>,[[<<"1.0.0">>]]}, + {<<"goodpkg">>,[[<<"1.0.0">>, <<"1.0.1">>, <<"1.1.1">>, <<"2.0.0">>]]}, {<<"badpkg">>,[[<<"1.0.0">>]]}, {{<<"badindexchk">>,<<"1.0.0">>}, [[], ?bad_checksum, [<<"rebar3">>]]}, {{<<"goodpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"1.0.1">>}, [[], ?good_checksum, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"1.1.1">>}, [[], ?good_checksum, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"2.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}, {{<<"badpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]} ]), CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), @@ -193,8 +222,8 @@ mock_config(Name, Config) -> meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end), meck:new(rebar_packages, [passthrough]), - meck:expect(rebar_packages, registry_dir, fun(_) -> CacheDir end), - meck:expect(rebar_packages, package_dir, fun(_) -> CacheDir end), + meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end), + meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end), rebar_prv_update:hex_to_index(rebar_state:new()), %% Cache fetches are mocked -- we assume the server and clients are diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index f7fa5d4..fef2310 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -98,8 +98,8 @@ mock_config(Name, Config) -> meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end), meck:new(rebar_packages, [passthrough, no_link]), - meck:expect(rebar_packages, registry_dir, fun(_) -> CacheDir end), - meck:expect(rebar_packages, package_dir, fun(_) -> CacheDir end), + meck:expect(rebar_packages, registry_dir, fun(_) -> {ok, CacheDir} end), + meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end), rebar_prv_update:hex_to_index(rebar_state:new()), %% Cache fetches are mocked -- we assume the server and clients are diff --git a/test/rebar_plugins_SUITE.erl b/test/rebar_plugins_SUITE.erl index 3df3c0e..c1a98de 100644 --- a/test/rebar_plugins_SUITE.erl +++ b/test/rebar_plugins_SUITE.erl @@ -10,7 +10,9 @@ compile_global_plugins/1, complex_plugins/1, list/1, - upgrade/1]). + upgrade/1, + sub_app_plugins/1, + sub_app_plugin_overrides/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -32,7 +34,7 @@ end_per_testcase(_, _Config) -> catch meck:unload(). all() -> - [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade]. + [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade, sub_app_plugins, sub_app_plugin_overrides]. %% Tests that compiling a project installs and compiles the plugins of deps compile_plugins(Config) -> @@ -208,3 +210,74 @@ upgrade(Config) -> Config, RConf, ["plugins", "upgrade", PkgName], {ok, [{app, Name}, {plugin, PkgName, <<"0.1.3">>}]} ). + +sub_app_plugins(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("sub_app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + + DepName = rebar_test_utils:create_random_name("dep1_"), + PluginName = rebar_test_utils:create_random_name("plugin1_"), + + mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []}, + {{list_to_binary(PluginName), list_to_binary(Vsn)}, []}]}]), + + SubAppsDir = filename:join([AppDir, "apps", Name]), + + rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_config(SubAppsDir, [{deps, [{list_to_binary(DepName), list_to_binary(Vsn)}]}, + {plugins, [list_to_atom(PluginName)]}]), + + RConfFile = + rebar_test_utils:create_config(AppDir, + [{deps, [ + list_to_atom(DepName) + ]}]), + {ok, RConf} = file:consult(RConfFile), + + %% Build with deps. + rebar_test_utils:run_and_check( + Config, RConf, ["compile"], + {ok, [{app, Name}, {dep, DepName}, {plugin, PluginName}]} + ). + +%% Tests that overrides in a dep that includes a plugin are applied to plugin fetching +sub_app_plugin_overrides(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("sub_app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + Dep2Name = rebar_test_utils:create_random_name("dep2_"), + + DepName = rebar_test_utils:create_random_name("dep1_"), + PluginName = rebar_test_utils:create_random_name("plugin1_"), + Vsn2 = rebar_test_utils:create_random_vsn(), + + Deps = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, [{DepName, Vsn, []}]}, + {DepName, Vsn, []}]), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), + + mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(Dep2Name), list_to_binary(Vsn)}, []}]}, + {config, [{plugins, [{list_to_atom(PluginName), + {git, "http://site.com/user/"++PluginName++".git", + {tag, Vsn}}}]}, + %% Dep2 overrides the plugin's deps to have vsn2 of dep1 + {overrides, [{override, list_to_atom(PluginName), + [{deps, [{list_to_atom(DepName), + {git, "http://site.com/user/"++DepName++".git", + {tag, Vsn2}}}]}]}]}]}]), + + SubAppsDir = filename:join([AppDir, "apps", Name]), + + rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), + + RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [{list_to_binary(Dep2Name), list_to_binary(Vsn)}]}]), + {ok, RConf} = file:consult(RConfFile), + + %% Build with deps. + rebar_test_utils:run_and_check( + Config, RConf, ["compile"], + {ok, [{app, Name}, {dep, Dep2Name, Vsn}, {plugin, DepName, Vsn2}, {plugin, PluginName}]} + ). diff --git a/test/rebar_release_SUITE.erl b/test/rebar_release_SUITE.erl index f6fe8ff..1125a7e 100644 --- a/test/rebar_release_SUITE.erl +++ b/test/rebar_release_SUITE.erl @@ -4,11 +4,14 @@ -include_lib("eunit/include/eunit.hrl"). all() -> [release, - dev_mode_release, - profile_dev_mode_override_release, - tar, - extend_release, - user_output_dir]. + dev_mode_release, + profile_dev_mode_override_release, + tar, + profile_ordering_sys_config_extend, + profile_ordering_sys_config_extend_3_tuple_merge, + extend_release, + user_output_dir, profile_overlays, + overlay_vars]. init_per_testcase(Case, Config0) -> Config = rebar_test_utils:init_rebar_state(Config0), @@ -111,6 +114,63 @@ extend_release(Config) -> {ok, [{release, extended, Vsn, false}]} ). +%% Ensure proper ordering of sys_config and extended releases in profiles +profile_ordering_sys_config_extend(Config) -> + AppDir = ?config(apps, Config), + Name = ?config(name, Config), + Vsn = "1.0.0", + TestSysConfig = filename:join(AppDir, "test.config"), + OtherSysConfig = filename:join(AppDir, "other.config"), + ok = file:write_file(TestSysConfig, "[]."), + ok = file:write_file(OtherSysConfig, "[{some, content}]."), + {ok, RebarConfig} = + file:consult(rebar_test_utils:create_config(AppDir, + [{relx, [{release, {list_to_atom(Name), Vsn}, + [list_to_atom(Name)]}, + {sys_config, OtherSysConfig}, + {lib_dirs, [AppDir]}]}, + {profiles, [{extended, + [{relx, [ + {sys_config, TestSysConfig}]}]}]}])), + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["as", "extended", "release"], + {ok, [{release, list_to_atom(Name), Vsn, false}]} + ), + + ReleaseDir = filename:join([AppDir, "./_build/extended/rel/", Name, "releases", Vsn]), + {ok, [[]]} = file:consult(filename:join(ReleaseDir, "sys.config")). + +%% test that tup_umerge works with tuples of different sizes +profile_ordering_sys_config_extend_3_tuple_merge(Config) -> + AppDir = ?config(apps, Config), + Name = ?config(name, Config), + Vsn = "1.0.0", + TestSysConfig = filename:join(AppDir, "test.config"), + OtherSysConfig = filename:join(AppDir, "other.config"), + ok = file:write_file(TestSysConfig, "[]."), + ok = file:write_file(OtherSysConfig, "[{some, content}]."), + {ok, RebarConfig} = + file:consult(rebar_test_utils:create_config(AppDir, + [{relx, [{release, {list_to_atom(Name), Vsn}, + [list_to_atom(Name)]}, + {sys_config, OtherSysConfig}, + {lib_dirs, [AppDir]}]}, + {profiles, [{extended, + [{relx, [ + {release, {extended, Vsn, {extend, list_to_atom(Name)}}, + []}, + {sys_config, TestSysConfig}]}]}]}])), + + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["as", "extended", "release", "-n", Name], + {ok, [{release, list_to_atom(Name), Vsn, false}]} + ), + + ReleaseDir = filename:join([AppDir, "./_build/extended/rel/", Name, "releases", Vsn]), + {ok, [[]]} = file:consult(filename:join(ReleaseDir, "sys.config")). + user_output_dir(Config) -> AppDir = ?config(apps, Config), Name = ?config(name, Config), @@ -134,3 +194,79 @@ user_output_dir(Config) -> {ok, RelxState2} = rlx_prv_app_discover:do(RelxState1), {ok, RelxState3} = rlx_prv_rel_discover:do(RelxState2), rlx_state:get_realized_release(RelxState3, list_to_atom(Name), Vsn). + +profile_overlays(Config) -> + AppDir = ?config(apps, Config), + Name = ?config(name, Config), + Vsn = "1.0.0", + {ok, RebarConfig} = + file:consult(rebar_test_utils:create_config(AppDir, + [{relx, [{release, {list_to_atom(Name), Vsn}, + [list_to_atom(Name)]}, + {overlay, [{mkdir, "randomdir"}]}, + {lib_dirs, [AppDir]}]}, + {profiles, [{prod, [{relx, [{overlay, [{mkdir, "otherrandomdir"}]}]}]}]}])), + + ReleaseDir = filename:join([AppDir, "./_build/prod/rel/", Name]), + + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["as", "prod", "release"], + {ok, [{release, list_to_atom(Name), Vsn, false}, + {dir, filename:join(ReleaseDir, "otherrandomdir")}, + {dir, filename:join(ReleaseDir, "randomdir")}]} + ). + +overlay_vars(Config) -> + AppDir = ?config(apps, Config), + Name = ?config(name, Config), + Vsn = "1.0.0", + {ok, RebarConfig} = + file:consult(rebar_test_utils:create_config(AppDir, + [{relx, [{release, {list_to_atom(Name), Vsn}, + [list_to_atom(Name)]}, + {overlay, [ + {template, filename:join([AppDir, "config/app.config"]), + "releases/{{release_version}}/sys.config"} + ]}, + {overlay_vars, filename:join([AppDir, "config/vars.config"])}, + {lib_dirs, [AppDir]}]} + ])), + + ok = filelib:ensure_dir(filename:join([AppDir, "config", "dummy"])), + + OverlayVars = [{var_int, 1}, + {var_string, "\"test\""}, + {var_bin_string, "<<\"test\">>"}, + {var_tuple, "{t, ['atom']}"}, + {var_list, "[a, b, c, 'd']"}, + {var_bin, "<<23, 24, 25>>"}], + rebar_test_utils:create_config(AppDir, + filename:join([AppDir, "config", "vars.config"]), + OverlayVars), + + AppConfig = [[{var_int, {{var_int}}}, + {var_string, {{{var_string}}}}, + {var_bin_string, {{{var_bin_string}}}}, + {var_tuple, {{{var_tuple}}}}, + {var_list, {{{var_list}}}}, + {var_bin, {{{var_bin}}}}]], + rebar_test_utils:create_config(AppDir, + filename:join([AppDir, "config", "app.config"]), + AppConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["release"], + {ok, [{release, list_to_atom(Name), Vsn, false}]}), + + %% now consult the sys.config file to make sure that is has the expected + %% format + ExpectedSysconfig = [{var_int, 1}, + {var_string, "test"}, + {var_bin_string, <<"test">>}, + {var_tuple, {t, ['atom']}}, + {var_list, [a, b, c, 'd']}, + {var_bin, <<23, 24, 25>>}], + {ok, [ExpectedSysconfig]} = file:consult(filename:join([AppDir, "_build/default/rel", + Name, "releases", Vsn, "sys.config"])). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 3943db7..5187bda 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -3,8 +3,8 @@ -include_lib("eunit/include/eunit.hrl"). -export([init_rebar_state/1, init_rebar_state/2, run_and_check/4, check_results/3]). -export([expand_deps/2, flat_deps/1, top_level_deps/1]). --export([create_app/4, create_eunit_app/4, create_empty_app/4, create_config/2, - package_app/3]). +-export([create_app/4, create_eunit_app/4, create_empty_app/4, + create_config/2, create_config/3, package_app/3]). -export([create_random_name/1, create_random_vsn/0, write_src_file/2]). %%%%%%%%%%%%%% @@ -104,11 +104,14 @@ create_empty_app(AppDir, Name, Vsn, Deps) -> %% each of which will be dumped as a consult file. For example, the list %% `[a, b, c]' will return the consult file `a. b. c.'. create_config(AppDir, Contents) -> - Conf = filename:join([AppDir, "rebar.config"]), - ok = filelib:ensure_dir(Conf), + ConfFilename = filename:join([AppDir, "rebar.config"]), + create_config(AppDir, ConfFilename, Contents). + +create_config(_AppDir, ConfFilename, Contents) -> + ok = filelib:ensure_dir(ConfFilename), Config = lists:flatten([io_lib:fwrite("~p.~n", [Term]) || Term <- Contents]), - ok = ec_file:write(Conf, Config), - Conf. + ok = ec_file:write(ConfFilename, Config), + ConfFilename. %% @doc Util to create a random variation of a given name. create_random_name(Name) -> diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 24e8afe..b32992d 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -30,7 +30,8 @@ invalid_otp_version/1, nonblacklisted_otp_version/1, blacklisted_otp_version/1, - sh_does_not_miss_messages/1]). + sh_does_not_miss_messages/1, + tup_merge/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -44,7 +45,8 @@ end_per_testcase(_, _Config) -> all() -> [{group, args_to_tasks}, - sh_does_not_miss_messages]. + sh_does_not_miss_messages, + tup_merge]. groups() -> [{args_to_tasks, [], [empty_arglist, @@ -198,3 +200,75 @@ sh_does_not_miss_messages(_Config) -> false end, AnyMessageRemained = false. + +tup_merge(_Config) -> + ?assertEqual( + [a,{a,a},{a,a,a},{a,b},{a,b,b},b,{b,a},{b,a,a},{b,b},{b,b,b},z,{z,a},{z,a,a},{z,b},{z,b,b}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}]), + rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}]) + ) + ), + ?assertEqual( + [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}]), + rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}]) + ) + ), + ?assertEqual( + [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([a,b,z,{a,b},{b,b},{z,b},{a,b,b},{b,b,b},{z,b,b}]), + rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}]) + ) + ), + ?assertEqual( + [{a,b},a,{a,b,b},{a,a},{a,a,a},{b,b},b,{b,b,b},{b,a},{b,a,a},{z,b},z,{z,b,b},{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{a,b},{b,b},{z,b},a,b,z,{a,b,b},{b,b,b},{z,b,b}]), + rebar_utils:tup_sort([a,{a,a},{a,a,a},b,{b,a},{b,a,a},z,{z,a},{z,a,a}]) + ) + ), + ?assertEqual( + [a,{a,b},{a,b,b},{a,a},{a,a,a},b,{b,b},{b,b,b},{b,a},{b,a,a},z,{z,b},{z,b,b},{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([a,{a,b},{a,b,b},b,{b,b},{b,b,b},z,{z,b},{z,b,b}]), + rebar_utils:tup_sort([{a,a},a,{a,a,a},{b,a},b,{b,a,a},{z,a},z,{z,a,a}]) + ) + ), + ?assertEqual( + [{a,b},a,{a,b,b},{a,a},{a,a,a},{b,b},b,{b,b,b},{b,a},{b,a,a},{z,b},z,{z,b,b},{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{a,b},{b,b},{z,b},a,b,z,{a,b,b},{b,b,b},{z,b,b}]), + rebar_utils:tup_sort([{a,a},a,{a,a,a},{b,a},b,{b,a,a},{z,a},z,{z,a,a}]) + ) + ), + ?assertEqual( + [{a,b},{a,b,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a},{b,a,a},{z,b},{z,b,b},z,{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{a,b},{a,b,b},{b,b},{b,b,b},{z,b},{z,b,b},a,b,z]), + rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a},{b,a,a},b,{z,a},{z,a,a},z]) + ) + ), + ?assertEqual( + [{a,b},{a,b,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a},{b,a,a},{z,b},{z,b,b},z,{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{a,b},{a,b,b},{b,b},{b,b,b},{z,b},{z,b,b},a,b,z]), + rebar_utils:tup_sort([{a,a},{a,b},{a,a,a},{a,b,b},a,{b,a},{b,a,a},b,{z,a},{z,a,a},z]) + ) + ), + ?assertEqual( + [{l, a}, {r, a, b}, {s, a}, {s, b}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{r, a, b}, {s, a}, {l, a}]), + rebar_utils:tup_sort([{s, b}]) + ) + ), + ?assertEqual( + [{a,b,b},{a,b},a,{a,a},{a,a,a},{b,b},{b,b,b},b,{b,a,a},{b,a},{z,b},{z,b,b},z,{z,a},{z,a,a}], + rebar_utils:tup_umerge( + rebar_utils:tup_sort([{a,b,b},{b,b},{a,b},{b,b,b},{z,b},{z,b,b},a,b,z]), + rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a,a},b,{z,a},{z,a,a},{b,a},z]) + ) + ). |