From 2458d263c46c90ac55a6eaf5cbca18b02c8a65f2 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Wed, 6 Mar 2013 22:26:10 +0100 Subject: Minor tweaks and fixes Fix a broken include in example code, remove an inappropriate ct:pal/2 outside of a testcase, echo more info from test/Makefile. --- lib/diameter/examples/code/redirect_cb.erl | 4 ++-- lib/diameter/test/Makefile | 5 +++++ lib/diameter/test/diameter_ct.erl | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/diameter/examples/code/redirect_cb.erl b/lib/diameter/examples/code/redirect_cb.erl index da31add70d..69836774a1 100644 --- a/lib/diameter/examples/code/redirect_cb.erl +++ b/lib/diameter/examples/code/redirect_cb.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. 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 @@ -20,7 +20,7 @@ -module(redirect_cb). -include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). +-include_lib("diameter/include/diameter_gen_base_rfc3588.hrl"). %% diameter callbacks -export([peer_up/3, diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile index 061f0bcbef..9719c67b32 100644 --- a/lib/diameter/test/Makefile +++ b/lib/diameter/test/Makefile @@ -93,6 +93,11 @@ info: @$(call list,HRL_FILES) @echo @$(call list,SUITES) + @echo + @echo erl = $(shell which erl) + @erl -noinput \ + -eval 'io:format("diameter = ~s~n", [code:lib_dir(diameter)])' \ + -s init stop @echo ======================================== help: diff --git a/lib/diameter/test/diameter_ct.erl b/lib/diameter/test/diameter_ct.erl index 1697287a22..ed2f884681 100644 --- a/lib/diameter/test/diameter_ct.erl +++ b/lib/diameter/test/diameter_ct.erl @@ -53,7 +53,7 @@ info(L0, L1) -> L0, L1), Diff = [T, C, {memory, M}], - ct:pal("INFO: ~p~n", [Diff]). + io:format("INFO: ~p~n", [Diff]). diff(time, T0, T1) -> timer:now_diff(T1, T0); -- cgit v1.2.3 From 849d61f719120fddac1e0797cd282e4f0ec7e335 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Mon, 4 Mar 2013 02:16:05 +0100 Subject: Add examples suite for testing example code That is, code installed under examples/code in an installation. --- lib/diameter/test/diameter_examples_SUITE.erl | 213 ++++++++++++++++++++++++++ lib/diameter/test/modules.mk | 1 + 2 files changed, 214 insertions(+) create mode 100644 lib/diameter/test/diameter_examples_SUITE.erl diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl new file mode 100644 index 0000000000..f857f893e2 --- /dev/null +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -0,0 +1,213 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013. 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 +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Test example code under ../examples/code. +%% + +-module(diameter_examples_SUITE). + +-export([suite/0, + all/0]). + +%% testcases +-export([compile/1, + enslave/1, + start/1, + traffic/1, + stop/1]). + +-export([install/1, + call/1]). + +-include("diameter.hrl"). + +%% =========================================================================== + +-define(util, diameter_util). + +%% The order here is significant and causes the server to listen +%% before the clients connect. +-define(NODES, [compile, server, client]). + +%% Options to ct_slave:start/2. +-define(TIMEOUTS, [{T, 15000} || T <- [boot_timeout, + init_timeout, + start_timeout]]). + +%% =========================================================================== + +suite() -> + [{timetrap, {seconds, 45}}]. + +all() -> + [compile, + enslave, + start, + traffic, + stop]. + +%% =========================================================================== + +%% compile/1 + +compile(Config) -> + Node = slave(hd(?NODES), here()), + [] = rpc:call(Node, + ?MODULE, + install, + [proplists:get_value(priv_dir, Config)]). + +%% Compile on another node since the code path may be modified. +install(PrivDir) -> + Top = install(here(), PrivDir), + Src = filename:join([Top, "examples", "code"]), + Files = find_files(Src, ".*\\.erl"), + [] = [{F,E} || F <- Files, + {error, _, _} = E <- [compile:file(F, [warnings_as_errors, + return_errors])]]. + +%% Copy include files into a temporary directory and adjust the code +%% path in order for example code to be able to include them with +%% include_lib. This is really only required when running in the reop +%% since generated includes, that the example code wants to +%% include_lib, are under src/gen and there's no way to get get the +%% preprocessor to find these otherwise. Generated hrls are only be +%% under include in an installation. ("Installing" them locally is +%% anathema.) +install(Dir, PrivDir) -> + %% Remove the path added by slave/1 (needed for the rpc:call/4 in + %% compile/1 to find ?MODULE) so the call to code:lib_dir/2 below + %% returns the installed path. + [Ebin | _] = code:get_path(), + true = code:del_path(Ebin), + Top = top(Dir, code:lib_dir(diameter)), + + %% Create a new diameter/include in priv_dir, copy all includes + %% there: first the installed includes, then any we find in + %% ../include and ../src/gen. + Tmp = filename:join([PrivDir, "diameter"]), + TmpInc = filename:join([PrivDir, "diameter", "include"]), + TmpEbin = filename:join([PrivDir, "diameter", "ebin"]), + [] = [{T,E} || T <- [Tmp, TmpInc, TmpEbin], + {error, E} <- [file:make_dir(T)]], + + Inc = filename:join([Top, "include"]), + Gen = filename:join([Top, "src", "gen"]), + Files = lists:append([find_files(F, ".*\\.hrl") || F <- [Inc, Gen]]), + [] = [{F,E} || F <- Files, + B <- [filename:basename(F)], + D <- [filename:join([TmpInc, B])], + {error, E} <- [file:copy(F,D)]], + + %% Prepend the created directory just so that code:lib_dir/1 finds + %% it when compile:file/2 tries to resolve include_lib. + true = code:add_patha(TmpEbin), + Tmp = code:lib_dir(diameter), %% assert + %% Return the top directory containing examples/code. + Top. + +find_files(Dir, RE) -> + filelib:fold_files(Dir, RE, false, fun cons/2, []). + +cons(H,T) -> + [H|T]. + +%% enslave/1 +%% +%% Start two nodes: one for the server, one for the client. + +enslave(Config) -> + Dir = here(), + Nodes = [{N, slave(N, Dir)} || N <- tl(?NODES)], + ?util:write_priv(Config, nodes, Nodes). + +slave(Name, Dir) -> + {ok, Node} = ct_slave:start(Name, ?TIMEOUTS), + ok = rpc:call(Node, + code, + add_pathsa, + [[Dir, filename:join([Dir, "..", "ebin"])]]), + Node. + +here() -> + filename:dirname(code:which(?MODULE)). + +top(Dir, LibDir) -> + File = filename:join([Dir, "depend.sed"]), %% only in the repo + case filelib:is_regular(File) of + true -> filename:join([Dir, ".."]); + false -> LibDir + end. + +%% start/1 + +start(server) -> + ok = diameter:start(), + ok = server:start(), + {ok, Ref} = server:listen(tcp), + [_] = ?util:lport(tcp, Ref, 20), + ok; + +start(client) -> + ok = diameter:start(), + true = diameter:subscribe(client), + ok = client:start(), + {ok, Ref} = client:connect(tcp), + receive #diameter_event{info = {up, Ref, _, _, _}} -> ok end; + +start(Config) -> + Nodes = ?util:read_priv(Config, nodes), + [] = [RC || {T,N} <- Nodes, + RC <- [rpc:call(N, ?MODULE, start, [T])], + RC /= ok]. + +%% traffic/1 +%% +%% Send successful messages from client to server. + +traffic(server) -> + ok; + +traffic(client) -> + {_, MRef} = spawn_monitor(fun() -> call(100) end), + receive {'DOWN', MRef, process, _, Reason} -> Reason end; + +traffic(Config) -> + Nodes = ?util:read_priv(Config, nodes), + [] = [RC || {T,N} <- Nodes, + RC <- [rpc:call(N, ?MODULE, traffic, [T])], + RC /= ok]. + +call(0) -> + exit(ok); + +call(N) -> + {ok, _} = client:call(), + call(N-1). + +%% stop/1 + +stop(Name) + when is_atom(Name) -> + {ok, _Node} = ct_slave:stop(Name), + ok; + +stop(_Config) -> + [] = [RC || N <- ?NODES, RC <- [stop(N)], RC /= ok]. diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk index beff588a02..c123de6d0b 100644 --- a/lib/diameter/test/modules.mk +++ b/lib/diameter/test/modules.mk @@ -34,6 +34,7 @@ MODULES = \ diameter_distribution_SUITE \ diameter_dpr_SUITE \ diameter_event_SUITE \ + diameter_examples_SUITE \ diameter_failover_SUITE \ diameter_gen_sctp_SUITE \ diameter_length_SUITE \ -- cgit v1.2.3 From dbdab43a5b4eab278538b9c82c17fccac7f778a3 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sat, 23 Mar 2013 19:16:19 +0100 Subject: Move example dict compilation to examples suite From compiler suite. --- lib/diameter/test/diameter_compiler_SUITE.erl | 51 +---------------- lib/diameter/test/diameter_examples_SUITE.erl | 81 +++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 52 deletions(-) diff --git a/lib/diameter/test/diameter_compiler_SUITE.erl b/lib/diameter/test/diameter_compiler_SUITE.erl index 79bf9d32db..81722c8dca 100644 --- a/lib/diameter/test/diameter_compiler_SUITE.erl +++ b/lib/diameter/test/diameter_compiler_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2012. All Rights Reserved. +%% Copyright Ericsson AB 2010-2013. 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 @@ -31,8 +31,7 @@ %% testcases -export([format/1, format/2, replace/1, replace/2, - generate/1, generate/4, - examples/1]). + generate/1, generate/4]). -export([dict/0]). %% fake dictionary module @@ -328,14 +327,6 @@ "@codecs mymod " "Origin-Host Origin-Realm\n&"}]}]). -%% Standard dictionaries in examples/dict. --define(EXAMPLES, [rfc4004_mip, - rfc4005_nas, - rfc4006_cc, - rfc4072_eap, - rfc4590_digest, - rfc4740_sip]). - %% =========================================================================== suite() -> @@ -344,8 +335,7 @@ suite() -> all() -> [format, replace, - generate, - examples]. + generate]. %% Error handling testcases will make an erroneous dictionary out of %% the base dictionary and check that the expected error results. @@ -428,41 +418,6 @@ generate(Mods, Bin, N, Mode) -> Mode == erl andalso ({ok, _} = compile:file(File ++ ".erl", [return_errors])). -%% =========================================================================== -%% examples/1 -%% -%% Compile dictionaries extracted from various standards. - -examples(_Config) -> - Dir = filename:join([code:lib_dir(diameter, examples), "dict"]), - [D || D <- ?EXAMPLES, _ <- [examples(?S(D), Dir)]]. - -examples(Dict, Dir) -> - {Name, Pre} = make_name(Dict), - ok = diameter_make:codec(filename:join([Dir, Dict ++ ".dia"]), - [{name, Name}, - {prefix, Pre}, - inherits("rfc3588_base") - | opts(Dict)]), - {ok, _, _} = compile:file(Name ++ ".erl", [return]). - -opts(M) - when M == "rfc4006_cc"; - M == "rfc4072_eap" -> - [inherits("rfc4005_nas")]; -opts("rfc4740_sip") -> - [inherits("rfc4590_digest")]; -opts(_) -> - []. - -inherits(File) -> - {Name, _} = make_name(File), - {inherits, File ++ "/" ++ Name}. - -make_name(File) -> - {R, [$_|N]} = lists:splitwith(fun(C) -> C /= $_ end, File), - {string:join(["diameter_gen", N, R], "_"), "diameter_" ++ N}. - %% =========================================================================== modify(Bin, Mods) -> diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl index f857f893e2..16b858041a 100644 --- a/lib/diameter/test/diameter_examples_SUITE.erl +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -27,7 +27,8 @@ all/0]). %% testcases --export([compile/1, +-export([dict/1, dict/0, + code/1, enslave/1, start/1, traffic/1, @@ -57,17 +58,87 @@ suite() -> [{timetrap, {seconds, 45}}]. all() -> - [compile, + [dict, + code, enslave, start, traffic, stop]. %% =========================================================================== +%% dict/1 +%% +%% Compile example dictionaries in examples/dict. + +-define(EXAMPLES, [rfc4004_mip, + rfc4005_nas, + rfc4006_cc, + rfc4072_eap, + rfc4590_digest, + rfc4740_sip]). + +dict() -> + [{timetrap, {minutes, length(?EXAMPLES)}}]. + +dict(_Config) -> + Dir = filename:join([code:lib_dir(diameter, examples), "dict"]), + [] = [RC || D <- ?EXAMPLES, + RC <- [dict(atom_to_list(D), Dir)], + RC /= ok]. + +dict(Dict, Dir) -> + {Name, Pre} = make_name(Dict), + try + ok = make(filename:join([Dir, Dict ++ ".dia"]), + [{name, Name}, + {prefix, Pre}, + inherits("rfc3588_base") + | opts(Dict)]), + ok = compile(Name) + catch + throw: {_,_} = E -> + E + end. + +make(File, Opts) -> + case diameter_make:codec(File, Opts) of + ok -> + ok; + No -> + throw({make, No}) + end. + +compile(Name) -> + case compile:file(Name ++ ".erl", [return]) of + {ok, _, _} -> + ok; + No -> + throw({compile, No}) + end. -%% compile/1 +opts(M) + when M == "rfc4006_cc"; + M == "rfc4072_eap" -> + [inherits("rfc4005_nas")]; +opts("rfc4740_sip") -> + [inherits("rfc4590_digest")]; +opts(_) -> + []. -compile(Config) -> +inherits(File) -> + {Name, _} = make_name(File), + {inherits, File ++ "/" ++ Name}. + +make_name(File) -> + {R, [$_|N]} = lists:splitwith(fun(C) -> C /= $_ end, File), + {string:join(["diameter_gen", N, R], "_"), "diameter_" ++ N}. + +%% =========================================================================== +%% code/1 +%% +%% Compile example code under examples/code. + +code(Config) -> Node = slave(hd(?NODES), here()), [] = rpc:call(Node, ?MODULE, @@ -129,6 +200,8 @@ find_files(Dir, RE) -> cons(H,T) -> [H|T]. +%% =========================================================================== + %% enslave/1 %% %% Start two nodes: one for the server, one for the client. -- cgit v1.2.3 From 9f0819a3582e128a9ef88d6dd79801ecaabcf0f8 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sat, 23 Mar 2013 19:05:39 +0100 Subject: Documentation fixes Fix errors and omissions related to dictionary compilation. --- lib/diameter/doc/src/diameter_compile.xml | 32 ++++++++++++++++++-------- lib/diameter/doc/src/diameter_dict.xml | 5 ++-- lib/diameter/doc/src/diameter_make.xml | 38 +++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/lib/diameter/doc/src/diameter_compile.xml b/lib/diameter/doc/src/diameter_compile.xml index 0bd7ad1789..fc81e4efed 100644 --- a/lib/diameter/doc/src/diameter_compile.xml +++ b/lib/diameter/doc/src/diameter_compile.xml @@ -11,7 +11,7 @@
-20112012 +20112013 Ericsson AB. All Rights Reserved. @@ -59,6 +59,7 @@ The module &man_make; provides an alternate compilation interface.

Compile a single dictionary file to Erlang source. Valid options are as follows.

+ ]]>

