diff options
Diffstat (limited to 'lib/diameter/test/diameter_app_SUITE.erl')
-rw-r--r-- | lib/diameter/test/diameter_app_SUITE.erl | 139 |
1 files changed, 117 insertions, 22 deletions
diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl index 898f302457..718f28d066 100644 --- a/lib/diameter/test/diameter_app_SUITE.erl +++ b/lib/diameter/test/diameter_app_SUITE.erl @@ -30,10 +30,12 @@ %% testcases -export([keys/1, + vsn/1, modules/1, exports/1, - applications/1, - undefined_calls/1, undefined_calls/0]). + release/1, + xref/1, xref/0, + relup/1]). -define(APP, diameter). -define(A, list_to_atom). @@ -45,46 +47,62 @@ suite() -> all() -> [keys, + vsn, modules, exports, - applications, - undefined_calls]. + release, + xref, + relup]. init_per_suite(Config) -> - {ok, App} = diameter_util:appfile(?APP), + [{application, ?APP, App}] = diameter_util:consult(?APP, app), [{app, App} | Config]. end_per_suite(_Config) -> ok. %% =========================================================================== - -%% keys/1 +%% # keys/1 %% -%% Ensure that the app file contain required keys. +%% Ensure that the app file contains selected keys. Some of these would +%% also be caught by other testcases. +%% =========================================================================== keys(Config) -> App = fetch(app, Config), [] = lists:filter(fun(K) -> not lists:keymember(K, 1, App) end, [vsn, description, modules, registered, applications]). -%% modules/1 +%% =========================================================================== +%% # vsn/1 +%% +%% Ensure that our app version sticks to convention. +%% =========================================================================== + +vsn(Config) -> + true = is_vsn(fetch(vsn, fetch(app, Config))). + +%% =========================================================================== +%% # modules/1 %% %% Ensure that the app file module list match the installed beams. +%% =========================================================================== modules(Config) -> Mods = fetch(modules, fetch(app, Config)), - Installed = installed_mods(), + Installed = code_mods(), {[], []} = {Mods -- Installed, Installed -- Mods}. -installed_mods() -> +code_mods() -> Dir = code:lib_dir(?APP, ebin), {ok, Files} = file:list_dir(Dir), [?A(lists:reverse(R)) || N <- Files, "maeb." ++ R <- [lists:reverse(N)]]. -%% exports/1 +%% =========================================================================== +%% # exports/1 %% %% Ensure that no module does export_all. +%% =========================================================================== exports(Config) -> Mods = fetch(modules, fetch(app, Config)), @@ -95,22 +113,38 @@ exports_all(Mod) -> is_list(Opts) andalso lists:member(export_all, Opts). -%% applications/1 +%% =========================================================================== +%% # release/1 %% -%% Ensure that each dependent application is on the code path. +%% Ensure that it's possible to build a minimal release with our app file. +%% =========================================================================== -applications(Config) -> - As = fetch(applications, fetch(app, Config)), - [] = [A || A <- As, {error, _} <- [diameter_util:appfile(A)]]. +release(Config) -> + App = fetch(app, Config), + Rel = {release, + {"diameter test release", fetch(vsn, App)}, + {erts, erlang:system_info(version)}, + [{A, appvsn(A)} || A <- fetch(applications, App)]}, + Dir = fetch(priv_dir, Config), + ok = write_file(filename:join([Dir, "diameter_test.rel"]), Rel), + {ok, _, []} = systools:make_script("diameter_test", [{path, [Dir]}, + {outdir, Dir}, + silent]). + +appvsn(Name) -> + [{application, Name, App}] = diameter_util:consult(Name, app), + fetch(vsn, App). -%% undefined_calls/1 +%% =========================================================================== +%% # xref/1 %% -%% Ensure that no function on our application calls an undefined function. +%% Ensure that no function in our application calls an undefined function. +%% =========================================================================== -undefined_calls() -> +xref() -> [{timetrap, {minutes, 2}}]. -undefined_calls(Config) -> +xref(Config) -> Mods = fetch(modules, fetch(app, Config)), RootDir = code:root_dir(), @@ -133,7 +167,68 @@ make_name(Suf) -> list_to_atom(atom_to_list(?APP) ++ "_" ++ atom_to_list(Suf)). %% =========================================================================== +%% # relup/1 +%% +%% Ensure that we can generate release upgrade files using our appup file. +%% =========================================================================== + +relup(Config) -> + [{Vsn, Up, Down}] = diameter_util:consult(?APP, appup), + true = is_vsn(Vsn), + + App = fetch(app, Config), + Rel = [{erts, erlang:system_info(version)} + | [{A, appvsn(A)} || A <- fetch(applications, App)]], + + Dir = fetch(priv_dir, Config), + + Name = write_rel(Dir, Rel, Vsn), + UpFrom = acc_rel(Dir, Rel, Up), + DownTo = acc_rel(Dir, Rel, Down), + + {[Name], [Name], UpFrom, DownTo} %% no intersections + = {[Name] -- UpFrom, + [Name] -- DownTo, + UpFrom -- DownTo, + DownTo -- UpFrom}, + + {ok, _, _, []} = systools:make_relup(Name, UpFrom, DownTo, [{path, [Dir]}, + {outdir, Dir}, + silent]). + +acc_rel(Dir, Rel, List) -> + lists:foldl(fun(T,A) -> acc_rel(Dir, Rel, T, A) end, + [], + List). + +acc_rel(Dir, Rel, {Vsn, _}, Acc) -> + [write_rel(Dir, Rel, Vsn) | Acc]. + +%% Write a rel file and return its name. +write_rel(Dir, [Erts | Apps], Vsn) -> + true = is_vsn(Vsn), + Name = "diameter_test_" ++ Vsn, + ok = write_file(filename:join([Dir, Name ++ ".rel"]), + {release, + {"diameter " ++ Vsn ++ " test release", Vsn}, + Erts, + Apps}), + Name. + +%% =========================================================================== +%% =========================================================================== fetch(Key, List) -> - {Key, Val} = lists:keyfind(Key, 1, List), + {Key, {Key, Val}} = {Key, lists:keyfind(Key, 1, List)}, %% useful badmatch Val. + +write_file(Path, T) -> + file:write_file(Path, io_lib:format("~p.", [T])). + +%% Is a version string of the expected form? Return the argument +%% itself for 'false' for a useful badmatch. +is_vsn(V) -> + is_list(V) + andalso length(V) == string:span(V, "0123456789.") + andalso V == string:join(string:tokens(V, [$.]), ".") %% no ".." + orelse {error, V}. |