From b94afdfa2d44b0cb1489234c7746cd72f85a167d Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Tue, 20 Jan 2015 01:39:43 +0000 Subject: WIP Test that all the correct locks are set for an upgrade run. Now to actually re-run the install deps and prove it works --- test/rebar_deps_SUITE.erl | 1 - test/rebar_test_utils.erl | 12 ++- test/rebar_upgrade_SUITE.erl | 185 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 test/rebar_upgrade_SUITE.erl (limited to 'test') diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index d67efe4..8407b55 100644 --- a/test/rebar_deps_SUITE.erl +++ b/test/rebar_deps_SUITE.erl @@ -1,4 +1,3 @@ -%%% TODO: check that warnings are appearing -module(rebar_deps_SUITE). -compile(export_all). -include_lib("common_test/include/ct.hrl"). diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 6095d6d..af40995 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -53,7 +53,17 @@ run_and_check(Config, RebarConfig, Command, Expect) -> ?assertEqual({error, Reason}, Res); {ok, Expected} -> {ok, _} = Res, - check_results(AppDir, Expected) + check_results(AppDir, Expected); + {unlocked, Expected} -> + ct:pal("Expected: ~p", [Expected]), + {ok, ResState} = Res, + Locks = rebar_state:lock(ResState), + ct:pal("Locks: ~p", [Locks]), + ?assertEqual(lists:sort(Expected), + lists:sort([rebar_app_info:name(Lock) + || Lock <- Locks])); + return -> + Res end. %% @doc Creates a dummy application including: diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl new file mode 100644 index 0000000..5915d0d --- /dev/null +++ b/test/rebar_upgrade_SUITE.erl @@ -0,0 +1,185 @@ +-module(rebar_upgrade_SUITE). +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-compile(export_all). + +all() -> [{group, git}].%, {group, pkg}]. + +groups() -> + [{all, [], [top, pair, triplet, tree]}, + {git, [], [{group, all}]}, + {pkg, [], [{group, all}]}]. + +init_per_suite(Config) -> + application:start(meck), + Config. + +end_per_suite(_Config) -> + application:stop(meck). + +init_per_group(git, Config) -> + [{deps_type, git} | Config]; +init_per_group(pkg, Config) -> + [{deps_type, pkg} | Config]; +init_per_group(_, Config) -> + Config. + +end_per_group(_, Config) -> + Config. + +init_per_testcase(Case, Config) -> + DepsType = ?config(deps_type, Config), + {Deps, Unlocks} = upgrades(Case), + Expanded = expand_deps(DepsType, Deps), + [{unlocks, normalize_unlocks(Unlocks)}, + {mock, fun() -> mock_deps(DepsType, Expanded, []) end} + | setup_project(Case, Config, Expanded)]. + +end_per_testcase(_, Config) -> + meck:unload(), + Config. + +setup_project(Case, Config0, Deps) -> + DepsType = ?config(deps_type, Config0), + Config = rebar_test_utils:init_rebar_state( + Config0, + atom_to_list(Case)++"_"++atom_to_list(DepsType)++"_" + ), + AppDir = ?config(apps, Config), + rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]), + TopDeps = top_level_deps(Deps), + RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]), + [{rebarconfig, RebarConf} | Config]. + + +upgrades(top) -> + {[{"A", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% upgrade vs. locked after upgrade + [{"A", []}, + {"B", {error, transitive_dependency}}, + {"C", {error, transitive_dependency}}, + {"D", "1", {error, transitive_dependency}}, + {"D", "2", {error, unknown_dependency}}]}; +upgrades(pair) -> + {[{"A", [{"C", []}]}, + {"B", [{"D", []}]}], + [{"A", ["B"]}, + {"B", ["A"]}, + {"C", {error, transitive_dependency}}, + {"D", {error, transitive_dependency}}]}; +upgrades(triplet) -> + {[{"A", [{"D",[]}, + {"E",[]}]}, + {"B", [{"F",[]}, + {"G",[]}]}, + {"C", [{"H",[]}, + {"I",[]}]}], + [{"A", ["B","C"]}, + {"B", ["A","C"]}, + {"C", ["A","B"]}, + {"D", {error, transitive_dependency}}, + %% ... + {"I", {error, transitive_dependency}}]}; +upgrades(tree) -> + {[{"A", [{"D",[{"J",[]}]}, + {"E",[{"K",[]}]}]}, + {"B", [{"F",[]}, + {"G",[]}]}, + {"C", [{"H",[]}, + {"I",[]}]}], + [{"A", ["B","C"]}, + {"B", ["A","C"]}, + {"C", ["A","B"]}, + {"D", {error, transitive_dependency}}, + %% ... + {"K", {error, transitive_dependency}}]}. + +%% TODO: add a test that verifies that unlocking files and then +%% running the upgrade code is enough to properly upgrade things. + +top_level_deps([]) -> []; +top_level_deps([{{Name, Vsn, Ref}, _} | Deps]) -> + [{list_to_atom(Name), Vsn, Ref} | top_level_deps(Deps)]; +top_level_deps([{{pkg, Name, Vsn, _URL}, _} | Deps]) -> + [{list_to_atom(Name), Vsn} | top_level_deps(Deps)]. + +mock_deps(git, Deps, Upgrades) -> + mock_git_resource:mock([{deps, flat_deps(Deps)}, {upgrade, Upgrades}]); +mock_deps(pkg, Deps, Upgrades) -> + mock_pkg_resource:mock([{pkgdeps, flat_pkgdeps(Deps)}, {upgrade, Upgrades}]). + +flat_deps([]) -> []; +flat_deps([{{Name,_Vsn,Ref}, Deps} | Rest]) -> + [{{Name,vsn_from_ref(Ref)}, top_level_deps(Deps)}] + ++ + flat_deps(Deps) + ++ + flat_deps(Rest). + +vsn_from_ref({git, _, {_, Vsn}}) -> Vsn; +vsn_from_ref({git, _, Vsn}) -> Vsn. + +flat_pkgdeps([]) -> []; +flat_pkgdeps([{{pkg, Name, Vsn, _Url}, Deps} | Rest]) -> + [{{iolist_to_binary(Name),iolist_to_binary(Vsn)}, top_level_deps(Deps)}] + ++ + flat_pkgdeps(Deps) + ++ + flat_pkgdeps(Rest). + +expand_deps(_, []) -> []; +expand_deps(git, [{Name, Deps} | Rest]) -> + Dep = {Name, ".*", {git, "https://example.org/user/"++Name++".git", "master"}}, + [{Dep, expand_deps(git, Deps)} | expand_deps(git, Rest)]; +expand_deps(git, [{Name, Vsn, Deps} | Rest]) -> + Dep = {Name, Vsn, {git, "https://example.org/user/"++Name++".git", {tag, Vsn}}}, + [{Dep, expand_deps(git, Deps)} | expand_deps(git, Rest)]; +expand_deps(pkg, [{Name, Deps} | Rest]) -> + Dep = {pkg, Name, "0.0.0", "https://example.org/user/"++Name++".tar.gz"}, + [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)]; +expand_deps(pkg, [{Name, Vsn, Deps} | Rest]) -> + Dep = {pkg, Name, Vsn, "https://example.org/user/"++Name++".tar.gz"}, + [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)]. + +normalize_unlocks([]) -> []; +normalize_unlocks([{App, Locks} | Rest]) -> + [{iolist_to_binary(App), + normalize_unlocks_expect(Locks)} | normalize_unlocks(Rest)]; +normalize_unlocks([{App, Vsn, Locks} | Rest]) -> + [{iolist_to_binary(App), iolist_to_binary(Vsn), + normalize_unlocks_expect(Locks)} | normalize_unlocks(Rest)]. + +normalize_unlocks_expect({error, Reason}) -> + {error, Reason}; +normalize_unlocks_expect([]) -> + []; +normalize_unlocks_expect([{App,Vsn} | Rest]) -> + [{iolist_to_binary(App), iolist_to_binary(Vsn)} + | normalize_unlocks_expect(Rest)]; +normalize_unlocks_expect([App | Rest]) -> + [iolist_to_binary(App) | normalize_unlocks_expect(Rest)]. + +top(Config) -> run(Config). +pair(Config) -> run(Config). +triplet(Config) -> run(Config). +tree(Config) -> run(Config). + +run(Config) -> + apply(?config(mock, Config), []), + {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), + %% Install dependencies before re-mocking for an upgrade + rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}), + Unlocks = ?config(unlocks, Config), + [begin + ct:pal("Unlocks: ~p -> ~p", [App, Unlocked]), + Expectation = case Unlocked of + Tuple when is_tuple(Tuple) -> Tuple; + _ -> {unlocked, Unlocked} + end, + rebar_test_utils:run_and_check( + Config, RebarConfig, ["upgrade", App], Expectation + ) + end || {App, Unlocked} <- Unlocks]. + -- cgit v1.1 From 748a046133fa5b0b2570f4675c223326299d711a Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 4 Feb 2015 21:26:48 +0000 Subject: Partial work + Failing tests The problem with the current effort is handling of transitive dependency upgrades and possible values. --- test/mock_git_resource.erl | 5 +- test/rebar_test_utils.erl | 8 -- test/rebar_upgrade_SUITE.erl | 328 +++++++++++++++++++++++++++++++++---------- 3 files changed, 261 insertions(+), 80 deletions(-) (limited to 'test') diff --git a/test/mock_git_resource.erl b/test/mock_git_resource.erl index 00f0a03..5d8288e 100644 --- a/test/mock_git_resource.erl +++ b/test/mock_git_resource.erl @@ -54,11 +54,13 @@ mock_lock(_) -> %% @doc The config passed to the `mock/2' function can specify which apps %% should be updated on a per-name basis: `{update, ["App1", "App3"]}'. mock_update(Opts) -> - ToUpdate = proplists:get_value(update, Opts, []), + ToUpdate = proplists:get_value(upgrade, Opts, []), + ct:pal("TOUp: ~p", [ToUpdate]), meck:expect( ?MOD, needs_update, fun(_Dir, {git, Url, _Ref}) -> App = app(Url), + ct:pal("Needed update? ~p -> ~p", [App, lists:member(App, ToUpdate)]), lists:member(App, ToUpdate) end). @@ -106,6 +108,7 @@ mock_download(Opts) -> {git, Url, {_, Vsn}} = normalize_git(Git, Overrides, Default), App = app(Url), AppDeps = proplists:get_value({App,Vsn}, Deps, []), + ct:pal("creating app ~p", [{Dir, App, Vsn, AppDeps}]), rebar_test_utils:create_app( Dir, App, Vsn, [element(1,D) || D <- AppDeps] diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index af40995..827d134 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -54,14 +54,6 @@ run_and_check(Config, RebarConfig, Command, Expect) -> {ok, Expected} -> {ok, _} = Res, check_results(AppDir, Expected); - {unlocked, Expected} -> - ct:pal("Expected: ~p", [Expected]), - {ok, ResState} = Res, - Locks = rebar_state:lock(ResState), - ct:pal("Locks: ~p", [Locks]), - ?assertEqual(lists:sort(Expected), - lists:sort([rebar_app_info:name(Lock) - || Lock <- Locks])); return -> Res end. diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 5915d0d..a7d4a06 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -6,7 +6,10 @@ all() -> [{group, git}].%, {group, pkg}]. groups() -> - [{all, [], [top, pair, triplet, tree]}, + [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, + pair_a, pair_b, pair_c, + triplet_a, triplet_b, triplet_c, + tree_a, tree_b, tree_c]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -29,10 +32,12 @@ end_per_group(_, Config) -> init_per_testcase(Case, Config) -> DepsType = ?config(deps_type, Config), - {Deps, Unlocks} = upgrades(Case), + {Deps, UpDeps, ToUp, Expectations} = upgrades(Case), Expanded = expand_deps(DepsType, Deps), - [{unlocks, normalize_unlocks(Unlocks)}, - {mock, fun() -> mock_deps(DepsType, Expanded, []) end} + UpExpanded = expand_deps(DepsType, UpDeps), + [{expected, normalize_unlocks(Expectations)}, + {mock, fun() -> mock_deps(DepsType, Expanded, []) end}, + {mock_update, fun() -> mock_deps(DepsType, UpExpanded, ToUp) end} | setup_project(Case, Config, Expanded)]. end_per_testcase(_, Config) -> @@ -52,49 +57,216 @@ setup_project(Case, Config0, Deps) -> [{rebarconfig, RebarConf} | Config]. -upgrades(top) -> - {[{"A", [{"B", [{"D", "1", []}]}, - {"C", [{"D", "2", []}]}]} - ], - %% upgrade vs. locked after upgrade - [{"A", []}, - {"B", {error, transitive_dependency}}, - {"C", {error, transitive_dependency}}, - {"D", "1", {error, transitive_dependency}}, - {"D", "2", {error, unknown_dependency}}]}; -upgrades(pair) -> - {[{"A", [{"C", []}]}, - {"B", [{"D", []}]}], - [{"A", ["B"]}, - {"B", ["A"]}, - {"C", {error, transitive_dependency}}, - {"D", {error, transitive_dependency}}]}; -upgrades(triplet) -> - {[{"A", [{"D",[]}, - {"E",[]}]}, - {"B", [{"F",[]}, - {"G",[]}]}, - {"C", [{"H",[]}, - {"I",[]}]}], - [{"A", ["B","C"]}, - {"B", ["A","C"]}, - {"C", ["A","B"]}, - {"D", {error, transitive_dependency}}, - %% ... - {"I", {error, transitive_dependency}}]}; -upgrades(tree) -> - {[{"A", [{"D",[{"J",[]}]}, - {"E",[{"K",[]}]}]}, - {"B", [{"F",[]}, - {"G",[]}]}, - {"C", [{"H",[]}, - {"I",[]}]}], - [{"A", ["B","C"]}, - {"B", ["A","C"]}, - {"C", ["A","B"]}, - {"D", {error, transitive_dependency}}, - %% ... - {"K", {error, transitive_dependency}}]}. +upgrades(top_a) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"A", [{"A","1"}, "B", "C", {"D","3"}]}}; +upgrades(top_b) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"B", {error, transitive_dependency}}}; +upgrades(top_c) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"C", {error, transitive_dependency}}}; +upgrades(top_d1) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"D", {error, transitive_dependency}}}; +upgrades(top_d2) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"D", {error, transitive_dependency}}}; +upgrades(top_e) -> + %% Original tree + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Updated tree + [{"A", "1", [{"B", [{"D", "3", []}]}, + {"C", [{"D", "2", []}]}]} + ], + %% Modified apps, gobally + ["A","B","D"], + %% upgrade vs. new tree + {"E", {error, unknown_dependency}}}; +upgrades(pair_a) -> + {[{"A", "1", [{"C", "1", []}]}, + {"B", "1", [{"D", "1", []}]} + ], + [{"A", "2", [{"C", "2", []}]}, + {"B", "2", [{"D", "2", []}]} + ], + ["A","B","C","D"], + {"A", [{"A","2"},{"C","2"},{"B","1"},{"D","1"}]}}; +upgrades(pair_b) -> + {[{"A", "1", [{"C", "1", []}]}, + {"B", "1", [{"D", "1", []}]} + ], + [{"A", "2", [{"C", "2", []}]}, + {"B", "2", [{"D", "2", []}]} + ], + ["A","B","C","D"], + {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}}; +upgrades(pair_c) -> + {[{"A", "1", [{"C", "1", []}]}, + {"B", "1", [{"D", "1", []}]} + ], + [{"A", "2", [{"C", "2", []}]}, + {"B", "2", [{"D", "2", []}]} + ], + ["A","B","C","D"], + {"C", {error, transitive_dependency}}}; +upgrades(triplet_a) -> + {[{"A", "1", [{"D",[]}, + {"E","3",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "0", [{"H","3",[]}, + {"I",[]}]}], + [{"A", "1", [{"D",[]}, + {"E","2",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "1", [{"H","4",[]}, + {"I",[]}]}], + ["A","C","E","H"], + {"A", [{"A","1"}, "D", {"E","2"}, + {"B","1"}, {"F","1"}, "G", + {"C","0"}, {"H","3"}, "I"]}}; +upgrades(triplet_b) -> + {[{"A", "1", [{"D",[]}, + {"E","3",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "0", [{"H","3",[]}, + {"I",[]}]}], + [{"A", "1", [{"D",[]}, + {"E","2",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "1", [{"H","4",[]}, + {"I",[]}]}], + ["A","C","E","H"], + {"B", [{"A","1"}, "D", {"E","3"}, + {"B","1"}, {"F","1"}, "G", + {"C","0"}, {"H","3"}, "I"]}}; +upgrades(triplet_c) -> + {[{"A", "1", [{"D",[]}, + {"E","3",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "0", [{"H","3",[]}, + {"I",[]}]}], + [{"A", "1", [{"D",[]}, + {"E","2",[]}]}, + {"B", "1", [{"F","1",[]}, + {"G",[]}]}, + {"C", "1", [{"H","4",[]}, + {"I",[]}]}], + ["A","C","E","H"], + {"C", [{"A","1"}, "D", {"E","3"}, + {"B","1"}, {"F","1"}, "G", + {"C","1"}, {"H","4"}, "I"]}}; +upgrades(tree_a) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}]} + ], + ["C"], + {"A", [{"A","1"}, "D", "J", "E", + {"B","1"}, "F", "G", + {"C","1"}, "H", {"I","2"}]}}; +upgrades(tree_b) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}]} + ], + ["C"], + {"B", [{"A","1"}, "D", "J", "E", + {"B","1"}, "F", "G", + {"C","1"}, "H", {"I","2"}]}}; +upgrades(tree_c) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}]} + ], + ["C"], + {"C", [{"A","1"}, "D", "J", "E", {"I","1"}, + {"B","1"}, "F", "G", + {"C","1"}, "H"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. @@ -106,8 +278,10 @@ top_level_deps([{{pkg, Name, Vsn, _URL}, _} | Deps]) -> [{list_to_atom(Name), Vsn} | top_level_deps(Deps)]. mock_deps(git, Deps, Upgrades) -> + catch mock_git_resource:unmock(), mock_git_resource:mock([{deps, flat_deps(Deps)}, {upgrade, Upgrades}]); mock_deps(pkg, Deps, Upgrades) -> + catch mock_pkg_resource:unmock(), mock_pkg_resource:mock([{pkgdeps, flat_pkgdeps(Deps)}, {upgrade, Upgrades}]). flat_deps([]) -> []; @@ -143,43 +317,55 @@ expand_deps(pkg, [{Name, Vsn, Deps} | Rest]) -> Dep = {pkg, Name, Vsn, "https://example.org/user/"++Name++".tar.gz"}, [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)]. -normalize_unlocks([]) -> []; -normalize_unlocks([{App, Locks} | Rest]) -> - [{iolist_to_binary(App), - normalize_unlocks_expect(Locks)} | normalize_unlocks(Rest)]; -normalize_unlocks([{App, Vsn, Locks} | Rest]) -> - [{iolist_to_binary(App), iolist_to_binary(Vsn), - normalize_unlocks_expect(Locks)} | normalize_unlocks(Rest)]. +normalize_unlocks({App, Locks}) -> + {iolist_to_binary(App), + normalize_unlocks_expect(Locks)}; +normalize_unlocks({App, Vsn, Locks}) -> + {iolist_to_binary(App), iolist_to_binary(Vsn), + normalize_unlocks_expect(Locks)}. normalize_unlocks_expect({error, Reason}) -> {error, Reason}; normalize_unlocks_expect([]) -> []; normalize_unlocks_expect([{App,Vsn} | Rest]) -> - [{iolist_to_binary(App), iolist_to_binary(Vsn)} + [{dep, App, Vsn} | normalize_unlocks_expect(Rest)]; normalize_unlocks_expect([App | Rest]) -> - [iolist_to_binary(App) | normalize_unlocks_expect(Rest)]. + [{dep, App} | normalize_unlocks_expect(Rest)]. + +top_a(Config) -> run(Config). +top_b(Config) -> run(Config). +top_c(Config) -> run(Config). +top_d1(Config) -> run(Config). +top_d2(Config) -> run(Config). +top_e(Config) -> run(Config). + +pair_a(Config) -> run(Config). +pair_b(Config) -> run(Config). +pair_c(Config) -> run(Config). + +triplet_a(Config) -> run(Config). +triplet_b(Config) -> run(Config). +triplet_c(Config) -> run(Config). -top(Config) -> run(Config). -pair(Config) -> run(Config). -triplet(Config) -> run(Config). -tree(Config) -> run(Config). +tree_a(Config) -> run(Config). +tree_b(Config) -> run(Config). +tree_c(Config) -> run(Config). run(Config) -> apply(?config(mock, Config), []), {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), %% Install dependencies before re-mocking for an upgrade rebar_test_utils:run_and_check(Config, RebarConfig, ["lock"], {ok, []}), - Unlocks = ?config(unlocks, Config), - [begin - ct:pal("Unlocks: ~p -> ~p", [App, Unlocked]), - Expectation = case Unlocked of - Tuple when is_tuple(Tuple) -> Tuple; - _ -> {unlocked, Unlocked} - end, - rebar_test_utils:run_and_check( - Config, RebarConfig, ["upgrade", App], Expectation - ) - end || {App, Unlocked} <- Unlocks]. + {App, Unlocks} = ?config(expected, Config), + ct:pal("Upgrades: ~p -> ~p", [App, Unlocks]), + Expectation = case Unlocks of + {error, Term} -> {error, Term}; + _ -> {ok, Unlocks} + end, + apply(?config(mock_update, Config), []), + rebar_test_utils:run_and_check( + Config, RebarConfig, ["upgrade", App], Expectation + ). -- cgit v1.1 From 92436d9960b9ce1ef8a8451c33e597248e1c9bfe Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 8 Feb 2015 23:23:15 +0000 Subject: More progress on upgrades Only the most complex case is failing, where cross-dependencies would need to be refetched as an update clears an app of its dependencies and a different subtree should override it. --- test/rebar_upgrade_SUITE.erl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index a7d4a06..0727fff 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -38,13 +38,13 @@ init_per_testcase(Case, Config) -> [{expected, normalize_unlocks(Expectations)}, {mock, fun() -> mock_deps(DepsType, Expanded, []) end}, {mock_update, fun() -> mock_deps(DepsType, UpExpanded, ToUp) end} - | setup_project(Case, Config, Expanded)]. + | setup_project(Case, Config, Expanded, UpExpanded)]. end_per_testcase(_, Config) -> meck:unload(), Config. -setup_project(Case, Config0, Deps) -> +setup_project(Case, Config0, Deps, UpDeps) -> DepsType = ?config(deps_type, Config0), Config = rebar_test_utils:init_rebar_state( Config0, @@ -54,7 +54,8 @@ setup_project(Case, Config0, Deps) -> rebar_test_utils:create_app(AppDir, "Root", "0.0.0", [kernel, stdlib]), TopDeps = top_level_deps(Deps), RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]), - [{rebarconfig, RebarConf} | Config]. + [{rebarconfig, RebarConf}, + {next_top_deps, top_level_deps(UpDeps)} | Config]. upgrades(top_a) -> @@ -279,6 +280,7 @@ top_level_deps([{{pkg, Name, Vsn, _URL}, _} | Deps]) -> mock_deps(git, Deps, Upgrades) -> catch mock_git_resource:unmock(), + ct:pal("mocked: ~p", [flat_deps(Deps)]), mock_git_resource:mock([{deps, flat_deps(Deps)}, {upgrade, Upgrades}]); mock_deps(pkg, Deps, Upgrades) -> catch mock_pkg_resource:unmock(), @@ -365,7 +367,10 @@ run(Config) -> _ -> {ok, Unlocks} end, apply(?config(mock_update, Config), []), + NewRebarConf = rebar_test_utils:create_config(?config(apps, Config), + [{deps, ?config(next_top_deps, Config)}]), + {ok, NewRebarConfig} = file:consult(NewRebarConf), rebar_test_utils:run_and_check( - Config, RebarConfig, ["upgrade", App], Expectation + Config, NewRebarConfig, ["upgrade", App], Expectation ). -- cgit v1.1 From 62dc8fa9c745cca60f45ad301e05c8b70517626c Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 11 Feb 2015 14:00:43 +0000 Subject: Fix testcases, add multi-app upgrade support todo: - relock stuff - default to all apps needing upgrade - more tests? - pkgs? --- test/mock_git_resource.erl | 3 +- test/rebar_upgrade_SUITE.erl | 69 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/mock_git_resource.erl b/test/mock_git_resource.erl index 5d8288e..2f7a72d 100644 --- a/test/mock_git_resource.erl +++ b/test/mock_git_resource.erl @@ -60,7 +60,7 @@ mock_update(Opts) -> ?MOD, needs_update, fun(_Dir, {git, Url, _Ref}) -> App = app(Url), - ct:pal("Needed update? ~p -> ~p", [App, lists:member(App, ToUpdate)]), + ct:pal("Needed update? ~p (~p) -> ~p", [App, {Url,_Ref}, lists:member(App, ToUpdate)]), lists:member(App, ToUpdate) end). @@ -108,7 +108,6 @@ mock_download(Opts) -> {git, Url, {_, Vsn}} = normalize_git(Git, Overrides, Default), App = app(Url), AppDeps = proplists:get_value({App,Vsn}, Deps, []), - ct:pal("creating app ~p", [{Dir, App, Vsn, AppDeps}]), rebar_test_utils:create_app( Dir, App, Vsn, [element(1,D) || D <- AppDeps] diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 0727fff..6491527 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -7,9 +7,9 @@ all() -> [{group, git}].%, {group, pkg}]. groups() -> [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, - pair_a, pair_b, pair_c, + pair_a, pair_b, pair_ab, pair_c, triplet_a, triplet_b, triplet_c, - tree_a, tree_b, tree_c]}, + tree_a, tree_b, tree_c, tree_c2, tree_ac]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -83,7 +83,7 @@ upgrades(top_b) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"B", {error, transitive_dependency}}}; + {"B", {error, {transitive_dependency, <<"B">>}}}}; upgrades(top_c) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -96,7 +96,7 @@ upgrades(top_c) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"C", {error, transitive_dependency}}}; + {"C", {error, {transitive_dependency, <<"C">>}}}}; upgrades(top_d1) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -109,7 +109,7 @@ upgrades(top_d1) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"D", {error, transitive_dependency}}}; + {"D", {error, {transitive_dependency, <<"D">>}}}}; upgrades(top_d2) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -122,7 +122,7 @@ upgrades(top_d2) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"D", {error, transitive_dependency}}}; + {"D", {error, {transitive_dependency, <<"D">>}}}}; upgrades(top_e) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -135,7 +135,7 @@ upgrades(top_e) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"E", {error, unknown_dependency}}}; + {"E", {error, {unknown_dependency, <<"E">>}}}}; upgrades(pair_a) -> {[{"A", "1", [{"C", "1", []}]}, {"B", "1", [{"D", "1", []}]} @@ -154,6 +154,15 @@ upgrades(pair_b) -> ], ["A","B","C","D"], {"B", [{"A","1"},{"C","1"},{"B","2"},{"D","2"}]}}; +upgrades(pair_ab) -> + {[{"A", "1", [{"C", "1", []}]}, + {"B", "1", [{"D", "1", []}]} + ], + [{"A", "2", [{"C", "2", []}]}, + {"B", "2", [{"D", "2", []}]} + ], + ["A","B","C","D"], + {"A,B", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}; upgrades(pair_c) -> {[{"A", "1", [{"C", "1", []}]}, {"B", "1", [{"D", "1", []}]} @@ -162,7 +171,7 @@ upgrades(pair_c) -> {"B", "2", [{"D", "2", []}]} ], ["A","B","C","D"], - {"C", {error, transitive_dependency}}}; + {"C", {error, {transitive_dependency, <<"C">>}}}}; upgrades(triplet_a) -> {[{"A", "1", [{"D",[]}, {"E","3",[]}]}, @@ -264,10 +273,47 @@ upgrades(tree_c) -> {"G",[]}]}, {"C", "1", [{"H",[]}]} ], - ["C"], + ["C","I"], {"C", [{"A","1"}, "D", "J", "E", {"I","1"}, {"B","1"}, "F", "G", - {"C","1"}, "H"]}}. + {"C","1"}, "H"]}}; +upgrades(tree_c2) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[{"K",[]}]}, + {"I","2",[]}]} + ], + ["C", "H"], + {"C", [{"A","1"}, "D", "J", "E", + {"B","1"}, "F", "G", + {"C","1"}, "H", {"I", "2"}, "K"]}}; +upgrades(tree_ac) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}]} + ], + ["C","I"], + {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"}, + {"B","1"}, "F", "G", + {"C","1"}, "H"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. @@ -345,6 +391,7 @@ top_e(Config) -> run(Config). pair_a(Config) -> run(Config). pair_b(Config) -> run(Config). +pair_ab(Config) -> run(Config). pair_c(Config) -> run(Config). triplet_a(Config) -> run(Config). @@ -354,6 +401,8 @@ triplet_c(Config) -> run(Config). tree_a(Config) -> run(Config). tree_b(Config) -> run(Config). tree_c(Config) -> run(Config). +tree_c2(Config) -> run(Config). +tree_ac(Config) -> run(Config). run(Config) -> apply(?config(mock, Config), []), -- cgit v1.1 From 6d8567a7edbf206a0f595c22ecd17af0c46acb87 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 11 Feb 2015 20:06:49 +0000 Subject: Support multiple app upgrade & lock tests - Many apps is supported through and through - Not mentioning any app upgrades all apps - Locks are refreshed on disk and tested as such after an upgrade --- test/rebar_test_utils.erl | 14 ++++++++++++++ test/rebar_upgrade_SUITE.erl | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl index 827d134..96200a6 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -103,6 +103,8 @@ create_random_vsn() -> check_results(AppDir, Expected) -> BuildDir = filename:join([AppDir, "_build", "lib"]), CheckoutsDir = filename:join([AppDir, "_checkouts"]), + LockFile = filename:join([AppDir, "rebar.lock"]), + Locks = lists:flatten(rebar_config:consult_file(LockFile)), Apps = rebar_app_discover:find_apps([AppDir]), InvalidApps = rebar_app_discover:find_apps([AppDir], invalid), ValidApps = rebar_app_discover:find_apps([AppDir], valid), @@ -153,6 +155,18 @@ check_results(AppDir, Expected) -> ?assertEqual(iolist_to_binary(Vsn), iolist_to_binary(rebar_app_info:original_vsn(App))) end + ; ({lock, Name}) -> + ct:pal("Name: ~p", [Name]), + ?assertNotEqual(false, lists:keyfind(iolist_to_binary(Name), 1, Locks)) + ; ({lock, Name, Vsn}) -> + ct:pal("Name: ~p, Vsn: ~p", [Name, Vsn]), + case lists:keyfind(iolist_to_binary(Name), 1, Locks) of + false -> + error({lock_not_found, Name}); + {_LockName, {_, _, {ref, LockVsn}}, _} -> + ?assertEqual(iolist_to_binary(Vsn), + iolist_to_binary(LockVsn)) + end end, Expected). write_src_file(Dir, Name) -> diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 6491527..e0bb011 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -7,9 +7,9 @@ all() -> [{group, git}].%, {group, pkg}]. groups() -> [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, - pair_a, pair_b, pair_ab, pair_c, + pair_a, pair_b, pair_ab, pair_c, pair_all, triplet_a, triplet_b, triplet_c, - tree_a, tree_b, tree_c, tree_c2, tree_ac]}, + tree_a, tree_b, tree_c, tree_c2, tree_ac, tree_all]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -172,6 +172,15 @@ upgrades(pair_c) -> ], ["A","B","C","D"], {"C", {error, {transitive_dependency, <<"C">>}}}}; +upgrades(pair_all) -> + {[{"A", "1", [{"C", "1", []}]}, + {"B", "1", [{"D", "1", []}]} + ], + [{"A", "2", [{"C", "2", []}]}, + {"B", "2", [{"D", "2", []}]} + ], + ["A","B","C","D"], + {"", [{"A","2"},{"C","2"},{"B","2"},{"D","2"}]}}; upgrades(triplet_a) -> {[{"A", "1", [{"D",[]}, {"E","3",[]}]}, @@ -313,7 +322,25 @@ upgrades(tree_ac) -> ["C","I"], {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"}, {"B","1"}, "F", "G", - {"C","1"}, "H"]}}. + {"C","1"}, "H"]}}; +upgrades(tree_all) -> + {[{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}, + {"I","2",[]}]} + ], + [{"A", "1", [{"D",[{"J",[]}]}, + {"E",[{"I","1",[]}]}]}, + {"B", "1", [{"F",[]}, + {"G",[]}]}, + {"C", "1", [{"H",[]}]} + ], + ["C","I"], + {"", [{"A","1"}, "D", "J", "E", {"I","1"}, + {"B","1"}, "F", "G", + {"C","1"}, "H"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. @@ -377,10 +404,12 @@ normalize_unlocks_expect({error, Reason}) -> normalize_unlocks_expect([]) -> []; normalize_unlocks_expect([{App,Vsn} | Rest]) -> - [{dep, App, Vsn} + [{dep, App, Vsn}, + {lock, App, Vsn} | normalize_unlocks_expect(Rest)]; normalize_unlocks_expect([App | Rest]) -> - [{dep, App} | normalize_unlocks_expect(Rest)]. + [{dep, App}, + {lock, App} | normalize_unlocks_expect(Rest)]. top_a(Config) -> run(Config). top_b(Config) -> run(Config). @@ -393,6 +422,7 @@ pair_a(Config) -> run(Config). pair_b(Config) -> run(Config). pair_ab(Config) -> run(Config). pair_c(Config) -> run(Config). +pair_all(Config) -> run(Config). triplet_a(Config) -> run(Config). triplet_b(Config) -> run(Config). @@ -403,6 +433,7 @@ tree_b(Config) -> run(Config). tree_c(Config) -> run(Config). tree_c2(Config) -> run(Config). tree_ac(Config) -> run(Config). +tree_all(Config) -> run(Config). run(Config) -> apply(?config(mock, Config), []), -- cgit v1.1 From 2e34e91dfb54218597f72faac3a39aedd57bcf97 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Wed, 11 Feb 2015 21:00:37 +0000 Subject: Warnings for Deletions and friendly errors Apps that are no longer used are not automatically deleted, but we tell users it can be done. This is safer while we're not sure of the correctness of these messages. Error messages are added for transient dependencies and dependencies not found. --- test/mock_git_resource.erl | 2 +- test/rebar_upgrade_SUITE.erl | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/mock_git_resource.erl b/test/mock_git_resource.erl index 2f7a72d..d2f0207 100644 --- a/test/mock_git_resource.erl +++ b/test/mock_git_resource.erl @@ -60,7 +60,7 @@ mock_update(Opts) -> ?MOD, needs_update, fun(_Dir, {git, Url, _Ref}) -> App = app(Url), - ct:pal("Needed update? ~p (~p) -> ~p", [App, {Url,_Ref}, lists:member(App, ToUpdate)]), +% ct:pal("Needed update? ~p (~p) -> ~p", [App, {Url,_Ref}, lists:member(App, ToUpdate)]), lists:member(App, ToUpdate) end). diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index e0bb011..39b9687 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -9,7 +9,8 @@ groups() -> [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, pair_a, pair_b, pair_ab, pair_c, pair_all, triplet_a, triplet_b, triplet_c, - tree_a, tree_b, tree_c, tree_c2, tree_ac, tree_all]}, + tree_a, tree_b, tree_c, tree_c2, tree_ac, tree_all, + delete_d]}, {git, [], [{group, all}]}, {pkg, [], [{group, all}]}]. @@ -83,7 +84,7 @@ upgrades(top_b) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"B", {error, {transitive_dependency, <<"B">>}}}}; + {"B", {error, {rebar_prv_upgrade, {transitive_dependency, <<"B">>}}}}}; upgrades(top_c) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -96,7 +97,7 @@ upgrades(top_c) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"C", {error, {transitive_dependency, <<"C">>}}}}; + {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}}; upgrades(top_d1) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -109,7 +110,7 @@ upgrades(top_d1) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"D", {error, {transitive_dependency, <<"D">>}}}}; + {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}}; upgrades(top_d2) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -122,7 +123,7 @@ upgrades(top_d2) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"D", {error, {transitive_dependency, <<"D">>}}}}; + {"D", {error, {rebar_prv_upgrade, {transitive_dependency, <<"D">>}}}}}; upgrades(top_e) -> %% Original tree {[{"A", "1", [{"B", [{"D", "1", []}]}, @@ -135,7 +136,7 @@ upgrades(top_e) -> %% Modified apps, gobally ["A","B","D"], %% upgrade vs. new tree - {"E", {error, {unknown_dependency, <<"E">>}}}}; + {"E", {error, {rebar_prv_upgrade, {unknown_dependency, <<"E">>}}}}}; upgrades(pair_a) -> {[{"A", "1", [{"C", "1", []}]}, {"B", "1", [{"D", "1", []}]} @@ -171,7 +172,7 @@ upgrades(pair_c) -> {"B", "2", [{"D", "2", []}]} ], ["A","B","C","D"], - {"C", {error, {transitive_dependency, <<"C">>}}}}; + {"C", {error, {rebar_prv_upgrade, {transitive_dependency, <<"C">>}}}}}; upgrades(pair_all) -> {[{"A", "1", [{"C", "1", []}]}, {"B", "1", [{"D", "1", []}]} @@ -340,7 +341,17 @@ upgrades(tree_all) -> ["C","I"], {"", [{"A","1"}, "D", "J", "E", {"I","1"}, {"B","1"}, "F", "G", - {"C","1"}, "H"]}}. + {"C","1"}, "H"]}}; +upgrades(delete_d) -> + {[{"A", "1", [{"B", [{"D", "1", []}]}, + {"C", [{"D", "2", []}]}]} + ], + [{"A", "2", [{"B", []}, + {"C", []}]} + ], + ["A","B", "C"], + %% upgrade vs. new tree + {"", [{"A","2"}, "B", "C"]}}. %% TODO: add a test that verifies that unlocking files and then %% running the upgrade code is enough to properly upgrade things. @@ -353,7 +364,6 @@ top_level_deps([{{pkg, Name, Vsn, _URL}, _} | Deps]) -> mock_deps(git, Deps, Upgrades) -> catch mock_git_resource:unmock(), - ct:pal("mocked: ~p", [flat_deps(Deps)]), mock_git_resource:mock([{deps, flat_deps(Deps)}, {upgrade, Upgrades}]); mock_deps(pkg, Deps, Upgrades) -> catch mock_pkg_resource:unmock(), @@ -435,6 +445,15 @@ tree_c2(Config) -> run(Config). tree_ac(Config) -> run(Config). tree_all(Config) -> run(Config). +delete_d(Config) -> + meck:new(rebar_log, [no_link, passthrough]), + run(Config), + Infos = [{Str, Args} + || {_, {rebar_log, log, [info, Str, Args]}, _} <- meck:history(rebar_log)], + meck:unload(rebar_log), + ?assertNotEqual([], + [1 || {"App ~ts is no longer needed and can be deleted.", + [<<"D">>]} <- Infos]). run(Config) -> apply(?config(mock, Config), []), {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), -- cgit v1.1