@@ -71,7 +72,6 @@ dependency, not an erl/hrl dependency.

Multiple -i options can be specified.

- ]]>

@@ -90,18 +90,30 @@ Supress erl and hrl generation, respectively.

]]>

-Set &dict_name; or &dict_prefix; to the specified -string. -Overrides any setting in the file itself.

+Transform the input dictionary before compilation, setting +&dict_name; or &dict_prefix; to the specified +string.

-]]> +]]>

-Append &dict_inherits; of the specified module. -Specifying "-" has the effect of discarding clearing any -previous inherits, both in the dictionary file and on the options -list.

+Transform the input dictionary before compilation, appending +&dict_inherits; of the specified string.

+ +

+Two forms of --inherits have special meaning:

+ +
+--inherits -
+--inherits Prev/Mod
+
+ +

+The first has the effect of clearing any previous inherits, the second +of replacing a previous inherits of Prev to one of Mod. +This allows the semantics of the input dictionary to be changed without +modifying the file itself.

Multiple --inherits options can be specified.

diff --git a/lib/diameter/doc/src/diameter_dict.xml b/lib/diameter/doc/src/diameter_dict.xml index 1034781ff2..419dc143af 100644 --- a/lib/diameter/doc/src/diameter_dict.xml +++ b/lib/diameter/doc/src/diameter_dict.xml @@ -263,15 +263,14 @@ dictionary's definitions but the former makes for easier reuse.

