Browse Source

very quick test of git_subdir

pull/2239/head
Tristan Sloughter 5 years ago
parent
commit
bff3b76dba
No known key found for this signature in database GPG Key ID: AAB97DDECCEB8150
3 changed files with 189 additions and 2 deletions
  1. +142
    -0
      test/mock_git_subdir_resource.erl
  2. +17
    -1
      test/rebar_compile_SUITE.erl
  3. +30
    -1
      test/rebar_test_utils.erl

+ 142
- 0
test/mock_git_subdir_resource.erl View File

@ -0,0 +1,142 @@
%%% Mock a git_subdir resource and create an app magically for each
%%% URL and subdirectory submitted.
-module(mock_git_subdir_resource).
-export([mock/0, mock/1, mock/2, unmock/0]).
-define(MOD, rebar_git_subdir_resource).
%%%%%%%%%%%%%%%%%
%%% Interface %%%
%%%%%%%%%%%%%%%%%
%% @doc same as `mock([])'.
mock() -> mock([]).
%% @doc Mocks a fake version of the git resource fetcher that creates
%% empty applications magically, rather than trying to download them.
%% Specific config options are explained in each of the private functions.
-spec mock(Opts) -> ok when
Opts :: [Option],
Option :: {update, [App]}
| {default_vsn, Vsn}
| {override_vsn, [{App, Vsn}]}
| {deps, [{App, [Dep]}]},
App :: string(),
Dep :: {App, {git_subdir, string(), term(), string()}}
| {pkg, App, term()},
Vsn :: string().
mock(Opts) ->
mock(Opts, create_app).
mock(Opts, CreateType) ->
meck:new(?MOD, [no_link, passthrough]),
mock_lock(Opts),
mock_update(Opts),
mock_vsn(Opts),
mock_download(Opts, CreateType),
ok.
unmock() ->
meck:unload(?MOD).
%%%%%%%%%%%%%%%
%%% Private %%%
%%%%%%%%%%%%%%%
%% @doc creates values for a lock file. The refs are fake, but
%% tags and existing refs declared for a dependency are preserved.
mock_lock(_) ->
meck:expect(
?MOD, lock,
fun(AppInfo, _) ->
case rebar_app_info:source(AppInfo) of
{git_subdir, Url, {tag, Ref}, Dir} -> {git_subdir, Url, {ref, Ref}, Dir};
{git_subdir, Url, {ref, Ref}, Dir} -> {git_subdir, Url, {ref, Ref}, Dir};
{git_subdir, Url, Dir} -> {git_subdir, Url, {ref, "0.0.0"}, Dir};
{git_subdir, Url, _, Dir} -> {git_subdir, Url, {ref, "0.0.0"}, Dir}
end
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"]}'.
mock_update(Opts) ->
ToUpdate = proplists:get_value(upgrade, Opts, []),
% ct:pal("TOUp: ~p", [ToUpdate]),
meck:expect(
?MOD, needs_update,
fun(AppInfo, _) ->
{git_subdir, 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)
end).
%% @doc Tries to fetch a version from the `*.app.src' file or otherwise
%% just returns random stuff, avoiding to check for the presence of git.
%% This probably breaks the assumption that stable references are returned.
%%
%% This function can't respect the `override_vsn' option because if the
%% .app.src file isn't there, we can't find the app name either.
mock_vsn(Opts) ->
Default = proplists:get_value(default_vsn, Opts, "0.0.0"),
meck:expect(
?MOD, make_vsn,
fun(AppInfo, _) ->
Dir = rebar_app_info:dir(AppInfo),
case filelib:wildcard("*.app.src", filename:join([Dir,"src"])) of
[AppSrc] ->
{ok, App} = file:consult(AppSrc),
Vsn = proplists:get_value(vsn, App),
{plain, Vsn};
_ ->
{plain, Default}
end
end).
%% @doc For each app to download, create a dummy app on disk instead.
%% The configuration for this one (passed in from `mock/1') includes:
%%
%% - Specify a version, branch, ref, or tag via the `{git_subdir, URL, {_, Vsn}'
%% format to specify a path.
%% - If there is no version submitted (`{git_subdir, URL}'), the function instead
%% reads from the `override_vsn' proplist (`{override_vsn, {"App1","1.2.3"}'),
%% and otherwise uses the value associated with `default_vsn'.
%% - Dependencies for each application must be passed of the form:
%% `{deps, [{"app1", [{app2, ".*", {git_subdir, ...}}]}]}' -- basically
%% the `deps' option takes a key/value list of terms to output directly
%% into a `rebar.config' file to describe dependencies.
mock_download(Opts, CreateType) ->
Deps = proplists:get_value(deps, Opts, []),
Config = proplists:get_value(config, Opts, []),
Default = proplists:get_value(default_vsn, Opts, "0.0.0"),
Overrides = proplists:get_value(override_vsn, Opts, []),
meck:expect(
?MOD, download,
fun (Dir, AppInfo, _, _) ->
Git = rebar_app_info:source(AppInfo),
filelib:ensure_dir(Dir),
{git_subdir, Url, {_, Vsn}, SubDir} = normalize_git(Git, Overrides, Default),
FullSubDir = filename:join(Dir, SubDir),
filelib:ensure_dir(FullSubDir),
App = app(Url),
AppDeps = proplists:get_value({App,Vsn}, Deps, []),
rebar_test_utils:CreateType(
FullSubDir, App, Vsn,
[kernel, stdlib] ++ [element(1,D) || D <- AppDeps]
),
rebar_test_utils:create_config(FullSubDir, [{deps, AppDeps}]++Config),
ok
end).
%%%%%%%%%%%%%%%
%%% Helpers %%%
%%%%%%%%%%%%%%%
app(Path) ->
filename:basename(Path, ".git").
normalize_git({git_subdir, Url, SubDir}, Overrides, Default) ->
Vsn = proplists:get_value(app(Url), Overrides, Default),
{git, Url, {tag, Vsn}, SubDir};
normalize_git({git_subdir, Url, Branch, SubDir}, _, _) when is_list(Branch) ->
{git, Url, {branch, Branch}, SubDir};
normalize_git(Git, _, _) ->
Git.

+ 17
- 1
test/rebar_compile_SUITE.erl View File

@ -27,7 +27,7 @@ all() ->
parse_transform_test, erl_first_files_test, mib_test,
umbrella_mib_first_test, only_default_transitive_deps, clean_all,
clean_specific, profile_deps, deps_build_in_prod, only_deps,
override_deps, override_add_deps, override_del_deps,
override_deps, git_subdir_deps, override_add_deps, override_del_deps,
override_opts, override_add_opts, override_del_opts,
apply_overrides_exactly_once, override_only_deps,
profile_override_deps, profile_override_add_deps, profile_override_del_deps,
@ -1531,6 +1531,22 @@ override_deps(Config) ->
{dep_not_exist, "other_dep"}]}
).
git_subdir_deps(Config) ->
Deps = rebar_test_utils:expand_deps(git_subdir, [{"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_subdir_resource:mock([{deps, SrcDeps}]),
RebarConfig = [
{deps, TopDeps}
],
rebar_test_utils:run_and_check(
Config, RebarConfig, ["compile"],
{ok, [{subdir_dep, "some_dep"},
{subdir_dep, "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),

+ 30
- 1
test/rebar_test_utils.erl View File

@ -183,6 +183,12 @@ random_seed() ->
-endif.
expand_deps(_, []) -> [];
expand_deps(git_subdir, [{Name, Deps} | Rest]) ->
Dep = {Name, {git_subdir, "https://example.org/user/"++Name++".git", {branch, "master"}, "appsubdir"}},
[{Dep, expand_deps(git_subdir, Deps)} | expand_deps(git_subdir, Rest)];
expand_deps(git_subdir, [{Name, Vsn, Deps} | Rest]) ->
Dep = {Name, Vsn, {git_subdir, "https://example.org/user/"++Name++".git", {tag, Vsn}, "appsubdir"}},
[{Dep, expand_deps(git_subdir, Deps)} | expand_deps(git_subdir, Rest)];
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)];
@ -226,6 +232,12 @@ flat_deps([{{pkg, Name, Vsn, undefined, undefined}, PkgDeps} | Rest], Src, Pkg)
Src,
Pkg ++ [Current | FlatPkgDeps]);
flat_deps([{{Name,_Vsn,Ref}, Deps} | Rest], Src, Pkg) ->
Current = {{Name,vsn_from_ref(Ref)}, top_level_deps(Deps)},
{FlatDeps, FlatPkgDeps} = flat_deps(Deps),
flat_deps(Rest,
Src ++ [Current | FlatDeps],
Pkg ++ FlatPkgDeps);
flat_deps([{{Name,Ref}, Deps} | Rest], Src, Pkg) ->
Current = {{Name,vsn_from_ref(Ref)}, top_level_deps(Deps)},
{FlatDeps, FlatPkgDeps} = flat_deps(Deps),
flat_deps(Rest,
@ -233,7 +245,9 @@ flat_deps([{{Name,_Vsn,Ref}, Deps} | Rest], Src, Pkg) ->
Pkg ++ FlatPkgDeps).
vsn_from_ref({git, _, {_, Vsn}}) -> Vsn;
vsn_from_ref({git, _, Vsn}) -> Vsn.
vsn_from_ref({git, _, Vsn}) -> Vsn;
vsn_from_ref({git_subdir, _, {_, Vsn}, _}) -> Vsn;
vsn_from_ref({git_subdir, _, Vsn, _}) -> Vsn.
top_level_deps([]) -> [];
top_level_deps([{{pkg, Name, Vsn, undefined, undefined}, _} | Deps]) ->
@ -246,6 +260,7 @@ top_level_deps([{{Name, Vsn, Ref}, _} | Deps]) ->
%%%%%%%%%%%%%%%
check_results(AppDir, Expected, ProfileRun) ->
BuildDirs = filelib:wildcard(filename:join([AppDir, "_build", ProfileRun, "lib", "*"])),
BuildSubDirs = 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", "*"])),
CheckoutsDirs = filelib:wildcard(filename:join([AppDir, "_checkouts", "*"])),
@ -259,7 +274,9 @@ check_results(AppDir, Expected, ProfileRun) ->
ValidDepsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- ValidApps],
Deps = rebar_app_discover:find_apps(BuildDirs, all),
SubDeps = rebar_app_discover:find_apps(BuildSubDirs, all),
DepsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- Deps],
SubDirDepsNames = [{ec_cnv:to_list(rebar_app_info:name(App)), App} || App <- SubDeps],
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),
@ -323,6 +340,18 @@ check_results(AppDir, Expected, ProfileRun) ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App)))
end
; ({subdir_dep, Name}) ->
ct:pal("Subdir Dep Name: ~p", [Name]),
?assertNotEqual(false, lists:keyfind(Name, 1, SubDirDepsNames))
; ({subdir_dep, Name, Vsn}) ->
ct:pal("Subdir Dep Name: ~p, Vsn: ~p", [Name, Vsn]),
case lists:keyfind(Name, 1, SubDirDepsNames) of
false ->
error({dep_not_found, Name});
{Name, App} ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(rebar_app_info:original_vsn(App)))
end
; ({plugin, Name}) ->
ct:pal("Plugin Name: ~p", [Name]),
?assertNotEqual(false, lists:keyfind(Name, 1, PluginsNames))

Loading…
Cancel
Save