File 0442-kernel-test-Extend-socket_suites.patch of Package erlang

From b596c923a4a3b030ef61f94db07446acd68c81dd Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Fri, 4 Jul 2025 12:45:43 +0200
Subject: [PATCH] [kernel|test] Extend socket_suites

Extend 'socket_suites' to also include gen_tcp_[api|echo|misc]_SUITE
and gen_udp_SUITE (specifically the inet_backend_socket top-groupes).
Also, tweaked the read_packets (udp) test case.
---
 lib/kernel/test/gen_tcp_api_SUITE.erl  |  55 ++++++++---
 lib/kernel/test/gen_tcp_echo_SUITE.erl |  90 +++++++++++++-----
 lib/kernel/test/gen_tcp_misc_SUITE.erl |  55 ++++++++---
 lib/kernel/test/gen_udp_SUITE.erl      | 121 ++++++++++++++++++++-----
 lib/kernel/test/kernel_test_lib.erl    |  11 ++-
 lib/kernel/test/kernel_test_lib.hrl    |  11 ++-
 lib/kernel/test/socket_suites.erl      |  29 +++++-
 7 files changed, 291 insertions(+), 81 deletions(-)

diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index 351fcae3c1..54072cf401 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -216,23 +216,50 @@ end_per_suite(Config0) ->
 
 
 init_per_group(inet_backend_default = _GroupName, Config) ->
-    [{socket_create_opts, []} | Config];
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            [{socket_create_opts, []} | Config];
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
+            {skip, "explicit inet-backend = socket"}
+    end;
 init_per_group(inet_backend_inet = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
-            [{socket_create_opts, [{inet_backend, inet}]} | Config]
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, inet}]} | Config]
+            end;
+        inet ->
+            [{socket_create_opts, [{inet_backend, inet}]} | Config];
+        socket ->
+            {skip, "explicit inet-backend = socket"}
     end;
 init_per_group(inet_backend_socket = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, socket}]} | Config]
+            end;
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
             [{socket_create_opts, [{inet_backend, socket}]} | Config]
     end;
 init_per_group(t_local = _GroupName, Config) ->
diff --git a/lib/kernel/test/gen_tcp_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl
index 23791d496b..f0ac37f9ea 100644
--- a/lib/kernel/test/gen_tcp_echo_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl
@@ -22,6 +22,7 @@
 -module(gen_tcp_echo_SUITE).
 
 -include_lib("common_test/include/ct.hrl").
+-include("kernel_test_lib.hrl").
 
 %%-compile(export_all).
 
@@ -41,12 +42,17 @@ suite() ->
      {timetrap, {minutes,1}}].
 
 all() ->
-    case kernel_test_lib:test_inet_backends() of
+    case ?TEST_INET_BACKENDS() of
         true ->
-            [{group, inet_backend_inet},
-             {group, inet_backend_socket}];
-        false ->
-            [{group, inet_backend_default}]
+            [
+             {group, inet_backend_default},
+             {group, inet_backend_inet},
+             {group, inet_backend_socket}
+            ];
+        _ ->
+            [
+             {group, inet_backend_default}
+            ]
     end.
 
 groups() ->
@@ -74,28 +80,68 @@ end_per_suite(_Config) ->
     ok.
 
 
+init_per_group(inet_backend_default = _GroupName, Config) ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            [{socket_create_opts, []} | Config];
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
+            {skip, "explicit inet-backend = socket"}
+    end;
+init_per_group(inet_backend_inet = _GroupName, Config) ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, inet}]} | Config]
+            end;
+        inet ->
+            [{socket_create_opts, [{inet_backend, inet}]} | Config];
+        socket ->
+            {skip, "explicit inet-backend = socket"}
+    end;
+init_per_group(inet_backend_socket = _GroupName, Config) ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, socket}]} | Config]
+            end;
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
+            [{socket_create_opts, [{inet_backend, socket}]} | Config]
+    end;
 init_per_group(Name, Config) ->
     case Name of
-        inet_backend_default ->
-            kernel_test_lib:config_inet_backend(Config, default);
-        inet_backend_socket ->
-            init_per_group_inet_backend(socket, Config);
-        inet_backend_inet ->
-            init_per_group_inet_backend(inet, Config);
-        %%
-        no_read_ahead   -> [{read_ahead, false} | Config];
-        delay_send      -> [{delay_send, true}  | Config];
+        no_read_ahead -> [{read_ahead, false} | Config];
+        delay_send    -> [{delay_send, true}  | Config];
         _ -> Config
     end.
 
