File 6557-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

openSUSE Build Service is sponsored by