diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/rebar_deps_SUITE.erl | 1 | ||||
| -rw-r--r-- | test/rebar_test_utils.erl | 12 | ||||
| -rw-r--r-- | test/rebar_upgrade_SUITE.erl | 185 | 
3 files changed, 196 insertions, 2 deletions
| 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]. + | 
