From b75f95e063f493ff19dca9aef54ce42b006e9611 Mon Sep 17 00:00:00 2001 From: Ilya Khaprov Date: Fri, 15 Jul 2016 14:12:30 +0300 Subject: ssl_verify_hostname was renamed to ssl_verify_fun --- test/rebar_unlock_SUITE_data/pkg.rebar.lock | 56 +++++++++++++---------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'test') diff --git a/test/rebar_unlock_SUITE_data/pkg.rebar.lock b/test/rebar_unlock_SUITE_data/pkg.rebar.lock index 38e22e5..231e266 100644 --- a/test/rebar_unlock_SUITE_data/pkg.rebar.lock +++ b/test/rebar_unlock_SUITE_data/pkg.rebar.lock @@ -1,32 +1,24 @@ -{"1.1.0",[{<<"bbmustache">>,{pkg,<<"bbmustache">>,<<"1.0.4">>},0}, - {<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},0}, - {<<"cf">>,{pkg,<<"cf">>,<<"0.2.1">>},0}, - {<<"cth_readable">>,{pkg,<<"cth_readable">>,<<"1.2.2">>},0}, - {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"0.21.0">>},0}, - {<<"eunit_formatters">>,{pkg,<<"eunit_formatters">>,<<"0.3.1">>},0}, - {<<"getopt">>,{pkg,<<"getopt">>,<<"0.8.2">>},0}, - {<<"providers">>,{pkg,<<"providers">>,<<"1.6.0">>},0}, - {<<"relx">>,{pkg,<<"relx">>,<<"3.19.0">>},0}, - {<<"ssl_verify_hostname">>, - {pkg,<<"ssl_verify_hostname">>,<<"1.0.5">>}, - 0}]}. -[{pkg_hash,[{<<"bbmustache">>, - <<"7BA94F971C5AFD7B6617918A4BB74705E36CAB36EB84B19B6A1B7EE06427AA38">>}, - {<<"certifi">>, - <<"A7966EFB868B179023618D29A407548F70C52466BF1849B9E8EBD0E34B7EA11F">>}, - {<<"cf">>, - <<"69D0B1349FD4D7D4DC55B7F407D29D7A840BF9A1EF5AF529F1EBE0CE153FC2AB">>}, - {<<"cth_readable">>, - <<"983913A8E8572310B7EAF5F2631148B7D70B3C090D2120DCFE777A93AA4165FB">>}, - {<<"erlware_commons">>, - <<"A04433071AD7D112EDEFC75AC77719DD3E6753E697AC09428FC83D7564B80B15">>}, - {<<"eunit_formatters">>, - <<"7A6FC351EB5B873E2356B8852EB751E20C13A72FBCA03393CF682B8483509573">>}, - {<<"getopt">>, - <<"B17556DB683000BA50370B16C0619DF1337E7AF7ECBF7D64FBF8D1D6BCE3109B">>}, - {<<"providers">>, - <<"DB0E2F9043AE60C0155205FCD238D68516331D0E5146155E33D1E79DC452964A">>}, - {<<"relx">>, - <<"286DD5244B4786F56AAC75D5C8E2D1FB4CFD306810D4EC8548F3AE1B3AADB8F7">>}, - {<<"ssl_verify_hostname">>, - <<"2E73E068CD6393526F9FA6D399353D7C9477D6886BA005F323B592D389FB47BE">>}]}]. +{"1.1.0", +[{<<"bbmustache">>,{pkg,<<"bbmustache">>,<<"1.0.4">>},0}, + {<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},0}, + {<<"cf">>,{pkg,<<"cf">>,<<"0.2.1">>},0}, + {<<"cth_readable">>,{pkg,<<"cth_readable">>,<<"1.2.3">>},0}, + {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"0.21.0">>},0}, + {<<"eunit_formatters">>,{pkg,<<"eunit_formatters">>,<<"0.3.1">>},0}, + {<<"getopt">>,{pkg,<<"getopt">>,<<"0.8.2">>},0}, + {<<"providers">>,{pkg,<<"providers">>,<<"1.6.0">>},0}, + {<<"relx">>,{pkg,<<"relx">>,<<"3.20.0">>},0}, + {<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.1">>},0}]}. +[ +{pkg_hash,[ + {<<"bbmustache">>, <<"7BA94F971C5AFD7B6617918A4BB74705E36CAB36EB84B19B6A1B7EE06427AA38">>}, + {<<"certifi">>, <<"A7966EFB868B179023618D29A407548F70C52466BF1849B9E8EBD0E34B7EA11F">>}, + {<<"cf">>, <<"69D0B1349FD4D7D4DC55B7F407D29D7A840BF9A1EF5AF529F1EBE0CE153FC2AB">>}, + {<<"cth_readable">>, <<"293120673DFF82F0768612C5282E35C40CACC1B6F94FE99077438FD3749D0E27">>}, + {<<"erlware_commons">>, <<"A04433071AD7D112EDEFC75AC77719DD3E6753E697AC09428FC83D7564B80B15">>}, + {<<"eunit_formatters">>, <<"7A6FC351EB5B873E2356B8852EB751E20C13A72FBCA03393CF682B8483509573">>}, + {<<"getopt">>, <<"B17556DB683000BA50370B16C0619DF1337E7AF7ECBF7D64FBF8D1D6BCE3109B">>}, + {<<"providers">>, <<"DB0E2F9043AE60C0155205FCD238D68516331D0E5146155E33D1E79DC452964A">>}, + {<<"relx">>, <<"B515B8317D25B3A1508699294C3D1FA6DC0527851DFFC87446661BCE21A36710">>}, + {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}]} +]. -- cgit v1.1 From f9576c8598c4d44a3bd8adf36d62f5eb9b8c29a3 Mon Sep 17 00:00:00 2001 From: Nathaniel Waisbrot Date: Thu, 4 Aug 2016 14:36:46 -0400 Subject: Handle `escriptize` when the specified app is missing When rebar.config contains a `escript_main_app` option, but the specified app doesn't exist in the build directory, print an error. --- test/rebar_escriptize_SUITE.erl | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_escriptize_SUITE.erl b/test/rebar_escriptize_SUITE.erl index 1817d6b..139d5cd 100644 --- a/test/rebar_escriptize_SUITE.erl +++ b/test/rebar_escriptize_SUITE.erl @@ -5,6 +5,8 @@ end_per_suite/1, init_per_testcase/2, all/0, + escriptize_with_name/1, + escriptize_with_bad_name/1, build_and_clean_app/1]). -include_lib("common_test/include/ct.hrl"). @@ -24,7 +26,11 @@ init_per_testcase(_, Config) -> rebar_test_utils:init_rebar_state(Config). all() -> - [build_and_clean_app]. + [ + build_and_clean_app, + escriptize_with_name, + escriptize_with_bad_name + ]. %% Test escriptize builds and runs the app's escript build_and_clean_app(Config) -> @@ -35,3 +41,21 @@ build_and_clean_app(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, [], ["escriptize"], {ok, [{app, Name, valid}]}). + +escriptize_with_name(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]), + rebar_test_utils:run_and_check(Config, [{escript_main_app, Name}], ["escriptize"], + {ok, [{app, Name, valid}]}). + +escriptize_with_bad_name(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]), + rebar_test_utils:run_and_check(Config, [{escript_main_app, boogers}], ["escriptize"], + {error,{rebar_prv_escriptize, {bad_name, boogers}}}). -- cgit v1.1 From 2c78cfd557249166cdd264d976ca191eb8a5061f Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 25 Aug 2016 09:35:59 -0400 Subject: Add tests for multi-app edoc linking working --- test/rebar_edoc_SUITE.erl | 52 ++++++++++++++++++++++ .../foo/apps/bar1/src/bar1.app.src | 16 +++++++ .../foo/apps/bar1/src/bar1.erl | 9 ++++ .../foo/apps/bar1/src/bar1_app.erl | 26 +++++++++++ .../foo/apps/bar1/src/bar1_sup.erl | 35 +++++++++++++++ .../foo/apps/bar2/src/bar2.app.src | 16 +++++++ .../foo/apps/bar2/src/bar2.erl | 9 ++++ .../foo/apps/bar2/src/bar2_app.erl | 26 +++++++++++ .../foo/apps/bar2/src/bar2_sup.erl | 35 +++++++++++++++ .../foo/apps/foo/src/foo.app.src | 17 +++++++ .../rebar_edoc_SUITE_data/foo/apps/foo/src/foo.erl | 19 ++++++++ .../foo/apps/foo/src/foo_app.erl | 26 +++++++++++ .../foo/apps/foo/src/foo_sup.erl | 35 +++++++++++++++ 13 files changed, 321 insertions(+) create mode 100644 test/rebar_edoc_SUITE.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.app.src create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_app.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_sup.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.app.src create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_app.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_sup.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.app.src create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_app.erl create mode 100644 test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_sup.erl (limited to 'test') diff --git a/test/rebar_edoc_SUITE.erl b/test/rebar_edoc_SUITE.erl new file mode 100644 index 0000000..fded2b0 --- /dev/null +++ b/test/rebar_edoc_SUITE.erl @@ -0,0 +1,52 @@ +-module(rebar_edoc_SUITE). +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-compile(export_all). + +all() -> [multiapp]. + +init_per_testcase(multiapp, Config) -> + application:load(rebar), + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + Name = rebar_test_utils:create_random_name("multiapp"), + AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]), + ec_file:copy(filename:join([DataDir, "foo"]), AppsDir, [recursive]), + Verbosity = rebar3:log_level(), + rebar_log:init(command_line, Verbosity), + State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])} + ,{root_dir, AppsDir}]), + [{apps, AppsDir}, {state, State}, {name, Name} | Config]. + +end_per_testcase(_, Config) -> + Config. + +multiapp(Config) -> + %% With an empty config (no `dir'), links are being processed + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, ["edoc"], {ok, []}), + %% validate that all doc entries are generated and links work + AppsDir = ?config(apps, Config), + ct:pal("AppsDir: ~s", [AppsDir]), + ?assert(file_content_matches( + filename:join([AppsDir, "apps", "bar1", "doc", "bar1.html"]), + "barer1")), + ?assert(file_content_matches( + filename:join([AppsDir, "apps", "bar2", "doc", "bar2.html"]), + "barer2")), + %% Links are in place for types + ?assert(file_content_matches( + filename:join([AppsDir, "apps", "foo", "doc", "foo.html"]), + "barer1")), + ?assert(file_content_matches( + filename:join([AppsDir, "apps", "foo", "doc", "foo.html"]), + "apps/bar1/doc/bar1.html")). + + +file_content_matches(Path, Regex) -> + case file:read_file(Path) of + {ok, Bin} -> + nomatch =/= re:run(Bin, Regex); + {error, Reason} -> + Reason + end. diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.app.src b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.app.src new file mode 100644 index 0000000..6e7ec24 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.app.src @@ -0,0 +1,16 @@ +{application, bar1, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { bar1_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.erl new file mode 100644 index 0000000..2700aef --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1.erl @@ -0,0 +1,9 @@ +-module(bar1). +-export([bar1/0]). +-export_type([barer1/0]). + +-type barer1() :: string(). + +% @doc Bar1 bars the bar. +-spec bar1() -> barer1(). +bar1() -> "Barer1". \ No newline at end of file diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_app.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_app.erl new file mode 100644 index 0000000..414ac30 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc bar1 public API +%% @end +%%%------------------------------------------------------------------- + +-module(bar1_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + bar1_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_sup.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_sup.erl new file mode 100644 index 0000000..f9d6670 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar1/src/bar1_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc bar1 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(bar1_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_edoc_SUITE_data/foo/apps/bar2/src/bar2.app.src b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.app.src new file mode 100644 index 0000000..58de8bc --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.app.src @@ -0,0 +1,16 @@ +{application, bar2, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { bar2_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.erl new file mode 100644 index 0000000..c639db0 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2.erl @@ -0,0 +1,9 @@ +-module(bar2). +-export([bar2/0]). +-export_type([barer2/0]). + +-type barer2() :: string(). + +% @doc Bar2 bars the bar2. +-spec bar2() -> barer2(). +bar2() -> "Barer2". \ No newline at end of file diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_app.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_app.erl new file mode 100644 index 0000000..d0058a0 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc bar2 public API +%% @end +%%%------------------------------------------------------------------- + +-module(bar2_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + bar2_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_sup.erl b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_sup.erl new file mode 100644 index 0000000..0bdaf4a --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/bar2/src/bar2_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc bar2 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(bar2_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_edoc_SUITE_data/foo/apps/foo/src/foo.app.src b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.app.src new file mode 100644 index 0000000..9987fd5 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.app.src @@ -0,0 +1,17 @@ +{application, foo, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { foo_app, []}}, + {applications, + [kernel, + stdlib, + bar1, bar2 + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.erl b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.erl new file mode 100644 index 0000000..52e3d0a --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo.erl @@ -0,0 +1,19 @@ +-module(foo). + +-export([foo/0, bar1/0, bar2/0]). + +-export_type([fooer/0]). + +-type fooer() :: string(). + +% @doc Foo function returns fooer. +-spec foo() -> fooer(). +foo() -> "fooer". + +% @doc Bar1 function returns barer1. +-spec bar1() -> bar1:barer1(). +bar1() -> bar1:bar1(). + +% @doc Bar2 functions returns barer2. +-spec bar2() -> bar2:barer2(). +bar2() -> bar2:bar2(). \ No newline at end of file diff --git a/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_app.erl b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_app.erl new file mode 100644 index 0000000..d0158d7 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc foo public API +%% @end +%%%------------------------------------------------------------------- + +-module(foo_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + foo_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_sup.erl b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_sup.erl new file mode 100644 index 0000000..67e88b4 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/foo/apps/foo/src/foo_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc foo top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(foo_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 +%%==================================================================== -- cgit v1.1 From dc03bb4c2d8f9dc4cb72590a02a20635e9526aa5 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 27 Aug 2016 07:32:09 -0400 Subject: Add test suite for cover_excl_mods option --- test/rebar_cover_SUITE.erl | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index 841e29f..1289f19 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -12,7 +12,8 @@ root_extra_src_dirs/1, index_written/1, flag_verbose/1, - config_verbose/1]). + config_verbose/1, + excl_mods/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -35,7 +36,8 @@ all() -> basic_extra_src_dirs, release_extra_src_dirs, root_extra_src_dirs, index_written, - flag_verbose, config_verbose]. + flag_verbose, config_verbose, + excl_mods]. flag_coverdata_written(Config) -> AppDir = ?config(apps, Config), @@ -206,3 +208,27 @@ config_verbose(Config) -> {ok, [{app, Name}]}), true = filelib:is_file(filename:join([AppDir, "_build", "test", "cover", "index.html"])). + +excl_mods(Config) -> + AppDir = ?config(apps, Config), + + Name1 = rebar_test_utils:create_random_name("relapp1_"), + Vsn1 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]), + + 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]), + + Mod1 = list_to_atom(Name1), + Mod2 = list_to_atom(Name2), + RebarConfig = [{erl_opts, [{d, some_define}]}, + {cover_excl_mods, [Mod2]}], + + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--cover"], + {ok, [{app, Name1}, {app, Name2}]}), + + {file, _} = cover:is_compiled(Mod1), + false = cover:is_compiled(Mod2). -- cgit v1.1 From 7e554d06978ac52a4e56b48f67819af356a3279b Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 27 Aug 2016 13:22:41 -0700 Subject: reset accumulated coverdata on writing out to disk. this prevents provider chains like `eunit, ct, proper` from misreporting cover stats from providers later in the sequence --- test/rebar_cover_SUITE.erl | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index 1289f19..d66ec6f 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -13,7 +13,8 @@ index_written/1, flag_verbose/1, config_verbose/1, - excl_mods/1]). + excl_mods/1, + coverdata_is_reset_on_write/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -37,7 +38,7 @@ all() -> root_extra_src_dirs, index_written, flag_verbose, config_verbose, - excl_mods]. + excl_mods, coverdata_is_reset_on_write]. flag_coverdata_written(Config) -> AppDir = ?config(apps, Config), @@ -232,3 +233,19 @@ excl_mods(Config) -> {file, _} = cover:is_compiled(Mod1), false = cover:is_compiled(Mod2). + +coverdata_is_reset_on_write(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("coverdata_is_reset_on_write_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}, {cover_enabled, true}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit"], + {ok, [{app, Name}]}), + + {result, Ok, []} = cover:analyse(), + [] = lists:filter(fun({_, {0,_}}) -> false; (_) -> true end, Ok). -- cgit v1.1 From 5ef4b7bcbe026852eb42e10ccc6f75b8e8854a15 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 27 Aug 2016 13:33:57 -0700 Subject: use `cover:analyse(cover:modules())` for tests instead of `cover:analyse()` `cover:analyse/0` didn't exist pre-otp18 --- test/rebar_cover_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index d66ec6f..84723ff 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -247,5 +247,5 @@ coverdata_is_reset_on_write(Config) -> ["eunit"], {ok, [{app, Name}]}), - {result, Ok, []} = cover:analyse(), + {result, Ok, []} = cover:analyse(cover:modules()), [] = lists:filter(fun({_, {0,_}}) -> false; (_) -> true end, Ok). -- cgit v1.1 From 3beeec9db0880c5e9f57a427796d9d9af9ffa46d Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 27 Aug 2016 13:44:33 -0700 Subject: r15 proof cover tests`` --- test/rebar_cover_SUITE.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index 84723ff..4192f4a 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -247,5 +247,6 @@ coverdata_is_reset_on_write(Config) -> ["eunit"], {ok, [{app, Name}]}), - {result, Ok, []} = cover:analyse(cover:modules()), + Res = lists:map(fun(M) -> cover:analyse(M) end, cover:modules()), + Ok = lists:foldl(fun({ok, R}, Acc) -> R ++ Acc end, [], Res), [] = lists:filter(fun({_, {0,_}}) -> false; (_) -> true end, Ok). -- cgit v1.1 From 2b6fa7a25e0acdee4ce2a452152b688f2df27dea Mon Sep 17 00:00:00 2001 From: David de Boer Date: Wed, 14 Sep 2016 16:32:16 +0200 Subject: Ignore mv warnings In some cases, mv will throw a warning, while still moving the files correctly and returning a 0 return code: "mv: can't preserve ownership of ... Permission denied". --- test/rebar_file_utils_SUITE.erl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index a44a06d..7285e13 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -14,7 +14,8 @@ path_from_ancestor/1, canonical_path/1, resolve_link/1, - split_dirname/1]). + split_dirname/1, + mv_warning_is_ignored/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -27,7 +28,8 @@ all() -> path_from_ancestor, canonical_path, resolve_link, - split_dirname]. + split_dirname, + mv_warning_is_ignored]. groups() -> [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]}, @@ -135,3 +137,9 @@ split_dirname(_Config) -> ?assertEqual({".", "foo"}, rebar_file_utils:split_dirname("foo")), ?assertEqual({"/foo", "bar"}, rebar_file_utils:split_dirname("/foo/bar")), ?assertEqual({"foo", "bar"}, rebar_file_utils:split_dirname("foo/bar")). + +mv_warning_is_ignored(_Config) -> + meck:new(rebar_utils, [passthrough]), + meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end), + ok = rebar_file_utils:mv("ding", "dong"), + meck:unload(rebar_utils). -- cgit v1.1 From dad7900d31fc2744c9d6b877f1a859f1f940cc39 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 20 Sep 2016 02:27:41 -0700 Subject: recompile all files when a parse transform given as an opt needs updating there's no way to detect which files actually rely on a parse transform passed to the compiler via the options (as opposed to `-compile(..)` so if any parse transforms are in modules that need recompiling just recompile the world fixes #1328 --- test/rebar_compile_SUITE.erl | 105 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index d9b75e4..cb16304 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -42,7 +42,9 @@ deps_build_in_prod/1, include_file_relative_to_working_directory/1, include_file_in_src/1, - always_recompile_when_erl_compiler_options_set/1]). + always_recompile_when_erl_compiler_options_set/1, + recompile_when_parse_transform_inline_changes/1, + recompile_when_parse_transform_as_opt_changes/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -65,7 +67,9 @@ all() -> parse_transform_test, erl_first_files_test, mib_test, umbrella_mib_first_test, only_default_transitive_deps, clean_all, override_deps, profile_override_deps, deps_build_in_prod, - include_file_relative_to_working_directory, include_file_in_src] ++ + include_file_relative_to_working_directory, include_file_in_src, + recompile_when_parse_transform_as_opt_changes, + recompile_when_parse_transform_inline_changes] ++ case erlang:function_exported(os, unsetenv, 1) of true -> [always_recompile_when_erl_compiler_options_set]; false -> [] @@ -1348,5 +1352,102 @@ always_recompile_when_erl_compiler_options_set(Config) -> _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) end. +recompile_when_parse_transform_inline_changes(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("parse_transform_inline_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])), + + ModSrc = <<"-module(example).\n" + "-export([foo/2]).\n" + "-compile([{parse_transform, example_parse_transform}]).\n" + "foo(_, _) -> ok.">>, + + ok = file:write_file(filename:join([AppDir, "src", "example.erl"]), + ModSrc), + + ParseTransform = <<"-module(example_parse_transform).\n" + "-export([parse_transform/2]).\n" + "parse_transform(AST, _) -> AST.\n">>, + + ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]), + ParseTransform), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + {ok, Files} = rebar_utils:list_dir(EbinDir), + ModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- Files, filename:basename(F, ".beam") == "example"], + + timer:sleep(1000), + + NewParseTransform = <<"-module(example_parse_transform).\n" + "-export([parse_transform/2]).\n" + "parse_transform(AST, _) -> identity(AST).\n" + "identity(AST) -> AST.\n">>, + + ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]), + NewParseTransform), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + {ok, NewFiles} = rebar_utils:list_dir(EbinDir), + NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- NewFiles, filename:basename(F, ".beam") == "example"], + ?assert(ModTime =/= NewModTime). + +recompile_when_parse_transform_as_opt_changes(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("parse_transform_opt_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])), + + ModSrc = <<"-module(example).\n" + "-export([foo/2]).\n" + "foo(_, _) -> ok.">>, + + ok = file:write_file(filename:join([AppDir, "src", "example.erl"]), + ModSrc), + + ParseTransform = <<"-module(example_parse_transform).\n" + "-export([parse_transform/2]).\n" + "parse_transform(AST, _) -> AST.">>, + + ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]), + ParseTransform), + + RebarConfig = [{erl_opts, [{parse_transform, example_parse_transform}]}], + + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + {ok, Files} = rebar_utils:list_dir(EbinDir), + ModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- Files, filename:basename(F, ".beam") == "example"], + + timer:sleep(1000), + + NewParseTransform = <<"-module(example_parse_transform).\n" + "-export([parse_transform/2]).\n" + "parse_transform(AST, _) -> identity(AST).\n" + "identity(AST) -> AST.">>, + + ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]), + NewParseTransform), + + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + {ok, NewFiles} = rebar_utils:list_dir(EbinDir), + NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- NewFiles, filename:basename(F, ".beam") == "example"], + + ?assert(ModTime =/= NewModTime). -- cgit v1.1 From b79e5da2363114de34ce612f32a109d37e7d01ac Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 20 Sep 2016 21:28:01 -0700 Subject: allow using an alternate regex to locate test modules during eunit runs {`eunit_test_regex`, Regex}` will use the supplied `Regex` instead of the default to locate tests in test dirs. note this matches only the filename, not the path. the regex is applied to all test dirs, recursively fixes #1331 --- test/rebar_eunit_SUITE.erl | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 41ab6ff..6fb325b 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -18,6 +18,7 @@ -export([misspecified_eunit_tests/1]). -export([misspecified_eunit_compile_opts/1]). -export([misspecified_eunit_first_files/1]). +-export([alternate_test_regex/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -27,7 +28,8 @@ all() -> [{group, basic_app}, {group, multi_app}, {group, cmd_line_args}, misspecified_eunit_tests, misspecified_eunit_compile_opts, - misspecified_eunit_first_files]. + misspecified_eunit_first_files, + alternate_test_regex]. groups() -> [{basic_app, [sequence], [basic_app_compiles, {group, basic_app_results}]}, @@ -579,3 +581,25 @@ misspecified_eunit_first_files(Config) -> {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. + +alternate_test_regex(Config) -> + State = rebar_test_utils:init_rebar_state(Config, "alternate_test_regex_"), + + 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_test_regex, "basic_app_tests.erl"}|BaseConfig], + + {ok, S} = rebar_test_utils:run_and_check(State, RebarConfig, ["as", "test", "lock"], return), + + Set = {ok, [{application, basic_app}, + {module, basic_app_tests}]}, + Set = rebar_prv_eunit:prepare_tests(S). \ No newline at end of file -- cgit v1.1 From 384e9e58dba9ff8cf801bfdbe3c2ec406453aa5f Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 27 Sep 2016 10:23:47 -0400 Subject: Properly support package aliasing and alt names Aliasing only had a bit of ad-hoc support in rebar3, and various issues have encountered problems related to the package names not mapping properly with the application name. One such issue is https://github.com/erlang/rebar3/issues/1290 The problem has been hard to find because it only impacts transitive dependencies (not top-level ones) of other packages. The root cause for this is that the application name was not being tracked by rebar3's internal index, only the package name and its version were. When a given application was a package app, the data for the application name would be reconstructed from the lock file, but only if it were a top-level app or a dependency of a source application where parsing the lock file is necessary to know what comes next. When a transitive dependency of a package dependency was fetched, we instead read its dependencies directly from the in-memory package index within rebar3. This caused us to only read the package name and version, and lost all information regarding application name. This worked fine for most cases since for the vast majority of packages, the package name matches the app name, but failed for all aliases, which would then be moved to directories that wouldn't match the app name. This in turn broke some aspects of code analysis (in Dialyzer), or other functionality relying on static paths, such as including .hrl files from dependencies. This patch reformats the internal storage format of dependencies to align with the internal one used by rebar3, so that the app name can be carried along with the package name and its version. The fix can only work once `rebar3 update` is called so the index is rebuilt internally, and will the file cached on disk will be incompatible with older rebar3 versions. Currently, the following is not covered: - Tests - Including the package hashes of dependencies so they may match what is in a lock file -- they're being `undefined` instead, which may break some lookups. The previous format did not lend itself to hashing in the same way, and it is possible transitive deps were not being tracked properly, or worked by respecting the current package hierarchy. This will require further analysis For now this commit can allow reviewing and discussion. --- test/rebar_deps_SUITE.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index 24bf2a0..6b2ecea 100644 --- a/test/rebar_deps_SUITE.erl +++ b/test/rebar_deps_SUITE.erl @@ -385,36 +385,36 @@ https_os_proxy_settings(_Config) -> semver_matching_lt(_Config) -> Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep}, + Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, <<"0.1.9">>}], + ?assertEqual([{Dep, {pkg, Dep, <<"0.1.9">>, undefined}}], rebar_prv_update:cmpl_(undefined, MaxVsn, Vsns, [], Dep1, fun ec_semver:lt/2)). semver_matching_lte(_Config) -> Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep}, + Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, <<"0.2.0">>}], + ?assertEqual([{Dep, {pkg, Dep, <<"0.2.0">>, undefined}}], rebar_prv_update:cmpl_(undefined, MaxVsn, Vsns, [], Dep1, fun ec_semver:lte/2)). semver_matching_gt(_Config) -> Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep}, + Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, <<"0.2.1">>}], + ?assertEqual([{Dep, {pkg, Dep, <<"0.2.1">>, undefined}}], rebar_prv_update:cmp_(undefined, MaxVsn, Vsns, [], Dep1, fun ec_semver:gt/2)). semver_matching_gte(_Config) -> Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep}, + Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>], - ?assertEqual([{Dep, <<"0.2.0">>}], + ?assertEqual([{Dep, {pkg, Dep, <<"0.2.0">>, undefined}}], rebar_prv_update:cmp_(undefined, MaxVsn, Vsns, [], Dep1, fun ec_semver:gt/2)). -- cgit v1.1 From 3f0e56d9c8c6da6c304543e47ff83e101aabf847 Mon Sep 17 00:00:00 2001 From: Brujo Benavides Date: Wed, 28 Sep 2016 19:32:22 -0300 Subject: Add support for behaviors, and not just behaviours --- test/rebar_xref_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_xref_SUITE.erl b/test/rebar_xref_SUITE.erl index 75d6786..09f73a7 100644 --- a/test/rebar_xref_SUITE.erl +++ b/test/rebar_xref_SUITE.erl @@ -150,7 +150,7 @@ get_module_body(mymod, AppName, IgnoreXref) -> ["-ignore_xref([{other2,1},{localfunc2,0},{fdeprecated,0}]).\n" || X <- [IgnoreXref], X =:= true], "-behaviour(", AppName, "_behaviour1).\n", % 2 behaviours - "-behaviour(", AppName, "_behaviour2).\n", + "-behavior(", AppName, "_behaviour2).\n", "-deprecated({fdeprecated,0}).\n", % deprecated function "bh1_a(A) -> localfunc1(bh1_a, A).\n", % behaviour functions "bh1_b(A) -> localfunc1(bh1_b, A).\n", -- cgit v1.1 From 787cd967b632bef4534ade58ab64a51eda838df1 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 30 Sep 2016 09:27:40 -0400 Subject: Fix private includes when compiling in test profile When an include file is set in a private path (i.e. src/), the rebar3 compiler would not add them to the {i, Path} params -- only include/ and the project root were being added. This meant that when some extra source directories were added to the compile job, such as test/ when running under the test profile, the private include paths could not be shared with the test module. This patch fixes the issues (and adds tests) for such a specific case by adding all the configured include paths to the {i, Path} erl_opts arguments, yielding successful compile runs. --- test/rebar_compile_SUITE.erl | 71 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index cb16304..f31ab39 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -42,6 +42,8 @@ deps_build_in_prod/1, include_file_relative_to_working_directory/1, include_file_in_src/1, + include_file_relative_to_working_directory_test/1, + include_file_in_src_test/1, always_recompile_when_erl_compiler_options_set/1, recompile_when_parse_transform_inline_changes/1, recompile_when_parse_transform_as_opt_changes/1]). @@ -68,6 +70,7 @@ all() -> umbrella_mib_first_test, only_default_transitive_deps, clean_all, override_deps, profile_override_deps, deps_build_in_prod, include_file_relative_to_working_directory, include_file_in_src, + include_file_relative_to_working_directory_test, include_file_in_src_test, recompile_when_parse_transform_as_opt_changes, recompile_when_parse_transform_inline_changes] ++ case erlang:function_exported(os, unsetenv, 1) of @@ -769,7 +772,7 @@ dont_recompile_when_opts_dont_change(Config) -> NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) || F <- NewFiles, filename:extension(F) == ".beam"], - ?assert(ModTime == NewModTime). + ?assertEqual(ModTime, NewModTime). dont_recompile_yrl_or_xrl(Config) -> AppDir = ?config(apps, Config), @@ -1314,6 +1317,72 @@ include_file_in_src(Config) -> ["compile"], {ok, [{app, Name}]}). +%% 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 +%% +%% This test ensures that things keep working when additional directories +%% are used for apps, such as the test/ directory within the test profile. +include_file_relative_to_working_directory_test(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 = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])), + ok = file:write_file(filename:join([AppDir, "test", "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, + ["as", "test", "compile"], + {ok, [{app, Name}]}). + +%% Same as `include_file_in_src/1' but using the `test/' directory +%% within the test profile. +include_file_in_src_test(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 = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])), + ok = file:write_file(filename:join([AppDir, "test", "test.erl"]), Src), + + ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include), + + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["as", "test", "compile"], + {ok, [{app, Name}]}). + always_recompile_when_erl_compiler_options_set(Config) -> %% save existing env to restore after test ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), -- cgit v1.1 From 75920a13a4251336d21bcbdbedb601dcf35de1f7 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 3 Oct 2016 23:35:58 -0400 Subject: Update existing tests to use new index structure --- test/mock_pkg_resource.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/mock_pkg_resource.erl b/test/mock_pkg_resource.erl index f837713..5769988 100644 --- a/test/mock_pkg_resource.erl +++ b/test/mock_pkg_resource.erl @@ -149,7 +149,10 @@ to_index(AllDeps, Dict) -> ets:new(package_index, [named_table, public]), dict:fold( fun(K, Deps, _) -> - DepsList = [{ec_cnv:to_binary(DK), ec_cnv:to_binary(DV)} || {DK, DV} <- Deps], + DepsList = [{DKB, {pkg, DKB, DVB, undefined}} + || {DK, DV} <- Deps, + DKB <- [ec_cnv:to_binary(DK)], + DVB <- [ec_cnv:to_binary(DV)]], ets:insert(package_index, {K, DepsList, <<"checksum">>}) end, ok, Dict), ets:insert(package_index, {package_index_version, 3}), -- cgit v1.1 From 45d9127dc952430d4b519741cb2303953e302665 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 4 Oct 2016 10:23:47 -0400 Subject: Add transitive alias tests --- test/rebar_pkg_alias_SUITE.erl | 82 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index 8915357..903fdad 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -4,7 +4,7 @@ -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). -all() -> [same_alias, diff_alias, diff_alias_vsn]. +all() -> [same_alias, diff_alias, diff_alias_vsn, transitive_alias]. %% {uuid, {pkg, uuid}} = uuid %% {uuid, {pkg, alias}} = uuid on disk @@ -32,6 +32,12 @@ init_per_testcase(diff_alias_vsn, Config0) -> AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, "1.0.0", {pkg, goodpkg}}]}]), + [{rebarconfig, RebarConf} | Config]; +init_per_testcase(transitive_alias, Config0) -> + Config = rebar_test_utils:init_rebar_state(Config0,"transitive_alias_vsn_"), + AppDir = ?config(apps, Config), + rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), + RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{topdep, "1.0.0", {pkg, topdep}}]}]), [{rebarconfig, RebarConf} | Config]. end_per_testcase(_, Config) -> @@ -73,23 +79,73 @@ diff_alias(Config) -> diff_alias_vsn(Config) -> diff_alias(Config). +transitive_alias(Config) -> + %% ensure that the apps fetched under transitive aliases are + %% locked properly, but also that they are stored in the right + %% directory in the build dir to avoid breaking includes and + %% static analysis tools that rely on the location to work + AppDir = ?config(apps, Config), + Lockfile = filename:join([AppDir, "rebar.lock"]), + {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), + rebar_test_utils:run_and_check( + Config, RebarConfig, ["lock"], + {ok, [{lock, "topdep"},{dep, "topdep"}, + {lock,"transitive_app"},{dep,"transitive_app"}]} + ), + {ok, [{_Vsn, LockData}|_]} = file:consult(Lockfile), + ?assert(lists:any(fun({<<"transitive_app">>,{pkg,<<"transitive">>,_},_}) -> true + ; (_) -> false end, LockData)), + AppDir = ?config(apps, Config), + AliasedName = filename:join([AppDir, "_build", "default", "lib", "transitive_app"]), + PkgName = filename:join([AppDir, "_build", "default", "lib", "transitive"]), + ?assert(filelib:is_dir(AliasedName)), + ?assertNot(filelib:is_dir(PkgName)), + %% An second run yields the same + rebar_test_utils:run_and_check( + Config, RebarConfig, ["lock"], + {ok, [{lock, "topdep"},{dep, "topdep"}, + {lock,"transitive_app"},{dep,"transitive_app"}]} + ), + {ok, [{_Vsn, LockData}|_]} = file:consult(Lockfile), + ?assert(filelib:is_dir(AliasedName)), + ?assertNot(filelib:is_dir(PkgName)), + %% So does an upgrade + rebar_test_utils:run_and_check( + Config, RebarConfig, ["upgrade"], + {ok, [{lock, "topdep"},{dep, "topdep"}, + {lock,"transitive_app"},{dep,"transitive_app"}]} + ), + {ok, [{_Vsn, LockData}|_]} = file:consult(Lockfile), + ?assert(filelib:is_dir(AliasedName)), + ?assertNot(filelib:is_dir(PkgName)), + ok. + mock_config(Name, Config) -> + {ChkFake, Etag} = create_lib(Name, Config, "fakelib"), + {ChkTop, _} = create_lib(Name, Config, "topdep"), + {ChkTrans, _} = create_lib(Name, Config, "transitive_app", "transitive"), Priv = ?config(priv_dir, Config), + TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]), + %% Add an alias for goodpkg -> fakelib by hand AppDir = filename:join([Priv, "fakelib"]), CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]), - TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]), CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), - filelib:ensure_dir(filename:join([CacheDir, "registry"])), rebar_test_utils:create_app(AppDir, "fakelib", "1.0.0", [kernel, stdlib]), - {Chk,Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "fakelib-1.0.0"), - {Chk,Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg-1.0.0"), + {ChkFake, Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg-1.0.0"), Tid = ets:new(registry_table, [public]), ets:insert_new(Tid, [ {<<"fakelib">>,[[<<"1.0.0">>]]}, {<<"goodpkg">>,[[<<"1.0.0">>]]}, - {{<<"fakelib">>,<<"1.0.0">>}, [[], Chk, [<<"rebar3">>]]}, - {{<<"goodpkg">>,<<"1.0.0">>}, [[], Chk, [<<"rebar3">>]]} + {<<"topdep">>,[[<<"1.0.0">>]]}, + {<<"transitive">>, [[<<"1.0.0">>]]}, + {{<<"fakelib">>,<<"1.0.0">>}, [[], ChkFake, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"1.0.0">>}, [[], ChkFake, [<<"rebar3">>]]}, + {{<<"topdep">>,<<"1.0.0">>}, + [[ + [<<"transitive">>, <<"1.0.0">>, false, <<"transitive_app">>] + ], ChkTop, [<<"rebar3">>]]}, + {{<<"transitive">>,<<"1.0.0">>}, [[], ChkTrans, [<<"rebar3">>]]} ]), ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])), ets:delete(Tid), @@ -119,3 +175,15 @@ mock_config(Name, Config) -> unmock_config(Config) -> meck:unload(), Config. + +create_lib(Name, Config, PkgName) -> + create_lib(Name, Config, PkgName, PkgName). + +create_lib(Name, Config, AppName, PkgName) -> + Priv = ?config(priv_dir, Config), + AppDir = filename:join([Priv, PkgName]), + CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]), + CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), + filelib:ensure_dir(filename:join([CacheDir, "registry"])), + rebar_test_utils:create_app(AppDir, AppName, "1.0.0", [kernel, stdlib]), + rebar_test_utils:package_app(AppDir, CacheDir, PkgName++"-1.0.0"). -- cgit v1.1 From 1f86ed1aed990438103c5f668c4ec930ab637fc9 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 4 Oct 2016 22:34:22 -0400 Subject: Track package hash in memory index, add hash test This adds tracking of package hash in the in-memory index rather than the current `undefined' values. According to the test added, this is not necessary for transitive package dep hash chcking, but does result in a more complete index search result when doing app lookups, and could yield some optimizations on hash checks by checking from the index structure before fetching a package. --- test/rebar_pkg_alias_SUITE.erl | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index 903fdad..2b8ccd2 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -4,7 +4,8 @@ -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). -all() -> [same_alias, diff_alias, diff_alias_vsn, transitive_alias]. +all() -> [same_alias, diff_alias, diff_alias_vsn, transitive_alias, + transitive_hash_mismatch]. %% {uuid, {pkg, uuid}} = uuid %% {uuid, {pkg, alias}} = uuid on disk @@ -38,6 +39,12 @@ init_per_testcase(transitive_alias, Config0) -> AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{topdep, "1.0.0", {pkg, topdep}}]}]), + [{rebarconfig, RebarConf} | Config]; +init_per_testcase(transitive_hash_mismatch, Config0) -> + Config = rebar_test_utils:init_rebar_state(Config0,"transitive_alias_vsn_"), + AppDir = ?config(apps, Config), + rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), + RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{topdep, "1.0.0", {pkg, topdep}}]}]), [{rebarconfig, RebarConf} | Config]. end_per_testcase(_, Config) -> @@ -120,6 +127,41 @@ transitive_alias(Config) -> ?assertNot(filelib:is_dir(PkgName)), ok. +transitive_hash_mismatch(Config) -> + %% ensure that the apps fetched under transitive aliases are + %% locked properly, but also that they are stored in the right + %% directory in the build dir to avoid breaking includes and + %% static analysis tools that rely on the location to work + AppDir = ?config(apps, Config), + Lockfile = filename:join([AppDir, "rebar.lock"]), + {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), + rebar_test_utils:run_and_check( + Config, RebarConfig, ["lock"], + {ok, [{lock, "topdep"},{dep, "topdep"}, + {lock,"transitive_app"},{dep,"transitive_app"}]} + ), + {ok, [LockData|Attrs]} = file:consult(Lockfile), + %% Change Lock hash data to cause a failure next time, but on transitive + %% deps only + NewLock = [LockData|lists:map( + fun([{pkg_hash, Hashes}|Rest]) -> + [{pkg_hash, [{<<"transitive_app">>, <<"fakehash">>} + | lists:keydelete(<<"transitive_app">>, 1, Hashes)]} + | Rest] + ; (Attr) -> + Attr + end, Attrs)], + {ok, Io} = file:open(Lockfile, [write]), + [io:format(Io, "~p.~n", [Attr]) || Attr <- NewLock], + file:close(Io), + ct:pal("lock: ~p", [file:consult(Lockfile)]), + ec_file:remove(filename:join([AppDir, "_build"]), [recursive]), + ?assertMatch( + {error, {rebar_fetch, {unexpected_hash, _, _, _}}}, + rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], return) + ), + ok. + mock_config(Name, Config) -> {ChkFake, Etag} = create_lib(Name, Config, "fakelib"), {ChkTop, _} = create_lib(Name, Config, "topdep"), -- cgit v1.1 From 504431473b9cc7f9c1641f640fc4d8a02c9aa079 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 17 Oct 2016 08:41:25 -0400 Subject: Prevent crashes in `rebar3 as` with no tasks checks on hd(...) and so on could not handle empty lists --- test/rebar_as_SUITE.erl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_as_SUITE.erl b/test/rebar_as_SUITE.erl index 0f37dc8..ce8046b 100644 --- a/test/rebar_as_SUITE.erl +++ b/test/rebar_as_SUITE.erl @@ -14,6 +14,7 @@ as_dir_name/1, as_with_task_args/1, warn_on_empty_profile/1, + error_on_empty_tasks/1, clean_as_profile/1]). -include_lib("common_test/include/ct.hrl"). @@ -33,7 +34,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, clean_as_profile]. + warn_on_empty_profile, error_on_empty_tasks, clean_as_profile]. as_basic(Config) -> AppDir = ?config(apps, Config), @@ -159,6 +160,20 @@ warn_on_empty_profile(Config) -> meck:unload(rebar_log), ok. +error_on_empty_tasks(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("as_error_empty_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + meck:new(rebar_log, [passthrough]), + rebar_test_utils:run_and_check(Config, + [], + ["as", "default"], + {error, "At least one task must be specified when using `as`"}), + ok. + warn_match(App, History) -> lists:any( fun({_, {rebar_log,log, [warn, "No entry for profile ~s in config.", -- cgit v1.1 From 203e5c15bd1935d66ca29fb071a8bc7ba8dad162 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Mon, 17 Oct 2016 17:10:41 -0700 Subject: allow test specifications to be passed via the command line `rebar3 ct --spec foo.spec,bar.spec,baz.spec` now works also added support for the `join_specs` flag on the command line --- test/rebar_ct_SUITE.erl | 54 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index c10875b..8e989b5 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -24,6 +24,8 @@ data_dir_correct/1, cmd_label/1, cmd_config/1, + cmd_spec/1, + cmd_join_specs/1, cmd_allow_user_terms/1, cmd_logdir/1, cmd_logopts/1, @@ -44,7 +46,6 @@ cmd_sys_config/1, cfg_opts/1, cfg_arbitrary_opts/1, - cfg_test_spec/1, cfg_cover_spec/1, cfg_atom_suites/1, cover_compiled/1, @@ -62,7 +63,7 @@ all() -> [{group, basic_app}, {group, ct_opts}, {group, cover}, cfg_opts, cfg_arbitrary_opts, - cfg_test_spec, cfg_cover_spec, + cfg_cover_spec, cfg_atom_suites, misspecified_ct_opts, misspecified_ct_compile_opts, @@ -88,6 +89,8 @@ groups() -> [{basic_app, [], [basic_app_default_dirs, {data_dirs, [], [data_dir_correct]}, {ct_opts, [], [cmd_label, cmd_config, + cmd_spec, + cmd_join_specs, cmd_allow_user_terms, cmd_logdir, cmd_logopts, @@ -761,6 +764,36 @@ cmd_config(Config) -> true = lists:member({config, ["config/foo", "config/bar", "config/baz"]}, TestOpts). +cmd_spec(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, ["--spec=foo.spec,bar.spec,baz.spec"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({spec, ["foo.spec", "bar.spec", "baz.spec"]}, TestOpts). + +cmd_join_specs(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, ["--join_specs=true"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + {ok, TestOpts} = rebar_prv_common_test:prepare_tests(NewState), + + true = lists:member({join_specs, true}, TestOpts). + cmd_allow_user_terms(Config) -> State = ?config(result, Config), @@ -1096,23 +1129,6 @@ cfg_arbitrary_opts(Config) -> 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, [Opt = {test_spec, "spec/foo.spec"}]}], - - {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), - - {ok, TestOpts} = rebar_prv_common_test:prepare_tests(State), - - false = lists:member(Opt, TestOpts). - cfg_cover_spec(Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_cover_spec_opts_"), -- cgit v1.1 From bcfd8d6f80f551e1b2a0e23eaa6b5ff2c7da5b15 Mon Sep 17 00:00:00 2001 From: James Fish Date: Thu, 3 Nov 2016 15:45:41 +0000 Subject: Add exclude_apps/mods, plt_extra_mods, base_plt_mods config * exclude_apps - never use applications for PLT/analysis * base_plt_mods - add modules to base PLT (overrules exclude_apps) * plt_extra_mods - add modules to PLT (overrules exclude_apps) * exclude_mods - never use modules for PLT/analysis (overrules all) --- test/rebar_dialyzer_SUITE.erl | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index e5d8c52..d0a3611 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/test/rebar_dialyzer_SUITE.erl @@ -14,7 +14,8 @@ update_base_plt/1, update_app_plt/1, build_release_plt/1, - plt_apps_option/1]). + plt_apps_option/1, + exclude_and_extra/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -57,7 +58,7 @@ all() -> groups() -> [{empty, [empty_base_plt, empty_app_plt, empty_app_succ_typings]}, - {build_and_check, [build_release_plt, plt_apps_option]}, + {build_and_check, [build_release_plt, plt_apps_option, exclude_and_extra]}, {update, [update_base_plt, update_app_plt]}]. empty_base_plt(Config) -> @@ -275,6 +276,39 @@ plt_apps_option(Config) -> {ok, PltFiles2} = plt_files(Plt), ?assertEqual([App1, App2, erts], get_apps_from_beam_files(PltFiles2)). +exclude_and_extra(Config) -> + AppDir = ?config(apps, Config), + RebarConfig = ?config(rebar_config, Config), + BasePlt = ?config(base_plt, Config), + Plt = ?config(plt, Config), + + {value, {dialyzer, Opts}, Rest} = lists:keytake(dialyzer, 1, RebarConfig), + % Remove erts => [] + % Add erlang+zlib => [erlang, zlib], + % Add erl_prim_loader+init => [erl_prim_loader, init, erlang, zlib] + % Remove zlib+init => [erl_prim_loader, erlang] + Opts2 = [{exclude_apps, [erts]}, + {base_plt_mods, [erlang, zlib]}, + {plt_extra_mods, [erl_prim_loader, init]}, + {exclude_mods, [zlib, init]} | + Opts], + RebarConfig2 = [{dialyzer, Opts2} | Rest], + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [erts]), + + rebar_test_utils:run_and_check(Config, RebarConfig2, ["dialyzer"], + {ok, [{app, Name}]}), + + Erlang = code:where_is_file("erlang.beam"), + {ok, BasePltFiles} = plt_files(BasePlt), + ?assertEqual([Erlang], BasePltFiles), + + Pair = lists:sort([Erlang, code:where_is_file("erl_prim_loader.beam")]), + {ok, PltFiles} = plt_files(Plt), + ?assertEqual(Pair, PltFiles). + %% Helpers erts_files() -> -- cgit v1.1 From 44fabbbf9173bc97365ccb3c7d28d1bc8503c28d Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 18 Nov 2016 17:42:39 +0100 Subject: Add 'recursive' option The option {recursive,boolean()} can now be set pr directory in 'src_dirs' and 'extra_src_dirs', and on top level in the new 'erlc_compiler' option. Example config: {erlc_compiler,[{recursive,false}]}. {src_dirs,[{"src",[{recursive,true}]}]}. This will cause recursive compilation within the "src" directory, but not in any other directoires. --- test/rebar_compile_SUITE.erl | 42 ++++++++++++++++++++++++++-- test/rebar_dir_SUITE.erl | 66 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index f31ab39..3e4d5b9 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -46,7 +46,8 @@ include_file_in_src_test/1, always_recompile_when_erl_compiler_options_set/1, recompile_when_parse_transform_inline_changes/1, - recompile_when_parse_transform_as_opt_changes/1]). + recompile_when_parse_transform_as_opt_changes/1, + recursive/1,no_recursive/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -72,7 +73,8 @@ all() -> include_file_relative_to_working_directory, include_file_in_src, include_file_relative_to_working_directory_test, include_file_in_src_test, recompile_when_parse_transform_as_opt_changes, - recompile_when_parse_transform_inline_changes] ++ + recompile_when_parse_transform_inline_changes, + recursive, no_recursive] ++ case erlang:function_exported(os, unsetenv, 1) of true -> [always_recompile_when_erl_compiler_options_set]; false -> [] @@ -1520,3 +1522,39 @@ recompile_when_parse_transform_as_opt_changes(Config) -> ?assert(ModTime =/= NewModTime). +recursive(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]), + rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + {ok, Files} = rebar_utils:list_dir(EbinDir), + ?assert(lists:member("rec.beam",Files)). + +no_recursive(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]), + rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"), + + RebarConfig1 = [{erlc_compiler,[{recursive,false}]}], + rebar_test_utils:run_and_check(Config, RebarConfig1, ["compile"], + {ok, [{app, Name}]}), + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + {ok, Files1} = rebar_utils:list_dir(EbinDir), + ?assert(false==lists:member("rec.beam",Files1)), + + RebarConfig2 = [{src_dirs,[{"src",[{recursive,false}]}]}], + rebar_test_utils:run_and_check(Config, RebarConfig2, ["compile"], + {ok, [{app, Name}]}), + {ok, Files2} = rebar_utils:list_dir(EbinDir), + ?assert(false==lists:member("rec.beam",Files2)), + + ok. diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 9734830..6797802 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -3,8 +3,10 @@ -export([all/0, init_per_testcase/2, end_per_testcase/2]). -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([src_dirs/1, src_dirs_with_opts/1, extra_src_dirs/1, all_src_dirs/1]). +-export([src_dir_opts/1, recursive/1]). -export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]). +-export([profile_src_dir_opts/1]). -export([retarget_path/1, alt_base_dir_abs/1, alt_base_dir_rel/1]). -export([global_cache_dir/1, default_global_cache_dir/1, overwrite_default_global_cache_dir/1]). @@ -14,8 +16,9 @@ all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs, - src_dirs, extra_src_dirs, all_src_dirs, + src_dirs, extra_src_dirs, all_src_dirs, src_dir_opts, recursive, profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs, + profile_src_dir_opts, retarget_path, alt_base_dir_abs, alt_base_dir_rel, global_cache_dir, default_global_cache_dir, overwrite_default_global_cache_dir]. @@ -70,6 +73,13 @@ src_dirs(Config) -> ["bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). +src_dirs_with_opts(Config) -> + RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}, + {src_dirs, [{"foo",[{recursive,false}]}, "qux"]}]}], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + + ["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State)). + extra_src_dirs(Config) -> RebarConfig = [{erl_opts, [{extra_src_dirs, ["foo", "bar", "baz"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), @@ -77,11 +87,41 @@ extra_src_dirs(Config) -> ["bar", "baz", "foo"] = rebar_dir:extra_src_dirs(rebar_state:opts(State)). all_src_dirs(Config) -> - RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}, {extra_src_dirs, ["baz", "qux"]}]}], + RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}, {extra_src_dirs, ["baz", "qux"]}, {src_dirs, [{"foo", [{recursive,false}]}]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), ["bar", "baz", "foo", "qux"] = rebar_dir:all_src_dirs(rebar_state:opts(State)). +src_dir_opts(Config) -> + RebarConfig = + [{erl_opts, [{src_dirs, [{"foo",[{recursive,true}]}, "bar"]}, + {extra_src_dirs, ["baz", {"foo", [{recursive,false}]}]}, + {src_dirs, [{"foo", [{recursive,false}]}]}]}], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, + ["compile"], return), + [{recursive,true}] = rebar_dir:src_dir_opts(rebar_state:opts(State), "foo"), + [] = rebar_dir:src_dir_opts(rebar_state:opts(State), "bar"), + [] = rebar_dir:src_dir_opts(rebar_state:opts(State), "nonexisting"). + +recursive(Config) -> + RebarConfig1 = + [{erl_opts, [{src_dirs, ["foo", "bar"]}, + {extra_src_dirs, ["baz", {"foo", [{recursive,true}]}]}, + {src_dirs, [{"foo", [{recursive,false}]}]}]}], + {ok, State1} = rebar_test_utils:run_and_check(Config, RebarConfig1, + ["compile"], return), + false = rebar_dir:recursive(rebar_state:opts(State1), "foo"), + true = rebar_dir:recursive(rebar_state:opts(State1), "bar"), + + RebarConfig2 = [{erlc_compiler,[{recursive,false}]}, + {erl_opts,[{src_dirs,["foo",{"bar",[{recursive,true}]}]}]}], + {ok, State2} = rebar_test_utils:run_and_check(Config, RebarConfig2, + ["compile"], return), + false = rebar_dir:recursive(rebar_state:opts(State2), "foo"), + true = rebar_dir:recursive(rebar_state:opts(State2), "bar"), + + ok. + profile_src_dirs(Config) -> RebarConfig = [ {erl_opts, [{src_dirs, ["foo", "bar"]}]}, @@ -118,6 +158,26 @@ profile_all_src_dirs(Config) -> R = lists:sort(["foo", "bar", "baz", "qux"]), R = rebar_dir:all_src_dirs(rebar_state:opts(State)). +profile_src_dir_opts(Config) -> + RebarConfig = [ + {erl_opts, [{src_dirs, ["foo"]}, + {extra_src_dirs, [{"bar",[recursive]}]}]}, + {profiles, [ + {more, [{erl_opts, [{src_dirs, [{"bar",[{recursive,false}]}]}, + {extra_src_dirs, ["qux"]}]}]} + ]} + ], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, + ["as", "more", "compile"], + return), + + [{recursive,false}] = rebar_dir:src_dir_opts(rebar_state:opts(State),"bar"), + + {ok, State1} = rebar_test_utils:run_and_check(Config, RebarConfig, + ["compile"], return), + + [{recursive,true}] = rebar_dir:src_dir_opts(rebar_state:opts(State1),"bar"). + retarget_path(Config) -> {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return), -- cgit v1.1 From ffc2cf98d390a35cf3f61c7c0bf5f26e3552fd2c Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Wed, 30 Nov 2016 13:45:06 -0500 Subject: 1394: added fix for rebar_utils, moved setting of http_options into init_config, added unit tests --- test/rebar_utils_SUITE.erl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index b32992d..0d496a3 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -31,7 +31,8 @@ nonblacklisted_otp_version/1, blacklisted_otp_version/1, sh_does_not_miss_messages/1, - tup_merge/1]). + tup_merge/1, + proxy_auth/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -46,7 +47,8 @@ end_per_testcase(_, _Config) -> all() -> [{group, args_to_tasks}, sh_does_not_miss_messages, - tup_merge]. + tup_merge, + proxy_auth]. groups() -> [{args_to_tasks, [], [empty_arglist, @@ -272,3 +274,15 @@ tup_merge(_Config) -> rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a,a},b,{z,a},{z,a,a},{b,a},z]) ) ). + +proxy_auth(_Config) -> + %% proxy auth with regular username/password + rebar_utils:set_proxy_auth("Username", "Password"), + ?assertEqual([{proxy_auth, {"Username", "Password"}}], + rebar_utils:get_proxy_auth()), + %% proxy auth with username missing and url encoded password + rebar_utils:set_proxy_auth("", "?!abc#$"), + ?assertEqual([{proxy_auth, {"", "%3F!abc%23%24"}}], + rebar_utils:get_proxy_auth()). + + -- cgit v1.1 From 8a546cae8eab79ea2107476e0978247457d89acb Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Wed, 30 Nov 2016 13:48:22 -0500 Subject: 1394: fixed typo --- test/rebar_utils_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 0d496a3..6cbac1a 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -277,11 +277,11 @@ tup_merge(_Config) -> proxy_auth(_Config) -> %% proxy auth with regular username/password - rebar_utils:set_proxy_auth("Username", "Password"), + rebar_utils:set_proxy_auth("Username:Password"), ?assertEqual([{proxy_auth, {"Username", "Password"}}], rebar_utils:get_proxy_auth()), %% proxy auth with username missing and url encoded password - rebar_utils:set_proxy_auth("", "?!abc#$"), + rebar_utils:set_proxy_auth(":?!abc#$"), ?assertEqual([{proxy_auth, {"", "%3F!abc%23%24"}}], rebar_utils:get_proxy_auth()). -- cgit v1.1 From f8873147abe49baa4e692b6dd93be1b8db89e172 Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Wed, 30 Nov 2016 13:52:23 -0500 Subject: 1394: fixed typos --- test/rebar_utils_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 6cbac1a..ad37e00 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -281,8 +281,8 @@ proxy_auth(_Config) -> ?assertEqual([{proxy_auth, {"Username", "Password"}}], rebar_utils:get_proxy_auth()), %% proxy auth with username missing and url encoded password - rebar_utils:set_proxy_auth(":?!abc#$"), - ?assertEqual([{proxy_auth, {"", "%3F!abc%23%24"}}], + rebar_utils:set_proxy_auth(":%3F!abc%23%24"), + ?assertEqual([{proxy_auth, {"", "?!abc#$"}}], rebar_utils:get_proxy_auth()). -- cgit v1.1 From e60562fb307a8ff59f56746427e60ed3b2a1227a Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Thu, 1 Dec 2016 02:49:53 -0500 Subject: 1394: one more test --- test/rebar_utils_SUITE.erl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index ad37e00..e8f33a3 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -276,6 +276,9 @@ tup_merge(_Config) -> ). proxy_auth(_Config) -> + application:unset_env(rebar, proxy_auth), + %% proxy auth not set + ?assertEqual([], rebar_utils:get_proxy_auth()), %% proxy auth with regular username/password rebar_utils:set_proxy_auth("Username:Password"), ?assertEqual([{proxy_auth, {"Username", "Password"}}], -- cgit v1.1 From c0184eae706f6c2bf7bcf8fc1db03c0569cb73c1 Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Thu, 1 Dec 2016 10:27:07 -0500 Subject: 1394: refined export list and tests --- test/rebar_utils_SUITE.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index e8f33a3..6307b42 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -276,15 +276,20 @@ tup_merge(_Config) -> ). proxy_auth(_Config) -> + Host = "host:", + Port = "1234", + application:unset_env(rebar, proxy_auth), %% proxy auth not set ?assertEqual([], rebar_utils:get_proxy_auth()), %% proxy auth with regular username/password - rebar_utils:set_proxy_auth("Username:Password"), + os:putenv("http_proxy", "http://Username:Password@" ++ Host ++ Port), + rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"Username", "Password"}}], rebar_utils:get_proxy_auth()), %% proxy auth with username missing and url encoded password - rebar_utils:set_proxy_auth(":%3F!abc%23%24"), + os:putenv("http_proxy", "http://:%3F!abc%23%24@" ++ Host ++ Port), + rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"", "?!abc#$"}}], rebar_utils:get_proxy_auth()). -- cgit v1.1 From 603683bca1ec067e7490405fd308cdabbc442702 Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Thu, 1 Dec 2016 11:16:33 -0500 Subject: 1394: restore original proxy spec after tests --- test/rebar_utils_SUITE.erl | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 6307b42..bdbffb0 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -278,19 +278,34 @@ tup_merge(_Config) -> proxy_auth(_Config) -> Host = "host:", Port = "1234", + + proxy_auth(_Config, "http_proxy"), + proxy_auth(_Config, "https_proxy"). + +proxy_auth(_Config, ProxyEnvKey) -> + %% remember current proxy specification + OldProxySpec = os:getenv(ProxyEnvKey), - application:unset_env(rebar, proxy_auth), %% proxy auth not set + application:unset_env(rebar, proxy_auth), ?assertEqual([], rebar_utils:get_proxy_auth()), + %% proxy auth with regular username/password - os:putenv("http_proxy", "http://Username:Password@" ++ Host ++ Port), + os:putenv(ProxyEnvKey, "http://Username:Password@" ++ Host ++ Port), rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"Username", "Password"}}], rebar_utils:get_proxy_auth()), + %% proxy auth with username missing and url encoded password - os:putenv("http_proxy", "http://:%3F!abc%23%24@" ++ Host ++ Port), + os:putenv(ProxyEnvKey, "http://:%3F!abc%23%24@" ++ Host ++ Port), rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"", "?!abc#$"}}], - rebar_utils:get_proxy_auth()). - - + rebar_utils:get_proxy_auth()), + + %% restore original proxy specification if any + restore_proxy_env(OldProxySpec). + +restore_proxy_env(false) -> + ok; +restore_proxy_env(ProxySpec) -> + os:putenv("http_proxy", ProxySpec). -- cgit v1.1 From 9ace3ba9fc1b2a1a7096e4fe62d9867f737cff1d Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Thu, 1 Dec 2016 11:17:07 -0500 Subject: 1394: fixed typo --- test/rebar_utils_SUITE.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index bdbffb0..57b6474 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -276,13 +276,13 @@ tup_merge(_Config) -> ). proxy_auth(_Config) -> - Host = "host:", - Port = "1234", - proxy_auth(_Config, "http_proxy"), proxy_auth(_Config, "https_proxy"). proxy_auth(_Config, ProxyEnvKey) -> + Host = "host:", + Port = "1234", + %% remember current proxy specification OldProxySpec = os:getenv(ProxyEnvKey), -- cgit v1.1 From 8df95d53bfd5dc892e69364dfe87ecf95c6897a2 Mon Sep 17 00:00:00 2001 From: Artem Pervin Date: Thu, 1 Dec 2016 11:20:58 -0500 Subject: 1394: fixed typo --- test/rebar_utils_SUITE.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 57b6474..dd92bbf 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -303,9 +303,9 @@ proxy_auth(_Config, ProxyEnvKey) -> rebar_utils:get_proxy_auth()), %% restore original proxy specification if any - restore_proxy_env(OldProxySpec). + restore_proxy_env(ProxyEnvKey, OldProxySpec). -restore_proxy_env(false) -> +restore_proxy_env(_, false) -> ok; -restore_proxy_env(ProxySpec) -> - os:putenv("http_proxy", ProxySpec). +restore_proxy_env(ProxyEnvKey, ProxySpec) -> + os:putenv(ProxyEnvKey, ProxySpec). -- cgit v1.1 From 2c155ead23abeedb39ff761e4db5269f7b2a78ca Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 1 Dec 2016 11:47:05 -0500 Subject: Fully clean up after test utils for proxy --- test/rebar_utils_SUITE.erl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index dd92bbf..8b8769b 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -303,9 +303,10 @@ proxy_auth(_Config, ProxyEnvKey) -> rebar_utils:get_proxy_auth()), %% restore original proxy specification if any - restore_proxy_env(ProxyEnvKey, OldProxySpec). + restore_proxy_env(ProxyEnvKey, OldProxySpec), + application:unset_env(rebar, proxy_auth). -restore_proxy_env(_, false) -> - ok; +restore_proxy_env(ProxyEnvKey, false) -> + os:putenv(ProxyEnvKey, ""); restore_proxy_env(ProxyEnvKey, ProxySpec) -> - os:putenv(ProxyEnvKey, ProxySpec). + os:putenv(ProxyEnvKey, ProxySpec). -- cgit v1.1 From 1b422b921b8921128213b29423a48cd7b2c8e417 Mon Sep 17 00:00:00 2001 From: Ted Burghart Date: Mon, 5 Dec 2016 13:22:35 -0500 Subject: Added regression tests for PR 1398 --- test/rebar_profiles_SUITE.erl | 104 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index a31a4c9..ed492a9 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -20,7 +20,12 @@ test_profile_applied_at_completion/1, test_profile_applied_before_compile/1, test_profile_applied_before_eunit/1, - test_profile_applied_to_apps/1]). + test_profile_applied_to_apps/1, + test_profile_erl_opts_order_1/1, + test_profile_erl_opts_order_2/1, + test_profile_erl_opts_order_3/1, + test_profile_erl_opts_order_4/1, + test_profile_erl_opts_order_5/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -36,7 +41,12 @@ all() -> test_profile_applied_at_completion, test_profile_applied_before_compile, test_profile_applied_before_eunit, - test_profile_applied_to_apps]. + test_profile_applied_to_apps, + test_profile_erl_opts_order_1, + test_profile_erl_opts_order_2, + test_profile_erl_opts_order_3, + test_profile_erl_opts_order_4, + test_profile_erl_opts_order_5]. init_per_suite(Config) -> application:start(meck), @@ -432,3 +442,93 @@ test_profile_applied_to_apps(Config) -> ErlOpts = dict:fetch(erl_opts, Opts), true = lists:member({d, 'TEST'}, ErlOpts) end, Apps). + +test_profile_erl_opts_order_1(Config) -> + Opts = get_compiled_profile_erl_opts([default], Config), + Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), + undefined = Opt. + +test_profile_erl_opts_order_2(Config) -> + Opts = get_compiled_profile_erl_opts([strict], Config), + Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), + warn_export_all = Opt. + +test_profile_erl_opts_order_3(Config) -> + Opts = get_compiled_profile_erl_opts([loose], Config), + Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), + nowarn_export_all = Opt. + +test_profile_erl_opts_order_4(Config) -> + Opts = get_compiled_profile_erl_opts([strict, loose], Config), + Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), + nowarn_export_all = Opt. + +test_profile_erl_opts_order_5(Config) -> + Opts = get_compiled_profile_erl_opts([loose, strict], Config), + Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), + warn_export_all = Opt. + +get_compiled_profile_erl_opts(Profiles, Config) -> + AppDir = ?config(apps, Config), + PStrs = [atom_to_list(P) || P <- Profiles], + + Name = rebar_test_utils:create_random_name( + lists:flatten(["erl_opts_order_" | [[S, $_] || S <- PStrs]])), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [ + {erl_opts, [warnings_as_errors, {d, profile_default}]}, + {profiles, [ + {strict, [{erl_opts, [warn_export_all, {d, profile_strict}]}]}, + {loose, [{erl_opts, [nowarn_export_all, {d, profile_loose}]}]} ]}], + rebar_test_utils:create_config(AppDir, RebarConfig), + + Command = case Profiles of + [] -> + ["compile"]; + [default] -> + ["compile"]; + _ -> + ["as", string:join(PStrs, ","), "compile"] + end, + {ok, State} = rebar_test_utils:run_and_check( + Config, RebarConfig, Command, {ok, [{app, Name}]}), + code:add_paths(rebar_state:code_paths(State, all_deps)), + Mod = list_to_atom(Name), + proplists:get_value(options, Mod:module_info(compile), []). + +% macro definitions get special handling +last_erl_opt([{d, Macro} = Opt | Opts], Targets, Last) -> + case lists:any(erl_opt_macro_match_fun(Macro), Targets) of + true -> + last_erl_opt(Opts, Targets, Opt); + _ -> + last_erl_opt(Opts, Targets, Last) + end; +last_erl_opt([{d, Macro, _} = Opt | Opts], Targets, Last) -> + case lists:any(erl_opt_macro_match_fun(Macro), Targets) of + true -> + last_erl_opt(Opts, Targets, Opt); + _ -> + last_erl_opt(Opts, Targets, Last) + end; +last_erl_opt([Opt | Opts], Targets, Last) -> + case lists:member(Opt, Targets) of + true -> + last_erl_opt(Opts, Targets, Opt); + _ -> + last_erl_opt(Opts, Targets, Last) + end; +last_erl_opt([], _, Last) -> + Last. + +erl_opt_macro_match_fun(Macro) -> + fun({d, M}) -> + M == Macro; + ({d, M, _}) -> + M == Macro; + (_) -> + false + end. + -- cgit v1.1 From 85e00f2a434d3295d7a683838cda002403f5af17 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 28 Nov 2016 11:45:21 +0100 Subject: Improve merge of command line options and config options Bug: option 'spec' is not specifically handled when merging options from the command line with options from rebar.config. Due to this, if the config specifies a 'spec', then this will take precedence over any 'dir' and/or 'suite' on the command line. This commit takes special care of all options that can be used to select tests - meaning that if any of the options 'spec', 'dir', 'suite', 'group' or 'case' are specified on the command line, then all 'spec', 'dir', 'suite', 'group' and 'case' options in rebar.config will be ignored. --- test/rebar_ct_SUITE.erl | 86 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 8e989b5..1995690 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -51,7 +51,9 @@ cover_compiled/1, misspecified_ct_opts/1, misspecified_ct_compile_opts/1, - misspecified_ct_first_files/1]). + misspecified_ct_first_files/1, + testspec/1, + cmd_vs_cfg_opts/1]). -include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -67,7 +69,9 @@ all() -> [{group, basic_app}, cfg_atom_suites, misspecified_ct_opts, misspecified_ct_compile_opts, - misspecified_ct_first_files]. + misspecified_ct_first_files, + testspec, + cmd_vs_cfg_opts]. groups() -> [{basic_app, [], [basic_app_default_dirs, basic_app_default_beams, @@ -1234,6 +1238,84 @@ misspecified_ct_first_files(Config) -> {badconfig, {"Value `~p' of option `~p' must be a list", {some_file, ct_first_files}}} = Error. +testspec(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_testspec_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + Spec = filename:join([AppDir, "test", "some.spec"]), + ok = filelib:ensure_dir(Spec), + ok = file:write_file(Spec, "[].\n"), + + {ok, State} = rebar_test_utils:run_and_check(C, + [], + ["as", "test", "lock"], + return), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + + {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]), + State1 = rebar_state:command_parsed_args(State, GetOptResult1), + Tests1 = rebar_prv_common_test:prepare_tests(State1), + {ok, _} = rebar_prv_common_test:compile(State1, Tests1), + + ok. + +cmd_vs_cfg_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_cmd_vs_cfg_opts_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_cmd_vs_cfg_opts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{ct_opts, [{spec,"mytest.spec"}, + {dir,"test"}, + {suite,"some_SUITE"}, + {group,"some_group"}, + {testcase,"some_test"}]}], + + {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({spec, "mytest.spec"}, TestOpts), + true = lists:member({dir, "test"}, TestOpts), + true = lists:member({suite, "some_SUITE"}, TestOpts), + true = lists:member({group, "some_group"}, TestOpts), + true = lists:member({testcase, "some_test"}, TestOpts), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + + {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]), + State1 = rebar_state:command_parsed_args(State, GetOptResult1), + {ok, TestOpts1} = rebar_prv_common_test:prepare_tests(State1), + true = lists:member({spec, ["test/some.spec"]}, TestOpts1), + false = lists:keymember(dir, 1, TestOpts1), + false = lists:keymember(suite, 1, TestOpts1), + false = lists:keymember(group, 1, TestOpts1), + false = lists:keymember(testcase, 1, TestOpts1), + + {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite","test/some_SUITE"]), + State2 = rebar_state:command_parsed_args(State, GetOptResult2), + {ok, TestOpts2} = rebar_prv_common_test:prepare_tests(State2), + true = lists:member({suite, ["test/some_SUITE"]}, TestOpts2), + false = lists:keymember(spec, 1, TestOpts2), + false = lists:keymember(dir, 1, TestOpts2), + false = lists:keymember(group, 1, TestOpts2), + false = lists:keymember(testcase, 1, TestOpts2), + + ok. + %% helper for generating test data test_suite(Name) -> io_lib:format("-module(~ts_SUITE).\n" -- cgit v1.1 From a0e7ff2eb95a8093f666d310bd5df6395a243bd8 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Thu, 8 Dec 2016 15:46:35 +0100 Subject: Add directory of testspec as extra_src_dir This is necessary in order to automatically get the testspec included as an artifact (i.e. copied to the _build dir) in the case when it is stored in another directory than 'test'. --- test/rebar_ct_SUITE.erl | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 1995690..d913748 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -1246,9 +1246,15 @@ testspec(Config) -> Name = rebar_test_utils:create_random_name("ct_testspec_"), Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), - Spec = filename:join([AppDir, "test", "some.spec"]), - ok = filelib:ensure_dir(Spec), - ok = file:write_file(Spec, "[].\n"), + Spec1 = filename:join([AppDir, "test", "some.spec"]), + ok = filelib:ensure_dir(Spec1), + ok = file:write_file(Spec1, "[].\n"), + Spec2 = filename:join([AppDir, "specs", "another.spec"]), + ok = filelib:ensure_dir(Spec2), + ok = file:write_file(Spec2, "[].\n"), + + {ok,Wd} = file:get_cwd(), + ok = file:set_cwd(AppDir), {ok, State} = rebar_test_utils:run_and_check(C, [], @@ -1263,7 +1269,21 @@ testspec(Config) -> {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]), State1 = rebar_state:command_parsed_args(State, GetOptResult1), Tests1 = rebar_prv_common_test:prepare_tests(State1), - {ok, _} = rebar_prv_common_test:compile(State1, Tests1), + {ok, NewState1} = rebar_prv_common_test:compile(State1, Tests1), + [App1] = rebar_state:project_apps(NewState1), + ["test"] = rebar_dir:extra_src_dirs(rebar_app_info:opts(App1)), + + {ok, GetOptResult2} = getopt:parse(GetOptSpec, + ["--spec","specs/another.spec"]), + State2 = rebar_state:command_parsed_args(State, GetOptResult2), + Tests2 = rebar_prv_common_test:prepare_tests(State2), + {ok, NewState2} = rebar_prv_common_test:compile(State1, Tests2), + + [App2] = rebar_state:project_apps(NewState2), + ["specs","test"] = + lists:sort(rebar_dir:extra_src_dirs(rebar_app_info:opts(App2))), + + ok = file:set_cwd(Wd), ok. -- cgit v1.1 From e427a835301c41a1403cf6b9e6c363ceae3e781c Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 9 Dec 2016 14:33:43 +0100 Subject: Translate path to testspec This is a bugfix. It makes sure that the given path to a testspec is translated so common_test will pick the spec from the _build directory, and not from the source tree. --- test/rebar_ct_SUITE.erl | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index d913748..6339e6b 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -1248,10 +1248,10 @@ testspec(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), Spec1 = filename:join([AppDir, "test", "some.spec"]), ok = filelib:ensure_dir(Spec1), - ok = file:write_file(Spec1, "[].\n"), + ok = file:write_file(Spec1, "{suites,\".\",all}.\n"), Spec2 = filename:join([AppDir, "specs", "another.spec"]), ok = filelib:ensure_dir(Spec2), - ok = file:write_file(Spec2, "[].\n"), + ok = file:write_file(Spec2, "{suites,\"../test/\",all}.\n"), {ok,Wd} = file:get_cwd(), ok = file:set_cwd(AppDir), @@ -1266,23 +1266,42 @@ testspec(Config) -> CommandProvider = providers:get_provider(ct, Providers, Namespace), GetOptSpec = providers:opts(CommandProvider), + %% Testspec in "test" directory {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec","test/some.spec"]), State1 = rebar_state:command_parsed_args(State, GetOptResult1), Tests1 = rebar_prv_common_test:prepare_tests(State1), {ok, NewState1} = rebar_prv_common_test:compile(State1, Tests1), + {ok, T1} = Tests1, + Opts1= rebar_prv_common_test:translate_paths(NewState1, T1), + + %% check thath extra src dir is added [App1] = rebar_state:project_apps(NewState1), ["test"] = rebar_dir:extra_src_dirs(rebar_app_info:opts(App1)), + %% check that path is translated + ExpectedSpec1 = filename:join([AppDir, "_build", "test", "lib", Name, + "test", "some.spec"]), + [ExpectedSpec1] = proplists:get_value(spec, Opts1), + + + %% Testspec in directory other than "test" {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--spec","specs/another.spec"]), State2 = rebar_state:command_parsed_args(State, GetOptResult2), - Tests2 = rebar_prv_common_test:prepare_tests(State2), - {ok, NewState2} = rebar_prv_common_test:compile(State1, Tests2), + Tests2 = {ok, T2} =rebar_prv_common_test:prepare_tests(State2), + {ok, NewState2} = rebar_prv_common_test:compile(State2, Tests2), + Opts2= rebar_prv_common_test:translate_paths(NewState2, T2), + %% check thath extra src dirs are added [App2] = rebar_state:project_apps(NewState2), ["specs","test"] = lists:sort(rebar_dir:extra_src_dirs(rebar_app_info:opts(App2))), + %% check that paths are translated + ExpectedSpec2 = filename:join([AppDir, "_build", "test", "lib", Name, + "specs", "another.spec"]), + [ExpectedSpec2] = proplists:get_value(spec, Opts2), + ok = file:set_cwd(Wd), ok. -- cgit v1.1 From a18340c6eed6e62237c4ec63f15daacfe86dc86c Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Tue, 13 Dec 2016 12:51:01 +0100 Subject: Allow using relative path to suite in project root --- test/rebar_ct_SUITE.erl | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 6339e6b..a47ea58 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -693,7 +693,33 @@ suite_at_root(Config) -> true = filelib:is_dir(DataDir), DataFile = filename:join([AppDir, "_build", "test", "extras", "root_SUITE_data", "some_data.txt"]), - true = filelib:is_file(DataFile). + true = filelib:is_file(DataFile), + + %% Same test again, but using relative path to the suite from the + %% project root + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(AppDir), + rebar_file_utils:rm_rf("_build"), + + {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite=" ++ "root_SUITE"]), + + State3 = rebar_state:command_parsed_args(State1, GetOptResult2), + + Tests2 = rebar_prv_common_test:prepare_tests(State3), + {ok, NewState2} = rebar_prv_common_test:compile(State3, Tests2), + {ok, T2} = Tests2, + Opts2 = rebar_prv_common_test:translate_paths(NewState2, T2), + + ok = file:set_cwd(Cwd), + + Suite2 = proplists:get_value(suite, Opts2), + [Expected] = Suite2, + true = filelib:is_file(TestHrl), + true = filelib:is_file(TestBeam), + true = filelib:is_dir(DataDir), + true = filelib:is_file(DataFile), + + ok. suite_at_app_root(Config) -> AppDir = ?config(apps, Config), @@ -730,7 +756,32 @@ suite_at_app_root(Config) -> 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). + true = filelib:is_file(DataFile), + + %% Same test again using relative path to the suite from the project root + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(AppDir), + rebar_file_utils:rm_rf("_build"), + + {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--suite=" ++ filename:join(["apps", Name2, "app_root_SUITE"])]), + + State3 = rebar_state:command_parsed_args(State1, GetOptResult2), + + Tests2 = rebar_prv_common_test:prepare_tests(State3), + {ok, NewState2} = rebar_prv_common_test:compile(State3, Tests2), + {ok, T2} = Tests2, + Opts2 = rebar_prv_common_test:translate_paths(NewState2, T2), + + ok = file:set_cwd(Cwd), + + Suite2 = proplists:get_value(suite, Opts2), + [Expected] = Suite2, + true = filelib:is_file(TestHrl), + true = filelib:is_file(TestBeam), + true = filelib:is_dir(DataDir), + true = filelib:is_file(DataFile), + + ok. %% this test probably only fails when this suite is run via rebar3 with the --cover flag data_dir_correct(Config) -> -- cgit v1.1 From 4e52ce58e505ba57f2188e34a002d70de1bd6ff5 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Fri, 16 Dec 2016 10:34:36 +0100 Subject: Add all dirs from test spec Parse given test specs and add all spec- and suite directories as extra_src_dirs in order to ensure that all these directories are copied to the _build area and the suites are compiled. Specs located in the project- or app root are explicitly copied to the _build area in order to avoid recursive copying of the complete directory tree. --- test/rebar_ct_SUITE.erl | 103 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index a47ea58..91324d2 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -53,6 +53,7 @@ misspecified_ct_compile_opts/1, misspecified_ct_first_files/1, testspec/1, + testspec_at_root/1, cmd_vs_cfg_opts/1]). -include_lib("eunit/include/eunit.hrl"). @@ -71,6 +72,7 @@ all() -> [{group, basic_app}, misspecified_ct_compile_opts, misspecified_ct_first_files, testspec, + testspec_at_root, cmd_vs_cfg_opts]. groups() -> [{basic_app, [], [basic_app_default_dirs, @@ -1302,7 +1304,9 @@ testspec(Config) -> ok = file:write_file(Spec1, "{suites,\".\",all}.\n"), Spec2 = filename:join([AppDir, "specs", "another.spec"]), ok = filelib:ensure_dir(Spec2), - ok = file:write_file(Spec2, "{suites,\"../test/\",all}.\n"), + Suites2 = filename:join([AppDir,"suites","*"]), + ok = filelib:ensure_dir(Suites2), + ok = file:write_file(Spec2, "{suites,\"../suites/\",all}.\n"), {ok,Wd} = file:get_cwd(), ok = file:set_cwd(AppDir), @@ -1325,7 +1329,7 @@ testspec(Config) -> {ok, T1} = Tests1, Opts1= rebar_prv_common_test:translate_paths(NewState1, T1), - %% check thath extra src dir is added + %% check that extra src dir is added [App1] = rebar_state:project_apps(NewState1), ["test"] = rebar_dir:extra_src_dirs(rebar_app_info:opts(App1)), @@ -1343,9 +1347,9 @@ testspec(Config) -> {ok, NewState2} = rebar_prv_common_test:compile(State2, Tests2), Opts2= rebar_prv_common_test:translate_paths(NewState2, T2), - %% check thath extra src dirs are added + %% check that extra src dirs are added [App2] = rebar_state:project_apps(NewState2), - ["specs","test"] = + ["specs","suites","test"] = lists:sort(rebar_dir:extra_src_dirs(rebar_app_info:opts(App2))), %% check that paths are translated @@ -1357,6 +1361,97 @@ testspec(Config) -> ok. +testspec_at_root(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_at_root_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_testspec_at_root_"), + Vsn = rebar_test_utils:create_random_vsn(), + AppDir1 = filename:join([AppDir, "apps", Name]), + rebar_test_utils:create_app(AppDir1, Name, Vsn, [kernel, stdlib]), + + Spec1 = filename:join([AppDir, "root.spec"]), + ok = filelib:ensure_dir(Spec1), + ok = file:write_file(Spec1, "{suites,\"test\",all}."), + Spec2 = filename:join([AppDir, "root1.spec"]), + ok = file:write_file(Spec2, "{suites,\".\",all}."), + Spec3 = filename:join([AppDir, "root2.spec"]), + ok = file:write_file(Spec3, "{suites,\"suites\",all}."), + Suite1 = filename:join(AppDir,"root_SUITE.erl"), + ok = file:write_file(Suite1, test_suite("root")), + Suite2 = filename:join([AppDir,"suites","test_SUITE.erl"]), + ok = filelib:ensure_dir(Suite2), + ok = file:write_file(Suite2, test_suite("test")), + + {ok, State} = rebar_test_utils:run_and_check(C, + [], + ["as", "test", "lock"], + return), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + + SpecArg1 = string:join([Spec1,Spec2,Spec3],","), + {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec",SpecArg1]), + State1 = rebar_state:command_parsed_args(State, GetOptResult1), + Tests1 = rebar_prv_common_test:prepare_tests(State1), + {ok, NewState1} = rebar_prv_common_test:compile(State1, Tests1), + {ok, T1} = Tests1, + Opts1= rebar_prv_common_test:translate_paths(NewState1, T1), + + %% check that extra src dir is added + ExtraDir = filename:join([AppDir, "_build", "test", "extras"]), + [ExtraDir,"suites","test"] = + rebar_dir:extra_src_dirs(rebar_state:opts(NewState1)), + + %% check that path is translated + ExpectedSpec1 = filename:join([AppDir, "_build", "test", + "extras", "root.spec"]), + ExpectedSpec2 = filename:join([AppDir, "_build", "test", + "extras", "root1.spec"]), + ExpectedSpec3 = filename:join([AppDir, "_build", "test", + "extras", "root2.spec"]), + [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] = + lists:sort(proplists:get_value(spec, Opts1)), + + %% check that test specs are copied + [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] = + lists:sort(filelib:wildcard(filename:join([AppDir, "_build", "test", + "extras", "*.spec"]))), + + %% Same test again, using relative path + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(AppDir), + ok = rebar_file_utils:rm_rf("_build"), + + SpecArg2 = "root.spec,root1.spec,root2.spec", + {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--spec",SpecArg2]), + State2 = rebar_state:command_parsed_args(State, GetOptResult2), + Tests2 = rebar_prv_common_test:prepare_tests(State2), + {ok, NewState2} = rebar_prv_common_test:compile(State2, Tests2), + {ok, T2} = Tests2, + Opts2= rebar_prv_common_test:translate_paths(NewState2, T2), + + %% check that extra src dir is added + [ExtraDir,"suites","test"] = + rebar_dir:extra_src_dirs(rebar_state:opts(NewState2)), + + %% check that path is translated + [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] = + lists:sort(proplists:get_value(spec, Opts2)), + + %% check that test specs are copied + [ExpectedSpec1,ExpectedSpec2,ExpectedSpec3] = + lists:sort(filelib:wildcard(filename:join([AppDir, "_build", "test", + "extras", "root*.spec"]))), + + ok = file:set_cwd(Cwd), + + ok. + cmd_vs_cfg_opts(Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_cmd_vs_cfg_opts_"), -- cgit v1.1 From 146f2732b96b5db6476e3b86b13e7a3d7b1b2dc5 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Thu, 22 Dec 2016 22:14:07 +0100 Subject: Handle errors from ct_testspec --- test/rebar_ct_SUITE.erl | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 91324d2..06dc76e 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -54,6 +54,7 @@ misspecified_ct_first_files/1, testspec/1, testspec_at_root/1, + testspec_parse_error/1, cmd_vs_cfg_opts/1]). -include_lib("eunit/include/eunit.hrl"). @@ -73,6 +74,7 @@ all() -> [{group, basic_app}, misspecified_ct_first_files, testspec, testspec_at_root, + testspec_parse_error, cmd_vs_cfg_opts]. groups() -> [{basic_app, [], [basic_app_default_dirs, @@ -1452,6 +1454,51 @@ testspec_at_root(Config) -> ok. +testspec_parse_error(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_error"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_testspec_error"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + Spec1 = filename:join([AppDir, "test", "nonexisting.spec"]), + Spec2 = filename:join([AppDir, "test", "some.spec"]), + ok = filelib:ensure_dir(Spec2), + ok = file:write_file(Spec2, ".\n"), + + {ok, State} = rebar_test_utils:run_and_check(C, + [], + ["as", "test", "lock"], + return), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + + %% Non existing testspec + {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec",Spec1]), + State1 = rebar_state:command_parsed_args(State, GetOptResult1), + Tests1 = rebar_prv_common_test:prepare_tests(State1), + {error, + {rebar_prv_common_test, + {error_reading_testspec, + {Spec1,"no such file or directory"}}}} = + rebar_prv_common_test:compile(State1, Tests1), + + %% Syntax error + {ok, GetOptResult2} = getopt:parse(GetOptSpec, ["--spec",Spec2]), + State2 = rebar_state:command_parsed_args(State, GetOptResult2), + Tests2 = rebar_prv_common_test:prepare_tests(State2), + {error, + {rebar_prv_common_test, + {error_reading_testspec, + {Spec2,"1: syntax error before: '.'"}}}} = + rebar_prv_common_test:compile(State2, Tests2), + + ok. + cmd_vs_cfg_opts(Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_cmd_vs_cfg_opts_"), -- cgit v1.1 From 92e6997cf128382f7596fcc546caceee9d10a428 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 27 Jan 2017 10:56:22 -0500 Subject: Fix mv command on windows Requires changing a bunch of arguments for xerocopy since it does not allow to rename while copying. Lots of tests added --- test/rebar_file_utils_SUITE.erl | 186 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index 7285e13..949001d 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -4,6 +4,8 @@ groups/0, init_per_group/2, end_per_group/2, + init_per_testcase/2, + end_per_testcase/2, raw_tmpdir/1, empty_tmpdir/1, simple_tmpdir/1, @@ -15,7 +17,13 @@ canonical_path/1, resolve_link/1, split_dirname/1, - mv_warning_is_ignored/1]). + mv_warning_is_ignored/1, + mv_dir/1, + mv_file_same/1, + mv_file_diff/1, + mv_file_dir_same/1, + mv_file_dir_diff/1, + mv_no_clobber/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -25,6 +33,7 @@ all() -> [{group, tmpdir}, {group, reset_dir}, + {group, mv}, path_from_ancestor, canonical_path, resolve_link, @@ -33,7 +42,9 @@ all() -> groups() -> [{tmpdir, [], [raw_tmpdir, empty_tmpdir, simple_tmpdir, multi_tmpdir]}, - {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]}]. + {reset_dir, [], [reset_nonexistent_dir, reset_empty_dir, reset_dir]}, + {mv, [], [mv_dir, mv_file_same, mv_file_diff, + mv_file_dir_same, mv_file_dir_diff, mv_no_clobber]}]. init_per_group(reset_dir, Config) -> TmpDir = rebar_file_utils:system_tmpdir(["rebar_file_utils_SUITE", "resetable"]), @@ -41,6 +52,20 @@ init_per_group(reset_dir, Config) -> init_per_group(_, Config) -> Config. end_per_group(_, Config) -> Config. +init_per_testcase(Test, Config) -> + case os:type() of + {win32, _} -> + case lists:member(Test, [resolve_link, mv_warning_is_ignored]) of + true -> {skip, "broken in windows"}; + false -> Config + end; + _ -> + Config + end. + +end_per_testcase(_Test, Config) -> + Config. + raw_tmpdir(_Config) -> case rebar_file_utils:system_tmpdir() of "/tmp" -> ok; @@ -143,3 +168,160 @@ mv_warning_is_ignored(_Config) -> meck:expect(rebar_utils, sh, fun("mv ding dong", _) -> {ok, "Warning"} end), ok = rebar_file_utils:mv("ding", "dong"), meck:unload(rebar_utils). + +%%% Ensure Windows & Unix operations to move files + +mv_dir(Config) -> + %% Move a directory to another one location + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_dir), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + %% empty dir movement + DstDir1 = filename:join(BaseDir, "dst1/"), + ?assertNot(filelib:is_dir(DstDir1)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir1)), + ?assert(filelib:is_dir(DstDir1)), + + %% move files from dir to empty dir + F1 = filename:join(SrcDir, "file1"), + F2 = filename:join(SrcDir, "subdir/file2"), + ec_file:mkdir_p(F2), + file:write_file(F1, "hello"), + file:write_file(F2, "world"), + DstDir2 = filename:join(BaseDir, "dst2/"), + D2F1 = filename:join(DstDir2, "file1"), + D2F2 = filename:join(DstDir2, "subdir/file2"), + ?assertNot(filelib:is_dir(DstDir2)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)), + ?assert(filelib:is_file(D2F1)), + ?assert(filelib:is_file(D2F2)), + + %% move files from dir to existing dir + ec_file:mkdir_p(F2), + file:write_file(F1, "hello"), + file:write_file(F2, "world"), + DstDir3 = filename:join(BaseDir, "dst3/"), + D3F1 = filename:join(DstDir3, "file1"), + D3F2 = filename:join(DstDir3, "subdir/file2"), + ec_file:mkdir_p(DstDir3), + ?assert(filelib:is_dir(DstDir3)), + ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)), + ?assert(filelib:is_file(D3F1)), + ?assert(filelib:is_file(D3F2)), + ?assertNot(filelib:is_dir(SrcDir)), + ok. + +mv_file_same(Config) -> + %% Move a file from a directory to the other without renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_same), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file"), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_diff(Config) -> + %% Move a file from a directory to another one while renaming + %% into a pre-existing file + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_diff), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file-rename"), + file:write_file(Dst, "not-the-right-content"), + ?assert(filelib:is_file(Dst)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_dir_same(Config) -> + %% Move a file to a directory without renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_dir_same), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file"), + ?assert(filelib:is_dir(DstDir)), + ?assertEqual(ok, rebar_file_utils:mv(F, DstDir)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_file_dir_diff(Config) -> + %% Move a file to a directory while renaming + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_file_dir_diff), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + DstDir = filename:join(BaseDir, "dst/"), + Dst = filename:join(DstDir, "file-rename"), + ?assertNot(filelib:is_dir(DstDir)), + ?assertNot(filelib:is_file(Dst)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ok. + +mv_no_clobber(Config) -> + %% Moving a file while renaming does not clobber other files + PrivDir = ?config(priv_dir, Config), + BaseDir = mk_base_dir(PrivDir, mv_no_clobber), + SrcDir = filename:join(BaseDir, "src/"), + ec_file:mkdir_p(SrcDir), + ?assert(filelib:is_dir(SrcDir)), + F = filename:join(SrcDir, "file"), + file:write_file(F, "hello"), + FBad = filename:join(SrcDir, "file-alt"), + file:write_file(FBad, "wrong-data"), + DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), + Dst = filename:join(DstDir, "file-alt"), + DstBad = filename:join(DstDir, "file"), + file:write_file(DstBad, "wrong-data"), + ?assert(filelib:is_file(F)), + ?assert(filelib:is_file(FBad)), + ?assert(filelib:is_dir(DstDir)), + ?assertNot(filelib:is_file(Dst)), + ?assert(filelib:is_file(DstBad)), + ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), + ?assert(filelib:is_file(Dst)), + ?assertNot(filelib:is_file(F)), + ?assert(filelib:is_file(DstBad)), + ?assert(filelib:is_file(FBad)), + ?assertEqual({ok, <<"hello">>}, file:read_file(Dst)), + ?assertEqual({ok, <<"wrong-data">>}, file:read_file(FBad)), + ?assertEqual({ok, <<"wrong-data">>}, file:read_file(DstBad)), + ok. + + +mk_base_dir(BasePath, Name) -> + {_,_,Micro} = os:timestamp(), + Index = integer_to_list(Micro), + Path = filename:join(BasePath, atom_to_list(Name) ++ Index), + ec_file:mkdir_p(Path), + Path. -- cgit v1.1 From bc3b53f1e5d1a78d94c3cc2f68404ee41a1abd66 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 27 Jan 2017 12:19:08 -0500 Subject: Rework test to work and pass on linux to be roundtripped again to windows. --- test/rebar_file_utils_SUITE.erl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/rebar_file_utils_SUITE.erl b/test/rebar_file_utils_SUITE.erl index 949001d..4cc6a93 100644 --- a/test/rebar_file_utils_SUITE.erl +++ b/test/rebar_file_utils_SUITE.erl @@ -187,7 +187,7 @@ mv_dir(Config) -> %% move files from dir to empty dir F1 = filename:join(SrcDir, "file1"), F2 = filename:join(SrcDir, "subdir/file2"), - ec_file:mkdir_p(F2), + filelib:ensure_dir(F2), file:write_file(F1, "hello"), file:write_file(F2, "world"), DstDir2 = filename:join(BaseDir, "dst2/"), @@ -197,17 +197,20 @@ mv_dir(Config) -> ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir2)), ?assert(filelib:is_file(D2F1)), ?assert(filelib:is_file(D2F2)), - - %% move files from dir to existing dir - ec_file:mkdir_p(F2), + + %% move files from dir to existing dir moves it to + %% a subdir + filelib:ensure_dir(F2), file:write_file(F1, "hello"), file:write_file(F2, "world"), DstDir3 = filename:join(BaseDir, "dst3/"), - D3F1 = filename:join(DstDir3, "file1"), - D3F2 = filename:join(DstDir3, "subdir/file2"), + D3F1 = filename:join(DstDir3, "src/file1"), + D3F2 = filename:join(DstDir3, "src/subdir/file2"), ec_file:mkdir_p(DstDir3), ?assert(filelib:is_dir(DstDir3)), ?assertEqual(ok, rebar_file_utils:mv(SrcDir, DstDir3)), + ?assertNot(filelib:is_file(F1)), + ?assertNot(filelib:is_file(F2)), ?assert(filelib:is_file(D3F1)), ?assert(filelib:is_file(D3F2)), ?assertNot(filelib:is_dir(SrcDir)), @@ -279,8 +282,9 @@ mv_file_dir_diff(Config) -> F = filename:join(SrcDir, "file"), file:write_file(F, "hello"), DstDir = filename:join(BaseDir, "dst/"), + ec_file:mkdir_p(DstDir), Dst = filename:join(DstDir, "file-rename"), - ?assertNot(filelib:is_dir(DstDir)), + ?assert(filelib:is_dir(DstDir)), ?assertNot(filelib:is_file(Dst)), ?assertEqual(ok, rebar_file_utils:mv(F, Dst)), ?assert(filelib:is_file(Dst)), -- cgit v1.1 From ba954cfb43f0b05e15ee206b13488d62c3537267 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 27 Jan 2017 21:30:18 -0500 Subject: Survive EDoc crashes Instead of a hard crash, display an error message indicating which app failed. We can't report the exact failure; only EDoc does it to stdout itself and we can't capture it. Pre/Post hooks are run properly despite the failure, as per escript and compile providers. --- test/rebar_edoc_SUITE.erl | 22 +++++++++++++- .../bad/apps/bar1/src/bar1.app.src | 16 ++++++++++ .../bad/apps/bar1/src/bar1.erl | 9 ++++++ .../bad/apps/bar1/src/bar1_app.erl | 26 ++++++++++++++++ .../bad/apps/bar1/src/bar1_sup.erl | 35 ++++++++++++++++++++++ .../bad/apps/bar2/src/bar2.app.src | 16 ++++++++++ .../bad/apps/bar2/src/bar2.erl | 12 ++++++++ .../bad/apps/bar2/src/bar2_app.erl | 26 ++++++++++++++++ .../bad/apps/bar2/src/bar2_sup.erl | 35 ++++++++++++++++++++++ .../bad/apps/foo/src/foo.app.src | 17 +++++++++++ .../rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl | 19 ++++++++++++ .../bad/apps/foo/src/foo_app.erl | 26 ++++++++++++++++ .../bad/apps/foo/src/foo_sup.erl | 35 ++++++++++++++++++++++ 13 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl create mode 100644 test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl (limited to 'test') diff --git a/test/rebar_edoc_SUITE.erl b/test/rebar_edoc_SUITE.erl index fded2b0..2c4aba5 100644 --- a/test/rebar_edoc_SUITE.erl +++ b/test/rebar_edoc_SUITE.erl @@ -3,7 +3,7 @@ -include_lib("eunit/include/eunit.hrl"). -compile(export_all). -all() -> [multiapp]. +all() -> [multiapp, error_survival]. init_per_testcase(multiapp, Config) -> application:load(rebar), @@ -16,6 +16,18 @@ init_per_testcase(multiapp, Config) -> rebar_log:init(command_line, Verbosity), State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])} ,{root_dir, AppsDir}]), + [{apps, AppsDir}, {state, State}, {name, Name} | Config]; +init_per_testcase(error_survival, Config) -> + application:load(rebar), + DataDir = ?config(data_dir, Config), + PrivDir = ?config(priv_dir, Config), + Name = rebar_test_utils:create_random_name("error_survival"), + AppsDir = filename:join([PrivDir, rebar_test_utils:create_random_name(Name)]), + ec_file:copy(filename:join([DataDir, "bad"]), AppsDir, [recursive]), + Verbosity = rebar3:log_level(), + rebar_log:init(command_line, Verbosity), + State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])} + ,{root_dir, AppsDir}]), [{apps, AppsDir}, {state, State}, {name, Name} | Config]. end_per_testcase(_, Config) -> @@ -42,6 +54,14 @@ multiapp(Config) -> filename:join([AppsDir, "apps", "foo", "doc", "foo.html"]), "apps/bar1/doc/bar1.html")). +error_survival(Config) -> + RebarConfig = [], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["edoc"], + {error,{rebar_prv_edoc,{app_failed,"bar2"}}} + ), + ok. + file_content_matches(Path, Regex) -> case file:read_file(Path) of diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src new file mode 100644 index 0000000..6e7ec24 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.app.src @@ -0,0 +1,16 @@ +{application, bar1, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { bar1_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl new file mode 100644 index 0000000..2700aef --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1.erl @@ -0,0 +1,9 @@ +-module(bar1). +-export([bar1/0]). +-export_type([barer1/0]). + +-type barer1() :: string(). + +% @doc Bar1 bars the bar. +-spec bar1() -> barer1(). +bar1() -> "Barer1". \ No newline at end of file diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl new file mode 100644 index 0000000..414ac30 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc bar1 public API +%% @end +%%%------------------------------------------------------------------- + +-module(bar1_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + bar1_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl new file mode 100644 index 0000000..f9d6670 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar1/src/bar1_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc bar1 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(bar1_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_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src new file mode 100644 index 0000000..58de8bc --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.app.src @@ -0,0 +1,16 @@ +{application, bar2, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { bar2_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl new file mode 100644 index 0000000..2afb745 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2.erl @@ -0,0 +1,12 @@ +%% @doc one docline is fine +%% @doc a second docline causes a failure +%% @doc if not, then a & causes a bad ref error. +-module(bar2). +-export([bar2/0]). +-export_type([barer2/0]). + +-type barer2() :: string(). + +% @doc Bar2 bars the bar2. +-spec bar2() -> barer2(). +bar2() -> "Barer2". diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl new file mode 100644 index 0000000..d0058a0 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc bar2 public API +%% @end +%%%------------------------------------------------------------------- + +-module(bar2_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + bar2_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl new file mode 100644 index 0000000..0bdaf4a --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/bar2/src/bar2_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc bar2 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(bar2_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_edoc_SUITE_data/bad/apps/foo/src/foo.app.src b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src new file mode 100644 index 0000000..9987fd5 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.app.src @@ -0,0 +1,17 @@ +{application, foo, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { foo_app, []}}, + {applications, + [kernel, + stdlib, + bar1, bar2 + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl new file mode 100644 index 0000000..52e3d0a --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo.erl @@ -0,0 +1,19 @@ +-module(foo). + +-export([foo/0, bar1/0, bar2/0]). + +-export_type([fooer/0]). + +-type fooer() :: string(). + +% @doc Foo function returns fooer. +-spec foo() -> fooer(). +foo() -> "fooer". + +% @doc Bar1 function returns barer1. +-spec bar1() -> bar1:barer1(). +bar1() -> bar1:bar1(). + +% @doc Bar2 functions returns barer2. +-spec bar2() -> bar2:barer2(). +bar2() -> bar2:bar2(). \ No newline at end of file diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl new file mode 100644 index 0000000..d0158d7 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc foo public API +%% @end +%%%------------------------------------------------------------------- + +-module(foo_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + foo_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl new file mode 100644 index 0000000..67e88b4 --- /dev/null +++ b/test/rebar_edoc_SUITE_data/bad/apps/foo/src/foo_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc foo top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(foo_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 +%%==================================================================== -- cgit v1.1 From 6c416febc2dfc9811270c20d090f43009d3bfc64 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 28 Jan 2017 22:24:38 -0800 Subject: consider `ERL_COMPILER_OPTIONS` when recompiling on 19.x forward the compiler should now take into consideration the value of the environment variable `ERL_COMPILER_OPTIONS` when deciding whether or not to recompile a module --- test/rebar_compile_SUITE.erl | 98 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 3e4d5b9..aec5dff 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -44,6 +44,8 @@ include_file_in_src/1, include_file_relative_to_working_directory_test/1, include_file_in_src_test/1, + dont_recompile_when_erl_compiler_options_env_does_not_change/1, + recompile_when_erl_compiler_options_env_changes/1, always_recompile_when_erl_compiler_options_set/1, recompile_when_parse_transform_inline_changes/1, recompile_when_parse_transform_as_opt_changes/1, @@ -74,10 +76,20 @@ all() -> include_file_relative_to_working_directory_test, include_file_in_src_test, recompile_when_parse_transform_as_opt_changes, recompile_when_parse_transform_inline_changes, - recursive, no_recursive] ++ - case erlang:function_exported(os, unsetenv, 1) of - true -> [always_recompile_when_erl_compiler_options_set]; - false -> [] + %% recompile behaviour when `ERL_COMPILER_OPTIONS` differs prior to 19.x + recursive, no_recursive] ++ recompile_when_env_changes_test(). + +recompile_when_env_changes_test() -> + _ = code:ensure_loaded(os), + UnSetEnv = erlang:function_exported(os, unsetenv, 1), + _ = code:ensure_loaded(compile), + EnvOpts = erlang:function_exported(compile, env_compiler_options, 0), + case {UnSetEnv, EnvOpts} of + {true, true} -> + [dont_recompile_when_erl_compiler_options_env_does_not_change, + recompile_when_erl_compiler_options_env_changes]; + {true, false} -> [always_recompile_when_erl_compiler_options_set]; + {false, _} -> [] end. groups() -> @@ -1385,7 +1397,45 @@ include_file_in_src_test(Config) -> ["as", "test", "compile"], {ok, [{app, Name}]}). -always_recompile_when_erl_compiler_options_set(Config) -> +dont_recompile_when_erl_compiler_options_env_does_not_change(Config) -> + %% save existing env to restore after test + ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), + + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("erl_compiler_options_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + true = os:unsetenv("ERL_COMPILER_OPTIONS"), + + true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + + {ok, Files} = rebar_utils:list_dir(EbinDir), + ModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- Files, filename:extension(F) == ".beam"], + + timer:sleep(1000), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + {ok, NewFiles} = rebar_utils:list_dir(EbinDir), + NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- NewFiles, filename:extension(F) == ".beam"], + + ?assert(ModTime == NewModTime), + + %% restore existing env + case ExistingEnv of + false -> ok; + _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) + end. + +recompile_when_erl_compiler_options_env_changes(Config) -> %% save existing env to restore after test ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), @@ -1423,6 +1473,44 @@ always_recompile_when_erl_compiler_options_set(Config) -> _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) end. +always_recompile_when_erl_compiler_options_set(Config) -> + %% save existing env to restore after test + ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), + + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("erl_compiler_options_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + true = os:unsetenv("ERL_COMPILER_OPTIONS"), + + true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + + {ok, Files} = rebar_utils:list_dir(EbinDir), + ModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- Files, filename:extension(F) == ".beam"], + + timer:sleep(1000), + + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + + {ok, NewFiles} = rebar_utils:list_dir(EbinDir), + NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- NewFiles, filename:extension(F) == ".beam"], + + ?assert(ModTime =/= NewModTime), + + %% restore existing env + case ExistingEnv of + false -> ok; + _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) + end. + recompile_when_parse_transform_inline_changes(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 8e055041607868fe6f5b37d93804c34b670b76a3 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 28 Jan 2017 23:28:01 -0800 Subject: comment `ERL_COMPILER_OPTIONS` tests --- test/rebar_compile_SUITE.erl | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index aec5dff..d5cc8b4 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1397,6 +1397,9 @@ include_file_in_src_test(Config) -> ["as", "test", "compile"], {ok, [{app, Name}]}). +%% this test sets the env var, compiles, records the file last modified timestamp, +%% recompiles and compares the file last modified timestamp to ensure it hasn't +%% changed. this test should run on 19.x+ dont_recompile_when_erl_compiler_options_env_does_not_change(Config) -> %% save existing env to restore after test ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), @@ -1435,6 +1438,9 @@ dont_recompile_when_erl_compiler_options_env_does_not_change(Config) -> _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) end. +%% this test compiles, records the file last modified timestamp, sets the env +%% var, recompiles and compares the file last modified timestamp to ensure it +%% has changed. this test should run on 19.x+ recompile_when_erl_compiler_options_env_changes(Config) -> %% save existing env to restore after test ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), @@ -1473,6 +1479,9 @@ recompile_when_erl_compiler_options_env_changes(Config) -> _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) end. +%% this test sets the env var, compiles, records the file last modified +%% timestamp, recompiles and compares the file last modified timestamp to +%% ensure it has changed. this test should run on 18.x always_recompile_when_erl_compiler_options_set(Config) -> %% save existing env to restore after test ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"), -- cgit v1.1 From 44132db73ea084249ed28c9b804564bfed8d69fd Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 28 Jan 2017 23:22:36 -0500 Subject: Add regression for #1410 --- test/rebar_compile_SUITE.erl | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index d5cc8b4..7df0d63 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -49,7 +49,8 @@ always_recompile_when_erl_compiler_options_set/1, recompile_when_parse_transform_inline_changes/1, recompile_when_parse_transform_as_opt_changes/1, - recursive/1,no_recursive/1]). + recursive/1,no_recursive/1, + regex_filter_skip/1, regex_filter_regression/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -76,6 +77,7 @@ all() -> include_file_relative_to_working_directory_test, include_file_in_src_test, recompile_when_parse_transform_as_opt_changes, recompile_when_parse_transform_inline_changes, + regex_filter_skip, regex_filter_regression, %% recompile behaviour when `ERL_COMPILER_OPTIONS` differs prior to 19.x recursive, no_recursive] ++ recompile_when_env_changes_test(). @@ -1653,5 +1655,35 @@ no_recursive(Config) -> {ok, [{app, Name}]}), {ok, Files2} = rebar_utils:list_dir(EbinDir), ?assert(false==lists:member("rec.beam",Files2)), + ok. +regex_filter_skip(Config) -> + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("regex_skip"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:write_src_file(filename:join(AppDir,src),"._rec.erl"), + Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","._rec.beam"]), + + RebarConfig = [], + try + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], + {ok, [{file, Expected}]}), + throw(should_not_be_found) + catch + error:{assert,_} -> % the file was not found, as desired! + ok + end. + +regex_filter_regression(Config) -> + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("regex_regression"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:write_src_file(filename:join(AppDir,src),"r_f.erl"), + Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","r_f.beam"]), + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], + {ok, [{file, Expected}]}), ok. + -- cgit v1.1 From 34546941ae3ef87816a087aa966bfec2a3c4e35b Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 29 Jan 2017 02:07:48 -0500 Subject: Make test work on all OTPs --- test/rebar_compile_SUITE.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 7df0d63..9f01496 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1671,7 +1671,10 @@ regex_filter_skip(Config) -> {ok, [{file, Expected}]}), throw(should_not_be_found) catch - error:{assert,_} -> % the file was not found, as desired! + %% the file was not found, as desired! + error:{assertion_failed,_} -> %% OTP =< 17 + ok; + error:{assert,_} -> %% OTP >= 18 ok end. -- cgit v1.1 From 9b099f41d6100f87dcb334d4acdcfbcdac2c97f1 Mon Sep 17 00:00:00 2001 From: Drew Varner Date: Mon, 30 Jan 2017 02:22:16 -0500 Subject: Allow exclusion of apps in cover Adds a new option `{cover_excl_apps, Apps}` to exclude apps from coverage analysis by name. --- test/rebar_cover_SUITE.erl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index 4192f4a..cc06c95 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -13,7 +13,7 @@ index_written/1, flag_verbose/1, config_verbose/1, - excl_mods/1, + excl_mods_and_apps/1, coverdata_is_reset_on_write/1]). -include_lib("common_test/include/ct.hrl"). @@ -38,7 +38,7 @@ all() -> root_extra_src_dirs, index_written, flag_verbose, config_verbose, - excl_mods, coverdata_is_reset_on_write]. + excl_mods_and_apps, coverdata_is_reset_on_write]. flag_coverdata_written(Config) -> AppDir = ?config(apps, Config), @@ -210,7 +210,7 @@ config_verbose(Config) -> true = filelib:is_file(filename:join([AppDir, "_build", "test", "cover", "index.html"])). -excl_mods(Config) -> +excl_mods_and_apps(Config) -> AppDir = ?config(apps, Config), Name1 = rebar_test_utils:create_random_name("relapp1_"), @@ -221,18 +221,25 @@ excl_mods(Config) -> Vsn2 = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]), + Name3 = rebar_test_utils:create_random_name("excludeme_"), + Vsn3 = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(filename:join([AppDir, "apps", Name3]), Name3, Vsn3, [kernel, stdlib]), + Mod1 = list_to_atom(Name1), Mod2 = list_to_atom(Name2), + Mod3 = list_to_atom(Name3), RebarConfig = [{erl_opts, [{d, some_define}]}, - {cover_excl_mods, [Mod2]}], + {cover_excl_mods, [Mod2]}, + {cover_excl_apps, [Name3]}], rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit", "--cover"], - {ok, [{app, Name1}, {app, Name2}]}), + {ok, [{app, Name1}, {app, Name2}, {app, Name3}]}), {file, _} = cover:is_compiled(Mod1), - false = cover:is_compiled(Mod2). + false = cover:is_compiled(Mod2), + false = cover:is_compiled(Mod3). coverdata_is_reset_on_write(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 5932c9608fc90e2cda7ff28c198c7e0b915a43d8 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sun, 5 Feb 2017 21:26:22 -0800 Subject: use proper skips in compiler tests that use unavailable functions --- test/rebar_compile_SUITE.erl | 46 ++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 9f01496..5a18745 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -78,21 +78,10 @@ all() -> recompile_when_parse_transform_as_opt_changes, recompile_when_parse_transform_inline_changes, regex_filter_skip, regex_filter_regression, - %% recompile behaviour when `ERL_COMPILER_OPTIONS` differs prior to 19.x - recursive, no_recursive] ++ recompile_when_env_changes_test(). - -recompile_when_env_changes_test() -> - _ = code:ensure_loaded(os), - UnSetEnv = erlang:function_exported(os, unsetenv, 1), - _ = code:ensure_loaded(compile), - EnvOpts = erlang:function_exported(compile, env_compiler_options, 0), - case {UnSetEnv, EnvOpts} of - {true, true} -> - [dont_recompile_when_erl_compiler_options_env_does_not_change, - recompile_when_erl_compiler_options_env_changes]; - {true, false} -> [always_recompile_when_erl_compiler_options_set]; - {false, _} -> [] - end. + recursive, no_recursive, + always_recompile_when_erl_compiler_options_set, + dont_recompile_when_erl_compiler_options_env_does_not_change, + recompile_when_erl_compiler_options_env_changes]. groups() -> [{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]}, @@ -266,7 +255,31 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ok. -init_per_testcase(_, Config) -> +init_per_testcase(Test, Config) when + Test == dont_recompile_when_erl_compiler_options_env_does_not_change + orelse + Test == recompile_when_erl_compiler_options_env_changes -> + _ = code:ensure_loaded(os), + UnSetEnv = erlang:function_exported(os, unsetenv, 1), + _ = code:ensure_loaded(compile), + EnvOpts = erlang:function_exported(compile, env_compiler_options, 0), + case {UnSetEnv, EnvOpts} of + {true, true} -> maybe_init_config(Config); + _ -> {skip, "compile:env_compiler_options/0 unavailable"} + end; +init_per_testcase(always_recompile_when_erl_compiler_options_set, Config) -> + _ = code:ensure_loaded(os), + UnSetEnv = erlang:function_exported(os, unsetenv, 1), + _ = code:ensure_loaded(compile), + EnvOpts = erlang:function_exported(compile, env_compiler_options, 0), + case {UnSetEnv, EnvOpts} of + {true, true} -> {skip, "compile:env_compiler_options/0 available"}; + {true, false} -> maybe_init_config(Config); + _ -> {skip, "os:unsetenv/1 unavailable"} + end; +init_per_testcase(_, Config) -> maybe_init_config(Config). + +maybe_init_config(Config) -> case ?config(apps, Config) of undefined -> rebar_test_utils:init_rebar_state(Config); _ -> Config @@ -276,7 +289,6 @@ end_per_testcase(_, _Config) -> catch meck:unload(). - %% test cases build_basic_app(Config) -> -- cgit v1.1 From c64c88f262abaad677042d8eab0c41ff54af4b7b Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 19 Feb 2017 11:11:24 -0500 Subject: Add respect for src_dirs option in app_discover This lets people who use custom directories layout without leaving the .app.src in src/ to still see their app build. --- test/rebar_src_dirs_SUITE.erl | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_src_dirs_SUITE.erl b/test/rebar_src_dirs_SUITE.erl index f854a94..1982301 100644 --- a/test/rebar_src_dirs_SUITE.erl +++ b/test/rebar_src_dirs_SUITE.erl @@ -11,6 +11,7 @@ src_dirs_in_erl_opts/1, extra_src_dirs_in_erl_opts/1, src_dirs_at_root_and_in_erl_opts/1, + dupe_src_dirs_at_root_and_in_erl_opts/1, extra_src_dirs_at_root_and_in_erl_opts/1, build_basic_app/1, build_multi_apps/1, @@ -35,7 +36,9 @@ end_per_testcase(_, _Config) -> ok. all() -> [src_dirs_at_root, extra_src_dirs_at_root, src_dirs_in_erl_opts, extra_src_dirs_in_erl_opts, - src_dirs_at_root_and_in_erl_opts, extra_src_dirs_at_root_and_in_erl_opts, + src_dirs_at_root_and_in_erl_opts, + dupe_src_dirs_at_root_and_in_erl_opts, + extra_src_dirs_at_root_and_in_erl_opts, build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra]. src_dirs_at_root(Config) -> @@ -93,15 +96,47 @@ extra_src_dirs_in_erl_opts(Config) -> src_dirs_at_root_and_in_erl_opts(Config) -> AppDir = ?config(apps, Config), - Name = rebar_test_utils:create_random_name("app1_"), + Name = rebar_test_utils:create_random_name("src_dirs_root_erlopts_"), Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, {src_dirs, ["baz", "qux"]}], + %% move the .app.src file to one of the subdirs, out of src/ + filelib:ensure_dir(filename:join([AppDir, "qux", "fake"])), + rebar_file_utils:mv(filename:join([AppDir, "src", Name ++ ".app.src"]), + filename:join([AppDir, "qux", Name ++ ".app.src"])), + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []). + ["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []), + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], + {ok, [{app, Name}]}), + ok. + +dupe_src_dirs_at_root_and_in_erl_opts(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("dupe_src_dirs_root_erlopts_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, {src_dirs, ["baz", "qux"]}], + + %% move the .app.src file to one of the subdirs, out of src/ + filelib:ensure_dir(filename:join([AppDir, "qux", "fake"])), + filelib:ensure_dir(filename:join([AppDir, "foo", "fake"])), + Src1 = filename:join([AppDir, "qux", Name ++ ".app.src"]), + Src2 = filename:join([AppDir, "foo", Name ++ ".app.src"]), + rebar_file_utils:mv(filename:join([AppDir, "src", Name ++ ".app.src"]), + Src1), + %% Then copy it over to create a conflict with dupes + file:copy(Src1, Src2), + + {error, {rebar_prv_app_discovery, {multiple_app_files, [Src2, Src1]}}} = + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + + ok. extra_src_dirs_at_root_and_in_erl_opts(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 1810ae30abdddc95dc93d96f5c9d0f27182f0e62 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 23 Feb 2017 21:48:46 -0500 Subject: Fix detection of src_dirs in unknown apps/deps First find the rebar.config file, and if any data is found, check for src_dirs config. If nothing is there or no app is found, default to src/ --- test/rebar_src_dirs_SUITE.erl | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_src_dirs_SUITE.erl b/test/rebar_src_dirs_SUITE.erl index 1982301..677dbaf 100644 --- a/test/rebar_src_dirs_SUITE.erl +++ b/test/rebar_src_dirs_SUITE.erl @@ -15,7 +15,8 @@ extra_src_dirs_at_root_and_in_erl_opts/1, build_basic_app/1, build_multi_apps/1, - src_dir_takes_precedence_over_extra/1]). + src_dir_takes_precedence_over_extra/1, + src_dir_checkout_dep/1]). -include_lib("common_test/include/ct.hrl"). @@ -39,7 +40,8 @@ all() -> src_dirs_at_root_and_in_erl_opts, dupe_src_dirs_at_root_and_in_erl_opts, extra_src_dirs_at_root_and_in_erl_opts, - build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra]. + build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra, + src_dir_checkout_dep]. src_dirs_at_root(Config) -> AppDir = ?config(apps, Config), @@ -271,3 +273,37 @@ src_dir_takes_precedence_over_extra(Config) -> [{application, _, KVs}] = App, Mods = proplists:get_value(modules, KVs), true = lists:member(extra, Mods). + +src_dir_checkout_dep(Config) -> + AppDir = ?config(apps, Config), + AppName = rebar_test_utils:create_random_name("src_dir_checkout_app"), + DepName = rebar_test_utils:create_random_name("src_dir_checkout_dep"), + AtomDep = list_to_atom(DepName), + + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, AppName, Vsn, [kernel, stdlib]), + RebarConfig = [{deps, [AtomDep]}], + + DepDir = filename:join([?config(checkouts, Config), DepName]), + ct:pal("checkouts dir: ~p", [DepDir]), + rebar_test_utils:create_app(DepDir, DepName, Vsn, [kernel, stdlib]), + + + %% move the .app.src file to one of the subdirs, out of src/ + rebar_file_utils:mv(filename:join([DepDir, "src"]), + filename:join([DepDir, "qux"])), + DepRebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar"]}]}, + {src_dirs, ["baz", "qux"]}], + file:write_file(filename:join([DepDir, "rebar.config"]), + io_lib:format("~p.~n~p.~n", DepRebarConfig)), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], + {ok, [{checkout, DepName}, {app, AppName}]} + ), + + % {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + % ["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []), + % rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], + % {ok, [{app, Name}]}), + ok. -- cgit v1.1 From ab1f93d6fa712c3b85bce30cab09edb5ddf7f3d9 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 24 Feb 2017 08:08:46 -0500 Subject: Fix default .app.src file for rebar_app_info The finding of the file was done based on an assumed 'src' path which may not be correct. This patch instead replaces the value with a lookup in configured paths and returns the first that matches to an existing file. --- test/rebar_src_dirs_SUITE.erl | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_src_dirs_SUITE.erl b/test/rebar_src_dirs_SUITE.erl index 677dbaf..bc22160 100644 --- a/test/rebar_src_dirs_SUITE.erl +++ b/test/rebar_src_dirs_SUITE.erl @@ -16,9 +16,11 @@ build_basic_app/1, build_multi_apps/1, src_dir_takes_precedence_over_extra/1, - src_dir_checkout_dep/1]). + src_dir_checkout_dep/1, + app_src_info/1]). -include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). suite() -> []. @@ -41,7 +43,7 @@ all() -> dupe_src_dirs_at_root_and_in_erl_opts, extra_src_dirs_at_root_and_in_erl_opts, build_basic_app, build_multi_apps, src_dir_takes_precedence_over_extra, - src_dir_checkout_dep]. + src_dir_checkout_dep, app_src_info]. src_dirs_at_root(Config) -> AppDir = ?config(apps, Config), @@ -301,9 +303,24 @@ src_dir_checkout_dep(Config) -> Config, RebarConfig, ["compile"], {ok, [{checkout, DepName}, {app, AppName}]} ), + ok. - % {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - % ["bar", "baz", "foo", "qux"] = rebar_dir:src_dirs(rebar_state:opts(State), []), - % rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], - % {ok, [{app, Name}]}), +app_src_info(Config) -> + PrivDir = ?config(priv_dir, Config), + AppName1 = rebar_test_utils:create_random_name("app_src_info"), + AppDir1 = filename:join(PrivDir, AppName1), + {ok, Info1} = rebar_app_info:new(AppName1, "1.0.0", AppDir1), + AppSrc1 = filename:join([AppDir1, "src", AppName1 ++ ".app.src"]), + ok = filelib:ensure_dir(AppSrc1), + ok = file:write_file(AppSrc1, "[]."), + ?assertEqual(AppSrc1, rebar_app_info:app_file_src(Info1)), + + AppName2 = rebar_test_utils:create_random_name("app_src_info"), + AppDir2 = filename:join(PrivDir, AppName2), + {ok, Info2Tmp} = rebar_app_info:new(AppName2, "1.0.0", AppDir2), + Info2 = rebar_app_info:set(Info2Tmp, src_dirs, ["foo", "bar", "baz"]), + AppSrc2 = filename:join([AppDir2, "bar", AppName2 ++ ".app.src"]), + ok = filelib:ensure_dir(AppSrc2), + ok = file:write_file(AppSrc2, "[]."), + ?assertEqual(AppSrc2, rebar_app_info:app_file_src(Info2)), ok. -- cgit v1.1 From 7c125d95f0583cb200c47c0c6af301c1182ce463 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 26 Feb 2017 12:49:01 -0500 Subject: More fixes for bad calls to find_apps --- test/rebar_test_utils.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 8c177c9..3b8ffac 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -218,7 +218,7 @@ check_results(AppDir, Expected, ProfileRun) -> BuildDirs = filelib:wildcard(filename:join([AppDir, "_build", ProfileRun, "lib", "*"])), PluginDirs = filelib:wildcard(filename:join([AppDir, "_build", ProfileRun, "plugins", "*"])), GlobalPluginDirs = filelib:wildcard(filename:join([AppDir, "global", "plugins", "*"])), - CheckoutsDir = filename:join([AppDir, "_checkouts", "*"]), + CheckoutsDirs = filelib:wildcard(filename:join([AppDir, "_checkouts", "*"])), LockFile = filename:join([AppDir, "rebar.lock"]), Locks = lists:flatten(rebar_config:consult_lock_file(LockFile)), @@ -230,7 +230,7 @@ check_results(AppDir, Expected, ProfileRun) -> Deps = rebar_app_discover:find_apps(BuildDirs, all), DepsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Deps], - Checkouts = rebar_app_discover:find_apps([CheckoutsDir], all), + Checkouts = rebar_app_discover:find_apps(CheckoutsDirs, all), CheckoutsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Checkouts], Plugins = rebar_app_discover:find_apps(PluginDirs, all), PluginsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Plugins], -- cgit v1.1 From 64b5d878af4839ac7e2514bdc497cce818b1755e Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 6 Mar 2017 11:36:26 +0100 Subject: Allow single test spec in ct_opts The option {spec,Specs} is allowed in ct_opts, but rebar_prv_common_test:test_dirs did not take into account that Specs could also be a string only, i.e. not a list of strings. --- test/rebar_ct_SUITE.erl | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 06dc76e..586e7b5 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -55,7 +55,8 @@ testspec/1, testspec_at_root/1, testspec_parse_error/1, - cmd_vs_cfg_opts/1]). + cmd_vs_cfg_opts/1, + single_testspec_in_ct_opts/1]). -include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -75,7 +76,8 @@ all() -> [{group, basic_app}, testspec, testspec_at_root, testspec_parse_error, - cmd_vs_cfg_opts]. + cmd_vs_cfg_opts, + single_testspec_in_ct_opts]. groups() -> [{basic_app, [], [basic_app_default_dirs, basic_app_default_beams, @@ -1548,6 +1550,41 @@ cmd_vs_cfg_opts(Config) -> ok. +single_testspec_in_ct_opts(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "ct_testspec_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name("ct_testspec_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + Spec = filename:join([AppDir, "test", "some.spec"]), + ok = filelib:ensure_dir(Spec), + ok = file:write_file(Spec, "{suites,\".\",all}.\n"), + + {ok,Wd} = file:get_cwd(), + ok = file:set_cwd(AppDir), + + RebarConfig = [{ct_opts, [{spec,"test/some.spec"}]}], + + {ok, State} = rebar_test_utils:run_and_check(C, RebarConfig, ["as", "test", "lock"], return), + + Providers = rebar_state:providers(State), + Namespace = rebar_state:namespace(State), + CommandProvider = providers:get_provider(ct, Providers, Namespace), + GetOptSpec = providers:opts(CommandProvider), + + %% Testspec in "test" directory + {ok, GetOptResult1} = getopt:parse(GetOptSpec, []), + State1 = rebar_state:command_parsed_args(State, GetOptResult1), + Tests1 = rebar_prv_common_test:prepare_tests(State1), + {ok, T1} = Tests1, + "test/some.spec" = proplists:get_value(spec,T1), + {ok, _NewState} = rebar_prv_common_test:compile(State1, Tests1), + + ok = file:set_cwd(Wd), + ok. + %% helper for generating test data test_suite(Name) -> io_lib:format("-module(~ts_SUITE).\n" -- cgit v1.1 From 26e174a5e49114156349fa9f373c4b8c6de17a7e Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sat, 18 Mar 2017 14:34:17 -0700 Subject: eunit in 19.3 errors if `init_per_*` isn't paired with `end_per_*` --- test/rebar_eunit_SUITE.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 6fb325b..4805b3d 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -1,7 +1,8 @@ -module(rebar_eunit_SUITE). -export([all/0, groups/0]). --export([init_per_suite/1, init_per_group/2, end_per_group/2]). +-export([init_per_suite/1, end_per_suite/1]). +-export([init_per_group/2, end_per_group/2]). -export([basic_app_compiles/1, basic_app_files/1]). -export([basic_app_exports/1, basic_app_testset/1]). -export([basic_app_eunit_macro/1]). @@ -60,6 +61,8 @@ init_per_suite(Config) -> {ok, _} = zip:extract(filename:join([PrivDir, "multi_app.zip"]), [{cwd, PrivDir}]), Config. +end_per_suite(Config) -> Config. + init_per_group(basic_app, Config) -> GroupState = rebar_test_utils:init_rebar_state(Config, "basic_app_"), -- cgit v1.1 From 49648927eedf9a614c07dfb9eddc7dda2c88eca6 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 2 May 2017 20:43:23 -0400 Subject: Add test for upgrade of profile deps --- test/rebar_upgrade_SUITE.erl | 69 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 66e1fdf..418c188 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -11,7 +11,7 @@ groups() -> triplet_a, triplet_b, triplet_c, tree_a, tree_b, tree_c, tree_c2, tree_cj, tree_ac, tree_all, delete_d, promote, stable_lock, fwd_lock, - compile_upgrade_parity, umbrella_config]}, + compile_upgrade_parity, umbrella_config, profiles]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -78,6 +78,22 @@ setup_project(Case=umbrella_config, Config0, Deps, UpDeps) -> [{rebarconfig, TopConf}, {rebarumbrella, RebarConf}, {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config]; +setup_project(Case=profiles, Config0, Deps, UpDeps) -> + DepsType = ?config(deps_type, Config0), + NameRoot = atom_to_list(Case)++"_"++atom_to_list(DepsType), + Config = rebar_test_utils:init_rebar_state(Config0, NameRoot++"_"), + AppDir = filename:join([?config(apps, Config), "apps", NameRoot]), + rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]), + [Top|ProfileDeps] = rebar_test_utils:top_level_deps(Deps), + RebarConf = rebar_test_utils:create_config(AppDir, [ + {deps, [Top]}, + {profiles, [{fake, [{deps, ProfileDeps}]}]} + ]), + [NextTop|NextPDeps] = rebar_test_utils:top_level_deps(UpDeps), + NextConfig = [{deps, [NextTop]}, + {profiles, [{fake, [{deps, NextPDeps}]}]}], + [{rebarconfig, RebarConf}, + {next_config, NextConfig} | Config]; setup_project(Case, Config0, Deps, UpDeps) -> DepsType = ?config(deps_type, Config0), Config = rebar_test_utils:init_rebar_state( @@ -454,7 +470,27 @@ upgrades(umbrella_config) -> {[{"A", "1", []}], [{"A", "2", []}], ["A"], - {"A", [{"A","2"}]}}. + {"A", [{"A","2"}]}}; +upgrades(profiles) -> + %% Ensure that we can unlock deps under a given profile; + %% B and C should both be in a custom profile + %% and must not be locked. + {[{"A", "1", [{"D",[]}, + {"E","3",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "0", [{"H","3",[]}, + {"I",[]}]}], + [{"A", "2", [{"D",[]}, + {"E","2",[]}]}, + {"B", "2", [{"F","2",[]}, + {"G",[]}]}, + {"C", "1", [{"H","4",[]}, + {"I",[]}]}], + ["A","B","C","E","F","H"], + {"C", [{"A","1"}, "D", {"E","3"}, + {"B","2"}, {"F","2"}, "G", + {"C","1"}, {"H","4"}, "I"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. @@ -613,6 +649,35 @@ umbrella_config(Config) -> ), meck:unload(rebar_prv_upgrade). +profiles(Config) -> + apply(?config(mock, Config), []), + {ok, TopConfig} = file:consult(?config(rebarconfig, Config)), + %% Install dependencies before re-mocking for an upgrade + rebar_test_utils:run_and_check(Config, TopConfig, ["lock"], {ok, []}), + %% Install test deps along with them + rebar_test_utils:run_and_check(Config, TopConfig, ["as","fake","lock"], {ok, []}), + {App, Unlocks} = ?config(expected, Config), + ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]), + Expectation = case Unlocks of + {error, Term} -> {error, Term}; + _ -> {ok, [T || T <- Unlocks, + element(1,T) == dep orelse + lists:member(element(2,T), ["A","D","E"])]} + end, + + meck:new(rebar_prv_app_discovery, [passthrough]), + meck:expect(rebar_prv_app_discovery, do, fun(S) -> + apply(?config(mock_update, Config), []), + meck:passthrough([S]) + end), + NewRebarConf = rebar_test_utils:create_config(?config(apps, Config), + ?config(next_config, Config)), + {ok, NewRebarConfig} = file:consult(NewRebarConf), + rebar_test_utils:run_and_check( + Config, NewRebarConfig, ["as","fake","upgrade", App], Expectation + ), + meck:unload(rebar_prv_app_discovery). + run(Config) -> apply(?config(mock, Config), []), ConfigPath = ?config(rebarconfig, Config), -- cgit v1.1 From 1783df5ad3ff0e632aedc2394674d627fa800241 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 11 May 2017 06:22:39 -0400 Subject: Add tests for the first_files profile merges --- test/rebar_profiles_SUITE.erl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index ed492a9..9ffaf98 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -25,7 +25,8 @@ test_profile_erl_opts_order_2/1, test_profile_erl_opts_order_3/1, test_profile_erl_opts_order_4/1, - test_profile_erl_opts_order_5/1]). + test_profile_erl_opts_order_5/1, + first_files_exception/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -46,7 +47,8 @@ all() -> test_profile_erl_opts_order_2, test_profile_erl_opts_order_3, test_profile_erl_opts_order_4, - test_profile_erl_opts_order_5]. + test_profile_erl_opts_order_5, + first_files_exception]. init_per_suite(Config) -> application:start(meck), @@ -468,6 +470,25 @@ test_profile_erl_opts_order_5(Config) -> Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), warn_export_all = Opt. +first_files_exception(_Config) -> + RebarConfig = [{erl_first_files, ["c","a","b"]}, + {mib_first_files, ["c","a","b"]}, + {other, ["c","a","b"]}, + {profiles, + [{profile2, [{erl_first_files, ["a","e"]}, + {mib_first_files, ["a","e"]}, + {other, ["a","e"]} + ]}]}], + State = rebar_state:new(RebarConfig), + State1 = rebar_state:apply_profiles(State, [profile2]), + + %% Combine lists + ?assertEqual(["a","b","c","e"], rebar_state:get(State1, other)), + %% there is no specific reason not to dedupe "a" here aside from "this is how it is" + ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, erl_first_files)), + ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, mib_first_files)), + ok. + get_compiled_profile_erl_opts(Profiles, Config) -> AppDir = ?config(apps, Config), PStrs = [atom_to_list(P) || P <- Profiles], -- cgit v1.1 From 216bf73f739bf8dfdcdb075837b99cd32d76e1ac Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 12 May 2017 08:17:33 -0400 Subject: Bump cth_readable to 1.2.6 This fixes the output of end_per_testcase crash notifications when the test passes. This also detect an issue of the kind with rebar_pkg_SUITE which is now fixed. --- test/rebar_pkg_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index 30cc0a8..32873c8 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -287,7 +287,7 @@ mock_config(Name, Config) -> unmock_config(Config) -> meck:unload(), - ets:delete(?config(mock_table, Config)). + catch ets:delete(?config(mock_table, Config)). copy_to_cache({Pkg,Vsn}, Config) -> Name = <>, -- cgit v1.1 From 0ce1a4f5fea0a0a58b862e1e375043e7696f9bff Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 19 May 2017 22:34:26 -0400 Subject: Cull default dep names in non-default upgrade Prevents showing false upgrade messages when upgrading in a non-default profile. Also shows an info message explaining default deps don't get updated in a non-default upgrade. --- test/rebar_upgrade_SUITE.erl | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 418c188..45a7433 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -11,7 +11,8 @@ groups() -> triplet_a, triplet_b, triplet_c, tree_a, tree_b, tree_c, tree_c2, tree_cj, tree_ac, tree_all, delete_d, promote, stable_lock, fwd_lock, - compile_upgrade_parity, umbrella_config, profiles]}, + compile_upgrade_parity, umbrella_config, + profiles, profiles_exclusion]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -78,7 +79,8 @@ setup_project(Case=umbrella_config, Config0, Deps, UpDeps) -> [{rebarconfig, TopConf}, {rebarumbrella, RebarConf}, {next_top_deps, rebar_test_utils:top_level_deps(UpDeps)} | Config]; -setup_project(Case=profiles, Config0, Deps, UpDeps) -> +setup_project(Case, Config0, Deps, UpDeps) when Case == profiles; + Case == profiles_exclusion -> DepsType = ?config(deps_type, Config0), NameRoot = atom_to_list(Case)++"_"++atom_to_list(DepsType), Config = rebar_test_utils:init_rebar_state(Config0, NameRoot++"_"), @@ -490,6 +492,26 @@ upgrades(profiles) -> ["A","B","C","E","F","H"], {"C", [{"A","1"}, "D", {"E","3"}, {"B","2"}, {"F","2"}, "G", + {"C","1"}, {"H","4"}, "I"]}}; +upgrades(profiles_exclusion) -> + %% Ensure that we can unlock deps under a given profile; + %% B and C should both be in a custom profile + %% and must not be locked. + {[{"A", "1", [{"D",[]}, + {"E","3",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "0", [{"H","3",[]}, + {"I",[]}]}], + [{"A", "2", [{"D",[]}, + {"E","2",[]}]}, + {"B", "2", [{"F","2",[]}, + {"G",[]}]}, + {"C", "1", [{"H","4",[]}, + {"I",[]}]}], + ["A","B","C","E","F","H"], + {"A", [{"A","1"}, "D", {"E","3"}, + {"B","2"}, {"F","2"}, "G", {"C","1"}, {"H","4"}, "I"]}}. %% TODO: add a test that verifies that unlocking files and then @@ -678,6 +700,8 @@ profiles(Config) -> ), meck:unload(rebar_prv_app_discovery). +profiles_exclusion(Config) -> profiles(Config). + run(Config) -> apply(?config(mock, Config), []), ConfigPath = ?config(rebarconfig, Config), -- cgit v1.1 From 249b5f13eb8f1859d7a70ab316bc7541543aaf57 Mon Sep 17 00:00:00 2001 From: Anthony Molinaro Date: Thu, 1 Jun 2017 18:32:30 +0000 Subject: Avoid reversing relx overlays. This mostly moves a lists:reverse/1 which ensures that profile overlays are run first but keeps the order of overlays otherwise. --- test/rebar_release_SUITE.erl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test') diff --git a/test/rebar_release_SUITE.erl b/test/rebar_release_SUITE.erl index 1125a7e..e41339b 100644 --- a/test/rebar_release_SUITE.erl +++ b/test/rebar_release_SUITE.erl @@ -11,6 +11,7 @@ all() -> [release, profile_ordering_sys_config_extend_3_tuple_merge, extend_release, user_output_dir, profile_overlays, + profile_overlay_merge, overlay_vars]. init_per_testcase(Case, Config0) -> @@ -217,6 +218,30 @@ profile_overlays(Config) -> {dir, filename:join(ReleaseDir, "randomdir")}]} ). +profile_overlay_merge (_Config) -> + % when profile and relx overlays both exist, the profile overlays should be + % first, then the relx overlays, all the rest of the config should come + % after, rebar_relx:merge_overlays/1 should do this. + RelxOverlay = [{mkdir, "1_from_relx"}, {mkdir, "2_from_relx"}], + ProfileOverlay = [{mkdir, "0_from_other_profile"}], + OtherConfig = [{other1, config}, {other2, config}], + + % test with no overlays + ?assertEqual([{overlay,[]}] ++ OtherConfig, + rebar_relx:merge_overlays(OtherConfig)), + + % test with relx only, just move overlays to the top + RelxOnly = OtherConfig ++ [{overlay, RelxOverlay}], + ?assertEqual([{overlay, RelxOverlay}]++OtherConfig, + rebar_relx:merge_overlays(RelxOnly)), + + % now test with a profile (profiles end up after relx overlays + ProfilesToMerge = OtherConfig ++ + [{overlay, RelxOverlay}, + {overlay, ProfileOverlay}], + ?assertEqual([{overlay, ProfileOverlay ++ RelxOverlay}] ++ OtherConfig, + rebar_relx:merge_overlays(ProfilesToMerge)). + overlay_vars(Config) -> AppDir = ?config(apps, Config), Name = ?config(name, Config), -- cgit v1.1 From 48dc9738bbab828381c15daab6035dda59cbd646 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 2 Jun 2017 12:46:17 -0700 Subject: reset hooks under profiles for application opts --- test/rebar_hooks_SUITE.erl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index b121dd5..f7fcb82 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -9,6 +9,7 @@ build_and_clean_app/1, escriptize_artifacts/1, run_hooks_once/1, + run_hooks_once_profiles/1, run_hooks_for_plugins/1, eunit_app_hooks/1, deps_hook_namespace/1]). @@ -33,8 +34,9 @@ end_per_testcase(_, _Config) -> catch meck:unload(). all() -> - [build_and_clean_app, run_hooks_once, escriptize_artifacts, - run_hooks_for_plugins, deps_hook_namespace, eunit_app_hooks]. + [build_and_clean_app, run_hooks_once, run_hooks_once_profiles, + escriptize_artifacts, run_hooks_for_plugins, deps_hook_namespace, + eunit_app_hooks]. %% Test post provider hook cleans compiled project app, leaving it invalid build_and_clean_app(Config) -> @@ -98,6 +100,18 @@ run_hooks_once(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name, valid}]}). +%% test that even if a hook is defined at the project level in a used profile +%% the hook is not run for each application in the project umbrella +run_hooks_once_profiles(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir blah"}]}]}]}], + rebar_test_utils:create_config(AppDir, RebarConfig), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "hooks", "compile"], {ok, [{app, Name, valid}]}). + deps_hook_namespace(Config) -> mock_git_resource:mock([{deps, [{some_dep, "0.0.1"}]}]), Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", []}]), -- cgit v1.1 From 9a6f04a2d9d00167e0b853776b60b12b5c5dcc57 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 7 Jun 2017 20:12:49 -0400 Subject: Fix xref compile hook on deps If xref analysis is being run by a dependency during its compilation phase, the xref provider will try to add that deps' parents to the check job while the ebin/ directories for them do not exist. This causes a crash. This patch makes it so directories are only added if they are existing, preventing failure on any compile hook for dependencies and allowing successful compilation as a best effort. --- test/rebar_xref_SUITE.erl | 17 +++++++++-- .../recursive/apps/rebar_issue1/rebar.config | 12 ++++++++ .../apps/rebar_issue1/src/rebar_issue1.app.src | 16 ++++++++++ .../apps/rebar_issue1/src/rebar_issue1_app.erl | 26 ++++++++++++++++ .../apps/rebar_issue1/src/rebar_issue1_sup.erl | 35 ++++++++++++++++++++++ .../apps/rebar_issue2/src/rebar_issue2.app.src | 17 +++++++++++ .../apps/rebar_issue2/src/rebar_issue2_app.erl | 26 ++++++++++++++++ .../apps/rebar_issue2/src/rebar_issue2_sup.erl | 35 ++++++++++++++++++++++ 8 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/rebar.config create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1.app.src create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_app.erl create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_sup.erl create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2.app.src create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_app.erl create mode 100644 test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_sup.erl (limited to 'test') diff --git a/test/rebar_xref_SUITE.erl b/test/rebar_xref_SUITE.erl index 09f73a7..d1c071b 100644 --- a/test/rebar_xref_SUITE.erl +++ b/test/rebar_xref_SUITE.erl @@ -9,7 +9,8 @@ end_per_testcase/2, all/0, xref_test/1, - xref_ignore_test/1]). + xref_ignore_test/1, + xref_dep_hook/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -28,6 +29,15 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ok. +init_per_testcase(xref_dep_hook, Config) -> + Src = filename:join([?config(data_dir, Config), "recursive"]), + Dst = filename:join([?config(priv_dir, Config), "recursive"]), + ok = rebar_file_utils:cp_r([Src], Dst), + GlobalDir = filename:join([?config(priv_dir, Config), "cache"]), + State = rebar_state:new([{base_dir, filename:join([Dst, "_build"])} + ,{global_rebar_dir, GlobalDir} + ,{root_dir, Dst}]), + [{apps, Dst}, {state, State} | Config]; init_per_testcase(Case, Config) -> UpdConfig = rebar_test_utils:init_rebar_state(Config), AppDir = ?config(apps, UpdConfig), @@ -48,7 +58,7 @@ end_per_testcase(_, _Config) -> ok. all() -> - [xref_test, xref_ignore_test]. + [xref_test, xref_ignore_test, xref_dep_hook]. %% =================================================================== %% Test cases @@ -70,6 +80,9 @@ xref_ignore_test(Config) -> Result = rebar3:run(rebar_state:new(State, RebarConfig, AppDir), ["xref"]), verify_results(xref_ignore_test, Name, Result). +xref_dep_hook(Config) -> + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, []}). + %% =================================================================== %% Helper functions %% =================================================================== diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/rebar.config b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/rebar.config new file mode 100644 index 0000000..cf48edf --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/rebar.config @@ -0,0 +1,12 @@ +{erl_opts, [debug_info]}. +{deps, []}. + +{xref_checks,[ + undefined_function_calls, + undefined_functions, + locals_not_used, + deprecated_function_calls, + deprecated_functions +]}. + +{provider_hooks, [{post, [{compile, xref}]}]}. diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1.app.src b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1.app.src new file mode 100644 index 0000000..b935082 --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1.app.src @@ -0,0 +1,16 @@ +{application, rebar_issue1, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { rebar_issue1_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_app.erl b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_app.erl new file mode 100644 index 0000000..78c88c1 --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc rebar_issue1 public API +%% @end +%%%------------------------------------------------------------------- + +-module(rebar_issue1_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + rebar_issue1_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_sup.erl b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_sup.erl new file mode 100644 index 0000000..6e5a9f8 --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue1/src/rebar_issue1_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc rebar_issue1 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(rebar_issue1_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_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2.app.src b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2.app.src new file mode 100644 index 0000000..59ffa35 --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2.app.src @@ -0,0 +1,17 @@ +{application, rebar_issue2, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, { rebar_issue2_app, []}}, + {applications, + [kernel, + stdlib, + rebar_issue1 + ]}, + {env,[]}, + {modules, []}, + + {maintainers, []}, + {licenses, []}, + {links, []} + ]}. diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_app.erl b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_app.erl new file mode 100644 index 0000000..968966c --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_app.erl @@ -0,0 +1,26 @@ +%%%------------------------------------------------------------------- +%% @doc rebar_issue2 public API +%% @end +%%%------------------------------------------------------------------- + +-module(rebar_issue2_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). + +%%==================================================================== +%% API +%%==================================================================== + +start(_StartType, _StartArgs) -> + rebar_issue2_sup:start_link(). + +%%-------------------------------------------------------------------- +stop(_State) -> + ok. + +%%==================================================================== +%% Internal functions +%%==================================================================== diff --git a/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_sup.erl b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_sup.erl new file mode 100644 index 0000000..3673548 --- /dev/null +++ b/test/rebar_xref_SUITE_data/recursive/apps/rebar_issue2/src/rebar_issue2_sup.erl @@ -0,0 +1,35 @@ +%%%------------------------------------------------------------------- +%% @doc rebar_issue2 top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(rebar_issue2_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 +%%==================================================================== -- cgit v1.1 From 7f1301f635b8c07fd22ffdf1c9dcf6f5cbba8655 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 13 Jun 2017 07:17:07 -0400 Subject: Prevent xref crashes with undef behaviours When a given behaviour module does not exist, rebar3 brutally crashes. This patch makes it so instead, there is a warning output menitoning the missing behaviour, and this one is omitted from the unused function calls check. This means that unused calls will instead be shown for the module implementing a non-existing behaviour, as if no behaviour were declared in the first place. --- test/rebar_xref_SUITE.erl | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_xref_SUITE.erl b/test/rebar_xref_SUITE.erl index d1c071b..f052fa4 100644 --- a/test/rebar_xref_SUITE.erl +++ b/test/rebar_xref_SUITE.erl @@ -10,7 +10,8 @@ all/0, xref_test/1, xref_ignore_test/1, - xref_dep_hook/1]). + xref_dep_hook/1, + xref_undef_behaviour/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -58,7 +59,7 @@ end_per_testcase(_, _Config) -> ok. all() -> - [xref_test, xref_ignore_test, xref_dep_hook]. + [xref_test, xref_ignore_test, xref_dep_hook, xref_undef_behaviour]. %% =================================================================== %% Test cases @@ -83,6 +84,18 @@ xref_ignore_test(Config) -> xref_dep_hook(Config) -> rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, []}). +xref_undef_behaviour(Config) -> + AppDir = ?config(apps, Config), + State = ?config(state, Config), + Name = ?config(app_name, Config), + RebarConfig = ?config(rebar_config, Config), + %% delete one of the behaviours, which should create new warnings + delete_src_file(AppDir, Name, behaviour1), + %% just ensure this does not crash + Result = rebar3:run(rebar_state:new(State, RebarConfig, AppDir), ["xref"]), + verify_results(xref_undef_behaviour, Name, Result). + + %% =================================================================== %% Helper functions %% =================================================================== @@ -123,6 +136,31 @@ verify_test_results(xref_test, AppName, XrefResults, _QueryResults) -> ?assertNot(lists:member({MyMod, bh2_a, 1}, ExportsNotUsed)), ?assertNot(lists:member({MyMod, bh2_b, 1}, ExportsNotUsed)), ok; +verify_test_results(xref_undef_behaviour, AppName, XrefResults, _QueryResults) -> + AppModules = ["behaviour2", "mymod", "othermod", "somemod"], + [Behaviour2Mod, MyMod, OtherMod, SomeMod] = + [list_to_atom(AppName ++ "_" ++ Mod) || Mod <- AppModules], + UndefFuns = proplists:get_value(undefined_functions, XrefResults), + UndefFunCalls = proplists:get_value(undefined_function_calls, XrefResults), + LocalsNotUsed = proplists:get_value(locals_not_used, XrefResults), + ExportsNotUsed = proplists:get_value(exports_not_used, XrefResults), + DeprecatedFuns = proplists:get_value(deprecated_functions, XrefResults), + DeprecatedFunCalls = proplists:get_value(deprecated_function_calls, XrefResults), + ?assert(lists:member({SomeMod, notavailable, 1}, UndefFuns)), + ?assert(lists:member({{OtherMod, somefunc, 0}, {SomeMod, notavailable, 1}}, + UndefFunCalls)), + ?assert(lists:member({MyMod, fdeprecated, 0}, DeprecatedFuns)), + ?assert(lists:member({{OtherMod, somefunc, 0}, {MyMod, fdeprecated, 0}}, + DeprecatedFunCalls)), + ?assert(lists:member({MyMod, localfunc2, 0}, LocalsNotUsed)), + ?assert(lists:member({Behaviour2Mod, behaviour_info, 1}, ExportsNotUsed)), + ?assert(lists:member({MyMod, other2, 1}, ExportsNotUsed)), + ?assert(lists:member({OtherMod, somefunc, 0}, ExportsNotUsed)), + ?assert(lists:member({MyMod, bh1_a, 1}, ExportsNotUsed)), + ?assert(lists:member({MyMod, bh1_b, 1}, ExportsNotUsed)), + ?assertNot(lists:member({MyMod, bh2_a, 1}, ExportsNotUsed)), + ?assertNot(lists:member({MyMod, bh2_b, 1}, ExportsNotUsed)), + ok; verify_test_results(xref_ignore_test, AppName, XrefResults, _QueryResults) -> AppModules = ["behaviour1", "behaviour2", "mymod", "othermod", "somemod"], [_Behaviour1Mod, _Behaviour2Mod, _MyMod, _OtherMod, SomeMod] = @@ -141,6 +179,10 @@ write_src_file(Dir, AppName, Module, IgnoreXref) -> ok = filelib:ensure_dir(Erl), ok = ec_file:write(Erl, get_module_body(Module, AppName, IgnoreXref)). +delete_src_file(Dir, AppName, Module) -> + Erl = filename:join([Dir, "src", module_name(AppName, Module)]), + ok = file:delete(Erl). + module_name(AppName, Module) -> lists:flatten([AppName, "_", atom_to_list(Module), ".erl"]). -- cgit v1.1 From e4f5b55557c8f21b2526216cd38fea0aa91c53f0 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 14 Jul 2017 09:15:26 -0700 Subject: add ct compile_only test, checks for compiled app --- test/rebar_ct_SUITE.erl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 586e7b5..752db6c 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -56,7 +56,8 @@ testspec_at_root/1, testspec_parse_error/1, cmd_vs_cfg_opts/1, - single_testspec_in_ct_opts/1]). + single_testspec_in_ct_opts/1, + compile_only/1]). -include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -77,7 +78,8 @@ all() -> [{group, basic_app}, testspec_at_root, testspec_parse_error, cmd_vs_cfg_opts, - single_testspec_in_ct_opts]. + single_testspec_in_ct_opts, + compile_only]. groups() -> [{basic_app, [], [basic_app_default_dirs, basic_app_default_beams, @@ -1585,6 +1587,22 @@ single_testspec_in_ct_opts(Config) -> ok = file:set_cwd(Wd), ok. +compile_only(Config) -> + C = rebar_test_utils:init_rebar_state(Config, "compile_only_"), + + AppDir = ?config(apps, C), + + Name = rebar_test_utils:create_random_name(atom_to_list(basic_app) ++ "_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + Suite = filename:join([AppDir, "test", Name ++ "_SUITE.erl"]), + ok = filelib:ensure_dir(Suite), + ok = file:write_file(Suite, test_suite(Name)), + + {ok, _State} = rebar_test_utils:run_and_check(C, [], ["ct", "--compile_only"], {ok, [{app,Name}], "test"}). + + %% helper for generating test data test_suite(Name) -> io_lib:format("-module(~ts_SUITE).\n" -- cgit v1.1 From 1c96de5e10bd51ba4da9a89c087c191a8c7cd8c5 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 5 Aug 2017 10:35:51 -0400 Subject: Allow top-level apps to take precedence over deps The use case has been described in issue #1478 where a local application can exist while being declared as a dependency as well. This allows, for example, to work on a release where all applications may require to be published independently, or to provide some form of 'vendoring' with a local app. The fix is done by decoupling the dependency source resolution form the dependency parsing. The reason for this being that the discovery phase needs to parse apps for their top-level deps, and dep installation needs to resolve the packages with accuracy. In the current implementation, both code paths call to the same function. This patch splits up the precise discovery and makes it happen *only* when installing dependencies, and only if a top-level app does not already define the application needing resolving. One weakness of this fix is that it necessarily breaks cycle detection in dependencies that involve a root application depending on itself since its own version as a dep will not be expanded. There appears to be no possible way to prevent this, but should be rare enough to be worth the tradeoff for the common case. --- test/rebar_deps_SUITE.erl | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index 6b2ecea..ae50ea3 100644 --- a/test/rebar_deps_SUITE.erl +++ b/test/rebar_deps_SUITE.erl @@ -7,7 +7,7 @@ all() -> [sub_app_deps, newly_added_dep, newly_added_after_empty_lock, http_proxy_settings, https_proxy_settings, http_os_proxy_settings, https_os_proxy_settings, semver_matching_lt, semver_matching_lte, semver_matching_gt, - valid_version, {group, git}, {group, pkg}]. + valid_version, top_override, {group, git}, {group, pkg}]. groups() -> [{all, [], [flat, pick_highest_left, pick_highest_right, @@ -47,6 +47,8 @@ init_per_testcase(newly_added_dep, Config) -> rebar_test_utils:init_rebar_state(Config); init_per_testcase(sub_app_deps, Config) -> rebar_test_utils:init_rebar_state(Config); +init_per_testcase(top_override, Config) -> + rebar_test_utils:init_rebar_state(Config); init_per_testcase(http_proxy_settings, Config) -> %% Create private rebar.config Priv = ?config(priv_dir, Config), @@ -255,6 +257,32 @@ circular1(Config) -> run(Config). circular2(Config) -> run(Config). circular_skip(Config) -> run(Config). +%% Test that a top-level application overtakes dependencies, and +%% works even if said deps do not exist. +top_override(Config) -> + AppDir = ?config(apps, Config), + ct:pal("dir: ~p", [AppDir]), + Name1 = rebar_test_utils:create_random_name("sub_app1_"), + Name2 = rebar_test_utils:create_random_name("sub_app2_"), + SubAppsDir1 = filename:join([AppDir, "apps", Name1]), + SubAppsDir2 = filename:join([AppDir, "apps", Name2]), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(SubAppsDir1, Name1, Vsn, [kernel, stdlib]), + rebar_test_utils:create_app(SubAppsDir2, Name2, Vsn, [kernel, stdlib]), + rebar_test_utils:create_config( + SubAppsDir1, + [{deps, [list_to_atom(Name2)]}] + ), + rebar_test_utils:create_config( + SubAppsDir2, + [{deps, [{list_to_atom(Name1), + {git, "https://example.org", {branch, "master"}}}]}] + ), + rebar_test_utils:run_and_check( + Config, [], ["compile"], + {ok, [{app, Name1}, {app,Name2}]} + ). + %% Test that the deps of project apps that have their own rebar.config %% are included, but that top level rebar.config deps take precedence sub_app_deps(Config) -> -- cgit v1.1 From 963c49f5eb9ab5b34e1843fb43305743720917ac Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 6 Aug 2017 07:26:21 -0400 Subject: Unicode support in all the places This is done through 3 main change groups: - replacing `~s` by `~ts` in format strings, so that strings that contain unicode are properly printed rather than crashing - adding the `unicode` argument to all function of the `re` module to ensure transformations on strings containing unicode data are valid instead of crashing (see issue #1302) - replacing `ec_cnv:to_binary/1` and `ec_cnv:to_list/1` with matching functions in `rebar_utils`. The last point has been done, rather than modifying and updating erlware commons, because binary and list conversions can be a contentious subject. For example, if what is being handled is actually bytes from a given binary stream, then forcing a byte-oriented interpretation of the data can corrupt it. As such, it does not appear safe to modify erlware commons' conversion functions since it may not be safe for all its users. Instead, rebar3 reimplements a subset of them (only converting atoms and chardata, ignoring numbers) with the explicit purpose of handling unicode string data. Tests were left as unchanged as possible. This may impact the ability to run rebar3's own suites in a unicode path, but respects a principle of least change for such a large patch. --- test/rebar_as_SUITE.erl | 2 +- test/rebar_ct_SUITE.erl | 4 ++-- test/rebar_test_utils.erl | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/rebar_as_SUITE.erl b/test/rebar_as_SUITE.erl index ce8046b..78ea8ae 100644 --- a/test/rebar_as_SUITE.erl +++ b/test/rebar_as_SUITE.erl @@ -176,7 +176,7 @@ error_on_empty_tasks(Config) -> warn_match(App, History) -> lists:any( - fun({_, {rebar_log,log, [warn, "No entry for profile ~s in config.", + fun({_, {rebar_log,log, [warn, "No entry for profile ~ts in config.", [ArgApp]]}, _}) -> ArgApp =:= App ; (_) -> false diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 752db6c..70cf60c 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -1611,7 +1611,7 @@ test_suite(Name) -> "some_test(_) -> ok.\n", [Name]). cmd_sys_config_file(AppName) -> - io_lib:format("[{~s, [{key, cmd_value}]}].", [AppName]). + io_lib:format("[{~ts, [{key, cmd_value}]}].", [AppName]). cfg_sys_config_file(AppName) -> - io_lib:format("[{~s, [{key, cfg_value}]}].", [AppName]). + io_lib:format("[{~ts, [{key, cfg_value}]}].", [AppName]). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 3b8ffac..0ccec56 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -349,7 +349,7 @@ check_results(AppDir, Expected, ProfileRun) -> iolist_to_binary(LockVsn)) end ; ({release, Name, Vsn, ExpectedDevMode}) -> - ct:pal("Release: ~p-~s", [Name, Vsn]), + ct:pal("Release: ~p-~ts", [Name, Vsn]), {ok, Cwd} = file:get_cwd(), try file:set_cwd(AppDir), @@ -377,14 +377,14 @@ check_results(AppDir, Expected, ProfileRun) -> file:set_cwd(Cwd) end ; ({tar, Name, Vsn}) -> - ct:pal("Tarball: ~s-~s", [Name, Vsn]), + ct:pal("Tarball: ~ts-~ts", [Name, Vsn]), Tarball = filename:join([AppDir, "_build", "rel", Name, Name++"-"++Vsn++".tar.gz"]), ?assertNotEqual([], filelib:is_file(Tarball)) ; ({file, Filename}) -> - ct:pal("Filename: ~s", [Filename]), + ct:pal("Filename: ~ts", [Filename]), ?assert(filelib:is_file(Filename)) ; ({dir, Dirname}) -> - ct:pal("Directory: ~s", [Dirname]), + ct:pal("Directory: ~ts", [Dirname]), ?assert(filelib:is_dir(Dirname)) end, Expected). -- cgit v1.1 From 13bdb75b2961e1ae43e43e7c8d06bf463571d541 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 11 Aug 2017 13:58:13 -0400 Subject: Fix recursive profile merging in umbrella apps When a config file exists at the root of a project, defines a given configuration value for a given profile, and that a sub-application (umbrella app) also has the same profile defined with the same key (but different values), the configuration values of the sub-application's profile would get silently dropped. The problem being that when the function to merge profiles is applied recursively, it is applied to each profile (so it will merge on the keys test, prod, etc.) rather than to each of the values of each profile. This patch reworks the profile merging so that the current behaviour is respected overall (a profile cannot be cancelled by a subdep's non-existant profile since its value should have been ignored), but ensures that sub-deps' profiles are otherwise applied recursively with the proper rules: - dependencies favor prior values - plugins favor new values - erl_first_files combine the lists - relx uses the tuple merge algorithm - erl_opts has its own custom merge as well - otherwise the new value takes precedence A test has also been added. There is a risk of breakage in some applications that may have relied on the buggy behaviour to work, though at this time we are aware of none of them. --- test/rebar_profiles_SUITE.erl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 9ffaf98..11aca6a 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -7,6 +7,7 @@ all/0, profile_new_key/1, profile_merge_keys/1, + profile_merge_umbrella_keys/1, explicit_profile_deduplicate_deps/1, implicit_profile_deduplicate_deps/1, all_deps_code_paths/1, @@ -33,7 +34,8 @@ -include_lib("kernel/include/file.hrl"). all() -> - [profile_new_key, profile_merge_keys, all_deps_code_paths, profile_merges, + [profile_new_key, profile_merge_keys, profile_merge_umbrella_keys, + all_deps_code_paths, profile_merges, explicit_profile_deduplicate_deps, implicit_profile_deduplicate_deps, same_profile_deduplication, stack_deduplication, add_to_profile, add_to_existing_profile, @@ -118,6 +120,35 @@ profile_merge_keys(Config) -> ,{dep, "a", "1.0.0"} ,{dep, "b", "2.0.0"}]}). +profile_merge_umbrella_keys(Config) -> + AppDir = ?config(apps, Config), + ct:pal("Path: ~s", [AppDir]), + Name = rebar_test_utils:create_random_name("profile_merge_umbrella_keys"), + Vsn = rebar_test_utils:create_random_vsn(), + SubAppDir = filename:join([AppDir, "apps", Name]), + + RebarConfig = [{vals, [{a,1},{b,1}]}, + {profiles, + [{ct, + [{vals, [{a,1},{b,2}]}]}]}], + + SubRebarConfig = [{vals, []}, + {profiles, [{ct, [{vals, [{c,1}]}]}]}], + + rebar_test_utils:create_app(SubAppDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_config(SubAppDir, SubRebarConfig), + {ok, RebarConfigRead} = file:consult(rebar_test_utils:create_config(AppDir, RebarConfig)), + + {ok, State} = rebar_test_utils:run_and_check( + Config, RebarConfigRead, ["as", "ct", "compile"], return + ), + + [ProjectApp] = rebar_state:project_apps(State), + ?assertEqual(Name, binary_to_list(rebar_app_info:name(ProjectApp))), + Opts = rebar_app_info:opts(ProjectApp), + ?assertEqual([{a,1},{b,2},{b,1},{c,1}], dict:fetch(vals, Opts)), + ok. + explicit_profile_deduplicate_deps(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From bc2f06220003499ac998f519c9eb595a0e957e15 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 15 Aug 2017 11:20:28 -0400 Subject: Fix ordering of overlays and overlay vars in Relx Specifically, this impacts profiles. It appears that relx as a whole requires its configuration to be merged in one tuple order (New takes precedence over Old), whereas the overlays require the opposite (Old takes precedence over New) since the operation order on disk is important to work well. This patch reorders overlay values such that the overlay of a profile takes place *after* the basic overlay, ensuring that the profile actions take place after the basic ones; this allows profiles to properly overwrite files as expected (see #1609) This is done while adequately maintaining the order of operations that were required as part of #1563 Overlay vars of profiles are also checked to be working fine, along with a test. This fixes #1247 and #1609 --- test/rebar_release_SUITE.erl | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/rebar_release_SUITE.erl b/test/rebar_release_SUITE.erl index e41339b..1bcc61e 100644 --- a/test/rebar_release_SUITE.erl +++ b/test/rebar_release_SUITE.erl @@ -200,13 +200,34 @@ profile_overlays(Config) -> AppDir = ?config(apps, Config), Name = ?config(name, Config), Vsn = "1.0.0", + file:write_file(filename:join(AppDir, "dev.file"), "dev.\n"), + file:write_file(filename:join(AppDir, "prod.file"), "prod.\n"), + file:write_file(filename:join(AppDir, "dev.vars"), "{env, \"dev\"}.\n"), + file:write_file(filename:join(AppDir, "prod.vars"), "{env, \"prod\"}.\n"), {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"}]}]}]}]}])), + file:consult(rebar_test_utils:create_config(AppDir, + %% Paths are relative, but to cwd in relx, not the project root as + %% seen by rebar3 (in non-test cases, they're the same). + %% Work around by being explicit. + [{relx, [{release, {list_to_atom(Name), Vsn}, + [list_to_atom(Name)]}, + {overlay_vars, filename:join(AppDir, "dev.vars")}, + {overlay, [{mkdir, "randomdir"}, + {copy, filename:join(AppDir,"./dev.file"), "profile.file"}, + {copy, filename:join(AppDir,"./dev.file"), "{{env}}.file"}, + {chmod, 8#00770, "profile.file"}]}, + {lib_dirs, [AppDir]}]}, + {profiles, [{prod, + [{relx, [ + {overlay_vars, filename:join(AppDir, "prod.vars")}, + {overlay, [{mkdir, "otherrandomdir"}, + {copy, filename:join(AppDir, "./prod.file"), "{{env}}.file"}, + {copy, filename:join(AppDir, "./prod.file"), "profile.file"}, + {chmod, 8#00770, "profile.file"}]} + + ]}] + }]} + ])), ReleaseDir = filename:join([AppDir, "./_build/prod/rel/", Name]), @@ -216,7 +237,12 @@ profile_overlays(Config) -> {ok, [{release, list_to_atom(Name), Vsn, false}, {dir, filename:join(ReleaseDir, "otherrandomdir")}, {dir, filename:join(ReleaseDir, "randomdir")}]} - ). + ), + ?assertMatch({ok,[prod]}, + file:consult(filename:join(ReleaseDir, "profile.file"))), + ?assertMatch({ok,[prod]}, + file:consult(filename:join(ReleaseDir, "prod.file"))), + ok. profile_overlay_merge (_Config) -> % when profile and relx overlays both exist, the profile overlays should be -- cgit v1.1 From 7095382e2c769f43214c32c4cb7f357b15ee095c Mon Sep 17 00:00:00 2001 From: suexcxine Date: Fri, 25 Aug 2017 22:50:22 +0800 Subject: Recompile when include files change --- test/rebar_compile_SUITE.erl | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 5a18745..6579617 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -24,6 +24,7 @@ clean_extra_dirs_in_project_root/1, recompile_when_hrl_changes/1, recompile_when_included_hrl_changes/1, + recompile_when_opts_included_hrl_changes/1, recompile_when_opts_change/1, dont_recompile_when_opts_dont_change/1, dont_recompile_yrl_or_xrl/1, @@ -66,6 +67,7 @@ all() -> {group, basic_extras}, {group, release_extras}, {group, unbalanced_extras}, {group, root_extras}, recompile_when_hrl_changes, recompile_when_included_hrl_changes, + recompile_when_opts_included_hrl_changes, recompile_when_opts_change, dont_recompile_when_opts_dont_change, dont_recompile_yrl_or_xrl, delete_beam_if_source_deleted, @@ -752,6 +754,53 @@ recompile_when_included_hrl_changes(Config) -> ?assert(ModTime =/= NewModTime). +recompile_when_opts_included_hrl_changes(Config) -> + AppsDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + AppDir = filename:join([AppsDir, "apps", Name]), + + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + ExtraSrc = <<"-module(test_header_include).\n" + "-export([main/0]).\n" + "-include(\"test_header_include.hrl\").\n" + "main() -> ?SOME_DEFINE.\n">>, + + ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>, + ok = filelib:ensure_dir(filename:join([AppsDir, "include", "dummy"])), + HeaderFile = filename:join([AppsDir, "include", "test_header_include.hrl"]), + ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc), + ok = file:write_file(HeaderFile, ExtraHeader), + + %% Using relative path from the project root + RebarConfig = [{erl_opts, [{i, "include/"}]}], + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(AppsDir), + + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + EbinDir = filename:join([AppsDir, "_build", "default", "lib", Name, "ebin"]), + {ok, Files} = rebar_utils:list_dir(EbinDir), + ModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- Files, filename:extension(F) == ".beam"], + + timer:sleep(1000), + + NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>, + ok = file:write_file(HeaderFile, NewExtraHeader), + + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + {ok, NewFiles} = rebar_utils:list_dir(EbinDir), + NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) + || F <- NewFiles, filename:extension(F) == ".beam"], + + ok = file:set_cwd(Cwd), + + ?assert(ModTime =/= NewModTime). + recompile_when_opts_change(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 7c959ccb4f91cdfdb956aa090b3789cf8fd396ed Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 30 Aug 2017 08:08:52 -0400 Subject: Fix relative src dir specifications When fetching src_dir values, some relative paths can be inserted. When deduplicating the paths on the fetch, this fact means that logically duplicate (but literally different) directories can be returned at once. By normalizing the names, duplication bugs can be resolved. --- test/rebar_dir_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 6797802..3b8e1fc 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -68,7 +68,7 @@ default_all_src_dirs(Config) -> ["src", "test"] = rebar_dir:all_src_dirs(rebar_state:opts(State), ["src"], ["test"]). src_dirs(Config) -> - RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}]}], + RebarConfig = [{erl_opts, [{src_dirs, ["foo", "./bar", "bar", "bar/", "./bar/", "baz"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), ["bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). -- cgit v1.1 From 8e4f90fa08bb44e041b4225c49d5a75124adcb3c Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 1 Sep 2017 12:21:25 -0700 Subject: fix sys config merging --- test/rebar_ct_SUITE.erl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index 70cf60c..f009930 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -1132,12 +1132,19 @@ cmd_sys_config(Config) -> CfgFile = filename:join([AppDir, "config", "cfg_sys.config"]), ok = filelib:ensure_dir(CfgFile), ok = file:write_file(CfgFile, cfg_sys_config_file(AppName)), + + OtherCfgFile = filename:join([AppDir, "config", "other.config"]), + ok = filelib:ensure_dir(OtherCfgFile), + ok = file:write_file(OtherCfgFile, other_sys_config_file(AppName)), + RebarConfig = [{ct_opts, [{sys_config, CfgFile}]}], {ok, State1} = rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "test", "lock"], return), {ok, _} = rebar_prv_common_test:prepare_tests(State1), ?assertEqual({ok, cfg_value}, application:get_env(AppName, key)), + ?assertEqual({ok, other_cfg_value}, application:get_env(AppName, other_key)), + Providers = rebar_state:providers(State1), Namespace = rebar_state:namespace(State1), CommandProvider = providers:get_provider(ct, Providers, Namespace), @@ -1614,4 +1621,7 @@ cmd_sys_config_file(AppName) -> io_lib:format("[{~ts, [{key, cmd_value}]}].", [AppName]). cfg_sys_config_file(AppName) -> - io_lib:format("[{~ts, [{key, cfg_value}]}].", [AppName]). + io_lib:format("[{~ts, [{key, cfg_value}]}, \"config/other\"].", [AppName]). + +other_sys_config_file(AppName) -> + io_lib:format("[{~ts, [{other_key, other_cfg_value}]}].", [AppName]). -- cgit v1.1 From cf83eb7fc45fac677a83b5f38e87c581cf516cf2 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 27 Sep 2017 19:01:44 -0400 Subject: Corrects a fix to src_dir values The previous patch at #7c959cc fixed the usage of duplicate values for directories through relative paths, but mistakenly went overboard and dropped the `./` path, which is still fairly common. Similarly for `../". The code is modified to special-case such values and keep the code working. --- test/rebar_dir_SUITE.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 3b8e1fc..4743865 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -68,10 +68,11 @@ default_all_src_dirs(Config) -> ["src", "test"] = rebar_dir:all_src_dirs(rebar_state:opts(State), ["src"], ["test"]). src_dirs(Config) -> - RebarConfig = [{erl_opts, [{src_dirs, ["foo", "./bar", "bar", "bar/", "./bar/", "baz"]}]}], + RebarConfig = [{erl_opts, [{src_dirs, ["foo", "./bar", "bar", "bar/", "./bar/", "baz", + "./", ".", "../", "..", "./../", "../.", ".././../"]}]}], {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), - ["bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). + [".", "..", "../..", "bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). src_dirs_with_opts(Config) -> RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}, -- cgit v1.1 From c92e2682a0391eeef523ac87fb1a92f576455028 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 4 Oct 2017 16:30:15 -0400 Subject: Bundle in debug for weak test Getting real tired of that nondeterministic set of runs on OSX CI --- test/rebar_pkg_alias_SUITE.erl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test') diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index 2b8ccd2..07656d0 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -166,6 +166,8 @@ mock_config(Name, Config) -> {ChkFake, Etag} = create_lib(Name, Config, "fakelib"), {ChkTop, _} = create_lib(Name, Config, "topdep"), {ChkTrans, _} = create_lib(Name, Config, "transitive_app", "transitive"), + ct:pal("{~p, _}",[ChkTop]), + ct:pal("{~p, _}",[ChkTrans]), Priv = ?config(priv_dir, Config), TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]), %% Add an alias for goodpkg -> fakelib by hand @@ -173,6 +175,7 @@ mock_config(Name, Config) -> CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]), CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), rebar_test_utils:create_app(AppDir, "fakelib", "1.0.0", [kernel, stdlib]), + ct:pal("{~p, ~p}",[ChkFake, Etag]), {ChkFake, Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg-1.0.0"), Tid = ets:new(registry_table, [public]), -- cgit v1.1 From e592573745ee5dbc337d77997aaa8ebb40b566bb Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 13 Oct 2017 10:38:43 -0400 Subject: Add tests for unlock state passthrough --- test/rebar_unlock_SUITE.erl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_unlock_SUITE.erl b/test/rebar_unlock_SUITE.erl index 8dbdb3a..b2c0205 100644 --- a/test/rebar_unlock_SUITE.erl +++ b/test/rebar_unlock_SUITE.erl @@ -42,8 +42,10 @@ unlock(Config) -> Locks = read_locks(Config), rebar_test_utils:run_and_check(Config, [], ["unlock", "fakeapp"], {ok, []}), Locks = read_locks(Config), - rebar_test_utils:run_and_check(Config, [], ["unlock", "uuid"], {ok, []}), + {ok, State} = rebar_test_utils:run_and_check(Config, [], ["unlock", "uuid"], return), ?assertEqual(Locks -- ["uuid"], read_locks(Config)), + ?assert(false =:= lists:keyfind(<<"uuid">>, 1, rebar_state:get(State, {locks, default}))), + ?assert(false =/= lists:keyfind(<<"itc">>, 1, rebar_state:get(State, {locks, default}))), rebar_test_utils:run_and_check(Config, [], ["unlock", "gproc,itc"], {ok, []}), ?assertEqual(Locks -- ["uuid","gproc","itc"], read_locks(Config)), rebar_test_utils:run_and_check(Config, [], ["unlock", string:join(Locks,",")], {ok, []}), @@ -52,8 +54,9 @@ unlock(Config) -> unlock_all(Config) -> [_|_] = read_locks(Config), - rebar_test_utils:run_and_check(Config, [], ["unlock"], {ok, []}), + {ok, State} = rebar_test_utils:run_and_check(Config, [], ["unlock"], return), ?assertEqual({error, enoent}, read_locks(Config)), + ?assertEqual([], rebar_state:get(State, {locks, default})), ok. read_locks(Config) -> -- cgit v1.1 From 02caf6297db344348f43b39dbe55b80420633d5f Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Mon, 16 Oct 2017 23:57:08 +0100 Subject: Profile deps counter test --- test/rebar_compile_SUITE.erl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 6579617..0b62cbe 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -40,6 +40,7 @@ clean_all/1, override_deps/1, profile_override_deps/1, + profile_deps/1, deps_build_in_prod/1, include_file_relative_to_working_directory/1, include_file_in_src/1, @@ -75,6 +76,7 @@ all() -> parse_transform_test, erl_first_files_test, mib_test, umbrella_mib_first_test, only_default_transitive_deps, clean_all, override_deps, profile_override_deps, deps_build_in_prod, + profile_override_deps, profile_deps, deps_build_in_prod, include_file_relative_to_working_directory, include_file_in_src, include_file_relative_to_working_directory_test, include_file_in_src_test, recompile_when_parse_transform_as_opt_changes, @@ -1305,6 +1307,19 @@ profile_override_deps(Config) -> {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]} ). +profile_deps(Config) -> + mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]), + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + RebarConfig = [ + {deps, TopDeps}, + {profiles, [{a, []}]}], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], + {ok, [{dep, "some_dep"},{dep, "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 -- cgit v1.1 From 65e07082018dec2a47f309258761db760100f5f2 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 23 Oct 2017 10:11:06 -0400 Subject: Fix include paths in profile multiapp edge case The compiling of OTP applications is done by first topographically sorting them according to their dependencies, deps-first. This allows all compilation to take place in order. In the current code, the same logic extends to top-level applications in an umbrella project. Unfortunately, there are cases where this is not going to be true: when an application has extra_src_dirs entries (or additional directories or files) to conditionally compile under some profiles, it may start depending on another top-level application dedicated to that profile for include files. However, such an app will never make it to production and neither will the compilation artifacts that create the dependency. Under that scenario, current rebar3 is unusable. This patch makes it so that the compilation provider instead changes the logic for top-level apps: rather than copying their directories one by one and compiling them in order, it: 1. copies all top-level apps to the build directory so the files are in their proper locations 2. adds the top-level apps to the path (after the global hooks have run, so the existing scope and env has not changed) 3. runs the compilation as usual. Fixes #1651 --- test/rebar_compile_SUITE.erl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 6579617..1655336 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -45,6 +45,7 @@ include_file_in_src/1, include_file_relative_to_working_directory_test/1, include_file_in_src_test/1, + include_file_in_src_test_multiapp/1, dont_recompile_when_erl_compiler_options_env_does_not_change/1, recompile_when_erl_compiler_options_env_changes/1, always_recompile_when_erl_compiler_options_set/1, @@ -77,6 +78,7 @@ all() -> clean_all, override_deps, profile_override_deps, deps_build_in_prod, include_file_relative_to_working_directory, include_file_in_src, include_file_relative_to_working_directory_test, include_file_in_src_test, + include_file_in_src_test_multiapp, recompile_when_parse_transform_as_opt_changes, recompile_when_parse_transform_inline_changes, regex_filter_skip, regex_filter_regression, @@ -1460,6 +1462,39 @@ include_file_in_src_test(Config) -> ["as", "test", "compile"], {ok, [{app, Name}]}). +%% Same as `include_file_in_src_test/1' but using multiple top-level +%% apps as dependencies. +include_file_in_src_test_multiapp(Config) -> + + Name1 = rebar_test_utils:create_random_name("app2_"), + Name2 = rebar_test_utils:create_random_name("app1_"), + AppDir1 = filename:join([?config(apps, Config), "lib", Name1]), + AppDir2 = filename:join([?config(apps, Config), "lib", Name2]), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir1, Name1, Vsn, [kernel, stdlib]), + rebar_test_utils:create_app(AppDir2, Name2, Vsn, [kernel, stdlib]), + + Src = "-module(test).\n" +"\n" +"-include_lib(\"" ++ Name2 ++ "/include/test.hrl\").\n" +"\n" +"test() -> ?TEST_MACRO.\n" +"\n", + Include = <<"-define(TEST_MACRO, test).\n">>, + + ok = filelib:ensure_dir(filename:join([AppDir1, "src", "dummy"])), + ok = filelib:ensure_dir(filename:join([AppDir1, "test", "dummy"])), + ok = filelib:ensure_dir(filename:join([AppDir2, "src", "dummy"])), + ok = filelib:ensure_dir(filename:join([AppDir2, "include", "dummy"])), + ok = file:write_file(filename:join([AppDir1, "test", "test.erl"]), Src), + + ok = file:write_file(filename:join([AppDir2, "include", "test.hrl"]), Include), + + RebarConfig = [], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["as", "test", "compile"], + {ok, [{app, Name1}]}). + %% this test sets the env var, compiles, records the file last modified timestamp, %% recompiles and compares the file last modified timestamp to ensure it hasn't %% changed. this test should run on 19.x+ -- cgit v1.1 From 2d5cd9c00cfa4e58066b48beee4057fdd52cc7be Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 1 Nov 2017 19:38:03 -0400 Subject: OTP-21 readiness, Full Unicode support This replaces all deprecated function usage by alternative ones based on a version switch enacted at compile time, preventing all warnings. This will likely introduce some possible runtime errors in using a Rebar3 compiled on OTP-20 or OTP-21 back in versions 19 and earlier, but we can't really work around that. A bunch of dependencies have been updated to support OTP-21 without warnings as well. --- test/rebar_ct_SUITE.erl | 2 +- test/rebar_dialyzer_SUITE.erl | 2 +- test/rebar_install_deps_SUITE.erl | 8 ++++---- test/rebar_profiles_SUITE.erl | 2 +- test/rebar_test_utils.erl | 8 ++++---- test/rebar_unlock_SUITE.erl | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index f009930..d7094ec 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -1407,7 +1407,7 @@ testspec_at_root(Config) -> CommandProvider = providers:get_provider(ct, Providers, Namespace), GetOptSpec = providers:opts(CommandProvider), - SpecArg1 = string:join([Spec1,Spec2,Spec3],","), + SpecArg1 = rebar_string:join([Spec1,Spec2,Spec3],","), {ok, GetOptResult1} = getopt:parse(GetOptSpec, ["--spec",SpecArg1]), State1 = rebar_state:command_parsed_args(State, GetOptResult1), Tests1 = rebar_prv_common_test:prepare_tests(State1), diff --git a/test/rebar_dialyzer_SUITE.erl b/test/rebar_dialyzer_SUITE.erl index d0a3611..6579afb 100644 --- a/test/rebar_dialyzer_SUITE.erl +++ b/test/rebar_dialyzer_SUITE.erl @@ -362,6 +362,6 @@ get_apps_from_beam_files(BeamFiles) -> lists:usort( [begin AppNameVsn = filename:basename(filename:dirname(filename:dirname(File))), - [AppName | _] = string:tokens(AppNameVsn ++ "-", "-"), + [AppName | _] = rebar_string:lexemes(AppNameVsn ++ "-", "-"), ec_cnv:to_atom(AppName) end || File <- BeamFiles]). diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl index 9ff28c7..3dbbf63 100644 --- a/test/rebar_install_deps_SUITE.erl +++ b/test/rebar_install_deps_SUITE.erl @@ -82,12 +82,12 @@ format_expected_mdeps(Deps) -> lists:append([ case Dep of {N,V} when hd(N) >= $a, hd(N) =< $z -> - UN = string:to_upper(N), + UN = rebar_string:uppercase(N), [{dep, UN, V}, {lock, pkg, UN, V}]; {N,V} when hd(N) >= $A, hd(N) =< $Z -> [{dep, N, V}, {lock, src, N, V}]; N when hd(N) >= $a, hd(N) =< $z -> - UN = string:to_upper(N), + UN = rebar_string:uppercase(N), [{dep, UN}, {lock, pkg, UN, "0.0.0"}]; N when hd(N) >= $A, hd(N) =< $Z -> [{dep, N}, {lock, src, N, "0.0.0"}] @@ -95,9 +95,9 @@ format_expected_mdeps(Deps) -> format_expected_mixed_warnings(Warnings) -> [case W of - {N, Vsn} when hd(N) >= $a, hd(N) =< $z -> {pkg, string:to_upper(N), Vsn}; + {N, Vsn} when hd(N) >= $a, hd(N) =< $z -> {pkg, rebar_string:uppercase(N), Vsn}; {N, Vsn} when hd(N) >= $A, hd(N) =< $Z -> {git, N, Vsn}; - N when hd(N) >= $a, hd(N) =< $z -> {pkg, string:to_upper(N), "0.0.0"}; + N when hd(N) >= $a, hd(N) =< $z -> {pkg, rebar_string:uppercase(N), "0.0.0"}; N when hd(N) >= $A, hd(N) =< $Z -> {git, N, "0.0.0"} end || W <- Warnings]. diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 11aca6a..324a771 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -542,7 +542,7 @@ get_compiled_profile_erl_opts(Profiles, Config) -> [default] -> ["compile"]; _ -> - ["as", string:join(PStrs, ","), "compile"] + ["as", rebar_string:join(PStrs, ","), "compile"] end, {ok, State} = rebar_test_utils:run_and_check( Config, RebarConfig, Command, {ok, [{app, Name}]}), diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 0ccec56..c1e8b62 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -167,14 +167,14 @@ expand_deps(pkg, [{Name, Vsn, Deps} | Rest]) -> [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)]; expand_deps(mixed, [{Name, Deps} | Rest]) -> Dep = if hd(Name) >= $a, hd(Name) =< $z -> - {pkg, string:to_upper(Name), "0.0.0", undefined} + {pkg, rebar_string:uppercase(Name), "0.0.0", undefined} ; hd(Name) >= $A, hd(Name) =< $Z -> {Name, ".*", {git, "https://example.org/user/"++Name++".git", "master"}} end, [{Dep, expand_deps(mixed, Deps)} | expand_deps(mixed, Rest)]; expand_deps(mixed, [{Name, Vsn, Deps} | Rest]) -> Dep = if hd(Name) >= $a, hd(Name) =< $z -> - {pkg, string:to_upper(Name), Vsn, undefined} + {pkg, rebar_string:uppercase(Name), Vsn, undefined} ; hd(Name) >= $A, hd(Name) =< $Z -> {Name, Vsn, {git, "https://example.org/user/"++Name++".git", {tag, Vsn}}} end, @@ -477,7 +477,7 @@ package_app(AppDir, DestDir, PkgName) -> {ok, Contents} = file:read_file(filename:join(DestDir, "contents.tar.gz")), Blob = <<"3who cares", Contents/binary>>, <> = crypto:hash(sha256, Blob), - BinChecksum = list_to_binary(string:to_upper(lists:flatten(io_lib:format("~64.16.0b", [X])))), + BinChecksum = list_to_binary(rebar_string:uppercase(lists:flatten(io_lib:format("~64.16.0b", [X])))), ok = file:write_file(filename:join(DestDir, "CHECKSUM"), BinChecksum), PkgFiles = ["contents.tar.gz", "VERSION", "metadata.config", "CHECKSUM"], Archive = filename:join(DestDir, Name), @@ -485,5 +485,5 @@ package_app(AppDir, DestDir, PkgName) -> lists:zip(PkgFiles, [filename:join(DestDir,F) || F <- PkgFiles])), {ok, BinFull} = file:read_file(Archive), <> = crypto:hash(md5, BinFull), - Etag = string:to_lower(lists:flatten(io_lib:format("~32.16.0b", [E]))), + Etag = rebar_string:lowercase(lists:flatten(io_lib:format("~32.16.0b", [E]))), {BinChecksum, Etag}. diff --git a/test/rebar_unlock_SUITE.erl b/test/rebar_unlock_SUITE.erl index b2c0205..a8d1400 100644 --- a/test/rebar_unlock_SUITE.erl +++ b/test/rebar_unlock_SUITE.erl @@ -33,7 +33,7 @@ pkgunlock(Config) -> rebar_test_utils:run_and_check(Config, [], ["unlock", "cf,certifi"], {ok, []}), ?assertEqual(Locks -- ["bbmustache","cf","certifi"], read_locks(Config)), ?assertEqual(Hashes -- ["bbmustache","cf","certifi"], read_hashes(Config)), - rebar_test_utils:run_and_check(Config, [], ["unlock", string:join(Locks,",")], {ok, []}), + rebar_test_utils:run_and_check(Config, [], ["unlock", rebar_string:join(Locks,",")], {ok, []}), ?assertEqual({error, enoent}, read_locks(Config)), ?assertEqual({error, enoent}, read_hashes(Config)), ok. @@ -48,7 +48,7 @@ unlock(Config) -> ?assert(false =/= lists:keyfind(<<"itc">>, 1, rebar_state:get(State, {locks, default}))), rebar_test_utils:run_and_check(Config, [], ["unlock", "gproc,itc"], {ok, []}), ?assertEqual(Locks -- ["uuid","gproc","itc"], read_locks(Config)), - rebar_test_utils:run_and_check(Config, [], ["unlock", string:join(Locks,",")], {ok, []}), + rebar_test_utils:run_and_check(Config, [], ["unlock", rebar_string:join(Locks,",")], {ok, []}), ?assertEqual({error, enoent}, read_locks(Config)), ok. -- cgit v1.1 From bf7ec3866f1819619286cc875fa88e1dc8bb9cfc Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 5 Nov 2017 22:24:58 -0500 Subject: Make debug_info rules clear Current rebar3 uses debug_info rules where debug_info is added by default, and no_debug_info prevents the default from being added, and removes any explicit debug_info, if any. The problem is that if 'no_debug_info' is anywhere in the config for a run, it cannot be removed even with other profiles. additionally, no_debug_info ignores special tuples like {debug_info, {Mod, Data}} and {debug_info_key, Key}, which can be used to add debug info and encrypt it (in lieu of plain debug_info) respectively. This patch makes it so that the following rules are in place: - the last option seen takes priority, allowing profile overrides by the ordering rules the compiler expects - the overriden options shall be explicitly deleted to avoid confusing the compiler - any option related to debug info seen last cancels any no_debug_info that preceded it - any no_debug_info option seen last cancels all of the other debug_info options - if debug_info is seen last, it cancels out {debug_info_key, Key} - if {debug_info_key, Key} is seen last, it cancels out debug_info - All other options are left untouched in that context (defines can still be expanded and so on) This should allow proper profile rules to be followed. Note that erl_opt profile merging puts precedence on the *last* element of a list, to match the compiler. --- test/rebar_profiles_SUITE.erl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 324a771..6afdc39 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -27,6 +27,7 @@ test_profile_erl_opts_order_3/1, test_profile_erl_opts_order_4/1, test_profile_erl_opts_order_5/1, + test_erl_opts_debug_info/1, first_files_exception/1]). -include_lib("common_test/include/ct.hrl"). @@ -50,6 +51,7 @@ all() -> test_profile_erl_opts_order_3, test_profile_erl_opts_order_4, test_profile_erl_opts_order_5, + test_erl_opts_debug_info, first_files_exception]. init_per_suite(Config) -> @@ -501,6 +503,30 @@ test_profile_erl_opts_order_5(Config) -> Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined), warn_export_all = Opt. +test_erl_opts_debug_info(_Config) -> + ToOpts = fun(List) -> rebar_opts:erl_opts(dict:from_list([{erl_opts, List}])) end, + ?assertEqual([debug_info,a,b,c], + ToOpts([a,b,c])), + ?assertEqual([{debug_info,{mod,123}},a,b,c,debug_info], + ToOpts([{debug_info,{mod,123}},a,b,c,debug_info])), + ?assertEqual([a,b,debug_info,c], + ToOpts([no_debug_info,a,b,debug_info,c])), + ?assertEqual([a,b,c], + ToOpts([debug_info,a,b,no_debug_info,c])), + ?assertEqual([a,b,c,debug_info], + ToOpts([{debug_info_key, "12345"},a,b, + no_debug_info,c,debug_info])), + ?assertEqual([a,b,c], + ToOpts([{debug_info,{mod,123}},{debug_info_key, "12345"}, + a,no_debug_info,b,c,debug_info,no_debug_info])), + ?assertEqual([a,b,c,{debug_info_key,"123"}], + ToOpts([{debug_info_key, "12345"},a,b,no_debug_info,debug_info, + c,{debug_info_key, "123"}])), + ?assertEqual([{debug_info_key,"12345"},a,b,c,{debug_info,{mod,"123"}}], + ToOpts([debug_info,{debug_info_key,"12345"},a, + no_debug_info,b,c,{debug_info,{mod,"123"}}])), + ok. + first_files_exception(_Config) -> RebarConfig = [{erl_first_files, ["c","a","b"]}, {mib_first_files, ["c","a","b"]}, -- cgit v1.1 From 510748e099b27e7ccff33524f38895f306925587 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 21 Nov 2017 16:41:00 -0500 Subject: Fix test mocking for profile overrides --- test/rebar_compile_SUITE.erl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 62df7aa..c5336cf 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1290,9 +1290,10 @@ override_deps(Config) -> ). profile_override_deps(Config) -> - mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]), Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), RebarConfig = [ {deps, TopDeps}, @@ -1310,9 +1311,10 @@ profile_override_deps(Config) -> ). profile_deps(Config) -> - mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]), Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), RebarConfig = [ {deps, TopDeps}, -- cgit v1.1 From 805dc0fa2aad53a5ac551033fd0da3b433f6b6e1 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 2 Dec 2017 17:32:15 -0500 Subject: Support minimal coverage validation in tests Adds an option (-m, --min_coverage, or {cover_opts, {min_coverage,X}}) to the 'cover' command, where the value is an integer between 0 and 100. If the total coverage during the analysis is below the value received, the command will fail with output like: ===> Requiring 64% coverage to pass. Only 62% obtained If the rate is correct, the command silently passes as it currently does. This feature allows to enforce code coverage standards in a project if desired. --- test/rebar_cover_SUITE.erl | 50 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index cc06c95..2918123 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -14,7 +14,9 @@ flag_verbose/1, config_verbose/1, excl_mods_and_apps/1, - coverdata_is_reset_on_write/1]). + coverdata_is_reset_on_write/1, + flag_min_coverage/1, + config_min_coverage/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -38,7 +40,8 @@ all() -> root_extra_src_dirs, index_written, flag_verbose, config_verbose, - excl_mods_and_apps, coverdata_is_reset_on_write]. + excl_mods_and_apps, coverdata_is_reset_on_write, + flag_min_coverage, config_min_coverage]. flag_coverdata_written(Config) -> AppDir = ?config(apps, Config), @@ -257,3 +260,46 @@ coverdata_is_reset_on_write(Config) -> Res = lists:map(fun(M) -> cover:analyse(M) end, cover:modules()), Ok = lists:foldl(fun({ok, R}, Acc) -> R ++ Acc end, [], Res), [] = lists:filter(fun({_, {0,_}}) -> false; (_) -> true end, Ok). + +flag_min_coverage(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("min_cover_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}], + ?assertMatch({ok, _}, + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["do", "eunit", "--cover", ",", "cover", "--min_coverage=5"], + return)), + + ?assertMatch({error,{rebar_prv_cover,{min_coverage_failed,{65,_}}}}, + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["do", "eunit", "--cover", ",", "cover", "--min_coverage=65"], + return)), + ok. + +config_min_coverage(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("cover_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig1 = [{erl_opts, [{d, some_define}]}, {cover_opts, [{min_coverage,5}]}], + ?assertMatch({ok, _}, + rebar_test_utils:run_and_check( + Config, RebarConfig1, + ["do", "eunit", "--cover", ",", "cover"], + return)), + + RebarConfig2 = [{erl_opts, [{d, some_define}]}, {cover_opts, [{min_coverage,65}]}], + ?assertMatch({error,{rebar_prv_cover,{min_coverage_failed,{65,_}}}}, + rebar_test_utils:run_and_check( + Config, RebarConfig2, + ["do", "eunit", "--cover", ",", "cover"], + return)), + ok. -- cgit v1.1 From 6e672852a72f51d088e16f3662b0299744435127 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 1 Dec 2017 16:44:00 -0800 Subject: fix code path when validating plugins --- test/rebar_plugins_SUITE.erl | 28 ++++++++++++++++++++++++++-- test/rebar_test_utils.erl | 9 +++++---- 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_plugins_SUITE.erl b/test/rebar_plugins_SUITE.erl index a313683..2d74539 100644 --- a/test/rebar_plugins_SUITE.erl +++ b/test/rebar_plugins_SUITE.erl @@ -14,7 +14,8 @@ upgrade_project_plugin/1, sub_app_plugins/1, sub_app_plugin_overrides/1, - project_plugins/1]). + project_plugins/1, + use_checkout_plugins/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -37,7 +38,7 @@ end_per_testcase(_, _Config) -> all() -> [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade, upgrade_project_plugin, - sub_app_plugins, sub_app_plugin_overrides, project_plugins]. + sub_app_plugins, sub_app_plugin_overrides, project_plugins, use_checkout_plugins]. %% Tests that compiling a project installs and compiles the plugins of deps compile_plugins(Config) -> @@ -370,3 +371,26 @@ project_plugins(Config) -> ?assertEqual(length(Release), 2), ?assertEqual(length(Compile), 1). + +use_checkout_plugins(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]), + + PluginName = "checkedout", + CheckoutsDir = filename:join(AppDir, "_checkouts/checkedout"), + rebar_test_utils:create_plugin(CheckoutsDir, PluginName, "1.0.0", []), + + RConfFile = + rebar_test_utils:create_config(AppDir, + [{deps, []}, + {plugins, [list_to_atom(PluginName)]}]), + {ok, RConf} = file:consult(RConfFile), + + %% Verify we can run the plugin + ?assertMatch({ok, _}, rebar_test_utils:run_and_check( + Config, RConf, ["checkedout"], + {ok, []} + )). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index c1e8b62..b74aa2f 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -425,15 +425,16 @@ erl_src_file(Name) -> plugin_src_file(Name) -> io_lib:format("-module('~s').\n" - "-export([init/1]).\n" + "-export([init/1, do/1]).\n" "init(State) -> \n" "Provider = providers:create([\n" "{name, '~s'},\n" "{module, '~s'}\n" "]),\n" - "{ok, rebar_state:add_provider(State, Provider)}.\n", [filename:basename(Name, ".erl"), - filename:basename(Name, ".erl"), - filename:basename(Name, ".erl")]). + "{ok, rebar_state:add_provider(State, Provider)}.\n" + "do(State) -> {ok, State}.\n", [filename:basename(Name, ".erl"), + filename:basename(Name, ".erl"), + filename:basename(Name, ".erl")]). erl_eunitized_src_file(Name) -> io_lib:format("-module('~s').\n" -- cgit v1.1 From 72b649cc664747d7682eec7150f6ad022b3838ae Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 4 Dec 2017 11:35:22 -0800 Subject: add eunit and ct option to set coverdata file name --- test/rebar_cover_SUITE.erl | 17 +++++++++++++++++ test/rebar_ct_SUITE.erl | 27 ++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_cover_SUITE.erl b/test/rebar_cover_SUITE.erl index cc06c95..c99dbb7 100644 --- a/test/rebar_cover_SUITE.erl +++ b/test/rebar_cover_SUITE.erl @@ -7,6 +7,7 @@ all/0, flag_coverdata_written/1, config_coverdata_written/1, + config_coverdata_overridden_name_written/1, basic_extra_src_dirs/1, release_extra_src_dirs/1, root_extra_src_dirs/1, @@ -34,6 +35,7 @@ init_per_testcase(_, Config) -> all() -> [flag_coverdata_written, config_coverdata_written, + config_coverdata_overridden_name_written, basic_extra_src_dirs, release_extra_src_dirs, root_extra_src_dirs, index_written, @@ -70,6 +72,21 @@ config_coverdata_written(Config) -> true = filelib:is_file(filename:join([AppDir, "_build", "test", "cover", "eunit.coverdata"])). +config_coverdata_overridden_name_written(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("cover_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]), + + RebarConfig = [{erl_opts, [{d, some_define}]}, {cover_enabled, true}], + rebar_test_utils:run_and_check(Config, + RebarConfig, + ["eunit", "--cover_export_name=test_name"], + {ok, [{app, Name}]}), + + true = filelib:is_file(filename:join([AppDir, "_build", "test", "cover", "test_name.coverdata"])). + basic_extra_src_dirs(Config) -> AppDir = ?config(apps, Config), diff --git a/test/rebar_ct_SUITE.erl b/test/rebar_ct_SUITE.erl index d7094ec..15dc63e 100644 --- a/test/rebar_ct_SUITE.erl +++ b/test/rebar_ct_SUITE.erl @@ -49,6 +49,7 @@ cfg_cover_spec/1, cfg_atom_suites/1, cover_compiled/1, + cover_export_name/1, misspecified_ct_opts/1, misspecified_ct_compile_opts/1, misspecified_ct_first_files/1, @@ -121,7 +122,8 @@ groups() -> [{basic_app, [], [basic_app_default_dirs, cmd_create_priv_dir, cmd_include_dir, cmd_sys_config]}, - {cover, [], [cover_compiled]}]. + {cover, [], [cover_compiled, + cover_export_name]}]. init_per_group(basic_app, Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_"), @@ -1251,6 +1253,29 @@ cover_compiled(Config) -> Mod = list_to_atom(Name), {file, _} = cover:is_compiled(Mod). +cover_export_name(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", "--cover_export_name=export_name"]), + + NewState = rebar_state:command_parsed_args(State, GetOptResult), + + Tests = rebar_prv_common_test:prepare_tests(NewState), + {ok, _} = rebar_prv_common_test:compile(NewState, Tests), + rebar_prv_common_test:maybe_write_coverdata(NewState), + + Name = ?config(name, Config), + Mod = list_to_atom(Name), + {file, _} = cover:is_compiled(Mod), + + Dir = rebar_dir:profile_dir(rebar_state:opts(NewState), [default, test]), + ct:pal("DIR ~s", [Dir]), + true = filelib:is_file(filename:join([Dir, "cover", "export_name.coverdata"])). + misspecified_ct_opts(Config) -> C = rebar_test_utils:init_rebar_state(Config, "ct_cfg_atom_suites_"), -- cgit v1.1 From 553a579b36fe0fb4a8bf464cd282d43c07d4e192 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 5 Dec 2017 07:47:07 -0500 Subject: Alias plugin promoted to built-in command - Uses the code at https://github.com/tsloughter/rebar_alias and brings it within rebar3 - adds safety checks to prevent redefining built-in commands or obvious circular dependencies between commands (indirect circular deps are still possible) - adds tests - adds a systest to ensure no clash with the existing plugin --- test/rebar_alias_SUITE.erl | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 test/rebar_alias_SUITE.erl (limited to 'test') diff --git a/test/rebar_alias_SUITE.erl b/test/rebar_alias_SUITE.erl new file mode 100644 index 0000000..f889ae4 --- /dev/null +++ b/test/rebar_alias_SUITE.erl @@ -0,0 +1,113 @@ +-module(rebar_alias_SUITE). +-compile([export_all]). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +init_per_suite(Config) -> Config. +end_per_suite(_Config) -> ok. + +init_per_testcase(_, Config) -> + rebar_test_utils:init_rebar_state(Config, "alias_"). + +end_per_testcase(_, _Config) -> + ok. + +all() -> [command, args, many, override_default, no_circular]. + %% namespaces: unsupported, untested. + +command() -> + [{doc, "Runs multiple regular commands as one alias"}]. +command(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_command_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [compile, unlock]}]}], + + %% compile job ran + rebar_test_utils:run_and_check(Config, RebarConfig, + ["test"], {ok, [{app, Name}]}), + %% unlock job also ran + Lockfile = filename:join(?config(apps, Config), "rebar.lock"), + ?assertNot(filelib:is_file(Lockfile)), + ok. + +args() -> + [{doc, "Runs multiple regular commands as one alias, some of " + "which have default arguments"}]. +args(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_args_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [{eunit,"-c"}, cover]}]}], + + %% test job ran (compiled and succeeded) + rebar_test_utils:run_and_check(Config, RebarConfig, + ["test"], {ok, [{app, Name}]}), + %% cover job also ran, meaning eunit had coverage on, otherwise + %% the index file is not generated. + CoverFile = filename:join([?config(apps, Config), + "_build", "test", "cover", "index.html"]), + ?assert(filelib:is_file(CoverFile)), + ok. + +many() -> + [{doc, "Multiple aliases may be registered"}]. +many(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_args_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [{eunit,"-c"}, cover]}, + {nolock, [compile, unlock]}]}], + + %% test job ran (compiled and succeeded) + rebar_test_utils:run_and_check(Config, RebarConfig, + ["test"], {ok, [{app, Name}]}), + rebar_test_utils:run_and_check(Config, RebarConfig, + ["nolock"], {ok, [{app, Name}]}), + %% both jobs ran (see args/1 and command/1) + CoverFile = filename:join([?config(apps, Config), + "_build", "test", "cover", "index.html"]), + ?assert(filelib:is_file(CoverFile)), + Lockfile = filename:join(?config(apps, Config), "rebar.lock"), + ?assertNot(filelib:is_file(Lockfile)), + ok. + +override_default() -> + [{doc, "An alias cannot take over a default provider"}]. +override_default(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_override_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{compile, [help]}]}], + + %% App compiles anyway + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], + {ok, [{app, Name}]}), + ok. + +no_circular() -> + [{doc, "An alias cannot define itself as itself"}, + {timetrap, 2000}]. +no_circular(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_circular_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [help, {test,"-a"}, compile]}]}], + + %% Code does not deadlock forever and errors by not knowing + %% the command + rebar_test_utils:run_and_check(Config, RebarConfig, ["test"], + {error, [$C,$o,$m,$m,$a,$n,$d,$ ,"test",$ ,$n,$o,$t,$ , + $f,$o,$u,$n,$d]}), + ok. -- cgit v1.1 From d0f958d59d1f87bda8d1d6c724a1af18af288324 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 14 Dec 2017 10:14:53 -0500 Subject: Fix escriptize failure when ebin/ has subdirs Although fairly irregular, the presence of a subdirectory in ebin/ while running rebar3 escriptize would crash the run and generate a dump. Since ebin subdirectories are generally not supported (adding a path for an application only adds ebin/ and no subdirectories to the VM's path set), we just silently ignore the directory altogether. Fixes #1693 --- test/rebar_escriptize_SUITE.erl | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_escriptize_SUITE.erl b/test/rebar_escriptize_SUITE.erl index 139d5cd..a6901f9 100644 --- a/test/rebar_escriptize_SUITE.erl +++ b/test/rebar_escriptize_SUITE.erl @@ -7,7 +7,8 @@ all/0, escriptize_with_name/1, escriptize_with_bad_name/1, - build_and_clean_app/1]). + build_and_clean_app/1, + escriptize_with_ebin_subdir/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -29,7 +30,8 @@ all() -> [ build_and_clean_app, escriptize_with_name, - escriptize_with_bad_name + escriptize_with_bad_name, + escriptize_with_ebin_subdir ]. %% Test escriptize builds and runs the app's escript @@ -59,3 +61,24 @@ escriptize_with_bad_name(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, [{escript_main_app, boogers}], ["escriptize"], {error,{rebar_prv_escriptize, {bad_name, boogers}}}). + +escriptize_with_ebin_subdir(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]), + + filelib:ensure_dir(filename:join([AppDir, "ebin", "subdir", "subdirfile"])), + + %% To work, this test must run from the AppDir itself. To avoid breaking + %% other tests, be careful with cwd + Cwd = file:get_cwd(), + try + file:set_cwd(AppDir), + {ok, _} = rebar3:run(rebar_state:new(?config(state,Config), [], AppDir), + ["escriptize"]) + after + file:set_cwd(Cwd) % reset always + end, + ok. -- cgit v1.1 From a3b5846b49f034854a7ea585d826ab69869320ef Mon Sep 17 00:00:00 2001 From: Carl-Johan Kjellander Date: Tue, 2 Jan 2018 15:24:07 +0100 Subject: add test for provider_hook clean --- test/rebar_hooks_SUITE.erl | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index f7fcb82..a36dbe1 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -12,7 +12,8 @@ run_hooks_once_profiles/1, run_hooks_for_plugins/1, eunit_app_hooks/1, - deps_hook_namespace/1]). + deps_hook_namespace/1, + deps_clean_hook_namespace/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -36,7 +37,7 @@ end_per_testcase(_, _Config) -> all() -> [build_and_clean_app, run_hooks_once, run_hooks_once_profiles, escriptize_artifacts, run_hooks_for_plugins, deps_hook_namespace, - eunit_app_hooks]. + deps_clean_hook_namespace, eunit_app_hooks]. %% Test post provider hook cleans compiled project app, leaving it invalid build_and_clean_app(Config) -> @@ -134,6 +135,28 @@ deps_hook_namespace(Config) -> {ok, [{dep, "some_dep"}]} ). +deps_clean_hook_namespace(Config) -> + mock_git_resource:mock([{deps, [{some_dep, "0.0.1"}]}]), + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", []}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + RebarConfig = [ + {deps, TopDeps}, + {overrides, [ + {override, some_dep, [ + {provider_hooks, [ + {pre, [ + {compile, clean} + ]} + ]} + ]} + ]} + ], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["clean"], + {ok, [{dep, "some_dep"}]} + ). + %% Checks that a hook that is defined on an app (not a top level hook of a project with subapps) is run eunit_app_hooks(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From cc70e4fe2ff7b3e318d353972021e548fc513440 Mon Sep 17 00:00:00 2001 From: Tobias Schlager Date: Wed, 24 Jan 2018 12:12:40 +0100 Subject: Issue #1704: Fix alias provider argument passing The way arguments are passed by the alias provider is not compatible with all rebar providers/commands. Especially the release (relx) provider does not like getting its arguments as a plain string. It expects its arguments in a pre-parsed format as returned by getopt:parse/2. Other commands, e.g. eunit, seem to be fine with both ways of argument passing. Therefore, this fix changes the alias provider argument passing to the getopt format in general. --- test/rebar_alias_SUITE.erl | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_alias_SUITE.erl b/test/rebar_alias_SUITE.erl index f889ae4..2544aac 100644 --- a/test/rebar_alias_SUITE.erl +++ b/test/rebar_alias_SUITE.erl @@ -13,7 +13,7 @@ init_per_testcase(_, Config) -> end_per_testcase(_, _Config) -> ok. -all() -> [command, args, many, override_default, no_circular]. +all() -> [command, args, many, override_default, no_circular, release]. %% namespaces: unsupported, untested. command() -> @@ -111,3 +111,28 @@ no_circular(Config) -> {error, [$C,$o,$m,$m,$a,$n,$d,$ ,"test",$ ,$n,$o,$t,$ , $f,$o,$u,$n,$d]}), ok. + +release() -> + [{doc, "An alias for a release command"}]. +release(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("alias_release_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{relx, + [{release, {skipped_release, Vsn}, []}, + {release, {the_release, Vsn}, [list_to_atom(Name)]}, + {lib_dirs, [AppDir]}]}, + {alias, + [{the_rel1, [clean, {release, "-n the_release"}]}, + {the_rel2, [clean, {release, "--relname=the_release"}]}]}], + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["the_rel1"], + {ok, [{release, the_release, Vsn, false}]}), + rebar_test_utils:run_and_check( + Config, RebarConfig, + ["the_rel2"], + {ok, [{release, the_release, Vsn, false}]}), + ok. -- cgit v1.1 From 8229d15b6c8384e8d974b32d587b05d64fce185b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 26 Feb 2018 15:31:42 -0800 Subject: rebar_package: do not return first package version for constraint with no match --- test/rebar_pkg_SUITE.erl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index 32873c8..8ddf58f 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -226,7 +226,12 @@ find_highest_matching(_Config) -> ?assertEqual(<<"1.1.1">>, Vsn1), {ok, Vsn2} = rebar_packages:find_highest_matching( <<"test">>, <<"1.0.0">>, <<"goodpkg">>, <<"2.0">>, package_index, State), - ?assertEqual(<<"2.0.0">>, Vsn2). + ?assertEqual(<<"2.0.0">>, Vsn2), + + %% regression test. ~> constraints higher than the available packages would result + %% in returning the first package version instead of 'none'. + ?assertEqual(none, rebar_packages:find_highest_matching(<<"test">>, <<"1.0.0">>, <<"goodpkg">>, + <<"~> 5.0">>, package_index, State)). %%%%%%%%%%%%%%% @@ -267,6 +272,9 @@ mock_config(Name, Config) -> meck:expect(rebar_packages, package_dir, fun(_) -> {ok, CacheDir} end), rebar_prv_update:hex_to_index(rebar_state:new()), + meck:new(rebar_prv_update, [passthrough]), + meck:expect(rebar_prv_update, do, fun(State) -> {ok, State} end), + %% Cache fetches are mocked -- we assume the server and clients are %% correctly used. GoodCache = ?config(good_cache, Config), -- cgit v1.1 From abad0e14bb5a6ea5df21f2732bd72bf6efb0ca1e Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Fri, 23 Feb 2018 04:07:24 +0100 Subject: sort-as: show issue more clearly --- test/rebar_profiles_SUITE.erl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 6afdc39..9f7912d 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -28,7 +28,8 @@ test_profile_erl_opts_order_4/1, test_profile_erl_opts_order_5/1, test_erl_opts_debug_info/1, - first_files_exception/1]). + first_files_exception/1, + deduplication_stability/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -52,7 +53,8 @@ all() -> test_profile_erl_opts_order_4, test_profile_erl_opts_order_5, test_erl_opts_debug_info, - first_files_exception]. + first_files_exception, + deduplication_stability]. init_per_suite(Config) -> application:start(meck), @@ -133,7 +135,7 @@ profile_merge_umbrella_keys(Config) -> {profiles, [{ct, [{vals, [{a,1},{b,2}]}]}]}], - + SubRebarConfig = [{vals, []}, {profiles, [{ct, [{vals, [{c,1}]}]}]}], @@ -546,6 +548,17 @@ first_files_exception(_Config) -> ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, mib_first_files)), ok. +deduplication_stability(_Config) -> + ?assertEqual([default,all_deps_test], rebar_state:deduplicate([default,all_deps_test])), + ?assertEqual([default,profile1,profile2], rebar_state:deduplicate([default,profile1,profile2])), + ?assertEqual([default,bar,foo], rebar_state:deduplicate([default,bar,foo,bar])), %% master wants [default,foo,bar] + ?assertEqual([default,test,bar], rebar_state:deduplicate([default,test,bar])), + ?assertEqual([default,test,bar], rebar_state:deduplicate([default,test,bar,test])), + ?assertEqual([default,profile1], rebar_state:deduplicate([default,profile1,profile1,profile1])), + ?assertEqual([default,a,b,c,d,e], rebar_state:deduplicate([default,a,b,c,d,e,a,e,b])), + ?assertEqual([default,test], rebar_state:deduplicate([default,test])), + ok. + get_compiled_profile_erl_opts(Profiles, Config) -> AppDir = ?config(apps, Config), PStrs = [atom_to_list(P) || P <- Profiles], -- cgit v1.1 From 6aeff6300bf8986079ac6e8f83fa37150e239810 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Fri, 23 Feb 2018 12:50:29 +0100 Subject: Revert "sort-as: show issue more clearly" This reverts commit 4ad1db97336a3ac070880876ada07d4c7b769327. --- test/rebar_profiles_SUITE.erl | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 9f7912d..6afdc39 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -28,8 +28,7 @@ test_profile_erl_opts_order_4/1, test_profile_erl_opts_order_5/1, test_erl_opts_debug_info/1, - first_files_exception/1, - deduplication_stability/1]). + first_files_exception/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -53,8 +52,7 @@ all() -> test_profile_erl_opts_order_4, test_profile_erl_opts_order_5, test_erl_opts_debug_info, - first_files_exception, - deduplication_stability]. + first_files_exception]. init_per_suite(Config) -> application:start(meck), @@ -135,7 +133,7 @@ profile_merge_umbrella_keys(Config) -> {profiles, [{ct, [{vals, [{a,1},{b,2}]}]}]}], - + SubRebarConfig = [{vals, []}, {profiles, [{ct, [{vals, [{c,1}]}]}]}], @@ -548,17 +546,6 @@ first_files_exception(_Config) -> ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, mib_first_files)), ok. -deduplication_stability(_Config) -> - ?assertEqual([default,all_deps_test], rebar_state:deduplicate([default,all_deps_test])), - ?assertEqual([default,profile1,profile2], rebar_state:deduplicate([default,profile1,profile2])), - ?assertEqual([default,bar,foo], rebar_state:deduplicate([default,bar,foo,bar])), %% master wants [default,foo,bar] - ?assertEqual([default,test,bar], rebar_state:deduplicate([default,test,bar])), - ?assertEqual([default,test,bar], rebar_state:deduplicate([default,test,bar,test])), - ?assertEqual([default,profile1], rebar_state:deduplicate([default,profile1,profile1,profile1])), - ?assertEqual([default,a,b,c,d,e], rebar_state:deduplicate([default,a,b,c,d,e,a,e,b])), - ?assertEqual([default,test], rebar_state:deduplicate([default,test])), - ok. - get_compiled_profile_erl_opts(Profiles, Config) -> AppDir = ?config(apps, Config), PStrs = [atom_to_list(P) || P <- Profiles], -- cgit v1.1 From cfe6dfcca5d6526d835531a81cb5bdc1a21c17b3 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Fri, 23 Feb 2018 13:08:02 +0100 Subject: sort-as: bar profile specializes dep "b" into a version anterior to what test profile wants --- test/rebar_profiles_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index 6afdc39..ddc3cf1 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -211,7 +211,7 @@ implicit_profile_deduplicate_deps(Config) -> rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "test,bar", "eunit"], {ok, [{app, Name} ,{dep, "a", "1.0.0"} - ,{dep, "b", "2.0.0"}]}). + ,{dep, "b", "1.0.0"}]}). all_deps_code_paths(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From a03da56fb39bddcf6b5ef75cb5b5e40b5b5ab1d9 Mon Sep 17 00:00:00 2001 From: Laszlo Toth Date: Wed, 11 Apr 2018 14:03:57 +0200 Subject: (#1743): store the etags in cache files --- test/rebar_pkg_SUITE.erl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index 8ddf58f..9ddd704 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -9,6 +9,7 @@ -define(good_etag, "22e1d7387c9085a462340088a2a8ba67"). -define(bad_checksum, <<"D576B442A68C7B92BACDE1EFE9C6E54D8D6C74BDB71D8175B9D3C6EC8C7B62A7">>). -define(good_checksum, <<"1C6CE379D191FBAB41B7905075E0BF87CBBE23C77CECE775C5A0B786B2244C35">>). +-define(BADPKG_ETAG, <<"BADETAG">>). all() -> [good_uncached, good_cached, badindexchk, badpkg, badhash_nocache, badhash_cache, @@ -83,7 +84,7 @@ init_per_testcase(bad_to_good=Name, Config0) -> Config; init_per_testcase(good_disconnect=Name, Config0) -> Pkg = {<<"goodpkg">>, <<"1.0.0">>}, - Config1 = [{good_cache, true}, + Config1 = [{good_cache, false}, {pkg, Pkg} | Config0], Config = mock_config(Name, Config1), @@ -147,11 +148,15 @@ badpkg(Config) -> Tmp = ?config(tmp_dir, Config), {Pkg,Vsn} = ?config(pkg, Config), State = ?config(state, Config), - ?assertMatch({bad_download, _Path}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), - %% The cached file is there for forensic purposes Cache = ?config(cache_dir, Config), - ?assert(filelib:is_regular(filename:join(Cache, <>))). + CachePath = filename:join(Cache, <>), + ETagPath = filename:join(Cache, <>), + rebar_pkg_resource:store_etag_in_cache(ETagPath, ?BADPKG_ETAG), + ?assertMatch({bad_download, _Path}, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State, false)), + %% The cached/etag files are there for forensic purposes + ?assert(filelib:is_regular(ETagPath)), + ?assert(filelib:is_regular(CachePath)). badhash_nocache(Config) -> Tmp = ?config(tmp_dir, Config), @@ -196,8 +201,10 @@ good_disconnect(Config) -> State = ?config(state, Config), Cache = ?config(cache_dir, Config), CachedFile = filename:join(Cache, <>), + ETagFile = filename:join(Cache, <>), ?assert(filelib:is_regular(CachedFile)), {ok, Content} = file:read_file(CachedFile), + rebar_pkg_resource:store_etag_in_cache(ETagFile, ?BADPKG_ETAG), ?assertEqual({ok, true}, rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), {ok, Content} = file:read_file(CachedFile). -- cgit v1.1 From 088c47ad1d1f23650dc7bdc3d10659b9a223abb8 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 20 Apr 2018 18:49:44 -0400 Subject: Add proxy auto-scheme test --- test/rebar_utils_SUITE.erl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index 8b8769b..e4a5bd3 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -275,11 +275,13 @@ tup_merge(_Config) -> ) ). -proxy_auth(_Config) -> - proxy_auth(_Config, "http_proxy"), - proxy_auth(_Config, "https_proxy"). +proxy_auth(Config) -> + proxy_auth(Config, "http://", "http_proxy"), + proxy_auth(Config, "https://", "https_proxy"), + proxy_auth(Config, "", "http_proxy"), + proxy_auth(Config, "", "https_proxy"). -proxy_auth(_Config, ProxyEnvKey) -> +proxy_auth(_Config, Schema, ProxyEnvKey) -> Host = "host:", Port = "1234", @@ -291,13 +293,13 @@ proxy_auth(_Config, ProxyEnvKey) -> ?assertEqual([], rebar_utils:get_proxy_auth()), %% proxy auth with regular username/password - os:putenv(ProxyEnvKey, "http://Username:Password@" ++ Host ++ Port), + os:putenv(ProxyEnvKey, Schema++"Username:Password@" ++ Host ++ Port), rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"Username", "Password"}}], rebar_utils:get_proxy_auth()), %% proxy auth with username missing and url encoded password - os:putenv(ProxyEnvKey, "http://:%3F!abc%23%24@" ++ Host ++ Port), + os:putenv(ProxyEnvKey, Schema++":%3F!abc%23%24@" ++ Host ++ Port), rebar_utils:set_httpc_options(), ?assertEqual([{proxy_auth, {"", "?!abc#$"}}], rebar_utils:get_proxy_auth()), -- cgit v1.1 From 543fe579a6d7c71fb4ed6a898540b573f6255dd0 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 20 Apr 2018 21:03:05 -0400 Subject: Fix precedence rules of erl_opts for test profile When adding the 'TEST' macro to the test profile, we mistakenly sourced the erl_opts values from the base profile rather than the test profile itself. This means that in cases where the base profile set an option such as 'no_debug_info' and a profile overrode it with 'debug_info', the default options would get injected within the test profile, and broke the precedence rules, yielding incompatible values. This patch fixes things by adding the macro to the values sourced from the test profile itself, fixing the issue. --- test/rebar_profiles_SUITE.erl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'test') diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl index ddc3cf1..512832a 100644 --- a/test/rebar_profiles_SUITE.erl +++ b/test/rebar_profiles_SUITE.erl @@ -28,6 +28,7 @@ test_profile_erl_opts_order_4/1, test_profile_erl_opts_order_5/1, test_erl_opts_debug_info/1, + test_profile_erl_opts_precedence/1, first_files_exception/1]). -include_lib("common_test/include/ct.hrl"). @@ -52,6 +53,7 @@ all() -> test_profile_erl_opts_order_4, test_profile_erl_opts_order_5, test_erl_opts_debug_info, + test_profile_erl_opts_precedence, first_files_exception]. init_per_suite(Config) -> @@ -527,6 +529,36 @@ test_erl_opts_debug_info(_Config) -> no_debug_info,b,c,{debug_info,{mod,"123"}}])), ok. +test_profile_erl_opts_precedence(Config) -> + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("profile_new_key_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{erl_opts, [no_debug_info]}, + {profiles, [ + {test, [{erl_opts, [debug_info, {d,'HI'}]}]}, + {other, [{erl_opts, [debug_info, {d,'HI'}]}]} + ]}], + {ok, State1} = rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "test", "compile"], return + ), + {ok, State2} = rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "other", "compile"], return + ), + {ok, State3} = rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], return + ), + Opts1 = rebar_state:opts(State1), + Opts2 = rebar_state:opts(State2), + Opts3 = rebar_state:opts(State3), + ErlOpts1 = rebar_opts:erl_opts(Opts1), + ErlOpts2 = rebar_opts:erl_opts(Opts2), + ErlOpts3 = rebar_opts:erl_opts(Opts3), + ?assertEqual([{d,'TEST'}, debug_info, {d,'HI'}], ErlOpts1), + ?assertEqual([debug_info, {d,'HI'}], ErlOpts2), + ?assertEqual([], ErlOpts3), + ok. + first_files_exception(_Config) -> RebarConfig = [{erl_first_files, ["c","a","b"]}, {mib_first_files, ["c","a","b"]}, -- cgit v1.1 From 288d0c7484ba9214cc6598100000bcce0fefe462 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 23 Apr 2018 13:38:37 -0400 Subject: Clear all dialyzer errors - this is done by adding a HiPE dependency - also in this: adding a test for directories, and fixing some indent --- test/rebar_dir_SUITE.erl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 4743865..0eda5bf 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -5,6 +5,7 @@ -export([default_src_dirs/1, default_extra_src_dirs/1, default_all_src_dirs/1]). -export([src_dirs/1, src_dirs_with_opts/1, extra_src_dirs/1, all_src_dirs/1]). -export([src_dir_opts/1, recursive/1]). +-export([top_src_dirs/1]). -export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]). -export([profile_src_dir_opts/1]). -export([retarget_path/1, alt_base_dir_abs/1, alt_base_dir_rel/1]). @@ -18,7 +19,7 @@ all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs, src_dirs, extra_src_dirs, all_src_dirs, src_dir_opts, recursive, profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs, - profile_src_dir_opts, + profile_src_dir_opts, top_src_dirs, retarget_path, alt_base_dir_abs, alt_base_dir_rel, global_cache_dir, default_global_cache_dir, overwrite_default_global_cache_dir]. @@ -123,6 +124,15 @@ recursive(Config) -> ok. +top_src_dirs(Config) -> + %% We can get the same result out of specifying src_dirs from the config root, + %% not just the erl_opts + RebarConfig = [{src_dirs, ["foo", "./bar", "bar", "bar/", "./bar/", "baz", + "./", ".", "../", "..", "./../", "../.", ".././../"]}], + {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return), + + [".", "..", "../..", "bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). + profile_src_dirs(Config) -> RebarConfig = [ {erl_opts, [{src_dirs, ["foo", "bar"]}]}, -- cgit v1.1 From c22fde17a7a30cee5e3e5e04fab187eed2ecfe42 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 23 Apr 2018 22:34:40 +0300 Subject: fix & test --- test/rebar_dir_SUITE.erl | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index 4743865..e544410 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -3,7 +3,7 @@ -export([all/0, init_per_testcase/2, end_per_testcase/2]). -export([default_src_dirs/1, default_extra_src_dirs/1, default_all_src_dirs/1]). --export([src_dirs/1, src_dirs_with_opts/1, extra_src_dirs/1, all_src_dirs/1]). +-export([src_dirs/1, alt_src_dir_nested/1, src_dirs_with_opts/1, extra_src_dirs/1, all_src_dirs/1]). -export([src_dir_opts/1, recursive/1]). -export([profile_src_dirs/1, profile_extra_src_dirs/1, profile_all_src_dirs/1]). -export([profile_src_dir_opts/1]). @@ -16,7 +16,7 @@ all() -> [default_src_dirs, default_extra_src_dirs, default_all_src_dirs, - src_dirs, extra_src_dirs, all_src_dirs, src_dir_opts, recursive, + src_dirs, alt_src_dir_nested, extra_src_dirs, all_src_dirs, src_dir_opts, recursive, profile_src_dirs, profile_extra_src_dirs, profile_all_src_dirs, profile_src_dir_opts, retarget_path, alt_base_dir_abs, alt_base_dir_rel, global_cache_dir, @@ -74,6 +74,26 @@ src_dirs(Config) -> [".", "..", "../..", "bar", "baz", "foo"] = rebar_dir:src_dirs(rebar_state:opts(State)). +alt_src_dir_nested(Config) -> + RebarConfig = [{src_dirs, ["src", "alt/nested"]}], + AppsDir = ?config(apps, Config), + Name1 = ?config(app_one, Config), + Name2 = ?config(app_two, Config), + ModDir = filename:join([AppsDir, "apps", Name1, "alt", "nested"]), + ModDir2 = filename:join([AppsDir, "apps", Name2, "alt", "nested"]), + Mod = "-module(altmod). -export([main/0]). main() -> ok.", + + ec_file:mkdir_path(ModDir), + ec_file:mkdir_path(ModDir2), + ok = file:write_file(filename:join([ModDir, "altmod.erl"]), Mod), + + Ebin = filename:join([AppsDir, "_build", "default", "lib", Name1, "ebin", "altmod.beam"]), + {ok, State} = rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], + {ok, [{file, Ebin}]} + ), + ["alt/nested", "src"] = rebar_dir:src_dirs(rebar_state:opts(State)). + src_dirs_with_opts(Config) -> RebarConfig = [{erl_opts, [{src_dirs, ["foo", "bar", "baz"]}, {src_dirs, [{"foo",[{recursive,false}]}, "qux"]}]}], -- cgit v1.1 From 775261dd0b24d74e48f5873ef1ffff56c0c4829a Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 27 Apr 2018 09:32:39 -0400 Subject: Prevent copying or symlink non-existing src_dirs This would cause crashes on linux and force people to have a src_dirs config that is strictly matching what is on the file system rather than acting as a specification of those that are valid. To compare, if lib_dirs worked the same, then any repo that did not both have apps/ and lib/ would crash, as the spec mentions both options as valid. --- test/rebar_dir_SUITE.erl | 3 --- 1 file changed, 3 deletions(-) (limited to 'test') diff --git a/test/rebar_dir_SUITE.erl b/test/rebar_dir_SUITE.erl index f5ac0fc..81051e6 100644 --- a/test/rebar_dir_SUITE.erl +++ b/test/rebar_dir_SUITE.erl @@ -79,13 +79,10 @@ alt_src_dir_nested(Config) -> RebarConfig = [{src_dirs, ["src", "alt/nested"]}], AppsDir = ?config(apps, Config), Name1 = ?config(app_one, Config), - Name2 = ?config(app_two, Config), ModDir = filename:join([AppsDir, "apps", Name1, "alt", "nested"]), - ModDir2 = filename:join([AppsDir, "apps", Name2, "alt", "nested"]), Mod = "-module(altmod). -export([main/0]). main() -> ok.", ec_file:mkdir_path(ModDir), - ec_file:mkdir_path(ModDir2), ok = file:write_file(filename:join([ModDir, "altmod.erl"]), Mod), Ebin = filename:join([AppsDir, "_build", "default", "lib", Name1, "ebin", "altmod.beam"]), -- cgit v1.1 From e876b42a987486d1a25372edc810765b1a33d167 Mon Sep 17 00:00:00 2001 From: Alexander Petrovsky Date: Wed, 30 May 2018 18:06:08 +0300 Subject: Fix override_deps test from suite rebar_compile_SUITE --- test/rebar_compile_SUITE.erl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index c5336cf..34a1bc5 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1272,21 +1272,22 @@ clean_all(Config) -> {app, PkgName, invalid}]}). override_deps(Config) -> - mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]), Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), RebarConfig = [ {deps, TopDeps}, {overrides, [ {override, some_dep, [ - {deps, []} - ]} - ]} - ], + {deps, []} + ]} + ]} + ], rebar_test_utils:run_and_check( Config, RebarConfig, ["compile"], - {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]} + {ok, [{dep, "some_dep"}, {dep_not_exist, "other_dep"}]} ). profile_override_deps(Config) -> -- cgit v1.1 From ea50c24f61e084f0cd258d0bdb1b2117783a7dcb Mon Sep 17 00:00:00 2001 From: Alexander Petrovsky Date: Thu, 31 May 2018 17:32:33 +0300 Subject: Introduce support of add and del operations under erl_opts directive --- test/rebar_compile_SUITE.erl | 387 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 375 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 34a1bc5..6470b06 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -39,8 +39,18 @@ only_default_transitive_deps/1, clean_all/1, override_deps/1, - profile_override_deps/1, + override_add_deps/1, + override_del_deps/1, + override_opts/1, + override_add_opts/1, + override_del_opts/1, profile_deps/1, + profile_override_deps/1, + profile_override_add_deps/1, + profile_override_del_deps/1, + profile_override_opts/1, + profile_override_add_opts/1, + profile_override_del_opts/1, deps_build_in_prod/1, include_file_relative_to_working_directory/1, include_file_in_src/1, @@ -75,9 +85,12 @@ all() -> delete_beam_if_source_deleted, 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, deps_build_in_prod, - profile_override_deps, profile_deps, deps_build_in_prod, + umbrella_mib_first_test, only_default_transitive_deps, clean_all, + profile_deps, deps_build_in_prod, + override_deps, override_add_deps, override_del_deps, + override_opts, override_add_opts, override_del_opts, + profile_override_deps, profile_override_add_deps, profile_override_del_deps, + profile_override_opts, profile_override_add_opts, profile_override_del_opts, include_file_relative_to_working_directory, include_file_in_src, include_file_relative_to_working_directory_test, include_file_in_src_test, include_file_in_src_test_multiapp, @@ -1274,6 +1287,7 @@ clean_all(Config) -> override_deps(Config) -> Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), mock_git_resource:mock([{deps, SrcDeps}]), @@ -1287,30 +1301,379 @@ override_deps(Config) -> ], rebar_test_utils:run_and_check( Config, RebarConfig, ["compile"], - {ok, [{dep, "some_dep"}, {dep_not_exist, "other_dep"}]} + {ok, [{dep, "some_dep"}, + {dep_not_exist, "other_dep"}]} ). +override_add_deps(Config) -> + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + DepA = {dep_a, "0.0.1", {git, "http://site.com/dep_a.git", {tag, "0.0.1"}}}, + DepB = {dep_b, "0.0.1", {git, "http://site.com/dep_b.git", {tag, "0.0.1"}}}, + DepC = {dep_c, "0.0.1", {git, "http://site.com/dep_c.git", {tag, "0.0.1"}}}, + + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, [DepA, DepB, DepC | SrcDeps]}]), + + RebarConfig = [ + {deps, TopDeps}, + {overrides, [ + {add, some_dep, [ + {deps, [DepA, DepB]} + ]}, + {add, [ + {deps, [DepC]} + ]} + ]} + ], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], + {ok, [{dep, "some_dep"}, + {dep, "other_dep"}, + {dep, "dep_a"}, + {dep, "dep_b"}, + {dep, "dep_c"}]} + ). + +override_del_deps(Config) -> + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"dep_a", "0.0.1", []}, + {"dep_b", "0.0.1", []}, + {"dep_c", "0.0.1", []}]}, + {"other_dep", "0.0.1", [{"dep_c", "0.0.1", []}, + {"dep_d", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + DepA = {dep_a, "0.0.1", {git, "https://example.org/user/dep_a.git", {tag, "0.0.1"}}}, + DepB = {dep_b, "0.0.1", {git, "https://example.org/user/dep_b.git", {tag, "0.0.1"}}}, + DepC = {dep_c, "0.0.1", {git, "https://example.org/user/dep_c.git", {tag, "0.0.1"}}}, + + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), + + RebarConfig = [ + {deps, TopDeps}, + {overrides, [ + {del, some_dep, [ + {deps, [DepA, DepB]} + ]}, + {del, [ + {deps, [DepC]} + ]} + ]} + ], + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], + {ok, [{dep, "some_dep"}, + {dep, "other_dep"}, + {dep_not_exist, "dep_a"}, + {dep_not_exist, "dep_b"}, + {dep_not_exist, "dep_c"}, + {dep, "dep_d"}]} + ). + +override_opts(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]), + + RebarConfig = [ + {erl_opts, [ + compressed, + warn_missing_spec + ]}, + {overrides, [ + {override, [ + {erl_opts, [compressed]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + +override_add_opts(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]), + + RebarConfig = [ + {erl_opts, [ + warn_missing_spec + ]}, + {overrides, [ + {add, [ + {erl_opts, [compressed]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + true = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + +override_del_opts(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]), + + RebarConfig = [ + {erl_opts, [ + compressed, + warn_missing_spec + ]}, + {overrides, [ + {del, [ + {erl_opts, [warn_missing_spec]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + profile_override_deps(Config) -> Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), mock_git_resource:mock([{deps, SrcDeps}]), RebarConfig = [ {deps, TopDeps}, - {profiles, [{a, - [{overrides, [ - {override, some_dep, [ - {deps, []} - ]} - ]} + {profiles, [ + {a, [ + {overrides, [ + {override, some_dep, [ + {deps, []} ]} + ]} + ]} ]}], rebar_test_utils:run_and_check( Config, RebarConfig, ["as", "a", "compile"], - {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]} + {ok, [{dep, "some_dep"}, + {dep_not_exist, "other_dep"}]} ). +profile_override_add_deps(Config) -> + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + DepA = {dep_a, "0.0.1", {git, "http://site.com/dep_a.git", {tag, "0.0.1"}}}, + DepB = {dep_b, "0.0.1", {git, "http://site.com/dep_b.git", {tag, "0.0.1"}}}, + DepC = {dep_c, "0.0.1", {git, "http://site.com/dep_c.git", {tag, "0.0.1"}}}, + + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, [DepA, DepB, DepC | SrcDeps]}]), + + RebarConfig = [ + {deps, TopDeps}, + {profiles, [ + {a, [ + {overrides, [ + {add, some_dep, [ + {deps, [DepA, DepB]} + ]}, + {add, [ + {deps, [DepC]} + ]} + ]} + ]} + ]} + ], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], + {ok, [{dep, "some_dep"}, + {dep, "other_dep"}, + {dep, "dep_a"}, + {dep, "dep_b"}, + {dep, "dep_c"}]} + ). + +profile_override_del_deps(Config) -> + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"dep_a", "0.0.1", []}, + {"dep_b", "0.0.1", []}, + {"dep_c", "0.0.1", []}]}, + {"other_dep", "0.0.1", [{"dep_c", "0.0.1", []}, + {"dep_d", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + DepA = {dep_a, "0.0.1", {git, "https://example.org/user/dep_a.git", {tag, "0.0.1"}}}, + DepB = {dep_b, "0.0.1", {git, "https://example.org/user/dep_b.git", {tag, "0.0.1"}}}, + DepC = {dep_c, "0.0.1", {git, "https://example.org/user/dep_c.git", {tag, "0.0.1"}}}, + + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), + + RebarConfig = [ + {deps, TopDeps}, + {profiles, [ + {a, [ + {overrides, [ + {del, some_dep, [ + {deps, [DepA, DepB]} + ]}, + {del, [ + {deps, [DepC]} + ]} + ]} + ]} + ]} + ], + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], + {ok, [{dep, "some_dep"}, + {dep, "other_dep"}, + {dep_not_exist, "dep_a"}, + {dep_not_exist, "dep_b"}, + {dep_not_exist, "dep_c"}, + {dep, "dep_d"}]} + ). + +profile_override_opts(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]), + + RebarConfig = [ + {erl_opts, [ + compressed, + warn_missing_spec + ]}, + {profiles, [ + {a, [ + {overrides, [ + {override, [ + {erl_opts, [compressed]} + ]} + ]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "a", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + +profile_override_add_opts(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]), + + RebarConfig = [ + {erl_opts, [ + warn_missing_spec + ]}, + {profiles, [ + {a, [ + {overrides, [ + {add, [ + {erl_opts, [compressed]} + ]} + ]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "a", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + true = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + +profile_override_del_opts(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]), + + RebarConfig = [ + {erl_opts, [ + compressed, + warn_missing_spec + ]}, + {profiles, [ + {a, [ + {overrides, [ + {del, [ + {erl_opts, [warn_missing_spec]} + ]} + ]} + ]} + ]} + ], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "a", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). + profile_deps(Config) -> Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), TopDeps = rebar_test_utils:top_level_deps(Deps), -- cgit v1.1 From d1fc937515b312c1e5129e9e435e5b462f34b874 Mon Sep 17 00:00:00 2001 From: Bryan Paxton Date: Thu, 7 Jun 2018 11:11:11 -0500 Subject: Abort if erl_first_files is not a list of strings - resolves #1645 --- test/rebar_utils_SUITE.erl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index e4a5bd3..233fcff 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -32,7 +32,8 @@ blacklisted_otp_version/1, sh_does_not_miss_messages/1, tup_merge/1, - proxy_auth/1]). + proxy_auth/1, + is_list_of_strings/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -48,7 +49,7 @@ all() -> [{group, args_to_tasks}, sh_does_not_miss_messages, tup_merge, - proxy_auth]. + proxy_auth, is_list_of_strings]. groups() -> [{args_to_tasks, [], [empty_arglist, @@ -312,3 +313,9 @@ restore_proxy_env(ProxyEnvKey, false) -> os:putenv(ProxyEnvKey, ""); restore_proxy_env(ProxyEnvKey, ProxySpec) -> os:putenv(ProxyEnvKey, ProxySpec). + +is_list_of_strings(_Config) -> + ?assert(rebar_utils:is_list_of_strings(["foo"])), + ?assert(rebar_utils:is_list_of_strings([])), + ?assert(rebar_utils:is_list_of_strings("")), + ?assert(rebar_utils:is_list_of_strings("foo") == false). -- cgit v1.1 From a74dc021cc9dd89b7448d894e262ebe5a82285cd Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 8 Jun 2018 20:57:48 -0600 Subject: run compile provider in default namespace from bare --- test/rebar_hooks_SUITE.erl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index a36dbe1..1f3edd2 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -13,6 +13,7 @@ run_hooks_for_plugins/1, eunit_app_hooks/1, deps_hook_namespace/1, + bare_compile_hooks_default_ns/1, deps_clean_hook_namespace/1]). -include_lib("common_test/include/ct.hrl"). @@ -37,7 +38,7 @@ end_per_testcase(_, _Config) -> all() -> [build_and_clean_app, run_hooks_once, run_hooks_once_profiles, escriptize_artifacts, run_hooks_for_plugins, deps_hook_namespace, - deps_clean_hook_namespace, eunit_app_hooks]. + bare_compile_hooks_default_ns, deps_clean_hook_namespace, eunit_app_hooks]. %% Test post provider hook cleans compiled project app, leaving it invalid build_and_clean_app(Config) -> @@ -135,6 +136,22 @@ deps_hook_namespace(Config) -> {ok, [{dep, "some_dep"}]} ). +%% tests that hooks to compile when running bare compile run in the default namespace +bare_compile_hooks_default_ns(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]), + + RConfFile = rebar_test_utils:create_config(AppDir, + [{provider_hooks, [{post, [{compile, clean}]}]}]), + {ok, RConf} = file:consult(RConfFile), + rebar_test_utils:run_and_check( + Config, RConf, ["bare", "compile", "--paths", "."], + {ok, []} + ). + deps_clean_hook_namespace(Config) -> mock_git_resource:mock([{deps, [{some_dep, "0.0.1"}]}]), Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", []}]), -- cgit v1.1 From 56b7d88975aa8da6446857cfd92de0825024bf63 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Thu, 13 Sep 2018 19:36:00 -0600 Subject: support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message --- test/mock_git_resource.erl | 17 +- test/mock_pkg_resource.erl | 100 ++++-- test/rebar_compile_SUITE.erl | 95 ++--- test/rebar_deps_SUITE.erl | 130 ++++--- test/rebar_install_deps_SUITE.erl | 108 +++--- test/rebar_localfs_resource.erl | 8 +- test/rebar_localfs_resource_v2.erl | 50 +++ test/rebar_pkg_SUITE.erl | 148 ++++---- test/rebar_pkg_SUITE_data/badindexchk-1.0.0.tar | Bin 10240 -> 10240 bytes test/rebar_pkg_SUITE_data/badpkg-1.0.0.tar | Bin 10240 -> 10240 bytes test/rebar_pkg_SUITE_data/goodpkg-1.0.0.tar | Bin 10240 -> 10240 bytes test/rebar_pkg_alias_SUITE.erl | 108 ++++-- test/rebar_pkg_repos_SUITE.erl | 331 ++++++++++++++++++ test/rebar_resource_SUITE.erl | 9 +- test/rebar_test_utils.erl | 48 +-- test/rebar_upgrade_SUITE.erl | 442 ++++++++++++------------ 16 files changed, 1029 insertions(+), 565 deletions(-) create mode 100644 test/rebar_localfs_resource_v2.erl create mode 100644 test/rebar_pkg_repos_SUITE.erl (limited to 'test') diff --git a/test/mock_git_resource.erl b/test/mock_git_resource.erl index e922af3..5673349 100644 --- a/test/mock_git_resource.erl +++ b/test/mock_git_resource.erl @@ -27,7 +27,7 @@ mock(Opts) -> mock(Opts, create_app). mock(Opts, CreateType) -> - meck:new(?MOD, [no_link]), + meck:new(?MOD, [no_link, passthrough]), mock_lock(Opts), mock_update(Opts), mock_vsn(Opts), @@ -46,8 +46,8 @@ unmock() -> mock_lock(_) -> meck:expect( ?MOD, lock, - fun(_AppDir, Git) -> - case Git of + fun(AppInfo, _) -> + case rebar_app_info:source(AppInfo) of {git, Url, {tag, Ref}} -> {git, Url, {ref, Ref}}; {git, Url, {ref, Ref}} -> {git, Url, {ref, Ref}}; {git, Url} -> {git, Url, {ref, "0.0.0"}}; @@ -62,7 +62,8 @@ mock_update(Opts) -> % ct:pal("TOUp: ~p", [ToUpdate]), meck:expect( ?MOD, needs_update, - fun(_Dir, {git, Url, _Ref}) -> + fun(AppInfo, _) -> + {git, Url, _Ref} = rebar_app_info:source(AppInfo), App = app(Url), % ct:pal("Needed update? ~p (~p) -> ~p", [App, {Url,_Ref}, lists:member(App, ToUpdate)]), lists:member(App, ToUpdate) @@ -78,7 +79,8 @@ mock_vsn(Opts) -> Default = proplists:get_value(default_vsn, Opts, "0.0.0"), meck:expect( ?MOD, make_vsn, - fun(Dir) -> + fun(AppInfo, _) -> + Dir = rebar_app_info:dir(AppInfo), case filelib:wildcard("*.app.src", filename:join([Dir,"src"])) of [AppSrc] -> {ok, App} = file:consult(AppSrc), @@ -108,7 +110,8 @@ mock_download(Opts, CreateType) -> Overrides = proplists:get_value(override_vsn, Opts, []), meck:expect( ?MOD, download, - fun (Dir, Git, _) -> + fun (Dir, AppInfo, _, _) -> + Git = rebar_app_info:source(AppInfo), filelib:ensure_dir(Dir), {git, Url, {_, Vsn}} = normalize_git(Git, Overrides, Default), App = app(Url), @@ -118,7 +121,7 @@ mock_download(Opts, CreateType) -> [kernel, stdlib] ++ [element(1,D) || D <- AppDeps] ), rebar_test_utils:create_config(Dir, [{deps, AppDeps}]++Config), - {ok, 'WHATEVER'} + ok end). %%%%%%%%%%%%%%% diff --git a/test/mock_pkg_resource.erl b/test/mock_pkg_resource.erl index 5769988..9a31461 100644 --- a/test/mock_pkg_resource.erl +++ b/test/mock_pkg_resource.erl @@ -3,6 +3,8 @@ -export([mock/0, mock/1, unmock/0]). -define(MOD, rebar_pkg_resource). +-include("rebar.hrl"). + %%%%%%%%%%%%%%%%% %%% Interface %%% %%%%%%%%%%%%%%%%% @@ -26,7 +28,7 @@ mock() -> mock([]). Vsn :: string(), Hash :: string() | undefined. mock(Opts) -> - meck:new(?MOD, [no_link]), + meck:new(?MOD, [no_link, passthrough]), mock_lock(Opts), mock_update(Opts), mock_vsn(Opts), @@ -44,7 +46,10 @@ unmock() -> %% @doc creates values for a lock file. mock_lock(_) -> - meck:expect(?MOD, lock, fun(_AppDir, Source) -> Source end). + meck:expect(?MOD, lock, fun(AppInfo, _) -> + {pkg, Name, Vsn, Hash, _RepoConfig} = rebar_app_info:source(AppInfo), + {pkg, Name, Vsn, Hash} + end). %% @doc The config passed to the `mock/2' function can specify which apps %% should be updated on a per-name basis: `{update, ["App1", "App3"]}'. @@ -52,7 +57,8 @@ mock_update(Opts) -> ToUpdate = proplists:get_value(upgrade, Opts, []), meck:expect( ?MOD, needs_update, - fun(_Dir, {pkg, App, _Vsn, _Hash}) -> + fun(AppInfo, _) -> + {pkg, App, _Vsn, _Hash, _} = rebar_app_info:source(AppInfo), lists:member(binary_to_list(App), ToUpdate) end). @@ -60,7 +66,7 @@ mock_update(Opts) -> mock_vsn(_Opts) -> meck:expect( ?MOD, make_vsn, - fun(_Dir) -> + fun(_AppInfo, _) -> {error, "Replacing version of type pkg not supported."} end). @@ -77,30 +83,32 @@ mock_download(Opts) -> Config = proplists:get_value(config, Opts, []), meck:expect( ?MOD, download, - fun (Dir, {pkg, AppBin, Vsn, _}, _) -> - App = binary_to_list(AppBin), + fun (Dir, AppInfo, _, _) -> + {pkg, AppBin, Vsn, _, _} = rebar_app_info:source(AppInfo), + App = rebar_utils:to_list(AppBin), filelib:ensure_dir(Dir), AppDeps = proplists:get_value({App,Vsn}, Deps, []), - {ok, AppInfo} = rebar_test_utils:create_app( - Dir, App, binary_to_list(Vsn), + {ok, AppInfo1} = rebar_test_utils:create_app( + Dir, App, rebar_utils:to_list(Vsn), [kernel, stdlib] ++ [element(1,D) || D <- AppDeps] ), rebar_test_utils:create_config(Dir, [{deps, AppDeps}]++Config), - TarApp = App++"-"++binary_to_list(Vsn)++".tar", - Tarball = filename:join([Dir, TarApp]), - Contents = filename:join([Dir, "contents.tar.gz"]), - Files = all_files(rebar_app_info:dir(AppInfo)), - ok = erl_tar:create(Contents, - archive_names(Dir, App, Vsn, Files), - [compressed]), - ok = erl_tar:create(Tarball, - [{"contents.tar.gz", Contents}], - []), + + TarApp = App++"-"++rebar_utils:to_list(Vsn)++".tar", + + Metadata = #{<<"app">> => AppBin, + <<"version">> => Vsn}, + + Files = all_files(rebar_app_info:dir(AppInfo1)), + {ok, {Tarball, _Checksum}} = hex_tarball:create(Metadata, archive_names(Dir, Files)), + Archive = filename:join([Dir, TarApp]), + file:write_file(Archive, Tarball), + Cache = proplists:get_value(cache_dir, Opts, filename:join(Dir,"cache")), Cached = filename:join([Cache, TarApp]), filelib:ensure_dir(Cached), - rebar_file_utils:mv(Tarball, Cached), - {ok, true} + rebar_file_utils:mv(Archive, Cached), + ok end). %% @doc On top of the pkg resource mocking, we need to mock the package @@ -110,16 +118,18 @@ mock_download(Opts) -> %% specific applications otherwise listed. mock_pkg_index(Opts) -> Deps = proplists:get_value(pkgdeps, Opts, []), + Repos = proplists:get_value(repos, Opts, [<<"hexpm">>]), Skip = proplists:get_value(not_in_index, Opts, []), %% Dict: {App, Vsn}: [{<<"link">>, <<>>}, {<<"deps">>, []}] %% Index: all apps and deps in the index Dict = find_parts(Deps, Skip), + to_index(Deps, Dict, Repos), meck:new(rebar_packages, [passthrough, no_link]), - meck:expect(rebar_packages, packages, - fun(_State) -> to_index(Deps, Dict) end), + meck:expect(rebar_packages, update_package, + fun(_, _, _State) -> ok end), meck:expect(rebar_packages, verify_table, - fun(_State) -> to_index(Deps, Dict), true end). + fun(_State) -> true end). %%%%%%%%%%%%%%% %%% Helpers %%% @@ -128,7 +138,7 @@ mock_pkg_index(Opts) -> all_files(Dir) -> filelib:wildcard(filename:join([Dir, "**"])). -archive_names(Dir, _App, _Vsn, Files) -> +archive_names(Dir, Files) -> [{(F -- Dir) -- "/", F} || F <- Files]. find_parts(Apps, Skip) -> find_parts(Apps, Skip, dict:new()). @@ -143,24 +153,42 @@ find_parts([{AppName, Deps}|Rest], Skip, Acc) -> Acc), find_parts(Rest, Skip, AccNew) end. +parse_deps(Deps) -> + [{maps:get(app, D, Name), {pkg, Name, Constraint, undefined}} || D=#{package := Name, + requirement := Constraint} <- Deps]. + +to_index(AllDeps, Dict, Repos) -> + catch ets:delete(?PACKAGE_TABLE), + rebar_packages:new_package_table(), -to_index(AllDeps, Dict) -> - catch ets:delete(package_index), - ets:new(package_index, [named_table, public]), dict:fold( - fun(K, Deps, _) -> - DepsList = [{DKB, {pkg, DKB, DVB, undefined}} + fun({N, V}, Deps, _) -> + DepsList = [#{package => DKB, + app => DKB, + requirement => DVB, + source => {pkg, DKB, DVB, undefined}} || {DK, DV} <- Deps, DKB <- [ec_cnv:to_binary(DK)], DVB <- [ec_cnv:to_binary(DV)]], - ets:insert(package_index, {K, DepsList, <<"checksum">>}) + Repo = rebar_test_utils:random_element(Repos), + ets:insert(?PACKAGE_TABLE, #package{key={N, V, Repo}, + dependencies=parse_deps(DepsList), + retired=false, + checksum = <<"checksum">>}) end, ok, Dict), - ets:insert(package_index, {package_index_version, 3}), + lists:foreach(fun({{Name, Vsn}, _}) -> - case ets:lookup(package_index, ec_cnv:to_binary(Name)) of - [{_, Vsns}] -> - ets:insert(package_index, {ec_cnv:to_binary(Name), [ec_cnv:to_binary(Vsn) | Vsns]}); - _ -> - ets:insert(package_index, {ec_cnv:to_binary(Name), [ec_cnv:to_binary(Vsn)]}) + case lists:any(fun(R) -> + ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(Name), Vsn, R}) + end, Repos) of + false -> + Repo = rebar_test_utils:random_element(Repos), + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(Name), Vsn, Repo}, + dependencies=[], + retired=false, + checksum = <<"checksum">>}); + true -> + ok end end, AllDeps). + diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 6470b06..10effda 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1,69 +1,6 @@ -module(rebar_compile_SUITE). --export([suite/0, - init_per_suite/1, - end_per_suite/1, - init_per_testcase/2, - end_per_testcase/2, - init_per_group/2, - end_per_group/2, - all/0, - groups/0, - build_basic_app/1, paths_basic_app/1, clean_basic_app/1, - build_release_apps/1, paths_release_apps/1, clean_release_apps/1, - build_checkout_apps/1, paths_checkout_apps/1, - build_checkout_deps/1, paths_checkout_deps/1, - build_basic_srcdirs/1, paths_basic_srcdirs/1, - build_release_srcdirs/1, paths_release_srcdirs/1, - build_unbalanced_srcdirs/1, paths_unbalanced_srcdirs/1, - build_basic_extra_dirs/1, paths_basic_extra_dirs/1, clean_basic_extra_dirs/1, - build_release_extra_dirs/1, paths_release_extra_dirs/1, clean_release_extra_dirs/1, - build_unbalanced_extra_dirs/1, paths_unbalanced_extra_dirs/1, - build_extra_dirs_in_project_root/1, - paths_extra_dirs_in_project_root/1, - clean_extra_dirs_in_project_root/1, - recompile_when_hrl_changes/1, - recompile_when_included_hrl_changes/1, - recompile_when_opts_included_hrl_changes/1, - recompile_when_opts_change/1, - dont_recompile_when_opts_dont_change/1, - dont_recompile_yrl_or_xrl/1, - deps_in_path/1, - delete_beam_if_source_deleted/1, - checkout_priority/1, - highest_version_of_pkg_dep/1, - parse_transform_test/1, - erl_first_files_test/1, - mib_test/1, - umbrella_mib_first_test/1, - only_default_transitive_deps/1, - clean_all/1, - override_deps/1, - override_add_deps/1, - override_del_deps/1, - override_opts/1, - override_add_opts/1, - override_del_opts/1, - profile_deps/1, - profile_override_deps/1, - profile_override_add_deps/1, - profile_override_del_deps/1, - profile_override_opts/1, - profile_override_add_opts/1, - profile_override_del_opts/1, - deps_build_in_prod/1, - include_file_relative_to_working_directory/1, - include_file_in_src/1, - include_file_relative_to_working_directory_test/1, - include_file_in_src_test/1, - include_file_in_src_test_multiapp/1, - dont_recompile_when_erl_compiler_options_env_does_not_change/1, - recompile_when_erl_compiler_options_env_changes/1, - always_recompile_when_erl_compiler_options_set/1, - recompile_when_parse_transform_inline_changes/1, - recompile_when_parse_transform_as_opt_changes/1, - recursive/1,no_recursive/1, - regex_filter_skip/1, regex_filter_regression/1]). +-compile(export_all). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -89,6 +26,7 @@ all() -> profile_deps, deps_build_in_prod, override_deps, override_add_deps, override_del_deps, override_opts, override_add_opts, override_del_opts, + apply_overrides_exactly_once, profile_override_deps, profile_override_add_deps, profile_override_del_deps, profile_override_opts, profile_override_add_opts, profile_override_del_opts, include_file_relative_to_working_directory, include_file_in_src, @@ -1405,6 +1343,35 @@ override_opts(Config) -> true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])). +%% test for fix of https://github.com/erlang/rebar3/issues/1801 +%% only apply overrides once +%% verify by having an override add the macro TEST to the dep some_dep +%% building under `ct` will fail if the `add` is applied more than once +apply_overrides_exactly_once(Config) -> + AppDir = ?config(apps, Config), + + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), + + 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]), + + RebarConfig = [{deps, TopDeps}, + {overrides, [ + {add, some_dep, [ + {erl_opts, [{d, 'TEST'}]} + ]} + ]}], + + rebar_test_utils:create_config(AppDir, RebarConfig), + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["ct", "--compile_only"], {ok, [{app, Name}, {dep, "some_dep"}], "test"}). + override_add_opts(Config) -> AppDir = ?config(apps, Config), diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index ae50ea3..8a3362d 100644 --- a/test/rebar_deps_SUITE.erl +++ b/test/rebar_deps_SUITE.erl @@ -188,27 +188,27 @@ deps(flat) -> [], {ok, ["B", "C"]}}; deps(pick_highest_left) -> - {[{"B", [{"C", "2", []}]}, - {"C", "1", []}], - [{"C","2"}], - {ok, ["B", {"C", "1"}]}}; + {[{"B", [{"C", "2.0.0", []}]}, + {"C", "1.0.0", []}], + [{"C","2.0.0"}], + {ok, ["B", {"C", "1.0.0"}]}}; deps(pick_highest_right) -> - {[{"B", "1", []}, - {"C", [{"B", "2", []}]}], - [{"B","2"}], - {ok, [{"B","1"}, "C"]}}; + {[{"B", "1.0.0", []}, + {"C", [{"B", "2.0.0", []}]}], + [{"B","2.0.0"}], + {ok, [{"B","1.0.0"}, "C"]}}; deps(pick_smallest1) -> - {[{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}], - [{"D","2"}], + {[{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}], + [{"D","2.0.0"}], %% we pick D1 because B < C - {ok, ["B","C",{"D","1"}]}}; + {ok, ["B","C",{"D","1.0.0"}]}}; deps(pick_smallest2) -> - {[{"C", [{"D", "2", []}]}, - {"B", [{"D", "1", []}]}], - [{"D","2"}], + {[{"C", [{"D", "2.0.0", []}]}, + {"B", [{"D", "1.0.0", []}]}], + [{"D","2.0.0"}], %% we pick D1 because B < C - {ok, ["B","C",{"D","1"}]}}; + {ok, ["B","C",{"D","1.0.0"}]}}; deps(circular1) -> {[{"B", [{"A", []}]}, % A is the top-level app {"C", []}], @@ -222,15 +222,17 @@ deps(circular2) -> deps(circular_skip) -> %% Never spot the circular dep due to being to low in the deps tree %% in source deps - {[{"B", [{"C", "2", [{"B", []}]}]}, - {"C", "1", [{"D",[]}]}], - [{"C","2"}], - {ok, ["B", {"C","1"}, "D"]}}. + {[{"B", [{"C", "2.0.0", [{"B", []}]}]}, + {"C", "1.0.0", [{"D",[]}]}], + [{"C","2.0.0"}], + {ok, ["B", {"C","1.0.0"}, "D"]}}. setup_project(Case, Config0, Deps) -> DepsType = ?config(deps_type, Config0), + %% spread packages across 3 repos randomly + Repos = [<<"test-repo-1">>, <<"test-repo-2">>, <<"hexpm">>], Config = rebar_test_utils:init_rebar_state( - Config0, + [{repos, Repos} | Config0], atom_to_list(Case)++"_"++atom_to_list(DepsType)++"_" ), AppDir = ?config(apps, Config), @@ -239,7 +241,7 @@ setup_project(Case, Config0, Deps) -> RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]), {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps), mock_git_resource:mock([{deps, SrcDeps}]), - mock_pkg_resource:mock([{pkgdeps, PkgDeps}]), + mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {repos, Repos}]), [{rebarconfig, RebarConf} | Config]. mock_warnings() -> @@ -412,70 +414,62 @@ https_os_proxy_settings(_Config) -> httpc:get_option(https_proxy, rebar)). semver_matching_lt(_Config) -> - Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, {pkg, Dep, <<"0.1.9">>, undefined}}], - rebar_prv_update:cmpl_(undefined, MaxVsn, Vsns, [], Dep1, + ?assertEqual({ok, <<"0.1.9">>}, + rebar_packages:cmpl_(undefined, MaxVsn, Vsns, fun ec_semver:lt/2)). semver_matching_lte(_Config) -> - Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, {pkg, Dep, <<"0.2.0">>, undefined}}], - rebar_prv_update:cmpl_(undefined, MaxVsn, Vsns, [], Dep1, + ?assertEqual({ok, <<"0.2.0">>}, + rebar_packages:cmpl_(undefined, MaxVsn, Vsns, fun ec_semver:lte/2)). semver_matching_gt(_Config) -> - Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>, <<"0.2.1">>], - ?assertEqual([{Dep, {pkg, Dep, <<"0.2.1">>, undefined}}], - rebar_prv_update:cmp_(undefined, MaxVsn, Vsns, [], Dep1, + ?assertEqual({ok, <<"0.2.1">>}, + rebar_packages:cmp_(undefined, MaxVsn, Vsns, fun ec_semver:gt/2)). semver_matching_gte(_Config) -> - Dep = <<"test">>, - Dep1 = {Dep, <<"1.0.0">>, Dep, Dep}, MaxVsn = <<"0.2.0">>, Vsns = [<<"0.1.7">>, <<"0.1.9">>, <<"0.1.8">>, <<"0.2.0">>], - ?assertEqual([{Dep, {pkg, Dep, <<"0.2.0">>, undefined}}], - rebar_prv_update:cmp_(undefined, MaxVsn, Vsns, [], Dep1, + ?assertEqual({ok, <<"0.2.0">>}, + rebar_packages:cmp_(undefined, MaxVsn, Vsns, fun ec_semver:gt/2)). valid_version(_Config) -> - ?assert(rebar_prv_update:valid_vsn(<<"0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<"0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<" 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<" 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"< 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"< 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<">0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<">0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"> 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"> 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<=0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<=0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<= 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"<= 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<">=0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<">=0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<">= 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<">= 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"==0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<"==0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"== 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"== 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"~>0.1">>)), - ?assert(rebar_prv_update:valid_vsn(<<"~>0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"~> 0.1.0">>)), - ?assert(rebar_prv_update:valid_vsn(<<"~> 0.1.0">>)), - ?assertNot(rebar_prv_update:valid_vsn(<<"> 0.1.0 and < 0.2.0">>)), + ?assert(rebar_packages:valid_vsn(<<"0.1">>)), + ?assert(rebar_packages:valid_vsn(<<"0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<" 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<" 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"<0.1">>)), + ?assert(rebar_packages:valid_vsn(<<"<0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"< 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"< 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<">0.1">>)), + ?assert(rebar_packages:valid_vsn(<<">0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"> 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"> 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"<=0.1">>)), + ?assert(rebar_packages:valid_vsn(<<"<=0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"<= 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"<= 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<">=0.1">>)), + ?assert(rebar_packages:valid_vsn(<<">=0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<">= 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<">= 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"==0.1">>)), + ?assert(rebar_packages:valid_vsn(<<"==0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"== 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"== 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"~>0.1">>)), + ?assert(rebar_packages:valid_vsn(<<"~>0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"~> 0.1.0">>)), + ?assert(rebar_packages:valid_vsn(<<"~> 0.1.0">>)), + ?assertNot(rebar_packages:valid_vsn(<<"> 0.1.0 and < 0.2.0">>)), ok. @@ -504,5 +498,5 @@ in_warnings(git, Warns, NameRaw, VsnRaw) -> in_warnings(pkg, Warns, NameRaw, VsnRaw) -> Name = iolist_to_binary(NameRaw), Vsn = iolist_to_binary(VsnRaw), - 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn, _}]} <- Warns, + 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn}]} <- Warns, AppName =:= Name, AppVsn =:= Vsn]). diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl index 3dbbf63..04cc441 100644 --- a/test/rebar_install_deps_SUITE.erl +++ b/test/rebar_install_deps_SUITE.erl @@ -121,27 +121,27 @@ deps(flat) -> [], {ok, ["B", "C"]}}; deps(pick_highest_left) -> - {[{"B", [{"C", "2", []}]}, - {"C", "1", []}], - [{"C","2"}], - {ok, ["B", {"C", "1"}]}}; + {[{"B", [{"C", "2.0.0", []}]}, + {"C", "1.0.0", []}], + [{"C","2.0.0"}], + {ok, ["B", {"C", "1.0.0"}]}}; deps(pick_highest_right) -> - {[{"B", "1", []}, - {"C", [{"B", "2", []}]}], - [{"B","2"}], - {ok, [{"B","1"}, "C"]}}; + {[{"B", "1.0.0", []}, + {"C", [{"B", "2.0.0", []}]}], + [{"B","2.0.0"}], + {ok, [{"B","1.0.0"}, "C"]}}; deps(pick_smallest1) -> - {[{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}], - [{"D","2"}], + {[{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}], + [{"D","2.0.0"}], %% we pick D1 because B < C - {ok, ["B","C",{"D","1"}]}}; + {ok, ["B","C",{"D","1.0.0"}]}}; deps(pick_smallest2) -> - {[{"C", [{"D", "2", []}]}, - {"B", [{"D", "1", []}]}], - [{"D","2"}], + {[{"C", [{"D", "2.0.0", []}]}, + {"B", [{"D", "1.0.0", []}]}], + [{"D","2.0.0"}], %% we pick D1 because B < C - {ok, ["B","C",{"D","1"}]}}; + {ok, ["B","C",{"D","1.0.0"}]}}; deps(circular1) -> {[{"B", [{"A", []}]}, % A is the top-level app {"C", []}], @@ -155,14 +155,14 @@ deps(circular2) -> deps(circular_skip) -> %% Never spot the circular dep due to being to low in the deps tree %% in source deps - {[{"B", [{"C", "2", [{"B", []}]}]}, - {"C", "1", [{"D",[]}]}], - [{"C","2"}], - {ok, ["B", {"C","1"}, "D"]}}; + {[{"B", [{"C", "2.0.0", [{"B", []}]}]}, + {"C", "1.0.0", [{"D",[]}]}], + [{"C","2.0.0"}], + {ok, ["B", {"C","1.0.0"}, "D"]}}; deps(fail_conflict) -> - {[{"B", [{"C", "2", []}]}, - {"C", "1", []}], - [{"C","2"}], + {[{"B", [{"C", "2.0.0", []}]}, + {"C", "1.0.0", []}], + [{"C","2.0.0"}], rebar_abort}; deps(default_profile) -> {[{"B", []}, @@ -216,39 +216,39 @@ mdeps(m_pick_source3) -> [], {ok, ["B"]}}; mdeps(m_pick_source4) -> - {[{"b", [{"d", "1", []}]}, - {"C", [{"D", "1", []}]}], - [{"D", "1"}], - {ok, ["b", "C", {"d", "1"}]}}; + {[{"b", [{"d", "1.0.0", []}]}, + {"C", [{"D", "1.0.0", []}]}], + [{"D", "1.0.0"}], + {ok, ["b", "C", {"d", "1.0.0"}]}}; mdeps(m_pick_source5) -> - {[{"B", [{"d", "1", []}]}, - {"C", [{"D", "1", []}]}], - [{"D", "1"}], - {ok, ["B", "C", {"d", "1"}]}}; + {[{"B", [{"d", "1.0.0", []}]}, + {"C", [{"D", "1.0.0", []}]}], + [{"D", "1.0.0"}], + {ok, ["B", "C", {"d", "1.0.0"}]}}; mdeps(m_source_to_pkg) -> {[{"B", [{"c",[{"d", []}]}]}], [], {ok, ["B", "c", "d"]}}; mdeps(m_pkg_level1) -> - {[{"B", [{"D", [{"e", "2", []}]}]}, - {"C", [{"e", "1", []}]}], - [{"e","2"}], - {ok, ["B","C","D",{"e","1"}]}}; + {[{"B", [{"D", [{"e", "2.0.0", []}]}]}, + {"C", [{"e", "1.0.0", []}]}], + [{"e","2.0.0"}], + {ok, ["B","C","D",{"e","1.0.0"}]}}; mdeps(m_pkg_level2) -> - {[{"B", [{"e", "1", []}]}, - {"C", [{"D", [{"e", "2", []}]}]}], - [{"e","2"}], - {ok, ["B","C","D",{"e","1"}]}}; + {[{"B", [{"e", "1.0.0", []}]}, + {"C", [{"D", [{"e", "2.0.0", []}]}]}], + [{"e","2.0.0"}], + {ok, ["B","C","D",{"e","1.0.0"}]}}; mdeps(m_pkg_level3_alpha_order) -> - {[{"B", [{"d", [{"f", "1", []}]}]}, - {"C", [{"E", [{"f", "2", []}]}]}], - [{"f","2"}], - {ok, ["B","C","d","E",{"f","1"}]}}; + {[{"B", [{"d", [{"f", "1.0.0", []}]}]}, + {"C", [{"E", [{"f", "2.0.0", []}]}]}], + [{"f","2.0.0"}], + {ok, ["B","C","d","E",{"f","1.0.0"}]}}; mdeps(m_pkg_level3) -> - {[{"B", [{"d", [{"f", "1", []}]}]}, - {"C", [{"E", [{"G", [{"f", "2", []}]}]}]}], - [{"f","2"}], - {ok, ["B","C","d","E","G",{"f","1"}]}}. + {[{"B", [{"d", [{"f", "1.0.0", []}]}]}, + {"C", [{"E", [{"G", [{"f", "2.0.0", []}]}]}]}], + [{"f","2.0.0"}], + {ok, ["B","C","d","E","G",{"f","1.0.0"}]}}. setup_project(fail_conflict, Config0, Deps) -> DepsType = ?config(deps_type, Config0), @@ -289,8 +289,8 @@ setup_project(nondefault_pick_highest, Config0, _) -> ), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), - DefaultDeps = rebar_test_utils:expand_deps(DepsType, [{"B", [{"C", "1", []}]}]), - ProfileDeps = rebar_test_utils:expand_deps(DepsType, [{"C", "2", []}]), + DefaultDeps = rebar_test_utils:expand_deps(DepsType, [{"B", [{"C", "1.0.0", []}]}]), + ProfileDeps = rebar_test_utils:expand_deps(DepsType, [{"C", "2.0.0", []}]), DefaultTop = rebar_test_utils:top_level_deps(DefaultDeps), ProfileTop = rebar_test_utils:top_level_deps(ProfileDeps), RebarConf = rebar_test_utils:create_config( @@ -412,19 +412,19 @@ nondefault_pick_highest(Config) -> {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), rebar_test_utils:run_and_check( Config, RebarConfig, ["lock"], - {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "1"}], "default"} + {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1.0.0"}, {dep, "C", "1.0.0"}], "default"} ), rebar_test_utils:run_and_check( Config, RebarConfig, ["as", "nondef", "lock"], - {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "2"}], "nondef"} + {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1.0.0"}, {dep, "C", "2.0.0"}], "nondef"} ), rebar_test_utils:run_and_check( Config, RebarConfig, ["lock"], - {ok, [{dep, "B"}, {lock, "B"}, {dep, "C", "1"}, {lock, "C", "1"}], "default"} + {ok, [{dep, "B"}, {lock, "B"}, {dep, "C", "1.0.0"}, {lock, "C", "1.0.0"}], "default"} ), rebar_test_utils:run_and_check( Config, RebarConfig, ["as", "nondef", "lock"], - {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "2"}], "nondef"} + {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1.0.0"}, {dep, "C", "2.0.0"}], "nondef"} ). m_flat1(Config) -> run(Config). @@ -475,5 +475,5 @@ in_warnings(git, Warns, NameRaw, VsnRaw) -> in_warnings(pkg, Warns, NameRaw, VsnRaw) -> Name = iolist_to_binary(NameRaw), Vsn = iolist_to_binary(VsnRaw), - 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn, _}]} <- Warns, + 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn}]} <- Warns, AppName =:= Name, AppVsn =:= Vsn]). diff --git a/test/rebar_localfs_resource.erl b/test/rebar_localfs_resource.erl index d60421e..3d1296a 100644 --- a/test/rebar_localfs_resource.erl +++ b/test/rebar_localfs_resource.erl @@ -2,6 +2,7 @@ %% ex: ts=4 sw=4 et %% %% @doc A localfs custom resource (for testing purposes only) +%% implementing the deprecated rebar_resource instead of v2 %% %% ``` %% {deps, [ @@ -13,13 +14,18 @@ -behaviour(rebar_resource). --export([lock/2 +-export([init/1 + ,lock/2 ,download/3 ,needs_update/2 ,make_vsn/1]). -include_lib("eunit/include/eunit.hrl"). +-spec init(rebar_state:t()) -> {ok, term()}. +init(_State) -> + {ok, #{}}. + lock(AppDir, {localfs, Path, _Ref}) -> lock(AppDir, {localfs, Path}); lock(_AppDir, {localfs, Path}) -> diff --git a/test/rebar_localfs_resource_v2.erl b/test/rebar_localfs_resource_v2.erl new file mode 100644 index 0000000..52af4d4 --- /dev/null +++ b/test/rebar_localfs_resource_v2.erl @@ -0,0 +1,50 @@ +%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et +%% +%% @doc A localfs custom resource (for testing purposes only) +%% +%% ``` +%% {deps, [ +%% %% Application files are copied from "/path/to/app_name" +%% {app_name, {localfs, "/path/to/app_name", undefined}} +%% ]}. +%% ''' +-module(rebar_localfs_resource_v2). + +-behaviour(rebar_resource_v2). + +-export([init/2 + ,lock/2 + ,download/4 + ,needs_update/2 + ,make_vsn/2]). + +-include_lib("eunit/include/eunit.hrl"). + +-spec init(atom(), rebar_state:t()) -> {ok, term()}. +init(Type, _State) -> + Resource = rebar_resource_v2:new(Type, ?MODULE, #{}), + {ok, Resource}. + +lock(AppInfo, _) -> + case rebar_app_info:source(AppInfo) of + {localfs, Path, _Ref} -> + {localfs, Path, undefined}; + {localfs, Path} -> + {localfs, Path, undefined} + end. + +needs_update(_AppInfo, _) -> + false. + +download(TmpDir, AppInfo, State, _) -> + download_(TmpDir, rebar_app_info:source(AppInfo), State). + +download_(TmpDir, {localfs, Path, _Ref}, State) -> + download_(TmpDir, {localfs, Path}, State); +download_(TmpDir, {localfs, Path}, _State) -> + ok = rebar_file_utils:cp_r(filelib:wildcard(Path ++ "/*"), TmpDir), + {ok, undefined}. + +make_vsn(_AppInfo, _) -> + {plain, "undefined"}. diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index 9ddd704..62bc4d1 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -4,17 +4,19 @@ -compile(export_all). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). +-include("rebar.hrl"). --define(bad_etag, "abcdef"). --define(good_etag, "22e1d7387c9085a462340088a2a8ba67"). +-define(bad_etag, <<"abcdef">>). +-define(good_etag, <<"22e1d7387c9085a462340088a2a8ba67">>). +-define(badpkg_checksum, <<"A14E3718B33F8124E98004433193509EC6660F6CA03302657CAB8785751D77A0">>). +-define(badindex_checksum, <<"7B2CBED315C89F3126B5BF553DD7FF0FB5FE94B064888DD1B095CE8BF4B6A16A">>). -define(bad_checksum, <<"D576B442A68C7B92BACDE1EFE9C6E54D8D6C74BDB71D8175B9D3C6EC8C7B62A7">>). --define(good_checksum, <<"1C6CE379D191FBAB41B7905075E0BF87CBBE23C77CECE775C5A0B786B2244C35">>). +-define(good_checksum, <<"12726BDE1F65583A0817A7E8AADCA73F03FD8CB06F01E6CD29117C4A0DA0AFCF">>). -define(BADPKG_ETAG, <<"BADETAG">>). -all() -> [good_uncached, good_cached, badindexchk, badpkg, - badhash_nocache, badhash_cache, - bad_to_good, good_disconnect, bad_disconnect, pkgs_provider, - find_highest_matching]. +all() -> [good_uncached, good_cached, badpkg, badhash_nocache, + badindexchk, badhash_cache, bad_to_good, good_disconnect, + bad_disconnect, pkgs_provider, find_highest_matching]. init_per_suite(Config) -> application:start(meck), @@ -32,10 +34,6 @@ init_per_testcase(pkgs_provider=Name, Config) -> 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}, @@ -89,9 +87,9 @@ init_per_testcase(good_disconnect=Name, Config0) -> | Config0], Config = mock_config(Name, Config1), copy_to_cache(Pkg, Config), - meck:unload(httpc), + %% meck:unload(httpc), meck:new(httpc, [passthrough, unsticky]), - meck:expect(httpc, request, fun(_, _, _, _, _) -> {error, econnrefused} end), + meck:expect(httpc, request, fun(_, _, _, _) -> {error, econnrefused} end), Config; init_per_testcase(bad_disconnect=Name, Config0) -> Pkg = {<<"goodpkg">>, <<"1.0.0">>}, @@ -99,9 +97,9 @@ init_per_testcase(bad_disconnect=Name, Config0) -> {pkg, Pkg} | Config0], Config = mock_config(Name, Config1), - meck:unload(httpc), - meck:new(httpc, [passthrough, unsticky]), - meck:expect(httpc, request, fun(_, _, _, _, _) -> {error, econnrefused} end), + meck:expect(hex_repo, get_tarball, fun(_, _, _) -> + {error, econnrefused} + end), Config; init_per_testcase(Name, Config0) -> Config = [{good_cache, false}, @@ -117,8 +115,8 @@ good_uncached(Config) -> Tmp = ?config(tmp_dir, Config), {Pkg,Vsn} = ?config(pkg, Config), State = ?config(state, Config), - ?assertEqual({ok, true}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), + ?assertEqual(ok, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum, #{}}, State, #{}, true)), Cache = ?config(cache_dir, Config), ?assert(filelib:is_regular(filename:join(Cache, <>))). @@ -130,16 +128,17 @@ good_cached(Config) -> CachedFile = filename:join(Cache, <>), ?assert(filelib:is_regular(CachedFile)), {ok, Content} = file:read_file(CachedFile), - ?assertEqual({ok, true}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), + ?assertEqual(ok, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum, #{}}, State, #{}, true)), {ok, Content} = file:read_file(CachedFile). + badindexchk(Config) -> Tmp = ?config(tmp_dir, Config), {Pkg,Vsn} = ?config(pkg, Config), State = ?config(state, Config), - ?assertMatch({bad_registry_checksum, _Path}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), + ?assertMatch({error, {rebar_pkg_resource, {bad_registry_checksum, _, _, _, _}}}, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?bad_checksum, #{}}, State, #{}, true)), %% The cached file is there for forensic purposes Cache = ?config(cache_dir, Config), ?assert(filelib:is_regular(filename:join(Cache, <>))). @@ -152,8 +151,8 @@ badpkg(Config) -> CachePath = filename:join(Cache, <>), ETagPath = filename:join(Cache, <>), rebar_pkg_resource:store_etag_in_cache(ETagPath, ?BADPKG_ETAG), - ?assertMatch({bad_download, _Path}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State, false)), + ?assertMatch({error, {hex_tarball, {tarball, {checksum_mismatch, _, _}}}}, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?badpkg_checksum, #{}}, State, #{}, false)), %% The cached/etag files are there for forensic purposes ?assert(filelib:is_regular(ETagPath)), ?assert(filelib:is_regular(CachePath)). @@ -162,8 +161,8 @@ badhash_nocache(Config) -> Tmp = ?config(tmp_dir, Config), {Pkg,Vsn} = ?config(pkg, Config), State = ?config(state, Config), - ?assertMatch({unexpected_hash, _Path, ?bad_checksum, ?good_checksum}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?bad_checksum}, State)), + ?assertMatch({error, {rebar_pkg_resource, {bad_registry_checksum, _, _, _, _}}}, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?bad_checksum, #{}}, State, #{}, true)), %% The cached file is there for forensic purposes Cache = ?config(cache_dir, Config), ?assert(filelib:is_regular(filename:join(Cache, <>))). @@ -176,8 +175,8 @@ badhash_cache(Config) -> CachedFile = filename:join(Cache, <>), ?assert(filelib:is_regular(CachedFile)), {ok, Content} = file:read_file(CachedFile), - ?assertMatch({unexpected_hash, _Path, ?bad_checksum, ?good_checksum}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?bad_checksum}, State)), + ?assertMatch({error, {rebar_pkg_resource, {bad_registry_checksum, _, _, _, _}}}, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?bad_checksum, #{}}, State, #{}, true)), %% The cached file is there still, unchanged. ?assert(filelib:is_regular(CachedFile)), ?assertEqual({ok, Content}, file:read_file(CachedFile)). @@ -190,8 +189,8 @@ bad_to_good(Config) -> CachedFile = filename:join(Cache, <>), ?assert(filelib:is_regular(CachedFile)), {ok, Contents} = file:read_file(CachedFile), - ?assertEqual({ok, true}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), + ?assertEqual(ok, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum, #{}}, State, #{}, true)), %% Cache has refreshed ?assert({ok, Contents} =/= file:read_file(CachedFile)). @@ -205,8 +204,8 @@ good_disconnect(Config) -> ?assert(filelib:is_regular(CachedFile)), {ok, Content} = file:read_file(CachedFile), rebar_pkg_resource:store_etag_in_cache(ETagFile, ?BADPKG_ETAG), - ?assertEqual({ok, true}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)), + ?assertEqual(ok, + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum, #{}}, State, #{}, true)), {ok, Content} = file:read_file(CachedFile). bad_disconnect(Config) -> @@ -214,32 +213,31 @@ bad_disconnect(Config) -> {Pkg,Vsn} = ?config(pkg, Config), State = ?config(state, Config), ?assertEqual({fetch_fail, Pkg, Vsn}, - rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum}, State)). + rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn, ?good_checksum, #{}}, State, #{}, true)). pkgs_provider(Config) -> Config1 = rebar_test_utils:init_rebar_state(Config), rebar_test_utils:run_and_check( - Config1, [], ["pkgs"], + Config1, [], ["pkgs", "relx"], {ok, []} ). find_highest_matching(_Config) -> State = rebar_state:new(), - {ok, Vsn} = rebar_packages:find_highest_matching( - <<"test">>, <<"1.0.0">>, <<"goodpkg">>, <<"1.0.0">>, package_index, State), + {ok, Vsn} = rebar_packages:find_highest_matching_( + <<"goodpkg">>, <<"1.0.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual(<<"1.0.1">>, Vsn), {ok, Vsn1} = rebar_packages:find_highest_matching( - <<"test">>, <<"1.0.0">>, <<"goodpkg">>, <<"1.0">>, package_index, State), + <<"goodpkg">>, <<"1.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual(<<"1.1.1">>, Vsn1), {ok, Vsn2} = rebar_packages:find_highest_matching( - <<"test">>, <<"1.0.0">>, <<"goodpkg">>, <<"2.0">>, package_index, State), + <<"goodpkg">>, <<"2.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual(<<"2.0.0">>, Vsn2), %% regression test. ~> constraints higher than the available packages would result %% in returning the first package version instead of 'none'. - ?assertEqual(none, rebar_packages:find_highest_matching(<<"test">>, <<"1.0.0">>, <<"goodpkg">>, - <<"~> 5.0">>, package_index, State)). - + ?assertEqual(none, rebar_packages:find_highest_matching_(<<"goodpkg">>, <<"~> 5.0">>, + #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State)). %%%%%%%%%%%%%%% %%% Helpers %%% @@ -249,35 +247,67 @@ mock_config(Name, Config) -> CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]), TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]), Tid = ets:new(registry_table, [public]), - ets:insert_new(Tid, [ - {<<"badindexchk">>,[[<<"1.0.0">>]]}, - {<<"goodpkg">>,[[<<"1.0.0">>, <<"1.0.1">>, <<"1.1.1">>, <<"2.0.0">>]]}, - {<<"badpkg">>,[[<<"1.0.0">>]]}, + AllDeps = [ {{<<"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">>]]} - ]), + {{<<"badpkg">>,<<"1.0.0">>}, [[], ?badpkg_checksum, [<<"rebar3">>]]} + ], + ets:insert_new(Tid, AllDeps), CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), filelib:ensure_dir(filename:join([CacheDir, "registry"])), ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])), + catch ets:delete(?PACKAGE_TABLE), + rebar_packages:new_package_table(), + lists:foreach(fun({{N, Vsn}, [Deps, Checksum, _]}) -> + case ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(N), Vsn, <<"hexpm">>}) of + false -> + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), Vsn, <<"hexpm">>}, + dependencies=Deps, + retired=false, + checksum=Checksum}); + true -> + ok + end + end, AllDeps), + + + meck:new(hex_repo, [passthrough]), + meck:expect(hex_repo, get_package, + fun(_Config, PkgName) -> + Matches = ets:match_object(Tid, {{PkgName,'_'}, '_'}), + Releases = + [#{checksum => Checksum, + version => Vsn, + dependencies => Deps} || + {{_, Vsn}, [Deps, Checksum, _]} <- Matches], + {ok, {200, #{}, #{releases => Releases}}} + end), + %% The state returns us a fake registry meck:new(rebar_state, [passthrough]), meck:expect(rebar_state, get, fun(_State, rebar_packages_cdn, _Default) -> - "http://test.com/" + "http://test.com/"; + (_, _, Default) -> + Default + end), + meck:expect(rebar_state, resources, + fun(_State) -> + DefaultConfig = hex_core:default_config(), + [rebar_resource_v2:new(pkg, rebar_pkg_resource, + #{repos => [DefaultConfig#{name => <<"hexpm">>}], + base_config => #{}})] end), meck:new(rebar_dir, [passthrough]), meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end), - 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()), + meck:expect(rebar_packages, package_dir, fun(_, _) -> {ok, CacheDir} end), meck:new(rebar_prv_update, [passthrough]), meck:expect(rebar_prv_update, do, fun(State) -> {ok, State} end), @@ -285,16 +315,16 @@ mock_config(Name, Config) -> %% Cache fetches are mocked -- we assume the server and clients are %% correctly used. GoodCache = ?config(good_cache, Config), - {Pkg,Vsn} = ?config(pkg, Config), + {Pkg,Vsn} = ?config(pkg, Config), PkgFile = <>, {ok, PkgContents} = file:read_file(filename:join(?config(data_dir, Config), PkgFile)), - meck:new(httpc, [passthrough, unsticky]), - meck:expect(httpc, request, - fun(get, {_Url, _Opts}, _, _, _) when GoodCache -> - {ok, {{Vsn, 304, <<"Not Modified">>}, [{"etag", ?good_etag}], <<>>}}; - (get, {_Url, _Opts}, _, _, _) -> - {ok, {{Vsn, 200, <<"OK">>}, [{"etag", ?good_etag}], PkgContents}} - end), + + meck:expect(hex_repo, get_tarball, fun(_, _, _) when GoodCache -> + {ok, {304, #{<<"etag">> => ?good_etag}, <<>>}}; + (_, _, _) -> + {ok, {200, #{<<"etag">> => ?good_etag}, PkgContents}} + end), + [{cache_root, CacheRoot}, {cache_dir, CacheDir}, {tmp_dir, TmpDir}, diff --git a/test/rebar_pkg_SUITE_data/badindexchk-1.0.0.tar b/test/rebar_pkg_SUITE_data/badindexchk-1.0.0.tar index e5b963f..1765bb3 100644 Binary files a/test/rebar_pkg_SUITE_data/badindexchk-1.0.0.tar and b/test/rebar_pkg_SUITE_data/badindexchk-1.0.0.tar differ diff --git a/test/rebar_pkg_SUITE_data/badpkg-1.0.0.tar b/test/rebar_pkg_SUITE_data/badpkg-1.0.0.tar index 4930cd2..37bb57d 100644 Binary files a/test/rebar_pkg_SUITE_data/badpkg-1.0.0.tar and b/test/rebar_pkg_SUITE_data/badpkg-1.0.0.tar differ diff --git a/test/rebar_pkg_SUITE_data/goodpkg-1.0.0.tar b/test/rebar_pkg_SUITE_data/goodpkg-1.0.0.tar index e5b963f..d0fa4cb 100644 Binary files a/test/rebar_pkg_SUITE_data/goodpkg-1.0.0.tar and b/test/rebar_pkg_SUITE_data/goodpkg-1.0.0.tar differ diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index 07656d0..d977b64 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -3,44 +3,53 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). +-include("rebar.hrl"). -all() -> [same_alias, diff_alias, diff_alias_vsn, transitive_alias, - transitive_hash_mismatch]. +all() -> [same_alias, diff_alias, diff_alias_vsn, transitive_alias%% , + %% transitive_hash_mismatch + ]. %% {uuid, {pkg, uuid}} = uuid %% {uuid, {pkg, alias}} = uuid on disk %% another run should yield the same lock file without error init_per_suite(Config) -> - mock_config(?MODULE, Config). + Config. + %% mock_config(?MODULE, Config). end_per_suite(Config) -> - unmock_config(Config). + Config. + %% unmock_config(Config). init_per_testcase(same_alias, Config0) -> + mock_config(?MODULE, Config0), Config = rebar_test_utils:init_rebar_state(Config0,"same_alias_"), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, {pkg, fakelib}}]}]), [{rebarconfig, RebarConf} | Config]; init_per_testcase(diff_alias, Config0) -> + mock_config(?MODULE, Config0), Config = rebar_test_utils:init_rebar_state(Config0,"diff_alias_"), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, {pkg, goodpkg}}]}]), [{rebarconfig, RebarConf} | Config]; init_per_testcase(diff_alias_vsn, Config0) -> + mock_config(?MODULE, Config0), Config = rebar_test_utils:init_rebar_state(Config0,"diff_alias_vsn_"), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, "1.0.0", {pkg, goodpkg}}]}]), [{rebarconfig, RebarConf} | Config]; init_per_testcase(transitive_alias, Config0) -> + mock_config(?MODULE, Config0), Config = rebar_test_utils:init_rebar_state(Config0,"transitive_alias_vsn_"), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{topdep, "1.0.0", {pkg, topdep}}]}]), [{rebarconfig, RebarConf} | Config]; init_per_testcase(transitive_hash_mismatch, Config0) -> + mock_config(?MODULE, Config0), Config = rebar_test_utils:init_rebar_state(Config0,"transitive_alias_vsn_"), AppDir = ?config(apps, Config), rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), @@ -48,6 +57,7 @@ init_per_testcase(transitive_hash_mismatch, Config0) -> [{rebarconfig, RebarConf} | Config]. end_per_testcase(_, Config) -> + unmock_config(Config), Config. same_alias(Config) -> @@ -162,6 +172,10 @@ transitive_hash_mismatch(Config) -> ), ok. +parse_deps(Deps) -> + [{maps:get(app, D, Name), {pkg, Name, Constraint, undefined}} || D=#{package := Name, + requirement := Constraint} <- Deps]. + mock_config(Name, Config) -> {ChkFake, Etag} = create_lib(Name, Config, "fakelib"), {ChkTop, _} = create_lib(Name, Config, "topdep"), @@ -176,40 +190,74 @@ mock_config(Name, Config) -> CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), rebar_test_utils:create_app(AppDir, "fakelib", "1.0.0", [kernel, stdlib]), ct:pal("{~p, ~p}",[ChkFake, Etag]), - {ChkFake, Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg-1.0.0"), + {ChkGood, EtagGood} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg", "1.0.0"), + AllDeps = [ + {<<"fakelib">>,[[<<"1.0.0">>]]}, + {<<"goodpkg">>,[[<<"1.0.0">>]]}, + {<<"topdep">>,[[<<"1.0.0">>]]}, + {<<"transitive">>, [[<<"1.0.0">>]]}, + {{<<"fakelib">>,<<"1.0.0">>}, [[], ChkFake, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"1.0.0">>}, [[], ChkGood, [<<"rebar3">>]]}, + {{<<"topdep">>,<<"1.0.0">>}, + [[ + {<<"transitive">>, <<"1.0.0">>, false, <<"transitive_app">>} + ], ChkTop, [<<"rebar3">>]]}, + {{<<"transitive">>,<<"1.0.0">>}, [[], ChkTrans, [<<"rebar3">>]]} + ], Tid = ets:new(registry_table, [public]), - ets:insert_new(Tid, [ - {<<"fakelib">>,[[<<"1.0.0">>]]}, - {<<"goodpkg">>,[[<<"1.0.0">>]]}, - {<<"topdep">>,[[<<"1.0.0">>]]}, - {<<"transitive">>, [[<<"1.0.0">>]]}, - {{<<"fakelib">>,<<"1.0.0">>}, [[], ChkFake, [<<"rebar3">>]]}, - {{<<"goodpkg">>,<<"1.0.0">>}, [[], ChkFake, [<<"rebar3">>]]}, - {{<<"topdep">>,<<"1.0.0">>}, - [[ - [<<"transitive">>, <<"1.0.0">>, false, <<"transitive_app">>] - ], ChkTop, [<<"rebar3">>]]}, - {{<<"transitive">>,<<"1.0.0">>}, [[], ChkTrans, [<<"rebar3">>]]} - ]), + ets:insert_new(Tid, AllDeps), ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])), - ets:delete(Tid), + %% ets:delete(Tid), %% The state returns us a fake registry meck:new(rebar_dir, [passthrough, no_link]), meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end), meck:new(rebar_packages, [passthrough, no_link]), 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 - %% correctly used. - meck:new(httpc, [passthrough, unsticky, no_link]), - meck:expect(httpc, request, - fun(get, {_Url, _Opts}, _, _, _) -> - {ok, {{<<"1.0.0">>, 304, <<"Not Modified">>}, [{"etag", Etag}], <<>>}} - end), + meck:expect(rebar_packages, package_dir, fun(_, _) -> {ok, CacheDir} end), + + %% TODO: is something else wrong that we need this for transitive_alias to pass + meck:expect(rebar_packages, update_package, fun(_, _, _) -> ok end), + + meck:new(rebar_prv_update, [passthrough]), + meck:expect(rebar_prv_update, do, fun(State) -> {ok, State} end), + + catch ets:delete(?PACKAGE_TABLE), + rebar_packages:new_package_table(), + + lists:foreach(fun({{N, Vsn}, [Deps, Checksum, _]}) -> + case ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(N), Vsn, <<"hexpm">>}) of + false -> + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), Vsn, <<"hexpm">>}, + dependencies=[{DAppName, {pkg, DN, DV, undefined}} || {DN, DV, _, DAppName} <- Deps], + retired=false, + checksum=Checksum}); + true -> + ok + end; + ({_N, _Vsns}) -> + ok + + end, AllDeps), + + meck:new(hex_repo, [passthrough]), + meck:expect(hex_repo, get_package, + fun(_Config, PkgName) -> + Matches = ets:match_object(Tid, {{PkgName,'_'}, '_'}), + Releases = + [#{checksum => Checksum, + version => Vsn, + dependencies => [{DAppName, {pkg, DN, DV, undefined}} || + {DN, DV, _, DAppName} <- Deps]} || + {{_, Vsn}, [Deps, Checksum, _]} <- Matches], + {ok, {200, #{}, #{releases => Releases}}} + end), + + meck:expect(hex_repo, get_tarball, fun(_, _, _) -> + {ok, {304, #{<<"etag">> => EtagGood}, <<>>}} + end), + %% Move all packages to cache NewConf = [{cache_root, CacheRoot}, {cache_dir, CacheDir}, @@ -231,4 +279,4 @@ create_lib(Name, Config, AppName, PkgName) -> CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]), filelib:ensure_dir(filename:join([CacheDir, "registry"])), rebar_test_utils:create_app(AppDir, AppName, "1.0.0", [kernel, stdlib]), - rebar_test_utils:package_app(AppDir, CacheDir, PkgName++"-1.0.0"). + rebar_test_utils:package_app(AppDir, CacheDir, PkgName, "1.0.0"). diff --git a/test/rebar_pkg_repos_SUITE.erl b/test/rebar_pkg_repos_SUITE.erl new file mode 100644 index 0000000..601566e --- /dev/null +++ b/test/rebar_pkg_repos_SUITE.erl @@ -0,0 +1,331 @@ +%% Test suite for the handling hexpm repo configurations +-module(rebar_pkg_repos_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-include("rebar.hrl"). + +all() -> + [default_repo, repo_merging, repo_replacing, + auth_merging, organization_merging, {group, resolve_version}]. + +groups() -> + [{resolve_version, [use_first_repo_match, use_exact_with_hash, fail_repo_update, + ignore_match_in_excluded_repo]}]. + +init_per_group(resolve_version, Config) -> + Repo1 = <<"test-repo-1">>, + Repo2 = <<"test-repo-2">>, + Repo3 = <<"test-repo-3">>, + Hexpm = <<"hexpm">>, + Repos = [Repo1, Repo2, Repo3, Hexpm], + + Deps = [{"A", "0.1.1", <<"good checksum">>, Repo1}, + {"A", "0.1.1", <<"good checksum">>, Repo2}, + {"B", "1.0.0", Repo1}, + {"B", "2.0.0", Repo2}, + {"B", "1.4.0", Repo3}, + {"B", "1.4.3", Hexpm}, + {"C", "1.3.1", <<"bad checksum">>, Repo1}, + {"C", "1.3.1", <<"good checksum">>, Repo2}], + [{deps, Deps}, {repos, Repos} | Config]; +init_per_group(_, Config) -> + Config. + +end_per_group(_, _) -> + ok. + +init_per_testcase(use_first_repo_match, Config) -> + Deps = ?config(deps, Config), + Repos = ?config(repos, Config), + State = setup_deps_and_repos(Deps, Repos), + + meck:new(rebar_packages, [passthrough, no_link]), + + %% fail when the first repo is updated since it doesn't have a matching package + %% should continue anyway + meck:expect(rebar_packages, update_package, + fun(_, _, _State) -> ok end), + meck:expect(rebar_packages, verify_table, + fun(_State) -> true end), + + [{state, State} | Config]; +init_per_testcase(use_exact_with_hash, Config) -> + Deps = ?config(deps, Config), + Repos = ?config(repos, Config), + State = setup_deps_and_repos(Deps, Repos), + + meck:new(rebar_packages, [passthrough, no_link]), + + %% fail when the first repo is updated since it doesn't have a matching package + %% should continue anyway + meck:expect(rebar_packages, update_package, + fun(_, _, _State) -> ok end), + meck:expect(rebar_packages, verify_table, + fun(_State) -> true end), + + [{state, State} | Config]; +init_per_testcase(fail_repo_update, Config) -> + Deps = ?config(deps, Config), + Repos = ?config(repos, Config), + State = setup_deps_and_repos(Deps, Repos), + + meck:new(rebar_packages, [passthrough, no_link]), + + %% fail when the first repo is updated since it doesn't have a matching package + %% should continue anyway + [Repo1 | _] = Repos, + meck:expect(rebar_packages, update_package, + fun(_, #{name := Repo}, _State) when Repo =:= Repo1 -> fail; + (_, _, _State) -> ok end), + meck:expect(rebar_packages, verify_table, + fun(_State) -> true end), + + [{state, State} | Config]; +init_per_testcase(ignore_match_in_excluded_repo, Config) -> + Deps = ?config(deps, Config), + Repos = [Repo1, _, Repo3 | _] = ?config(repos, Config), + + %% drop repo1 and repo2 from the repos to be used by the pkg resource + State = setup_deps_and_repos(Deps, [R || R <- Repos, R =/= Repo3, R =/= Repo1]), + + meck:new(rebar_packages, [passthrough, no_link]), + + %% fail when the first repo is updated since it doesn't have a matching package + %% should continue anyway + [_, _, Repo3 | _] = Repos, + meck:expect(rebar_packages, update_package, + fun(_, _, _State) -> ok end), + meck:expect(rebar_packages, verify_table, + fun(_State) -> true end), + + [{state, State} | Config]; +init_per_testcase(auth_merging, Config) -> + meck:new(file, [passthrough, no_link, unstick]), + meck:new(rebar_packages, [passthrough, no_link]), + Config; +init_per_testcase(organization_merging, Config) -> + meck:new(file, [passthrough, no_link, unstick]), + meck:new(rebar_packages, [passthrough, no_link]), + Config; +init_per_testcase(_, Config) -> + Config. + +end_per_testcase(Case, _Config) when Case =:= auth_merging ; + Case =:= organization_merging -> + meck:unload(file), + meck:unload(rebar_packages); +end_per_testcase(Case, _Config) when Case =:= use_first_repo_match ; + Case =:= use_exact_with_hash ; + Case =:= fail_repo_update ; + Case =:= ignore_match_in_excluded_repo -> + meck:unload(rebar_packages); +end_per_testcase(_, _) -> + ok. + + +default_repo(_Config) -> + Repo1 = #{name => <<"hexpm">>, + api_key => <<"asdf">>}, + + MergedRepos = rebar_hex_repos:repos([{repos, [Repo1]}]), + + ?assertMatch([#{name := <<"hexpm">>, + api_key := <<"asdf">>, + api_url := <<"https://hex.pm/api">>}], MergedRepos). + + +repo_merging(_Config) -> + Repo1 = #{name => <<"repo-1">>, + api_url => <<"repo-1/api">>}, + Repo2 = #{name => <<"repo-2">>, + repo_url => <<"repo-2/repo">>, + repo_verify => false}, + Result = rebar_hex_repos:merge_repos([Repo1, Repo2, + #{name => <<"repo-2">>, + api_url => <<"repo-2/api">>, + repo_url => <<"bad url">>, + repo_verify => true}, + #{name => <<"repo-1">>, + api_url => <<"bad url">>, + repo_verify => true}, + #{name => <<"repo-2">>, + api_url => <<"repo-2/api-2">>, + repo_url => <<"other/repo">>}]), + ?assertMatch([#{name := <<"repo-1">>, + api_url := <<"repo-1/api">>, + repo_verify := true}, + #{name := <<"repo-2">>, + api_url := <<"repo-2/api">>, + repo_url := <<"repo-2/repo">>, + repo_verify := false}], Result). + +repo_replacing(_Config) -> + Repo1 = #{name => <<"repo-1">>, + api_url => <<"repo-1/api">>}, + Repo2 = #{name => <<"repo-2">>, + repo_url => <<"repo-2/repo">>, + repo_verify => false}, + + ?assertMatch([Repo1, Repo2, #{name := <<"hexpm">>}], + rebar_hex_repos:repos([{repos, [Repo1]}, + {repos, [Repo2]}])), + + %% use of replace is ignored if found in later entries than the first + ?assertMatch([Repo1, Repo2, #{name := <<"hexpm">>}], + rebar_hex_repos:repos([{repos, [Repo1]}, + {repos, replace, [Repo2]}])), + + ?assertMatch([Repo1], + rebar_hex_repos:repos([{repos, replace, [Repo1]}, + {repos, [Repo2]}])). + +auth_merging(_Config) -> + Repo1 = #{name => <<"repo-1">>, + api_url => <<"repo-1/api">>}, + Repo2 = #{name => <<"repo-2">>, + repo_url => <<"repo-2/repo">>, + repo_verify => false}, + + State = rebar_state:new([{hex, [{repos, [Repo1, Repo2]}]}]), + meck:expect(file, consult, + fun(_) -> + {ok, [#{<<"repo-1">> => #{read_key => <<"read key">>, + write_key => <<"write key">>}, + <<"repo-2">> => #{read_key => <<"read key 2">>, + repos_key => <<"repos key 2">>, + write_key => <<"write key 2">>}, + <<"hexpm">> => #{write_key => <<"write key hexpm">>}}]} + end), + + ?assertMatch({ok, + #resource{state=#{repos := [#{name := <<"repo-1">>, + read_key := <<"read key">>, + write_key := <<"write key">>}, + #{name := <<"repo-2">>, + read_key := <<"read key 2">>, + repos_key := <<"repos key 2">>, + write_key := <<"write key 2">>}, + #{name := <<"hexpm">>, + write_key := <<"write key hexpm">>}]}}}, + rebar_pkg_resource:init(pkg, State)), + + ok. + +organization_merging(_Config) -> + Repo1 = #{name => <<"hexpm:repo-1">>, + api_url => <<"repo-1/api">>}, + Repo2 = #{name => <<"hexpm:repo-2">>, + repo_url => <<"repo-2/repo">>, + repo_verify => false}, + + State = rebar_state:new([{hex, [{repos, [Repo1, Repo2]}]}]), + meck:expect(file, consult, + fun(_) -> + {ok, [#{<<"hexpm:repo-1">> => #{read_key => <<"read key">>}, + <<"hexpm:repo-2">> => #{read_key => <<"read key 2">>, + repos_key => <<"repos key 2">>, + write_key => <<"write key 2">>}, + <<"hexpm">> => #{write_key => <<"write key hexpm">>}}]} + end), + + ?assertMatch({ok, + #resource{state=#{repos := [#{name := <<"hexpm:repo-1">>, + parent := <<"hexpm">>, + read_key := <<"read key">>, + write_key := <<"write key hexpm">>}, + #{name := <<"hexpm:repo-2">>, + parent := <<"hexpm">>, + read_key := <<"read key 2">>, + repos_key := <<"repos key 2">>, + write_key := <<"write key 2">>}, + #{name := <<"hexpm">>, + write_key := <<"write key hexpm">>}]}}}, + rebar_pkg_resource:init(pkg, State)), + + ok. + +use_first_repo_match(Config) -> + State = ?config(state, Config), + + ?assertMatch({ok,{package,{<<"B">>, <<"2.0.0">>, Repo2}, + <<"some checksum">>, false, []}, + #{name := Repo2, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"> 1.4.0">>, undefined, + ?PACKAGE_TABLE, State)), + + ?assertMatch({ok,{package,{<<"B">>, <<"1.4.0">>, Repo3}, + <<"some checksum">>, false, []}, + #{name := Repo3, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"~> 1.4.0">>, undefined, + ?PACKAGE_TABLE, State)). + +%% tests that even though an easier repo has C-1.3.1 it doesn't use it since its hash is different +use_exact_with_hash(Config) -> + State = ?config(state, Config), + + ?assertMatch({ok,{package,{<<"C">>, <<"1.3.1">>, Repo2}, + <<"good checksum">>, false, []}, + #{name := Repo2, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"C">>, <<"1.3.1">>, <<"good checksum">>, + ?PACKAGE_TABLE, State)). + +fail_repo_update(Config) -> + State = ?config(state, Config), + + ?assertMatch({ok,{package,{<<"B">>, <<"1.4.0">>, Repo3}, + <<"some checksum">>, false, []}, + #{name := Repo3, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"~> 1.4.0">>, undefined, + ?PACKAGE_TABLE, State)). + +ignore_match_in_excluded_repo(Config) -> + State = ?config(state, Config), + Repos = ?config(repos, Config), + + ?assertMatch({ok,{package,{<<"B">>, <<"1.4.3">>, Hexpm}, + <<"some checksum">>, false, []}, + #{name := Hexpm, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"~> 1.4.0">>, undefined, + ?PACKAGE_TABLE, State)), + + [_, Repo2 | _] = Repos, + ?assertMatch({ok,{package,{<<"A">>, <<"0.1.1">>, Repo2}, + <<"good checksum">>, false, []}, + #{name := Repo2, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"A">>, <<"0.1.1">>, <<"good checksum">>, + ?PACKAGE_TABLE, State)). + +%% + +setup_deps_and_repos(Deps, Repos) -> + true = rebar_packages:new_package_table(), + insert_deps(Deps), + State = rebar_state:new([{hex, [{repos, [#{name => R} || R <- Repos]}]}]), + rebar_state:create_resources([{pkg, rebar_pkg_resource}], State). + + +insert_deps(Deps) -> + lists:foreach(fun({Name, Version, Repo}) -> + ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name), + rebar_utils:to_binary(Version), + rebar_utils:to_binary(Repo)}, + dependencies=[], + retired=false, + checksum = <<"some checksum">>}); + ({Name, Version, Checksum, Repo}) -> + ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name), + rebar_utils:to_binary(Version), + rebar_utils:to_binary(Repo)}, + dependencies=[], + retired=false, + checksum = Checksum}) + end, Deps). diff --git a/test/rebar_resource_SUITE.erl b/test/rebar_resource_SUITE.erl index 15f14db..ddacb91 100644 --- a/test/rebar_resource_SUITE.erl +++ b/test/rebar_resource_SUITE.erl @@ -29,12 +29,15 @@ init_per_testcase(change_type_upgrade, Config) -> TypeStr = atom_to_list(Type), DirName = filename:join([?config(priv_dir, Config), "resource_"++TypeStr]), ec_file:mkdir_path(DirName), - [{path, DirName} | Config]. + + {ok, AppInfo} = rebar_app_info:new(test_app, "0.0.1", DirName), + AppInfo1 = rebar_app_info:source(AppInfo, ?config(resource, Config)), + + [{app, AppInfo1} | Config]. end_per_testcase(_, Config) -> Config. change_type_upgrade(Config) -> - ?assert(rebar_fetch:needs_update(?config(path, Config), - ?config(resource, Config), + ?assert(rebar_fetch:needs_update(?config(app, Config), ?config(state, Config))). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index b74aa2f..8bcb6d1 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -4,8 +4,9 @@ -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_plugin/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]). + create_config/2, create_config/3, package_app/4]). +-export([create_random_name/1, create_random_vsn/0, write_src_file/2, + random_element/1]). %% Pick the right random module -ifdef(rand_only). @@ -34,8 +35,10 @@ init_rebar_state(Config, Name) -> Verbosity = rebar3:log_level(), rebar_log:init(command_line, Verbosity), GlobalDir = filename:join([DataDir, "cache"]), + Repos = proplists:get_value(repos, Config, []), State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])} ,{global_rebar_dir, GlobalDir} + ,{hex, [{repos, [#{name => R} || R <- Repos]}]} ,{root_dir, AppsDir}]), [{apps, AppsDir}, {checkouts, CheckoutsDir}, {state, State} | Config]. @@ -467,24 +470,25 @@ get_app_metadata(Name, Vsn, Deps) -> {registered, []}, {applications, Deps}]}. -package_app(AppDir, DestDir, PkgName) -> - Name = PkgName++".tar", - {ok, Fs} = rebar_utils:list_dir(AppDir), - ok = erl_tar:create(filename:join(DestDir, "contents.tar.gz"), - lists:zip(Fs, [filename:join(AppDir,F) || F <- Fs]), - [compressed]), - ok = file:write_file(filename:join(DestDir, "metadata.config"), "who cares"), - ok = file:write_file(filename:join(DestDir, "VERSION"), "3"), - {ok, Contents} = file:read_file(filename:join(DestDir, "contents.tar.gz")), - Blob = <<"3who cares", Contents/binary>>, - <> = crypto:hash(sha256, Blob), - BinChecksum = list_to_binary(rebar_string:uppercase(lists:flatten(io_lib:format("~64.16.0b", [X])))), - ok = file:write_file(filename:join(DestDir, "CHECKSUM"), BinChecksum), - PkgFiles = ["contents.tar.gz", "VERSION", "metadata.config", "CHECKSUM"], +package_app(AppDir, DestDir, PkgName, PkgVsn) -> + AppSrc = filename:join(AppDir, "src"), + {ok, Fs} = rebar_utils:list_dir(AppSrc), + Files = lists:zip([filename:join("src", F) || F <- Fs], [filename:join(AppSrc,F) || F <- Fs]), + Metadata = #{<<"app">> => list_to_binary(PkgName), + <<"version">> => list_to_binary(PkgVsn)}, + {ok, {Tarball, <>}} = hex_tarball:create(Metadata, Files), + + Name = PkgName++"-"++PkgVsn++".tar", Archive = filename:join(DestDir, Name), - ok = erl_tar:create(Archive, - lists:zip(PkgFiles, [filename:join(DestDir,F) || F <- PkgFiles])), - {ok, BinFull} = file:read_file(Archive), - <> = crypto:hash(md5, BinFull), - Etag = rebar_string:lowercase(lists:flatten(io_lib:format("~32.16.0b", [E]))), - {BinChecksum, Etag}. + file:write_file(Archive, Tarball), + + <> = crypto:hash(md5, Tarball), + + Checksum1 = list_to_binary( + rebar_string:uppercase( + lists:flatten(io_lib:format("~64.16.0b", [Checksum])))), + {Checksum1, E}. + +random_element(Repos) -> + Index = ?random:uniform(length(Repos)), + lists:nth(Index, Repos). diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 45a7433..c55456c 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -112,25 +112,25 @@ setup_project(Case, Config0, Deps, UpDeps) -> upgrades(top_a) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"A", [{"A","1"}, "B", "C", {"D","3"}]}}; + {"A", [{"A","1.0.0"}, "B", "C", {"D","3.0.0"}]}}; upgrades(top_b) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], @@ -138,12 +138,12 @@ upgrades(top_b) -> {"B", {error, {rebar_prv_upgrade, {transitive_dependency, <<"B">>}}}}}; upgrades(top_c) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], @@ -151,12 +151,12 @@ upgrades(top_c) -> {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}}; upgrades(top_d1) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], @@ -164,12 +164,12 @@ upgrades(top_d1) -> {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}}; upgrades(top_d2) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], @@ -177,342 +177,342 @@ upgrades(top_d2) -> {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}}; upgrades(top_e) -> %% Original tree - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Updated tree - [{"A", "1", [{"B", [{"D", "3", []}]}, - {"C", [{"D", "2", []}]}]} + [{"A", "1.0.0", [{"B", [{"D", "3.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree {"E", {error, {rebar_prv_upgrade, {unknown_dependency, <<"E">>}}}}}; upgrades(pair_a) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], - {"A", [{"A","2"},{"C","2"},{"B","1"},{"D","1"}]}}; + {"A", [{"A","2.0.0"},{"C","2.0.0"},{"B","1.0.0"},{"D","1.0.0"}]}}; upgrades(pair_b) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], - {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}}; + {"B", [{"A","1.0.0"},{"C","1.0.0"},{"B","2.0.0"},{"D","2.0.0"}]}}; upgrades(pair_ab) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], - {"A,B", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}; + {"A,B", [{"A","2.0.0"},{"C","2.0.0"},{"B","2.0.0"},{"D","2.0.0"}]}}; upgrades(pair_c) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}}; upgrades(pair_all) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], - {"", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}; + {"", [{"A","2.0.0"},{"C","2.0.0"},{"B","2.0.0"},{"D","2.0.0"}]}}; upgrades(triplet_a) -> - {[{"A", "1", [{"D",[]}, - {"E","3",[]}]}, - {"B", "1", [{"F","1",[]}, + {[{"A", "1.0.0", [{"D",[]}, + {"E","3.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "0", [{"H","3",[]}, + {"C", "0.0.0", [{"H","3.0.0",[]}, {"I",[]}]}], - [{"A", "1", [{"D",[]}, - {"E","2",[]}]}, - {"B", "1", [{"F","1",[]}, + [{"A", "1.0.0", [{"D",[]}, + {"E","2.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "1", [{"H","4",[]}, + {"C", "1.0.0", [{"H","4.0.0",[]}, {"I",[]}]}], ["A","C","E","H"], - {"A", [{"A","1"}, "D", {"E","2"}, - {"B","1"}, {"F","1"}, "G", - {"C","0"}, {"H","3"}, "I"]}}; + {"A", [{"A","1.0.0"}, "D", {"E","2.0.0"}, + {"B","1.0.0"}, {"F","1.0.0"}, "G", + {"C","0.0.0"}, {"H","3.0.0"}, "I"]}}; upgrades(triplet_b) -> - {[{"A", "1", [{"D",[]}, - {"E","3",[]}]}, - {"B", "1", [{"F","1",[]}, + {[{"A", "1.0.0", [{"D",[]}, + {"E","3.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "0", [{"H","3",[]}, + {"C", "0.0.0", [{"H","3.0.0",[]}, {"I",[]}]}], - [{"A", "2", [{"D",[]}, - {"E","2",[]}]}, - {"B", "1", [{"F","1",[]}, + [{"A", "2.0.0", [{"D",[]}, + {"E","2.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "1", [{"H","4",[]}, + {"C", "1.0.0", [{"H","4.0.0",[]}, {"I",[]}]}], ["A","C","E","H"], - {"B", [{"A","1"}, "D", {"E","3"}, - {"B","1"}, {"F","1"}, "G", - {"C","0"}, {"H","3"}, "I"]}}; + {"B", [{"A","1.0.0"}, "D", {"E","3.0.0"}, + {"B","1.0.0"}, {"F","1.0.0"}, "G", + {"C","0.0.0"}, {"H","3.0.0"}, "I"]}}; upgrades(triplet_c) -> - {[{"A", "1", [{"D",[]}, - {"E","3",[]}]}, - {"B", "1", [{"F","1",[]}, + {[{"A", "1.0.0", [{"D",[]}, + {"E","3.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "0", [{"H","3",[]}, + {"C", "0.0.0", [{"H","3.0.0",[]}, {"I",[]}]}], - [{"A", "2", [{"D",[]}, - {"E","2",[]}]}, - {"B", "1", [{"F","1",[]}, + [{"A", "2.0.0", [{"D",[]}, + {"E","2.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "1", [{"H","4",[]}, + {"C", "1.0.0", [{"H","4.0.0",[]}, {"I",[]}]}], ["A","C","E","H"], - {"C", [{"A","1"}, "D", {"E","3"}, - {"B","1"}, {"F","1"}, "G", - {"C","1"}, {"H","4"}, "I"]}}; + {"C", [{"A","1.0.0"}, "D", {"E","3.0.0"}, + {"B","1.0.0"}, {"F","1.0.0"}, "G", + {"C","1.0.0"}, {"H","4.0.0"}, "I"]}}; upgrades(tree_a) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "2", [{"H",[]}]} + {"C", "2.0.0", [{"H",[]}]} ], ["C"], - {"A", [{"A","1"}, "D", "J", "E", - {"B","1"}, "F", "G", - {"C","1"}, "H", {"I","2"}]}}; + {"A", [{"A","1.0.0"}, "D", "J", "E", + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H", {"I","2.0.0"}]}}; upgrades(tree_b) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "2", [{"H",[]}]} + {"C", "2.0.0", [{"H",[]}]} ], ["C"], - {"B", [{"A","1"}, "D", "J", "E", - {"B","1"}, "F", "G", - {"C","1"}, "H", {"I","2"}]}}; + {"B", [{"A","1.0.0"}, "D", "J", "E", + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H", {"I","2.0.0"}]}}; upgrades(tree_c) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}]} + {"C", "1.0.0", [{"H",[]}]} ], ["C","I"], - {"C", [{"A","1"}, "D", "J", "E", {"I","1"}, - {"B","1"}, "F", "G", - {"C","1"}, "H"]}}; + {"C", [{"A","1.0.0"}, "D", "J", "E", {"I","1.0.0"}, + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H"]}}; upgrades(tree_c2) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[{"K",[]}]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[{"K",[]}]}, + {"I","2.0.0",[]}]} ], ["C", "H"], - {"C", [{"A","1"}, "D", "J", "E", - {"B","1"}, "F", "G", - {"C","1"}, "H", {"I", "2"}, "K"]}}; + {"C", [{"A","1.0.0"}, "D", "J", "E", + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H", {"I", "2.0.0"}, "K"]}}; upgrades(tree_cj) -> - {[{"A", "1", [{"D",[{"J", "1",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J", "1.0.0",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","1",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","1.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J", "2", []}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J", "2.0.0", []}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","1",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","1.0.0",[]}]} ], ["C","J"], - {"C", [{"A","1"}, "D", {"J", "1"}, "E", {"I","1"}, - {"B","1"}, "F", "G", - {"C","1"}, "H"]}}; + {"C", [{"A","1.0.0"}, "D", {"J", "1.0.0"}, "E", {"I","1.0.0"}, + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H"]}}; upgrades(tree_ac) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}]} + {"C", "1.0.0", [{"H",[]}]} ], ["C","I"], - {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"}, - {"B","1"}, "F", "G", - {"C","1"}, "H"]}}; + {"C, A", [{"A","1.0.0"}, "D", "J", "E", {"I","1.0.0"}, + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H"]}}; upgrades(tree_all) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], - [{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + [{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}]} + {"C", "1.0.0", [{"H",[]}]} ], ["C","I"], - {"", [{"A","1"}, "D", "J", "E", {"I","1"}, - {"B","1"}, "F", "G", - {"C","1"}, "H"]}}; + {"", [{"A","1.0.0"}, "D", "J", "E", {"I","1.0.0"}, + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H"]}}; upgrades(delete_d) -> - {[{"A", "1", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} + {[{"A", "1.0.0", [{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "2.0.0", []}]}]} ], - [{"A", "2", [{"B", []}, + [{"A", "2.0.0", [{"B", []}, {"C", []}]} ], ["A","B", "C"], %% upgrade vs. new tree - {"", [{"A","2"}, "B", "C"]}}; + {"", [{"A","2.0.0"}, "B", "C"]}}; upgrades(promote) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]}, - {"C", "3", []} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]}, + {"C", "3.0.0", []} ], ["A","B","C","D"], - {"C", [{"A","1"},{"C","3"},{"B","1"},{"D","1"}]}}; + {"C", [{"A","1.0.0"},{"C","3.0.0"},{"B","1.0.0"},{"D","1.0.0"}]}}; upgrades(stable_lock) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], % lock after this - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], [], %% Run a regular lock and no app should be upgraded - {"any", [{"A","1"},{"C","1"},{"B","1"},{"D","1"}]}}; + {"any", [{"A","1.0.0"},{"C","1.0.0"},{"B","1.0.0"},{"D","1.0.0"}]}}; upgrades(fwd_lock) -> - {[{"A", "1", [{"C", "1", []}]}, - {"B", "1", [{"D", "1", []}]} + {[{"A", "1.0.0", [{"C", "1.0.0", []}]}, + {"B", "1.0.0", [{"D", "1.0.0", []}]} ], - [{"A", "2", [{"C", "2", []}]}, - {"B", "2", [{"D", "2", []}]} + [{"A", "2.0.0", [{"C", "2.0.0", []}]}, + {"B", "2.0.0", [{"D", "2.0.0", []}]} ], ["A","B","C","D"], %% For this one, we should build, rewrite the lock %% file to include the result post-upgrade, and then %% run a regular lock to see that the lock file is respected %% in deps. - {"any", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}; + {"any", [{"A","2.0.0"},{"C","2.0.0"},{"B","2.0.0"},{"D","2.0.0"}]}}; upgrades(compile_upgrade_parity) -> - {[{"A", "1", [{"D",[{"J",[]}]}, - {"E",[{"I","1",[]}]}]}, - {"B", "1", [{"F",[]}, + {[{"A", "1.0.0", [{"D",[{"J",[]}]}, + {"E",[{"I","1.0.0",[]}]}]}, + {"B", "1.0.0", [{"F",[]}, {"G",[]}]}, - {"C", "1", [{"H",[]}, - {"I","2",[]}]} + {"C", "1.0.0", [{"H",[]}, + {"I","2.0.0",[]}]} ], [], [], - {"", [{"A","1"}, "D", "J", "E", {"I","1"}, - {"B","1"}, "F", "G", - {"C","1"}, "H"]}}; + {"", [{"A","1.0.0"}, "D", "J", "E", {"I","1.0.0"}, + {"B","1.0.0"}, "F", "G", + {"C","1.0.0"}, "H"]}}; upgrades(umbrella_config) -> - {[{"A", "1", []}], - [{"A", "2", []}], + {[{"A", "1.0.0", []}], + [{"A", "2.0.0", []}], ["A"], - {"A", [{"A","2"}]}}; + {"A", [{"A","2.0.0"}]}}; upgrades(profiles) -> %% Ensure that we can unlock deps under a given profile; %% B and C should both be in a custom profile %% and must not be locked. - {[{"A", "1", [{"D",[]}, - {"E","3",[]}]}, - {"B", "1", [{"F","1",[]}, + {[{"A", "1.0.0", [{"D",[]}, + {"E","3.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "0", [{"H","3",[]}, + {"C", "0.0.0", [{"H","3.0.0",[]}, {"I",[]}]}], - [{"A", "2", [{"D",[]}, - {"E","2",[]}]}, - {"B", "2", [{"F","2",[]}, + [{"A", "2.0.0", [{"D",[]}, + {"E","2.0.0",[]}]}, + {"B", "2.0.0", [{"F","2.0.0",[]}, {"G",[]}]}, - {"C", "1", [{"H","4",[]}, + {"C", "1.0.0", [{"H","4.0.0",[]}, {"I",[]}]}], ["A","B","C","E","F","H"], - {"C", [{"A","1"}, "D", {"E","3"}, - {"B","2"}, {"F","2"}, "G", - {"C","1"}, {"H","4"}, "I"]}}; + {"C", [{"A","1.0.0"}, "D", {"E","3.0.0"}, + {"B","2.0.0"}, {"F","2.0.0"}, "G", + {"C","1.0.0"}, {"H","4.0.0"}, "I"]}}; upgrades(profiles_exclusion) -> %% Ensure that we can unlock deps under a given profile; %% B and C should both be in a custom profile %% and must not be locked. - {[{"A", "1", [{"D",[]}, - {"E","3",[]}]}, - {"B", "1", [{"F","1",[]}, + {[{"A", "1.0.0", [{"D",[]}, + {"E","3.0.0",[]}]}, + {"B", "1.0.0", [{"F","1.0.0",[]}, {"G",[]}]}, - {"C", "0", [{"H","3",[]}, + {"C", "0.0.0", [{"H","3.0.0",[]}, {"I",[]}]}], - [{"A", "2", [{"D",[]}, - {"E","2",[]}]}, - {"B", "2", [{"F","2",[]}, + [{"A", "2.0.0", [{"D",[]}, + {"E","2.0.0",[]}]}, + {"B", "2.0.0", [{"F","2.0.0",[]}, {"G",[]}]}, - {"C", "1", [{"H","4",[]}, + {"C", "1.0.0", [{"H","4.0.0",[]}, {"I",[]}]}], ["A","B","C","E","F","H"], - {"A", [{"A","1"}, "D", {"E","3"}, - {"B","2"}, {"F","2"}, "G", - {"C","1"}, {"H","4"}, "I"]}}. + {"A", [{"A","1.0.0"}, "D", {"E","3.0.0"}, + {"B","2.0.0"}, {"F","2.0.0"}, "G", + {"C","1.0.0"}, {"H","4.0.0"}, "I"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. -- cgit v1.1 From 43769ae87f7c60a9b6cb3bf08085a4a4206961b7 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 17 Sep 2018 09:02:30 -0600 Subject: only print skip warning if version is different (#1886) --- test/rebar_install_deps_SUITE.erl | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl index 04cc441..96b9d38 100644 --- a/test/rebar_install_deps_SUITE.erl +++ b/test/rebar_install_deps_SUITE.erl @@ -17,7 +17,7 @@ groups() -> {mixed, [], [ m_flat1, m_flat2, m_circular1, m_circular2, m_pick_source1, m_pick_source2, m_pick_source3, - m_pick_source4, m_pick_source5, m_source_to_pkg, + m_pick_source4, m_pick_source5, m_pick_source6, m_source_to_pkg, m_pkg_level1, m_pkg_level2, m_pkg_level3, m_pkg_level3_alpha_order ]} ]. @@ -93,6 +93,8 @@ format_expected_mdeps(Deps) -> [{dep, N}, {lock, src, N, "0.0.0"}] end || Dep <- Deps]). +format_expected_mixed_warnings(none) -> + none; format_expected_mixed_warnings(Warnings) -> [case W of {N, Vsn} when hd(N) >= $a, hd(N) =< $z -> {pkg, rebar_string:uppercase(N), Vsn}; @@ -225,6 +227,11 @@ mdeps(m_pick_source5) -> {"C", [{"D", "1.0.0", []}]}], [{"D", "1.0.0"}], {ok, ["B", "C", {"d", "1.0.0"}]}}; +mdeps(m_pick_source6) -> + {[{"B", [{"D", "1.0.0", []}]}, + {"C", [{"D", "1.0.0", []}]}], + none, + {ok, ["B", "C", {"D", "1.0.0"}]}}; mdeps(m_source_to_pkg) -> {[{"B", [{"c",[{"d", []}]}]}], [], @@ -436,6 +443,7 @@ m_pick_source2(Config) -> run(Config). m_pick_source3(Config) -> run(Config). m_pick_source4(Config) -> run(Config). m_pick_source5(Config) -> run(Config). +m_pick_source6(Config) -> run(Config). m_source_to_pkg(Config) -> run(Config). m_pkg_level1(Config) -> run(Config). m_pkg_level2(Config) -> run(Config). @@ -466,7 +474,10 @@ check_warnings(Warns, [{Type, Name, Vsn} | Rest], mixed) -> check_warnings(Warns, [{Name, Vsn} | Rest], Type) -> ct:pal("Checking for warning ~p in ~p", [{Name,Vsn},Warns]), ?assert(in_warnings(Type, Warns, Name, Vsn)), - check_warnings(Warns, Rest, Type). + check_warnings(Warns, Rest, Type); +check_warnings(Warns, none, _Type) -> + ct:pal("Checking that there were no warnings", []), + ?assert(Warns == []). in_warnings(git, Warns, NameRaw, VsnRaw) -> Name = iolist_to_binary(NameRaw), -- cgit v1.1 From 8e0ef83de48968fed80114cc4518004ed59fa649 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Wed, 19 Sep 2018 08:24:38 -0600 Subject: add option to compiler provider to only build dependencies (#1888) --- test/rebar_compile_SUITE.erl | 21 ++++++++++++++++++++- test/rebar_test_utils.erl | 8 ++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 10effda..269413e 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -23,7 +23,7 @@ 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, - profile_deps, deps_build_in_prod, + profile_deps, deps_build_in_prod, only_deps, override_deps, override_add_deps, override_del_deps, override_opts, override_add_opts, override_del_opts, apply_overrides_exactly_once, @@ -1655,6 +1655,25 @@ profile_deps(Config) -> {ok, [{dep, "some_dep"},{dep, "other_dep"}]} ). +only_deps(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]), + + Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + {SrcDeps, _} = rebar_test_utils:flat_deps(Deps), + mock_git_resource:mock([{deps, SrcDeps}]), + + RConfFile = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]), + {ok, RConf} = file:consult(RConfFile), + rebar_test_utils:run_and_check( + Config, RConf, ["compile", "--deps_only"], + {ok, [{app_not_exist, Name}, {dep, "some_dep"},{dep, "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 diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 8bcb6d1..efe7467 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -266,6 +266,14 @@ check_results(AppDir, Expected, ProfileRun) -> ok end ; ({dep_not_exist, Name}) -> + ct:pal("Dep Not Exist Name: ~p", [Name]), + case lists:keyfind(Name, 1, DepsNames) of + false -> + ok; + {Name, _App} -> + error({app_found, Name}) + end + ; ({app_not_exist, Name}) -> ct:pal("App Not Exist Name: ~p", [Name]), case lists:keyfind(Name, 1, DepsNames) of false -> -- cgit v1.1 From 2dfba204e4dea5d1c3821fd26d22bd7201595f6c Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 21 Sep 2018 10:32:57 -0600 Subject: properly support top level app erl_opts from REBAR_CONFIG os var (#1889) When REBAR_CONFIG was set it would not effect the top level app's configuration because app_discover was rereading the top level rebar.config which ignored REBAR_CONFIG. Instead this patch has it use the existing configuration from REBAR_CONFIG. --- test/rebar_compile_SUITE.erl | 28 +++++++++++++++++-- test/rebar_hooks_SUITE.erl | 65 ++++++++++++++++++++++++++++++++------------ test/rebar_test_utils.erl | 29 +++++++++++++++++++- 3 files changed, 101 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 269413e..e97b5fb 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -38,7 +38,8 @@ all() -> recursive, no_recursive, always_recompile_when_erl_compiler_options_set, dont_recompile_when_erl_compiler_options_env_does_not_change, - recompile_when_erl_compiler_options_env_changes]. + recompile_when_erl_compiler_options_env_changes, + rebar_config_os_var]. groups() -> [{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]}, @@ -774,7 +775,7 @@ recompile_when_opts_change(Config) -> rebar_test_utils:create_config(AppDir, [{erl_opts, [{d, some_define}]}]), - rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + rebar_test_utils:run_and_check(Config, [{erl_opts, [{d, some_define}]}], ["compile"], {ok, [{app, Name}]}), {ok, NewFiles} = rebar_utils:list_dir(EbinDir), NewModTime = [filelib:last_modified(filename:join([EbinDir, F])) @@ -1944,6 +1945,29 @@ recompile_when_erl_compiler_options_env_changes(Config) -> _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv) end. +rebar_config_os_var(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("rebar_config_os_var_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + + rebar_test_utils:create_config(AppDir, [{erl_opts, []}]), + + AltConfig = filename:join(AppDir, "test.rebar.config"), + file:write_file(AltConfig, "{erl_opts, [compressed]}."), + true = os:putenv("REBAR_CONFIG", AltConfig), + + rebar_test_utils:run_and_check(Config, ["compile"], {ok, [{app, Name}]}), + + Path = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + code:add_patha(Path), + + Mod = list_to_atom("not_a_real_src_" ++ Name), + + true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])), + ok. + %% this test sets the env var, compiles, records the file last modified %% timestamp, recompiles and compares the file last modified timestamp to %% ensure it has changed. this test should run on 18.x diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index 1f3edd2..aae7ea0 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -1,20 +1,6 @@ -module(rebar_hooks_SUITE). --export([suite/0, - init_per_suite/1, - end_per_suite/1, - init_per_testcase/2, - end_per_testcase/2, - all/0, - build_and_clean_app/1, - escriptize_artifacts/1, - run_hooks_once/1, - run_hooks_once_profiles/1, - run_hooks_for_plugins/1, - eunit_app_hooks/1, - deps_hook_namespace/1, - bare_compile_hooks_default_ns/1, - deps_clean_hook_namespace/1]). +-compile(export_all). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -38,7 +24,8 @@ end_per_testcase(_, _Config) -> all() -> [build_and_clean_app, run_hooks_once, run_hooks_once_profiles, escriptize_artifacts, run_hooks_for_plugins, deps_hook_namespace, - bare_compile_hooks_default_ns, deps_clean_hook_namespace, eunit_app_hooks]. + bare_compile_hooks_default_ns, deps_clean_hook_namespace, eunit_app_hooks, + sub_app_hooks, root_hooks]. %% Test post provider hook cleans compiled project app, leaving it invalid build_and_clean_app(Config) -> @@ -97,7 +84,7 @@ run_hooks_once(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{pre_hooks, [{compile, "mkdir blah"}]}], + RebarConfig = [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name, valid}]}). @@ -109,7 +96,7 @@ run_hooks_once_profiles(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir blah"}]}]}]}], + RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "hooks", "compile"], {ok, [{app, Name, valid}]}). @@ -215,3 +202,45 @@ run_hooks_for_plugins(Config) -> rebar_test_utils:run_and_check(Config, RConf, ["compile"], {ok, [{app, Name, valid}, {plugin, PluginName}, {file, filename:join([AppDir, "_build", "default", "plugins", PluginName, "randomfile"])}]}). + +%% test that a subapp of a project keeps its hooks +sub_app_hooks(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("sub_app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + + SubAppsDir = filename:join([AppDir, "apps", Name]), + + rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_config(SubAppsDir, [{provider_hooks, [{post, [{compile, clean}]}]}]), + + RConfFile = rebar_test_utils:create_config(AppDir, []), + {ok, RConf} = file:consult(RConfFile), + + %% Build with deps. + rebar_test_utils:run_and_check( + Config, RConf, ["compile"], + {ok, [{app, Name, invalid}]} + ). + +%% test that hooks at the top level don't run in the subapps +root_hooks(Config) -> + AppDir = ?config(apps, Config), + + Name = rebar_test_utils:create_random_name("sub_app1_"), + Vsn = rebar_test_utils:create_random_vsn(), + + SubAppsDir = filename:join([AppDir, "apps", Name]), + + rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), + rebar_test_utils:create_config(SubAppsDir, [{provider_hooks, [{post, [{compile, clean}]}]}]), + + RConfFile = rebar_test_utils:create_config(AppDir, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]), + {ok, RConf} = file:consult(RConfFile), + + %% Build with deps. + rebar_test_utils:run_and_check( + Config, RConf, ["compile"], + {ok, [{app, Name, invalid}]} + ). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index efe7467..944efa0 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -1,7 +1,7 @@ -module(rebar_test_utils). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). --export([init_rebar_state/1, init_rebar_state/2, run_and_check/4, check_results/3]). +-export([init_rebar_state/1, init_rebar_state/2, run_and_check/3, run_and_check/4, check_results/3]). -export([expand_deps/2, flat_deps/1, top_level_deps/1]). -export([create_app/4, create_plugin/4, create_eunit_app/4, create_empty_app/4, create_config/2, create_config/3, package_app/4]). @@ -82,6 +82,33 @@ run_and_check(Config, RebarConfig, Command, Expect) -> rebar_abort when Expect =:= rebar_abort -> rebar_abort end. +run_and_check(Config, Command, Expect) -> + %% Assumes init_rebar_state has run first + AppDir = ?config(apps, Config), + {ok, Cwd} = file:get_cwd(), + try + ok = file:set_cwd(AppDir), + Res = rebar3:run(Command), + case Expect of + {error, Reason} -> + ?assertEqual({error, Reason}, Res); + {ok, Expected} -> + {ok, _} = Res, + check_results(AppDir, Expected, "*"), + Res; + {ok, Expected, ProfileRun} -> + {ok, _} = Res, + check_results(AppDir, Expected, ProfileRun), + Res; + return -> + Res + end + catch + rebar_abort when Expect =:= rebar_abort -> rebar_abort + after + ok = file:set_cwd(Cwd) + end. + %% @doc Creates a dummy application including: %% - src/.erl %% - src/.app.src -- cgit v1.1 From 8bcb7da1dd294f13bc8d2040ec88f0b41b941e1b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 1 Oct 2018 15:41:34 -0600 Subject: warn if the matched package is retired, skip prerelease (#1897) retired packages are now used the same as any other but a warning will be printed when it is resolved. prerelease versions are skipped unless explicitly given as the version in the constraint or lock file. --- test/mock_pkg_resource.erl | 6 +-- test/rebar_pkg_SUITE.erl | 8 ++-- test/rebar_pkg_alias_SUITE.erl | 2 +- test/rebar_pkg_repos_SUITE.erl | 91 +++++++++++++++++++++++++++++++----------- 4 files changed, 76 insertions(+), 31 deletions(-) (limited to 'test') diff --git a/test/mock_pkg_resource.erl b/test/mock_pkg_resource.erl index 9a31461..a169efd 100644 --- a/test/mock_pkg_resource.erl +++ b/test/mock_pkg_resource.erl @@ -171,7 +171,7 @@ to_index(AllDeps, Dict, Repos) -> DKB <- [ec_cnv:to_binary(DK)], DVB <- [ec_cnv:to_binary(DV)]], Repo = rebar_test_utils:random_element(Repos), - ets:insert(?PACKAGE_TABLE, #package{key={N, V, Repo}, + ets:insert(?PACKAGE_TABLE, #package{key={N, ec_semver:parse(V), Repo}, dependencies=parse_deps(DepsList), retired=false, checksum = <<"checksum">>}) @@ -179,11 +179,11 @@ to_index(AllDeps, Dict, Repos) -> lists:foreach(fun({{Name, Vsn}, _}) -> case lists:any(fun(R) -> - ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(Name), Vsn, R}) + ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(Name), ec_semver:parse(Vsn), R}) end, Repos) of false -> Repo = rebar_test_utils:random_element(Repos), - ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(Name), Vsn, Repo}, + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(Name), ec_semver:parse(Vsn), Repo}, dependencies=[], retired=false, checksum = <<"checksum">>}); diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index 62bc4d1..b8495fd 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -226,13 +226,13 @@ find_highest_matching(_Config) -> State = rebar_state:new(), {ok, Vsn} = rebar_packages:find_highest_matching_( <<"goodpkg">>, <<"1.0.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), - ?assertEqual(<<"1.0.1">>, Vsn), + ?assertEqual({{1,0,1},{[],[]}}, Vsn), {ok, Vsn1} = rebar_packages:find_highest_matching( <<"goodpkg">>, <<"1.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), - ?assertEqual(<<"1.1.1">>, Vsn1), + ?assertEqual({{1,1,1},{[],[]}}, Vsn1), {ok, Vsn2} = rebar_packages:find_highest_matching( <<"goodpkg">>, <<"2.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), - ?assertEqual(<<"2.0.0">>, Vsn2), + ?assertEqual({{2,0,0},{[],[]}}, Vsn2), %% regression test. ~> constraints higher than the available packages would result %% in returning the first package version instead of 'none'. @@ -265,7 +265,7 @@ mock_config(Name, Config) -> lists:foreach(fun({{N, Vsn}, [Deps, Checksum, _]}) -> case ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(N), Vsn, <<"hexpm">>}) of false -> - ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), Vsn, <<"hexpm">>}, + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), ec_semver:parse(Vsn), <<"hexpm">>}, dependencies=Deps, retired=false, checksum=Checksum}); diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index d977b64..079a3fd 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -229,7 +229,7 @@ mock_config(Name, Config) -> lists:foreach(fun({{N, Vsn}, [Deps, Checksum, _]}) -> case ets:member(?PACKAGE_TABLE, {ec_cnv:to_binary(N), Vsn, <<"hexpm">>}) of false -> - ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), Vsn, <<"hexpm">>}, + ets:insert(?PACKAGE_TABLE, #package{key={ec_cnv:to_binary(N), ec_semver:parse(Vsn), <<"hexpm">>}, dependencies=[{DAppName, {pkg, DN, DV, undefined}} || {DN, DV, _, DAppName} <- Deps], retired=false, checksum=Checksum}); diff --git a/test/rebar_pkg_repos_SUITE.erl b/test/rebar_pkg_repos_SUITE.erl index 601566e..c808475 100644 --- a/test/rebar_pkg_repos_SUITE.erl +++ b/test/rebar_pkg_repos_SUITE.erl @@ -13,7 +13,7 @@ all() -> groups() -> [{resolve_version, [use_first_repo_match, use_exact_with_hash, fail_repo_update, - ignore_match_in_excluded_repo]}]. + ignore_match_in_excluded_repo, optional_prereleases]}]. init_per_group(resolve_version, Config) -> Repo1 = <<"test-repo-1">>, @@ -22,14 +22,17 @@ init_per_group(resolve_version, Config) -> Hexpm = <<"hexpm">>, Repos = [Repo1, Repo2, Repo3, Hexpm], - Deps = [{"A", "0.1.1", <<"good checksum">>, Repo1}, - {"A", "0.1.1", <<"good checksum">>, Repo2}, - {"B", "1.0.0", Repo1}, - {"B", "2.0.0", Repo2}, - {"B", "1.4.0", Repo3}, - {"B", "1.4.3", Hexpm}, - {"C", "1.3.1", <<"bad checksum">>, Repo1}, - {"C", "1.3.1", <<"good checksum">>, Repo2}], + Deps = [{"A", "0.1.1", <<"good checksum">>, Repo1, false}, + {"A", "0.1.1", <<"good checksum">>, Repo2, false}, + {"B", "1.0.0", Repo1, false}, + {"B", "2.0.0", Repo2, false}, + {"B", "1.4.0", Repo3, false}, + {"B", "1.4.3", Hexpm, false}, + {"B", "1.4.6", Hexpm, #{reason => 'RETIRED_INVALID'}}, + {"B", "1.5.0", Hexpm, false}, + {"B", "1.5.6-rc.0", Hexpm, true}, + {"C", "1.3.1", <<"bad checksum">>, Repo1, false}, + {"C", "1.3.1", <<"good checksum">>, Repo2, false}], [{deps, Deps}, {repos, Repos} | Config]; init_per_group(_, Config) -> Config. @@ -102,6 +105,20 @@ init_per_testcase(ignore_match_in_excluded_repo, Config) -> fun(_State) -> true end), [{state, State} | Config]; +init_per_testcase(optional_prereleases, Config) -> + Deps = ?config(deps, Config), + Repos = ?config(repos, Config), + + State = setup_deps_and_repos(Deps, Repos), + + meck:new(rebar_packages, [passthrough, no_link]), + + meck:expect(rebar_packages, update_package, + fun(_, _, _State) -> ok end), + meck:expect(rebar_packages, verify_table, + fun(_State) -> true end), + + [{state, State} | Config]; init_per_testcase(auth_merging, Config) -> meck:new(file, [passthrough, no_link, unstick]), meck:new(rebar_packages, [passthrough, no_link]), @@ -120,7 +137,8 @@ end_per_testcase(Case, _Config) when Case =:= auth_merging ; end_per_testcase(Case, _Config) when Case =:= use_first_repo_match ; Case =:= use_exact_with_hash ; Case =:= fail_repo_update ; - Case =:= ignore_match_in_excluded_repo -> + Case =:= ignore_match_in_excluded_repo ; + Case =:= optional_prereleases -> meck:unload(rebar_packages); end_per_testcase(_, _) -> ok. @@ -250,14 +268,14 @@ organization_merging(_Config) -> use_first_repo_match(Config) -> State = ?config(state, Config), - ?assertMatch({ok,{package,{<<"B">>, <<"2.0.0">>, Repo2}, + ?assertMatch({ok,{package,{<<"B">>, {{2,0,0}, {[],[]}}, Repo2}, <<"some checksum">>, false, []}, #{name := Repo2, http_adapter_config := #{profile := rebar}}}, rebar_packages:resolve_version(<<"B">>, <<"> 1.4.0">>, undefined, ?PACKAGE_TABLE, State)), - ?assertMatch({ok,{package,{<<"B">>, <<"1.4.0">>, Repo3}, + ?assertMatch({ok,{package,{<<"B">>, {{1,4,0}, {[],[]}}, Repo3}, <<"some checksum">>, false, []}, #{name := Repo3, http_adapter_config := #{profile := rebar}}}, @@ -268,7 +286,7 @@ use_first_repo_match(Config) -> use_exact_with_hash(Config) -> State = ?config(state, Config), - ?assertMatch({ok,{package,{<<"C">>, <<"1.3.1">>, Repo2}, + ?assertMatch({ok,{package,{<<"C">>, {{1,3,1}, {[],[]}}, Repo2}, <<"good checksum">>, false, []}, #{name := Repo2, http_adapter_config := #{profile := rebar}}}, @@ -278,7 +296,7 @@ use_exact_with_hash(Config) -> fail_repo_update(Config) -> State = ?config(state, Config), - ?assertMatch({ok,{package,{<<"B">>, <<"1.4.0">>, Repo3}, + ?assertMatch({ok,{package,{<<"B">>, {{1,4,0}, {[],[]}}, Repo3}, <<"some checksum">>, false, []}, #{name := Repo3, http_adapter_config := #{profile := rebar}}}, @@ -289,24 +307,51 @@ ignore_match_in_excluded_repo(Config) -> State = ?config(state, Config), Repos = ?config(repos, Config), - ?assertMatch({ok,{package,{<<"B">>, <<"1.4.3">>, Hexpm}, - <<"some checksum">>, false, []}, + ?assertMatch({ok,{package,{<<"B">>, {{1,4,6}, {[],[]}}, Hexpm}, + <<"some checksum">>, #{reason := 'RETIRED_INVALID'}, []}, #{name := Hexpm, http_adapter_config := #{profile := rebar}}}, rebar_packages:resolve_version(<<"B">>, <<"~> 1.4.0">>, undefined, ?PACKAGE_TABLE, State)), [_, Repo2 | _] = Repos, - ?assertMatch({ok,{package,{<<"A">>, <<"0.1.1">>, Repo2}, + ?assertMatch({ok,{package,{<<"A">>, {{0,1,1}, {[],[]}}, Repo2}, <<"good checksum">>, false, []}, #{name := Repo2, http_adapter_config := #{profile := rebar}}}, rebar_packages:resolve_version(<<"A">>, <<"0.1.1">>, <<"good checksum">>, ?PACKAGE_TABLE, State)). +optional_prereleases(Config) -> + State = ?config(state, Config), + + ?assertMatch({ok,{package,{<<"B">>, {{1,5,0}, {[],[]}}, Hexpm}, + <<"some checksum">>, false, []}, + #{name := Hexpm, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"~> 1.5.0">>, undefined, + ?PACKAGE_TABLE, State)), + + ?assertMatch({ok,{package,{<<"B">>, {{1,5,6}, {[<<"rc">>,0],[]}}, Hexpm}, + <<"some checksum">>, true, []}, + #{name := Hexpm, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"1.5.6-rc.0">>, <<"some checksum">>, + ?PACKAGE_TABLE, State)), + + %% allow prerelease through configuration + State1 = rebar_state:set(State, deps_allow_prerelease, true), + ?assertMatch({ok,{package,{<<"B">>, {{1,5,6}, {[<<"rc">>,0],[]}}, Hexpm}, + <<"some checksum">>, true, []}, + #{name := Hexpm, + http_adapter_config := #{profile := rebar}}}, + rebar_packages:resolve_version(<<"B">>, <<"~> 1.5.0">>, <<"some checksum">>, + ?PACKAGE_TABLE, State1)). + %% setup_deps_and_repos(Deps, Repos) -> + catch ets:delete(?PACKAGE_TABLE), true = rebar_packages:new_package_table(), insert_deps(Deps), State = rebar_state:new([{hex, [{repos, [#{name => R} || R <- Repos]}]}]), @@ -314,18 +359,18 @@ setup_deps_and_repos(Deps, Repos) -> insert_deps(Deps) -> - lists:foreach(fun({Name, Version, Repo}) -> + lists:foreach(fun({Name, Version, Repo, Retired}) -> ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name), - rebar_utils:to_binary(Version), + ec_semver:parse(Version), rebar_utils:to_binary(Repo)}, dependencies=[], - retired=false, + retired=Retired, checksum = <<"some checksum">>}); - ({Name, Version, Checksum, Repo}) -> + ({Name, Version, Checksum, Repo, Retired}) -> ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name), - rebar_utils:to_binary(Version), + ec_semver:parse(Version), rebar_utils:to_binary(Repo)}, dependencies=[], - retired=false, + retired=Retired, checksum = Checksum}) end, Deps). -- cgit v1.1 From dec484643c233fda9c17d38c1854ba7f3f37547b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 5 Oct 2018 08:29:07 -0600 Subject: compiler behaviour (#1893) * add compile type for dynamic project compilation * new rebar_compiler abstraction for running multiple compilers rebar_compiler is a new behaviour that a plugin can implement to be called on any ues of the compile provider to compile source files and keep track of their dependencies. * fix check that modules in .app modules list are from src_dirs * use project_type to find module for building projects * allow plugins to add project builders and compilers --- test/rebar_eunit_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_eunit_SUITE.erl b/test/rebar_eunit_SUITE.erl index 4805b3d..1a8bade 100644 --- a/test/rebar_eunit_SUITE.erl +++ b/test/rebar_eunit_SUITE.erl @@ -605,4 +605,4 @@ alternate_test_regex(Config) -> Set = {ok, [{application, basic_app}, {module, basic_app_tests}]}, - Set = rebar_prv_eunit:prepare_tests(S). \ No newline at end of file + Set = rebar_prv_eunit:prepare_tests(S). -- cgit v1.1 From 763fd05a0f6be023a4f646c55ddd72ae193e350b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 6 Oct 2018 18:52:20 -0600 Subject: fix yrl compiler and add test (#1906) --- test/rebar_compile_SUITE.erl | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index e97b5fb..867460c 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -832,19 +832,36 @@ dont_recompile_yrl_or_xrl(Config) -> "Erlang code.", ok = ec_file:write(Xrl, XrlBody), + Yrl = filename:join([AppDir, "src", "not_a_real_yrl_" ++ Name ++ ".yrl"]), + ok = filelib:ensure_dir(Yrl), + YrlBody = ["Nonterminals E T F.\n" + "Terminals '+' '*' '(' ')' number.\n" + "Rootsymbol E.\n" + "E -> E '+' T: {'$2', '$1', '$3'}.\n" + "E -> T : '$1'.\n" + "T -> T '*' F: {'$2', '$1', '$3'}.\n" + "T -> F : '$1'.\n" + "F -> '(' E ')' : '$2'.\n" + "F -> number : '$1'.\n"], + ok = ec_file:write(Yrl, YrlBody), + XrlBeam = filename:join([AppDir, "ebin", filename:basename(Xrl, ".xrl") ++ ".beam"]), + YrlBeam = filename:join([AppDir, "ebin", filename:basename(Yrl, ".yrl") ++ ".beam"]), rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), - ModTime = filelib:last_modified(XrlBeam), + XrlModTime = filelib:last_modified(XrlBeam), + YrlModTime = filelib:last_modified(YrlBeam), timer:sleep(1000), rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), - NewModTime = filelib:last_modified(XrlBeam), + NewXrlModTime = filelib:last_modified(XrlBeam), + NewYrlModTime = filelib:last_modified(YrlBeam), - ?assert(ModTime == NewModTime). + ?assert(XrlModTime == NewXrlModTime), + ?assert(YrlModTime == NewYrlModTime). delete_beam_if_source_deleted(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 9d788d893620f868b9c0ee00ddec8ae4d5d8fea7 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Fri, 5 Oct 2018 07:57:20 -0400 Subject: Abstracted path management Move path management out of rebar_utils manual code path function handling (which we leave there for backwards compat), and centralize them to allow easier coordination of paths between plugins and deps. On top of path handling, do a check of loaded modules to only purge and reload those that actually need it done in order to prevent all kinds of weird interaction and accidental purge kills. It also allows the possible cohabitation of both at once, with a "in case of conflict pick X" as a policy Changing path handling in providers also highlighted a bunch of bugs in some tests and appears to fix some in other providers, specifically around plugins. --- test/rebar_compile_SUITE.erl | 5 +- test/rebar_paths_SUITE.erl | 211 +++++++++++++++++++++++++++++++++++++++++++ test/rebar_plugins_SUITE.erl | 2 +- 3 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 test/rebar_paths_SUITE.erl (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 867460c..6b1d791 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1856,7 +1856,7 @@ include_file_in_src_test_multiapp(Config) -> AppDir1 = filename:join([?config(apps, Config), "lib", Name1]), AppDir2 = filename:join([?config(apps, Config), "lib", Name2]), Vsn = rebar_test_utils:create_random_vsn(), - rebar_test_utils:create_app(AppDir1, Name1, Vsn, [kernel, stdlib]), + rebar_test_utils:create_app(AppDir1, Name1, Vsn, [kernel, stdlib, list_to_atom(Name2)]), rebar_test_utils:create_app(AppDir2, Name2, Vsn, [kernel, stdlib]), Src = "-module(test).\n" @@ -1878,7 +1878,8 @@ include_file_in_src_test_multiapp(Config) -> RebarConfig = [], rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "test", "compile"], - {ok, [{app, Name1}]}). + {ok, [{app, Name1}]}), + ok. %% this test sets the env var, compiles, records the file last modified timestamp, %% recompiles and compares the file last modified timestamp to ensure it hasn't diff --git a/test/rebar_paths_SUITE.erl b/test/rebar_paths_SUITE.erl new file mode 100644 index 0000000..48a7000 --- /dev/null +++ b/test/rebar_paths_SUITE.erl @@ -0,0 +1,211 @@ +-module(rebar_paths_SUITE). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). +-compile(export_all). + +all() -> + [%clashing_apps, + check_modules, + set_paths + ]. + +init_per_testcase(Case, Config) -> + BasePaths = code:get_path(), + %% This test checks that the right module sets get loaded; however, we must + %% ensure that we do not have clashes with other test suites' loaded modules, + %% which we cannot track. As such, we have to ensure all module names here are + %% unique. + %% + %% This is done by hand; if you see this test suite failing on its own, you + %% probably wrote a test suite that clashes! + Dir = filename:join([?config(priv_dir, Config), atom_to_list(?MODULE), + atom_to_list(Case)]), + InDir = fun(Path) -> filename:join([Dir, Path]) end, + ADep = fake_app(<<"rp_a">>, <<"1.0.0">>, InDir("_build/default/lib/rp_a/")), + BDep = fake_app(<<"rp_b">>, <<"1.0.0">>, InDir("_build/default/lib/rp_b/")), + CDep = fake_app(<<"rp_c">>, <<"1.0.0">>, InDir("_build/default/lib/rp_c/")), + DDep = fake_app(<<"rp_d">>, <<"1.0.0">>, InDir("_build/default/lib/rp_d/")), + RelxDep = fake_app(<<"relx">>, <<"1.0.0">>, InDir("_build/default/lib/relx/")), + + APlug = fake_app(<<"rp_a">>, <<"1.0.0">>, + InDir("_build/default/plugins/lib/rp_a/")), + RelxPlug = fake_app(<<"relx">>, <<"1.1.1">>, + InDir("_build/default/plugins/lib/relx")), + EPlug = fake_app(<<"rp_e">>, <<"1.0.0">>, + InDir("_build/default/plugins/lib/rp_e/")), + + S0 = rebar_state:new(), + S1 = rebar_state:all_deps(S0, [ADep, BDep, CDep, DDep, RelxDep]), + S2 = rebar_state:all_plugin_deps(S1, [APlug, RelxPlug]), + S3 = rebar_state:code_paths(S2, default, code:get_path()), + S4 = rebar_state:code_paths( + S3, + all_deps, + [rebar_app_info:ebin_dir(A) || A <- [ADep, BDep, CDep, DDep, RelxDep]] + ), + S5 = rebar_state:code_paths( + S4, + all_plugin_deps, + [rebar_app_info:ebin_dir(A) || A <- [APlug, RelxPlug, EPlug]] + ), + [{base_paths, BasePaths}, {root_dir, Dir}, {state, S5} | Config]. + +end_per_testcase(_, Config) -> + %% this is deeply annoying because we interfere with rebar3's own + %% path handling! + rebar_paths:unset_paths([plugins, deps], ?config(state, Config)), + Config. + +fake_app(Name, Vsn, OutDir) -> + {ok, App} = rebar_app_info:new(Name, Vsn, OutDir), + compile_fake_appmod(App), + App. + +compile_fake_appmod(App) -> + OutDir = rebar_app_info:ebin_dir(App), + Vsn = rebar_app_info:original_vsn(App), + Name = rebar_app_info:name(App), + + ok = filelib:ensure_dir(filename:join([OutDir, ".touch"])), + + AppFile = [ + "{application,", Name, ", " + " [{description, \"some app\"}, " + " {vsn, \"", Vsn, "\"}, " + " {modules, [",Name,"]}, " + " {registered, []}, " + " {applications, [stdlib, kernel]} " + " ]}. "], + + ok = file:write_file(filename:join([OutDir, <>]), AppFile), + + Mod = [{attribute, 1, module, binary_to_atom(Name, utf8)}, + {attribute, 2, export, [{f,0}]}, + {function,3,f,0, + [{clause,3, [], [], + [{string,3,OutDir}] + }]} + ], + + {ok, _, Bin} = compile:forms(Mod), + ok = file:write_file(filename:join([OutDir, <>]), Bin). + +clashing_apps(Config) -> + Clashes = rebar_paths:clashing_apps([deps, plugins], + ?config(state, Config)), + ct:pal("Clashes: ~p", [Clashes]), + + ?assertEqual([<<"relx">>, <<"rp_a">>], lists:sort(proplists:get_value(deps, Clashes))), + ?assertEqual(undefined, proplists:get_value(plugins, Clashes)), + ok. + +set_paths(Config) -> + State = ?config(state, Config), + RootDir = filename:split(?config(root_dir, Config)), + rebar_paths:set_paths([plugins, deps], State), + PluginPaths = code:get_path(), + rebar_paths:set_paths([deps, plugins], State), + DepPaths = code:get_path(), + + ?assertEqual( + RootDir ++ ["_build", "default", "plugins", "lib", "rp_a", "ebin"], + find_first_instance("rp_a", PluginPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_b", "ebin"], + find_first_instance("rp_b", PluginPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_c", "ebin"], + find_first_instance("rp_c", PluginPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_d", "ebin"], + find_first_instance("rp_d", PluginPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "plugins", "lib", "rp_e", "ebin"], + find_first_instance("rp_e", PluginPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "plugins", "lib", "relx", "ebin"], + find_first_instance("relx", PluginPaths) + ), + + + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_a", "ebin"], + find_first_instance("rp_a", DepPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_b", "ebin"], + find_first_instance("rp_b", DepPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_c", "ebin"], + find_first_instance("rp_c", DepPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "rp_d", "ebin"], + find_first_instance("rp_d", DepPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "plugins", "lib", "rp_e", "ebin"], + find_first_instance("rp_e", DepPaths) + ), + ?assertEqual( + RootDir ++ ["_build", "default", "lib", "relx", "ebin"], + find_first_instance("relx", DepPaths) + ), + ok. + +check_modules(Config) -> + State = ?config(state, Config), + RootDir = ?config(root_dir, Config)++"/", + rebar_paths:set_paths([plugins, deps], State), + ct:pal("code:get_path() -> ~p", [code:get_path()]), + + ?assertEqual(RootDir ++ "_build/default/plugins/lib/rp_a/ebin", rp_a:f()), + ct:pal("~p", [catch file:list_dir(RootDir ++ "_build/default/lib/")]), + ct:pal("~p", [catch file:list_dir(RootDir ++ "_build/default/lib/rp_b/")]), + ct:pal("~p", [catch file:list_dir(RootDir ++ "_build/default/lib/rp_b/ebin")]), + ct:pal("~p", [catch b:module_info()]), + ?assertEqual(RootDir ++ "_build/default/lib/rp_b/ebin", rp_b:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_c/ebin", rp_c:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_d/ebin", rp_d:f()), + ?assertEqual(RootDir ++ "_build/default/plugins/lib/rp_e/ebin", rp_e:f()), + ?assertEqual(RootDir ++ "_build/default/plugins/lib/relx/ebin", relx:f()), + ?assertEqual(3, length(relx:module_info(exports))), % can't replace bundled + + rebar_paths:set_paths([deps, plugins], State), + ct:pal("code:get_path() -> ~p", [code:get_path()]), + + ?assertEqual(RootDir ++ "_build/default/lib/rp_a/ebin", rp_a:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_b/ebin", rp_b:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_c/ebin", rp_c:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_d/ebin", rp_d:f()), + ?assertEqual(RootDir ++ "_build/default/plugins/lib/rp_e/ebin", rp_e:f()), + ?assertEqual(RootDir ++ "_build/default/lib/relx/ebin", relx:f()), + ?assertEqual(3, length(relx:module_info(exports))), % can't replace bundled + + %% once again + rebar_paths:set_paths([plugins, deps], State), + ct:pal("code:get_path() -> ~p", [code:get_path()]), + + ?assertEqual(RootDir ++ "_build/default/plugins/lib/rp_a/ebin", rp_a:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_b/ebin", rp_b:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_c/ebin", rp_c:f()), + ?assertEqual(RootDir ++ "_build/default/lib/rp_d/ebin", rp_d:f()), + ?assertEqual(RootDir ++ "_build/default/plugins/lib/rp_e/ebin", rp_e:f()), + ?assertEqual(RootDir ++ "_build/default/plugins/lib/relx/ebin", relx:f()), + ?assertEqual(3, length(relx:module_info(exports))), % can't replace bundled + ok. + +find_first_instance(Frag, []) -> + {not_found, Frag}; +find_first_instance(Frag, [Path|Rest]) -> + Frags = filename:split(Path), + case lists:member(Frag, Frags) of + true -> Frags; + false -> find_first_instance(Frag, Rest) + end. diff --git a/test/rebar_plugins_SUITE.erl b/test/rebar_plugins_SUITE.erl index 2d74539..c7a5d51 100644 --- a/test/rebar_plugins_SUITE.erl +++ b/test/rebar_plugins_SUITE.erl @@ -335,7 +335,7 @@ project_plugins(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), DepName = rebar_test_utils:create_random_name("dep1_"), - PluginName = "compile", + PluginName = "compile_plugin", PluginName2 = "release", Plugins = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, []}, {PluginName2, Vsn, []}]), -- cgit v1.1 From af5cecd8eec9692f43d04ad53c8f28734012b873 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Mon, 8 Oct 2018 12:41:30 -0400 Subject: Clean path code, add tests, add clash detection Some finishing touch to that code --- test/rebar_paths_SUITE.erl | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_paths_SUITE.erl b/test/rebar_paths_SUITE.erl index 48a7000..f2832c0 100644 --- a/test/rebar_paths_SUITE.erl +++ b/test/rebar_paths_SUITE.erl @@ -4,11 +4,16 @@ -compile(export_all). all() -> - [%clashing_apps, + [clashing_apps, check_modules, - set_paths + set_paths, + misloaded_mods ]. +%%%%%%%%%%%%%%%%%% +%%% TEST SETUP %%% +%%%%%%%%%%%%%%%%%% + init_per_testcase(Case, Config) -> BasePaths = code:get_path(), %% This test checks that the right module sets get loaded; however, we must @@ -90,13 +95,17 @@ compile_fake_appmod(App) -> {ok, _, Bin} = compile:forms(Mod), ok = file:write_file(filename:join([OutDir, <>]), Bin). +%%%%%%%%%%%%% +%%% TESTS %%% +%%%%%%%%%%%%% + clashing_apps(Config) -> Clashes = rebar_paths:clashing_apps([deps, plugins], ?config(state, Config)), ct:pal("Clashes: ~p", [Clashes]), ?assertEqual([<<"relx">>, <<"rp_a">>], lists:sort(proplists:get_value(deps, Clashes))), - ?assertEqual(undefined, proplists:get_value(plugins, Clashes)), + ?assertEqual([], proplists:get_value(plugins, Clashes)), ok. set_paths(Config) -> @@ -201,6 +210,28 @@ check_modules(Config) -> ?assertEqual(3, length(relx:module_info(exports))), % can't replace bundled ok. +misloaded_mods(_Config) -> + Res = rebar_paths:misloaded_modules( + [a,b,c,d,e,f], + ["/1/2/3/4", + "/1/2/4", + "/2/1/1", + "/3/4/5"], + [{a, "/0/1/2/file.beam"}, + {aa, "/1/2/3/4/file.beam"}, + {b, "/1/2/3/4/file.beam"}, + {c, "/2/1/file.beam"}, + {f, preloaded}, + {d, "/3/5/7/file.beam"}, + {e, "/3/4/5/file.beam"}] + ), + ?assertEqual([a,c,d], Res), + ok. + +%%%%%%%%%%%%%%% +%%% HELPERS %%% +%%%%%%%%%%%%%%% + find_first_instance(Frag, []) -> {not_found, Frag}; find_first_instance(Frag, [Path|Rest]) -> -- cgit v1.1 From dada4e36e6d9a5c4b41bbe1f68389520e7c59ace Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 11 Oct 2018 08:38:37 -0400 Subject: Optimize path handling - Only set paths that need to be put as a priority - Clean up paths before leaving API mode The first point accounted for some performance cost, but the latter one explains the 40% overhead in test runs: since rebar3 calls rebar3 a lot with a bunch of fake apps, and that the new mechanism for path handling by default does not _remove_ paths, it just _orders_ them, we would end up in a situation where as the tests ran, more and more fake paths would get added to the VM. By the time the run was over, all path handling would take longer since more paths needed filtering every time. By resetting paths at the end of an API run, we prevent a given 'project' from polluting another one's runtime and performance once the API successfully returns. --- test/rebar_paths_SUITE.erl | 2 -- 1 file changed, 2 deletions(-) (limited to 'test') diff --git a/test/rebar_paths_SUITE.erl b/test/rebar_paths_SUITE.erl index f2832c0..96cda45 100644 --- a/test/rebar_paths_SUITE.erl +++ b/test/rebar_paths_SUITE.erl @@ -212,13 +212,11 @@ check_modules(Config) -> misloaded_mods(_Config) -> Res = rebar_paths:misloaded_modules( - [a,b,c,d,e,f], ["/1/2/3/4", "/1/2/4", "/2/1/1", "/3/4/5"], [{a, "/0/1/2/file.beam"}, - {aa, "/1/2/3/4/file.beam"}, {b, "/1/2/3/4/file.beam"}, {c, "/2/1/file.beam"}, {f, preloaded}, -- cgit v1.1 From a80d1988963698717548ba269d7e5f915fca4e27 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 14 Oct 2018 09:37:50 -0600 Subject: fix finding transitive deps with prerelease versions (#1914) --- test/rebar_pkg_SUITE.erl | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl index b8495fd..ee74af5 100644 --- a/test/rebar_pkg_SUITE.erl +++ b/test/rebar_pkg_SUITE.erl @@ -225,19 +225,24 @@ pkgs_provider(Config) -> find_highest_matching(_Config) -> State = rebar_state:new(), {ok, Vsn} = rebar_packages:find_highest_matching_( - <<"goodpkg">>, <<"1.0.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), + <<"goodpkg">>, ec_semver:parse(<<"1.0.0">>), #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual({{1,0,1},{[],[]}}, Vsn), {ok, Vsn1} = rebar_packages:find_highest_matching( - <<"goodpkg">>, <<"1.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), + <<"goodpkg">>, ec_semver:parse(<<"1.0">>), #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual({{1,1,1},{[],[]}}, Vsn1), {ok, Vsn2} = rebar_packages:find_highest_matching( - <<"goodpkg">>, <<"2.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), + <<"goodpkg">>, ec_semver:parse(<<"2.0">>), #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), ?assertEqual({{2,0,0},{[],[]}}, Vsn2), %% regression test. ~> constraints higher than the available packages would result %% in returning the first package version instead of 'none'. - ?assertEqual(none, rebar_packages:find_highest_matching_(<<"goodpkg">>, <<"~> 5.0">>, - #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State)). + ?assertEqual(none, rebar_packages:find_highest_matching_(<<"goodpkg">>, ec_semver:parse(<<"5.0">>), + #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State)), + + + {ok, Vsn3} = rebar_packages:find_highest_matching_(<<"goodpkg">>, ec_semver:parse(<<"3.0.0-rc.0">>), + #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State), + ?assertEqual({{3,0,0},{[<<"rc">>,0],[]}}, Vsn3). %%%%%%%%%%%%%%% %%% Helpers %%% @@ -253,6 +258,7 @@ mock_config(Name, Config) -> {{<<"goodpkg">>,<<"1.0.1">>}, [[], ?good_checksum, [<<"rebar3">>]]}, {{<<"goodpkg">>,<<"1.1.1">>}, [[], ?good_checksum, [<<"rebar3">>]]}, {{<<"goodpkg">>,<<"2.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}, + {{<<"goodpkg">>,<<"3.0.0-rc.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}, {{<<"badpkg">>,<<"1.0.0">>}, [[], ?badpkg_checksum, [<<"rebar3">>]]} ], ets:insert_new(Tid, AllDeps), -- cgit v1.1 From c9fbb4a44feac75a325c5831293901d5cb12075a Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Thu, 18 Oct 2018 15:38:48 -0400 Subject: Fix shell hook expansion on windows Dollar Variable expansion (`$VAR`) was inadvertently disabled for windows variables, although %VARIABLES% already worked. This reduced the portability of hooks in general. Additionally, tests would fail on windows due to bad quoting of paths: the path C:/a/b/c would fail when passed to the command `cmd /q /c C:/a/b/c` because it would interpret /a /b and /c as 3 options. Using quotes makes the tests pass. --- test/rebar_hooks_SUITE.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index aae7ea0..29e343f 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -84,7 +84,7 @@ run_hooks_once(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}], + RebarConfig = [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name, valid}]}). @@ -96,7 +96,7 @@ run_hooks_once_profiles(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]}]}], + RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}]}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "hooks", "compile"], {ok, [{app, Name, valid}]}). @@ -236,7 +236,7 @@ root_hooks(Config) -> rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:create_config(SubAppsDir, [{provider_hooks, [{post, [{compile, clean}]}]}]), - RConfFile = rebar_test_utils:create_config(AppDir, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]), + RConfFile = rebar_test_utils:create_config(AppDir, [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}]), {ok, RConf} = file:consult(RConfFile), %% Build with deps. -- cgit v1.1 From 8d31d559c18b12d3d06655de2ca9c7f76c67c948 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 9 Nov 2018 12:22:12 -0700 Subject: check last modified time on erl files for xrl and yrl files before compiling --- test/rebar_compile_SUITE.erl | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 6b1d791..4d51f2a 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -845,20 +845,33 @@ dont_recompile_yrl_or_xrl(Config) -> "F -> number : '$1'.\n"], ok = ec_file:write(Yrl, YrlBody), - XrlBeam = filename:join([AppDir, "ebin", filename:basename(Xrl, ".xrl") ++ ".beam"]), - YrlBeam = filename:join([AppDir, "ebin", filename:basename(Yrl, ".yrl") ++ ".beam"]), + XrlErl = filename:join([AppDir, "src", filename:basename(Xrl, ".xrl") ++ ".erl"]), + YrlErl = filename:join([AppDir, "src", filename:basename(Yrl, ".yrl") ++ ".erl"]), + + EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), + XrlBeam = filename:join([EbinDir, filename:basename(Xrl, ".xrl") ++ ".beam"]), + YrlBeam = filename:join([EbinDir, filename:basename(Yrl, ".yrl") ++ ".beam"]), rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), - XrlModTime = filelib:last_modified(XrlBeam), - YrlModTime = filelib:last_modified(YrlBeam), + XrlModTime = filelib:last_modified(XrlErl), + YrlModTime = filelib:last_modified(YrlErl), + + XrlBeamModTime = filelib:last_modified(XrlBeam), + YrlBeamModTime = filelib:last_modified(YrlBeam), timer:sleep(1000), rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), - NewXrlModTime = filelib:last_modified(XrlBeam), - NewYrlModTime = filelib:last_modified(YrlBeam), + NewXrlModTime = filelib:last_modified(XrlErl), + NewYrlModTime = filelib:last_modified(YrlErl), + + NewXrlBeamModTime = filelib:last_modified(XrlBeam), + NewYrlBeamModTime = filelib:last_modified(YrlBeam), + + ?assert(XrlBeamModTime == NewXrlBeamModTime), + ?assert(YrlBeamModTime == NewYrlBeamModTime), ?assert(XrlModTime == NewXrlModTime), ?assert(YrlModTime == NewYrlModTime). -- cgit v1.1 From 5facb035fe67a0e2683c6460833ac1ec8baa8c82 Mon Sep 17 00:00:00 2001 From: tothlac Date: Sun, 11 Nov 2018 17:12:41 +0100 Subject: Support alias format {Namespace, Cmd} and {Namespace, Cmd, Args} (#1940) --- test/rebar_alias_SUITE.erl | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_alias_SUITE.erl b/test/rebar_alias_SUITE.erl index 2544aac..d6e27d9 100644 --- a/test/rebar_alias_SUITE.erl +++ b/test/rebar_alias_SUITE.erl @@ -13,8 +13,8 @@ init_per_testcase(_, Config) -> end_per_testcase(_, _Config) -> ok. -all() -> [command, args, many, override_default, no_circular, release]. - %% namespaces: unsupported, untested. +all() -> [command, args, many, override_default, no_circular, release, + check_namespaces, create_lib]. command() -> [{doc, "Runs multiple regular commands as one alias"}]. @@ -136,3 +136,30 @@ release(Config) -> ["the_rel2"], {ok, [{release, the_release, Vsn, false}]}), ok. + +check_namespaces() -> + [{doc, "Test calling commands with namespaces from rebar3"}]. +check_namespaces(Config) -> + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("alias_args_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [{eunit,"-c"}, {plugins, list}]}]}], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["test"], {ok, [{app, Name}]}), + ok. + +create_lib() -> + [{doc, "Test calling commands with namespaces from rebar3"}]. +create_lib(Config) -> + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("create_lib_"), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + RebarConfig = [{alias, [{test, [compile, {do, "new lib shouldexist"}]}]}], + rebar_test_utils:run_and_check(Config, RebarConfig, + ["test"], {ok, [{app, Name}]}), + AppFile = filename:join(?config(apps, Config), + "../../../../shouldexist/src/shouldexist.app.src"), + ?assert(filelib:is_file(AppFile)), + ok. -- cgit v1.1 From 37fdc7e515bd3db197cec92fa476923d19ec283a Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 23 Nov 2018 14:56:03 -0700 Subject: fix base path used for yrl/xrl includefile configs (#1952) --- test/rebar_compile_SUITE.erl | 150 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 4d51f2a..9cbe8a2 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -852,7 +852,13 @@ dont_recompile_yrl_or_xrl(Config) -> XrlBeam = filename:join([EbinDir, filename:basename(Xrl, ".xrl") ++ ".beam"]), YrlBeam = filename:join([EbinDir, filename:basename(Yrl, ".yrl") ++ ".beam"]), - rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + Hrl = filename:join([AppDir, "include", "some_header.hrl"]), + ok = filelib:ensure_dir(Hrl), + HrlBody = yeccpre_hrl(), + ok = ec_file:write(Hrl, HrlBody), + RebarConfig = [{yrl_opts, [{includefile, "include/some_header.hrl"}]}], + + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), XrlModTime = filelib:last_modified(XrlErl), YrlModTime = filelib:last_modified(YrlErl), @@ -862,7 +868,7 @@ dont_recompile_yrl_or_xrl(Config) -> timer:sleep(1000), - rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}), + rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), NewXrlModTime = filelib:last_modified(XrlErl), NewYrlModTime = filelib:last_modified(YrlErl), @@ -2208,3 +2214,143 @@ regex_filter_regression(Config) -> {ok, [{file, Expected}]}), ok. +%% + +%% a copy of lib/parsetools/include/yeccpre.hrl so we can test yrl includefile +yeccpre_hrl() -> + <<"-type yecc_ret() :: {'error', _} | {'ok', _}. + +-spec parse(Tokens :: list()) -> yecc_ret(). +parse(Tokens) -> + yeccpars0(Tokens, {no_func, no_line}, 0, [], []). + +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). +parse_and_scan({F, A}) -> + yeccpars0([], {{F, A}, no_line}, 0, [], []); +parse_and_scan({M, F, A}) -> + Arity = length(A), + yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). + +-spec format_error(any()) -> [char() | list()]. +format_error(Message) -> + case io_lib:deep_char_list(Message) of + true -> + Message; + _ -> + io_lib:write(Message) + end. + +%% To be used in grammar files to throw an error message to the parser +%% toplevel. Doesn't have to be exported! +-compile({nowarn_unused_function, return_error/2}). +-spec return_error(integer(), any()) -> no_return(). +return_error(Line, Message) -> + throw({error, {Line, ?MODULE, Message}}). + +-define(CODE_VERSION, \"1.4\"). + +yeccpars0(Tokens, Tzr, State, States, Vstack) -> + try yeccpars1(Tokens, Tzr, State, States, Vstack) + catch + error:Error -> + try yecc_error_type(Error, []) of + Desc -> + erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, + []) + catch _:_ -> erlang:raise(error, Error, []) + end; + %% Probably thrown from return_error/2: + throw: {error, {_Line, ?MODULE, _M}} = Error -> + Error + end. + +yecc_error_type(function_clause, _) -> + not_implemented. + +yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> + yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr); +yeccpars1([], {{F, A},_Line}, State, States, Vstack) -> + case apply(F, A) of + {ok, Tokens, Endline} -> + yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack); + {eof, Endline} -> + yeccpars1([], {no_func, Endline}, State, States, Vstack); + {error, Descriptor, _Endline} -> + {error, Descriptor} + end; +yeccpars1([], {no_func, no_line}, State, States, Vstack) -> + Line = 999999, + yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [], + {no_func, Line}); +yeccpars1([], {no_func, Endline}, State, States, Vstack) -> + yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [], + {no_func, Endline}). + +%% yeccpars1/7 is called from generated code. +%% +%% When using the {includefile, Includefile} option, make sure that +%% yeccpars1/7 can be found by parsing the file without following +%% include directives. yecc will otherwise assume that an old +%% yeccpre.hrl is included (one which defines yeccpars1/5). +yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) -> + yeccpars2(State, element(1, Token), [State1 | States], + [Token0 | Vstack], Token, Tokens, Tzr); +yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) -> + yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) -> + Line = yecctoken_end_location(Token0), + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}); +yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) -> + yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack], + yecc_end(Line), [], {no_func, Line}). + +%% For internal use only. +yecc_end({Line,_Column}) -> + {'$end', Line}; +yecc_end(Line) -> + {'$end', Line}. + +yecctoken_end_location(Token) -> + try erl_anno:end_location(element(2, Token)) of + undefined -> yecctoken_location(Token); + Loc -> Loc + catch _:_ -> yecctoken_location(Token) + end. + +-compile({nowarn_unused_function, yeccerror/1}). +yeccerror(Token) -> + Text = yecctoken_to_string(Token), + Location = yecctoken_location(Token), + {error, {Location, ?MODULE, [\"syntax error before: \", Text]}}. + +-compile({nowarn_unused_function, yecctoken_to_string/1}). +yecctoken_to_string(Token) -> + try erl_scan:text(Token) of + undefined -> yecctoken2string(Token); + Txt -> Txt + catch _:_ -> yecctoken2string(Token) + end. + +yecctoken_location(Token) -> + try erl_scan:location(Token) + catch _:_ -> element(2, Token) + end. + +-compile({nowarn_unused_function, yecctoken2string/1}). +yecctoken2string({atom, _, A}) -> io_lib:write_atom(A); +yecctoken2string({integer,_,N}) -> io_lib:write(N); +yecctoken2string({float,_,F}) -> io_lib:write(F); +yecctoken2string({char,_,C}) -> io_lib:write_char(C); +yecctoken2string({var,_,V}) -> io_lib:format(\"~s\", [V]); +yecctoken2string({string,_,S}) -> io_lib:write_string(S); +yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); +yecctoken2string({_Cat, _, Val}) -> io_lib:format(\"~p\", [Val]); +yecctoken2string({dot, _}) -> \"'.'\"; +yecctoken2string({'$end', _}) -> []; +yecctoken2string({Other, _}) when is_atom(Other) -> + io_lib:write_atom(Other); +yecctoken2string(Other) -> + io_lib:format(\"~p\", [Other]). +">>. -- cgit v1.1 From a90f84a7a6823e9576ae22b8c4c573858513757f Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 23 Nov 2018 16:28:44 -0700 Subject: fix to include beams built from src files in subdirs in modules list --- test/rebar_compile_SUITE.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 9cbe8a2..a300690 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -2157,7 +2157,13 @@ recursive(Config) -> EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]), {ok, Files} = rebar_utils:list_dir(EbinDir), - ?assert(lists:member("rec.beam",Files)). + ?assert(lists:member("rec.beam",Files)), + + %% check that rec is in modules list of .app file + AppFile = filename:join(EbinDir, Name++".app"), + {ok, [{application, _, List}]} = file:consult(AppFile), + {modules, Modules} = lists:keyfind(modules, 1, List), + ?assert(lists:member(rec, Modules)). no_recursive(Config) -> AppDir = ?config(apps, Config), -- cgit v1.1 From 4deb6437f548a803509bce1ee87850c5501edc03 Mon Sep 17 00:00:00 2001 From: Bryan Paxton Date: Fri, 30 Nov 2018 20:06:42 -0600 Subject: Support ignoring whole modules in xref results - Added support to rebar_prv_xref for filtering out whole module. A module may now be added to the list of xref_ignores in rebar.config or via -ignore_xref() module attribute - Added unit test for whole module filtering support to xref CT suite --- test/rebar_xref_SUITE.erl | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/rebar_xref_SUITE.erl b/test/rebar_xref_SUITE.erl index f052fa4..9f4bc7d 100644 --- a/test/rebar_xref_SUITE.erl +++ b/test/rebar_xref_SUITE.erl @@ -46,9 +46,11 @@ init_per_testcase(Case, Config) -> Name = rebar_test_utils:create_random_name("xrefapp_"), Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_empty_app(AppDir, Name, Vsn, [kernel, stdlib]), - AppModules = [behaviour1, behaviour2, mymod, othermod], + AppModules = [behaviour1, behaviour2, mymod, othermod, ignoremod, ignoremod2], [write_src_file(AppDir, Name, Module, ignore_xref(Case)) || Module <- AppModules], + IgnoreMod = list_to_atom(Name ++ "_" ++ "ignoremod"), RebarConfig = [{erl_opts, [debug_info]}, + {xref_ignores, [IgnoreMod]}, {xref_checks, [deprecated_function_calls,deprecated_functions, undefined_function_calls,undefined_functions, exports_not_used,locals_not_used]}], @@ -95,7 +97,6 @@ xref_undef_behaviour(Config) -> Result = rebar3:run(rebar_state:new(State, RebarConfig, AppDir), ["xref"]), verify_results(xref_undef_behaviour, Name, Result). - %% =================================================================== %% Helper functions %% =================================================================== @@ -162,8 +163,9 @@ verify_test_results(xref_undef_behaviour, AppName, XrefResults, _QueryResults) - ?assertNot(lists:member({MyMod, bh2_b, 1}, ExportsNotUsed)), ok; verify_test_results(xref_ignore_test, AppName, XrefResults, _QueryResults) -> - AppModules = ["behaviour1", "behaviour2", "mymod", "othermod", "somemod"], - [_Behaviour1Mod, _Behaviour2Mod, _MyMod, _OtherMod, SomeMod] = + AppModules = ["behaviour1", "behaviour2", "mymod", "othermod", "somemod", + "ignoremod", "ignoremod2"], + [_Behaviour1Mod, _Behaviour2Mod, _MyMod, _OtherMod, SomeMod, IgnoreMod, IgnoreMod2] = [list_to_atom(AppName ++ "_" ++ Mod) || Mod <- AppModules], UndefFuns = proplists:get_value(undefined_functions, XrefResults), ?assertNot(lists:keymember(undefined_function_calls, 1, XrefResults)), @@ -171,6 +173,8 @@ verify_test_results(xref_ignore_test, AppName, XrefResults, _QueryResults) -> ?assertNot(lists:keymember(exports_not_used, 1, XrefResults)), ?assertNot(lists:keymember(deprecated_functions, 1, XrefResults)), ?assertNot(lists:keymember(deprecated_function_calls, 1, XrefResults)), + ?assertNot(lists:member({IgnoreMod, notavailable, 1}, UndefFuns)), + ?assertNot(lists:member({IgnoreMod2, notavailable, 1}, UndefFuns)), ?assert(lists:member({SomeMod, notavailable, 1}, UndefFuns)), ok. @@ -189,13 +193,15 @@ module_name(AppName, Module) -> get_module_body(behaviour1, AppName, IgnoreXref) -> ["-module(", AppName, "_behaviour1).\n", "-export([behaviour_info/1]).\n", - ["-ignore_xref({behaviour_info,1}).\n" || X <- [IgnoreXref], X =:= true], + ["-ignore_xref([ignoremod,{behaviour_info,1}]).\n" + || X <- [IgnoreXref], X =:= true], "behaviour_info(callbacks) -> [{bh1_a,1},{bh1_b,1}];\n", "behaviour_info(_Other) -> undefined.\n"]; get_module_body(behaviour2, AppName, IgnoreXref) -> ["-module(", AppName, "_behaviour2).\n", "-export([behaviour_info/1]).\n", - ["-ignore_xref({behaviour_info,1}).\n" || X <- [IgnoreXref], X =:= true], + ["-ignore_xref({behaviour_info,1}).\n" + || X <- [IgnoreXref], X =:= true], "behaviour_info(callbacks) -> [{bh2_a,1},{bh2_b,1}];\n", "behaviour_info(_Other) -> undefined.\n"]; get_module_body(mymod, AppName, IgnoreXref) -> @@ -217,6 +223,26 @@ get_module_body(mymod, AppName, IgnoreXref) -> "localfunc2() -> ok.\n", % unused local "fdeprecated() -> ok.\n" % deprecated function ]; +get_module_body(ignoremod, AppName, IgnoreXref) -> + ["-module(", AppName, "_ignoremod).\n", + "-export([]).\n", + [["-ignore_xref(", AppName, "_ignoremod).\n"] + || X <- [IgnoreXref], X =:= true], + "localfunc1(A, B) -> {A, B}.\n", % used local + "localfunc2() -> ok.\n", % unused local + "fdeprecated() -> ok.\n" % deprecated function + + ]; +get_module_body(ignoremod2, AppName, IgnoreXref) -> + ["-module(", AppName, "_ignoremod2).\n", + "-export([]).\n", + [["-ignore_xref(", AppName, "_ignoremod2).\n"] + || X <- [IgnoreXref], X =:= true], + "localfunc1(A, B) -> {A, B}.\n", % used local + "localfunc2() -> ok.\n", % unused local + "fdeprecated() -> ok.\n" % deprecated function + + ]; get_module_body(othermod, AppName, IgnoreXref) -> ["-module(", AppName, "_othermod).\n", "-export([somefunc/0]).\n", @@ -226,4 +252,5 @@ get_module_body(othermod, AppName, IgnoreXref) -> "somefunc() ->\n", " ", AppName, "_mymod:other1(arg),\n", " ", AppName, "_somemod:notavailable(arg),\n", - " ", AppName, "_mymod:fdeprecated().\n"]. + " ", AppName, "_mymod:fdeprecated(),\n", + " ", AppName, "_ignoremod:notavailable().\n"]. -- cgit v1.1 From 52ceecf1ff4b0d376ded33cbe72c51381e7cd391 Mon Sep 17 00:00:00 2001 From: Stefan Grundmann Date: Wed, 5 Dec 2018 20:48:34 +0000 Subject: check for mib_first_files regression in umbrella_mib_first_test consider A-MIB imports from B-MIB: rebar compile MUST FAIL if mib_first_files is ["mibs/A-MIB.mib"] rebar compile MUST SUCCEED if mib_first_files is ["mibs/B-MIB.mib"] --- test/rebar_compile_SUITE.erl | 66 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index a300690..ddaad0c 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -1161,17 +1161,19 @@ umbrella_mib_first_test(Config) -> rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), - MibsSrc = <<"-- SIMPLE-MIB.\n" + BExporterSrc = <<"-- BEXPORTER-MIB.\n" "-- This is just a simple MIB used for testing!\n" "--\n" -"SIMPLE-MIB DEFINITIONS ::= BEGIN\n" +"BEXPORTER-MIB DEFINITIONS ::= BEGIN\n" "IMPORTS\n" +" TEXTUAL-CONVENTION\n" +" FROM SNMPv2-TC\n" " MODULE-IDENTITY, enterprises\n" " FROM SNMPv2-SMI;\n" "\n" "ericsson MODULE-IDENTITY\n" " LAST-UPDATED\n" -" \"201403060000Z\"\n" +" \"201812050000Z\"\n" " ORGANIZATION\n" " \"rebar\"\n" " CONTACT-INFO\n" @@ -1183,25 +1185,71 @@ umbrella_mib_first_test(Config) -> " \"This very small module is made available\n" " for mib-compilation testing.\"\n" " ::= { enterprises 999 }\n" +"\n" +"Something ::= TEXTUAL-CONVENTION\n" +" STATUS current\n" +" DESCRIPTION \"\"\n" +" SYNTAX OCTET STRING (SIZE (4))\n" +"END\n">>, + + AImporterSrc = <<"-- AIMPORTER-MIB.\n" +"-- This is just a simple MIB used for testing!\n" +"--\n" +"AIMPORTER-MIB DEFINITIONS ::= BEGIN\n" +"IMPORTS\n" +" Something\n" +" FROM BEXPORTER-MIB\n" +" MODULE-IDENTITY, enterprises\n" +" FROM SNMPv2-SMI;\n" +"\n" +"ericsson MODULE-IDENTITY\n" +" LAST-UPDATED\n" +" \"201812050000Z\"\n" +" ORGANIZATION\n" +" \"rebar\"\n" +" CONTACT-INFO\n" +" \"rebar \n" +" or\n" +" whoever is currently responsible for the SIMPLE\n" +" enterprise MIB tree branch (enterprises.999).\"\n" +" DESCRIPTION\n" +" \"This very small module is made available\n" +" for mib-compilation testing.\"\n" +" ::= { enterprises 1000 }\n" "END\n">>, + + ok = filelib:ensure_dir(filename:join([AppDir, "mibs", "dummy"])), - ok = file:write_file(filename:join([AppDir, "mibs", "SIMPLE-MIB.mib"]), MibsSrc), + ok = file:write_file(filename:join([AppDir, "mibs", "AIMPORTER-MIB.mib"]), AImporterSrc), + ok = file:write_file(filename:join([AppDir, "mibs", "BEXPORTER-MIB.mib"]), BExporterSrc), - RebarConfig = [{mib_first_files, ["mibs/SIMPLE-MIB.mib"]}], + FailureRebarConfig = [{mib_first_files, ["mibs/AIMPORTER-MIB.mib"]}], + SuccessRebarConfig = [{mib_first_files, ["mibs/BEXPORTER-MIB.mib"]}], - rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}), + PrivMibsDir = filename:join([AppsDir, "_build", "default", "lib", Name, "priv", "mibs"]), + + FailureRebarConfig = [{mib_first_files, ["mibs/AIMPORTER-MIB.mib"]}], + catch ( + rebar_test_utils:run_and_check(Config, FailureRebarConfig, ["compile"], {ok, [{app, Name}]}) ), + + %% check that the bin file was NOT cretated + false = filelib:is_file(filename:join([PrivMibsDir, "AIMPORTER-MIB.bin"])), + + + SuccessRebarConfig = [{mib_first_files, ["mibs/BEXPORTER-MIB.mib"]}], + rebar_test_utils:run_and_check(Config, SuccessRebarConfig, ["compile"], {ok, [{app, Name}]}), %% 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"])), + true = filelib:is_file(filename:join([PrivMibsDir, "AIMPORTER-MIB.bin"])), %% 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"])), + true = filelib:is_file(filename:join([AppDir, "include", "AIMPORTER-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) -> AppDir = ?config(apps, Config), -- cgit v1.1