All dictionaries should typically inherit &the_rfc; AVPs from -diameter_gen_base_rfc3588.

+diameter_gen_base_rfc6733.

Example:

-@inherits diameter_gen_base_rfc3588
+@inherits diameter_gen_base_rfc6733
 
-
diff --git a/lib/diameter/doc/src/diameter_make.xml b/lib/diameter/doc/src/diameter_make.xml index da6124310e..ec71251be1 100644 --- a/lib/diameter/doc/src/diameter_make.xml +++ b/lib/diameter/doc/src/diameter_make.xml @@ -14,6 +14,7 @@
2012 +2013 Ericsson AB. All Rights Reserved. @@ -73,7 +74,7 @@ Compile a single dictionary file to Erlang source. -{include, Dir::string()} +{include, string()}

Prepend the specified directory to the code path. @@ -85,7 +86,7 @@ dependency, not an erl/hrl dependency.

Multiple include options can be specified.

-{outdir, Dir::string()} +{outdir, string()}

Write generated source to the specified directory. @@ -95,18 +96,30 @@ Defaults to the current working directory.

{name|prefix, string()}

-Set &dict_name; or &dict_prefix; to the specified -string. -Overrides any setting in the file itself.

+Transform the input dictionary before compilation, setting +&dict_name; or &dict_prefix; to the specified +string.

