aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-03-30 19:49:52 +0200
committerAnders Svensson <[email protected]>2014-03-31 16:43:10 +0200
commitd360e898d93502d1d27d4552688476a629fdd52e (patch)
treea8cf2dd51c0cd88b89b7898bf56e500f21d25a15
parent1106d1e478f979cd201a66d3180a4511bfa56a93 (diff)
downloadotp-d360e898d93502d1d27d4552688476a629fdd52e.tar.gz
otp-d360e898d93502d1d27d4552688476a629fdd52e.tar.bz2
otp-d360e898d93502d1d27d4552688476a629fdd52e.zip
Add app suite test for app file runtime_dependencies
In particular, that modules listed in the 'modules' tuple only call modules in other applications listed in the 'runtime_dependencies' tuple.
-rw-r--r--lib/diameter/test/diameter_app_SUITE.erl54
1 files changed, 44 insertions, 10 deletions
diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl
index 1e262895a6..891147b7d1 100644
--- a/lib/diameter/test/diameter_app_SUITE.erl
+++ b/lib/diameter/test/diameter_app_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -158,12 +158,15 @@ appvsn(Name) ->
%% # xref/1
%%
%% Ensure that no function in our application calls an undefined function
-%% or one in an application we haven't specified as a dependency. (Almost.)
+%% or one in an application we haven't declared as a dependency. (Almost.)
%% ===========================================================================
xref(Config) ->
App = fetch(app, Config),
- Mods = fetch(modules, App),
+ Mods = fetch(modules, App), %% modules listed in the app file
+
+ %% List of application names extracted from runtime_dependencies.
+ Deps = lists:map(fun unversion/1, fetch(runtime_dependencies, App)),
{ok, XRef} = xref:start(make_name(xref_test_name)),
ok = xref:set_default(XRef, [{verbose, false}, {warnings, false}]),
@@ -178,7 +181,8 @@ xref(Config) ->
[?APP, erts | fetch(applications, App)]),
{ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
- {ok, Called} = xref:analyze(XRef, {module_call, ?COMPILER_MODULES}),
+ {ok, CTdeps} = xref:analyze(XRef, {module_call, ?COMPILER_MODULES}),
+ {ok, RTdeps} = xref:analyze(XRef, {module_call, Mods}),
xref:stop(XRef),
@@ -193,15 +197,45 @@ xref(Config) ->
%% TLS security: it's up to a client who wants TLS it to start
%% ssl.
- [] = lists:filter(fun is_bad_dependency/1, Called).
+ %% Ensure that compiler modules don't call runtime modules.
+ [] = lists:filter(fun nok_compiler_dependency/1, CTdeps),
+
+ %% Ensure that runtime modules only call other runtime modules, or
+ %% applications declared as in runtime_dependencies in the app
+ %% file. Note that the declared application versions are ignored
+ %% since we only know what we can see now.
+ [] = lists:filter(fun(M) -> not ok_runtime_dependency(M, Mods, Deps) end,
+ RTdeps).
+
+unversion(App) ->
+ T = lists:dropwhile(fun is_vsn_ch/1, lists:reverse(App)),
+ lists:reverse(case T of [$-|TT] -> TT; _ -> T end).
+
+is_vsn_ch(C) ->
+ $0 =< C andalso C =< $9 orelse $. == C.
%% It's not strictly necessary that diameter compiler modules not
%% depend on other diameter modules but it's a simple source of build
-%% errors if not encoded in the makefile (hence the test) so guard
-%% against it.
-is_bad_dependency(Mod) ->
- lists:prefix("diameter", atom_to_list(Mod))
- andalso not lists:member(Mod, ?COMPILER_MODULES).
+%% errors if not properly encoded in the makefile so guard against it.
+nok_compiler_dependency(Mod) ->
+ is_diameter(Mod) andalso not lists:member(Mod, ?COMPILER_MODULES).
+
+ok_runtime_dependency(Mod, Mods, Apps) ->
+ lists:member(app(Mod), Apps)
+ orelse (is_diameter(Mod) andalso lists:member(Mod, Mods)).
+
+is_diameter(Mod) ->
+ lists:prefix("diameter", atom_to_list(Mod)).
+
+app('$M_EXPR') -> %% could be anything but assume it's ok
+ "erts";
+app(Mod) ->
+ case code:which(Mod) of
+ preloaded ->
+ "erts";
+ Path ->
+ unversion(lists:nth(3, lists:reverse(filename:split(Path))))
+ end.
add_application(XRef, App) ->
add_application(XRef, App, code:lib_dir(App)).