-init_per_group_inet_backend(Backend, Config) ->
-    case kernel_test_lib:explicit_inet_backend() of
-        true ->
-            %% Contradicting kernel variables - skip group
-            {skip, "explicit inet backend"};
-        false ->
-            kernel_test_lib:config_inet_backend(Config, Backend)
-    end.
+%% init_per_group_inet_backend(Backend, Config) ->
+%%     case kernel_test_lib:explicit_inet_backend() of
+%%         true ->
+%%             %% Contradicting kernel variables - skip group
+%%             {skip, "explicit inet backend"};
+%%         false ->
+%%             kernel_test_lib:config_inet_backend(Config, Backend)
+%%     end.
 
 end_per_group(Name, Config) ->
     case Name of
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 2ab88c87d5..44e52df60e 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -411,23 +411,50 @@ end_per_suite(Config0) ->
     Config1.
 
 init_per_group(inet_backend_default = _GroupName, Config) ->
-    [{socket_create_opts, []} | Config];
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            [{socket_create_opts, []} | Config];
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
+            {skip, "explicit inet-backend = socket"}
+    end;
 init_per_group(inet_backend_inet = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
-            [{socket_create_opts, [{inet_backend, inet}]} | Config]
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, inet}]} | Config]
+            end;
+        inet ->
+            [{socket_create_opts, [{inet_backend, inet}]} | Config];
+        socket ->
+            {skip, "explicit inet-backend = socket"}
     end;
 init_per_group(inet_backend_socket = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, socket}]} | Config]
+            end;
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
             [{socket_create_opts, [{inet_backend, socket}]} | Config]
     end;
 init_per_group(_GroupName, Config) ->
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 67573eed8e..db9ea8b6c1 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -271,23 +271,50 @@ end_per_suite(Config0) ->
     Config1.
 
 init_per_group(inet_backend_default = _GroupName, Config) ->
-    [{socket_create_opts, []} | Config];
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            [{socket_create_opts, []} | Config];
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
+            {skip, "explicit inet-backend = socket"}
+    end;
 init_per_group(inet_backend_inet = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
-            [{socket_create_opts, [{inet_backend, inet}]} | Config]
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, inet}]} | Config]
+            end;
+        inet ->
+            [{socket_create_opts, [{inet_backend, inet}]} | Config];
+        socket ->
+            {skip, "explicit inet-backend = socket"}
     end;
 init_per_group(inet_backend_socket = _GroupName, Config) ->
-    case ?EXPLICIT_INET_BACKEND() of
-        true ->
-            %% The environment trumps us,
-            %% so only the default group should be run!
-            {skip, "explicit inet backend"};
-        false ->
+    ?P("~w(~w) -> check explicit inet-backend when"
+       "~n   Config: ~p", [?FUNCTION_NAME, _GroupName, Config]),
+    case ?EXPLICIT_INET_BACKEND(Config) of
+        undefined ->
+            case ?EXPLICIT_INET_BACKEND() of
+                true ->
+                    %% The environment trumps us,
+                    %% so only the default group should be run!
+                    {skip, "explicit inet backend"};
+                false ->
+                    [{socket_create_opts, [{inet_backend, socket}]} | Config]
+            end;
+        inet ->
+            {skip, "explicit inet-backend = inet"};
+        socket ->
             [{socket_create_opts, [{inet_backend, socket}]} | Config]
     end;
 init_per_group(local, Config) -> 
@@ -917,6 +944,7 @@ do_bad_address(Config) when is_list(Config) ->
 
 %% OTP-6249 UDP option for number of packet reads.
 read_packets(Config) when is_list(Config) ->
+    process_flag(trap_exit, true),
     Cond = fun() ->
 		   case ?IS_SOCKET_BACKEND(Config) of
 		       true ->
@@ -1044,31 +1072,80 @@ read_packets_test(Config, R, RA, RP, Msgs, Node) ->
 	  [link,{priority,high}]),
     receive
 	{Sender, {sockname, {SA, SP}}} ->
+            ?P("~w -> got socket info from sender", [?FUNCTION_NAME]),
 	    erlang:trace(R, true,
 			 [running_ports,'send',{tracer,Tracer}]),
 	    erlang:yield(),
+            ?P("~w -> release sender (~p)", [?FUNCTION_NAME, Sender]),
 	    Sender ! {Receiver,go},
-	    read_packets_recv(Msgs),
+            ?P("~w -> receive", [?FUNCTION_NAME]),
+	    read_packets_recv(Sender, Msgs),
+            ?P("~w -> turn off trace", [?FUNCTION_NAME]),
 	    erlang:trace(R, false, [all]),
