Browse Source

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
pull/126/head
Fred Hebert 10 years ago
parent
commit
6d8567a7ed
3 changed files with 69 additions and 24 deletions
  1. +19
    -19
      src/rebar_prv_upgrade.erl
  2. +14
    -0
      test/rebar_test_utils.erl
  3. +36
    -5
      test/rebar_upgrade_SUITE.erl

+ 19
- 19
src/rebar_prv_upgrade.erl View File

@ -40,35 +40,39 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) -> do(State) ->
{Args, _} = rebar_state:command_parsed_args(State), {Args, _} = rebar_state:command_parsed_args(State),
Names = parse_names(ec_cnv:to_binary(proplists:get_value(package, Args))),
%% TODO: support many names. Only a subtree can be updated per app
%% mentioned. When no app is named, unlock *everything*
Locks = rebar_state:get(State, {locks, default}, []), Locks = rebar_state:get(State, {locks, default}, []),
Deps = rebar_state:get(State, deps), Deps = rebar_state:get(State, deps),
Names = parse_names(ec_cnv:to_binary(proplists:get_value(package, Args)), Locks),
case prepare_locks(Names, Deps, Locks, []) of case prepare_locks(Names, Deps, Locks, []) of
{error, Reason} -> {error, Reason} ->
{error, Reason}; {error, Reason};
{Locks0, Unlocks0} ->
{Locks0, _Unlocks0} -> % unlocks may be useful for deletions
Deps0 = top_level_deps(Deps, Locks), Deps0 = top_level_deps(Deps, Locks),
State1 = rebar_state:set(State, {deps, default}, Deps0), State1 = rebar_state:set(State, {deps, default}, Deps0),
State2 = rebar_state:set(State1, {locks, default}, Locks0), State2 = rebar_state:set(State1, {locks, default}, Locks0),
State3 = rebar_state:set(State2, upgrade, true), State3 = rebar_state:set(State2, upgrade, true),
Res = rebar_prv_install_deps:do(State3), Res = rebar_prv_install_deps:do(State3),
case Res of case Res of
{ok, S} ->
ct:pal("original locks ~p", [Locks]),
ct:pal("new locks ~p", [Locks0]),
ct:pal("old deps: ~p", [Deps]),
ct:pal("new deps: ~p", [Deps0]),
ct:pal("Unlocks: ~p", [Unlocks0]),
%% TODO: replace new locks onto the old locks list
rebar_prv_lock:do(S);
_ -> Res
{ok, State4} ->
rebar_prv_lock:do(State4);
_ ->
Res
end end
end. end.
parse_names(Bin) ->
lists:usort(re:split(Bin, <<" *, *">>, [trim])).
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
parse_names(Bin, Locks) ->
case lists:usort(re:split(Bin, <<" *, *">>, [trim])) of
%% Nothing submitted, use *all* apps
[<<"">>] -> [Name || {Name, _, 0} <- Locks];
[] -> [Name || {Name, _, 0} <- Locks];
%% Regular options
Other -> Other
end.
prepare_locks([], _, Locks, Unlocks) -> prepare_locks([], _, Locks, Unlocks) ->
{Locks, Unlocks}; {Locks, Unlocks};
@ -109,7 +113,3 @@ unlock_higher_than(Level, [App = {_,_,AppLevel} | Apps], Locks, Unlocks) ->
AppLevel =< Level -> unlock_higher_than(Level, Apps, [App | Locks], Unlocks) AppLevel =< Level -> unlock_higher_than(Level, Apps, [App | Locks], Unlocks)
end. end.
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).

+ 14
- 0
test/rebar_test_utils.erl View File

@ -103,6 +103,8 @@ create_random_vsn() ->
check_results(AppDir, Expected) -> check_results(AppDir, Expected) ->
BuildDir = filename:join([AppDir, "_build", "lib"]), BuildDir = filename:join([AppDir, "_build", "lib"]),
CheckoutsDir = filename:join([AppDir, "_checkouts"]), 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]), Apps = rebar_app_discover:find_apps([AppDir]),
InvalidApps = rebar_app_discover:find_apps([AppDir], invalid), InvalidApps = rebar_app_discover:find_apps([AppDir], invalid),
ValidApps = rebar_app_discover:find_apps([AppDir], valid), ValidApps = rebar_app_discover:find_apps([AppDir], valid),
@ -153,6 +155,18 @@ check_results(AppDir, Expected) ->
?assertEqual(iolist_to_binary(Vsn), ?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App))) iolist_to_binary(rebar_app_info:original_vsn(App)))
end 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). end, Expected).
write_src_file(Dir, Name) -> write_src_file(Dir, Name) ->

+ 36
- 5
test/rebar_upgrade_SUITE.erl View File

@ -7,9 +7,9 @@ all() -> [{group, git}].%, {group, pkg}].
groups() -> groups() ->
[{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, [{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, 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}]}, {git, [], [{group, all}]},
{pkg, [], [{group, all}]}]. {pkg, [], [{group, all}]}].
@ -172,6 +172,15 @@ upgrades(pair_c) ->
], ],
["A","B","C","D"], ["A","B","C","D"],
{"C", {error, {transitive_dependency, <<"C">>}}}}; {"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) -> upgrades(triplet_a) ->
{[{"A", "1", [{"D",[]}, {[{"A", "1", [{"D",[]},
{"E","3",[]}]}, {"E","3",[]}]},
@ -313,7 +322,25 @@ upgrades(tree_ac) ->
["C","I"], ["C","I"],
{"C, A", [{"A","1"}, "D", "J", "E", {"I","1"}, {"C, A", [{"A","1"}, "D", "J", "E", {"I","1"},
{"B","1"}, "F", "G", {"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 %% TODO: add a test that verifies that unlocking files and then
%% running the upgrade code is enough to properly upgrade things. %% 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([]) ->
[]; [];
normalize_unlocks_expect([{App,Vsn} | Rest]) -> normalize_unlocks_expect([{App,Vsn} | Rest]) ->
[{dep, App, Vsn}
[{dep, App, Vsn},
{lock, App, Vsn}
| normalize_unlocks_expect(Rest)]; | normalize_unlocks_expect(Rest)];
normalize_unlocks_expect([App | 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_a(Config) -> run(Config).
top_b(Config) -> run(Config). top_b(Config) -> run(Config).
@ -393,6 +422,7 @@ pair_a(Config) -> run(Config).
pair_b(Config) -> run(Config). pair_b(Config) -> run(Config).
pair_ab(Config) -> run(Config). pair_ab(Config) -> run(Config).
pair_c(Config) -> run(Config). pair_c(Config) -> run(Config).
pair_all(Config) -> run(Config).
triplet_a(Config) -> run(Config). triplet_a(Config) -> run(Config).
triplet_b(Config) -> run(Config). triplet_b(Config) -> run(Config).
@ -403,6 +433,7 @@ tree_b(Config) -> run(Config).
tree_c(Config) -> run(Config). tree_c(Config) -> run(Config).
tree_c2(Config) -> run(Config). tree_c2(Config) -> run(Config).
tree_ac(Config) -> run(Config). tree_ac(Config) -> run(Config).
tree_all(Config) -> run(Config).
run(Config) -> run(Config) ->
apply(?config(mock, Config), []), apply(?config(mock, Config), []),

Loading…
Cancel
Save