Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
3257-Rework-remaining-diameter-testsuites.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3257-Rework-remaining-diameter-testsuites.patch of Package erlang
From d42d0fe0a89d115caa596c229c1c758c4859ee44 Mon Sep 17 00:00:00 2001 From: Anders Svensson <anders@erlang.org> Date: Fri, 25 Feb 2022 11:15:51 +0100 Subject: [PATCH 7/7] Rework remaining diameter testsuites As in the previous two commit: remove common_test as a requirement and make all testcases independent. Add a make target for running any suite without common test; for example, to run all testcases in diameter_dpr_SUITE: make _dpr Similar to the target that runs suites with common_test, just add an underscore prefix. --- lib/diameter/test/Makefile | 12 +- lib/diameter/test/diameter_3xxx_SUITE.erl | 152 +++++-------- lib/diameter/test/diameter_app_SUITE.erl | 104 +++++---- lib/diameter/test/diameter_capx_SUITE.erl | 206 +++++++----------- lib/diameter/test/diameter_codec_SUITE.erl | 140 +++++++----- lib/diameter/test/diameter_compiler_SUITE.erl | 104 +++++---- lib/diameter/test/diameter_config_SUITE.erl | 74 ++++--- lib/diameter/test/diameter_ct.hrl | 22 -- lib/diameter/test/diameter_dpr_SUITE.erl | 125 ++++++----- lib/diameter/test/diameter_event_SUITE.erl | 78 ++++--- lib/diameter/test/diameter_failover_SUITE.erl | 102 +++++---- lib/diameter/test/diameter_gen_sctp_SUITE.erl | 37 ++-- lib/diameter/test/diameter_gen_tcp_SUITE.erl | 37 +++- lib/diameter/test/diameter_length_SUITE.erl | 84 +++---- lib/diameter/test/diameter_pool_SUITE.erl | 97 +++++---- lib/diameter/test/diameter_reg_SUITE.erl | 82 +++---- lib/diameter/test/diameter_relay_SUITE.erl | 161 +++++++------- lib/diameter/test/diameter_stats_SUITE.erl | 71 +++--- lib/diameter/test/diameter_sync_SUITE.erl | 81 +++---- lib/diameter/test/diameter_util.erl | 47 ---- lib/diameter/test/diameter_watchdog_SUITE.erl | 129 ++++++----- lib/diameter/test/modules.mk | 3 - 22 files changed, 943 insertions(+), 1005 deletions(-) delete mode 100644 lib/diameter/test/diameter_ct.hrl diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile index b537292834..3ae0f8eaf8 100644 --- a/lib/diameter/test/Makefile +++ b/lib/diameter/test/Makefile @@ -91,8 +91,6 @@ info: @echo ======================================== @$(call list,MODULES) @echo - @$(call list,HRL_FILES) - @echo @$(call list,SUITES) @echo @echo erl = $(shell which erl) @@ -116,6 +114,7 @@ help: @echo @echo " $(SUITES):" @echo " Compile and run a specific test suite." + @echo " Prefix with _ to run without common_test." @echo @echo " clean | realclean:" @echo " Remove generated files." @@ -142,6 +141,14 @@ $(SUITES): log opt | awk '{print} / FAILED /{rc=1} END{exit rc}' rc=0 # Shorter in sed but requires a GNU extension (ie. Q). +# Run suites without common_test. +$(SUITES:%=_%): opt + $(ERL) -noinput \ + -pa ../ebin \ + -sname diameter_test_$@ \ + -s diameter$@_SUITE run \ + -s init stop + cover: log opt coverspec $(ERL) -noinput \ -pa $(realpath ../ebin) \ @@ -173,7 +180,6 @@ release_tests_spec: $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(TEST_SPEC_FILE) \ $(COVER_SPEC_FILE) \ - $(HRL_FILES) \ "$(RELSYSDIR)" $(MAKE) $(DATA_DIRS:%/=release_data_%) $(MAKE) $(ERL_FILES:%=/%) diff --git a/lib/diameter/test/diameter_3xxx_SUITE.erl b/lib/diameter/test/diameter_3xxx_SUITE.erl index 0f060c4ba7..63de2467a3 100644 --- a/lib/diameter/test/diameter_3xxx_SUITE.erl +++ b/lib/diameter/test/diameter_3xxx_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,19 +26,17 @@ -module(diameter_3xxx_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1, - init_per_group/2, - end_per_group/2, - init_per_testcase/2, - end_per_testcase/2]). - -%% testcases --export([start/1, - send_unknown_application/1, + traffic/1]). + +%% internal +-export([send_unknown_application/1, send_unknown_command/1, send_ok/1, send_invalid_hdr_bits/1, @@ -47,9 +45,7 @@ send_5xxx_missing_avp/1, send_double_error/1, send_3xxx/1, - send_5xxx/1, - counters/1, - stop/1]). + send_5xxx/1]). %% diameter callbacks -export([peer_up/3, @@ -67,11 +63,7 @@ %% =========================================================================== -define(util, diameter_util). --define(testcase(), proplists:get_value(testcase, get(?MODULE))). --define(group(Config), begin - put(?MODULE, Config), - ?util:name(proplists:get_value(group, Config)) - end). +-define(testcase(), get(?MODULE)). -define(L, atom_to_list). -define(A, list_to_atom). @@ -106,34 +98,15 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 90}}]. all() -> - [{group, ?util:name([E,D])} || E <- ?ERRORS, D <- ?RFCS]. - -groups() -> - Tc = tc(), - [{?util:name([E,D]), [], [start] ++ Tc ++ [counters, stop]} - || E <- ?ERRORS, D <- ?RFCS]. - -init_per_suite(Config) -> - ok = diameter:start(), - Config. + [traffic]. -end_per_suite(_Config) -> - ok = diameter:stop(). +traffic(_Config) -> + run(). -init_per_group(Group, Config) -> - [{group, Group} | Config]. - -end_per_group(_, _) -> - ok. - -init_per_testcase(Name, Config) -> - [{testcase, Name} | Config]. - -end_per_testcase(_, _) -> - ok. +%% =========================================================================== tc() -> [send_unknown_application, @@ -147,25 +120,36 @@ tc() -> send_3xxx, send_5xxx]. -%% =========================================================================== +%% run/0 + +run() -> + ?util:run([[{{?MODULE, run, [{E,D}]}, 60000} || E <- ?ERRORS, + D <- ?RFCS]]). + +%% run/1 -%% start/1 +run({F, [_,_] = G}) -> + put(?MODULE, F), + apply(?MODULE, F, [G]); -start(Config) -> - Group = proplists:get_value(group, Config), - [Errors, RFC] = ?util:name(Group), - ok = diameter:start_service(?SERVER, ?SERVICE(?L(Group), - Errors, - RFC)), +run({E,D}) -> + try + run([E,D]) + after + ok = diameter:stop() + end; + +run([Errors, RFC] = G) -> + Name = ?L(Errors) ++ "," ++ ?L(RFC), + ok = diameter:start(), + ok = diameter:start_service(?SERVER, ?SERVICE(Name, Errors, RFC)), ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT, callback, rfc6733)), LRef = ?util:listen(?SERVER, tcp), - ?util:connect(?CLIENT, tcp, LRef). - -%% stop/1 - -stop(_Config) -> + ?util:connect(?CLIENT, tcp, LRef), + ?util:run([{?MODULE, run, [{F,G}]} || F <- tc()]), + _ = counters(G), ok = diameter:remove_transport(?CLIENT, true), ok = diameter:remove_transport(?SERVER, true), ok = diameter:stop_service(?SERVER), @@ -175,9 +159,7 @@ stop(_Config) -> %% %% Check that counters are as expected. -counters(Config) -> - Group = proplists:get_value(group, Config), - [_Errors, _Rfc] = G = ?util:name(Group), +counters([_Errors, _RFC] = G) -> [] = ?util:run([[fun counters/3, K, S, G] || K <- [statistics, transport, connections], S <- [?CLIENT, ?SERVER]]). @@ -379,10 +361,7 @@ send_unknown_application([_,_]) -> %% UNSUPPORTED_APPLICATION 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_unknown_application(Config) -> - send_unknown_application(?group(Config)). + = call(). %% send_unknown_command/1 %% @@ -398,10 +377,7 @@ send_unknown_command([_,_]) -> %% UNSUPPORTED_COMMAND 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_unknown_command(Config) -> - send_unknown_command(?group(Config)). + = call(). %% send_ok/1 %% @@ -412,10 +388,7 @@ send_ok([_,_]) -> #diameter_base_STA{'Result-Code' = 5002, %% UNKNOWN_SESSION_ID 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_ok(Config) -> - send_ok(?group(Config)). + = call(). %% send_invalid_hdr_bits/1 %% @@ -433,10 +406,7 @@ send_invalid_hdr_bits([_,_]) -> #'diameter_base_answer-message'{'Result-Code' = 3008, %% INVALID_HDR_BITS 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_invalid_hdr_bits(Config) -> - send_invalid_hdr_bits(?group(Config)). + = call(). %% send_missing_avp/1 %% @@ -454,10 +424,7 @@ send_missing_avp([_,_]) -> #diameter_base_STA{'Result-Code' = 5005, %% MISSING_AVP 'Failed-AVP' = [_], 'AVP' = []} - = call(); - -send_missing_avp(Config) -> - send_missing_avp(?group(Config)). + = call(). %% send_ignore_missing_avp/1 %% @@ -475,10 +442,7 @@ send_ignore_missing_avp([_,_]) -> #diameter_base_STA{'Result-Code' = 2001, %% SUCCESS 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_ignore_missing_avp(Config) -> - send_ignore_missing_avp(?group(Config)). + = call(). %% send_5xxx_missing_avp/1 %% @@ -501,10 +465,7 @@ send_5xxx_missing_avp([_,_]) -> #diameter_base_STA{'Result-Code' = 2001, %% SUCCESS 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_5xxx_missing_avp(Config) -> - send_5xxx_missing_avp(?group(Config)). + = call(). %% send_double_error/1 %% @@ -522,10 +483,7 @@ send_double_error([_,_]) -> #'diameter_base_answer-message'{'Result-Code' = 3008, %% INVALID_HDR_BITS 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_double_error(Config) -> - send_double_error(?group(Config)). + = call(). %% send_3xxx/1 %% @@ -536,10 +494,7 @@ send_3xxx([_,_]) -> #'diameter_base_answer-message'{'Result-Code' = 3999, 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_3xxx(Config) -> - send_3xxx(?group(Config)). + = call(). %% send_5xxx/1 %% @@ -555,10 +510,7 @@ send_5xxx([_,_]) -> #'diameter_base_answer-message'{'Result-Code' = 5999, 'Failed-AVP' = [], 'AVP' = []} - = call(); - -send_5xxx(Config) -> - send_5xxx(?group(Config)). + = call(). %% =========================================================================== diff --git a/lib/diameter/test/diameter_app_SUITE.erl b/lib/diameter/test/diameter_app_SUITE.erl index ef4a28d3f4..0211ab1982 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-2018. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,22 +24,24 @@ -module(diameter_app_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, - all/0, - init_per_suite/1, - end_per_suite/1]). + all/0]). %% testcases -export([keys/1, vsn/1, - modules/1, - exports/1, + modules/1, + exports/1, release/1, - xref/1, + xref/1, relup/1]). --include("diameter_ct.hrl"). - +-define(util, diameter_util). -define(A, list_to_atom). %% Modules not in the app and that should not have dependencies on it @@ -57,7 +59,7 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 20}}]. all() -> [keys, @@ -68,12 +70,22 @@ all() -> xref, relup]. -init_per_suite(Config) -> - [{application, ?APP, App}] = diameter_util:consult(?APP, app), - [{app, App} | Config]. +%% =========================================================================== + +run() -> + run(all()). + +run(List) -> + Tmp = ?util:mktemp(filename:join(?util:tmpdir(), "diameter_app")), + try + run([{priv_dir, Tmp}], List) + after + file:del_dir_r(Tmp) + end. -end_per_suite(_Config) -> - ok. +run(Config, List) -> + [{application, diameter, App}] = ?util:consult(diameter, app), + ?util:run([{{?MODULE, F, [{App, Config}]}, 10000} || F <- List]). %% =========================================================================== %% # keys/1 @@ -82,10 +94,12 @@ end_per_suite(_Config) -> %% also be caught by other testcases. %% =========================================================================== -keys(Config) -> - App = fetch(app, Config), +keys({App, _Config}) -> [] = lists:filter(fun(K) -> not lists:keymember(K, 1, App) end, - [vsn, description, modules, registered, applications]). + [vsn, description, modules, registered, applications]); + +keys(Config) -> + run(Config, [keys]). %% =========================================================================== %% # vsn/1 @@ -93,8 +107,11 @@ keys(Config) -> %% Ensure that our app version sticks to convention. %% =========================================================================== +vsn({App, _Config}) -> + true = is_vsn(fetch(vsn, App)); + vsn(Config) -> - true = is_vsn(fetch(vsn, fetch(app, Config))). + run(Config, [vsn]). %% =========================================================================== %% # modules/1 @@ -103,15 +120,17 @@ vsn(Config) -> %% compiler/info modules. %% =========================================================================== -modules(Config) -> - Mods = fetch(modules, fetch(app, Config)), +modules({App, _Config}) -> + Mods = fetch(modules, App), Installed = code_mods(), Help = lists:sort(?INFO_MODULES ++ ?COMPILER_MODULES), + {[], Help} = {Mods -- Installed, lists:sort(Installed -- Mods)}; - {[], Help} = {Mods -- Installed, lists:sort(Installed -- Mods)}. +modules(Config) -> + run(Config, [modules]). code_mods() -> - Dir = code:lib_dir(?APP, ebin), + Dir = code:lib_dir(diameter, ebin), {ok, Files} = file:list_dir(Dir), [?A(lists:reverse(R)) || N <- Files, "maeb." ++ R <- [lists:reverse(N)]]. @@ -121,9 +140,12 @@ code_mods() -> %% Ensure that no module does export_all. %% =========================================================================== +exports({App, _Config}) -> + Mods = fetch(modules, App), + [] = [M || M <- Mods, exports_all(M)]; + exports(Config) -> - Mods = fetch(modules, fetch(app, Config)), - [] = [M || M <- Mods, exports_all(M)]. + run(Config, [exports]). exports_all(Mod) -> Opts = fetch(options, Mod:module_info(compile)), @@ -136,8 +158,7 @@ exports_all(Mod) -> %% Ensure that it's possible to build a minimal release with our app file. %% =========================================================================== -release(Config) -> - App = fetch(app, Config), +release({App, Config}) -> Rel = {release, {"diameter test release", fetch(vsn, App)}, {erts, erlang:system_info(version)}, @@ -146,13 +167,16 @@ release(Config) -> ok = write_file(filename:join([Dir, "diameter_test.rel"]), Rel), {ok, _, []} = systools:make_script("diameter_test", [{path, [Dir]}, {outdir, Dir}, - silent]). + silent]); + +release(Config) -> + run(Config, [release]). %% sasl need to be included to avoid a missing_sasl warning, error %% in the case of relup/1. appvsn(Name) -> - [{application, Name, App}] = diameter_util:consult(Name, app), + [{application, Name, App}] = ?util:consult(Name, app), fetch(vsn, App). %% =========================================================================== @@ -162,8 +186,7 @@ appvsn(Name) -> %% or one in an application we haven't declared as a dependency. (Almost.) %% =========================================================================== -xref(Config) -> - App = fetch(app, Config), +xref({App, _Config}) -> Mods = fetch(modules, App), %% modules listed in the app file %% List of application names extracted from runtime_dependencies. @@ -179,7 +202,7 @@ xref(Config) -> %% the sense that there's no .app file, and isn't listed in %% applications. ok = lists:foreach(fun(A) -> add_application(XRef, A) end, - [?APP, erts | fetch(applications, App)]), + [diameter, erts | fetch(applications, App)]), {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), {ok, RTmods} = xref:analyze(XRef, {module_use, Mods}), @@ -212,7 +235,10 @@ xref(Config) -> %% The declared application versions are ignored since we only %% know what we see now. [] = lists:filter(fun(M) -> not lists:member(app(M), Deps) end, - RTdeps -- Mods). + RTdeps -- Mods); + +xref(Config) -> + run(Config, [xref]). ignored({FromMod,_,_}, {ToMod,_,_} = To, Rel)-> %% diameter_tcp does call ssl despite the latter not being listed @@ -281,7 +307,7 @@ add_application(XRef, App, Dir) {ok, App} = xref:add_application(XRef, Dir, []). make_name(Suf) -> - list_to_atom(atom_to_list(?APP) ++ "_" ++ atom_to_list(Suf)). + list_to_atom("diameter_" ++ atom_to_list(Suf)). %% =========================================================================== %% # relup/1 @@ -289,11 +315,10 @@ make_name(Suf) -> %% Ensure that we can generate release upgrade files using our appup file. %% =========================================================================== -relup(Config) -> - [{Vsn, Up, Down}] = diameter_util:consult(?APP, appup), +relup({App, Config}) -> + [{Vsn, Up, Down}] = ?util:consult(diameter, appup), true = is_vsn(Vsn), - App = fetch(app, Config), Rel = [{erts, erlang:system_info(version)} | [{A, appvsn(A)} || A <- [sasl | fetch(applications, App)]]], @@ -314,7 +339,10 @@ relup(Config) -> {ok, _, _, []} = systools:make_relup(Name, UpFrom, DownTo, [{path, [Dir]}, {outdir, Dir}, - silent]). + silent]); + +relup(Config) -> + run(Config, [relup]). acc_rel(Dir, Rel, List) -> lists:foldl(fun(T,A) -> acc_rel(Dir, Rel, T, A) end, diff --git a/lib/diameter/test/diameter_capx_SUITE.erl b/lib/diameter/test/diameter_capx_SUITE.erl index 51b6c1d7f2..852450bc9f 100644 --- a/lib/diameter/test/diameter_capx_SUITE.erl +++ b/lib/diameter/test/diameter_capx_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,39 +25,30 @@ -module(diameter_capx_SUITE). +%% testcases, no common_test dependency +-export([run/0]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1, - init_per_group/2, - end_per_group/2, - init_per_testcase/2, - end_per_testcase/2]). - -%% testcases --export([start/1, - vendor_id/1, - start_services/1, - add_listeners/1, - s_no_common_application/1, - c_no_common_application/1, - s_no_common_security/1, - c_no_common_security/1, - s_unknown_peer/1, - c_unknown_peer/1, - s_unable/1, - c_unable/1, - s_client_reject/1, - c_client_reject/1, - remove_listeners/1, - stop_services/1, - stop/1]). + traffic/1]). %% diameter callbacks -export([peer_up/4, peer_down/4]). +%% internal +-export([s_no_common_application/1, + s_no_common_security/1, + s_unknown_peer/1, + s_unable/1, + s_client_reject/1, + c_no_common_application/1, + c_no_common_security/1, + c_unknown_peer/1, + c_unable/1, + c_client_reject/1]). + -include("diameter.hrl"). -include("diameter_gen_base_rfc3588.hrl"). %% Use only the Vendor-Specific-Application-Id record from the base @@ -108,7 +99,7 @@ -define(caps, #diameter_caps). -define(packet, #diameter_packet). --define(fail(T), erlang:error({T, process_info(self(), messages)})). +-define(fail(T), error({T, process_info(self(), messages)})). -define(TIMEOUT, 10000). @@ -117,56 +108,15 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. - -all() -> [start, - vendor_id, - start_services, - add_listeners] - ++ [{group, D, P} || D <- ?DICTS, P <- [[], [parallel]]] - ++ [remove_listeners, - stop_services, - stop]. - -groups() -> - Tc = lists:flatmap(fun tc/1, tc()), - [{D, [], Tc} || D <- ?DICTS]. - -init_per_suite(Config) -> - lists:foreach(fun load_dict/1, ?NOAPPS), - Config. + [{timetrap, {seconds, 20}}]. -end_per_suite(_Config) -> - [] = [Mod || N <- ?NOAPPS, - Mod <- [dict(N)], - false <- [code:delete(Mod)]], - ok. - -%% Generate a unique hostname for each testcase so that watchdogs -%% don't prevent a connection from being brought up immediately. -init_per_testcase(Name, Config) -> - [{host, ?L(Name) ++ "." ++ diameter_util:unique_string()} - | Config]. - -init_per_group(Name, Config) -> - [{rfc, Name} | Config]. +all() -> + [traffic]. -end_per_group(_, _) -> - ok. +traffic(_Config) -> + run(). -end_per_testcase(N, _) - when N == start; - N == vendor_id; - N == start_services; - N == add_listeners; - N == remove_listeners; - N == stop_services; - N == stop -> - ok; - -end_per_testcase(Name, Config) -> - CRef = ?util:read_priv(Config, Name), - ok = diameter:remove_transport(?CLIENT, CRef). +%% =========================================================================== %% Testcases all come in two flavours, client and server. tc(Name) -> @@ -179,17 +129,46 @@ tc() -> unable, client_reject]. -%% =========================================================================== -%% start/stop testcases +run() -> + try + ?util:run([{fun traffic/0, 15000}]) + after + ok = diameter:stop(), + [] = [M || N <- ?NOAPPS, + M <- [dict(N)], + B <- [code:delete(M)], + _ <- [code:purge(M)], + not B] + end. + +traffic() -> + lists:foreach(fun load_dict/1, ?NOAPPS), + ok = diameter:start(), + _ = vendor_id(), + ok = diameter:start_service(?SERVER, ?SERVICE), + ok = diameter:start_service(?CLIENT, ?SERVICE), + LRefs = add_listeners(), + ?util:run([[fun traffic/3, F, D, LRefs] || D <- ?DICTS, + N <- tc(), + F <- tc(N)]), + ok = diameter:remove_transport(?SERVER, true), + ok = diameter:stop_service(?CLIENT), + ok = diameter:stop_service(?SERVER). -start(_Config) -> - ok = diameter:start(). +%% Generate a unique hostname for each testcase so that watchdogs +%% don't prevent a connection from being brought up immediately. +traffic(F, Dict, {_Base, _Acct} = LRefs) -> + apply(?MODULE, + F, + [[{lref, LRefs}, + {rfc, Dict}, + {host, ?L(F) ++ "." ++ ?util:unique_string()}]]). %% Ensure that both integer and list-valued vendor id's can be %% configured in a Vendor-Specific-Application-Id, the arity having %% changed between RFC 3588 and RFC 6733. -vendor_id(_Config) -> - [] = ?util:run([[fun vid/1, V] || V <- [1, [1], [1,2], x]]). +vendor_id() -> + ?util:run([[fun vid/1, V] || V <- [1, [1], [1,2], x]]). vid(V) -> RC = diameter:start_service(make_ref(), @@ -203,14 +182,10 @@ vid(x, {error, _}) -> vid(_, ok) -> ok. -start_services(_Config) -> - ok = diameter:start_service(?SERVER, ?SERVICE), - ok = diameter:start_service(?CLIENT, ?SERVICE). - %% One server that responds only to base accounting, one that responds %% to both this and the common application. Share a common service just %% to simplify config, and because we can. -add_listeners(Config) -> +add_listeners() -> Acct = [listen(?SERVER, [{capabilities, [{'Origin-Host', ?HOST(H)}, {'Auth-Application-Id', []}]}, @@ -224,17 +199,7 @@ add_listeners(Config) -> {capabilities_cb, [fun server_capx/3, base]}]) || {A,H} <- [{[base3588, acct3588], "base3588-srv"}, {[base6733, acct6733], "base6733-srv"}]], - ?util:write_priv(Config, ?MODULE, {Base, Acct}). %% lref/2 reads - -remove_listeners(_Config) -> - ok = diameter:remove_transport(?SERVER, true). - -stop_services(_Config) -> - ok = diameter:stop_service(?CLIENT), - ok = diameter:stop_service(?SERVER). - -stop(_Config) -> - ok = diameter:stop(). + {Base, Acct}. %% =========================================================================== %% All the testcases come in pairs, one for receiving an event on the @@ -338,13 +303,10 @@ s_client_reject(Config) -> receive ?event{service = ?SERVER, info = {up, LRef, - {_, ?caps{origin_host = {_, OH}}}, - {listen, _}, - ?packet{}}} - = Info -> - Info - after ?TIMEOUT -> - ?fail({LRef, OH}) + {_, ?caps{origin_host = {_, OH}}}, + {listen, _}, + ?packet{}}} -> + ok end. c_client_reject(Config) -> @@ -404,12 +366,9 @@ server_closed(Config, F, RC) -> info = {closed, LRef, {'CER', RC, ?caps{origin_host = {_, OH}}, - ?packet{}} - = Reason, + ?packet{}}, {listen, _}}} -> - Reason - after ?TIMEOUT -> - ?fail({LRef, OH}) + ok end. %% server_reject/3 @@ -425,12 +384,9 @@ server_reject(Config, F, RC) -> info = {closed, LRef, {'CER', {capabilities_cb, _, RC}, ?caps{origin_host = {_, OH}}, - ?packet{}} - = Reason, + ?packet{}}, {listen, _}}} -> - Reason - after ?TIMEOUT -> - ?fail({LRef, OH}) + ok end. %% client_closed/4 @@ -459,8 +415,6 @@ client_recv(CRef) -> ?event{service = ?CLIENT, info = {closed, CRef, Reason, {connect, _}}} -> Reason - after ?TIMEOUT -> - ?fail(CRef) end. %% server_capx/3 @@ -504,20 +458,14 @@ listen(Name, Opts) -> connect(Config, T, Opts) -> {_, H} = lists:keyfind(host, 1, Config), LRef = lref(Config, T), - CRef = connect(LRef, [{capabilities, [{'Origin-Host', ?HOST(H)}]} - | Opts]), - Name = lists:takewhile(fun(C) -> C /= $. end, H), - ?util:write_priv(Config, Name, CRef), %% end_per_testcase reads - {CRef, LRef}. - -connect(LRef, Opts) -> [PortNr] = ?util:lport(tcp, LRef), - {ok, CRef} = diameter:add_transport(?CLIENT, - {connect, opts(PortNr, Opts)}), - CRef. + {ok, CRef} + = diameter:add_transport(?CLIENT, {connect, opts(H, PortNr, Opts)}), + {CRef, LRef}. -opts(PortNr, Opts) -> - [{transport_module, diameter_tcp}, +opts(Host, PortNr, Opts) -> + [{capabilities, [{'Origin-Host', ?HOST(Host)}]}, + {transport_module, diameter_tcp}, {transport_config, [{raddr, ?ADDR}, {rport, PortNr}, {ip, ?ADDR}, @@ -531,7 +479,7 @@ lref(rfc6733, [_, LRef]) -> lref(Config, T) -> lref(proplists:get_value(rfc, Config), - case ?util:read_priv(Config, ?MODULE) of + case proplists:get_value(lref, Config) of {R, _} when T == base -> R; {_, R} when T == acct -> diff --git a/lib/diameter/test/diameter_codec_SUITE.erl b/lib/diameter/test/diameter_codec_SUITE.erl index 17112794e4..ff8a031460 100644 --- a/lib/diameter/test/diameter_codec_SUITE.erl +++ b/lib/diameter/test/diameter_codec_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -28,86 +28,110 @@ -module(diameter_codec_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1, - init_per_group/2, - end_per_group/2, - init_per_testcase/2, - end_per_testcase/2]). - -%% testcases --export([base/1, + base/1, gen/1, lib/1, unknown/1, - success/1, - grouped_error/1, - failed_error/1]). + recode/1]). --include("diameter_ct.hrl"). -include("diameter.hrl"). +-define(util, diameter_util). -define(L, atom_to_list). %% =========================================================================== suite() -> - [{timetrap, {seconds, 10}}]. + [{timetrap, {seconds, 15}}]. all() -> - [base, gen, lib, unknown, {group, recode}]. + [base, gen, lib, unknown, recode]. -groups() -> - [{recode, [], [success, - grouped_error, - failed_error]}]. +base(_Config) -> + run(base). -init_per_suite(Config) -> - Config. +gen(_Config) -> + run(gen). -end_per_suite(_Config) -> - ok. +lib(_Config) -> + run(lib). -init_per_group(recode, Config) -> - ok = diameter:start(), - Config. +unknown(Config) -> + Priv = proplists:get_value(priv_dir, Config), + Data = proplists:get_value(data_dir, Config), + unknown(Priv, Data). + +recode(_Config) -> + run(recode). + +%% =========================================================================== + +%% run/0 + +run() -> + run(all()). + +%% run/1 -end_per_group(_, _) -> - ok = diameter:stop(). +run(base) -> + diameter_codec_test:base(); -init_per_testcase(gen, Config) -> - [{application, ?APP, App}] = diameter_util:consult(?APP, app), +run(gen) -> + [{application, diameter, App}] = diameter_util:consult(diameter, app), {modules, Ms} = lists:keyfind(modules, 1, App), [_|_] = Gs = lists:filter(fun(M) -> lists:prefix("diameter_gen_", ?L(M)) end, Ms), - [{dicts, Gs} | Config]; + lists:foreach(fun diameter_codec_test:gen/1, Gs); -init_per_testcase(_Name, Config) -> - Config. +run(lib) -> + diameter_codec_test:lib(); -end_per_testcase(_, _) -> - ok. - -%% =========================================================================== - -base(_Config) -> - diameter_codec_test:base(). +%% Have a separate AVP dictionary just to exercise more code. +run(unknown) -> + PD = ?util:mktemp(filename:join(?util:tmpdir(), "diameter_codec")), + DD = filename:join([code:lib_dir(diameter), + "test", + "diameter_codec_SUITE_data"]), + try + unknown(PD, DD) + after + file:del_dir_r(PD) + end; + +run(success) -> + success(); + +run(grouped_error) -> + grouped_error(); + +run(failed_error) -> + failed_error(); + +run(recode) -> + ok = diameter:start(), + try + ?util:run([{?MODULE, run, [F]} || F <- [success, + grouped_error, + failed_error]]) + after + ok = diameter:stop() + end; -gen([{dicts, Ms} | _]) -> - lists:foreach(fun diameter_codec_test:gen/1, Ms). +run(List) -> + ?util:run([{{?MODULE, run, [F]}, 10000} || F <- List]). -lib(_Config) -> - diameter_codec_test:lib(). +%% =========================================================================== -%% Have a separate AVP dictionary just to exercise more code. -unknown(Config) -> - Priv = proplists:get_value(priv_dir, Config), - Data = proplists:get_value(data_dir, Config), +unknown(Priv, Data) -> ok = make(Data, "recv.dia"), ok = make(Data, "avps.dia"), {ok, _, _} = compile("diameter_test_avps.erl"), @@ -130,7 +154,7 @@ compile(File, Opts) -> %% =========================================================================== %% Ensure a Grouped AVP is represented by a list in the avps field. -success(_) -> +success() -> Avps = [{295, <<1:32>>}, %% Termination-Cause {284, [{280, "Proxy-Host"}, %% Proxy-Info {33, "Proxy-State"}, %% @@ -145,13 +169,13 @@ success(_) -> value = 2, data = <<2:32>>}]], errors = []} - = str(recode(str(Avps))). + = str(repkg(str(Avps))). %% =========================================================================== %% Ensure a Grouped AVP is represented by a list in the avps field %% even in the case of a decode error on a component AVP. -grouped_error(_) -> +grouped_error() -> Avps = [{295, <<1:32>>}, %% Termination-Cause {284, [{295, <<0:32>>}, %% Proxy-Info, Termination-Cause {280, "Proxy-Host"}, @@ -166,13 +190,13 @@ grouped_error(_) -> #diameter_avp{code = 280}, #diameter_avp{code = 33}]], errors = [{5004, #diameter_avp{code = 284}}]} - = str(recode(str(Avps))). + = str(repkg(str(Avps))). %% =========================================================================== %% Ensure that a failed decode in Failed-AVP is acceptable, and that %% the component AVPs are decoded if possible. -failed_error(_) -> +failed_error() -> Avps = [{279, [{295, <<0:32>>}, %% Failed-AVP, Termination-Cause {258, <<1:32>>}, %% Auth-Application-Id {284, [{280, "Proxy-Host"}, %% Proxy-Info @@ -195,7 +219,7 @@ failed_error(_) -> value = 2, data = <<2:32>>}]]], errors = []} - = sta(recode(sta(Avps))). + = sta(repkg(sta(Avps))). %% =========================================================================== @@ -279,9 +303,9 @@ avp([{_,_} | _] = Avps) -> avp(V) -> V. -%% recode/1 +%% repkg/1 -recode(Msg) -> +repkg(Msg) -> recode(Msg, diameter_gen_base_rfc6733). recode(#diameter_packet{} = Pkt, Dict) -> diff --git a/lib/diameter/test/diameter_compiler_SUITE.erl b/lib/diameter/test/diameter_compiler_SUITE.erl index 73fe1ef6e0..a33da0f64e 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-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,16 +24,17 @@ -module(diameter_compiler_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - init_per_suite/1, - end_per_suite/1]). - -%% testcases --export([format/1, format/2, - replace/1, replace/2, - generate/1, generate/4, - flatten1/1, flatten1/3, + format/1, + replace/1, + generate/1, + flatten1/1, flatten2/1]). -export([dict/0]). %% fake dictionary module @@ -364,7 +365,7 @@ %% =========================================================================== suite() -> - [{timetrap, {minutes, 10}}]. + [{timetrap, {seconds, 45}}]. all() -> [format, @@ -373,33 +374,37 @@ all() -> flatten1, flatten2]. -%% Error handling testcases will make an erroneous dictionary out of -%% the base dictionary and check that the expected error results. -%% ?REPLACE encodes the modifications and expected error. -init_per_suite(Config) -> +%% =========================================================================== + +%% run/0 + +run() -> + run(all()). + +%% run/1 + +run(List) -> Path = filename:join([code:lib_dir(diameter, src), "dict", ?base]), {ok, Bin} = file:read_file(Path), - [{base, Bin} | Config]. - -end_per_suite(_Config) -> - ok. + ?util:run([{{?MODULE, F, [Bin]}, 30000} || F <- List]). %% =========================================================================== %% format/1 %% %% Ensure that parse o format is the identity map. -format(Config) -> - Bin = proplists:get_value(base, Config), - [] = ?util:run([{?MODULE, [format, M, Bin]} - || E <- ?REPLACE, - {ok, M} <- [norm(E)]]). +format(<<_/binary>> = Bin) -> + ?util:run([{?MODULE, format, [{M, Bin}]} || E <- ?REPLACE, + {ok, M} <- [norm(E)]]); -format(Mods, Bin) -> +format({Mods, Bin}) -> B = modify(Bin, Mods), {ok, Dict} = parse(B, []), {ok, D} = parse(diameter_make:format(Dict), []), - {Dict, Dict} = {Dict, D}. + {Dict, Dict} = {Dict, D}; + +format(_Config) -> + run([format]). parse(File, Opts) -> case diameter_make:codec(File, [parse, hrl, return | Opts]) of @@ -415,20 +420,21 @@ parse(File, Opts) -> %% Ensure the expected success/error when parsing a morphed common %% dictionary. -replace(Config) -> - Bin = proplists:get_value(base, Config), - [] = ?util:run([{?MODULE, [replace, N, Bin]} - || E <- ?REPLACE, - N <- [norm(E)]]). +replace(<<_/binary>> = Bin) -> + ?util:run([{?MODULE, replace, [{N, Bin}]} || E <- ?REPLACE, + N <- [norm(E)]]); -replace({E, Mods}, Bin) -> +replace({{E, Mods}, Bin}) -> B = modify(Bin, Mods), case {E, parse(B, [{include, here()}]), Mods} of {ok, {ok, Dict}, _} -> Dict; {_, {error, {E,_} = T}, _} when E /= ok -> diameter_make:format_error(T) - end. + end; + +replace(_Config) -> + run([replace]). re({RE, Repl}, Bin) -> re:replace(Bin, RE, Repl, [multiline]). @@ -438,15 +444,14 @@ re({RE, Repl}, Bin) -> %% %% Ensure success when generating code and compiling. -generate(Config) -> - Bin = proplists:get_value(base, Config), +generate(<<_/binary>> = Bin) -> Rs = lists:zip(?REPLACE, lists:seq(1, length(?REPLACE))), - [] = ?util:run([{?MODULE, [generate, M, Bin, N, T]} - || {E,N} <- Rs, - {ok, M} <- [norm(E)], - T <- [erl, hrl, parse, forms]]). + ?util:run([{?MODULE, generate, [{M, Bin, N, T}]} + || {E,N} <- Rs, + {ok, M} <- [norm(E)], + T <- [erl, hrl, parse, forms]]); -generate(Mods, Bin, N, Mode) -> +generate({Mods, Bin, N, Mode}) -> B = modify(Bin, Mods ++ [{"@name .*", "@name dict" ++ ?L(N)}]), {ok, Dict} = parse(B, []), File = "dict" ++ integer_to_list(N), @@ -454,7 +459,10 @@ generate(Mods, Bin, N, Mode) -> [{name, File}, {prefix, "base"}, Mode])}, - generate(Mode, File, Dict). + generate(Mode, File, Dict); + +generate(_Config) -> + run([generate]). generate(erl, File, _) -> {ok, _} = compile:file(File ++ ".erl", [return_errors]); @@ -473,21 +481,21 @@ generate(hrl, _, _) -> %% =========================================================================== %% flatten1/1 -flatten1(_Config) -> +flatten1({Key, BaseD, FlatD}) -> + Vs = orddict:fetch(Key, BaseD), + Vs = orddict:fetch(Key, FlatD); + +flatten1(_) -> [Vsn | BaseD] = diameter_gen_base_rfc6733:dict(), {ok, I} = parse("@inherits diameter_gen_base_rfc6733\n", []), [Vsn | FlatD] = diameter_make:flatten(I), - [] = ?util:run([{?MODULE, [flatten1, K, BaseD, FlatD]} - || K <- [avp_types, grouped, enum]]). - -flatten1(Key, BaseD, FlatD) -> - Vs = orddict:fetch(Key, BaseD), - Vs = orddict:fetch(Key, FlatD). + ?util:run([{?MODULE, flatten1, [{K, BaseD, FlatD}]} + || K <- [avp_types, grouped, enum]]). %% =========================================================================== %% flatten2/1 -flatten2(_Config) -> +flatten2(_) -> Dict1 = "@name diameter_test1\n" "@prefix diameter_test1\n" diff --git a/lib/diameter/test/diameter_config_SUITE.erl b/lib/diameter/test/diameter_config_SUITE.erl index 31a6b49041..90773e8f6d 100644 --- a/lib/diameter/test/diameter_config_SUITE.erl +++ b/lib/diameter/test/diameter_config_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2015. All Rights Reserved. +%% Copyright Ericsson AB 2013-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,14 +25,15 @@ -module(diameter_config_SUITE). --export([suite/0, - all/0]). +%% testscases, no common_test dependency +-export([run/0, + run/1]). -%% testcases --export([start/1, +%% common_test wrapping +-export([suite/0, + all/0, start_service/1, - add_transport/1, - stop/1]). + add_transport/1]). -define(util, diameter_util). @@ -204,38 +205,53 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 15}}]. all() -> - [start, - start_service, - add_transport, - stop]. + [start_service, + add_transport]. + +start_service(_Config) -> + run([start_service]). + +add_transport(_Config) -> + run([add_transport]). %% =========================================================================== -start(_) -> - ok = diameter:start(). +run() -> + run(all()). -start_service(T) - when is_tuple(T) -> - do(fun start/3, T); +run(List) + when is_list(List) -> + try + ?util:run([[[fun run/1, {F, 5000}] || F <- List]]) + after + dbg:stop_clear(), + diameter:stop() + end; + +run({F, Tmo}) -> + ok = diameter:start(), + try + ?util:run([{[fun run/1, F], Tmo}]) + after + ok = diameter:stop() + end; -start_service(_) -> - [] = ?util:run([{?MODULE, start_service, [T]} - || T <- [lists:keyfind(capabilities, 1, ?TRANSPORT_CONFIG) - | ?SERVICE_CONFIG]]). +run(start_service) -> + ?util:run([[fun start/1, T] + || T <- [lists:keyfind(capabilities, 1, ?TRANSPORT_CONFIG) + | ?SERVICE_CONFIG]]); -add_transport(T) - when is_tuple(T) -> - do(fun add/3, T); +run(add_transport) -> + ?util:run([[fun add/1, T] || T <- ?TRANSPORT_CONFIG]). -add_transport(_) -> - [] = ?util:run([{?MODULE, add_transport, [T]} - || T <- ?TRANSPORT_CONFIG]). +start(T) -> + do(fun start/3, T). -stop(_) -> - ok = diameter:stop(). +add(T) -> + do(fun add/3, T). %% =========================================================================== diff --git a/lib/diameter/test/diameter_ct.hrl b/lib/diameter/test/diameter_ct.hrl deleted file mode 100644 index fdf8782456..0000000000 --- a/lib/diameter/test/diameter_ct.hrl +++ /dev/null @@ -1,22 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - --define(APP, diameter). --define(ERROR(T), erlang:error({?MODULE, ?LINE, T})). diff --git a/lib/diameter/test/diameter_dpr_SUITE.erl b/lib/diameter/test/diameter_dpr_SUITE.erl index 779b919d3c..45f4ec9b5a 100644 --- a/lib/diameter/test/diameter_dpr_SUITE.erl +++ b/lib/diameter/test/diameter_dpr_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2012-2017. All Rights Reserved. +%% Copyright Ericsson AB 2012-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,22 +24,26 @@ -module(diameter_dpr_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1, - init_per_group/2, - end_per_group/2]). - -%% testcases --export([start/1, - connect/1, + client/1, + server/1, + uncommon/1, + transport/1, + service/1, + application/1]). + +%% internal +-export([connect/1, send_dpr/1, remove_transport/1, stop_service/1, - check/1, - stop/1]). + check/1]). %% disconnect_cb -export([disconnect/5]). @@ -84,42 +88,54 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 30}}]. all() -> - [{group, R} || R <- [client, server, uncommon | ?REASONS]]. + [client, server, uncommon, transport, service, application]. -%% The group determines how transports are terminated: by remove_transport, -%% stop_service or application stop. -groups() -> - [{R, [], [start, send_dpr, stop]} || R <- [client, server, uncommon]] - ++ [{R, [], Ts} || Ts <- [tc()], R <- ?REASONS]. +-define(tc(Name), Name(_) -> run([Name])). -init_per_suite(Config) -> %% not need, but a useful place to enable trace - Config. +?tc(client). +?tc(server). +?tc(uncommon). +?tc(transport). +?tc(service). +?tc(application). -end_per_suite(_Config) -> - ok. +%% =========================================================================== -init_per_group(Name, Config) -> - [{group, Name} | Config]. +%% run/0 -end_per_group(_, _) -> - ok. +run() -> + run(all()). -tc() -> - [start, connect, remove_transport, stop_service, check, stop]. +%% run/1 -%% =========================================================================== +run(List) + when is_list(List) -> + try + ?util:run([[{[fun run/1, T], 15000} || T <- List]]) + after + diameter:stop() + end; -%% start/1 - -start(Config) - when is_list(Config) -> - Grp = group(Config), +run(Grp) -> ok = diameter:start(), ok = diameter:start_service(?SERVER, service(?SERVER, Grp)), - ok = diameter:start_service(?CLIENT, service(?CLIENT, Grp)). + ok = diameter:start_service(?CLIENT, service(?CLIENT, Grp)), + _ = lists:foldl(fun(F,A) -> apply(?MODULE, F, [A]) end, + [{group, Grp}], + tc(Grp)), + ok = diameter:stop(). + +tc(T) + when T == client; + T == server; + T == uncommon -> + [send_dpr]; + +tc(_) -> + [connect, remove_transport, stop_service, check]. service(?SERVER = Svc, _) -> ?SERVICE(Svc) @@ -192,26 +208,30 @@ sender(_) -> %% connect/1 connect(Config) -> - Pid = spawn(fun init/0), %% process for disconnect_cb to bang + Self = self(), Grp = group(Config), + Pid = spawn(fun() -> init(Self) end), %% process for disconnect_cb to bang LRef = ?util:listen(?SERVER, tcp), Refs = [?util:connect(?CLIENT, tcp, LRef, opts(RCs, {Grp, Pid})) || RCs <- ?RETURNS], - ?util:write_priv(Config, config, [Pid | Refs]). + Pid ! (Grp == application orelse length(Refs)), + [{config, [Pid | Refs]} | Config]. %% remove_transport/1 %% Remove all the client transports only in the transport group. remove_transport(Config) -> transport == group(Config) - andalso (ok = diameter:remove_transport(?CLIENT, true)). + andalso (ok = diameter:remove_transport(?CLIENT, true)), + Config. %% stop_service/1 %% Stop the service only in the service group. stop_service(Config) -> service == group(Config) - andalso (ok = diameter:stop_service(?CLIENT)). + andalso (ok = diameter:stop_service(?CLIENT)), + Config. %% check/1 @@ -219,16 +239,11 @@ stop_service(Config) -> %% for the timing reason explained below. check(Config) -> Grp = group(Config), - [Pid | Refs] = ?util:read_priv(Config, config), + [Pid | Refs] = proplists:get_value(config, Config), Pid ! self(), %% ask for dictionary Dict = receive {Pid, D} -> D end, %% get it check(Refs, ?RETURNS, Grp, Dict). %% check for callbacks -%% stop/1 - -stop(_Config) -> - ok = diameter:stop(). - %% =========================================================================== %% Whether or not there are callbacks after diameter:stop() depends on @@ -258,8 +273,7 @@ check1(Ref, [], _, Dict) -> %% ---------------------------------------- group(Config) -> - {group, Grp} = lists:keyfind(group, 1, Config), - Grp. + proplists:get_value(group, Config). %% Configure the callback with the group name (= disconnect reason) as %% extra argument. @@ -274,13 +288,18 @@ disconnect(Reason, Ref, Peer, {Reason, Pid}, RC) -> Pid ! {Reason, Ref}, RC. -init() -> - exit(recv(dict:new())). +init(Pid) -> + monitor(process, Pid), + exit(recv(receive T -> T end, dict:new())). -recv(Dict) -> +recv(true, Dict) -> + recv(0, Dict); +recv(N, Dict) -> receive - Pid when is_pid(Pid) -> + Pid when N == 0, is_pid(Pid) -> Pid ! {self(), Dict}; {Reason, Ref} -> - recv(dict:store(Ref, Reason, Dict)) + recv(N - 1, dict:store(Ref, Reason, Dict)); + {'DOWN', _, process, _, _} -> + ok end. diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl index 6d1d1dfd8f..f4cb5e6d79 100644 --- a/lib/diameter/test/diameter_event_SUITE.erl +++ b/lib/diameter/test/diameter_event_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2020. All Rights Reserved. +%% Copyright Ericsson AB 2013-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,20 +26,18 @@ -module(diameter_event_SUITE). +%% testcase, no common_test dependency +-export([run/0]). + +%% common_test wrapping -export([suite/0, all/0, - init_per_suite/1, - end_per_suite/1, - init_per_testcase/2, - end_per_testcase/2]). - -%% testcases --export([start/1, - start_server/1, - up/1, + traffic/1]). + +%% internal +-export([up/1, down/1, - cea_timeout/1, - stop/1]). + cea_timeout/1]). -include("diameter.hrl"). @@ -77,43 +75,44 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 90}}]. all() -> - [start, - start_server, - up, - down, - cea_timeout, - stop]. - -%% Not used, but a convenient place to enable trace. -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. + [traffic]. -init_per_testcase(Name, Config) -> - [{name, Name} | Config]. - -end_per_testcase(_, _) -> - ok. +traffic(_Config) -> + run(). %% =========================================================================== -%% start/stop testcases -start(_Config) -> - ok = diameter:start(). +%% run/0 -start_server(Config) -> +run() -> + ok = diameter:start(), + try + ?util:run([{fun traffic/0, 60000}]) + after + ok = diameter:stop() + end. + +%% traffic/0 + +traffic() -> + PortNr = start_server(), + Config = [{portnr, PortNr}], + Funs = [up, down, cea_timeout], + ?util:run([[{?MODULE, F, [[{name, F} | Config]]} || F <- Funs]]). + +%% start_server/0 + +start_server() -> diameter:subscribe(?SERVER), ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER, [?DICT_COMMON])), LRef = ?util:listen(?SERVER, tcp, [{capabilities_cb, fun capx_cb/2}, {capx_timeout, ?SERVER_CAPX_TMO}]), [PortNr] = ?util:lport(tcp, LRef), - ?util:write_priv(Config, portnr, PortNr), - start = event(?SERVER). + start = event(?SERVER), + PortNr. %% Connect with matching capabilities and expect the connection to %% come up. @@ -158,9 +157,6 @@ cea_timeout(Config) -> start = event(Svc), {{closed, Ref, {'CEA', timeout}, T}, _} = {event(Svc), T}. -stop(_Config) -> - ok = diameter:stop(). - %% ---------------------------------------- %% Keep the server from sending CEA until the client has timed out. @@ -201,7 +197,7 @@ start_service(Name, Opts) -> diameter:start_service(Name, [{monitor, self()} | Opts]). opts(Config, Opts) -> - PortNr = ?util:read_priv(Config, portnr), + PortNr = proplists:get_value(portnr, Config), {connect, [{transport_module, diameter_tcp}, {transport_config, [{ip, ?ADDR}, {port, 0}, diff --git a/lib/diameter/test/diameter_failover_SUITE.erl b/lib/diameter/test/diameter_failover_SUITE.erl index 8a3b3e8413..0c78119e50 100644 --- a/lib/diameter/test/diameter_failover_SUITE.erl +++ b/lib/diameter/test/diameter_failover_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -36,20 +36,19 @@ -module(diameter_failover_SUITE). +%% testcases, no common_test dependency +-export([run/0]). + +%% common_test wrapping -export([suite/0, - all/0]). - -%% testcases --export([start/1, - start_services/1, - connect/1, - send_ok/1, - send_nok/1, - send_discard_1/1, - send_discard_2/1, - stop_services/1, - empty/1, - stop/1]). + all/0, + parallel/1]). + +%% internal +-export([send_ok/0, + send_nok/0, + send_discard_1/0, + send_discard_2/0]). %% diameter callbacks -export([pick_peer/4, @@ -112,50 +111,61 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 90}}]. all() -> - [start, - start_services, - connect, - send_ok, - send_nok, - send_discard_1, - send_discard_2, - stop_services, - empty, - stop]. + [parallel]. + +parallel(_Config) -> + run(). %% =========================================================================== -%% start/stop testcases -start(_Config) -> - ok = diameter:start(). +%% run/0 + +run() -> + ok = diameter:start(), + try + ?util:run([{fun traffic/0, 60000}]) + after + ok = diameter:stop() + end. + +%% traffic/0 -start_services(_Config) -> +traffic() -> + Servers = start_services(), + ok = connect(Servers), + [] = send(), + [] = stop_services(), + [] = ets:tab2list(diameter_request). + +%% start_services/0 + +start_services() -> Servers = [server(N) || N <- ?SERVERS], [] = [T || C <- ?CLIENTS, T <- [diameter:start_service(C, ?SERVICE(C))], T /= ok], + Servers. - {save_config, Servers}. +%% send/0 -connect(Config) -> - {start_services, Servers} = proplists:get_value(saved_config, Config), +send() -> + Funs = [send_ok, send_nok, send_discard_1, send_discard_2], + ?util:run([[{?MODULE, F, []} || F <- Funs]]). - lists:foreach(fun(C) -> connect(C, Servers) end, ?CLIENTS). +%% connect/1 -stop_services(_Config) -> - [] = [{H,T} || H <- ?CLIENTS ++ ?SERVERS, - T <- [diameter:stop_service(H)], - T /= ok]. +connect(Servers) -> + lists:foreach(fun(C) -> connect(C, Servers) end, ?CLIENTS). -%% Ensure transports have been removed from request table. -empty(_Config) -> - [] = ets:tab2list(diameter_request). +%% stop_services/0 -stop(_Config) -> - ok = diameter:stop(). +stop_services() -> + [{H,T} || H <- ?CLIENTS ++ ?SERVERS, + T <- [diameter:stop_service(H)], + T /= ok]. %% ---------------------------------------- @@ -171,7 +181,7 @@ connect(Name, Refs) -> %% Send an STR and expect success after SERVER3 answers after a couple %% of failovers. -send_ok(_Config) -> +send_ok() -> Req = #diameter_base_STR{'Destination-Realm' = realm(?SERVER1), 'Termination-Cause' = ?LOGOUT, 'Auth-Application-Id' = ?APP_ID}, @@ -180,19 +190,19 @@ send_ok(_Config) -> = call(?CLIENT1, Req). %% Send an STR and expect failure when both servers fail. -send_nok(_Config) -> +send_nok() -> Req = #diameter_base_STR{'Destination-Realm' = realm(?SERVER4), 'Termination-Cause' = ?LOGOUT, 'Auth-Application-Id' = ?APP_ID}, {failover, ?LOGOUT} = call(?CLIENT1, Req). %% Send an STR and have prepare_retransmit discard it. -send_discard_1(_Config) -> +send_discard_1() -> Req = #diameter_base_STR{'Destination-Realm' = realm(?SERVER1), 'Termination-Cause' = ?TIMEOUT, 'Auth-Application-Id' = ?APP_ID}, {rejected, ?TIMEOUT} = call(?CLIENT2, Req). -send_discard_2(_Config) -> +send_discard_2() -> Req = #diameter_base_STR{'Destination-Realm' = realm(?SERVER4), 'Termination-Cause' = ?MOVED, 'Auth-Application-Id' = ?APP_ID}, diff --git a/lib/diameter/test/diameter_gen_sctp_SUITE.erl b/lib/diameter/test/diameter_gen_sctp_SUITE.erl index ccee6baec1..7a3dae723d 100644 --- a/lib/diameter/test/diameter_gen_sctp_SUITE.erl +++ b/lib/diameter/test/diameter_gen_sctp_SUITE.erl @@ -27,14 +27,19 @@ -module(diameter_gen_sctp_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, init_per_suite/1, end_per_suite/1]). %% testcases --export([send_one_from_many/1, send_one_from_many/0, - send_many_from_one/1, send_many_from_one/0, +-export([send_one_from_many/1, + send_many_from_one/1, receive_what_was_sent/1]). -include_lib("kernel/include/inet_sctp.hrl"). @@ -67,7 +72,7 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 10}}]. + [{timetrap, {seconds, 15}}]. all() -> [send_one_from_many, @@ -89,13 +94,20 @@ end_per_suite(_Config) -> %% =========================================================================== -%% send_one_from_many/0 +%% run/0 + +run() -> + run(all()). + +%% run/1 + +run(List) -> + diameter_util:run([{{?MODULE, F, [[]]}, 10000} || F <- List]). + +%% send_one_from_many/1 %% %% Demonstrates sluggish delivery of messages. -send_one_from_many() -> - [{timetrap, {seconds, 30}}]. - send_one_from_many(_) -> ?OK = send_multiple(128, 1, 1024). @@ -402,23 +414,20 @@ unmark(Bin) -> %% =========================================================================== -%% send_many_from_one/0 +%% send_many_from_one/1 %% %% Demonstrates sluggish delivery of messages. -send_many_from_one() -> - [{timetrap, {seconds, 30}}]. - send_many_from_one(_) -> ?OK = send_multiple(1, 128, 1024). %% =========================================================================== -%% receive_what_was_sent/1 +%% receive_what_was_sent/0 %% %% Demonstrates reception of a message that differs from that sent. -receive_what_was_sent(_Config) -> +receive_what_was_sent(_) -> ?OK = send_multiple(1, 1, 1024*32). %% =========================================================================== diff --git a/lib/diameter/test/diameter_gen_tcp_SUITE.erl b/lib/diameter/test/diameter_gen_tcp_SUITE.erl index db42ea813e..d1e01da27e 100644 --- a/lib/diameter/test/diameter_gen_tcp_SUITE.erl +++ b/lib/diameter/test/diameter_gen_tcp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014-2017. All Rights Reserved. +%% Copyright Ericsson AB 2014-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -27,11 +27,14 @@ -module(diameter_gen_tcp_SUITE). --export([suite/0, - all/0]). +%% testcases, not common_test dependency +-export([run/0, + run/1]). -%% testcases --export([send_long/1, +%% common_test wrapping +-export([suite/0, + all/0, + send_long/1, connect/1]). -define(LOOPBACK, {127,0,0,1}). @@ -46,13 +49,29 @@ all() -> [connect, %% Appears to fail only when run first. send_long]. +send_long(_) -> + send_long(). + +connect(_) -> + connect(). + %% =========================================================================== -%% send_long/1 +%% run/0 + +run() -> + run(all()). + +%% run/1 + +run(List) -> + diameter_util:run([{{?MODULE, F, [[]]}, 10000} || F <- List]). + +%% send_long/0 %% %% Test that a long message is received. -send_long(_) -> +send_long() -> {Sock, SendF} = connection(), B = binary:copy(<<$X>>, 1 bsl 20), ok = SendF(B), @@ -101,13 +120,13 @@ send(Sock, Bin) -> %% =========================================================================== -%% connect/1 +%% connect/0 %% %% Test that simultaneous connections succeed. This fails sporadically %% on OS X at the time of writing, when gen_tcp:connect/2 returns %% {error, econnreset}. -connect(_) -> +connect() -> {ok, LSock} = gen_tcp:listen(0, ?GEN_OPTS), {ok, {_,PortNr}} = inet:sockname(LSock), Count = lists:seq(1,8), %% 8 simultaneous connects diff --git a/lib/diameter/test/diameter_length_SUITE.erl b/lib/diameter/test/diameter_length_SUITE.erl index daaaae6e00..66d1be114f 100644 --- a/lib/diameter/test/diameter_length_SUITE.erl +++ b/lib/diameter/test/diameter_length_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,20 +24,14 @@ -module(diameter_length_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1, - init_per_group/2, - end_per_group/2, - init_per_testcase/2, - end_per_testcase/2]). - -%% testcases --export([start/1, - send/1, - stop/1]). + parallel/1]). %% diameter callbacks -export([peer_up/3, @@ -83,39 +77,20 @@ -define(LOGOUT, ?'DIAMETER_BASE_TERMINATION-CAUSE_LOGOUT'). --define(GROUPS, [exit, handle, discard]). - -define(L, atom_to_list). %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 120}}]. all() -> - [{group, G} || G <- ?GROUPS]. - -groups() -> - [{G, [], [start, send, stop]} || G <- ?GROUPS]. - -init_per_suite(Config) -> - ok = diameter:start(), - Config. - -end_per_suite(_Config) -> - ok = diameter:stop(). - -init_per_group(Group, Config) -> - [{group, Group} | Config]. - -end_per_group(_, _) -> - ok. + [parallel]. -init_per_testcase(_Name, Config) -> - Config. +parallel(_Config) -> + run(). -end_per_testcase(_, _) -> - ok. +%% =========================================================================== origin(exit) -> 0; origin(handle) -> 1; @@ -127,25 +102,39 @@ origin(2) -> discard. %% =========================================================================== +run() -> + run([exit, handle, discard]). + +run(List) + when is_list(List) -> + ok = diameter:start(), + try + ?util:run([[{[fun run/1, T], 30000} || T <- List]]) + after + ok = diameter:stop() + end; + +run(Group) -> + start(Group), + send(Group), + stop(). + %% start/1 -start(Config) -> - Group = proplists:get_value(group, Config), +start(Group) -> ok = diameter:start_service(?SERVER, ?SERVICE(?L(Group))), ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT)), - LRef = ?util:listen(?SERVER, - tcp, - [{length_errors, Group}]), + LRef = ?util:listen(?SERVER, tcp, [{length_errors, Group}]), ?util:connect(?CLIENT, tcp, LRef, [{capabilities, [{'Origin-State-Id', origin(Group)}]}]). -%% stop/1 +%% stop/0 -stop(_Config) -> - ok = diameter:remove_transport(?CLIENT, true), +stop() -> ok = diameter:remove_transport(?SERVER, true), + ok = diameter:remove_transport(?CLIENT, true), ok = diameter:stop_service(?SERVER), ok = diameter:stop_service(?CLIENT). @@ -194,10 +183,7 @@ send(discard) -> {error, timeout} = call(4), #diameter_base_STA{'Result-Code' = ?SUCCESS} - = call(0); - -send(Config) -> - send(proplists:get_value(group, Config)). + = call(0). %% =========================================================================== diff --git a/lib/diameter/test/diameter_pool_SUITE.erl b/lib/diameter/test/diameter_pool_SUITE.erl index a36a4fa17a..40d34c6237 100644 --- a/lib/diameter/test/diameter_pool_SUITE.erl +++ b/lib/diameter/test/diameter_pool_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2015-2019. All Rights Reserved. +%% Copyright Ericsson AB 2015-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,17 +25,16 @@ -module(diameter_pool_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - init_per_testcase/2, - end_per_testcase/2, - init_per_suite/1, - end_per_suite/1]). - -%% testcases --export([tcp_connect/1, - sctp_connect/1, - any_connect/1]). + tcp/1, + sctp/1, + any/1]). %% =========================================================================== @@ -62,44 +61,53 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 30}}]. + [{timetrap, {seconds, 45}}]. all() -> - [tcp_connect, - sctp_connect, - any_connect]. + [tcp, sctp, any]. -init_per_testcase(_Name, Config) -> - Config. +tcp(_Config) -> + run([tcp]). -end_per_testcase(_Name, _Config) -> - diameter:stop(). - -init_per_suite(Config) -> - [{sctp, ?util:have_sctp()} | Config]. +sctp(_Config) -> + case ?util:have_sctp() of + true -> run([sctp]); + false -> {skip, no_sctp} + end. -end_per_suite(_Config) -> - ok. +any(_Config) -> + run([any]). %% =========================================================================== -tcp_connect(_Config) -> - connect(tcp, tcp). +%% run/0 -sctp_connect(Config) -> - case lists:member({sctp, true}, Config) of - true -> connect(sctp, sctp); - false -> {skip, no_sctp} - end. +run() -> + run(all()). + +%% run/1 + +run(tcp = T) -> + connect(T, T); -any_connect(_Config) -> - connect(any, tcp). +run(sctp = T) -> + connect(T, T); + +run(any = T) -> + connect(T, tcp); + +run(List) -> + ok = diameter:start(), + try + ?util:run([[{[fun run/1, T], 30000} || T <- List]]) + after + ok = diameter:stop() + end. %% connect/2 %% Establish multiple connections between a client and server. connect(ClientProt, ServerProt) -> - ok = diameter:start(), [] = [{S,T} || S <- ["server", "client"], T <- [diameter:start_service(S, ?SERVICE(S))], T /= ok], @@ -108,20 +116,24 @@ connect(ClientProt, ServerProt) -> LRef = ?util:listen("server", ServerProt, [{pool_size, 4}]), {4,0} = count("server", LRef, accept), %% 4 transports, no connections %% Establish 5 connections. - Ref = ?util:connect("client", ClientProt, LRef, [{pool_size, 5}]), - {5,5} = count("client", Ref, pool), %% 5 connections + N = pool_size(5), %% connections to establish + Ref = ?util:connect("client", ClientProt, LRef, [{pool_size, N}]), + {N,N} = count("client", Ref, pool), %% N connections %% Ensure the server has started replacement transports within a %% reasonable time. Sleepsince there's no guarantee the %% replacements have been started before the client has received %% 'up' events. (Although it's likely.) - sleep(), - {9,5} = count("server", LRef, accept), %% 5 connections + 4 accepting + timer:sleep(1000), + N4 = N + 4, + {N4,N} = count("server", LRef, accept), %% N connections + 4 accepting %% Ensure there are still the expected number of accepting transports %% after stopping the client service. ok = diameter:stop_service("client"), - sleep(), + timer:sleep(1000), {4,0} = count("server", LRef, accept), %% 4 transports, no connections %% Done. + ok = diameter:remove_transport("client", true), + ok = diameter:remove_transport("server", true), ok = diameter:stop_service("server"). count(Name, Ref, Key) -> @@ -131,5 +143,10 @@ count(Name, Ref, Key) -> {Key, Ps} = lists:keyfind(Key, 1, T), {length(Ps), length(Cs)}. %% number of processes, connections -sleep() -> - receive after 1000 -> ok end. +%% Simultaneous connections are often refused on Darwin: don't try to +%% establish more than one. +pool_size(N) -> + case os:type() of + {_, 'darwin'} -> 1; + _ -> rand:uniform(N) + end. diff --git a/lib/diameter/test/diameter_reg_SUITE.erl b/lib/diameter/test/diameter_reg_SUITE.erl index cd9242faa8..02e10ffb74 100644 --- a/lib/diameter/test/diameter_reg_SUITE.erl +++ b/lib/diameter/test/diameter_reg_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,86 +24,76 @@ -module(diameter_reg_SUITE). --export([suite/0, - all/0, - groups/0, - init_per_suite/1, - end_per_suite/1]). +%% testcases, no common_test dependency +-export([run/0, + run/1]). -%% testcases --export([add/1, - add_new/1, - remove/1, - down/1, - terms/1, - pids/1]). +%% common_test wrapping +-export([all/0, + parallel/1]). --define(reg, diameter_reg). --define(util, diameter_util). +-define(reg, diameter_reg). %% =========================================================================== -suite() -> - [{timetrap, {seconds, 60}}]. - all() -> - [{group, all}, - {group, all, [parallel]}]. + [parallel]. -groups() -> - [{all, [], tc()}]. +parallel(_Config) -> + run(). -tc() -> - [add, - add_new, - remove, - down, - terms, - pids]. +%% =========================================================================== -init_per_suite(Config) -> - ok = diameter:start(), - Config. +%% run/0 -end_per_suite(_Config) -> - ok = diameter:stop(). +run() -> + run([add, add_new, remove, down, terms, pids]). -%% =========================================================================== +%% run/1 + +run(List) + when is_list(List) -> + ok = diameter:start(), + try + diameter_util:run([{[fun run/1, T], 10000} || T <- List]) + after + ok = diameter:stop() + end; -add(_) -> +run(add) -> Ref = make_ref(), true = ?reg:add(Ref), true = ?reg:add(Ref), [{Ref, Pid}] = ?reg:match(Ref), - Pid = self(). + Pid = self(); -add_new(_) -> +run(add_new) -> Ref = make_ref(), true = ?reg:add_new(Ref), - false = ?reg:add_new(Ref). + false = ?reg:add_new(Ref); -remove(_) -> +run(remove) -> Ref = make_ref(), true = ?reg:add_new(Ref), true = ?reg:add_new({Ref}), true = ?reg:remove({Ref}), [{Ref, Pid}] = ?reg:match(Ref), - Pid = self(). + Pid = self(); -down(_) -> +run(down) -> Ref = make_ref(), {_, MRef} = spawn_monitor(fun() -> ?reg:add_new(Ref), timer:sleep(1000) end), receive {'DOWN', MRef, process, _, _} -> ok end, timer:sleep(1000), - [] = ?reg:match(Ref). + [] = ?reg:match(Ref); -terms(_) -> +run(terms) -> Ref = make_ref(), true = ?reg:add_new(Ref), [[Pid]] = [L || {T,L} <- ?reg:terms(), T == Ref], - Pid = self(). + Pid = self(); -pids(_) -> +run(pids) -> Ref = make_ref(), true = ?reg:add_new(Ref), %% Don't match [[Ref]] since this will only necessarily be the diff --git a/lib/diameter/test/diameter_relay_SUITE.erl b/lib/diameter/test/diameter_relay_SUITE.erl index 9de5cbe685..2502820e0f 100644 --- a/lib/diameter/test/diameter_relay_SUITE.erl +++ b/lib/diameter/test/diameter_relay_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2017. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -34,26 +34,13 @@ -module(diameter_relay_SUITE). +%% testcases, no common_test dependency +-export([run/0]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0]). - -%% testcases --export([start/1, - start_services/1, - connect/1, - send1/1, - send2/1, - send3/1, - send4/1, - send_loop/1, - send_timeout_1/1, - send_timeout_2/1, - info/1, - counters/1, - disconnect/1, - stop_services/1, - stop/1]). + parallel/1]). %% diameter callbacks -export([pick_peer/4, @@ -115,41 +102,37 @@ %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 30}}]. all() -> - [start, - start_services, - connect, - {group, all}, - counters, - {group, all, [parallel]}, - disconnect, - stop_services, - stop]. - -groups() -> - [{all, [], tc()}]. + [parallel]. -%% Traffic cases run when services are started and connections -%% established. -tc() -> - [send1, - send2, - send3, - send4, - send_loop, - send_timeout_1, - send_timeout_2, - info]. +parallel(_Config) -> + run(). %% =========================================================================== -%% start/stop testcases -start(_Config) -> - ok = diameter:start(). +%% run/0 + +run() -> + ok = diameter:start(), + try + ?util:run([{fun traffic/0, 20000}]) + after + ok = diameter:stop() + end. -start_services(_Config) -> +%% traffic/0 + +traffic() -> + Servers = start_services(), + Conns = connect(Servers), + [] = send(), + [] = counters(), + [] = disconnect(Conns), + [] = stop_services(). + +start_services() -> [S1,S2,S3,S4] = [server(N, ?DICT_COMMON) || N <- [?SERVER1, ?SERVER2, ?SERVER3, @@ -158,30 +141,32 @@ start_services(_Config) -> ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT, ?DICT_COMMON)), - {save_config, [{?RELAY1, [S1,S2,R2]}, - {?RELAY2, [S3,S4]}, - {?CLIENT, [R1,R2]}]}. - -connect(Config) -> - {_, Conns} = proplists:get_value(saved_config, Config), + [{?RELAY1, [S1,S2,R2]}, {?RELAY2, [S3,S4]}, {?CLIENT, [R1,R2]}]. - ?util:write_priv(Config, - "cfg", - lists:flatmap(fun({CN,Ss}) -> connect(CN, Ss) end, - Conns)). +connect(Servers) -> + lists:flatmap(fun({CN,Ss}) -> connect(CN, Ss) end, Servers). -disconnect(Config) -> - [] = [{T,C} || C <- ?util:read_priv(Config, "cfg"), - T <- [break(C)], - T /= ok]. +disconnect(Conns) -> + [{T,C} || C <- Conns, + T <- [break(C)], + T /= ok]. -stop_services(_Config) -> - [] = [{H,T} || H <- ?SERVICES, - T <- [diameter:stop_service(H)], - T /= ok]. +stop_services() -> + [{H,T} || H <- ?SERVICES, + T <- [diameter:stop_service(H)], + T /= ok]. -stop(_Config) -> - ok = diameter:stop(). +%% Traffic cases run when services are started and connections +%% established. +send() -> + ?util:run([[fun traffic/1, T] || T <- [send1, + send2, + send3, + send4, + send_loop, + send_timeout_1, + send_timeout_2, + info]]). %% ---------------------------------------- @@ -203,50 +188,50 @@ connect(Name, Refs) -> %% traffic testcases %% Send an STR intended for a specific server and expect success. -send1(_Config) -> - call(?SERVER1). -send2(_Config) -> - call(?SERVER2). -send3(_Config) -> - call(?SERVER3). -send4(_Config) -> - call(?SERVER4). +traffic(send1) -> + call(?SERVER1); +traffic(send2) -> + call(?SERVER2); +traffic(send3) -> + call(?SERVER3); +traffic(send4) -> + call(?SERVER4); %% Send an ASR that loops between the relays (RELAY1 -> RELAY2 -> %% RELAY1) and expect the loop to be detected. -send_loop(_Config) -> +traffic(send_loop) -> Req = ['ASR', {'Destination-Realm', realm(?SERVER1)}, {'Destination-Host', ?SERVER1}, {'Auth-Application-Id', ?APP_ID}], #'diameter_base_answer-message'{'Result-Code' = ?LOOP_DETECTED} - = call(Req, [{filter, realm}]). + = call(Req, [{filter, realm}]); %% Send a RAR that is incorrectly routed and then discarded and expect %% different results depending on whether or not we or the relay %% timeout first. -send_timeout_1(_Config) -> +traffic(send_timeout_1) -> #'diameter_base_answer-message'{'Result-Code' = ?UNABLE_TO_DELIVER} - = send_timeout(7000). -send_timeout_2(_Config) -> - {error, timeout} = send_timeout(3000). + = traffic({timeout, 7000}); +traffic(send_timeout_2) -> + {error, timeout} = traffic({timeout, 3000}); -send_timeout(Tmo) -> +traffic({timeout, Tmo}) -> Req = ['RAR', {'Destination-Realm', realm(?SERVER1)}, {'Destination-Host', ?SERVER1}, {'Auth-Application-Id', ?APP_ID}, {'Re-Auth-Request-Type', ?AUTHORIZE_ONLY}], - call(Req, [{filter, realm}, {timeout, Tmo}]). + call(Req, [{filter, realm}, {timeout, Tmo}]); -info(_Config) -> +traffic(info) -> %% Wait for RELAY1 to have answered all requests, so that the %% suite doesn't end before all answers are sent and counted. receive after 6000 -> ok end, [] = ?util:info(). -counters(_Config) -> - [] = ?util:run([[fun counters/2, K, S] - || K <- [statistics, transport, connections], - S <- ?SERVICES]). +counters() -> + ?util:run([[fun counters/2, K, S] + || K <- [statistics, transport, connections], + S <- ?SERVICES]). counters(Key, Svc) -> counters(Key, Svc, [_|_] = diameter:service_info(Svc, Key)). diff --git a/lib/diameter/test/diameter_stats_SUITE.erl b/lib/diameter/test/diameter_stats_SUITE.erl index 4716082394..b48e7a84bf 100644 --- a/lib/diameter/test/diameter_stats_SUITE.erl +++ b/lib/diameter/test/diameter_stats_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2015. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,55 +24,52 @@ -module(diameter_stats_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1]). - -%% testcases --export([reg/1, - incr/1, - read/1, - sum/1, - flush/1]). + parallel/1]). -define(stat, diameter_stats). %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 30}}]. all() -> - [{group, all}, - {group, all, [parallel]}]. + [parallel]. -groups() -> - [{all, [], tc()}]. +parallel(_Config) -> + run(). -tc() -> - [reg, - incr, - read, - sum, - flush]. +%% =========================================================================== -init_per_suite(Config) -> - ok = diameter:start(), - Config. +%% run/0 -end_per_suite(_Config) -> - ok = diameter:stop(). +run() -> + run([reg, incr, read, sum, flush]). -%% =========================================================================== +%% run/1 + +run(List) + when is_list(List) -> + ok = diameter:start(), + try + diameter_util:run([{[fun run/1, T], 15000} || T <- List]) + after + ok = diameter:stop() + end; -reg(_) -> +run(reg) -> Ref = '$1', true = ?stat:reg(Ref), - false = ?stat:reg(Ref). %% duplicate + false = ?stat:reg(Ref); %% duplicate -incr(_) -> +run(incr) -> Ref = '_', Ctr = x, false = ?stat:incr(Ctr), %% not registered, @@ -83,9 +80,9 @@ incr(_) -> 2 = ?stat:incr(Ctr, self(), 2) end), ok = fold(Ctr, Ref, 3), %% folded - ?stat:flush([self(), Ref]). + ?stat:flush([self(), Ref]); -read(_) -> +run(read) -> Ref = make_ref(), C1 = {a,b}, C2 = {b,a}, @@ -99,9 +96,9 @@ read(_) -> = ?stat:read([self(), Ref, make_ref()]), [] = ?stat:read([]), [] = ?stat:read([make_ref()]), - ?stat:flush([self(), Ref, make_ref()]). + ?stat:flush([self(), Ref, make_ref()]); -sum(_) -> +run(sum) -> Ref = make_ref(), C1 = {a,b}, C2 = {b,a}, @@ -116,9 +113,9 @@ sum(_) -> [{Self, [{C1,1}, {C2,2}]}] = ?stat:sum([self()]), [{Ref, [{C1,7}]}, {Self, [{C1,1}, {C2,2}]}] - = ?stat:flush([self(), Ref]). + = ?stat:flush([self(), Ref]); -flush(_) -> +run(flush) -> Ref = make_ref(), Ctr = '_', true = ?stat:reg(Ref), diff --git a/lib/diameter/test/diameter_sync_SUITE.erl b/lib/diameter/test/diameter_sync_SUITE.erl index 2785bd92d6..395c99bd0b 100644 --- a/lib/diameter/test/diameter_sync_SUITE.erl +++ b/lib/diameter/test/diameter_sync_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2016. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,63 +24,59 @@ -module(diameter_sync_SUITE). +%% testcases, no common_test depedency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - groups/0, - init_per_suite/1, - end_per_suite/1]). - -%% testcases --export([call/1, - cast/1, - timeout/1, - flush/1]). + parallel/1]). -define(sync, diameter_sync). --define(util, diameter_util). - --define(TIMEOUT, infinity). %% =========================================================================== suite() -> - [{timetrap, {seconds, 60}}]. + [{timetrap, {seconds, 15}}]. all() -> - [{group, all}, - {group, all, [parallel]}]. + [parallel]. -groups() -> - [{all, [], tc()}]. +parallel(_Config) -> + run(). -tc() -> - [call, - cast, - timeout, - flush]. +%% =========================================================================== -init_per_suite(Config) -> - ok = diameter:start(), - Config. +%% run/0 -end_per_suite(_Config) -> - ok = diameter:stop(). +run() -> + run([call, cast, timeout, flush]). -%% =========================================================================== +%% run/1 + +run(List) + when is_list(List) -> + ok = diameter:start(), + try + diameter_util:run([{[fun run/1, T], 10000} || T <- List]) + after + ok = diameter:stop() + end; -call(_) -> +run(call) -> Ref = make_ref(), Q = {q, Ref}, F = fun() -> Ref end, - Ref = ?sync:call(Q, F, infinity, ?TIMEOUT), + Ref = ?sync:call(Q, F, infinity, infinity), Ref = ?sync:call(Q, F, 0, infinity), Ref = call(Q, F), Ref = call(Q, {fun(_) -> Ref end, x}), timeout = call(Q, fun() -> exit(unexpected) end), {_,_,_} = call(Q, {erlang, now, []}), - {_,_,_} = call(Q, [fun erlang:now/0]). + {_,_,_} = call(Q, [fun erlang:now/0]); -cast(_) -> +run(cast) -> Ref = make_ref(), Q = {q, Ref}, false = ?sync:carp(Q), @@ -95,26 +91,21 @@ cast(_) -> true = 2 =< ?sync:pending(), true = lists:member(Q, ?sync:queues()), %% ... and that the max number of requests is respected. - rejected = ?sync:call(Q, {erlang, now, []}, 1, ?TIMEOUT), - rejected = ?sync:cast(Q, {erlang, now, []}, 1, ?TIMEOUT), + rejected = ?sync:call(Q, {erlang, now, []}, 1, infinity), + rejected = ?sync:cast(Q, {erlang, now, []}, 1, infinity), %% Monitor on the identifiable request and see that exits when we %% let the blocking request finish. MRef = erlang:monitor(process, Pid), {value, P} = ?sync:carp(Q), P ! Ref, - Ref = receive - {'DOWN', MRef, process, _, Reason} -> - Reason - after ?TIMEOUT -> - false - end. - -timeout(_) -> + Ref = receive {'DOWN', MRef, process, _, Reason} -> Reason end; + +run(timeout) -> Q = make_ref(), ok = ?sync:cast(Q, {timer, sleep, [2000]}, infinity, 2000), - timeout = ?sync:call(Q, fun() -> ok end, infinity, 1000). + timeout = ?sync:call(Q, fun() -> ok end, infinity, 1000); -flush(_) -> +run(flush) -> Q = make_ref(), F = {timer, sleep, [2000]}, ok = cast(Q, F), diff --git a/lib/diameter/test/diameter_util.erl b/lib/diameter/test/diameter_util.erl index 5ccfeb7a7e..f6c101b7f5 100644 --- a/lib/diameter/test/diameter_util.erl +++ b/lib/diameter/test/diameter_util.erl @@ -45,11 +45,6 @@ disconnect/4, info/0]). -%% common_test-specific --export([write_priv/3, - read_priv/2, - map_priv/3]). - -define(L, atom_to_list). %% --------------------------------------------------------------------------- @@ -274,48 +269,6 @@ eval(F) when is_function(F,0) -> F(). -%% --------------------------------------------------------------------------- -%% write_priv/3 -%% -%% Write an arbitrary term to a named file. - -write_priv(Config, Name, Term) -> - write(path(Config, Name), Term). - -write(Path, Term) -> - ok = file:write_file(Path, term_to_binary(Term)). - -%% read_priv/2 -%% -%% Read a term from a file. - -read_priv(Config, Name) -> - read(path(Config, Name)). - -read(Path) -> - {ok, Bin} = file:read_file(Path), - binary_to_term(Bin). - -%% map_priv/3 -%% -%% Modify a term in a file and return both old and new values. - -map_priv(Config, Name, Fun1) -> - map(path(Config, Name), Fun1). - -map(Path, Fun1) -> - T0 = read(Path), - T1 = Fun1(T0), - write(Path, T1), - {T0, T1}. - -path(Config, Name) - when is_atom(Name) -> - path(Config, ?L(Name)); -path(Config, Name) -> - Dir = proplists:get_value(priv_dir, Config), - filename:join([Dir, Name]). - %% --------------------------------------------------------------------------- %% lport/2 %% diff --git a/lib/diameter/test/diameter_watchdog_SUITE.erl b/lib/diameter/test/diameter_watchdog_SUITE.erl index f3f168e671..02f15ff21b 100644 --- a/lib/diameter/test/diameter_watchdog_SUITE.erl +++ b/lib/diameter/test/diameter_watchdog_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2018. All Rights Reserved. +%% Copyright Ericsson AB 2010-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,18 +25,22 @@ -module(diameter_watchdog_SUITE). +%% testcases, no common_test dependency +-export([run/0, + run/1]). + +%% common_test wrapping -export([suite/0, all/0, - init_per_suite/1, - end_per_suite/1]). - -%% testcases --export([reopen/0, reopen/1, reopen/4, reopen/6, - suspect/1, suspect/4, - okay/1, okay/4]). - --export([id/1, %% jitter callback - run1/1, + reopen/1, + suspect/1, + okay/1]). + +%% internal callbacks +-export([reopen/4, reopen/6, + suspect/4, + okay/4, + id/1, %% jitter callback abuse/1, abuse/2]). @@ -48,7 +52,6 @@ -export([message/3]). -include("diameter.hrl"). --include("diameter_ct.hrl"). %% =========================================================================== @@ -105,49 +108,72 @@ [])). %% Log to make failures identifiable. --define(LOG(T), ?LOG("~p", [T])). --define(LOG(F,A), ct:pal("~p: " ++ F, [self() | A])). --define(WARN(F,A), ct:pal(error, "~p: " ++ F, [self() | A])). +-define(LOG(F,A), io:format("~p: " ++ F ++ "~n", [self() | A])). %% =========================================================================== suite() -> - [{timetrap, {seconds, 90}}]. + [{timetrap, {seconds, 315}}]. all() -> - [reopen, - suspect, - okay]. + [reopen, suspect, okay]. -init_per_suite(Config) -> - ok = diameter:start(), - Config. +reopen(_Config) -> + run([reopen]). + +suspect(_Config) -> + run([suspect]). + +okay(_Config) -> + run([okay]). + +%% =========================================================================== + +%% run/0 -end_per_suite(_Config) -> - ok = diameter:stop(). +run() -> + run(all()). + +%% run/1. + +run(reopen) -> + reopen(); %% 20 watchdogs @ 15 sec + +run(suspect) -> + suspect(); + +run(okay) -> + okay(); + +run(List) -> + ok = diameter:start(), + try + ?util:run([{[fun run/1, T], maps:get(T, #{reopen => 300000}, 90000)} + || T <- List]) + after + ok = diameter:stop() + end. %% =========================================================================== -%% # reopen/1 +%% # reopen/0 %% =========================================================================== %% Test the watchdog state machine for the required failover, failback %% and reopen behaviour by examining watchdog events. reopen() -> - [{timetrap, {minutes, 5}}]. %% 20 watchdogs @ 15 sec - -reopen(_) -> - [] = run([[reopen, T, W, N, M] - || T <- [listen, connect], %% watchdog to test - W <- ?WD_TIMERS, %% watchdog_timer value - N <- [0,1,2], %% DWR's to answer before ignoring - M <- ['DWR', 'DWA', 'RAA']]). %% how to induce failback + ?util:run([{?MODULE, reopen, [T, W, N, M]} + || T <- [listen, connect], %% watchdog to test + W <- ?WD_TIMERS, %% watchdog_timer value + N <- [0,1,2], %% DWR's to answer before ignoring + M <- ['DWR', 'DWA', 'RAA']]). %% how to induce failback reopen(Test, Wd, N, M) -> %% Publish a ref ensure the connecting transport is added only %% once events from the listening transport are subscribed to. Ref = make_ref(), - [] = run([[reopen, T, Test, Ref, Wd, N, M] || T <- [listen, connect]]). + ?util:run([{?MODULE, reopen, [T, Test, Ref, Wd, N, M]} + || T <- [listen, connect]]). %% reopen/6 @@ -377,14 +403,14 @@ tpid(Ref, [[{ref, Ref}, TPid. %% =========================================================================== -%% # suspect/1 +%% # suspect/0 %% =========================================================================== %% Configure transports to require a set number of watchdog timeouts %% before moving from OKAY to SUSPECT. -suspect(_) -> - [] = run([[abuse, [suspect, N]] || N <- [0,1,3]]). +suspect() -> + ?util:run([{?MODULE, abuse, [[suspect, N]]} || N <- [0,1,3]]). suspect(Type, Fake, Ref, N) when is_reference(Ref) -> @@ -417,7 +443,7 @@ suspect(TRef, false, SvcName, N) -> %% abuse/1 abuse(F) -> - [] = run([[abuse, F, T] || T <- [listen, connect]]). + ?util:run([{?MODULE, abuse, [F, T]} || T <- [listen, connect]]). abuse(F, [_,_,_|_] = Args) -> ?LOG("~p", [Args]), @@ -425,21 +451,21 @@ abuse(F, [_,_,_|_] = Args) -> abuse([F|A], Test) -> Ref = make_ref(), - [] = run([[abuse, F, [T, T == Test, Ref] ++ A] - || T <- [listen, connect]]); + ?util:run([{?MODULE, abuse, [F, [T, T == Test, Ref] ++ A]} + || T <- [listen, connect]]); abuse(F, Test) -> abuse([F], Test). %% =========================================================================== -%% # okay/1 +%% # okay/0 %% =========================================================================== %% Configure the number of watchdog exchanges before moving from %% REOPEN to OKAY. -okay(_) -> - [] = run([[abuse, [okay, N]] || N <- [0,2,3]]). +okay() -> + ?util:run([{?MODULE, abuse, [[okay, N]]} || N <- [0,2,3]]). okay(Type, Fake, Ref, N) when is_reference(Ref) -> @@ -626,23 +652,6 @@ choose(false, _, X) -> X. id(T) -> T. -%% run/1 -%% -%% A more useful badmatch in case of failure. - -run(Fs) -> - ?util:run([{?MODULE, [run1, F]} || F <- Fs]). - -run1([F|A]) -> - ok = try - apply(?MODULE, F, A), - ok - catch - E:R:Stack -> - ?WARN("~p", [{A, E, R, Stack}]), - Stack - end. - %% jitter/2 jitter(?WD(T), _) -> diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk index b1717aff00..fb8cfc445c 100644 --- a/lib/diameter/test/modules.mk +++ b/lib/diameter/test/modules.mk @@ -50,9 +50,6 @@ MODULES = \ diameter_transport_SUITE \ diameter_watchdog_SUITE -HRL_FILES = \ - diameter_ct.hrl - DATA = \ diameter_codec_SUITE_data/avps.dia \ diameter_codec_SUITE_data/send.dia \ -- 2.34.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor