File 3166-kernel-inet-res-test-Add-two-simple-test-cases.patch of Package erlang

From 7d15cf5abd30a96998c7ed07e505e0c7a4a8e095 Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Tue, 3 Nov 2020 09:21:42 +0100
Subject: [PATCH 6/6] [kernel|inet-res|test] Add two simple test cases

Add two test cases for servfail retry timeout validation.
Default value and explicit retry timeout.

OTP-16956
---
 lib/kernel/test/inet_res_SUITE.erl | 176 ++++++++++++++++++++++-------
 1 file changed, 134 insertions(+), 42 deletions(-)

diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index 428f6c5d32..91ff883466 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -29,9 +29,11 @@
 
 -export([all/0, suite/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]).
+	 init_per_testcase/2, end_per_testcase/2
+        ]).
 -export([basic/1, resolve/1, edns0/1, txt_record/1, files_monitor/1,
 	 last_ms_answer/1, intermediate_error/1,
+         servfail_retry_timeout_default/1, servfail_retry_timeout_1000/1,
          label_compression_limit/1
         ]).
 -export([
@@ -71,6 +73,7 @@ all() ->
     [basic, resolve, edns0, txt_record, files_monitor,
      last_ms_answer,
      intermediate_error,
+     intermediate_error, servfail_retry_timeout_default, servfail_retry_timeout_1000,
      label_compression_limit,
      gethostbyaddr, gethostbyaddr_v6, gethostbyname,
      gethostbyname_v6, getaddr, getaddr_v6, ipv4_to_ipv6,
@@ -119,14 +122,20 @@ end_per_group(_GroupName, Config) ->
 
 zone_dir(TC) ->
     case TC of
-	basic -> otptest;
-	resolve -> otptest;
-	edns0 -> otptest;
-	files_monitor -> otptest;
-	last_ms_answer -> otptest;
+	basic              -> otptest;
+	resolve            -> otptest;
+	edns0              -> otptest;
+	files_monitor      -> otptest;
+	last_ms_answer     -> otptest;
         intermediate_error ->
             {internal,
              #{rcode => ?REFUSED}};
+        servfail_retry_timeout_default ->
+            {internal,
+             #{rcode => ?SERVFAIL, etd => 1500}};
+        servfail_retry_timeout_1000 ->
+            {internal,
+             #{rcode => ?SERVFAIL, etd => 1000}};
 	_ -> undefined
     end.
 
@@ -329,44 +338,81 @@ ns_printlog(Fname) ->
 %% Internal name server
 
 ns_internal(ServerSpec, Mref, Tag, S) ->
-    ?P("ns_internal -> await message"),
+    ?P("ns-internal -> await message"),
     receive
         {'DOWN',Mref,_,_,Reason} ->
-            ?P("ns_internal -> received DOWN: "
+            ?P("ns-internal -> received DOWN: "
                "~n      ~p", [Reason]),
             exit(Reason);
         Tag ->
-            ?P("ns_internal -> received tag: done"),
+            ?P("ns-internal -> received tag: done"),
             ok;
         {udp,S,IP,Port,Data} ->
-            ?P("ns_internal -> received UDP message"),
+            ?P("ns-internal -> received UDP message"),
             Req = ok(inet_dns:decode(Data)),
-            Resp = ns_internal(ServerSpec, Req),
+            {Resp, ServerSpec2} = ns_internal(ServerSpec, Req),
             RespData = inet_dns:encode(Resp),
             _ = ok(gen_udp:send(S, IP, Port, RespData)),
             _ = ok(inet:setopts(S, [{active,once}])),
-            ns_internal(ServerSpec, Mref, Tag, S)
+            ns_internal(ServerSpec2, Mref, Tag, S)
     end.
 
-ns_internal(#{rcode := Rcode}, Req) ->
-    Hdr = inet_dns:msg(Req, header),
+ns_internal(#{rcode := Rcode,
+              ts    := TS0,
+              etd   := ETD} = ServerSpec, Req) ->
+    ?P("ns-internal -> request received (time validation)"),
+    TS1    = timestamp(),
+    Hdr    = inet_dns:msg(Req, header),
+    Opcode = inet_dns:header(Hdr, opcode),
+    Id     = inet_dns:header(Hdr, id),
+    Rd     = inet_dns:header(Hdr, rd),
+    %%
+    Qdlist = inet_dns:msg(Req, qdlist),
+    ?P("ns-internal -> time validation: "
+       "~n      ETD:       ~w"
+       "~n      TS1 - TS0: ~w", [ETD, TS1 - TS0]),
+    RC = if ((TS1 - TS0) >= ETD) ->
+                 ?P("ns-internal -> time validated"),
+                 ?NOERROR;
+            true ->
+                 ?P("ns-internal -> time validation failed"),
+                 Rcode
+         end,
+    Resp   = inet_dns:make_msg(
+               [{header,
+                 inet_dns:make_header(
+                   [{id,     Id},
+                    {qr,     true},
+                    {opcode, Opcode},
+                    {aa,     true},
+                    {tc,     false},
+                    {rd,     Rd},
+                    {ra,     false},
+                    {rcode,  RC}])},
+                {qdlist, Qdlist}]),
+    {Resp, ServerSpec#{ts => timestamp()}};
+ns_internal(#{rcode := Rcode} = ServerSpec, Req) ->
+    ?P("ns-internal -> request received"),
+    Hdr    = inet_dns:msg(Req, header),
     Opcode = inet_dns:header(Hdr, opcode),
-    Id = inet_dns:header(Hdr, id),
-    Rd = inet_dns:header(Hdr, rd),
+    Id     = inet_dns:header(Hdr, id),
+    Rd     = inet_dns:header(Hdr, rd),
     %%
     Qdlist = inet_dns:msg(Req, qdlist),
-    inet_dns:make_msg(
-       [{header,
-         inet_dns:make_header(
-           [{id,Id},
-            {qr,true},
-            {opcode,Opcode},
-            {aa,true},
-            {tc,false},
-            {rd,Rd},
-            {ra,false},
-            {rcode,Rcode}])},
-         {qdlist,Qdlist}]).
+    Resp   = inet_dns:make_msg(
+               [{header,
+                 inet_dns:make_header(
+                   [{id,Id},
+                    {qr,true},
+                    {opcode,Opcode},
+                    {aa,true},
+                    {tc,false},
+                    {rd,Rd},
+                    {ra,false},
+                    {rcode,Rcode}])},
+                {qdlist,Qdlist}]),
+    {Resp, ServerSpec#{ts => timestamp()}}.
+
 
 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% Behaviour modifying nameserver proxy
@@ -378,10 +424,13 @@ proxy_start(TC, {NS,P}) ->
 	spawn_link(
 	  fun () ->
 		  try proxy_start(TC, NS, P, Parent, Tag)
-		  catch C:X ->
-			  io:format(
-			    "~w: ~w:~p ~p~n",
-			    [self(),C,X,erlang:get_stacktrace()])
+		  catch
+                      C:X:Stacktrace ->
+			  ?P("~p Failed starting proxy: "
+                             "~n      Class:      ~w"
+                             "~n      Error:      ~p"
+                             "~n      Stacktrace: ~p",
+                             [self(), C, X, erlang:get_stacktrace()])
 		  end
 	  end),
     receive {started,Tag,Port} ->
@@ -871,24 +874,62 @@ last_ms_answer(Config) when is_list(Config) ->
     proxy_wait(PSpec),
     ok.
 
+
 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% First name server answers ?REFUSED, second does not answer.
 %% Check that we get the error code from the first server.
 
 intermediate_error(Config) when is_list(Config) ->
-    NS = ns(Config),
-    Name = "ns.otptest",
-    IP = {127,0,0,1},
+    NS      = ns(Config),
+    Name    = "ns.otptest",
+    Class   = in,
+    Type    = a,
+    IP      = {127,0,0,1},
     %% A "name server" that does not respond
-    S = ok(gen_udp:open(0, [{ip,IP},{active,false}])),
-    Port = ok(inet:port(S)),
-    NSs = [NS,{IP,Port}],
-    {error,{refused,_}} =
-        inet_res:resolve(Name, in, a, [{nameservers,NSs},verbose], 500),
+    S       = ok(gen_udp:open(0, [{ip,IP},{active,false}])),
+    Port    = ok(inet:port(S)),
+    NSs     = [NS,{IP,Port}],
+    Opts    = [{nameservers, NSs}, verbose],
+    Timeout = 500,
+    {error, {refused,_}} = inet_res:resolve(Name, Class, Type, Opts, Timeout),
     _ = gen_udp:close(S),
     ok.
 
 
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A name server that firstanswers ?SERVFAIL, the second try *if* the retry
+%% is not received *too soon* (etd) answers noerror.
+
+servfail_retry_timeout_default(Config) when is_list(Config) ->
+    NS        = ns(Config),
+    Name      = "ns.otptest",
+    Class     = in,
+    Type      = a,
+    Opts      = [{nameservers,[NS]}, verbose],
+    ?P("try resolve"),
+    {ok, Rec} = inet_res:resolve(Name, Class, Type, Opts),
+    ?P("resolved: "
+       "~n      ~p", [Rec]),
+    ok.
+
+
+%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% A name server that firstanswers ?SERVFAIL, the second try *if* the retry
+%% is not received *too soon* (etd) answers noerror.
+
+servfail_retry_timeout_1000(Config) when is_list(Config) ->
+    NS        = ns(Config),
+    Name      = "ns.otptest",
+    Class     = in,
+    Type      = a,
+    Opts      = [{nameservers,[NS]}, {servfail_retry_timeout, 1000}, verbose],
+    ?P("try resolve"),
+    {ok, Rec} = inet_res:resolve(Name, Class, Type, Opts),
+    ?P("resolved: "
+       "~n      ~p", [Rec]),
+    ok.
+
+
 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% Test that label encoding compression limits at 14 bits pointer size
 
@@ -987,6 +1074,9 @@ host_and_addr() -> inet_SUITE:host_and_addr().
 host_and_addr(Config) -> inet_SUITE:host_and_addr(Config).
 
 
+timestamp() ->
+    erlang:monotonic_time(milli_seconds).
+
 
 %% Case flip helper
 
-- 
2.26.2

openSUSE Build Service is sponsored by