File 0487-Add-tests-for-message_cb.patch of Package erlang
From da04f7c26ffc1c5ea8aa277ab0a939c2a9397044 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20W=C4=85sowski?= <michal@erlang.org>
Date: Wed, 27 Aug 2025 10:44:22 +0200
Subject: [PATCH 2/2] Add tests for message_cb
---
.../test/diameter_transport_SUITE.erl | 111 +++++++++++++++++-
1 file changed, 110 insertions(+), 1 deletion(-)
diff --git a/lib/diameter/test/diameter_transport_SUITE.erl b/lib/diameter/test/diameter_transport_SUITE.erl
index e8b695c666..7403185c84 100644
--- a/lib/diameter/test/diameter_transport_SUITE.erl
+++ b/lib/diameter/test/diameter_transport_SUITE.erl
@@ -47,6 +47,9 @@
reconnect/1,
init/2]).
+-export([message_client/4,
+ message_server/4]).
+
-include_lib("kernel/include/inet_sctp.hrl").
-include("diameter.hrl").
@@ -86,6 +89,8 @@
%% Messages from gen_sctp.
-define(SCTP(Sock, Data), {sctp, Sock, _, _, Data}).
+-define(A, list_to_atom).
+-define(L, atom_to_list).
-define(TL(F), ?TL(F, [])).
-define(TL(F, A), ?LOG("DTRANSPS", F, A)).
@@ -125,7 +130,7 @@ run() ->
try
?RUN([[fun run/1, {P,F}]
|| P <- [sctp || ?HAVE_SCTP()] ++ [tcp],
- F <- [connect, accept, reconnect]])
+ F <- [connect, accept, reconnect, callback]])
after
diameter:stop()
end.
@@ -154,6 +159,14 @@ run({Prot, connect}) ->
Res = connect(Prot),
?TL("run(connect) -> done when"
"~n Res: ~p", [Res]),
+ Res;
+
+run({Prot, callback}) ->
+ ?TL("run(callback) -> entry with"
+ "~n Prot: ~p", [Prot]),
+ Res = callback(Prot),
+ ?TL("run(callback) -> done when"
+ "~n Res: ~p", [Res]),
Res.
@@ -313,6 +326,102 @@ reconnect(Prot) ->
"~n Res: ~p", [Res]),
ok.
+%% ===========================================================================
+%% callback/1
+%%
+%% Check that when message callback is updated after message sending,
+%% the ack is reported using the new callback.
+
+callback(Prot) ->
+ ?TL("callback -> entry with"
+ "~n Prot: ~p", [Prot]),
+
+ ServerSvcName = {callback, listen, make_ref()},
+ ?TL("callback -> register service ~p", [ServerSvcName]),
+ ok = ?DEL_REG(ServerSvcName),
+ ?TL("callback -> start service ~p", [ServerSvcName]),
+ ok = start_service(ServerSvcName),
+ ?TL("callback -> listen when"
+ "~n ServerSvcName: ~p", [ServerSvcName]),
+ ServerProtOpts = [Prot, {message_cb, {?MODULE, message_server, [self(), 0]}}],
+ LRef = ?LISTEN(ServerSvcName, ServerProtOpts, []),
+ ?TL("callback -> wait"),
+ [_] = diameter_reg:wait({?A("diameter_" ++ ?L(Prot)), listener, {LRef, '_'}}),
+
+ ClientSvcName = {callback, connect, make_ref()},
+ ?TL("callback -> register service ~p", [ClientSvcName]),
+ ok = ?DEL_REG(ClientSvcName),
+ ?TL("callback -> start service ~p", [ClientSvcName]),
+ ok = start_service(ClientSvcName),
+ ?TL("callback -> connect when"
+ "~n ClientSvcName: ~p"
+ "~n LRef: ~p", [ClientSvcName, LRef]),
+ ClientProtOpts = [Prot, {message_cb, {?MODULE, message_client, [self(), 0]}}],
+ CRef = ?CONNECT(ClientSvcName, ClientProtOpts, LRef, [{connect_timer, 2000}]),
+ ?TL("callback -> CRef: ~p", [CRef]),
+
+ [{'Origin-Host', OH}, {'Origin-Realm', OR}] =
+ diameter:service_info(ServerSvcName, ['Origin-Host', 'Origin-Realm']),
+ Msg = ['ACR', {'Session-Id', "invalid"},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR},
+ {'Destination-Realm', OR},
+ {'Accounting-Record-Type', 1},
+ {'Accounting-Record-Number', 0}],
+
+ diameter:call(ClientSvcName, diameter_gen_base_rfc6733, Msg, []),
+ ok = verify_message_callbacks([]).
+
+verify_message_callbacks(States) ->
+ receive
+ {Type, N} when Type == client; Type == server ->
+ ?TL("verify_message_callbacks -> received"
+ "~n Type: ~p"
+ "~n N: ~p", [Type, N]),
+ case lists:member({Type, N}, States) of
+ true ->
+ {error, "State already received previously"};
+ false ->
+ verify_message_callbacks([{Type, N} | States])
+ end
+ after 1000 ->
+ case length(States) of
+ 0 ->
+ {error, "No message callbacks received"};
+ _ ->
+ ok
+ end
+ end.
+
+message_client(ack, Msg, Parent, N) ->
+ ?TL("message_client(ack) -> entry with"
+ "~n Dir: ack"
+ "~n Msg: ~p"
+ "~n N: ~p", [Msg, N]),
+ Parent ! {client, N},
+ [{?MODULE, ?FUNCTION_NAME, [Parent, N + 1]}];
+message_client(Dir, Msg, Parent, N) ->
+ ?TL("message_client -> entry with"
+ "~n Dir: ~p"
+ "~n Msg: ~p"
+ "~n N: ~p", [Dir, Msg, N]),
+ Parent ! {client, N},
+ [Msg, {?MODULE, ?FUNCTION_NAME, [Parent, N + 1]}].
+
+message_server(ack, Msg, Parent, N) ->
+ ?TL("message_server(ack) -> entry with"
+ "~n Dir: ack"
+ "~n Msg: ~p"
+ "~n N: ~p", [Msg, N]),
+ Parent ! {server, N},
+ [{?MODULE, ?FUNCTION_NAME, [Parent, N + 1]}];
+message_server(Dir, Msg, Parent, N) ->
+ ?TL("message_server -> entry with"
+ "~n Dir: ~p"
+ "~n Msg: ~p"
+ "~n N: ~p", [Dir, Msg, N]),
+ Parent ! {server, N},
+ [Msg, {?MODULE, ?FUNCTION_NAME, [Parent, N + 1]}].
start_service(SvcName) ->
OH = diameter_util:unique_string(),
--
2.51.0