aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/test/diameter_app_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diameter/test/diameter_app_SUITE.erl')
-rw-r--r--lib/diameter/test/diameter_app_SUITE.erl139
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}.