+            ?P("~w -> get trace (from tracer ~p)", [?FUNCTION_NAME, Tracer]),
 	    Tracer ! {Receiver,get_trace},
 	    receive
 		{Tracer,{trace,Trace}} ->
+                    ?P("~w -> got trace - verify", [?FUNCTION_NAME]),
 		    {read_packets_verify(R, SA, SP, Trace), Trace}
 	    end
     end.
 
-read_packets_send(_S, _RA, _RP, 0) ->
-    ok;
 read_packets_send(S, RA, RP, Msgs) ->
-    ok = gen_udp:send(S, RA, RP, "UDP FLOOOOOOD"),
-    read_packets_send(S, RA, RP, Msgs - 1).
+    LastWouldBlock = never,
+    NoWouldBlock   = 0,
+    read_packets_send(S, RA, RP, Msgs, LastWouldBlock, NoWouldBlock).
+
+read_packets_send(S, _RA, _RP, 0, _LastWouldBlock, NoWouldBlock) ->
+    ?P("~w -> done when"
+       "~n   NumberOf WouldBlock: ~w"
+       "~n   info(Sock):          ~p",
+       [?FUNCTION_NAME, NoWouldBlock, inet:info(S)]),
+    ok;
+read_packets_send(S, RA, RP, Msgs, LastWouldBlock, NoWouldBlock) ->
+    case gen_udp:send(S, RA, RP, "UDP FLOOOOOOD") of
+        ok ->
+            read_packets_send(S, RA, RP, Msgs - 1,
+                              LastWouldBlock, NoWouldBlock);
+        {error, eagain = Reason} when (Msgs =/= LastWouldBlock) ->
+            ?P("~w -> ~w: sleep when"
+               "~n   Msgs:       ~w"
+               "~n   info(Sock): ~p",
+               [?FUNCTION_NAME, Reason, Msgs, inet:info(S)]),
+            receive after 1000 -> ok end,
+            ?P("~w -> try again", [?FUNCTION_NAME]),
+            read_packets_send(S, RA, RP, Msgs, Msgs, NoWouldBlock + 1);
+        {error, eagain = Reason} ->
+            ?P("~w -> send failure: "
+               "~n   Reason:              ~p"
+               "~n   Msgs:                ~p"
+               "~n   NumberOf WouldBlock: ~p"
+               "~n   info(Sock):          ~p",
+               [?FUNCTION_NAME,
+                Reason, Msgs, NoWouldBlock+1, (catch inet:info(S))]),
+            exit({send_failed, Reason, Msgs, NoWouldBlock+1});
+        {error, Reason} ->
+            ?P("~w -> send failure: "
+               "~n   Reason:              ~p"
+               "~n   Msgs:                ~p"
+               "~n   NumberOf WouldBlock: ~p"
+               "~n   info(Sock):          ~p",
+               [?FUNCTION_NAME,
+                Reason, Msgs, NoWouldBlock, (catch inet:info(S))]),
+            exit({send_failed, Reason, Msgs, NoWouldBlock})
+    end.
 
-read_packets_recv(0) ->
+read_packets_recv(_Sender, 0) ->
+    ?P("~w -> done", [?FUNCTION_NAME]),
     ok;
-read_packets_recv(N) ->
+read_packets_recv(Sender, N) ->
     receive
+        {'EXIT', Sender, Reason} when Reason =/= normal ->
+            ?P("received unexpected exit from sender: "
+               "~n   ~p", [Reason]),
+            exit({skip, {sender, Reason}});
 	_ ->
-	    read_packets_recv(N - 1)
+	    read_packets_recv(Sender, N - 1)
     after 5000 ->
 	    timeout
     end.
diff --git a/lib/kernel/test/kernel_test_lib.erl b/lib/kernel/test/kernel_test_lib.erl
index cd41c3e9ef..709953be1c 100644
--- a/lib/kernel/test/kernel_test_lib.erl
+++ b/lib/kernel/test/kernel_test_lib.erl
@@ -31,7 +31,7 @@
          open/3,
          is_socket_backend/1,
          inet_backend_opts/1,
-         explicit_inet_backend/0,
+         explicit_inet_backend/0, explicit_inet_backend/1,
          test_inet_backends/0,
          which_inet_backend/1,
          config_inet_backend/2]).
@@ -2667,6 +2667,15 @@ explicit_inet_backend() ->
             false
     end.
 
