summaryrefslogtreecommitdiff
path: root/test/rebar_install_deps_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'test/rebar_install_deps_SUITE.erl')
-rw-r--r--test/rebar_install_deps_SUITE.erl225
1 files changed, 191 insertions, 34 deletions
diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl
index 4e6c3d9..cf3b260 100644
--- a/test/rebar_install_deps_SUITE.erl
+++ b/test/rebar_install_deps_SUITE.erl
@@ -4,16 +4,24 @@
-include_lib("eunit/include/eunit.hrl").
-include_lib("kernel/include/file.hrl").
-all() -> [{group, git}, {group, pkg}].
+all() -> [{group, git}, {group, pkg}, {group, mixed}].
groups() ->
- [{all, [], [flat, pick_highest_left, pick_highest_right,
- pick_smallest1, pick_smallest2,
- circular1, circular2, circular_skip,
- fail_conflict, default_profile, nondefault_profile,
- nondefault_pick_highest]},
- {git, [], [{group, all}]},
- {pkg, [], [{group, all}]}].
+ [{unique, [], [flat, pick_highest_left, pick_highest_right,
+ pick_smallest1, pick_smallest2,
+ circular1, circular2, circular_skip,
+ fail_conflict, default_profile, nondefault_profile,
+ nondefault_pick_highest]},
+ {git, [], [{group, unique}]},
+ {pkg, [], [{group, unique}]},
+ {mixed, [], [
+ m_flat1, m_flat2, m_circular1, m_circular2, m_circular3,
+ m_pick_source1, m_pick_source2, m_pick_source3,
+ m_pick_source4, m_pick_source5, m_source_to_pkg,
+ m_pkg_level1, m_pkg_level2,
+ m_pkg_src_override
+ ]}
+ ].
init_per_suite(Config) ->
application:start(meck),
@@ -26,19 +34,33 @@ init_per_group(git, Config) ->
[{deps_type, git} | Config];
init_per_group(pkg, Config) ->
[{deps_type, pkg} | Config];
+init_per_group(mixed, Config) ->
+ [{deps_type, mixed} | Config];
init_per_group(_, Config) ->
Config.
end_per_group(_, Config) ->
Config.
-init_per_testcase(Case, Config) ->
+init_per_testcase(Case, Config) when is_atom(Case) ->
+ DepsType = ?config(deps_type, Config),
+ init_per_testcase({DepsType, Case}, Config);
+init_per_testcase({mixed, Case}, Config) ->
+ {Deps, Warnings, Expect} = mdeps(Case),
+ Expected = case Expect of
+ {ok, List} -> {ok, format_expected_mdeps(List)};
+ Other -> Other
+ end,
+ mock_warnings(),
+ [{expect, Expected},
+ {warnings, format_expected_mixed_warnings(Warnings)}
+ | setup_project(Case, Config, rebar_test_utils:expand_deps(mixed, Deps))];
+init_per_testcase({DepsType, Case}, Config) ->
{Deps, Warnings, Expect} = deps(Case),
Expected = case Expect of
{ok, List} -> {ok, format_expected_deps(List)};
Other -> Other
end,
- DepsType = ?config(deps_type, Config),
mock_warnings(),
[{expect, Expected},
{warnings, Warnings}
@@ -54,6 +76,32 @@ format_expected_deps(Deps) ->
N -> [{dep, N}, {lock, N}]
end || Dep <- Deps]).
+format_expected_mdeps(Deps) ->
+ %% for mixed deps, lowercase is a package, uppercase is source.
+ %% We can't check which was used from the dep, but the lock contains
+ %% the type and we can use that information.
+ lists:append([
+ case Dep of
+ {N,V} when hd(N) >= $a, hd(N) =< $z ->
+ UN = string:to_upper(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),
+ [{dep, UN}, {lock, pkg, UN, "0.0.0"}];
+ N when hd(N) >= $A, hd(N) =< $Z ->
+ [{dep, N}, {lock, src, N, "0.0.0"}]
+ end || Dep <- 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 -> {src, 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 -> {src, N, "0.0.0"}
+ end || W <- Warnings].
+
%% format:
%% {Spec,
%% [Warning],
@@ -131,6 +179,78 @@ deps(nondefault_pick_highest) ->
%% This is all handled in setup_project
{[],[],{ok,[]}}.
+%% format:
+%% Same as `deps/1' except "A" is a source dep
+%% and "a" is a package dep.
+mdeps(m_flat1) ->
+ {[{"c", []},
+ {"B", []}],
+ [],
+ {ok, ["B","c"]}};
+mdeps(m_flat2) ->
+ {[{"B", []},
+ {"c", []}],
+ [],
+ {ok, ["B","c"]}};
+mdeps(m_circular1) ->
+ {[{"b", [{"a",[]}]}], % "A" is the top app
+ [],
+ {error, {rebar_prv_install_deps, {cycles, [[<<"A">>,<<"B">>]]}}}};
+mdeps(m_circular2) ->
+ {[{"B", [{"c", [{"b", []}]}]}],
+ [],
+ {error, {rebar_prv_install_deps, {cycles, [[<<"B">>,<<"C">>]]}}}};
+mdeps(m_circular3) ->
+ %% Spot the circular dep due to being to low in the deps tree
+ %% but as a source dep, taking precedence over packages
+ {[{"B", [{"C", "2", [{"B", []}]}]},
+ {"c", "1", [{"d",[]}]}],
+ [],
+ {error, {rebar_prv_install_deps, {cycles, [[<<"B">>,<<"C">>]]}}}};
+mdeps(m_pick_source1) ->
+ {[{"B", [{"D", []}]},
+ {"c", [{"d", []}]}],
+ ["d"],
+ {ok, ["B", "c", "D"]}};
+mdeps(m_pick_source2) ->
+ {[{"b", [{"d", []}]},
+ {"C", [{"D", []}]}],
+ ["d"],
+ {ok, ["b", "C", "D"]}};
+mdeps(m_pick_source3) ->
+ {[{"b", []},
+ {"B", []}],
+ ["b"],
+ {ok, ["B"]}};
+mdeps(m_pick_source4) ->
+ {[{"B", []},
+ {"b", []}],
+ ["b"],
+ {ok, ["B"]}};
+mdeps(m_pick_source5) ->
+ {[{"B", [{"d", []}]},
+ {"C", [{"D", []}]}],
+ ["d"],
+ {ok, ["B", "C", "D"]}};
+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"}]}};
+mdeps(m_pkg_level2) ->
+ {[{"B", [{"e", "1", []}]},
+ {"C", [{"D", [{"e", "2", []}]}]}],
+ [{"e","2"}],
+ {ok, ["B","C","D",{"e","1"}]}};
+mdeps(m_pkg_src_override) ->
+ %% This is all handled in setup_project
+ {[],[],{ok,[]}}.
+
+
setup_project(fail_conflict, Config0, Deps) ->
DepsType = ?config(deps_type, Config0),
Config = rebar_test_utils:init_rebar_state(
@@ -142,12 +262,9 @@ setup_project(fail_conflict, Config0, Deps) ->
TopDeps = rebar_test_utils:top_level_deps(Deps),
RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps},
{deps_error_on_conflict, true}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config];
setup_project(nondefault_profile, Config0, Deps) ->
DepsType = ?config(deps_type, Config0),
@@ -161,12 +278,9 @@ setup_project(nondefault_profile, Config0, Deps) ->
RebarConf = rebar_test_utils:create_config(AppDir, [{profiles, [
{nondef, [{deps, TopDeps}]}
]}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config];
setup_project(nondefault_pick_highest, Config0, _) ->
DepsType = ?config(deps_type, Config0),
@@ -187,15 +301,30 @@ setup_project(nondefault_pick_highest, Config0, _) ->
),
case DepsType of
git ->
- mock_git_resource:mock(
- [{deps, rebar_test_utils:flat_deps(DefaultDeps ++ ProfileDeps)}]
- );
+ {SrcDeps, _} = rebar_test_utils:flat_deps(DefaultDeps++ProfileDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]);
pkg ->
- mock_pkg_resource:mock(
- [{pkgdeps, rebar_test_utils:flat_pkgdeps(DefaultDeps ++ ProfileDeps)}]
- )
+ {_, PkgDeps} = rebar_test_utils:flat_deps(DefaultDeps++ProfileDeps),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}])
end,
[{rebarconfig, RebarConf} | Config];
+setup_project(m_pkg_src_override, Config0, _) ->
+ Config = rebar_test_utils:init_rebar_state(Config0, "m_pkg_src_override_mixed_"),
+ AppDir = ?config(apps, Config),
+ rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
+ DefaultDeps = rebar_test_utils:expand_deps(mixed, [{"b", [{"c", []}]}]),
+ OverrideDeps = rebar_test_utils:expand_deps(mixed, [{"C", []}]),
+ DefaultTop = rebar_test_utils:top_level_deps(DefaultDeps),
+ OverrideTop = rebar_test_utils:top_level_deps(OverrideDeps),
+ RebarConf = rebar_test_utils:create_config(
+ AppDir,
+ [{deps, DefaultTop},
+ {overrides, [{override, b, [{deps, OverrideTop}]}]}]
+ ),
+ {SrcDeps,PkgDeps} = rebar_test_utils:flat_deps(DefaultDeps++OverrideDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
+ [{rebarconfig, RebarConf} | Config];
setup_project(Case, Config0, Deps) ->
DepsType = ?config(deps_type, Config0),
Config = rebar_test_utils:init_rebar_state(
@@ -206,12 +335,9 @@ setup_project(Case, Config0, Deps) ->
rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
TopDeps = rebar_test_utils:top_level_deps(Deps),
RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config].
mock_warnings() ->
@@ -319,6 +445,33 @@ nondefault_pick_highest(Config) ->
{ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "2"}], "nondef"}
).
+m_flat1(Config) -> run(Config).
+m_flat2(Config) -> run(Config).
+m_circular1(Config) -> run(Config).
+m_circular2(Config) -> run(Config).
+m_circular3(Config) -> run(Config).
+m_pick_source1(Config) -> run(Config).
+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_source_to_pkg(Config) -> run(Config).
+m_pkg_level1(Config) -> run(Config).
+m_pkg_level2(Config) -> run(Config).
+
+
+m_pkg_src_override(Config) ->
+ %% Detect the invalid override where a package dep's are overriden
+ %% with source dependencies. We only test with overrides because
+ %% we trust the package index to be correct there and not introduce
+ %% that kind of error.
+ {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"],
+ {error, {rebar_prv_install_deps,
+ {source_dep_in_pkg, [<<"C">>,<<"b">>]}}}
+ ).
+
run(Config) ->
{ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
rebar_test_utils:run_and_check(
@@ -336,6 +489,10 @@ error_calls() ->
check_warnings(_, [], _) ->
ok;
+check_warnings(Warns, [{Type, Name, Vsn} | Rest], mixed) ->
+ ct:pal("Checking for warning ~p in ~p", [{Name,Vsn},Warns]),
+ ?assert(in_warnings(Type, Warns, Name, Vsn)),
+ check_warnings(Warns, 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)),