File 2461-snmp-test-Add-simple-test-case-to-verify-file-descri.patch of Package erlang

From 555b0733dc4444444df7052dc104a28cfbaf33bd Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Fri, 20 Nov 2020 11:45:10 +0100
Subject: [PATCH 1/3] [snmp|test] Add simple test case to verify file
 descriptor leak

Add a simple test case to "verify" that the file descriptor leak
when reloading mibs has been fixed.

OTP-16993
---
 lib/snmp/test/snmp_conf_SUITE.erl | 86 +++++++++++++++++++++++++++++--
 1 file changed, 82 insertions(+), 4 deletions(-)

diff --git a/lib/snmp/test/snmp_conf_SUITE.erl b/lib/snmp/test/snmp_conf_SUITE.erl
index 7d60485060..635ff6646f 100644
--- a/lib/snmp/test/snmp_conf_SUITE.erl
+++ b/lib/snmp/test/snmp_conf_SUITE.erl
@@ -28,6 +28,7 @@
 %% Include files
 %%----------------------------------------------------------------------
 
+-include_lib("kernel/include/file.hrl").
 -include_lib("common_test/include/ct.hrl").
 -include("snmp_test_lib.hrl").
 
@@ -109,10 +110,15 @@ init_per_suite(Config0) when is_list(Config0) ->
             %% We need a monitor on this node also
             snmp_test_sys_monitor:start(),
 
+            PrivDir    = ?config(priv_dir, Config1),
+            PrivSubdir = filename:join(PrivDir, "snmp_conf_test"),
+            ok = filelib:ensure_dir(filename:join(PrivSubdir, "dummy")),
+            Config2 = [{priv_subdir, PrivSubdir} | Config1],
+
             ?IPRINT("init_per_suite -> end when"
-                    "~n      Config: ~p", [Config1]),
+                    "~n      Config: ~p", [Config2]),
             
-            Config1
+            Config2
     end.
 
 end_per_suite(Config0) when is_list(Config0) ->
@@ -144,6 +150,30 @@ end_per_group(_GroupName, Config) ->
 %% -----
 %%
 
+init_per_testcase(read = _Case, Config) when is_list(Config) ->
+    %% There are other ways to test this:
+    %% lsof (linux and maybe FreeBSD):    lsof -p <pid>
+    %%    os:cmd("lsof -p " ++ os:getpid() ++ " | grep -v COMMAND | wc -l").
+    %% fstat (FreeBSD and maybe OpenBSD): fstat -p <pid>
+    %%    os:cmd("fstat -p " ++ os:getpid() ++ " | grep -v USER | wc -l").
+    %% But this (list:dir) is good enough...
+    case os:type() of
+        {unix, linux} ->
+            case file:read_file_info("/proc/" ++ os:getpid() ++ "/fd") of
+                {ok, #file_info{type   = directory,
+                                access = Access}}
+                  when (Access =:= read) orelse
+                       (Access =:= read_write) ->
+                    [{num_open_fd, fun num_open_fd_using_list_dir/0} |
+                     Config];
+                _ ->
+                    {skip, "Not proc fd"}
+            end;
+        {win32, _} ->
+            {skip, "Not implemented"};
+        _ ->
+            {skip, "Not implemented"}
+    end;
 init_per_testcase(_Case, Config) when is_list(Config) ->
     Config.
 
@@ -701,10 +731,58 @@ verify_not_timer(Val) ->
 
 %%======================================================================
 
+%% Since we need something to read, we also write.
+%% And we can just as well that too...
 read(suite) -> [];
 read(Config) when is_list(Config) ->
-    ?P(read),
-    ?SKIP(not_implemented_yet).
+    ?TC_TRY(read,
+            fun() -> ok end,
+            fun(_) -> do_read(Config) end,
+            fun(_) -> ok end).
+
+do_read(Config) ->
+    Dir       = ?config(priv_subdir, Config),
+    NumOpenFD = ?config(num_open_fd, Config),
+
+    Entries = [
+               snmpa_conf:agent_entry(intAgentIpAddress, {0,0,0,0}),
+               snmpa_conf:agent_entry(intAgentUDPPort, 161),
+               snmpa_conf:agent_entry(snmpEngineMaxMessageSize, 484),
+               snmpa_conf:agent_entry(snmpEngineID, "fooBarEI")
+              ],
+
+    NumFD01 = NumOpenFD(),
+
+    ok = snmpa_conf:write_agent_config(Dir, Entries),
+
+    NumFD02 = NumOpenFD(),
+
+    {ok, _} = snmpa_conf:read_agent_config(Dir),
+
+
+    NumFD03 = NumOpenFD(),
+    if
+        (NumFD01 =:= NumFD02) andalso (NumFD02 =:= NumFD03) ->
+            ok;
+        true ->
+            ?FAIL({num_open_fd, NumFD01, NumFD02, NumFD03})
+    end.
+
+
+
+%% There are other ways to test this:
+%% lsof (linux and maybe FreeBSD):    lsof -p <pid>
+%%    os:cmd("lsof -p " ++ os:getpid() ++ " | grep -v COMMAND | wc -l").
+%% fstat (FreeBSD and maybe OpenBSD): fstat -p <pid>
+%%    os:cmd("fstat -p " ++ os:getpid() ++ " | grep -v USER | wc -l").
+%% But this is good enough...
+num_open_fd_using_list_dir() ->
+    case file:list_dir("/proc/" ++ os:getpid() ++ "/fd") of
+        {ok, FDs} ->
+            length(FDs);
+        {error, Reason} ->
+            ?SKIP({failed_listing_fd, Reason})
+    end.
 
 
 %%======================================================================
-- 
2.26.2

openSUSE Build Service is sponsored by