+explicit_inet_backend(Config) ->
+    Key = inet_backend,
+    case lists:keysearch(Key, 1, Config) of
+        {value, {Key, Backend}} ->
+            Backend;
+        false ->
+            undefined
+    end.
+
 
 test_inet_backends() ->
     case application:get_all_env(kernel) of
diff --git a/lib/kernel/test/kernel_test_lib.hrl b/lib/kernel/test/kernel_test_lib.hrl
index 372df79e80..e499f17f42 100644
--- a/lib/kernel/test/kernel_test_lib.hrl
+++ b/lib/kernel/test/kernel_test_lib.hrl
@@ -52,11 +52,12 @@
 -define(OPEN(C, P),              ?LIB:open(C, P, [])).
 -define(OPEN(C, P, O),           ?LIB:open(C, P, O)).
 
--define(INET_BACKEND_OPTS(C),    ?LIB:inet_backend_opts(C)).
--define(EXPLICIT_INET_BACKEND(), ?LIB:explicit_inet_backend()).
--define(TEST_INET_BACKENDS(),    ?LIB:test_inet_backends()).
--define(WHICH_INET_BACKEND(C),   ?LIB:which_inet_backend(C)).
--define(IS_SOCKET_BACKEND(C),    ?LIB:is_socket_backend(C)).
+-define(INET_BACKEND_OPTS(C),     ?LIB:inet_backend_opts(C)).
+-define(EXPLICIT_INET_BACKEND(),  ?LIB:explicit_inet_backend()).
+-define(EXPLICIT_INET_BACKEND(C), ?LIB:explicit_inet_backend(C)).
+-define(TEST_INET_BACKENDS(),     ?LIB:test_inet_backends()).
+-define(WHICH_INET_BACKEND(C),    ?LIB:which_inet_backend(C)).
+-define(IS_SOCKET_BACKEND(C),     ?LIB:is_socket_backend(C)).
 
 -define(ENSURE_NOT_DOG_SLOW(C, L), ?LIB:ensure_not_dog_slow((C), (L))).
 
diff --git a/lib/kernel/test/socket_suites.erl b/lib/kernel/test/socket_suites.erl
index 3fdaeed39f..2aea9f268b 100644
--- a/lib/kernel/test/socket_suites.erl
+++ b/lib/kernel/test/socket_suites.erl
@@ -26,6 +26,7 @@
 
 -module(socket_suites).
 
+-include("kernel_test_lib.hrl").
 
 -export([suite/0, all/0, groups/0]).
 -export([
@@ -45,6 +46,12 @@ end_per_suite(_Config) ->
     ok.
 
 
+init_per_group(GroupName, Config)
+  when (GroupName =:= gen_tcp_api) orelse
+       (GroupName =:= gen_tcp_echo) orelse
+       (GroupName =:= gen_tcp_misc) orelse
+       (GroupName =:= gen_udp) ->
+    [{inet_backend, socket}|Config];
 init_per_group(_GroupName, Config) ->
     Config.
 
@@ -67,11 +74,22 @@ suite() ->
      {timetrap, {minutes,1}}].
 
 all() -> 
-    [{group, main},
+    %% This, together with the group init above, is what is required to
+    %% run the inet_backend_socket group (and only this top grooup) of
+    %% the gen_tcp_api, gen_tcp_echo, gen_tcp_misc, gen_udp test suites.
+    ok = application:set_env(kernel, test_inet_backends, true),
+    [
+     {group, main},
      {group, api},
      {group, traffic},
      {group, ttest},
-     {group, gen_tcp}].
+     {group, gen_tcp},
+
+     {group, gen_tcp_api},
+     {group, gen_tcp_echo},
+     {group, gen_tcp_misc},
+     {group, gen_udp}
+    ].
 
 groups() -> 
     [
@@ -79,5 +97,10 @@ groups() ->
      {api,            [], [{socket_api_SUITE,           all}]},
      {traffic,        [], [{socket_traffic_SUITE,       all}]},
      {ttest,          [], [{socket_ttest_SUITE,         all}]},
-     {gen_tcp,        [], [{gen_tcp_socket_SUITE,       all}]}
+     {gen_tcp,        [], [{gen_tcp_socket_SUITE,       all}]},
+
+     {gen_tcp_api,    [], [{gen_tcp_api_SUITE,          all}]},
+     {gen_tcp_echo,   [], [{gen_tcp_echo_SUITE,         all}]},
+     {gen_tcp_misc,   [], [{gen_tcp_misc_SUITE,         all}]},
+     {gen_udp,        [], [{gen_udp_SUITE,              all}]}
     ].
-- 
2.43.0

openSUSE Build Service is sponsored by