-{inherits, Mod::string()} +{inherits, string()}

-Append &dict_inherits; of the specified module. -Specifying "-" has the effect of discarding clearing any -previous inherits, both in the dictionary file and on the options -list.

+Transform the input dictionary before compilation, appending +&dict_inherits; of the specified string.

+ +

+Two forms of @inherits have special meaning:

+ +
+{inherits, "-"}
+{inherits, "Prev/Mod"}
+
+ +

+The first has the effect of clearing any previous inherits, the second +of replacing a previous inherits of Prev to one of Mod. +This allows the semantics of the input dictionary to be changed without +modifying the file itself.

Multiple inherits options can be specified.

@@ -126,8 +139,9 @@ Multiple inherits options can be specified.

All options are string-valued. -In particular, it is not currently possible to -an &dict_inherits; module as an atom() or a path as a &filename;

+In particular, it is not currently possible to specify +an &dict_inherits; module as an atom(), or a path as an arbitrary +&filename;

-- cgit v1.2.3 From a8482e3c1c6eec7989868484da5aa3176a412b1b Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 24 Mar 2013 12:11:15 +0100 Subject: Compile example dicts from the repo when running locally Instead of from the installation. --- lib/diameter/test/diameter_examples_SUITE.erl | 110 +++++++++++++++++--------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl index 16b858041a..3ef901f4bd 100644 --- a/lib/diameter/test/diameter_examples_SUITE.erl +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -52,6 +52,13 @@ init_timeout, start_timeout]]). +%% @inherits dependencies between example dictionaries. This is needed +%% in order compile them in the right order. Can't compile to erl to +%% find out since @inherits is a beam dependency. +-define(INHERITS, [{rfc4006_cc, [rfc4005_nas]}, + {rfc4072_eap, [rfc4005_nas]}, + {rfc4740_sip, [rfc4590_digest]}]). + %% =========================================================================== suite() -> @@ -70,30 +77,53 @@ all() -> %% %% Compile example dictionaries in examples/dict. --define(EXAMPLES, [rfc4004_mip, - rfc4005_nas, - rfc4006_cc, - rfc4072_eap, - rfc4590_digest, - rfc4740_sip]). - dict() -> - [{timetrap, {minutes, length(?EXAMPLES)}}]. + [{timetrap, {minutes, 10}}]. dict(_Config) -> - Dir = filename:join([code:lib_dir(diameter, examples), "dict"]), - [] = [RC || D <- ?EXAMPLES, - RC <- [dict(atom_to_list(D), Dir)], + Dirs = [filename:join(H ++ ["examples", "dict"]) + || H <- [[code:lib_dir(diameter)], [here(), ".."]]], + [] = [RC || {_,F} <- sort(find_files(Dirs, ".*\\.dia")), + RC <- [make(F)], RC /= ok]. -dict(Dict, Dir) -> +sort([{_,_} | _] = Files) -> + lists:sort(fun({A,_},{B,_}) -> + sort([filename:rootname(F) || F <- [A,B]]) + end, + Files); + +sort([A,B] = L) -> + [DA,DB] = [dep([D],[]) || D <- L], + case {[A] -- DB, [B] -- DA} of + {[], [_]} -> %% B depends on A + true; + {[_], []} -> %% A depends on B + false; + {[_],[_]} -> %% or not + length(DA) < length(DB) + end. + +%% Recursively accumulate inherited dictionaries. +dep([D|Rest], Acc) -> + dep(opts(D), Rest, Acc); +dep([], Acc) -> + Acc. + +dep([{inherits, Map} | T], Rest, Acc) -> + [Dict, _] = filename:split(Map), + dep(T, [Dict | Rest], [Dict | Acc]); +dep([], Rest, Acc) -> + dep(Rest, Acc). + +make(Path) -> + Dict = filename:rootname(filename:basename(Path)), {Name, Pre} = make_name(Dict), try - ok = make(filename:join([Dir, Dict ++ ".dia"]), - [{name, Name}, - {prefix, Pre}, - inherits("rfc3588_base") - | opts(Dict)]), + ok = make(Path, [{name, Name}, + {prefix, Pre}, + inherits(rfc3588_base) + | opts(Dict)]), ok = compile(Name) catch throw: {_,_} = E -> @@ -116,14 +146,17 @@ compile(Name) -> throw({compile, No}) end. -opts(M) - when M == "rfc4006_cc"; - M == "rfc4072_eap" -> - [inherits("rfc4005_nas")]; -opts("rfc4740_sip") -> - [inherits("rfc4590_digest")]; -opts(_) -> - []. +opts(Dict) -> + case lists:keyfind(list_to_atom(Dict), 1, ?INHERITS) of + {_, Is} -> + lists:map(fun inherits/1, Is); + false -> + [] + end. + +inherits(File) + when is_atom(File) -> + inherits(atom_to_list(File)); inherits(File) -> {Name, _} = make_name(File), @@ -149,8 +182,8 @@ code(Config) -> install(PrivDir) -> Top = install(here(), PrivDir), Src = filename:join([Top, "examples", "code"]), - Files = find_files(Src, ".*\\.erl"), - [] = [{F,E} || F <- Files, + Files = find_files([Src], ".*\\.erl"), + [] = [{F,E} || {_,F} <- Files, {error, _, _} = E <- [compile:file(F, [warnings_as_errors, return_errors])]]. @@ -170,9 +203,9 @@ install(Dir, PrivDir) -> true = code:del_path(Ebin), Top = top(Dir, code:lib_dir(diameter)), - %% Create a new diameter/include in priv_dir, copy all includes - %% there: first the installed includes, then any we find in - %% ../include and ../src/gen. + %% Create a new diameter/include in priv_dir. Copy all includes + %% there, from below ../include and ../src/gen if they exist (in + %% the repo). Tmp = filename:join([PrivDir, "diameter"]), TmpInc = filename:join([PrivDir, "diameter", "include"]), TmpEbin = filename:join([PrivDir, "diameter", "ebin"]), @@ -181,8 +214,8 @@ install(Dir, PrivDir) -> Inc = filename:join([Top, "include"]), Gen = filename:join([Top, "src", "gen"]), - Files = lists:append([find_files(F, ".*\\.hrl") || F <- [Inc, Gen]]), - [] = [{F,E} || F <- Files, + Files = find_files([Inc, Gen], ".*\\.hrl"), + [] = [{F,E} || {_,F} <- Files, B <- [filename:basename(F)], D <- [filename:join([TmpInc, B])], {error, E} <- [file:copy(F,D)]], @@ -194,11 +227,16 @@ install(Dir, PrivDir) -> %% Return the top directory containing examples/code. Top. -find_files(Dir, RE) -> - filelib:fold_files(Dir, RE, false, fun cons/2, []). +find_files(Dirs, RE) -> + lists:foldl(fun(D,A) -> fold_files(D, RE, A) end, + orddict:new(), + Dirs). + +fold_files(Dir, RE, Acc) -> + filelib:fold_files(Dir, RE, false, fun store/2, Acc). -cons(H,T) -> - [H|T]. +store(Path, Dict) -> + orddict:store(filename:basename(Path), Path, Dict). %% =========================================================================== -- cgit v1.2.3 From e00e939a07e811fcf8cf1daff491dc761805c611 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 24 Mar 2013 15:03:27 +0100 Subject: Compile example dictionaries against both RFC 3588 and 6733 --- lib/diameter/test/diameter_examples_SUITE.erl | 58 ++++++++++++++++----------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl index 3ef901f4bd..6d797f6911 100644 --- a/lib/diameter/test/diameter_examples_SUITE.erl +++ b/lib/diameter/test/diameter_examples_SUITE.erl @@ -59,6 +59,9 @@ {rfc4072_eap, [rfc4005_nas]}, {rfc4740_sip, [rfc4590_digest]}]). +%% Common dictionaries to inherit from examples. +-define(DICT0, [rfc3588_base, rfc6733_base]). + %% =========================================================================== suite() -> @@ -83,9 +86,10 @@ dict() -> dict(_Config) -> Dirs = [filename:join(H ++ ["examples", "dict"]) || H <- [[code:lib_dir(diameter)], [here(), ".."]]], - [] = [RC || {_,F} <- sort(find_files(Dirs, ".*\\.dia")), - RC <- [make(F)], - RC /= ok]. + [] = [{F,D,RC} || {_,F} <- sort(find_files(Dirs, ".*\\.dia")), + D <- ?DICT0, + RC <- [make(F,D)], + RC /= ok]. sort([{_,_} | _] = Files) -> lists:sort(fun({A,_},{B,_}) -> @@ -106,31 +110,37 @@ sort([A,B] = L) -> %% Recursively accumulate inherited dictionaries. dep([D|Rest], Acc) -> - dep(opts(D), Rest, Acc); + dep(dep(D), Rest, Acc); dep([], Acc) -> Acc. -dep([{inherits, Map} | T], Rest, Acc) -> - [Dict, _] = filename:split(Map), +dep([{Dict, _} | T], Rest, Acc) -> dep(T, [Dict | Rest], [Dict | Acc]); dep([], Rest, Acc) -> dep(Rest, Acc). -make(Path) -> +make(Path, Dict0) + when is_atom(Dict0) -> + make(Path, atom_to_list(Dict0)); + +make(Path, Dict0) -> Dict = filename:rootname(filename:basename(Path)), - {Name, Pre} = make_name(Dict), + {Mod, Pre} = make_name(Dict), + {"diameter_gen_base" ++ Suf = Mod0, _} = make_name(Dict0), + Name = Mod ++ Suf, try - ok = make(Path, [{name, Name}, - {prefix, Pre}, - inherits(rfc3588_base) - | opts(Dict)]), - ok = compile(Name) + ok = to_erl(Path, [{name, Name}, + {prefix, Pre}, + {inherits, "rfc3588_base/" ++ Mod0} + | [{inherits, D ++ "/" ++ M ++ Suf} + || {D,M} <- dep(Dict)]]), + ok = to_beam(Name) catch throw: {_,_} = E -> E end. -make(File, Opts) -> +to_erl(File, Opts) -> case diameter_make:codec(File, Opts) of ok -> ok; @@ -138,7 +148,7 @@ make(File, Opts) -> throw({make, No}) end. -compile(Name) -> +to_beam(Name) -> case compile:file(Name ++ ".erl", [return]) of {ok, _, _} -> ok; @@ -146,7 +156,7 @@ compile(Name) -> throw({compile, No}) end. -opts(Dict) -> +dep(Dict) -> case lists:keyfind(list_to_atom(Dict), 1, ?INHERITS) of {_, Is} -> lists:map(fun inherits/1, Is); @@ -154,16 +164,16 @@ opts(Dict) -> [] end. -inherits(File) - when is_atom(File) -> - inherits(atom_to_list(File)); +inherits(Dict) + when is_atom(Dict) -> + inherits(atom_to_list(Dict)); -inherits(File) -> - {Name, _} = make_name(File), - {inherits, File ++ "/" ++ Name}. +inherits(Dict) -> + {Name, _} = make_name(Dict), + {Dict, Name}. -make_name(File) -> - {R, [$_|N]} = lists:splitwith(fun(C) -> C /= $_ end, File), +make_name(Dict) -> + {R, [$_|N]} = lists:splitwith(fun(C) -> C /= $_ end, Dict), {string:join(["diameter_gen", N, R], "_"), "diameter_" ++ N}. %% =========================================================================== -- cgit v1.2.3