summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--OTP_VERSION2
-rw-r--r--erts/doc/src/alt_disco.xml14
-rw-r--r--erts/doc/src/epmd.xml6
-rw-r--r--erts/doc/src/erl.xml22
-rw-r--r--erts/doc/src/notes.xml106
-rw-r--r--erts/emulator/beam/break.c4
-rw-r--r--erts/emulator/beam/erl_init.c4
-rw-r--r--erts/emulator/nifs/common/socket_nif.c6
-rw-r--r--erts/emulator/test/socket_SUITE.erl39
-rw-r--r--erts/emulator/test/socket_test_lib.erl51
-rw-r--r--erts/preloaded/ebin/atomics.beambin3312 -> 3316 bytes
-rw-r--r--erts/preloaded/ebin/counters.beambin3112 -> 3116 bytes
-rw-r--r--erts/preloaded/ebin/erl_init.beambin2304 -> 2312 bytes
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin52560 -> 52732 bytes
-rw-r--r--erts/preloaded/ebin/erl_tracer.beambin2224 -> 2228 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin100436 -> 100440 bytes
-rw-r--r--erts/preloaded/ebin/erts_code_purger.beambin10996 -> 10996 bytes
-rw-r--r--erts/preloaded/ebin/erts_dirty_process_signal_handler.beambin2784 -> 2784 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin20988 -> 20984 bytes
-rw-r--r--erts/preloaded/ebin/erts_literal_area_collector.beambin3272 -> 3272 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin50224 -> 50236 bytes
-rw-r--r--erts/preloaded/ebin/persistent_term.beambin1860 -> 1864 bytes
-rw-r--r--erts/preloaded/ebin/prim_buffer.beambin3612 -> 3620 bytes
-rw-r--r--erts/preloaded/ebin/prim_eval.beambin1540 -> 1544 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin28008 -> 28016 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin81472 -> 81480 bytes
-rw-r--r--erts/preloaded/ebin/prim_net.beambin5140 -> 5144 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22452 -> 22460 bytes
-rw-r--r--erts/preloaded/ebin/socket.beambin79040 -> 79020 bytes
-rw-r--r--erts/preloaded/ebin/socket_registry.beambin5724 -> 5676 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin19728 -> 19732 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl18
-rw-r--r--erts/preloaded/src/prim_file.erl10
-rw-r--r--lib/compiler/src/beam_ssa_bsm.erl19
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl16
-rw-r--r--lib/crypto/test/crypto_bench_SUITE.erl2
-rw-r--r--lib/crypto/test/crypto_property_test_SUITE.erl16
-rw-r--r--lib/crypto/test/engine_SUITE.erl4
-rw-r--r--lib/diameter/doc/src/diameter.xml14
-rw-r--r--lib/diameter/doc/src/notes.xml51
-rw-r--r--lib/diameter/examples/code/GNUmakefile6
-rw-r--r--lib/diameter/examples/code/README105
-rw-r--r--lib/diameter/examples/code/client.erl171
-rw-r--r--lib/diameter/examples/code/client_cb.erl29
-rw-r--r--lib/diameter/examples/code/node.erl202
-rw-r--r--lib/diameter/examples/code/redirect.erl66
-rw-r--r--lib/diameter/examples/code/redirect_cb.erl62
-rw-r--r--lib/diameter/examples/code/relay.erl73
-rw-r--r--lib/diameter/examples/code/relay_cb.erl55
-rw-r--r--lib/diameter/examples/code/server.erl121
-rw-r--r--lib/diameter/examples/code/server_cb.erl101
-rw-r--r--lib/diameter/src/Makefile17
-rw-r--r--lib/diameter/src/base/diameter.erl49
-rw-r--r--lib/diameter/src/base/diameter_codec.erl4
-rw-r--r--lib/diameter/src/base/diameter_config.erl20
-rw-r--r--lib/diameter/src/base/diameter_dist.erl17
-rw-r--r--lib/diameter/src/base/diameter_peer_fsm.erl2
-rw-r--r--lib/diameter/src/base/diameter_service.erl83
-rw-r--r--lib/diameter/src/base/diameter_traffic.erl56
-rw-r--r--lib/diameter/src/diameter.appup.src22
-rw-r--r--lib/diameter/src/modules.mk5
-rw-r--r--lib/diameter/src/transport/diameter_tcp.erl6
-rw-r--r--lib/diameter/test/diameter_dist_SUITE.erl53
-rw-r--r--lib/diameter/test/diameter_event_SUITE.erl47
-rw-r--r--lib/diameter/test/diameter_examples_SUITE.erl25
-rw-r--r--lib/diameter/test/diameter_traffic_SUITE.erl18
-rw-r--r--lib/diameter/vsn.mk2
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl1
-rw-r--r--lib/hipe/test/basic_SUITE_data/basic_exceptions.erl15
-rw-r--r--lib/kernel/doc/src/erl_epmd.xml4
-rw-r--r--lib/kernel/doc/src/notes.xml4
-rw-r--r--lib/kernel/src/code_server.erl25
-rw-r--r--lib/kernel/src/logger_config.erl12
-rw-r--r--lib/kernel/src/logger_proxy.erl18
-rw-r--r--lib/kernel/test/logger_proxy_SUITE.erl14
-rw-r--r--lib/kernel/test/net_SUITE.erl2
-rw-r--r--lib/megaco/test/megaco_codec_flex_lib.erl2
-rw-r--r--lib/megaco/test/megaco_mess_SUITE.erl9
-rw-r--r--lib/megaco/test/megaco_mib_SUITE.erl166
-rw-r--r--lib/megaco/test/megaco_segment_SUITE.erl125
-rw-r--r--lib/megaco/test/megaco_test_generator.erl4
-rw-r--r--lib/megaco/test/megaco_test_lib.erl456
-rw-r--r--lib/megaco/test/megaco_test_megaco_generator.erl15
-rw-r--r--lib/megaco/test/megaco_test_tcp_generator.erl5
-rw-r--r--lib/megaco/test/megaco_trans_SUITE.erl387
-rw-r--r--lib/public_key/asn1/PKIX1Algorithms88.asn18
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl8
-rw-r--r--lib/public_key/src/public_key.erl4
-rw-r--r--lib/snmp/doc/src/snmp_agent_netif.xml4
-rw-r--r--lib/snmp/doc/src/snmp_app.xml34
-rw-r--r--lib/snmp/doc/src/snmp_config.xml38
-rw-r--r--lib/snmp/doc/src/snmp_manager_netif.xml257
-rw-r--r--lib/snmp/doc/src/snmpm.xml17
-rw-r--r--lib/snmp/doc/src/snmpm_user.xml10
-rw-r--r--lib/snmp/src/manager/snmpm.erl20
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl21
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl40
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl375
-rw-r--r--lib/snmp/src/manager/snmpm_user.erl4
-rw-r--r--lib/snmp/src/misc/snmp_verbosity.erl1
-rw-r--r--lib/snmp/src/misc/snmp_verbosity.hrl34
-rw-r--r--lib/snmp/test/Makefile12
-rw-r--r--lib/snmp/test/modules.mk10
-rw-r--r--lib/snmp/test/snmp_agent_SUITE.erl1103
-rw-r--r--lib/snmp/test/snmp_agent_conf_SUITE.erl4
-rw-r--r--lib/snmp/test/snmp_agent_mibs_SUITE.erl145
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl228
-rw-r--r--lib/snmp/test/snmp_compiler_SUITE.erl187
-rw-r--r--lib/snmp/test/snmp_conf_SUITE.erl40
-rw-r--r--lib/snmp/test/snmp_log_SUITE.erl127
-rw-r--r--lib/snmp/test/snmp_manager_SUITE.erl1352
-rw-r--r--lib/snmp/test/snmp_manager_config_SUITE.erl1135
-rw-r--r--lib/snmp/test/snmp_manager_user_SUITE.erl290
-rw-r--r--lib/snmp/test/snmp_note_store_SUITE.erl185
-rw-r--r--lib/snmp/test/snmp_pdus_SUITE.erl166
-rw-r--r--lib/snmp/test/snmp_test_lib.erl603
-rw-r--r--lib/snmp/test/snmp_test_lib.hrl61
-rw-r--r--lib/snmp/test/snmp_test_mgr.erl323
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl64
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl41
-rw-r--r--lib/ssh/doc/src/notes.xml15
-rw-r--r--lib/ssh/doc/src/ssh.xml35
-rw-r--r--lib/ssh/src/ssh.erl20
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl42
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl39
-rw-r--r--lib/ssl/src/ssl.app.src2
-rw-r--r--lib/ssl/src/ssl_connection.erl29
-rw-r--r--lib/ssl/src/ssl_handshake.erl20
-rw-r--r--lib/ssl/src/tls_connection.erl35
-rw-r--r--lib/ssl/src/tls_sender.erl4
-rw-r--r--lib/ssl/src/tls_v1.erl6
-rw-r--r--lib/ssl/test/Makefile2
-rw-r--r--lib/ssl/test/openssl_key_update_SUITE.erl134
-rw-r--r--lib/ssl/test/openssl_session_ticket_SUITE.erl409
-rw-r--r--lib/ssl/test/ssl_cipher_suite_SUITE.erl95
-rw-r--r--lib/ssl/test/ssl_key_update_SUITE.erl99
-rw-r--r--lib/ssl/test/ssl_session_SUITE.erl184
-rw-r--r--lib/ssl/test/ssl_session_ticket_SUITE.erl385
-rw-r--r--lib/ssl/test/ssl_test_lib.erl37
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml81
-rw-r--r--lib/stdlib/src/calendar.erl8
-rw-r--r--lib/stdlib/src/gen_statem.erl229
-rw-r--r--lib/stdlib/src/ms_transform.erl5
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl3
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl33
-rw-r--r--lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl14
-rw-r--r--lib/tools/src/cover.erl5
-rw-r--r--lib/tools/src/fprof.erl2
-rw-r--r--lib/tools/test/cover_SUITE.erl13
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_16476/obvious_booleans.erl17
-rw-r--r--lib/tools/test/fprof_SUITE.erl33
-rw-r--r--make/otp_version_tickets_in_merge4
-rw-r--r--otp_versions.table3
-rwxr-xr-xscripts/bundle-otp4
-rw-r--r--system/doc/design_principles/release_handling.xml4
-rw-r--r--system/doc/design_principles/statem.xml45
157 files changed, 7724 insertions, 4411 deletions
diff --git a/.travis.yml b/.travis.yml
index 51453639b0..5a87bd3fd1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -100,8 +100,8 @@ matrix:
api_key:
secure: vW5PN6zng5H5+TCvwfwpGZsABrdCWYcFwDm3KXq+plsecBmTayu/0jgNso5Z97FbzDGVTLHWchvywEYQWnmrEByyOrqH73v1LN6JEfN99VpSrdFr15IzhblcyU1R9ugYc3WEoYjX0Q1uGelDSWRuuQOPbzy8mZf3D4rSGonyraP7jPTdHhs5P3ZWk6OMFz+tCdF4XohXqbhXIBOeH/EKg0svX2u5IcV01/YOL8LHWz6G7+gqBryEXx1+ngjQXQmMQwd7Yg3WOKE4XV9gX8ixZsbpUPZXAQKF+VOYdEgeiIr1hI0tBQUYX7FYEzYH5MCxqng5RdaPTOAm1oQroyGkIcWSXzDwN4AhJ7xqa/0NRdEaBPdQzPBCc+pVUDkxBR1ytXjBQqdQMnI6184TDiU5XBnj3kmieLkkKPKQNoPve/Y8Q8zutw4GNc7gixGcQCjtAFUbrT73QVRrezQH0qIdt23rivvf2R7CCOWSmgzowrswmtHdgeEVbodUIBPTNp7qzlUk9gDp6vW0XrOC4qEFI+VaY5PsEOXrrxZmI3gGGJgsbfzRvzvvupQcLNERniJ67r/uumbForpL0x1c65scKuMWwcn1wqt2OLbDoIIuM31Ph2HX/09TTqECU7CTvqLT5MnbZHXGjY9c3ch+sY3tSfaEX6aazl/Dqx28c7boCEw=
file:
- - ${TRAVIS_TAG}-bundle.txt
- - ${TRAVIS_TAG}-bundle.tar.gz
+ - ${TRAVIS_TAG}.0-bundle.txt
+ - ${TRAVIS_TAG}.0-bundle.tar.gz
on:
# We only deploy on pushes to tags that match the regexp
tags: true
diff --git a/OTP_VERSION b/OTP_VERSION
index a5a5c04503..3abee4573a 100644
--- a/OTP_VERSION
+++ b/OTP_VERSION
@@ -1 +1 @@
-22.2.7
+22.2.8
diff --git a/erts/doc/src/alt_disco.xml b/erts/doc/src/alt_disco.xml
index 067eb4992d..d95e62bc8a 100644
--- a/erts/doc/src/alt_disco.xml
+++ b/erts/doc/src/alt_disco.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2018</year><year>2018</year>
+ <year>2018</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -22,7 +22,7 @@
</legalnotice>
- <title>How to Implement an Alternative Service Discovery for Erlang Distribution
+ <title>How to Implement an Alternative Node Discovery for Erlang Distribution
</title>
<prepared>Timmo Verlaan</prepared>
<responsible></responsible>
@@ -34,20 +34,20 @@
<file>alt_disco.xml</file>
</header>
<p>
- This section describes how to implement an alternative discovery mechanism
- for Erlang distribution. Discovery is normally done using DNS and the
- Erlang Port Mapper Daemon (EPMD) for port discovery.
+ This section describes how to implement an alternative node discovery
+ mechanism for Erlang distribution. Node discovery is normally done using DNS
+ and the Erlang Port Mapper Daemon (EPMD) for port registration and lookup.
</p>
<note><p>
- Support for alternative service discovery mechanisms was added in Erlang/OTP
+ Support for alternative node discovery mechanisms was added in Erlang/OTP
21.
</p></note>
<section>
<title>Introduction</title>
- <p>To implement your own service discovery module you have to write your own
+ <p>To implement your own node discovery module you have to write your own
EPMD module. The <seealso marker="kernel:erl_epmd">EPMD module</seealso> is
responsible for providing the location of another node. The distribution
modules (<c>inet_tcp_dist</c>/<c>inet_tls_dist</c>) call the EPMD module to
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index 311483022d..75353cbc07 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -72,6 +72,12 @@
therefore required for an Erlang network to function
correctly.</p>
+ <note><p>On Windows the maximum number of nodes allowed in one
+ epmd instance is 60. This is because of limitations in the current
+ implementation. If you need more nodes, you should look into using
+ and erlang based epmd implementation such as
+ <url href="https://github.com/erlang/epmd">Erlang EPMD</url>.</p></note>
+
<taglist>
<tag>Starting the port mapper daemon</tag>
<item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index ed1b0880b4..a37707f7f9 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -575,7 +575,11 @@
<tag><marker id="async_thread_pool_size"/><c><![CDATA[+A size]]></c></tag>
<item>
<p>Sets the number of threads in async thread pool. Valid range
- is 0-1024. Defaults to 1.</p>
+ is 0-1024. The async thread pool is used by linked-in drivers to
+ handle work that may take a very long time. Since OTP-21 there are
+ very few linked-in drivers in the default Erlang/OTP distribution
+ that uses the async thread pool. Most of them have been migrated to
+ dirty IO schedulers. Defaults to 1.</p>
</item>
<tag><c><![CDATA[+B [c | d | i]]]></c></tag>
<item>
@@ -1015,6 +1019,12 @@
executing on ordinary schedulers. If the amount of dirty CPU
schedulers was allowed to be unlimited, dirty CPU bound jobs would
potentially starve normal jobs.</p>
+ <p>Typical users of the dirty CPU schedulers are large garbage collections,
+ json protocol encode/decoders written as nifs and matrix manipulation
+ libraries.</p>
+ <p>You can use <seealso marker="runtime_tools:msacc">msacc(3)</seealso>
+ in order to see the current load of the dirty CPU schedulers threads
+ and adjust the number used accordingly.</p>
</item>
<tag><marker id="+SDPcpu"/><c><![CDATA[+SDPcpu
DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></tag>
@@ -1043,16 +1053,18 @@
<tag><marker id="+SDio"/><c><![CDATA[+SDio DirtyIOSchedulers]]></c></tag>
<item>
<p>Sets the number of dirty I/O scheduler threads to create.
- Valid range is 0-1024. By
- default, the number of dirty I/O scheduler threads created is 10,
- same as the default number of threads in the <seealso
- marker="#async_thread_pool_size">async thread pool</seealso>.</p>
+ Valid range is 1-1024. By
+ default, the number of dirty I/O scheduler threads created is 10.</p>
<p>The amount of dirty IO schedulers is not limited by the amount of
normal schedulers <seealso marker="#+SDcpu">like the amount of
dirty CPU schedulers</seealso>. This since only I/O bound work is
expected to execute on dirty I/O schedulers. If the user should schedule CPU
bound jobs on dirty I/O schedulers, these jobs might starve ordinary
jobs executing on ordinary schedulers.</p>
+ <p>Typical users of the dirty IO schedulers are reading and writing to files.</p>
+ <p>You can use <seealso marker="runtime_tools:msacc">msacc(3)</seealso>
+ in order to see the current load of the dirty IO schedulers threads
+ and adjust the number used accordingly.</p>
</item>
<tag><c><![CDATA[+sFlag Value]]></c></tag>
<item>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 7fa61d0195..48208574d1 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2018</year>
+ <year>2004</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1546,6 +1546,45 @@
</section>
+<section><title>Erts 10.3.5.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed bug in <c>ets:update_counter/4</c>, when called
+ with an invalid <c>UpdateOp</c> and a <c>Key</c> that
+ does not exist, causing <c>ets:info(T,size)</c> to return
+ incorrect values. Bug exists since OTP-19.0.2.</p>
+ <p>
+ Own Id: OTP-16404 Aux Id: ERL-1127 </p>
+ </item>
+ <item>
+ <p>
+ A process could get into an inconsistent state where it
+ was runnable, but never scheduled for execution. This
+ could occur when a mix of <c>normal</c> and <c>low</c>
+ priority processes where scheduled on the same type of
+ dirty scheduler simultaneously.</p>
+ <p>
+ Own Id: OTP-16446 Aux Id: ERL-1157 </p>
+ </item>
+ <item>
+ <p>
+ Corrected the valid range of the <c>erl</c> command line
+ argument <seealso marker="erts:erl#+SDio"><c>+SDio
+ &lt;NumberOfDirtyIoSchedulers&gt;</c></seealso> from
+ <c>0..1024</c> to <c>1..1024</c>. <c>+SDio 0</c> was
+ erroneously allowed which just caused the VM to crash on
+ the first dirty I/O job scheduled.</p>
+ <p>
+ Own Id: OTP-16481</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 10.3.5.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -3865,7 +3904,7 @@
marker="kernel:erl_epmd"><c>erl_epmd</c></seealso>
reference manual and ERTS User's Guide <seealso
marker="erts:alt_disco">How to Implement an Alternative
- Service Discovery for Erlang Distribution</seealso>.</p>
+ Node Discovery for Erlang Distribution</seealso>.</p>
<p>
Own Id: OTP-15086 Aux Id: PR-1694 </p>
</item>
@@ -3874,6 +3913,69 @@
</section>
+<section><title>Erts 9.3.3.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A process could end up in a state where it got endlessly
+ rescheduled without making any progress. This occurred
+ when a system task, such as check of process code (part
+ of a code purge), was scheduled on a high priority
+ process trying to execute on a dirty scheduler.</p>
+ <p>
+ Own Id: OTP-16436 Aux Id: ERL-1152 </p>
+ </item>
+ <item>
+ <p>
+ Fixed bug in <c>erlang:list_to_ref/1</c> when called with
+ a reference created by a remote note. Function
+ <c>list_to_ref/1</c> is intended for debugging and not to
+ be used in application programs. Bug exist since OTP
+ 20.0.</p>
+ <p>
+ Own Id: OTP-16438</p>
+ </item>
+ <item>
+ <p>
+ A process could get into an inconsistent state where it
+ was runnable, but never scheduled for execution. This
+ could occur when a mix of <c>normal</c> and <c>low</c>
+ priority processes where scheduled on the same type of
+ dirty scheduler simultaneously.</p>
+ <p>
+ Own Id: OTP-16446 Aux Id: ERL-1157 </p>
+ </item>
+ <item>
+ <p>
+ Fixed erroneous mapping of exit reason from <c>kill</c>
+ to <c>killed</c> on reception of some exit signals due to
+ a broken link. This bug has existed since ERTS version
+ 5.5.2 (OTP R11).</p>
+ <p>
+ This bug was also unknowingly fixed in ERTS version 10.0
+ (OTP 21.0) due to a new ERTS internal implementation of
+ signaling between processes.</p>
+ <p>
+ Own Id: OTP-16465 Aux Id: ERL-1165, OTP-6160, OTP-14589 </p>
+ </item>
+ <item>
+ <p>
+ Corrected the valid range of the <c>erl</c> command line
+ argument <seealso marker="erts:erl#+SDio"><c>+SDio
+ &lt;NumberOfDirtyIoSchedulers&gt;</c></seealso> from
+ <c>0..1024</c> to <c>1..1024</c>. <c>+SDio 0</c> was
+ erroneously allowed which just caused the VM to crash on
+ the first dirty I/O job scheduled.</p>
+ <p>
+ Own Id: OTP-16481</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 9.3.3.14</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 6379e4e04d..c1af14cc89 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -578,8 +578,8 @@ do_break(void)
ASSERT(erts_thr_progress_is_blocking());
erts_printf("\n"
- "BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded\n"
- " (v)ersion (k)ill (D)b-tables (d)istribution\n");
+ "BREAK: (a)bort (A)bort with dump (c)ontinue (p)roc info (i)nfo\n"
+ " (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution\n");
while (1) {
if ((i = sys_get_key(0)) <= 0)
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 547e4064a2..5f0352f5c0 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -694,7 +694,7 @@ void erts_usage(void)
erts_fprintf(stderr, "-SDPcpu p1:p2 specify dirty CPU schedulers (p1) and dirty CPU schedulers\n");
erts_fprintf(stderr, " online (p2) as percentages of logical processors configured\n");
erts_fprintf(stderr, " and logical processors available, respectively\n");
- erts_fprintf(stderr, "-SDio n set number of dirty I/O schedulers, valid range is [0-%d]\n",
+ erts_fprintf(stderr, "-SDio n set number of dirty I/O schedulers, valid range is [1-%d]\n",
ERTS_MAX_NO_OF_DIRTY_IO_SCHEDULERS);
erts_fprintf(stderr, "-t size set the maximum number of atoms the emulator can handle\n");
erts_fprintf(stderr, " valid range is [%d-%d]\n",
@@ -1054,7 +1054,7 @@ early_init(int *argc, char **argv) /*
} else if (sys_strncmp(type, "io", 2) == 0) {
arg = get_arg(argv[i]+5, argv[i+1], &i);
dirty_io_scheds = atoi(arg);
- if (dirty_io_scheds < 0 ||
+ if (dirty_io_scheds < 1 ||
dirty_io_scheds > ERTS_MAX_NO_OF_DIRTY_IO_SCHEDULERS) {
erts_fprintf(stderr,
"bad number of dirty I/O schedulers %s\n",
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index ab95748458..fbda73d518 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -6770,7 +6770,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env,
if ((argc != 4) ||
!GET_BIN(env, argv[2], &sndData) ||
!GET_UINT(env, argv[3], &eflags)) {
- SSDBG( descP, ("SOCKET", "nif_send -> argv decode failed\r\n") );
+ SGDBG( ("SOCKET", "nif_send -> argv decode failed\r\n") );
return enif_make_badarg(env);
}
sockRef = argv[0]; // We need this in case we send in case we send abort
@@ -6909,7 +6909,7 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env,
if ((argc != 5) ||
!GET_BIN(env, argv[2], &sndData) ||
!GET_UINT(env, argv[4], &eflags)) {
- SSDBG( descP, ("SOCKET", "nif_sendto -> argv decode failed\r\n") );
+ SGDBG( ("SOCKET", "nif_sendto -> argv decode failed\r\n") );
return enif_make_badarg(env);
}
sockRef = argv[0]; // We need this in case we send abort (to the caller)
@@ -7047,7 +7047,7 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env,
if ((argc != 4) ||
!IS_MAP(env, argv[2]) ||
!GET_UINT(env, argv[3], &eflags)) {
- SSDBG( descP, ("SOCKET", "nif_sendmsg -> argv decode failed\r\n") );
+ SGDBG( ("SOCKET", "nif_sendmsg -> argv decode failed\r\n") );
return enif_make_badarg(env);
}
sockRef = argv[0]; // We need this in case we send abort (to the caller)
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index bce4ae1a5f..a263ac87bc 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -2234,6 +2234,25 @@ analyze_and_print_freebsd_host_info(Version) ->
+init_per_group(GroupName, Config)
+ when (GroupName =:= sc_remote_close) orelse
+ (GroupName =:= sc_remote_shutdown) orelse
+ (GroupName =:= traffic) ->
+ io:format("init_per_group(~w) -> entry with"
+ "~n Config: ~p"
+ "~n", [GroupName, Config]),
+ %% Maybe we should skip the entire suite for this platform,
+ %% but for now we just skip these groups, which seem to
+ %% have problems (slave node start).
+ %% As stated elsewhere, its not really Fedora 16, but
+ %% the *really* slow VM that is the issue.
+ try is_old_fedora16() of
+ ok ->
+ Config
+ catch
+ throw:{skip, _} = SKIP ->
+ SKIP
+ end;
init_per_group(ttest = _GroupName, Config) ->
io:format("init_per_group(~w) -> entry with"
"~n Config: ~p"
@@ -24427,7 +24446,9 @@ sc_lc_recvfrom_response_udpL(_Config) when is_list(_Config) ->
tc_try(sc_lc_recvfrom_response_udpL,
fun() -> has_support_unix_domain_socket() end,
fun() ->
- Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ Recv = fun(Sock, To) ->
+ socket:recvfrom(Sock, [], To)
+ end,
InitState = #{domain => local,
protocol => default,
recv => Recv},
@@ -24461,8 +24482,20 @@ sc_lc_receive_response_udp(InitState) ->
#{desc => "open socket",
cmd => fun(#{domain := Domain, protocol := Proto} = State) ->
Sock = sock_open(Domain, dgram, Proto),
- SA = sock_sockname(Sock),
- {ok, State#{sock => Sock, sa => SA}}
+ %% SA = sock_sockname(Sock),
+ case socket:sockname(Sock) of
+ {ok, SA} ->
+ {ok, State#{sock => Sock, sa => SA}};
+ {error, eafnosupport = Reason} ->
+ ?SEV_IPRINT("Failed get socket name: "
+ "~n ~p", [Reason]),
+ (catch socket:close(Sock)),
+ {skip, Reason};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Failed get socket name: "
+ "~n ~p", [Reason]),
+ ERROR
+ end
end},
#{desc => "bind socket",
cmd => fun(#{sock := Sock, local_sa := LSA}) ->
diff --git a/erts/emulator/test/socket_test_lib.erl b/erts/emulator/test/socket_test_lib.erl
index 39cbf0c79f..f05796cbcf 100644
--- a/erts/emulator/test/socket_test_lib.erl
+++ b/erts/emulator/test/socket_test_lib.erl
@@ -194,49 +194,34 @@ which_local_host_info(Domain) ->
which_local_host_info(_Domain, []) ->
{error, no_address};
-which_local_host_info(Domain, [{"lo" ++ _, _}|IFL]) ->
- which_local_host_info(Domain, IFL);
which_local_host_info(Domain, [{"docker" ++ _, _}|IFL]) ->
which_local_host_info(Domain, IFL);
which_local_host_info(Domain, [{"br-" ++ _, _}|IFL]) ->
which_local_host_info(Domain, IFL);
which_local_host_info(Domain, [{Name, IFO}|IFL]) ->
- try which_local_host_info2(Domain, IFO) of
- Info ->
- {ok, Info#{name => Name}}
- catch
- throw:_:_ ->
+ case if_is_running_and_not_loopback(IFO) of
+ true ->
+ try which_local_host_info2(Domain, IFO) of
+ Info ->
+ {ok, Info#{name => Name}}
+ catch
+ throw:_:_ ->
+ which_local_host_info(Domain, IFL)
+ end;
+ false ->
which_local_host_info(Domain, IFL)
end;
which_local_host_info(Domain, [_|IFL]) ->
which_local_host_info(Domain, IFL).
-%% which_local_host_info2(Domain, IFO) ->
-%% case lists:keysearch(flags, 1, IFO) of
-%% {value, {flags, Flags}} ->
-%% which_local_host_info2(Domain, IFO, Flags);
-%% false ->
-%% {error, no_flags}
-%% end.
-
-
-%% which_local_host_info2(_Domain, [], _Flags) ->
-%% {error, no_address};
-%% which_local_host_info2(inet = _Domain, [{addr, Addr}|_IFO], Flags)
-%% when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) ->
-%% {ok, {Flags, Addr}};
-%% which_local_host_info2(inet6 = _Domain, [{addr, Addr}|_IFO], Flags)
-%% when (size(Addr) =:= 8) andalso
-%% (element(1, Addr) =/= 0) andalso
-%% (element(1, Addr) =/= 16#fe80) ->
-%% {ok, {Flags, Addr}};
-%% which_local_host_info2(Domain, [_|IFO], Flags) ->
-%% which_local_host_info2(Domain, IFO, Flags).
-
-%% foo(Info, inet = Domain, IFO) ->
-%% foo(Info, Domain, IFO, [flags, addr, netmask, broadaddr, hwaddr]);
-%% foo(Info, inet6 = Domain, IFO) ->
-%% foo(Info, Domain, IFO, [flags, addr, netmask, hwaddr]).
+if_is_running_and_not_loopback(If) ->
+ lists:keymember(flags, 1, If) andalso
+ begin
+ {value, {flags, Flags}} = lists:keysearch(flags, 1, If),
+ (not lists:member(loopback, Flags)) andalso
+ lists:member(running, Flags)
+ end.
+
which_local_host_info2(inet = _Domain, IFO) ->
Addr = which_local_host_info3(addr, IFO,
diff --git a/erts/preloaded/ebin/atomics.beam b/erts/preloaded/ebin/atomics.beam
index 610264de8f..aa246f8808 100644
--- a/erts/preloaded/ebin/atomics.beam
+++ b/erts/preloaded/ebin/atomics.beam
Binary files differ
diff --git a/erts/preloaded/ebin/counters.beam b/erts/preloaded/ebin/counters.beam
index df4a3dce2d..1fb85276f9 100644
--- a/erts/preloaded/ebin/counters.beam
+++ b/erts/preloaded/ebin/counters.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_init.beam b/erts/preloaded/ebin/erl_init.beam
index 511f38624d..04559ff767 100644
--- a/erts/preloaded/ebin/erl_init.beam
+++ b/erts/preloaded/ebin/erl_init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 7723e420fe..b8adf71297 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erl_tracer.beam b/erts/preloaded/ebin/erl_tracer.beam
index 18a06a7446..4430489710 100644
--- a/erts/preloaded/ebin/erl_tracer.beam
+++ b/erts/preloaded/ebin/erl_tracer.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 1f8d94d547..b744d97a41 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_code_purger.beam b/erts/preloaded/ebin/erts_code_purger.beam
index 16b1930635..a94b37854e 100644
--- a/erts/preloaded/ebin/erts_code_purger.beam
+++ b/erts/preloaded/ebin/erts_code_purger.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam b/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
index b67b682a6d..dd92fb9582 100644
--- a/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
+++ b/erts/preloaded/ebin/erts_dirty_process_signal_handler.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index bf5193729b..d52ae9a2dc 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_literal_area_collector.beam b/erts/preloaded/ebin/erts_literal_area_collector.beam
index 72d347f401..44103e5d56 100644
--- a/erts/preloaded/ebin/erts_literal_area_collector.beam
+++ b/erts/preloaded/ebin/erts_literal_area_collector.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index be3036d4f2..06074d1717 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/persistent_term.beam b/erts/preloaded/ebin/persistent_term.beam
index bb889f181e..dc4a1aceb5 100644
--- a/erts/preloaded/ebin/persistent_term.beam
+++ b/erts/preloaded/ebin/persistent_term.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_buffer.beam b/erts/preloaded/ebin/prim_buffer.beam
index e7c8adf589..a54a956fac 100644
--- a/erts/preloaded/ebin/prim_buffer.beam
+++ b/erts/preloaded/ebin/prim_buffer.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam
index 6b3e0220cc..7b39f3e5ba 100644
--- a/erts/preloaded/ebin/prim_eval.beam
+++ b/erts/preloaded/ebin/prim_eval.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index d4cb52e5a8..d0ef080a30 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 2293728375..197ff59503 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_net.beam b/erts/preloaded/ebin/prim_net.beam
index 02dea609fa..76d4f0fc69 100644
--- a/erts/preloaded/ebin/prim_net.beam
+++ b/erts/preloaded/ebin/prim_net.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index bcdd836d5b..75413bb065 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 1cffd45f05..1a5f34f3ee 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/ebin/socket_registry.beam b/erts/preloaded/ebin/socket_registry.beam
index 9e055cbe48..a5eb2c190f 100644
--- a/erts/preloaded/ebin/socket_registry.beam
+++ b/erts/preloaded/ebin/socket_registry.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 16bc893d41..14558a7424 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 1605c20f2c..658a138694 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -300,12 +300,18 @@ check_file_result(Func, Target, {error,Reason}) ->
%% This is equal to calling logger:error/2 which
%% we don't want to do from code_server during system boot.
%% We don't want to call logger:timestamp() either.
- logger ! {log,error,#{label=>{?MODULE,file_error},report=>Report},
- #{pid=>self(),
- gl=>group_leader(),
- time=>os:system_time(microsecond),
- error_logger=>#{tag=>error_report,
- type=>std_error}}},
+ _ = try
+ logger ! {log,error,#{label=>{?MODULE,file_error},report=>Report},
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>os:system_time(microsecond),
+ error_logger=>#{tag=>error_report,
+ type=>std_error}}}
+ catch _:_ ->
+ %% If logger has not been started yet we just display it
+ erlang:display({?MODULE,file_error}),
+ erlang:display(Report)
+ end,
error
end;
check_file_result(_, _, Other) ->
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 1aa5d85c64..f241be8569 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -575,11 +575,11 @@ list_dir_convert([RawName | Rest], SkipInvalid, Result) ->
%% This is equal to calling logger:warning/3 which
%% we don't want to do from code_server during system boot.
%% We don't want to call logger:timestamp() either.
- logger ! {log,warning,"Non-unicode filename ~p ignored\n", [RawName],
- #{pid=>self(),
- gl=>group_leader(),
- time=>os:system_time(microsecond),
- error_logger=>#{tag=>warning_msg}}},
+ catch logger ! {log,warning,"Non-unicode filename ~p ignored\n", [RawName],
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>os:system_time(microsecond),
+ error_logger=>#{tag=>warning_msg}}},
list_dir_convert(Rest, SkipInvalid, Result);
{error, _} ->
{error, {no_translation, RawName}}
diff --git a/lib/compiler/src/beam_ssa_bsm.erl b/lib/compiler/src/beam_ssa_bsm.erl
index cb36f1c242..d950ef58ec 100644
--- a/lib/compiler/src/beam_ssa_bsm.erl
+++ b/lib/compiler/src/beam_ssa_bsm.erl
@@ -520,20 +520,29 @@ cm_register_prior(Src, DstCtx, Lbl, State) ->
State#cm{ prior_matches = PriorMatches }.
cm_combine_tail(Src, DstCtx, Bool, Acc, State0) ->
- SrcCtx = match_context_of(Src, State0#cm.definitions),
+ SrcCtx0 = match_context_of(Src, State0#cm.definitions),
+
+ {SrcCtx, Renames} = cm_combine_tail_1(Bool, DstCtx, SrcCtx0,
+ State0#cm.renames),
%% We replace the source with a context alias as it normally won't be used
%% on the happy path after being matched, and the added cost of conversion
%% is negligible if it is.
Aliases = maps:put(Src, {0, SrcCtx}, State0#cm.match_aliases),
-
- Renames0 = State0#cm.renames,
- Renames = Renames0#{ Bool => #b_literal{val=true}, DstCtx => SrcCtx },
-
State = State0#cm{ match_aliases = Aliases, renames = Renames },
{Acc, State}.
+cm_combine_tail_1(Bool, DstCtx, SrcCtx, Renames0) ->
+ case Renames0 of
+ #{ SrcCtx := New } ->
+ cm_combine_tail_1(Bool, DstCtx, New, Renames0);
+ #{} ->
+ Renames = Renames0#{ Bool => #b_literal{val=true},
+ DstCtx => SrcCtx },
+ {SrcCtx, Renames}
+ end.
+
%% Lets functions accept match contexts as arguments. The parameter must be
%% unused before the bs_start_match instruction, and it must be matched in the
%% first block.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index a789b82910..2e91f7b53e 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -45,7 +45,8 @@
expression_before_match/1,erl_689/1,restore_on_call/1,
restore_after_catch/1,matches_on_parameter/1,big_positions/1,
matching_meets_apply/1,bs_start_match2_defs/1,
- exceptions_after_match_failure/1, bad_phi_paths/1]).
+ exceptions_after_match_failure/1, bad_phi_paths/1,
+ combine_empty_segments/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -82,7 +83,8 @@ groups() ->
expression_before_match,erl_689,restore_on_call,
matches_on_parameter,big_positions,
matching_meets_apply,bs_start_match2_defs,
- exceptions_after_match_failure,bad_phi_paths]}].
+ exceptions_after_match_failure,bad_phi_paths,
+ combine_empty_segments]}].
init_per_suite(Config) ->
@@ -2033,4 +2035,14 @@ bad_phi_paths_1(Arg) ->
end,
id(B).
+combine_empty_segments(_Config) ->
+ <<0,1,2,3>> = combine_empty_segments_1(<<0,1,2,3>>),
+ ok.
+
+combine_empty_segments_1(A) ->
+ <<B/bits>> = A,
+ <<C/bits>> = B,
+ <<D/bits>> = C,
+ D.
+
id(I) -> I.
diff --git a/lib/crypto/test/crypto_bench_SUITE.erl b/lib/crypto/test/crypto_bench_SUITE.erl
index c66a27f0c8..d738902ac8 100644
--- a/lib/crypto/test/crypto_bench_SUITE.erl
+++ b/lib/crypto/test/crypto_bench_SUITE.erl
@@ -67,7 +67,7 @@ init_per_suite(Config0) ->
calibrate([{sec_goal,10} | Config1])
catch _:_ ->
- {fail, "Crypto did not start"}
+ {skip, "Crypto did not start"}
end.
end_per_suite(_Config) ->
diff --git a/lib/crypto/test/crypto_property_test_SUITE.erl b/lib/crypto/test/crypto_property_test_SUITE.erl
index 18977f733a..bcfd5d3de1 100644
--- a/lib/crypto/test/crypto_property_test_SUITE.erl
+++ b/lib/crypto/test/crypto_property_test_SUITE.erl
@@ -31,7 +31,21 @@ all() -> [encrypt_decrypt_one_time,
%%% First prepare Config and compile the property tests for the found tool:
init_per_suite(Config) ->
- ct_property_test:init_per_suite(Config).
+ case
+ try crypto:start() of
+ ok -> true;
+ {error, already_started} -> true;
+ _ -> false
+ catch
+ _:_ -> false
+ end
+ of
+ true ->
+ ct_property_test:init_per_suite(Config);
+ false ->
+ {skip, "Crypto did not start"}
+ end.
+
end_per_suite(Config) ->
Config.
diff --git a/lib/crypto/test/engine_SUITE.erl b/lib/crypto/test/engine_SUITE.erl
index 41cd132734..572f86e3c9 100644
--- a/lib/crypto/test/engine_SUITE.erl
+++ b/lib/crypto/test/engine_SUITE.erl
@@ -80,7 +80,7 @@ groups() ->
init_per_suite(Config) ->
- case {os:type(), crypto:info_lib()} of
+ try {os:type(), crypto:info_lib()} of
{_, [{_,_, <<"OpenSSL 1.0.1s-freebsd 1 Mar 2016">>}]} ->
{skip, "Problem with engine on OpenSSL 1.0.1s-freebsd"};
@@ -100,6 +100,8 @@ init_per_suite(Config) ->
catch _:_ ->
{skip, "Crypto did not start"}
end
+ catch _:_ ->
+ {skip, "Crypto not loaded"}
end.
end_per_suite(_Config) ->
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index 85522c99b2..aa4eb6ad45 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -23,7 +23,7 @@
<copyright>
<year>2011</year>
-<year>2019</year>
+<year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1046,8 +1046,9 @@ each node from which requests are sent.</p>
<tag><c>&transport_opt;</c></tag>
<item>
<p>
-Any transport option except <c>applications</c> or
-<c>capabilities</c>.
+Any transport option except <c>applications</c>,
+<c>capabilities</c>, <c>transport_config</c>, and
+<c>transport_module</c>.
Used as defaults for transport configuration, values passed to
&add_transport; overriding values configured on the service.</p>
</item>
@@ -1398,10 +1399,11 @@ Options <c>monitor</c> and <c>link</c> are ignored in the list-valued
case.
An MFA is applied with an additional term prepended to its argument
list, and should return either the pid of the handler process that
-invokes <c>diameter_traffic:request/1</c> on the term in order to
+invokes <c>diameter_traffic:request/1</c> on the argument in order to
process the request, or the atom <c>discard</c>.
-The handler process need not be local, but diameter must be started on
-the remote node.</p>
+The handler process need not be local, and diameter need not be
+started on the remote node, but diameter and relevant application
+callbacks must be on the code path.</p>
<p>
Defaults to the empty list.</p>
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index 8dcba93273..780b0b894a 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -43,6 +43,57 @@ first.</p>
<!-- ===================================================================== -->
+<section><title>diameter 2.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The possibility of choosing a handler process for an
+ incoming Diameter request with a configured MFA was
+ documented in OTP 20.0, but counters (with
+ {traffic_counters, true}) were not incremented when this
+ process was on a remote node. Counters are now
+ incremented on the node that configures the transport in
+ question.</p>
+ <p>
+ Introduced in OTP 21.3.</p>
+ <p>
+ Own Id: OTP-16457</p>
+ </item>
+ <item>
+ <p>
+ Transport options differing from those passed to
+ diameter:add_transport/2 were used in several situations:
+ when starting a transport process after connect_timer
+ expiry after an initial connection attempt has failed,
+ when starting a transport process after a connection has
+ been accepted, when sending events, when returning
+ options in diameter:service_info/2, and possibly more. In
+ particular, the following configuration options to
+ diameter:add_transport/2 were dropped: avp_dictionaries,
+ incoming_maxlen, spawn_opt, strict_mbit.</p>
+ <p>
+ Moreover, any service options mistakenly passed to
+ diameter:add_transport/2 were interpreted as such,
+ instead of being ignored as the documentation states,
+ with the consequence that outgoing and incoming requests
+ saw different values of some options, some were always
+ taken from transport options, and others from service
+ options.</p>
+ <p>
+ diameter:add_transport/2 must be called in new code for
+ the fix to have effect.</p>
+ <p>
+ Introduced in OTP 20.1.</p>
+ <p>
+ Own Id: OTP-16459</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>diameter 2.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/diameter/examples/code/GNUmakefile b/lib/diameter/examples/code/GNUmakefile
index f5c2e5f869..9efb966e65 100644
--- a/lib/diameter/examples/code/GNUmakefile
+++ b/lib/diameter/examples/code/GNUmakefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2015. All Rights Reserved.
+# Copyright Ericsson AB 2010-2020. 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.
@@ -18,10 +18,10 @@
# %CopyrightEnd%
#
-EXAMPLES = client server relay # redirect proxy
+EXAMPLES = client server relay redirect # proxy
CALLBACKS = $(EXAMPLES:%=%_cb)
-MODULES = node $(EXAMPLES) $(EXAMPLES:%=%_cb)
+MODULES = $(EXAMPLES) $(EXAMPLES:%=%_cb)
BEAM = $(MODULES:%=%.beam)
diff --git a/lib/diameter/examples/code/README b/lib/diameter/examples/code/README
new file mode 100644
index 0000000000..b639849390
--- /dev/null
+++ b/lib/diameter/examples/code/README
@@ -0,0 +1,105 @@
+
+This directory contains small examples of simple Diameter nodes. They
+don't do everything a real node should do obviously, but they're a
+starting point.
+
+Each example consists of an interface module with functions to start
+and stop a service and add transport, and a corresponding callback
+module for the Diameter application the service configures. A real
+node might support multiple Diameter applications, either with the
+same callback or sharing a common callback, maybe using extra
+arguments to distinguish between callbacks for the different
+applications.
+
+The interface functions are named start, stop, connect, and listen;
+the client example also has a call function that sends an example
+message. Service names should be atoms in these modules (since the
+default setting of Origin-Host assumes this), but doesn't need to be
+in general. Options are passed directly to diameter:start_service/2
+and diameter:add_transport/2, with some additional convenience options
+for the latter; in particular, the atoms tcp and sctp to connect to or
+listen on default endpoints (127.0.01:3868), or tuples with protocol
+and another endpoint {eg. {tcp, {192,168,1,5}, 3869}. This convenience
+makes the simplest usage like this in an Erlang shell:
+
+ diameter:start().
+ server:start().
+ server:listen(tcp).
+ client:start().
+ client:connect(tcp).
+ client:call().
+
+Or put a relay between the client and server:
+
+ diameter:start().
+ server:start().
+ server:listen(sctp).
+ relay:start().
+ relay:connect(sctp).
+ relay:listen(tcp).
+ client:start().
+ client:connect(tcp).
+ client:call().
+
+Most services should probably set the following options, which have
+been added to solve various problems over the years, while the
+defaults have not been changed for backwards compatibility.
+
+ {decode_format, map}
+
+ Provide decoded messages in #diameter_packet.msg of a
+ handle_request or handle_answer callback in the form [Name | Avps],
+ where Name is the atom() name of the message in the (Diameter)
+ application dictionary in question (eg. 'ACR') and Avps is a map
+ of AVP values. This avoids compile-time dependencies on the
+ generated records and their (generally) long-winded names. The
+ hrl files generated from dictionaries are best avoided.
+
+ {restrict_connections, false}
+
+ Accept multiple connections with the same peer. By default,
+ diameter will only accept a single connection with a given peer,
+ which the Diameter RFC can be interpreted as requiring. In
+ practice, wanting multiple connections to the same peer is
+ common.
+
+ {string_decode, false}
+
+ Disable the decoding of string-ish Diameter types to Erlang
+ strings, leaving them as binary(). Strings can be costly if
+ decoded Diameter messages are passed between processes.
+
+ {strict_mbit, false}
+
+ Relax the interpretation of the M-bit so that an AVP setting
+ this bit is not regarded as a 5001 error when the message
+ grammar in question doesn't explicitly list the AVP. Without
+ this, a Redirect-Host AVP received in a 3006
+ (DIAMETER_REDIRECT_INDICATION) answer-message from a redirect
+ agent will be treated as error, and there have been other
+ situations in which the default value has caused problems (or at
+ least surprise).
+
+ {call_mutates_state, false} (on each configured application)
+
+ Avoid pick_peer and subsequent callbacks going through a single
+ process, which can be a bottleneck. Better to use the tid() of
+ an ets table as (immutable) state, for example.
+
+Other options that are particularly useful/necessary in some
+situations are:
+
+ pool_size - Create a pool of accepting processes for a listening
+ transport, to avoid refused connections when many peers
+ connect simultaneously. Can also be used on a connecting
+ transport to establish multiple connections with a
+ single call to diameter:add_transport/2.
+
+ sequence - Ensure unique End-to-End and Hop-by-Hop identifiers over
+ a cluster of Erlang nodes.
+
+ share_peers - Share peer connections across a cluster of
+ use_shared_peers Erlang nodes.
+
+ spawn_opt - Replace diameter's spawning of a new handler process for
+ each request by something else: diameter_dist is an example.
diff --git a/lib/diameter/examples/code/client.erl b/lib/diameter/examples/code/client.erl
index 0864919cdd..04c91e37fa 100644
--- a/lib/diameter/examples/code/client.erl
+++ b/lib/diameter/examples/code/client.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -18,120 +18,173 @@
%% %CopyrightEnd%
%%
+-module(client).
+
%%
-%% An example Diameter client that can sends base protocol RAR
+%% An example Diameter client that can sends base protocol ACR
%% requests to a connected peer.
%%
-%% The simplest usage is as follows this to connect to a server
-%% listening on the default port on the local host, assuming diameter
-%% is already started (eg. diameter:start()).
+%% Simplest usage to connect to a server listening on TCP at
+%% 127.0.0.1:3868:
%%
%% client:start().
%% client:connect(tcp).
%% client:call().
%%
-%% The first call starts the a service with the default name of
-%% ?MODULE, the second defines a connecting transport that results in
-%% a connection to the peer (if it's listening), the third sends it a
-%% RAR and returns the answer.
-%%
-
--module(client).
-
--include_lib("diameter/include/diameter.hrl").
-export([start/1, %% start a service
start/2, %%
connect/2, %% add a connecting transport
- call/1, %% send using the record encoding
- cast/1, %% send using the list encoding and detached
+ call/2, %% send a request
stop/1]). %% stop a service
-%% A real application would typically choose an encoding and whether
-%% they want the call to return the answer or not. Sending with
-%% both the record and list encoding here, one detached and one not,
-%% is just for demonstration purposes.
%% Convenience functions using the default service name.
-export([start/0,
connect/1,
stop/0,
call/0,
- cast/0]).
+ call/1]).
-define(DEF_SVC_NAME, ?MODULE).
-define(L, atom_to_list).
+-define(LOOPBACK, {127,0,0,1}).
-%% The service configuration. As in the server example, a client
-%% supporting multiple Diameter applications may or may not want to
-%% configure a common callback module on all applications.
+%% Service configuration.
-define(SERVICE(Name), [{'Origin-Host', ?L(Name) ++ ".example.com"},
{'Origin-Realm', "example.com"},
{'Vendor-Id', 0},
{'Product-Name', "Client"},
{'Auth-Application-Id', [0]},
- {string_decode, false},
{decode_format, map},
+ {restrict_connections, false},
+ {strict_mbit, false},
+ {string_decode, false},
{application, [{alias, common},
{dictionary, diameter_gen_base_rfc6733},
- {module, client_cb}]}]).
+ {module, client_cb},
+ {answer_errors, callback},
+ {call_mutates_state, false}]}]).
-%% start/1
+%% start/2
-start(Name)
- when is_atom(Name) ->
- start(Name, []);
+start(Name, Opts) ->
+ Defaults = [T || {K,_} = T <- ?SERVICE(Name),
+ not lists:keymember(K, 1, Opts)],
+ diameter:start_service(Name, Opts ++ Defaults).
-start(Opts)
- when is_list(Opts) ->
+%% start/1
+
+start(Opts) ->
start(?DEF_SVC_NAME, Opts).
%% start/0
start() ->
- start(?DEF_SVC_NAME).
+ start(?DEF_SVC_NAME, []).
-%% start/2
+%% connect/1
-start(Name, Opts) ->
- node:start(Name, Opts ++ [T || {K,_} = T <- ?SERVICE(Name),
- false == lists:keymember(K, 1, Opts)]).
+connect(Opts) ->
+ connect(?DEF_SVC_NAME, Opts).
%% connect/2
+connect(Name, Opts)
+ when is_list(Opts) ->
+ diameter:add_transport(Name, {connect, lists:flatmap(fun opts/1, Opts)});
+
+%% backwards compatibility with old config
+connect(Name, {T, Opts}) ->
+ connect(Name, [T | Opts]);
connect(Name, T) ->
- node:connect(Name, T).
+ connect(Name, [T]).
-connect(T) ->
- connect(?DEF_SVC_NAME, T).
+%% call/2
-%% call/1
+call(Name, #{'Session-Id' := _} = Avps) ->
+ Defaults = #{'Destination-Realm' => "example.com",
+ 'Accounting-Record-Type' => 1, %% EVENT_RECORD
+ 'Accounting-Record-Number' => 0},
+ ACR = ['ACR' | maps:merge(Defaults, Avps)],
+ diameter:call(Name, common, ACR, []);
-call(Name) ->
- SId = diameter:session_id(?L(Name)),
- RAR = ['RAR' | #{'Session-Id' => SId,
- 'Auth-Application-Id' => 0,
- 'Re-Auth-Request-Type' => 0}],
- diameter:call(Name, common, RAR, []).
+call(Name, #{} = Avps) ->
+ call(Name, Avps#{'Session-Id' => diameter:session_id(?L(Name))});
-call() ->
- call(?DEF_SVC_NAME).
+call(Name, Avps) ->
+ call(Name, maps:from_list(Avps)).
-%% cast/1
+%% call/1
+
+call(Avps) ->
+ call(?DEF_SVC_NAME, Avps).
-cast(Name) ->
- SId = diameter:session_id(?L(Name)),
- RAR = ['RAR', {'Session-Id', SId},
- {'Auth-Application-Id', 0},
- {'Re-Auth-Request-Type', 1}],
- diameter:call(Name, common, RAR, [detach]).
+%% call/0
-cast() ->
- cast(?DEF_SVC_NAME).
+call() ->
+ call(?DEF_SVC_NAME, #{}).
%% stop/1
stop(Name) ->
- node:stop(Name).
+ diameter:stop_service(Name).
stop() ->
stop(?DEF_SVC_NAME).
+
+%% ===========================================================================
+
+%% opts/1
+%%
+%% Map some terms to transport_module/transport_config pairs as a
+%% convenience, pass everything else unmodified.
+
+opts(T)
+ when T == any;
+ T == tcp;
+ T == sctp ->
+ opts({T, loopback, 3868});
+
+opts({T, RA, RP}) ->
+ opts({T, [], RA, RP});
+
+opts({T, loopback, RA, RP}) ->
+ opts({T, ?LOOPBACK, RA, RP});
+
+opts({T, LA, RA, RP})
+ when is_tuple(LA) ->
+ opts({T, [{ip, LA}], RA, RP});
+
+opts({any, Opts, RA, RP}) ->
+ All = Opts ++ opts(RA, RP),
+ [{transport_module, diameter_sctp},
+ {transport_config, All, 2000},
+ {transport_module, diameter_tcp},
+ {transport_config, All}];
+
+opts({tcp, Opts, RA, RP}) ->
+ opts({diameter_tcp, Opts, RA, RP});
+
+opts({sctp, Opts, RA, RP}) ->
+ opts({diameter_sctp, Opts, RA, RP});
+
+opts({Mod, Opts, loopback, RP}) ->
+ opts({Mod, Opts, ?LOOPBACK, RP});
+
+opts({Mod, Opts, RA, default}) ->
+ opts({Mod, Opts, RA, 3868});
+
+opts({Mod, Opts, RA, RP}) ->
+ [{transport_module, Mod},
+ {transport_config, opts(RA, RP) ++ Opts}];
+
+opts(T) ->
+ [T].
+
+%% opts/2
+
+opts(loopback, RP) ->
+ opts(?LOOPBACK, RP);
+
+opts(RA, RP) ->
+ [{raddr, RA}, {rport, RP}, {reuseaddr, true}].
diff --git a/lib/diameter/examples/code/client_cb.erl b/lib/diameter/examples/code/client_cb.erl
index af2d4d6da7..7721c47a9a 100644
--- a/lib/diameter/examples/code/client_cb.erl
+++ b/lib/diameter/examples/code/client_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -21,7 +21,6 @@
-module(client_cb).
-include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
%% diameter callbacks
-export([peer_up/3,
@@ -50,28 +49,16 @@ pick_peer([Peer | _], _, _SvcName, _State) ->
%% prepare_request/3
-prepare_request(#diameter_packet{msg = ['RAR' = T | Avps]}, _, {_, Caps}) ->
- #diameter_caps{origin_host = {OH, DH},
- origin_realm = {OR, DR}}
+prepare_request(#diameter_packet{msg = [Name | Avps]}, _, {_, Caps}) ->
+ #diameter_caps{origin_host = {OH, _},
+ origin_realm = {OR, _}}
= Caps,
-
- {send, [T | if is_map(Avps) ->
- Avps#{'Origin-Host' => OH,
- 'Origin-Realm' => OR,
- 'Destination-Host' => DH,
- 'Destination-Realm' => DR};
- is_list(Avps) ->
- [{'Origin-Host', OH},
- {'Origin-Realm', OR},
- {'Destination-Host', DH},
- {'Destination-Realm', DR}
- | Avps]
- end]}.
+ {send, [Name | Avps#{'Origin-Host' => OH, 'Origin-Realm' => OR}]}.
%% prepare_retransmit/3
-prepare_retransmit(Packet, SvcName, Peer) ->
- prepare_request(Packet, SvcName, Peer).
+prepare_retransmit(Pkt, _SvcName, _Peer) ->
+ {send, Pkt}.
%% handle_answer/4
@@ -86,4 +73,4 @@ handle_error(Reason, _Request, _SvcName, _Peer) ->
%% handle_request/3
handle_request(_Packet, _SvcName, _Peer) ->
- erlang:error({unexpected, ?MODULE, ?LINE}).
+ {answer_message, 3001}. %% DIAMETER_COMMAND_UNSUPPORTED
diff --git a/lib/diameter/examples/code/node.erl b/lib/diameter/examples/code/node.erl
deleted file mode 100644
index 77810bf893..0000000000
--- a/lib/diameter/examples/code/node.erl
+++ /dev/null
@@ -1,202 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2018. 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%
-%%
-
-%%
-%% A library module used by the example Diameter nodes. Does little
-%% more than provide an alternate/simplified transport configuration.
-%%
-
--module(node).
-
--export([start/2,
- listen/2,
- connect/2,
- stop/1]).
-
--export([message/3]).
-
--type protocol()
- :: tcp | sctp.
-
--type ip_address()
- :: default
- | inet:ip_address().
-
--type server_transport()
- :: protocol()
- | {protocol(), ip_address(), non_neg_integer()}.
-
--type server_opts()
- :: server_transport()
- | {server_transport(), [diameter:transport_opt()]}
- | [diameter:transport_opt()].
-
--type client_transport()
- :: protocol() | any
- | {protocol() | any, ip_address(), non_neg_integer()}
- | {protocol() | any, ip_address(), ip_address(), non_neg_integer()}.
-
--type client_opts()
- :: client_transport()
- | {client_transport(), [diameter:transport_opt()]}
- | [diameter:transport_opt()].
-
-%% The server_transport() and client_transport() config is just
-%% convenience: arbitrary options can be specifed as a
-%% [diameter:transport_opt()].
-
--define(DEFAULT_PORT, 3868).
-
-%% ---------------------------------------------------------------------------
-%% Interface functions
-%% ---------------------------------------------------------------------------
-
-%% start/2
-
--spec start(diameter:service_name(), [diameter:service_opt()])
- -> ok
- | {error, term()}.
-
-start(Name, Opts)
- when is_atom(Name), is_list(Opts) ->
- diameter:start_service(Name, Opts).
-
-%% connect/2
-
--spec connect(diameter:service_name(), client_opts())
- -> {ok, diameter:transport_ref()}
- | {error, term()}.
-
-connect(Name, Opts)
- when is_list(Opts) ->
- diameter:add_transport(Name, {connect, Opts});
-
-connect(Name, {T, Opts}) ->
- connect(Name, Opts ++ client_opts(T));
-
-connect(Name, T) ->
- connect(Name, [{connect_timer, 5000} | client_opts(T)]).
-
-%% listen/2
-
--spec listen(diameter:service_name(), server_opts())
- -> {ok, diameter:transport_ref()}
- | {error, term()}.
-
-listen(Name, Opts)
- when is_list(Opts) ->
- diameter:add_transport(Name, {listen, Opts});
-
-listen(Name, {T, Opts}) ->
- listen(Name, Opts ++ server_opts(T));
-
-listen(Name, T) ->
- listen(Name, server_opts(T)).
-
-%% stop/1
-
--spec stop(diameter:service_name())
- -> ok
- | {error, term()}.
-
-stop(Name) ->
- diameter:stop_service(Name).
-
-%% ---------------------------------------------------------------------------
-%% Internal functions
-%% ---------------------------------------------------------------------------
-
-%% server_opts/1
-%%
-%% Return transport options for a listening transport.
-
-server_opts({T, Addr, Port}) ->
- [{transport_module, tmod(T)},
- {transport_config, [{reuseaddr, true},
- {sender, true},
- {message_cb, [fun ?MODULE:message/3, 0]},
- {ip, addr(Addr)},
- {port, Port}]}];
-
-server_opts(T) ->
- server_opts({T, loopback, ?DEFAULT_PORT}).
-
-%% client_opts/1
-%%
-%% Return transport options for a connecting transport.
-
-client_opts({T, LA, RA, RP})
- when T == all; %% backwards compatibility
- T == any ->
- [[S, {C,Os}], T] = [client_opts({P, LA, RA, RP}) || P <- [sctp,tcp]],
- [S, {C,Os,2000} | T];
-
-client_opts({T, LA, RA, RP}) ->
- [{transport_module, tmod(T)},
- {transport_config, [{raddr, addr(RA)},
- {rport, RP},
- {reuseaddr, true}
- | ip(LA)]}];
-
-client_opts({T, RA, RP}) ->
- client_opts({T, default, RA, RP});
-
-client_opts(T) ->
- client_opts({T, loopback, loopback, ?DEFAULT_PORT}).
-
-%% ---------------------------------------------------------------------------
-
-tmod(tcp) -> diameter_tcp;
-tmod(sctp) -> diameter_sctp.
-
-ip(default) ->
- [];
-ip(loopback) ->
- [{ip, {127,0,0,1}}];
-ip(Addr) ->
- [{ip, Addr}].
-
-addr(loopback) ->
- {127,0,0,1};
-addr(A) ->
- A.
-
-%% ---------------------------------------------------------------------------
-
-%% message/3
-%%
-%% Simple message callback that limits the number of concurrent
-%% requests on the peer connection in question.
-
-%% Incoming request.
-message(recv, <<_:32, 1:1, _/bits>> = Bin, N) ->
- [Bin, N < 32, fun ?MODULE:message/3, N+1];
-
-%% Outgoing request.
-message(ack, <<_:32, 1:1, _/bits>>, _) ->
- [];
-
-%% Incoming answer or request discarded.
-message(ack, _, N) ->
- [N =< 32, fun ?MODULE:message/3, N-1];
-
-%% Outgoing message or incoming answer.
-message(_, Bin, _) ->
- [Bin].
diff --git a/lib/diameter/examples/code/redirect.erl b/lib/diameter/examples/code/redirect.erl
index 6934e54507..1f9749ba84 100644
--- a/lib/diameter/examples/code/redirect.erl
+++ b/lib/diameter/examples/code/redirect.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -20,52 +20,80 @@
-module(redirect).
--include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
+%%
+%% An example Diameter redirect agent.
+%%
+%% Simplest usage to listen on TCP at 127.0.0.1:3868.
+%%
+%% redirect:start().
+%% redirect:listen(tcp).
+%%
+%% Interface.
-export([start/1,
listen/2,
stop/1]).
+%% Convenience functions using the default service name.
-export([start/0,
listen/1,
stop/0]).
--define(APP_ALIAS, ?MODULE).
--define(SVC_NAME, ?MODULE).
--define(CALLBACK_MOD, redirect_mod).
+-define(DEF_SVC_NAME, ?MODULE).
%% The service configuration.
-define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"},
{'Origin-Realm', "example.com"},
{'Vendor-Id', 193},
{'Product-Name', "RedirectAgent"},
- {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]},
- {application, [{alias, ?APP_ALIAS},
- {dictionary, ?DIAMETER_DICT_RELAY},
- {module, ?CALLBACK_MOD}]}]).
+ {'Auth-Application-Id', [16#FFFFFFFF]},
+ {decode_format, map},
+ {restrict_connections, false},
+ {strict_mbit, false},
+ {string_decode, false},
+ {application, [{alias, redirect},
+ {dictionary, diameter_gen_relay},
+ {module, redirect_cb},
+ {call_mutates_state, false}]}]).
+
+%% start/0
+
+start() ->
+ start(?DEF_SVC_NAME).
%% start/1
start(Name)
when is_atom(Name) ->
- peer:start(Name, ?SERVICE(Name)).
+ start(Name, []);
-start() ->
- start(?SVC_NAME).
+start(Opts)
+ when is_list(Opts) ->
+ start(?DEF_SVC_NAME, Opts).
+
+%% start/2
+
+start(Name, Opts) ->
+ Defaults = [T || {K,_} = T <- ?SERVICE(Name),
+ not lists:keymember(K, 1, Opts)],
+ diameter:start_service(Name, Opts ++ Defaults).
%% listen/2
-listen(Name, T) ->
- peer:listen(Name, T).
+listen(Name, Opts) ->
+ server:listen(Name, Opts).
+
+%% listen/1
-listen(T) ->
- listen(?SVC_NAME, T).
+listen(Opts) ->
+ listen(?DEF_SVC_NAME, Opts).
%% stop/1
stop(Name) ->
- peer:stop(Name).
+ diameter:stop_service(Name).
+
+%% stop.0
stop() ->
- stop(?SVC_NAME).
+ stop(?DEF_SVC_NAME).
diff --git a/lib/diameter/examples/code/redirect_cb.erl b/lib/diameter/examples/code/redirect_cb.erl
index 8325e86391..76ab091be3 100644
--- a/lib/diameter/examples/code/redirect_cb.erl
+++ b/lib/diameter/examples/code/redirect_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -21,7 +21,6 @@
-module(redirect_cb).
-include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
%% diameter callbacks
-export([peer_up/3,
@@ -33,30 +32,71 @@
handle_error/4,
handle_request/3]).
--define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})).
+%% Dictionary to encode answer-message AVPs with.
+-define(Dict, diameter_gen_base_rfc6733).
+
+%% Raise an error on callbacks that aren't expected.
+-define(ERROR, error({unexpected, ?MODULE, ?LINE})).
+
+%% peer_up/3
peer_up(_SvcName, _Peer, State) ->
State.
+%% peer_down/3
+
peer_down(_SvcName, _Peer, State) ->
State.
+%% pick_peer/4
+
pick_peer(_, _, _SvcName, _State) ->
- ?UNEXPECTED.
+ false.
+
+%% prepare_request/3
prepare_request(_, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% prepare_retransmit/3
prepare_retransmit(_Packet, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_answer/4
handle_answer(_Packet, _Request, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_error/4
handle_error(_Reason, _Request, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_request/3
-handle_request(#diameter_packet{msg = _, errors = []}, _SvcName, {_, Caps}) ->
- #diameter_caps{}
+handle_request(#diameter_packet{avps = Avps}, _, {_, Caps}) ->
+ #diameter_caps{origin_host = {OH, _},
+ origin_realm = {OR, _}}
= Caps,
- discard. %% TODO
+
+ Tail = [#diameter_avp{data = {?Dict, A, V}}
+ || {A,V} <- [{'Origin-Host', OH},
+ {'Origin-Realm', OR},
+ {'Result-Code', 3006}, %% DIAMETER_REDIRECT_INDICATION
+ {'Redirect-Host', <<"aaa://server.example.com:3868">>}]],
+
+ {reply, ['answer-message' | lists:append([session(Avps), Tail])]}.
+
+%% ===========================================================================
+
+%% session/1
+
+session(Avps) ->
+ try
+ [] = [A || #diameter_avp{code = 263, vendor_id = undefined} = A
+ <- Avps,
+ throw(A)]
+ catch
+ Avp -> [Avp]
+ end.
diff --git a/lib/diameter/examples/code/relay.erl b/lib/diameter/examples/code/relay.erl
index 806f79915b..ec53ac01f1 100644
--- a/lib/diameter/examples/code/relay.erl
+++ b/lib/diameter/examples/code/relay.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -18,81 +18,94 @@
%% %CopyrightEnd%
%%
+-module(relay).
+
%%
%% An example Diameter relay agent.
%%
-%% Usage to connect to a server listening on the default port over TCP
-%% and to listen on the default port over SCTP is as follows, assuming
-%% diameter is already started (eg. diameter:start()).
+%% Simplets usage to connect to a server listening on TCP at
+%% 127.0.0.1:3868 and listen for connections on TCP at the same
+%% endpoint:
%%
-%% Eg. relay:start().
-%% relay:connect(tcp).
-%% relay:listen(sctp).
+%% relay:start().
+%% relay:connect(tcp).
+%% relay:listen(sctp).
%%
--module(relay).
-
+%% Interface.
-export([start/1,
start/2,
listen/2,
connect/2,
stop/1]).
+%% Convenience functions using the default service name.
-export([start/0,
listen/1,
connect/1,
stop/0]).
+%% Default service name.
-define(DEF_SVC_NAME, ?MODULE).
-%% The service configuration.
+%% Service configuration.
-define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"},
{'Origin-Realm', "example.com"},
{'Vendor-Id', 193},
{'Product-Name', "RelayAgent"},
{'Auth-Application-Id', [16#FFFFFFFF]},
+ {decode_format, map},
+ {restrict_connections, false},
{string_decode, false},
+ {strict_mbit, false},
{application, [{alias, relay},
{dictionary, diameter_gen_relay},
- {module, relay_cb}]}]).
+ {module, relay_cb},
+ {call_mutates_state, false}]}]).
-%% start/1
+%% start/2
-start(Name)
- when is_atom(Name) ->
- start(Name, []).
+start(Name, Opts) ->
+ Defaults = [T || {K,_} = T <- ?SERVICE(Name),
+ not lists:keymember(K, 1, Opts)],
+ diameter:start_service(Name, Opts ++ Defaults).
%% start/1
-start() ->
- start(?DEF_SVC_NAME).
+start(Opts) ->
+ start(?DEF_SVC_NAME, Opts).
-%% start/2
+%% start/0
-start(Name, Opts) ->
- node:start(Name, Opts ++ [T || {K,_} = T <- ?SERVICE(Name),
- false == lists:keymember(K, 1, Opts)]).
+start() ->
+ start(?DEF_SVC_NAME, []).
%% listen/2
-listen(Name, T) ->
- node:listen(Name, T).
+listen(Name, Opts) ->
+ server:listen(Name, Opts).
-listen(T) ->
- listen(?DEF_SVC_NAME, T).
+%% listen/1
+
+listen(Opts) ->
+ listen(?DEF_SVC_NAME, Opts).
%% connect/2
-connect(Name, T) ->
- node:connect(Name, T).
+connect(Name, Opts) ->
+ client:connect(Name, Opts).
+
+%% connect/1
-connect(T) ->
- connect(?DEF_SVC_NAME, T).
+connect(Opts) ->
+ connect(?DEF_SVC_NAME, Opts).
%% stop/1
stop(Name) ->
- node:stop(Name).
+ diameter:stop_service(Name).
+
+%% stop/0
stop() ->
stop(?DEF_SVC_NAME).
diff --git a/lib/diameter/examples/code/relay_cb.erl b/lib/diameter/examples/code/relay_cb.erl
index 6df1738143..0d56a14401 100644
--- a/lib/diameter/examples/code/relay_cb.erl
+++ b/lib/diameter/examples/code/relay_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -21,48 +21,59 @@
-module(relay_cb).
-include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
%% diameter callbacks
-export([peer_up/3,
peer_down/3,
- pick_peer/5,
- prepare_request/4,
- prepare_retransmit/4,
- handle_answer/5,
- handle_error/5,
+ pick_peer/4,
+ prepare_request/3,
+ prepare_retransmit/3,
+ handle_answer/4,
+ handle_error/4,
handle_request/3]).
+%% peer_up/3
+
peer_up(_SvcName, _Peer, State) ->
State.
+%% peer_down/3
+
peer_down(_SvcName, _Peer, State) ->
State.
-%% Returning 'relay' from handle_request causes diameter to resend the
-%% incoming request, which leads to pick_peer and prepare_request
-%% callbacks as if sending explicitly. The 'extra' argument is
-%% appended to the argument list for callbacks following from
-%% resending of the request.
+%% handle_request/3
+
+%% Assume the destination is directly connected; filter
+%% correspondingly; don't relay to the sender.
+handle_request(_Pkt, _SvcName, {_, Caps}) ->
+ #diameter_caps{origin_host = {_, OH}}
+ = Caps,
+ {relay, [{timeout, 2000},
+ {filter, {all, [host, realm, {neg, {host, OH}}]}}]}.
-handle_request(_Pkt, _SvcName, _Peer) ->
- {relay, [{timeout, 1000}, {extra, [relayed]}]}.
+%% pick_peer/4
-%% diameter will filter the sender in the Peers list.
-pick_peer([Peer | _], _, _SvcName, _State, relayed) ->
+pick_peer([Peer | _], _, _SvcName, _State) ->
{ok, Peer}.
-prepare_request(Pkt, _SvcName, _Peer, relayed) ->
+%% prepare_request/3
+
+prepare_request(Pkt, _SvcName, _Peer) ->
{send, Pkt}.
-prepare_retransmit(Pkt, _SvcName, _Peer, relayed) ->
+%% prepare_request/3
+
+prepare_retransmit(Pkt, _SvcName, _Peer) ->
{send, Pkt}.
-%% diameter expects handle_answer to return the diameter_packet record
-%% containing the answer when called for a relayed request.
+%% handle_answer/4
-handle_answer(Pkt, _Request, _SvcName, _Peer, relayed) ->
+%% Relay an answer by returning the first argument.
+handle_answer(Pkt, _Request, _SvcName, _Peer) ->
Pkt.
-handle_error(Reason, _Request, _SvcName, _Peer, relayed) ->
+%% handle_error/4
+
+handle_error(Reason, _Request, _SvcName, _Peer) ->
{error, Reason}.
diff --git a/lib/diameter/examples/code/server.erl b/lib/diameter/examples/code/server.erl
index a91be70664..6ee49fb678 100644
--- a/lib/diameter/examples/code/server.erl
+++ b/lib/diameter/examples/code/server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -18,23 +18,20 @@
%% %CopyrightEnd%
%%
+-module(server).
+
%%
-%% An example Diameter server that can respond to the base protocol
-%% RAR sent by the client example.
+%% An example Diameter server that answers the base protocol ACR sent
+%% by the client example.
%%
-%% The simplest example to start a server listening on the loopback
-%% address (which will serve the example usage given in client.erl) is
-%% like this assuming diameter is already started (eg. diameter:start()):
+%% Simplest usage to listen on TCP at 127.0.0.1:3868:
%%
%% server:start().
%% server:listen(tcp).
%%
-%% The first call starts a service, the second adds a transport listening
-%% on the default port.
-%%
--module(server).
+%% Interface.
-export([start/1, %% start a service
start/2, %%
listen/2, %% add a listening transport
@@ -45,6 +42,9 @@
listen/1,
stop/0]).
+%% Internal callback.
+-export([message/3]).
+
-define(DEF_SVC_NAME, ?MODULE).
%% The service configuration. In a server supporting multiple Diameter
@@ -55,45 +55,110 @@
{'Vendor-Id', 193},
{'Product-Name', "Server"},
{'Auth-Application-Id', [0]},
+ {decode_format, map},
{restrict_connections, false},
+ {strict_mbit, false},
{string_decode, false},
{application, [{alias, common},
{dictionary, diameter_gen_base_rfc6733},
- {module, server_cb}]}]).
+ {module, server_cb},
+ {call_mutates_state, false}]}]).
-%% start/1
+%% start/2
-start(Name)
- when is_atom(Name) ->
- start(Name, []);
+start(Name, Opts) ->
+ Defaults = [T || {K,_} = T <- ?SERVICE(Name),
+ not lists:keymember(K, 1, Opts)],
+ diameter:start_service(Name, Opts ++ Defaults).
-start(Opts)
- when is_list(Opts) ->
+%% start/1
+
+start(Opts) ->
start(?DEF_SVC_NAME, Opts).
%% start/0
start() ->
- start(?DEF_SVC_NAME).
-
-%% start/2
-
-start(Name, Opts) ->
- node:start(Name, Opts ++ [T || {K,_} = T <- ?SERVICE(Name),
- false == lists:keymember(K, 1, Opts)]).
+ start(?DEF_SVC_NAME, []).
%% listen/2
+listen(Name, Opts)
+ when is_list(Opts) ->
+ diameter:add_transport(Name, {listen, lists:flatmap(fun opts/1, Opts)});
+
+%% backwards compatibility with old config
+listen(Name, {T, Opts}) ->
+ listen(Name, [T | Opts]);
listen(Name, T) ->
- node:listen(Name, T).
+ listen(Name, [T]).
-listen(T) ->
- listen(?DEF_SVC_NAME, T).
+%% listen/1
+
+listen(Opts) ->
+ listen(?DEF_SVC_NAME, Opts).
%% stop/1
stop(Name) ->
- node:stop(Name).
+ diameter:stop_service(Name).
+
+%% stop/0
stop() ->
stop(?DEF_SVC_NAME).
+
+%% ===========================================================================
+
+%% opts/1
+%%
+%% Map a 3-tuple a transport_module/transport_config pair as a
+%% convenience, pass everything else unmodified.
+
+opts(T)
+ when T == tcp;
+ T == sctp ->
+ opts({T, loopback, default});
+
+opts({tcp, Addr, Port}) ->
+ opts({diameter_tcp, Addr, Port});
+
+opts({sctp, Addr, Port}) ->
+ opts({diameter_sctp, Addr, Port});
+
+opts({Mod, loopback, Port}) ->
+ opts({Mod, {127,0,0,1}, Port});
+
+opts({Mod, Addr, default}) ->
+ opts({Mod, Addr, 3868});
+
+opts({Mod, Addr, Port}) ->
+ [{transport_module, Mod},
+ {transport_config, [{reuseaddr, true},
+ {sender, true},
+ {message_cb, {?MODULE, message, [0]}},
+ {ip, Addr},
+ {port, Port}]}];
+opts(T) ->
+ [T].
+
+%% message/3
+%%
+%% Simple message callback that limits the number of concurrent
+%% requests on the peer connection in question.
+
+%% Incoming request.
+message(recv, <<_:32, 1:1, _/bits>> = Bin, N) ->
+ [Bin, N < 32, {?MODULE, message, [N+1]}];
+
+%% Outgoing request.
+message(ack, <<_:32, 1:1, _/bits>>, _) ->
+ [];
+
+%% Incoming answer or request discarded.
+message(ack, _, N) ->
+ [N =< 32, {?MODULE, message, [N-1]}];
+
+%% Outgoing message or incoming answer.
+message(_, Bin, _) ->
+ [Bin].
diff --git a/lib/diameter/examples/code/server_cb.erl b/lib/diameter/examples/code/server_cb.erl
index a2fb8fbda6..5662717c00 100644
--- a/lib/diameter/examples/code/server_cb.erl
+++ b/lib/diameter/examples/code/server_cb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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,7 +25,6 @@
-module(server_cb).
-include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc6733.hrl").
%% diameter callbacks
-export([peer_up/3,
@@ -37,67 +36,87 @@
handle_error/4,
handle_request/3]).
--define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})).
+%% Raise an error on callbacks that aren't expected.
+-define(ERROR, error({unexpected, ?MODULE, ?LINE})).
+
+%% peer_up/3
peer_up(_SvcName, _Peer, State) ->
State.
+%% peer_down/3
+
peer_down(_SvcName, _Peer, State) ->
State.
-pick_peer(_, _, _SvcName, _State) ->
- ?UNEXPECTED.
+%% pick_peer/3
+
+%% Don't let requests be sent, so other request callbacks shouldn't
+%% happen.
+pick_peer(_LocalCandidates, _RemoteCandidates, _SvcName, _State) ->
+ false.
+
+%% prepare_request/3
-prepare_request(_, _SvcName, _Peer) ->
- ?UNEXPECTED.
+prepare_request(_Packet, _SvcName, _Peer) ->
+ ?ERROR.
+
+%% prepare_retransmit/3
prepare_retransmit(_Packet, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_answer/4
handle_answer(_Packet, _Request, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_error/4
handle_error(_Reason, _Request, _SvcName, _Peer) ->
- ?UNEXPECTED.
+ ?ERROR.
+
+%% handle_request/3
-%% A request whose decode was successful ...
-handle_request(#diameter_packet{msg = Req, errors = []}, _SvcName, {_, Caps})
- when is_record(Req, diameter_base_RAR) ->
+%% ACR without decode errors.
+handle_request(#diameter_packet{msg = ['ACR' | #{} = Request],
+ errors = []},
+ _SvcName,
+ {_, Caps}) ->
#diameter_caps{origin_host = {OH,_},
origin_realm = {OR,_}}
= Caps,
- #diameter_base_RAR{'Session-Id' = Id,
- 'Re-Auth-Request-Type' = Type}
- = Req,
-
- {reply, #diameter_base_RAA{'Result-Code' = rc(Type),
- 'Origin-Host' = OH,
- 'Origin-Realm' = OR,
- 'Session-Id' = Id}};
-
-%% ... or one that wasn't. 3xxx errors are answered by diameter itself
-%% but these are 5xxx errors for which we must contruct a reply.
-%% diameter will set Result-Code and Failed-AVP's.
-handle_request(#diameter_packet{msg = Req}, _SvcName, {_, Caps})
- when is_record(Req, diameter_base_RAR) ->
+
+ #{'Session-Id' := Sid,
+ 'Accounting-Record-Type' := T,
+ 'Accounting-Record-Number' := N}
+ = Request,
+
+ Answer = #{'Result-Code' => 2001, %% DIAMETER_SUCCESS
+ 'Origin-Host' => OH,
+ 'Origin-Realm' => OR,
+ 'Session-Id' => Sid,
+ 'Accounting-Record-Type' => T,
+ 'Accounting-Record-Number' => N},
+
+ {reply, ['ACA' | Answer]};
+
+%% ACR with decode errors.
+handle_request(#diameter_packet{msg = ['ACR' | #{} = Request]},
+ _SvcName,
+ {_, Caps}) ->
#diameter_caps{origin_host = {OH,_},
origin_realm = {OR,_}}
= Caps,
- #diameter_base_RAR{'Session-Id' = Id}
- = Req,
- {reply, #diameter_base_RAA{'Origin-Host' = OH,
- 'Origin-Realm' = OR,
- 'Session-Id' = Id}};
+ Answer = maps:merge(maps:with(['Session-Id'], Request),
+ #{'Origin-Host' => OH,
+ 'Origin-Realm' => OR}),
-%% Answer that any other message is unsupported.
+ %% Let diameter set Result-Code and Failed-AVP if there were
+ %% decode errors.
+ {reply, ['answer-message' | Answer]};
+
+%% Answer anything else as unsupported.
handle_request(#diameter_packet{}, _SvcName, _) ->
{answer_message, 3001}. %% DIAMETER_COMMAND_UNSUPPORTED
-
-%% Map Re-Auth-Request-Type to Result-Code just for the purpose of
-%% generating different answers.
-
-rc(0) ->
- 2001; %% DIAMETER_SUCCESS
-rc(_) ->
- 5012. %% DIAMETER_UNABLE_TO_COMPLY
diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile
index 98636ed6e2..d6854cfd27 100644
--- a/lib/diameter/src/Makefile
+++ b/lib/diameter/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2018. All Rights Reserved.
+# Copyright Ericsson AB 2010-2020. 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.
@@ -210,12 +210,16 @@ realclean: clean
PLT = ./otp.plt
-plt:
+plt: $(PLT)
+
+$(PLT):
dialyzer --build_plt \
--apps erts stdlib kernel \
xmerl ssl public_key crypto \
compiler syntax_tools runtime_tools \
- --output_plt $(PLT) \
+ --output_plt $@ \
+ --get_warnings \
+ --statistics \
--verbose
dialyze: opt $(PLT)
@@ -224,9 +228,12 @@ dialyze: opt $(PLT)
-Wno_improper_lists \
$(EBIN)/diameter_gen_base_rfc3588.$(EMULATOR) \
$(patsubst %, $(EBIN)/%.$(EMULATOR), \
- $(notdir $(RT_MODULES) $(CT_MODULES) $(INFO_MODULES)))
+ $(notdir $(DICT_YRL) \
+ $(RT_MODULES) \
+ $(CT_MODULES) \
+ $(INFO_MODULES)))
# Omit all but the common dictionary module since these
-# (diameter_gen_relay in particular) generate warning depending on how
+# (diameter_gen_relay in particular) generate warnings depending on how
# much of the included diameter_gen.hrl they use.
# ----------------------------------------------------
diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl
index 7f172e1fa1..2982486a10 100644
--- a/lib/diameter/src/base/diameter.erl
+++ b/lib/diameter/src/base/diameter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -146,8 +146,9 @@ services() ->
%% service_info/2
%% ---------------------------------------------------------------------------
--spec service_info(service_name(), atom() | [atom()])
- -> any().
+-spec service_info(service_name(), Item | [Item])
+ -> any()
+ when Item :: atom() | peer_ref().
service_info(SvcName, Option) ->
diameter_service:info(SvcName, Option).
@@ -351,45 +352,45 @@ call(SvcName, App, Message) ->
%% Options common to both start_service/2 and add_transport/2.
-type common_opt()
- :: {pool_size, pos_integer()}
+ :: {avp_dictionaries, [module()]}
| {capabilities_cb, eval()}
| {capx_timeout, 'Unsigned32'()}
- | {strict_capx, boolean()}
- | {strict_mbit, boolean()}
- | {avp_dictionaries, [module()]}
+ | {connect_timer, 'Unsigned32'()}
| {disconnect_cb, eval()}
- | {dpr_timeout, 'Unsigned32'()}
| {dpa_timeout, 'Unsigned32'()}
+ | {dpr_timeout, 'Unsigned32'()}
| {incoming_maxlen, message_length()}
| {length_errors, exit | handle | discard}
- | {connect_timer, 'Unsigned32'()}
- | {watchdog_timer, 'Unsigned32'() | {module(), atom(), list()}}
+ | {pool_size, pos_integer()}
+ | {spawn_opt, list() | mfa()}
+ | {strict_capx, boolean()}
+ | {strict_mbit, boolean()}
| {watchdog_config, [{okay|suspect, non_neg_integer()}]}
- | {spawn_opt, list() | mfa()}.
+ | {watchdog_timer, 'Unsigned32'() | {module(), atom(), list()}}.
%% Options passed to start_service/2
-type service_opt()
:: capability()
| {application, [application_opt()]}
+ | {decode_format, decode_format()}
| {restrict_connections, restriction()}
| {sequence, sequence() | eval()}
| {share_peers, remotes()}
- | {decode_format, decode_format()}
- | {traffic_counters, boolean()}
- | {string_decode, boolean()}
| {strict_arities, true | strict_arities()}
+ | {string_decode, boolean()}
+ | {traffic_counters, boolean()}
| {use_shared_peers, remotes()}
| common_opt().
-type application_opt()
:: {alias, app_alias()}
+ | {answer_errors, callback|report|discard}
+ | {call_mutates_state, boolean()}
| {dictionary, module()}
| {module, app_module()}
- | {state, any()}
- | {call_mutates_state, boolean()}
- | {answer_errors, callback|report|discard}
- | {request_errors, answer_3xxx|answer|callback}.
+ | {request_errors, answer_3xxx|answer|callback}
+ | {state, any()}.
-type app_alias()
:: any().
@@ -407,11 +408,11 @@ call(SvcName, App, Message) ->
%% Options passed to add_transport/2
-type transport_opt()
- :: {transport_module, atom()}
+ :: {applications, [app_alias()]}
+ | {capabilities, [capability()]}
| {transport_config, any()}
| {transport_config, any(), 'Unsigned32'() | infinity}
- | {applications, [app_alias()]}
- | {capabilities, [capability()]}
+ | {transport_module, atom()}
| common_opt()
| {private, any()}.
@@ -430,8 +431,8 @@ call(SvcName, App, Message) ->
%% Options passed to call/4
-type call_opt()
- :: {extra, list()}
+ :: detach
+ | {extra, list()}
| {filter, peer_filter()}
- | {timeout, 'Unsigned32'()}
| {peer, peer_ref()}
- | detach.
+ | {timeout, 'Unsigned32'()}.
diff --git a/lib/diameter/src/base/diameter_codec.erl b/lib/diameter/src/base/diameter_codec.erl
index 493a6ab1e3..7f6baf666a 100644
--- a/lib/diameter/src/base/diameter_codec.erl
+++ b/lib/diameter/src/base/diameter_codec.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -208,7 +208,7 @@ values(Avps) ->
encode_avps(_, _, [#diameter_avp{} | _] = Avps, Opts) ->
encode_avps(Avps, Opts);
-%% ... or as a tuple list or record.
+%% ... or as a tuple list, map, or record.
encode_avps(Mod, MsgName, Values, Opts) ->
Mod:encode_avps(MsgName, Values, Opts).
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index 36ae4c2276..495e57e456 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -661,6 +661,9 @@ opt(transport, {transport_module, M}) ->
opt(transport, {transport_config, _, Tmo}) ->
?IS_UINT32(Tmo) orelse Tmo == infinity;
+opt(transport, {transport_config, _}) ->
+ true;
+
opt(transport, {applications, As}) ->
is_list(As);
@@ -720,15 +723,16 @@ opt(_, {K, _})
when K == disconnect_cb;
K == capabilities_cb ->
true;
-opt(transport, {K, _})
- when K == transport_config;
- K == private ->
+opt(transport, {private, _}) ->
true;
-%% Anything else, which is ignored in transport config. This makes
-%% options sensitive to spelling mistakes, but arbitrary options are
-%% passed by some users as a way to identify transports so can't just
-%% do away with it.
+%% Anything else is ignored in transport config. This makes options
+%% sensitive to spelling mistakes and unintentionally passing service
+%% options, but arbitrary options are passed by some users as a way to
+%% identify transports (they can be returned by diameter:service_info/2
+%% for example) so can't just do away with it, although silently
+%% swallowing service options is at least debatable. The documentation
+%% says anything, so accept anything.
opt(K, _) ->
K == transport.
diff --git a/lib/diameter/src/base/diameter_dist.erl b/lib/diameter/src/base/diameter_dist.erl
index ed23152b8b..1edca58eb9 100644
--- a/lib/diameter/src/base/diameter_dist.erl
+++ b/lib/diameter/src/base/diameter_dist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2019. All Rights Reserved.
+%% Copyright Ericsson AB 2019-2020. 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,6 +27,21 @@
%% transport configuration, to be able to distribute incoming Diameter
%% requests to handler processes (local or remote) in various ways.
%%
+%% The gen_server implemented here must be started on each node on
+%% which {diameter_dist, route_session, _} is configured as a
+%% spawn_opt MFA, as well as each node that wants to receive requests.
+%% This happens as a consequence of diameter application start, but a
+%% minimal solution could start only this server on nodes that should
+%% handle requests but not configure transport. (Although the typical
+%% case is probably that diameter should be started in any case; for
+%% example, to be able to originate requests.)
+%%
+%% Moreover, attach/1 must be called to communicate the list of
+%% services for which the local node is willing to handle requests.
+%% The servers on different nodes communicate so that each server
+%% knows which nodes are prepared to handle requests for which
+%% services.
+%%
%% spawn_opt callbacks
-export([spawn_local/2,
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index cf5e7f21d3..b86dcaf923 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 77d184cfc7..520a7233cc 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -735,29 +735,31 @@ init_peers() ->
%% Alias,
%% TPid}
+%% Valid service options are all 2-tuples.
service_opts(Opts) ->
- remove([{strict_arities, true},
- {avp_dictionaries, []}],
- maps:merge(maps:from_list([{monitor, false} | def_opts()]),
- maps:from_list(Opts))).
+ remove([{strict_arities, true}, {avp_dictionaries, []}],
+ merge(lists:append([[{monitor, false}] | def_opts()]), Opts)).
+
+merge(List1, List2) ->
+ maps:merge(maps:from_list(List1), maps:from_list(List2)).
remove(List, Map) ->
maps:filter(fun(K,V) -> not lists:member({K,V}, List) end,
Map).
-def_opts() -> %% defaults on the service map
- [{share_peers, false},
- {use_shared_peers, false},
- {sequence, {0,32}},
- {restrict_connections, nodes},
- {incoming_maxlen, 16#FFFFFF},
- {strict_arities, true},
- {strict_mbit, true},
- {decode_format, record},
- {avp_dictionaries, []},
- {traffic_counters, true},
- {string_decode, true},
- {spawn_opt, []}].
+def_opts() -> %% defaults on the options map
+ [[{decode_format, record}, %% service options
+ {restrict_connections, nodes},
+ {sequence, {0,32}},
+ {share_peers, false},
+ {strict_arities, true},
+ {string_decode, true},
+ {traffic_counters, true},
+ {use_shared_peers, false}],
+ [{avp_dictionaries, []}, %% common options
+ {incoming_maxlen, 16#FFFFFF},
+ {spawn_opt, []},
+ {strict_mbit, true}]].
mref(false = No) ->
No;
@@ -875,27 +877,46 @@ start(Ref, Type, Opts, N, #state{watchdogT = WatchdogT,
= Svc1
= merge_service(Opts, Svc0),
Svc = binary_caps(Svc1, SD),
- {SOpts, TOpts} = merge_opts(SvcOpts, Opts),
- RecvData = diameter_traffic:make_recvdata([SvcName, PeerT, Apps, SOpts]),
- T = {TOpts, SOpts, RecvData, Svc},
+ {Map, Rest} = merge_opts(SvcOpts, Opts),
+ RecvData = diameter_traffic:make_recvdata([SvcName, PeerT, Apps, Map]),
+ T = {Rest, Map, RecvData, Svc},
Rec = #watchdog{type = Type,
ref = Ref,
- options = TOpts},
-
+ options = Opts}, %% original options, returned
+ %% by service_info/2
diameter_lib:fold_n(fun(_,A) ->
[wd(Type, Ref, T, WatchdogT, Rec) | A]
end,
[],
N).
-merge_opts(SvcOpts, Opts) ->
- Keys = [K || {K,_} <- def_opts()],
- SO = [T || {K,_} = T <- Opts, lists:member(K, Keys)],
- TO = Opts -- SO,
- {maps:merge(maps:with(Keys, SvcOpts), maps:from_list(SO)),
- TO ++ [T || {K,_} = T <- maps:to_list(SvcOpts),
- not lists:member(K, Keys),
- not lists:keymember(K, 1, Opts)]}.
+%% This is awkward. We have service options that have been passed to
+%% diameter:start_service/2 (minus application and capabilities
+%% options, removed in diameter_config) and transport options passed
+%% to diameter:add_transport/2. The former can include defaults for
+%% the latter, but the latter can also contain arbitrary options that
+%% are just returned by diameter:service_info/2. There's nothing
+%% stopping these arbitrary options from being valid service options,
+%% but these aren't interpreted as such.
+%%
+%% The options are merged (transport defaults have already been merged
+%% into the service options in service_opts/1) and split into a map
+%% for the service options and a few transport options, and a list for
+%% the rest. This is historical convolution. Some options are are
+%% pulled out of the list on the way to starting the transport process
+%% in diameter_peer_fsm, but more work could probably be done here to
+%% simplify things.
+%%
+%% Transport options are not necessarily 2-tuples: the transport_config
+%% 3-tuple means they can't just be turned into a map.
+merge_opts(SOpts, TOpts) ->
+ [SD,TD] = Def = def_opts(),
+ Keys = [K || L <- Def, {K,_} <- L],
+ Opts = [T || {K,_} = T <- TOpts, lists:keymember(K, 1, TD)],
+ {maps:merge(maps:with(Keys, SOpts), maps:from_list(Opts)),%% merge TOpts
+ TOpts ++ [T || {K,_} = T <- maps:to_list(SOpts), %% append SOpts
+ not lists:keymember(K, 1, SD),
+ [] == [A || {A,_} <- TOpts, A == K]]}.
binary_caps(Svc, true) ->
Svc;
diff --git a/lib/diameter/src/base/diameter_traffic.erl b/lib/diameter/src/base/diameter_traffic.erl
index 8423e30269..4667bbc3f2 100644
--- a/lib/diameter/src/base/diameter_traffic.erl
+++ b/lib/diameter/src/base/diameter_traffic.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2020. 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.
@@ -86,6 +86,7 @@
string_decode := boolean(),
strict_arities => diameter:strict_arities(),
strict_mbit := boolean(),
+ ordered_encode => boolean(),
incoming_maxlen := diameter:message_length()}}).
%% Note that incoming_maxlen is currently handled in diameter_peer_fsm,
%% so that any message exceeding the maximum is discarded. Retain the
@@ -284,12 +285,18 @@ recv(false, false, TPid, Pkt, _, _) ->
spawn_request(false, _, _, _, _, _, _) -> %% no transport
discard;
-%% An MFA should return the pid() of a process in which the argument
-%% fun in applied, or the atom 'discard' if the fun is not applied.
-%% The latter results in an acknowledgment back to the transport
-%% process when appropriate, to ensure that send/recv callbacks can
-%% count outstanding requests. Acknowledgement is implicit if the
-%% handler process dies (in a handle_request callback for example).
+%% An MFA should return the pid() of a process that invokes
+%% diameter_traffic:request(ReqT), or the atom 'discard' if the
+%% function is not called. The latter results in an acknowledgment
+%% back to the transport process when appropriate, to ensure that
+%% send/recv callbacks can count outstanding requests. Acknowledgement
+%% is implicit if the handler process dies (in a handle_request
+%% callback for example).
+%%
+%% There is no requirement that diameter be started on nodes on which
+%% handler processes are spawned, just that diameter and application
+%% callbacks are on the code path. (Although the MFA itself may have
+%% requirements, as in the case of diameter_dist.)
spawn_request(AppT, {M,F,A}, Ack, TPid, Pkt, Dict0, RecvData) ->
%% Term to pass to request/1 in an appropriate process. Module
%% diameter_dist implements callbacks.
@@ -520,7 +527,7 @@ request_cb(noreply, _App, EvalPktFs, EvalFs) ->
%% Relay a request to another peer. This is equivalent to doing an
%% explicit call/4 with the message in question except that (1) a loop
-%% will be detected by examining Route-Record AVP's, (3) a
+%% will be detected by examining Route-Record AVP's, (2) a
%% Route-Record AVP will be added to the outgoing request and (3) the
%% End-to-End Identifier will default to that in the
%% #diameter_header{} without the need for an end_to_end_identifier
@@ -556,14 +563,7 @@ request_cb(T, App, _, _) ->
send_A({reply, Ans}, TPid, App, Dict0, RecvData, Pkt, _Caps, Fs) ->
AppDict = App#diameter_app.dictionary,
MsgDict = msg_dict(AppDict, Dict0, Ans),
- send_answer(Ans,
- TPid,
- MsgDict,
- AppDict,
- Dict0,
- RecvData,
- Pkt,
- Fs);
+ send_answer(Ans, TPid, MsgDict, AppDict, Dict0, RecvData, Pkt, Fs);
send_A({call, Opts}, TPid, App, Dict0, RecvData, Pkt, Caps, Fs) ->
AppDict = App#diameter_app.dictionary,
@@ -667,7 +667,7 @@ is_answer_message(#diameter_packet{msg = Msg}, Dict0) ->
is_answer_message([#diameter_header{is_request = R, is_error = E} | _], _) ->
E andalso not R;
-%% Message sent as a map or tagged avp/value list.
+%% Message sent as a map or avp list.
is_answer_message([Name | _], _) ->
Name == 'answer-message';
@@ -1239,7 +1239,12 @@ is_result(RC, true, _) ->
%% incr/2
incr(TPid, Counter) ->
- diameter_stats:incr(Counter, TPid, 1).
+ Node = node(TPid),
+ if Node == node() ->
+ diameter_stats:incr(Counter, TPid, 1);
+ true ->
+ spawn(Node, diameter_stats, incr, [Counter, TPid, 1])
+ end.
%% rcc/1
@@ -1866,23 +1871,26 @@ z(#diameter_packet{header = H, bin = Bin, transport_data = T}) ->
transport_data = T}.
%% send/1
+%%
+%% Send from a remote node using a peer connection on this one. Pkt is
+%% already stripped.
send({TPid, Pkt, #request{handler = Pid} = Req0, SvcName, Timeout, TRef}) ->
Req = Req0#request{handler = self()},
- recv(TPid, Pid, TRef, zend_requezt(TPid, Pkt, Req, SvcName, Timeout)).
+ Pid ! recv(TPid, TRef, send_request(TPid, Pkt, Req, SvcName, Timeout)).
-%% recv/4
+%% recv/3
%%
%% Relay an answer from a remote node.
-recv(TPid, Pid, TRef, {LocalTRef, MRef}) ->
+recv(TPid, TRef, {LocalTRef, MRef}) ->
receive
{answer, _, _, _, _} = A ->
- Pid ! A;
+ A;
{'DOWN', MRef, process, _, _} ->
- Pid ! {failover, TRef};
+ {failover, TRef};
{failover = T, LocalTRef} ->
- Pid ! {T, TRef};
+ {T, TRef};
T ->
exit({timeout, LocalTRef, TPid} = T)
end.
diff --git a/lib/diameter/src/diameter.appup.src b/lib/diameter/src/diameter.appup.src
index bb2a4a8e92..627213637b 100644
--- a/lib/diameter/src/diameter.appup.src
+++ b/lib/diameter/src/diameter.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -62,7 +62,15 @@
{"2.1.4.1", [{restart_application, diameter}]}, %% 20.3.8.19
{"2.1.5", [{restart_application, diameter}]}, %% 21.0
{"2.1.6", [{restart_application, diameter}]}, %% 21.1
- {"2.2", [{update, diameter_dist, {advanced, "2.2"}}]} %% 21.3
+ {"2.2", [{restart_application, diameter}]}, %% 21.3
+ {"2.2.1", [{load_module, diameter}, %% 21.3.5
+ {load_module, diameter_codec},
+ {update, diameter_config},
+ {update, diameter_dist},
+ {update, diameter_peer_fsm},
+ {update, diameter_service},
+ {load_module, diameter_traffic},
+ {update, diameter_tcp}]}
],
[
{"0.9", [{restart_application, diameter}]},
@@ -106,6 +114,14 @@
{"2.1.4.1", [{restart_application, diameter}]},
{"2.1.5", [{restart_application, diameter}]},
{"2.1.6", [{restart_application, diameter}]},
- {"2.2", [{restart_application, diameter}]}
+ {"2.2", [{restart_application, diameter}]},
+ {"2.2.1", [{load_module, diameter},
+ {load_module, diameter_codec},
+ {update, diameter_config},
+ {update, diameter_dist},
+ {update, diameter_peer_fsm},
+ {update, diameter_service},
+ {load_module, diameter_traffic},
+ {update, diameter_tcp}]}
]
}.
diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk
index d16292bb88..cf938785e3 100644
--- a/lib/diameter/src/modules.mk
+++ b/lib/diameter/src/modules.mk
@@ -1,7 +1,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2019. All Rights Reserved.
+# Copyright Ericsson AB 2010-2020. 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.
@@ -98,13 +98,14 @@ BINS = \
# Released files relative to ../examples.
EXAMPLES = \
code/GNUmakefile \
- code/node.erl \
code/client.erl \
code/client_cb.erl \
code/server.erl \
code/server_cb.erl \
code/relay.erl \
code/relay_cb.erl \
+ code/redirect.erl \
+ code/redirect_cb.erl \
dict/rfc4004_mip.dia \
dict/rfc4005_nas.dia \
dict/rfc4006_cc.dia \
diff --git a/lib/diameter/src/transport/diameter_tcp.erl b/lib/diameter/src/transport/diameter_tcp.erl
index e5e766d2a0..a051aeb156 100644
--- a/lib/diameter/src/transport/diameter_tcp.erl
+++ b/lib/diameter/src/transport/diameter_tcp.erl
@@ -569,7 +569,11 @@ m({'DOWN', M, process, P, _} = T, #monitor{parent = MRef,
%% l/2
%%
-%% Transition listener state.
+%% Transition listener state. Or not anymore since any message causes
+%% the process to exit.
+
+-spec l(tuple(), #listener{})
+ -> no_return().
%% Service process has died.
l({'DOWN', _, process, Pid, _} = T, #listener{service = Pid,
diff --git a/lib/diameter/test/diameter_dist_SUITE.erl b/lib/diameter/test/diameter_dist_SUITE.erl
index b2e4c35b9a..2fda2830ae 100644
--- a/lib/diameter/test/diameter_dist_SUITE.erl
+++ b/lib/diameter/test/diameter_dist_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2019. All Rights Reserved.
+%% Copyright Ericsson AB 2019-2020. 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.
@@ -160,15 +160,32 @@ ping(Config) ->
%%
%% Start diameter services.
-start(SvcName)
- when is_atom(SvcName) ->
+%% There's no need to start diameter on a node that only services
+%% diameter_dist as a handler of incoming requests, but the
+%% diameter_dist server must be started since the servers communicate
+%% to determine who services what. The typical case is probably that
+%% handler nodes also want to be able to send Diameter requests, in
+%% which case the application needs to be started and diameter_dist is
+%% started as a part of this, but only start the server here to ensure
+%% everything still works as expected.
+start({_SvcName, [_, {S1, _}, {S2, _}, _]})
+ when node() == S1; %% server1
+ node() == S2 -> %% server2
+ Mod = diameter_dist,
+ {ok, _} = gen_server:start({local, Mod}, Mod, _Args = [], _Opts = []),
+ ok;
+
+start({SvcName, [{S0, _}, _, _, {C, _}]})
+ when node() == S0; %% server0
+ node() == C -> %% client
ok = diameter:start(),
ok = diameter:start_service(SvcName, ?SERVICE((?L(SvcName))));
-start(Config) ->
+start(Config)
+ when is_list(Config) ->
Nodes = ?util:read_priv(Config, nodes),
[] = [{N,RC} || {N,S} <- Nodes,
- RC <- [rpc:call(N, ?MODULE, start, [S])],
+ RC <- [rpc:call(N, ?MODULE, start, [{S, Nodes}])],
RC /= ok].
sequence() ->
@@ -194,13 +211,12 @@ origin(Server) ->
%% Establish one connection from the client, terminated on the first
%% server node, the others handling requests.
-connect({?SERVER, Config, [{Node, _} | _]}) ->
- if Node == node() -> %% server0
- ?util:write_priv(Config, lref, {Node, ?util:listen(?SERVER, tcp)});
- true ->
- diameter_dist:attach([?SERVER])
- end,
- ok;
+connect({?SERVER, Config, [{Node, _} | _]})
+ when Node == node() -> %% server0
+ ok = ?util:write_priv(Config, lref, {Node, ?util:listen(?SERVER, tcp)});
+
+connect({?SERVER, _Config, _}) -> %% server[12]: register to receive requests
+ ok = diameter_dist:attach([?SERVER]);
connect({?CLIENT, Config, _}) ->
?util:connect(?CLIENT, tcp, ?util:read_priv(Config, lref)),
@@ -239,7 +255,18 @@ send(Config) ->
send(Config, 0, Dict) ->
[{Server0, _} | _] = ?util:read_priv(Config, nodes) ,
Node = atom_to_binary(Server0, utf8),
- {false, _} = {dict:is_key(Node, Dict), dict:to_list(Dict)};
+ {false, _} = {dict:is_key(Node, Dict), dict:to_list(Dict)},
+ %% Check that counters have been incremented as expected on server0.
+ [Info] = rpc:call(Server0, diameter, service_info, [?SERVER, connections]),
+ {[Stats], _} = {[S || {statistics, S} <- Info], Info},
+ {[{recv, 1, 100}, {send, 0, 100}], _}
+ = {[{D,R,N} || T <- [recv, send],
+ {{{0,275,R}, D}, N} <- Stats,
+ D == T],
+ Stats},
+ {[{send, 0, 100, 2001}], _}
+ = {[{D,R,N,C} || {{{0,275,R}, D, {'Result-Code', C}}, N} <- Stats],
+ Stats};
send(Config, N, Dict) ->
#diameter_base_STA{'Result-Code' = ?SUCCESS,
diff --git a/lib/diameter/test/diameter_event_SUITE.erl b/lib/diameter/test/diameter_event_SUITE.erl
index a291dde6be..6d1d1dfd8f 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-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2020. 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,6 +28,8 @@
-export([suite/0,
all/0,
+ init_per_suite/1,
+ end_per_suite/1,
init_per_testcase/2,
end_per_testcase/2]).
@@ -85,6 +87,13 @@ all() ->
cea_timeout,
stop].
+%% Not used, but a convenient place to enable trace.
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
init_per_testcase(Name, Config) ->
[{name, Name} | Config].
@@ -109,17 +118,19 @@ start_server(Config) ->
%% Connect with matching capabilities and expect the connection to
%% come up.
up(Config) ->
- {Svc, Ref} = connect(Config, [{connect_timer, 5000},
- {watchdog_timer, 15000}]),
+ {Svc, Ref, T} = connect(Config, [{strict_mbit, false},
+ {connect_timer, 5000},
+ {watchdog_timer, 15000}]),
start = event(Svc),
- {up, Ref, {TPid, Caps}, Cfg, #diameter_packet{msg = M}} = event(Svc),
+ {{up, Ref, {TPid, Caps}, T, #diameter_packet{msg = M}}, _}
+ = {event(Svc), T},
['CEA' | #{}] = M, %% assert
{watchdog, Ref, _, {initial, okay}, _} = event(Svc),
%% Kill the transport process and see that the connection is
%% reestablished after a watchdog timeout, not after connect_timer
%% expiry.
exit(TPid, kill),
- {down, Ref, {TPid, Caps}, Cfg} = event(Svc),
+ {{down, Ref, {TPid, Caps}, T}, _} = {event(Svc), T},
{watchdog, Ref, _, {okay, down}, _} = event(Svc),
{reconnect, Ref, _} = event(Svc, 10000, 20000).
@@ -127,24 +138,25 @@ up(Config) ->
%% to indicate as much and then for the transport to be restarted
%% (after connect_timer).
down(Config) ->
- {Svc, Ref} = connect(Config, [{capabilities, [{'Acct-Application-Id',
- [?DICT_ACCT:id()]}]},
- {applications, [?DICT_ACCT]},
- {connect_timer, 5000},
- {watchdog_timer, 20000}]),
+ {Svc, Ref, T} = connect(Config, [{capabilities, [{'Acct-Application-Id',
+ [?DICT_ACCT:id()]}]},
+ {applications, [?DICT_ACCT]},
+ {connect_timer, 5000},
+ {watchdog_timer, 20000}]),
start = event(Svc),
- {closed, Ref, {'CEA', ?NO_COMMON_APP, _, #diameter_packet{msg = M}}, _}
- = event(Svc),
+ {{closed, Ref, {'CEA', ?NO_COMMON_APP, _, #diameter_packet{msg = M}}, T},
+ _}
+ = {event(Svc), T},
['CEA' | #{}] = M, %% assert
{reconnect, Ref, _} = event(Svc, 4000, 10000).
%% Connect with matching capabilities but have the server delay its
%% CEA and cause the client to timeout.
cea_timeout(Config) ->
- {Svc, Ref} = connect(Config, [{capx_timeout, ?SERVER_CAPX_TMO div 2},
- {connect_timer, 2*?SERVER_CAPX_TMO}]),
+ {Svc, Ref, T} = connect(Config, [{capx_timeout, ?SERVER_CAPX_TMO div 2},
+ {connect_timer, 2*?SERVER_CAPX_TMO}]),
start = event(Svc),
- {closed, Ref, {'CEA', timeout}, _} = event(Svc).
+ {{closed, Ref, {'CEA', timeout}, T}, _} = {event(Svc), T}.
stop(_Config) ->
ok = diameter:stop().
@@ -168,8 +180,9 @@ connect(Config, Opts) ->
Name = Pre ++ uniq() ++ ?CLIENT,
diameter:subscribe(Name),
ok = start_service(Name, ?SERVICE(Name, [?DICT_COMMON, ?DICT_ACCT])),
- {ok, Ref} = diameter:add_transport(Name, opts(Config, Opts)),
- {Name, Ref}.
+ {connect, _} = T = opts(Config, Opts),
+ {ok, Ref} = diameter:add_transport(Name, T),
+ {Name, Ref, T}.
uniq() ->
"-" ++ diameter_util:unique_string().
diff --git a/lib/diameter/test/diameter_examples_SUITE.erl b/lib/diameter/test/diameter_examples_SUITE.erl
index ee44ed8dc9..7d47efd527 100644
--- a/lib/diameter/test/diameter_examples_SUITE.erl
+++ b/lib/diameter/test/diameter_examples_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2020. 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,6 +27,8 @@
-export([suite/0,
all/0,
groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
init_per_group/2,
end_per_group/2]).
@@ -85,6 +87,13 @@ groups() ->
[{all, [parallel], [{group, P} || P <- ?PROTS]}
| [{P, [], Tc} || P <- ?PROTS]].
+%% Not used, but a convenient place to enable trace.
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
init_per_group(all, Config) ->
Config;
@@ -216,12 +225,14 @@ make_name(Dict) ->
%% Compile example code under examples/code.
code(Config) ->
- Node = slave(compile, here()),
- [] = rpc:call(Node,
- ?MODULE,
- install,
- [proplists:get_value(priv_dir, Config)]),
- {ok, Node} = ct_slave:stop(compile).
+ try
+ [] = rpc:call(slave(compile, here()),
+ ?MODULE,
+ install,
+ [proplists:get_value(priv_dir, Config)])
+ after
+ {ok, _} = ct_slave:stop(compile)
+ end.
%% Compile on another node since the code path may be modified.
install(PrivDir) ->
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index 47b00c25a2..452bd28333 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -128,7 +128,7 @@
%% ===========================================================================
%% Fraction of shuffle/parallel groups to randomly skip.
--define(SKIP, 0.25).
+-define(SKIP, 0.90).
%% Positive number of testcases from which to select (randomly) from
%% tc(), the list of testcases to run, or [] to run all. The random
@@ -305,7 +305,8 @@ names() ->
S <- ?STRING_DECODES,
ST <- ?CALLBACKS,
SS <- ?SENDERS,
- CS <- ?SENDERS].
+ CS <- ?SENDERS,
+ ?SKIP =< rand:uniform()].
names(Names, []) ->
[N || N <- Names,
@@ -336,14 +337,9 @@ init_per_group(_) ->
init_per_group(Name, Config)
when Name == shuffle;
Name == parallel ->
- case rand:uniform() < ?SKIP of
- true ->
- {skip, random};
- false ->
- start_services(Config),
- add_transports(Config),
- replace({sleep, Name == parallel}, Config)
- end;
+ start_services(Config),
+ add_transports(Config),
+ replace({sleep, Name == parallel}, Config);
init_per_group(sctp = Name, Config) ->
{_, Sctp} = lists:keyfind(Name, 1, Config),
diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk
index a8fbca5bc8..e72b6216a7 100644
--- a/lib/diameter/vsn.mk
+++ b/lib/diameter/vsn.mk
@@ -17,5 +17,5 @@
# %CopyrightEnd%
APPLICATION = diameter
-DIAMETER_VSN = 2.2.1
+DIAMETER_VSN = 2.2.2
APP_VSN = $(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index a1f1128124..63b34f23a4 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -133,6 +133,7 @@ is_safe({hipe_bs_primop, {bs_append, _, _, _, _}}) -> false;
is_safe({hipe_bs_primop, {bs_private_append, _, _}}) -> false;
is_safe({hipe_bs_primop, bs_init_writable}) -> true;
is_safe(build_stacktrace) -> true;
+is_safe(raw_raise) -> false;
is_safe(#mkfun{}) -> true;
is_safe(#unsafe_element{}) -> true;
is_safe(#unsafe_update_element{}) -> true;
diff --git a/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl b/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl
index ba9c03d4ba..9f79231e5a 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_exceptions.erl
@@ -25,6 +25,7 @@ test() ->
ok = test_guard_bif(),
ok = test_eclectic(),
ok = test_raise(),
+ ok = test_effect(),
ok.
%%--------------------------------------------------------------------
@@ -675,4 +676,18 @@ do_test_raise_3(Expr) ->
erlang:raise(exit, {exception,C,E}, Stk)
end.
+test_effect() ->
+ ok = effect_try(2),
+ {'EXIT',{badarith,_}} = (catch effect_try(bad)),
+ ok.
+
+effect_try(X) ->
+ try
+ X + 1
+ catch
+ C:E:Stk ->
+ erlang:raise(C, E, Stk)
+ end,
+ ok.
+
id(I) -> I.
diff --git a/lib/kernel/doc/src/erl_epmd.xml b/lib/kernel/doc/src/erl_epmd.xml
index 2adbf11a28..31f49a05cb 100644
--- a/lib/kernel/doc/src/erl_epmd.xml
+++ b/lib/kernel/doc/src/erl_epmd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2018</year><year>2018</year>
+ <year>2018</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,7 +36,7 @@
<p>This module communicates with the EPMD daemon, see <seealso
marker="erts:epmd">epmd</seealso>. To implement your own epmd module please
see <seealso marker="erts:alt_disco">ERTS User's Guide: How to Implement an
- Alternative Service Discovery for Erlang Distribution</seealso></p>
+ Alternative Node Discovery for Erlang Distribution</seealso></p>
</description>
<funcs>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 39da9ef3d6..7cf7ab3b4d 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2018</year>
+ <year>2004</year><year>2019</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1048,7 +1048,7 @@
marker="kernel:erl_epmd"><c>erl_epmd</c></seealso>
reference manual and ERTS User's Guide <seealso
marker="erts:alt_disco">How to Implement an Alternative
- Service Discovery for Erlang Distribution</seealso>.</p>
+ Node Discovery for Erlang Distribution</seealso>.</p>
<p>
Own Id: OTP-15086 Aux Id: PR-1694 </p>
</item>
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 68e1205301..5469d8694c 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1437,11 +1437,16 @@ error_msg(Format, Args) ->
%% This is equal to calling logger:error/3 which we don't want to
%% do from code_server. We don't want to call logger:timestamp()
%% either.
- logger ! {log,error,Format,Args,
- #{pid=>self(),
- gl=>group_leader(),
- time=>os:system_time(microsecond),
- error_logger=>#{tag=>error}}},
+ _ = try
+ logger ! {log,error,Format,Args,
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>os:system_time(microsecond),
+ error_logger=>#{tag=>error}}}
+ catch _:_ ->
+ erlang:display({?MODULE,error}),
+ erlang:display({Format,Args})
+ end,
ok.
-spec info_msg(io:format(), [term()]) -> 'ok'.
@@ -1449,11 +1454,11 @@ info_msg(Format, Args) ->
%% This is equal to calling logger:info/3 which we don't want to
%% do from code_server. We don't want to call logger:timestamp()
%% either.
- logger ! {log,info,Format,Args,
- #{pid=>self(),
- gl=>group_leader(),
- time=>os:system_time(microsecond),
- error_logger=>#{tag=>info_msg}}},
+ catch logger ! {log,info,Format,Args,
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>os:system_time(microsecond),
+ error_logger=>#{tag=>info_msg}}},
ok.
objfile_extension() ->
diff --git a/lib/kernel/src/logger_config.erl b/lib/kernel/src/logger_config.erl
index 5024d20cfe..af8ebfd4e9 100644
--- a/lib/kernel/src/logger_config.erl
+++ b/lib/kernel/src/logger_config.erl
@@ -41,7 +41,7 @@ delete(Tid,Id) ->
allow(Tid,Level,Module) ->
LevelInt = level_to_int(Level),
- case ets:lookup(Tid,Module) of
+ try ets:lookup(Tid,Module) of
[{Module,{ModLevel,cached}}] when is_integer(ModLevel),
LevelInt =< ModLevel ->
true;
@@ -53,11 +53,17 @@ allow(Tid,Level,Module) ->
allow(Tid,Level);
_ ->
false
+ catch error:badarg ->
+ true
end.
allow(Tid,Level) ->
- GlobalLevelInt = ets:lookup_element(Tid,?PRIMARY_KEY,2),
- level_to_int(Level) =< GlobalLevelInt.
+ try ets:lookup_element(Tid,?PRIMARY_KEY,2) of
+ GlobalLevelInt ->
+ level_to_int(Level) =< GlobalLevelInt
+ catch error:badarg ->
+ true
+ end.
exist(Tid,What) ->
ets:member(Tid,table_key(What)).
diff --git a/lib/kernel/src/logger_proxy.erl b/lib/kernel/src/logger_proxy.erl
index 24b293805c..6ab8e3e4c5 100644
--- a/lib/kernel/src/logger_proxy.erl
+++ b/lib/kernel/src/logger_proxy.erl
@@ -42,11 +42,16 @@
StringOrReport :: unicode:chardata() | logger:report(),
Meta :: logger:metadata().
log(RemoteLog) ->
- Olp = persistent_term:get(?MODULE),
- case logger_olp:get_pid(Olp) =:= self() of
+ Olp = persistent_term:get(?MODULE, undefined),
+ case (Olp =:= undefined) orelse (logger_olp:get_pid(Olp) =:= self()) of
true ->
%% This happens when the log event comes from the
%% emulator, and the group leader is on a remote node.
+ %%
+ %% OR
+ %%
+ %% when we are to log a remote message before the logger_proxy
+ %% has started
_ = handle_load(RemoteLog, no_state),
ok;
false ->
@@ -112,9 +117,12 @@ init([]) ->
%% Log event to send to the node where the group leader of it's client resides
handle_load({remote,Node,Log},State) ->
- %% If the connection is overloaded (send_nosuspend returns false),
- %% we drop the message.
- _ = erlang:send_nosuspend({?SERVER,Node},Log),
+ case erlang:send({?SERVER,Node},Log,[nosuspend]) of
+ _ok_or_nosuspend ->
+ %% If the connection is overloaded (send returns nosuspend),
+ %% we drop the message.
+ ok
+ end,
State;
%% Log event to log on this node
handle_load({log,Level,Format,Args,Meta},State) ->
diff --git a/lib/kernel/test/logger_proxy_SUITE.erl b/lib/kernel/test/logger_proxy_SUITE.erl
index 777531e4ed..bae2bd8d17 100644
--- a/lib/kernel/test/logger_proxy_SUITE.erl
+++ b/lib/kernel/test/logger_proxy_SUITE.erl
@@ -72,6 +72,7 @@ all() ->
[basic,
emulator,
remote,
+ remote_disconnect,
remote_emulator,
config,
restart_after,
@@ -118,6 +119,19 @@ remote(Config) ->
remote(cleanup,_Config) ->
ok = logger:remove_handler(?HNAME).
+remote_disconnect(Config) ->
+ {ok,_,Node} = logger_test_lib:setup(Config,[{logger,[{proxy,#{}}]}]),
+ ok = logger:add_handler(?HNAME,?MODULE,#{config=>self()}),
+ RemoteGL = rpc:call(Node, erlang, whereis, [user]),
+ net_kernel:disconnect(Node),
+ L1 = ?LOC#{ gl => RemoteGL }, logger:notice("Log from ~p; ~p",[?FUNCTION_NAME,?LINE],L1),
+ ok = ensure(L1),
+ L2 = ?LOC#{ gl => RemoteGL }, logger:notice([{test_case,?FUNCTION_NAME},{line,?LINE}],L2),
+ ok = ensure(L2),
+ ok.
+remote_disconnect(cleanup,_Config) ->
+ ok = logger:remove_handler(?HNAME).
+
remote_emulator(Config) ->
{ok,_,Node} = logger_test_lib:setup(Config,[{logger,[{proxy,#{}}]}]),
ok = logger:add_handler(?HNAME,?MODULE,#{config=>self()}),
diff --git a/lib/kernel/test/net_SUITE.erl b/lib/kernel/test/net_SUITE.erl
index 4f27628bed..1e657a6cdd 100644
--- a/lib/kernel/test/net_SUITE.erl
+++ b/lib/kernel/test/net_SUITE.erl
@@ -219,6 +219,8 @@ api_b_getifaddrs() ->
i("IfAddrs: "
"~n ~p", [IfAddrs]),
ok;
+ {error, enotsup = Reason} ->
+ skip(Reason);
{error, Reason} ->
?FAIL(Reason)
end.
diff --git a/lib/megaco/test/megaco_codec_flex_lib.erl b/lib/megaco/test/megaco_codec_flex_lib.erl
index e322c21dad..566ab0fe47 100644
--- a/lib/megaco/test/megaco_codec_flex_lib.erl
+++ b/lib/megaco/test/megaco_codec_flex_lib.erl
@@ -60,6 +60,8 @@ init(Config) when is_list(Config) ->
%% "~n", [?MODULE, Res]),
process_flag(trap_exit, Flag),
case Res of
+ {error, {failed_loading_flex_scanner_driver, Reason}} ->
+ skip(?F("Failed loading flex driver: ~p", [Reason]));
{error, Reason} ->
skip(Reason);
{ok, FlexConfig} ->
diff --git a/lib/megaco/test/megaco_mess_SUITE.erl b/lib/megaco/test/megaco_mess_SUITE.erl
index 0e4d2b90cb..f3dfc053c6 100644
--- a/lib/megaco/test/megaco_mess_SUITE.erl
+++ b/lib/megaco/test/megaco_mess_SUITE.erl
@@ -9896,10 +9896,10 @@ otp_6442_resend_request1(Config) when is_list(Config) ->
try_tc(otp6442rreq1, Pre, Case, Post).
do_otp_6442_resend_request1([MgNode]) ->
- d("[MG] start the simulator "),
+ d("[MG] start the simulator"),
{ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
- d("[MG] create the event sequence"),
+ d("[MG] create the event sequence (~p)", [Mg]),
MgMid = {deviceName,"mg"},
MgEvSeq = otp_6442_resend_request1_mg_event_sequence(MgMid),
@@ -10103,11 +10103,6 @@ otp_6442_resend_request1_mg_event_sequence(Mid) ->
?otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
NotifyReplyVerify =
?otp_6442_resend_request1_mg_verify_notify_rep_fun(),
- %% ConnectVerify =
- %% otp_6442_resend_request1_mg_verify_handle_connect_fun(),
- %% ServiceChangeReplyVerify =
- %% otp_6442_resend_request1_mg_verify_service_change_reply_fun(),
- %% NotifyReplyVerify = otp_6442_resend_request1_mg_verify_notify_reply_fun(),
EvSeq = [
{debug, false},
megaco_start,
diff --git a/lib/megaco/test/megaco_mib_SUITE.erl b/lib/megaco/test/megaco_mib_SUITE.erl
index 8763145bbc..e040705b05 100644
--- a/lib/megaco/test/megaco_mib_SUITE.erl
+++ b/lib/megaco/test/megaco_mib_SUITE.erl
@@ -53,8 +53,8 @@
-include("megaco_test_lib.hrl").
-define(TEST_VERBOSITY, info). % silence | info | debug
--define(MGC_VERBOSITY, info).
--define(MG_VERBOSITY, info).
+-define(MGC_VERBOSITY, debug).
+-define(MG_VERBOSITY, debug).
-define(LOAD_COUNTER_START, 100).
-define(A4444, ["11111111", "00000000", "00000000"]).
@@ -292,28 +292,40 @@ connect(suite) ->
connect(doc) ->
[];
connect(Config) when is_list(Config) ->
- put(verbosity, ?TEST_VERBOSITY),
- put(sname, "TEST"),
- i("connect -> starting"),
- progress("start nodes"),
- MgcNode = make_node_name(mgc),
- Mg1Node = make_node_name(mg1),
- Mg2Node = make_node_name(mg2),
- d("connect -> Nodes: "
- "~n MgcNode: ~p"
- "~n Mg1Node: ~p"
- "~n Mg2Node: ~p", [MgcNode, Mg1Node, Mg2Node]),
- ok = ?START_NODES([MgcNode, Mg1Node, Mg2Node]),
-
+ Pre = fun() ->
+ progress("start nodes"),
+ MgcNode = make_node_name(mgc),
+ Mg1Node = make_node_name(mg1),
+ Mg2Node = make_node_name(mg2),
+ d("connect -> Nodes: "
+ "~n MgcNode: ~p"
+ "~n Mg1Node: ~p"
+ "~n Mg2Node: ~p", [MgcNode, Mg1Node, Mg2Node]),
+ Nodes = [MgcNode, Mg1Node, Mg2Node],
+ ok = ?START_NODES(Nodes, true),
+ Nodes
+ end,
+ Case = fun do_connect/1,
+ Post = fun(Nodes) ->
+ progress("stop nodes"),
+ d("stop nodes"),
+ ?STOP_NODES(lists:reverse(Nodes))
+ end,
+ try_tc(connect, Pre, Case, Post).
+
+do_connect([MgcNode, Mg1Node, Mg2Node]) ->
%% Start the MGC and MGs
- ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}],
- progress("start MGC"),
+
+ ET = [{text, tcp}, {text, udp}, {binary, tcp}, {binary, udp}],
+ progress("start MGC (on ~p)", [MgcNode]),
{ok, Mgc} =
start_mgc(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY),
- progress("start MG1"),
+
+ progress("start MG1 (on ~p) using tcp", [Mg1Node]),
{ok, Mg1} =
start_mg(Mg1Node, {deviceName, "mg1"}, text, tcp, ?MG_VERBOSITY),
- progress("start MG2"),
+
+ progress("start MG2 (on ~p) using udp", [Mg2Node]),
{ok, Mg2} =
start_mg(Mg2Node, {deviceName, "mg2"}, binary, udp, ?MG_VERBOSITY),
@@ -385,7 +397,6 @@ connect(Config) when is_list(Config) ->
stop(Mgc),
i("connect -> done", []),
- progress("done"),
ok.
@@ -397,27 +408,36 @@ traffic(suite) ->
traffic(doc) ->
[];
traffic(Config) when is_list(Config) ->
- put(verbosity, ?TEST_VERBOSITY),
- put(sname, "TEST"),
- i("traffic -> starting"),
- progress("start nodes"),
- MgcNode = make_node_name(mgc),
- Mg1Node = make_node_name(mg1),
- Mg2Node = make_node_name(mg2),
- Mg3Node = make_node_name(mg3),
- Mg4Node = make_node_name(mg4),
- d("traffic -> Nodes: "
- "~n MgcNode: ~p"
- "~n Mg1Node: ~p"
- "~n Mg2Node: ~p"
- "~n Mg3Node: ~p"
- "~n Mg4Node: ~p",
- [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
- ok = ?START_NODES([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
-
+ Pre = fun() ->
+ progress("start nodes"),
+ MgcNode = make_node_name(mgc),
+ Mg1Node = make_node_name(mg1),
+ Mg2Node = make_node_name(mg2),
+ Mg3Node = make_node_name(mg3),
+ Mg4Node = make_node_name(mg4),
+ Nodes = [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node],
+ d("traffic -> Nodes: "
+ "~n MgcNode: ~p"
+ "~n Mg1Node: ~p"
+ "~n Mg2Node: ~p"
+ "~n Mg3Node: ~p"
+ "~n Mg4Node: ~p",
+ [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
+ ok = ?START_NODES(Nodes, true),
+ Nodes
+ end,
+ Case = fun do_traffic/1,
+ Post = fun(Nodes) ->
+ progress("stop nodes"),
+ d("stop nodes"),
+ ?STOP_NODES(lists:reverse(Nodes))
+ end,
+ try_tc(traffic, Pre, Case, Post).
+
+do_traffic([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) ->
%% Start the MGC and MGs
- i("traffic -> start the MGC"),
- progress("start MGC"),
+ i("start the MGC"),
+ progress("start MGC (on ~p)", [MgcNode]),
ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}],
{ok, Mgc} =
start_mgc(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY),
@@ -550,7 +570,6 @@ traffic(Config) when is_list(Config) ->
stop(Mgc),
i("traffic -> done", []),
- progress("done"),
ok.
@@ -671,10 +690,12 @@ traffic_connect_mg([{Node, Name, Coding, Trans}|Mg], Acc) ->
traffic_connect_mg(Mg, [{Name, Pid}|Acc]).
traffic_connect_mg(Node, Name, Coding, Trans) ->
+ progress("start (and connect) ~s (on ~p) using ~p", [Name, Node, Trans]),
Mid = {deviceName, Name},
{ok, Pid} = start_mg(Node, Mid, Coding, Trans, ?MG_VERBOSITY),
%% Ask the MGs to do a service change
+ progress("perform ~s service change", [Name]),
{ok, Res} = service_change(Pid),
d("traffic_connect_mg -> (~s) service change result: ~p", [Name, Res]),
Pid.
@@ -831,8 +852,12 @@ mgc_init(Config) ->
RH = megaco:user_info(Mid,receive_handle),
d("mgc_init -> parse receive info"),
ListenTo = mgc_parse_receive_info(RI, RH),
- i("mgc_init -> start transport(s)"),
+ i("mgc_init -> start transport(s) with:"
+ "~n ListenTo: ~p", [ListenTo]),
{Tcp, Udp} = mgc_start_transports(ListenTo),
+ i("mgc_init -> transport(s) started:"
+ "~n Tcp: ~p"
+ "~n Udp: ~p", [Tcp, Udp]),
{Mid, Tcp, Udp}.
@@ -1247,10 +1272,15 @@ mg_loop(#mg{state = State} = S) ->
%% Do a service change
{service_change, Parent} when S#mg.parent == Parent,
State == initiated ->
- i("mg_loop(~p) -> received request to perform service change",
- [State]),
+ i("mg_loop(~p) -> received request to perform service change when:"
+ "~n Conn Handle: ~p"
+ "~n Conn Data: ~p",
+ [State,
+ S#mg.conn_handle,
+ megaco:conn_info(S#mg.conn_handle, conn_data)]),
Res = mg_service_change(S#mg.conn_handle),
- d("mg_loop(~p) -> result: ~p", [State, Res]),
+ d("mg_loop(~p) -> service change request send result: ~p",
+ [State, Res]),
mg_loop(S#mg{state = connecting});
@@ -1358,9 +1388,12 @@ mg_start_tcp(MgcPort, RH) ->
{port, MgcPort},
{receive_handle, RH},
{tcp_options, [{nodelay, true}]}],
+ i("tcp transport started: attempt (tcp) connect to MGC at:"
+ "~n ~p", [LocalHost]),
case megaco_tcp:connect(Sup, Opts) of
{ok, SendHandle, ControlPid} ->
PrelMgcMid = preliminary_mid,
+ i("tcp transport (tcp) connected: attempt (megaco) connect:"),
{ok, ConnHandle} =
megaco:connect(RH, PrelMgcMid,
SendHandle, ControlPid),
@@ -1382,12 +1415,18 @@ mg_start_udp(MgcPort, RH) ->
%% local host. Try instead to "figure out" tha actual address...
LocalAddr = which_local_addr(),
Opts = [{port, 0}, {receive_handle, RH}],
+ i("udp transport started: attempt (udp) open"),
case megaco_udp:open(Sup, Opts) of
{ok, Handle, ControlPid} ->
MgcMid = preliminary_mid,
+ i("udp transport open: "
+ "now create send handle with MGC address: "
+ "~n ~p", [LocalAddr]),
SendHandle = megaco_udp:create_send_handle(Handle,
LocalAddr,
MgcPort),
+ i("udp transport: attempt (megaco) connect to:"
+ "~n ~p", [SendHandle]),
{ok, ConnHandle} =
megaco:connect(RH, MgcMid,
SendHandle, ControlPid),
@@ -1712,6 +1751,7 @@ get_conf(Key, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Tries to find a valid local address...
which_local_addr() ->
case inet:getifaddrs() of
{ok, IFs} ->
@@ -1722,10 +1762,10 @@ which_local_addr() ->
?SKIP({failed_get_local_addr, Reason})
end.
+%% We explicitly skip some interfaces that we know is not "valid"
+%% (docker stuff)
which_local_addr([]) ->
?SKIP(failed_get_local_addr);
-which_local_addr([{"lo" = _IfName, _IfOpts}|IFs]) ->
- which_local_addr(IFs);
which_local_addr([{"br-" ++ _ = _IfName, _IfOpts}|IFs]) ->
which_local_addr(IFs);
which_local_addr([{"docker" ++ _ = _IfName, _IfOpts}|IFs]) ->
@@ -1738,14 +1778,38 @@ which_local_addr([{_IfName, IfOpts}|IFs]) ->
which_local_addr(IFs)
end.
+which_local_addr2(IfOpts) ->
+ case if_is_running(IfOpts) of
+ true ->
+ which_local_addr3(IfOpts);
+ false ->
+ error
+ end.
-which_local_addr2([]) ->
+if_is_running(If) ->
+ lists:keymember(flags, 1, If) andalso
+ begin
+ {value, {flags, Flags}} = lists:keysearch(flags, 1, If),
+ (not lists:member(loopback, Flags)) andalso lists:member(running, Flags)
+ end.
+
+which_local_addr3([]) ->
error;
-which_local_addr2([{addr, Addr}|_])
+which_local_addr3([{addr, Addr}|_])
when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) ->
{ok, Addr};
-which_local_addr2([_|T]) ->
- which_local_addr2(T).
+which_local_addr3([_|T]) ->
+ which_local_addr3(T).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+try_tc(TCName, Pre, Case, Post) ->
+ try_tc(TCName, "TEST", ?TEST_VERBOSITY, Pre, Case, Post).
+
+try_tc(TCName, Name, Verbosity, Pre, Case, Post) ->
+ ?TRY_TC(TCName, Name, Verbosity, Pre, Case, Post).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_segment_SUITE.erl b/lib/megaco/test/megaco_segment_SUITE.erl
index 018625d9cb..08b86606de 100644
--- a/lib/megaco/test/megaco_segment_SUITE.erl
+++ b/lib/megaco/test/megaco_segment_SUITE.erl
@@ -47,6 +47,7 @@
]).
+-include_lib("common_test/include/ct.hrl").
-include("megaco_test_lib.hrl").
-include_lib("megaco/include/megaco.hrl").
-include_lib("megaco/include/megaco_message_v3.hrl").
@@ -2103,6 +2104,8 @@ send_segmented_msg_plain4(doc) ->
"Forth plain test that it is possible to send segmented messages. "
"Send window = 3. ";
send_segmented_msg_plain4(Config) when is_list(Config) ->
+ Factor = ?config(megaco_factor, Config),
+ ct:timetrap(Factor * ?SECS(60)),
Pre = fun() ->
MgcNode = make_node_name(mgc),
MgNode = make_node_name(mg),
@@ -2114,19 +2117,19 @@ send_segmented_msg_plain4(Config) when is_list(Config) ->
ok = ?START_NODES(Nodes),
Nodes
end,
- Case = fun do_send_segmented_msg_plain4/1,
+ Case = fun(X) -> do_send_segmented_msg_plain4(Factor, X) end,
Post = fun(Nodes) ->
d("stop nodes"),
?STOP_NODES(lists:reverse(Nodes))
end,
try_tc(ssmp4, Pre, Case, Post).
-do_send_segmented_msg_plain4([MgcNode, MgNode]) ->
+do_send_segmented_msg_plain4(Factor, [MgcNode, MgNode]) ->
d("[MGC] start the simulator "),
{ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
d("[MGC] create the event sequence"),
- MgcEvSeq = ssmp4_mgc_event_sequence(text, tcp),
+ MgcEvSeq = ssmp4_mgc_event_sequence(Factor, text, tcp),
i("wait some time before starting the MGC simulation"),
sleep(1000),
@@ -2141,7 +2144,7 @@ do_send_segmented_msg_plain4([MgcNode, MgNode]) ->
{ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
d("[MG] create the event sequence"),
- MgEvSeq = ssmp4_mg_event_sequence(text, tcp),
+ MgEvSeq = ssmp4_mg_event_sequence(Factor, text, tcp),
i("wait some time before starting the MG simulation"),
sleep(1000),
@@ -2169,7 +2172,7 @@ do_send_segmented_msg_plain4([MgcNode, MgNode]) ->
%% MGC generator stuff
%%
-ssmp4_mgc_event_sequence(text, tcp) ->
+ssmp4_mgc_event_sequence(Factor, text, tcp) ->
DecodeFun = ssmp4_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
EncodeFun = ssmp4_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
Mid = {deviceName,"mgc"},
@@ -2238,33 +2241,38 @@ ssmp4_mgc_event_sequence(text, tcp) ->
SegmentRep7 = ssmp4_mgc_segment_reply_msg(Mid, TransId, 7, false),
SegmentRep8 = ssmp4_mgc_segment_reply_msg(Mid, TransId, 8, true),
TransAck = ssmp4_mgc_trans_ack_msg(Mid, TransId),
+ TO = fun(T) -> Factor*T end,
EvSeq = [{debug, true},
+ {trigger, "verbosity",
+ fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{decode, DecodeFun},
{encode, EncodeFun},
{listen, 2944},
{expect_accept, any},
- {expect_receive, "service-change-request", {ScrVerifyFun, 5000}},
+ {expect_receive, "service-change-request", {ScrVerifyFun, TO(5000)}},
{send, "service-change-reply", ServiceChangeRep},
{expect_nothing, 1000},
{send, "notify request", NotifyReq},
- {expect_receive, "notify reply: segment 1", {NrVerifyFun1, 1000}},
- {expect_receive, "notify reply: segment 2", {NrVerifyFun2, 1000}},
- {expect_receive, "notify reply: segment 3", {NrVerifyFun3, 1000}},
+ {expect_receive, "notify reply: segment 1", {NrVerifyFun1, TO(1000)}},
+ {expect_receive, "notify reply: segment 2", {NrVerifyFun2, TO(1000)}},
+ {expect_receive, "notify reply: segment 3", {NrVerifyFun3, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 1", SegmentRep1},
- {expect_receive, "notify reply: segment 4", {NrVerifyFun4, 1000}},
+ {expect_receive, "notify reply: segment 4", {NrVerifyFun4, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 2", SegmentRep2},
- {expect_receive, "notify reply: segment 5", {NrVerifyFun5, 1000}},
+ {expect_receive, "notify reply: segment 5", {NrVerifyFun5, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 3", SegmentRep3},
- {expect_receive, "notify reply: segment 6", {NrVerifyFun6, 1000}},
+ {expect_receive, "notify reply: segment 6", {NrVerifyFun6, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 4", SegmentRep4},
- {expect_receive, "notify reply: segment 7", {NrVerifyFun7, 1000}},
+ {expect_receive, "notify reply: segment 7", {NrVerifyFun7, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 5", SegmentRep5},
- {expect_receive, "notify reply: segment 8", {NrVerifyFun8, 1000}},
+ {expect_receive, "notify reply: segment 8", {NrVerifyFun8, TO(1000)}},
{expect_nothing, 1000},
{send, "segment reply 6", SegmentRep6},
{expect_nothing, 1000},
@@ -2531,7 +2539,7 @@ ssmp4_mgc_trans_ack_msg(Mid, TransId) ->
%%
%% MG generator stuff
%%
-ssmp4_mg_event_sequence(text, tcp) ->
+ssmp4_mg_event_sequence(Factor, text, tcp) ->
Mid = {deviceName,"mg"},
RI = [
{port, 2944},
@@ -2552,7 +2560,8 @@ ssmp4_mg_event_sequence(text, tcp) ->
Tid8 = #megaco_term_id{id = ["00000000","00000000","00000008"]},
Tids = [Tid1, Tid2, Tid3, Tid4, Tid5, Tid6, Tid7, Tid8],
NotifyReqVerify = ssmp4_mg_verify_notify_request_fun(Tids),
- AckVerify = ssmp4_mg_verify_ack_fun(),
+ AckVerify = ssmp4_mg_verify_ack_fun(),
+ TO = fun(T) -> Factor*T end,
EvSeq = [
{debug, true},
{megaco_trace, disable},
@@ -2573,7 +2582,7 @@ ssmp4_mg_event_sequence(text, tcp) ->
{megaco_update_conn_info, max_pdu_size, 128},
{sleep, 1000},
{megaco_callback, handle_trans_request, NotifyReqVerify},
- {megaco_callback, handle_trans_ack, AckVerify, 15000},
+ {megaco_callback, handle_trans_ack, AckVerify, TO(15000)},
megaco_stop_user,
megaco_stop,
{sleep, 1000}
@@ -2661,30 +2670,34 @@ ssmp4_mg_verify_notify_request_fun(Tids) ->
ssmp4_mg_verify_notify_request(
{handle_trans_request, _CH, ?VERSION, ARs}, Tids)
- when length(ARs) == length(Tids) ->
+ when length(ARs) =:= length(Tids) ->
(catch ssmp4_mg_do_verify_notify_request(Tids, ARs));
ssmp4_mg_verify_notify_request(
{handle_trans_request, _CH, ?VERSION, ARs}, _Tids) ->
+ e("MG Notify Request verification failed: invalid action requests"
+ "~n ARs: ~p", [ARs]),
{error, {invalid_action_requests, ARs}, ok};
ssmp4_mg_verify_notify_request(
{handle_trans_request, CH, V, ARs}, _Tids) ->
+ e("MG Notify Request verification failed: invalid trans request"
+ "~n CH: ~p"
+ "~n V: ~p"
+ "~n ARs: ~p", [CH, V, ARs]),
{error, {invalid_trans_request, {CH, V, ARs}}, ok};
ssmp4_mg_verify_notify_request(Crap, _Tids) ->
- io:format("ssmp4_mg_verify_notify_request -> unknown request"
- "~n Crap: ~p"
- "~n Tids: ~p"
- "~n", [Crap, _Tids]),
+ e("MG Notify Request verification failed: unknown request"
+ "~n Crap: ~p"
+ "~n Tids: ~p", [Crap, _Tids]),
{error, {unexpected_event, Crap}, ok}.
ssmp4_mg_do_verify_notify_request(Tids, ARs) ->
- io:format("ssmp4_mg_do_verify_notify_request -> ok"
- "~n Tids: ~p"
- "~n ARs: ~p"
- "~n", [Tids, ARs]),
+ p("MG Notify Request verification - attempt verify action request(s):"
+ "~n Tids: ~p"
+ "~n ARs: ~p", [Tids, ARs]),
ActionReplies = ssmp4_mg_do_verify_notify_request_ars(Tids, ARs),
- io:format("ssmp4_mg_do_verify_notify_request -> ok"
- "~n ActionReplies: ~p"
- "~n", [ActionReplies]),
+ p("MG Notify Request verification - ok"
+ "~n ActionReplies: ~p"
+ "~n", [ActionReplies]),
Reply = {{handle_ack, ssmp4}, ActionReplies},
{ok, ARs, Reply}.
@@ -2698,10 +2711,9 @@ ssmp4_mg_do_verify_notify_request_ars([Tid|Tids], [AR|ARs], Acc) ->
ssmp4_mg_do_verify_notify_request_ars(Tids, ARs, [ActionReply|Acc]).
ssmp4_mg_do_verify_notify_request_ar(Tid, AR) ->
- io:format("ssmp4_mg_do_verify_notify_request_ar -> ok"
- "~n Tid: ~p"
- "~n AR: ~p"
- "~n", [Tid, AR]),
+ p("ssmp4_mg_do_verify_notify_request_ar -> ok"
+ "~n Tid: ~p"
+ "~n AR: ~p", [Tid, AR]),
{Cid, CR} =
case AR of
#'ActionRequest'{contextId = CtxId,
@@ -3648,6 +3660,10 @@ ssmmsr1_mgc_event_sequence(text, tcp) ->
TransAck = ssmmsr1_mgc_trans_ack_msg(Mid, TransId),
ReadyForSegments = ssmmsr1_mgc_ready_for_segments_fun(),
EvSeq = [{debug, true},
+ {trigger, "verbosity",
+ fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{decode, DecodeFun},
{encode, EncodeFun},
{listen, 2944},
@@ -3977,6 +3993,10 @@ ssmmsr1_mg_event_sequence(text, tcp) ->
ReadyForSegments = ssmmsr1_mg_ready_for_segments_fun(),
EvSeq = [
{debug, true},
+ {trigger,
+ fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{megaco_trace, disable},
%% {megaco_trace, max},
megaco_start,
@@ -4393,6 +4413,10 @@ ssmmsr2_mgc_event_sequence(text, tcp) ->
SegmentRep1 = ssmmsr2_mgc_segment_reply_msg(Mid, TransId, 1, false),
ReadyForSegments = ssmmsr2_mgc_ready_for_segments_fun(),
EvSeq = [{debug, true},
+ {trigger, "verbosity",
+ fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{decode, DecodeFun},
{encode, EncodeFun},
{listen, 2944},
@@ -4701,6 +4725,10 @@ ssmmsr2_mg_event_sequence(text, tcp) ->
ReadyForSegments = ssmmsr2_mg_ready_for_segments_fun(),
EvSeq = [
{debug, true},
+ {trigger,
+ fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{megaco_trace, disable},
%% {megaco_trace, max},
megaco_start,
@@ -7912,34 +7940,49 @@ p(F, A) ->
[?FTS(), self() | A]).
+%% e(F) ->
+%% e(F, []).
+
+e(F, A) ->
+ print(error, get(verbosity), "ERROR", get(tc), F, A).
+
+
i(F) ->
i(F, []).
i(F, A) ->
- print(info, get(verbosity), get(tc), "INF", F, A).
+ print(info, get(verbosity), "INFO", get(tc), F, A).
d(F) ->
d(F, []).
d(F, A) ->
- print(debug, get(verbosity), get(tc), "DBG", F, A).
+ print(debug, get(verbosity), "DBG", get(tc), F, A).
printable(_, debug) -> true;
printable(info, info) -> true;
+printable(error, _) -> true;
printable(_,_) -> false.
-print(Severity, Verbosity, Tc, P, F, A) ->
- print(printable(Severity, Verbosity), Tc, P, F, A).
+print(Severity, Verbosity, P, TC, F, A) ->
+ print(printable(Severity, Verbosity), P, TC, F, A).
-print(true, Tc, P, F, A) ->
- io:format("*** [~s] ~s ~p ~s:~w ***"
- "~n " ++ F ++ "~n",
- [?FTS(), P, self(), get(sname), Tc | A]);
+print(true, P, TC, F, A) when (TC =:= undefined) ->
+ print(P, "", F, A);
+print(true, P, TC, F, A) when is_atom(TC) ->
+ print(P, ":" ++ atom_to_list(TC), F, A);
+print(true, P, TC, F, A) when is_list(TC) ->
+ print(P, TC, F, A);
print(_, _, _, _, _) ->
ok.
+print(P, TCStr, F, A) ->
+ io:format("*** [~s] ~s ~p ~s~s ***"
+ "~n " ++ F ++ "~n",
+ [?FTS(), P, self(), get(sname), TCStr | A]).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_test_generator.erl b/lib/megaco/test/megaco_test_generator.erl
index e179f87de8..a7920e7f9e 100644
--- a/lib/megaco/test/megaco_test_generator.erl
+++ b/lib/megaco/test/megaco_test_generator.erl
@@ -423,7 +423,7 @@ handler_main(Parent, Mod, State, []) ->
handler_main(Parent, Mod, State, [Instruction|Instructions]) ->
d("handler_main -> entry with"
- "~n Instruction: ~p", [Instruction]),
+ "~n Instruction: ~p", [Instruction]),
receive
{stop, Parent} ->
d("handler_main -> premature stop requested"),
@@ -435,6 +435,8 @@ handler_main(Parent, Mod, State, [Instruction|Instructions]) ->
Result = (catch Mod:terminate({parent_died, Reason}, State)),
exit({parent_died, Reason, Result})
after 0 ->
+ d("handler_main -> exec: "
+ "~n Instruction: ~p", [Instruction]),
case (catch handler_callback_exec(Mod, State, Instruction)) of
{ok, NewState} ->
handler_main(Parent, Mod, NewState, Instructions);
diff --git a/lib/megaco/test/megaco_test_lib.erl b/lib/megaco/test/megaco_test_lib.erl
index a337224afb..1e4b7841ee 100644
--- a/lib/megaco/test/megaco_test_lib.erl
+++ b/lib/megaco/test/megaco_test_lib.erl
@@ -478,8 +478,29 @@ init_per_suite(Config) ->
%% This version is *not* ok: Skip
true
end,
- COND = [{unix, [{linux, LinuxVersionVerify},
- {darwin, DarwinVersionVerify}]}],
+ %% We are "looking" for a specific machine (a VM)
+ %% which are *old and crappy" and slow, because it
+ %% causes a bunch of test cases to fail randomly.
+ %% But we don not want to test for the host name...
+ WinVersionVerify =
+ fun(V) when (V =:= {6,2,9200}) ->
+ try erlang:system_info(schedulers) of
+ 2 ->
+ true;
+ _ ->
+ false
+ catch
+ _:_:_ ->
+ true
+ end;
+ (_) ->
+ false
+ end,
+ COND = [
+ {unix, [{linux, LinuxVersionVerify},
+ {darwin, DarwinVersionVerify}]}%% ,
+ %% {win32, [{nt, WinVersionVerify}]}
+ ],
case os_based_skip(COND) of
true ->
{skip, "Unstable host and/or os (or combo thererof)"};
@@ -569,14 +590,15 @@ analyze_and_print_host_info() ->
{unix, freebsd} ->
analyze_and_print_freebsd_host_info(Version);
{unix, sunos} ->
- io:format("Solaris: ~s"
- "~n", [Version]),
- 2;
+ analyze_and_print_solaris_host_info(Version);
+ {win32, nt} ->
+ analyze_and_print_win_host_info(Version);
_ ->
io:format("OS Family: ~p"
- "~n OS Type: ~p"
- "~n Version: ~p"
- "~n", [OsFam, OsName, Version]),
+ "~n OS Type: ~p"
+ "~n Version: ~p"
+ "~n Num Schedulers: ~s"
+ "~n", [OsFam, OsName, Version, str_num_schedulers()]),
try erlang:system_info(schedulers) of
1 ->
10;
@@ -591,6 +613,14 @@ analyze_and_print_host_info() ->
10
end
end.
+
+str_num_schedulers() ->
+ try erlang:system_info(schedulers) of
+ N -> f("~w", [N])
+ catch
+ _:_:_ -> "-"
+ end.
+
analyze_and_print_linux_host_info(Version) ->
case file:read_file_info("/etc/issue") of
@@ -607,34 +637,44 @@ analyze_and_print_linux_host_info(Version) ->
case (catch linux_which_cpuinfo()) of
{ok, {CPU, BogoMIPS}} ->
io:format("CPU: "
- "~n Model: ~s"
- "~n BogoMIPS: ~s"
- "~n", [CPU, BogoMIPS]),
+ "~n Model: ~s"
+ "~n BogoMIPS: ~s"
+ "~n Num Schedulers: ~s"
+ "~n", [CPU, BogoMIPS, str_num_schedulers()]),
%% We first assume its a float, and if not try integer
try list_to_float(string:trim(BogoMIPS)) of
- F when F > 1000 ->
+ F when F > 4000 ->
1;
F when F > 1000 ->
2;
+ F when F > 500 ->
+ 3;
_ ->
- 3
+ 5
catch
_:_:_ ->
- %%
try list_to_integer(string:trim(BogoMIPS)) of
- I when I > 1000 ->
+ I when I > 4000 ->
1;
I when I > 1000 ->
2;
+ I when I > 500 ->
+ 3;
_ ->
- 3
+ 5
catch
_:_:_ ->
- 1
+ 5 % Be a "bit" conservative...
end
end;
+ {ok, CPU} ->
+ io:format("CPU: "
+ "~n Model: ~s"
+ "~n Num Schedulers: ~s"
+ "~n", [CPU, str_num_schedulers()]),
+ 2; % Be a "bit" conservative...
_ ->
- 1
+ 5 % Be a "bit" (more) conservative...
end,
%% Check if we need to adjust the factor because of the memory
try linux_which_meminfo() of
@@ -704,9 +744,9 @@ linux_which_meminfo() ->
(MemSz3 >= 4194304) ->
1;
(MemSz3 >= 2097152) ->
- 2;
+ 3;
true ->
- 3
+ 5
end;
_X ->
0
@@ -813,47 +853,43 @@ analyze_and_print_freebsd_host_info(Version) ->
io:format("FreeBSD:"
"~n Version: ~p"
"~n", [Version]),
- Extract =
- fun(Key) ->
- string:tokens(string:trim(os:cmd("sysctl " ++ Key)), [$:])
- end,
+ %% This test require that the program 'sysctl' is in the path.
+ %% First test with 'which sysctl', if that does not work
+ %% try with 'which /sbin/sysctl'. If that does not work either,
+ %% we skip the test...
try
begin
- CPU =
- case Extract("hw.model") of
- ["hw.model", Model] ->
- string:trim(Model);
- _ ->
- "-"
- end,
- CPUSpeed =
- case Extract("hw.clockrate") of
- ["hw.clockrate", Speed] ->
- list_to_integer(string:trim(Speed));
- _ ->
- -1
- end,
- NCPU =
- case Extract("hw.ncpu") of
- ["hw.ncpu", N] ->
- list_to_integer(string:trim(N));
- _ ->
- -1
+ SysCtl =
+ case string:trim(os:cmd("which sysctl")) of
+ [] ->
+ case string:trim(os:cmd("which /sbin/sysctl")) of
+ [] ->
+ throw(sysctl);
+ SC2 ->
+ SC2
+ end;
+ SC1 ->
+ SC1
end,
- Memory =
- case Extract("hw.physmem") of
- ["hw.physmem", PhysMem] ->
- list_to_integer(string:trim(PhysMem)) div 1024;
- _ ->
- -1
+ Extract =
+ fun(Key) ->
+ string:tokens(string:trim(os:cmd(SysCtl ++ " " ++ Key)),
+ [$:])
end,
+ CPU = analyze_freebsd_cpu(Extract),
+ CPUSpeed = analyze_freebsd_cpu_speed(Extract),
+ NCPU = analyze_freebsd_ncpu(Extract),
+ Memory = analyze_freebsd_memory(Extract),
io:format("CPU:"
- "~n Model: ~s"
- "~n Speed: ~w"
- "~n N: ~w"
+ "~n Model: ~s"
+ "~n Speed: ~w"
+ "~n N: ~w"
+ "~n Num Schedulers: ~w"
"~nMemory:"
"~n ~w KB"
- "~n", [CPU, CPUSpeed, NCPU, Memory]),
+ "~n",
+ [CPU, CPUSpeed, NCPU,
+ erlang:system_info(schedulers), Memory]),
CPUFactor =
if
(CPUSpeed =:= -1) ->
@@ -869,6 +905,8 @@ analyze_and_print_freebsd_host_info(Version) ->
end;
true ->
if
+ (NCPU =:= -1) ->
+ 1;
(NCPU >= 4) ->
2;
(NCPU >= 2) ->
@@ -894,8 +932,300 @@ analyze_and_print_freebsd_host_info(Version) ->
end
catch
_:_:_ ->
+ io:format("CPU:"
+ "~n Num Schedulers: ~w"
+ "~n", [erlang:system_info(schedulers)]),
+ case erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ _ ->
+ 2
+ end
+ end.
+
+analyze_freebsd_cpu(Extract) ->
+ analyze_freebsd_item(Extract, "hw.model", fun(X) -> X end, "-").
+
+analyze_freebsd_cpu_speed(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.clockrate",
+ fun(X) -> list_to_integer(X) end,
+ -1).
+
+analyze_freebsd_ncpu(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.ncpu",
+ fun(X) -> list_to_integer(X) end,
+ -1).
+
+analyze_freebsd_memory(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.physmem",
+ fun(X) -> list_to_integer(X) div 1024 end,
+ -1).
+
+analyze_freebsd_item(Extract, Key, Process, Default) ->
+ try
+ begin
+ case Extract(Key) of
+ [Key, Model] ->
+ Process(string:trim(Model));
+ _ ->
+ Default
+ end
+ end
+ catch
+ _:_:_ ->
+ Default
+ end.
+
+
+analyze_and_print_solaris_host_info(Version) ->
+ Release =
+ case file:read_file_info("/etc/release") of
+ {ok, _} ->
+ case [string:trim(S) || S <- string:tokens(os:cmd("cat /etc/release"), [$\n])] of
+ [Rel | _] ->
+ Rel;
+ _ ->
+ "-"
+ end;
+ _ ->
+ "-"
+ end,
+ %% Display the firmware device tree root properties (prtconf -b)
+ Props = [list_to_tuple([string:trim(PS) || PS <- Prop]) ||
+ Prop <- [string:tokens(S, [$:]) ||
+ S <- string:tokens(os:cmd("prtconf -b"), [$\n])]],
+ BannerName = case lists:keysearch("banner-name", 1, Props) of
+ {value, {_, BN}} ->
+ string:trim(BN);
+ _ ->
+ "-"
+ end,
+ InstructionSet =
+ case string:trim(os:cmd("isainfo -k")) of
+ "Pseudo-terminal will not" ++ _ ->
+ "-";
+ IS ->
+ IS
+ end,
+ PtrConf = [list_to_tuple([string:trim(S) || S <- Items]) || Items <- [string:tokens(S, [$:]) || S <- string:tokens(os:cmd("prtconf"), [$\n])], length(Items) > 1],
+ SysConf =
+ case lists:keysearch("System Configuration", 1, PtrConf) of
+ {value, {_, SC}} ->
+ SC;
+ _ ->
+ "-"
+ end,
+ NumPhysProc =
+ begin
+ NPPStr = string:trim(os:cmd("psrinfo -p")),
+ try list_to_integer(NPPStr) of
+ _ ->
+ NPPStr
+ catch
+ _:_:_ ->
+ "-"
+ end
+ end,
+ NumProc = try integer_to_list(length(string:tokens(os:cmd("psrinfo"), [$\n]))) of
+ NPStr ->
+ NPStr
+ catch
+ _:_:_ ->
+ "-"
+ end,
+ MemSz =
+ case lists:keysearch("Memory size", 1, PtrConf) of
+ {value, {_, MS}} ->
+ MS;
+ _ ->
+ "-"
+ end,
+ io:format("Solaris: ~s"
+ "~n Release: ~s"
+ "~n Banner Name: ~s"
+ "~n Instruction Set: ~s"
+ "~n CPUs: ~s (~s)"
+ "~n System Config: ~s"
+ "~n Memory Size: ~s"
+ "~n Num Schedulers: ~s"
+ "~n~n", [Version, Release, BannerName, InstructionSet,
+ NumPhysProc, NumProc,
+ SysConf, MemSz,
+ str_num_schedulers()]),
+ MemFactor =
+ try string:tokens(MemSz, [$ ]) of
+ [SzStr, "Mega" ++ _] ->
+ try list_to_integer(SzStr) of
+ Sz when Sz > 8192 ->
+ 0;
+ Sz when Sz > 4096 ->
+ 1;
+ Sz when Sz > 2048 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ [SzStr, "Giga" ++ _] ->
+ try list_to_integer(SzStr) of
+ Sz when Sz > 8 ->
+ 0;
+ Sz when Sz > 4 ->
+ 1;
+ Sz when Sz > 2 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ _ ->
+ 10
+ catch
+ _:_:_ ->
+ 10
+ end,
+ try erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ N when (N =< 6) ->
+ 2;
+ _ ->
1
+ catch
+ _:_:_ ->
+ 10
+ end + MemFactor.
+
+
+analyze_and_print_win_host_info(Version) ->
+ SysInfo = which_win_system_info(),
+ OsName = win_sys_info_lookup(os_name, SysInfo),
+ OsVersion = win_sys_info_lookup(os_version, SysInfo),
+ SysMan = win_sys_info_lookup(system_manufacturer, SysInfo),
+ NumProcs = win_sys_info_lookup(num_processors, SysInfo),
+ TotPhysMem = win_sys_info_lookup(total_phys_memory, SysInfo),
+ io:format("Windows: ~s"
+ "~n OS Version: ~s (~p)"
+ "~n System Manufacturer: ~s"
+ "~n Number of Processor(s): ~s"
+ "~n Total Physical Memory: ~s"
+ "~n", [OsName, OsVersion, Version, SysMan, NumProcs, TotPhysMem]),
+ MemFactor =
+ try
+ begin
+ [MStr, MUnit|_] =
+ string:tokens(lists:delete($,, TotPhysMem), [$\ ]),
+ case string:to_lower(MUnit) of
+ "gb" ->
+ try list_to_integer(MStr) of
+ M when M > 8 ->
+ 0;
+ M when M > 4 ->
+ 1;
+ M when M > 2 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ "mb" ->
+ try list_to_integer(MStr) of
+ M when M > 8192 ->
+ 0;
+ M when M > 4096 ->
+ 1;
+ M when M > 2048 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ _ ->
+ 10
+ end
+ end
+ catch
+ _:_:_ ->
+ 10
+ end,
+ CPUFactor =
+ case erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ _ ->
+ 2
+ end,
+ CPUFactor + MemFactor.
+
+win_sys_info_lookup(Key, SysInfo) ->
+ win_sys_info_lookup(Key, SysInfo, "-").
+
+win_sys_info_lookup(Key, SysInfo, Def) ->
+ case lists:keysearch(Key, 1, SysInfo) of
+ {value, {Key, Value}} ->
+ Value;
+ false ->
+ Def
+ end.
+
+%% This function only extracts the prop we actually care about!
+which_win_system_info() ->
+ SysInfo = os:cmd("systeminfo"),
+ try process_win_system_info(string:tokens(SysInfo, [$\r, $\n]), [])
+ catch
+ _:_:_ ->
+ io:format("Failed process System info: "
+ "~s~n", [SysInfo]),
+ []
+ end.
+
+process_win_system_info([], Acc) ->
+ Acc;
+process_win_system_info([H|T], Acc) ->
+ case string:tokens(H, [$:]) of
+ [Key, Value] ->
+ case string:to_lower(Key) of
+ "os name" ->
+ process_win_system_info(T,
+ [{os_name, string:trim(Value)}|Acc]);
+ "os version" ->
+ process_win_system_info(T,
+ [{os_version, string:trim(Value)}|Acc]);
+ "system manufacturer" ->
+ process_win_system_info(T,
+ [{system_manufacturer, string:trim(Value)}|Acc]);
+ "processor(s)" ->
+ [NumProcStr|_] = string:tokens(Value, [$\ ]),
+ T2 = lists:nthtail(list_to_integer(NumProcStr), T),
+ process_win_system_info(T2,
+ [{num_processors, NumProcStr}|Acc]);
+ "total physical memory" ->
+ process_win_system_info(T,
+ [{total_phys_memory, string:trim(Value)}|Acc]);
+ _ ->
+ process_win_system_info(T, Acc)
+ end;
+ _ ->
+ process_win_system_info(T, Acc)
end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -942,33 +1272,33 @@ try_tc(TCName, Name, Verbosity, Pre, Case, Post)
p("try_tc -> starting: try pre"),
try Pre() of
State ->
- p("try_tc -> pre done: try case"),
+ p("try_tc -> pre done: try test case"),
try Case(State) of
Res ->
- p("try_tc -> case done: try post"),
+ p("try_tc -> test case done: try post"),
(catch Post(State)),
p("try_tc -> done"),
Res
catch
throw:{skip, _} = SKIP:_ ->
- p("try_tc -> case (throw) skip: try post"),
+ p("try_tc -> test case (throw) skip: try post"),
(catch Post(State)),
- p("try_tc -> case (throw) skip: done"),
+ p("try_tc -> test case (throw) skip: done"),
SKIP;
exit:{skip, _} = SKIP:_ ->
- p("try_tc -> case (exit) skip: try post"),
+ p("try_tc -> test case (exit) skip: try post"),
(catch Post(State)),
- p("try_tc -> case (exit) skip: done"),
+ p("try_tc -> test case (exit) skip: done"),
SKIP;
C:E:S ->
- p("try_tc -> case failed: try post"),
+ p("try_tc -> test case failed: try post"),
(catch Post(State)),
case megaco_test_global_sys_monitor:events() of
[] ->
- p("try_tc -> case failed: done"),
+ p("try_tc -> test case failed: done"),
exit({case_catched, C, E, S});
SysEvs ->
- p("try_tc -> case failed with system event(s): "
+ p("try_tc -> test case failed with system event(s): "
"~n ~p", [SysEvs]),
{skip, "TC failure with system events"}
end
diff --git a/lib/megaco/test/megaco_test_megaco_generator.erl b/lib/megaco/test/megaco_test_megaco_generator.erl
index 4c2b66e3cd..4eedd8d731 100644
--- a/lib/megaco/test/megaco_test_megaco_generator.erl
+++ b/lib/megaco/test/megaco_test_megaco_generator.erl
@@ -377,7 +377,8 @@ handle_exec({expect_nothing, To}, State) ->
"~n ~p", [Any]),
error({expect_nothing, Any})
after To ->
- {ok, State}
+ p("go nothing (~p) as expected", [To]),
+ {ok, State}
end;
handle_exec({megaco_trace, disable}, State) ->
@@ -683,6 +684,7 @@ handle_exec({megaco_callback, nocall, Timeout}, State) ->
Err = {unexpected_callback, Type, Msg, Pid},
{error, State#state{result = [Err|Res]}}
after Timeout ->
+ p("got no callback (~p) as expected", [Timeout]),
{ok, State}
end;
@@ -1090,11 +1092,16 @@ handle_megaco_callback_call(P, Msg) ->
d("handle_megaco_callback_call -> deliver reply after delay [~w]",
[Delay]),
Reply;
+ {'EXIT', Pid, Reason} when (Pid =:= P) ->
+ d("handle_megaco_callback_call -> "
+ "received unexpected EXIT signal (from ~p): "
+ "~n Reason: ~p", [Pid, Reason]),
+ exit({unexpected_EXIT_signal, Pid, Reason});
{'EXIT', SomePid, SomeReason} ->
d("handle_megaco_callback_call -> "
- "received unexpected EXIT signal: "
- "~n SomePid: ~p"
- "~n SomeReason: ~p", [SomePid, SomeReason]),
+ "received unexpected EXIT signal from unknown process: "
+ "~n Pid: ~p"
+ "~n Reason: ~p", [SomePid, SomeReason]),
exit({unexpected_EXIT_signal, SomePid, SomeReason})
end.
diff --git a/lib/megaco/test/megaco_test_tcp_generator.erl b/lib/megaco/test/megaco_test_tcp_generator.erl
index 04ac32b381..0edeac6733 100644
--- a/lib/megaco/test/megaco_test_tcp_generator.erl
+++ b/lib/megaco/test/megaco_test_tcp_generator.erl
@@ -404,6 +404,7 @@ handle_exec({expect_receive, Desc, {Verify, To}},
e("received unknown message: ~p", [Else]),
{error, {expect_receive, {unexpected_message, Else}}}
after To ->
+ e("(expect) receive timeout: ~w", [To]),
{error, {expect_receive, timeout}}
end;
@@ -419,7 +420,7 @@ handle_exec({expect_closed, To},
{ok, State#state{connection = undefined,
result = [closed|Acc]}}
after To ->
- e("expect_closed timeout after ~w", [To]),
+ e("(expect) closed timeout after ~w", [To]),
{error, {expect_closed, timeout}}
end;
@@ -434,7 +435,7 @@ handle_exec({expect_nothing, To},
e("expect_nothing - received: ~p", [Any]),
{error, {expect_nothing, Any}}
after To ->
- p("expect_nothing timeout after ~w", [To]),
+ p("got nothing (~w) as expected", [To]),
{ok, State#state{result = [{nothing, To}|Acc]}}
end;
diff --git a/lib/megaco/test/megaco_trans_SUITE.erl b/lib/megaco/test/megaco_trans_SUITE.erl
index 1703e197c5..1e281987b8 100644
--- a/lib/megaco/test/megaco_trans_SUITE.erl
+++ b/lib/megaco/test/megaco_trans_SUITE.erl
@@ -4397,6 +4397,10 @@ mtrtaat_err_desc(T) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Transaction Sender
+%%
+%%
+
multi_trans_req_and_ack_ackmaxcount(suite) ->
[];
multi_trans_req_and_ack_ackmaxcount(doc) ->
@@ -4514,6 +4518,9 @@ mtrtaaamc_mgc_event_sequence(text, tcp) ->
DiscoVerify = ?mtrtaaamc_mgc_verify_handle_disconnect_fun(),
EvSeq = [
{debug, true},
+ {trigger, fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
{megaco_trace, disable},
megaco_start,
{megaco_start_user, Mid, RI, []},
@@ -4545,12 +4552,12 @@ mtrtaaamc_mgc_event_sequence(text, tcp) ->
mtrtaaamc_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
- io:format("mtrtaaamc_mgc_verify_handle_connect -> ok"
- "~n CH: ~p~n", [CH]),
+ i("MGC Connect verification ok"
+ "~n ~p~n", [CH]),
{ok, CH, ok};
mtrtaaamc_mgc_verify_handle_connect(Else) ->
- io:format("mtrtaaamc_mgc_verify_handle_connect -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MGC Connect verification failed: unknown"
+ "~n ~p~n", [Else]),
{error, Else, ok}.
mtrtaaamc_mgc_verify_service_change_req_fun(Mid) ->
@@ -4560,8 +4567,9 @@ mtrtaaamc_mgc_verify_service_change_req_fun(Mid) ->
mtrtaaamc_mgc_verify_service_change_req(
{handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
- io:format("mtrtaaamc_mgc_verify_service_change_req -> ok"
- "~n AR: ~p~n", [AR]),
+ i("MGC Service Change Request verification: begin"
+ "~n AR: ~p"
+ "~n", [AR]),
case AR of
#'ActionRequest'{commandRequests = [CR]} ->
case CR of
@@ -4577,11 +4585,17 @@ mtrtaaamc_mgc_verify_service_change_req(
#'ServiceChangeParm'{
serviceChangeMethod = restart,
serviceChangeReason = [[$9,$0,$1|_]]} ->
+ i("MGC Service Change Request "
+ "verification ok"),
Reply =
{discard_ack,
[mtrtaaamc_mgc_service_change_reply_ar(Mid, 1)]},
{ok, AR, Reply};
_ ->
+ e("MGC Service Change Request "
+ "verification failed: invalid SCP"
+ "~n ~p"
+ "~n", [Parms]),
Err = {invalid_SCP, Parms},
ED = mtrtaaamc_err_desc(Parms),
ErrReply = {discard_ack,
@@ -4589,32 +4603,50 @@ mtrtaaamc_mgc_verify_service_change_req(
{error, Err, ErrReply}
end;
_ ->
+ e("MGC Service Change Request "
+ "verification failed: "
+ "invalid termination id"
+ "~n ~p"
+ "~n", [Tid]),
Err = {invalid_termination_id, Tid},
ED = mtrtaaamc_err_desc(Tid),
ErrReply = {discard_ack, ED},
{error, Err, ErrReply}
end;
_ ->
+ e("MGC Service Change Request verification failed: "
+ "invalid command"
+ "~n ~p"
+ "~n", [Cmd]),
Err = {invalid_command, Cmd},
ED = mtrtaaamc_err_desc(Cmd),
ErrReply = {discard_ack, ED},
{error, Err, ErrReply}
end;
_ ->
+ e("MGC Service Change Request verification failed: "
+ "invalid command request"
+ "~n ~p"
+ "~n", [CR]),
Err = {invalid_command_request, CR},
ED = mtrtaaamc_err_desc(CR),
ErrReply = {discard_ack, ED},
{error, Err, ErrReply}
end;
_ ->
+ e("MGC Service Change Request verification failed: "
+ "invalid action request"
+ "~n ~p"
+ "~n", [AR]),
Err = {invalid_action_request, AR},
ED = mtrtaaamc_err_desc(AR),
ErrReply = {discard_ack, ED},
{error, Err, ErrReply}
end;
mtrtaaamc_mgc_verify_service_change_req(Else, _Mid) ->
- io:format("mtrtaaamc_mgc_verify_service_change_req -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MGC Service Change Request verification failed: unknown"
+ "~n ~p"
+ "~n", [Else]),
ED = mtrtaaamc_err_desc(Else),
ErrReply = {discard_ack, ED},
{error, Else, ErrReply}.
@@ -4626,9 +4658,11 @@ mtrtaaamc_mgc_verify_notify_request_fun() ->
mtrtaaamc_mgc_verify_notify_request(
{handle_trans_request, _, ?VERSION, [AR]}) ->
- io:format("mtrtaaamc_mgc_verify_notify_request:fun -> ok"
- "~n AR: ~p~n", [AR]),
+ i("MGC Notify Request verification: begin"
+ "~n AR: ~p"
+ "~n", [AR]),
case AR of
+ %% *** SLOPPY ACK ***
#'ActionRequest'{contextId = 1 = Cid,
commandRequests = [CR]} ->
#'CommandRequest'{command = Cmd} = CR,
@@ -4640,9 +4674,15 @@ mtrtaaamc_mgc_verify_notify_request(
observedEventLst = [OE]} = OED,
#'ObservedEvent'{eventName = "al/of"} = OE,
HandleAck = {handle_sloppy_ack, {kalle, Rid}},
+ i("MGC Notify Request verification ok: sloppy ack"
+ "~n Cid: ~p"
+ "~n Tid: ~p"
+ "~n Rid: ~p", [Cid, Tid, Rid]),
Reply = {HandleAck,
[mtrtaaamc_mgc_notify_reply_ar(Cid, Tid)]},
{ok, AR, Reply};
+
+ %% *** PROPER ACK ***
#'ActionRequest'{contextId = 2 = Cid,
commandRequests = [CR]} ->
#'CommandRequest'{command = Cmd} = CR,
@@ -4650,43 +4690,54 @@ mtrtaaamc_mgc_verify_notify_request(
#'NotifyRequest'{terminationID = [Tid],
observedEventsDescriptor = OED,
errorDescriptor = asn1_NOVALUE} = NR,
- #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
+ #'ObservedEventsDescriptor'{requestId = _Rid,
+ observedEventLst = [OE]} = OED,
#'ObservedEvent'{eventName = "al/of"} = OE,
+ i("MGC Notify Request verification ok: discard ack"
+ "~n Cid: ~p"
+ "~n Tid: ~p"
+ "~n Rid: ~p", [Cid, Tid, _Rid]),
Reply = {discard_ack, [mtrtaaamc_mgc_notify_reply_ar(Cid, Tid)]},
{ok, AR, Reply};
+
_ ->
+ e("MGC Notify Request verification failed: unexpected AR"
+ "~n ~p"
+ "~n", [AR]),
ED = mtrtaaamc_err_desc(AR),
ErrReply = {discard_ack, ED},
{error, AR, ErrReply}
end;
mtrtaaamc_mgc_verify_notify_request(Else) ->
- io:format("mtrtaaamc_mgc_verify_notify_request:fun -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MGC Notify Request verification failed: unexpected callback"
+ "~n ~p"
+ "~n", [Else]),
ED = mtrtaaamc_err_desc(Else),
ErrReply = {discard_ack, ED},
{error, Else, ErrReply}.
mtrtaaamc_mgc_verify_ack({handle_trans_ack, CH, ?VERSION, ok,
{kalle, Rid}}) ->
- io:format("mtrtaaamc_mgc_verify_ack -> ok"
- "~n CH: ~p"
- "~n Rid: ~p"
- "~n", [CH, Rid]),
+ i("MGC Ack verification: ok (kalle)"
+ "~n CH: ~p"
+ "~n Rid: ~p"
+ "~n", [CH, Rid]),
{ok, CH, ok};
mtrtaaamc_mgc_verify_ack(Else) ->
- io:format("mtrtaaamc_mgc_verify_ack -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MGC Ack verification failed: unknown"
+ "~n ~p~n", [Else]),
{error, Else, ok}.
mtrtaaamc_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
- io:format("mtrtaaamc_mgc_verify_handle_disconnect -> ok"
- "~n CH: ~p"
- "~n R: ~p"
- "~n", [CH, R]),
+ i("MGC Disconnect verification: ok"
+ "~n CH: ~p"
+ "~n R: ~p"
+ "~n", [CH, R]),
{ok, CH, ok};
mtrtaaamc_mgc_verify_handle_disconnect(Else) ->
- io:format("mtrtaaamc_mgc_verify_handle_disconnect -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MGC Disconnect verification failed: unknown"
+ "~n ~p"
+ "~n", [Else]),
{error, Else, ok}.
@@ -4698,26 +4749,11 @@ mtrtaaamc_mgc_service_change_reply_ar(Mid, Cid) ->
CR = cre_cmdReply(SCR),
cre_actionReply(Cid, [CR]).
-%% mtrtaaamc_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
-%% AR = mtrtaaamc_mgc_service_change_reply_ar(Mid, Cid),
-%% TRes = cre_transResult([AR]),
-%% TR = cre_transReply(TransId, TRes),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
-
mtrtaaamc_mgc_notify_reply_ar(Cid, TermId) ->
NR = cre_notifyReply([TermId]),
CR = cre_cmdReply(NR),
cre_actionReply(Cid, [CR]).
-%% mtrtaaamc_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
-%% AR = mtrtaaamc_mgc_notify_reply_ar(Cid, TermId),
-%% TRes = cre_transResult([AR]),
-%% TR = cre_transReply(TransId, TRes),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
%%
@@ -4757,6 +4793,9 @@ mtrtaaamc_mg_event_sequence(text, tcp) ->
NotifyReplyVerify = ?mtrtaaamc_mg_verify_notify_reply_fun(),
EvSeq = [
{debug, true},
+ {trigger, fun() ->
+ put(verbosity, ?TEST_VERBOSITY)
+ end},
megaco_start,
{megaco_start_user, Mid, RI, []},
start_transport,
@@ -4780,20 +4819,35 @@ mtrtaaamc_mg_event_sequence(text, tcp) ->
{megaco_update_conn_info, trans_ack, true},
{megaco_update_conn_info, trans_req, true},
{megaco_conn_info, all},
+ {megaco_conn_info, requests},
{megaco_cast, NR(1,1), []},
+ {megaco_conn_info, requests},
{megaco_cast, NR(1,2), []},
+ {megaco_conn_info, requests},
{megaco_cast, NR(1,3), []},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_cast, NR(2,1), []},
+ {megaco_conn_info, requests},
{megaco_cast, NR(2,2), []},
+ {megaco_conn_info, requests},
{megaco_cast, NR(2,3), []},
+ {megaco_conn_info, requests},
{megaco_cast, NR(1,4), [{trans_req,false}]},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_conn_info, requests},
{sleep, 3000},
megaco_stop_user,
megaco_stop,
@@ -4802,18 +4856,21 @@ mtrtaaamc_mg_event_sequence(text, tcp) ->
EvSeq.
mtrtaaamc_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
- io:format("mtrtaaamc_mg_verify_handle_connect -> ok"
- "~n CH: ~p~n", [CH]),
+ i("MG Connect verification: ok"
+ "~n CH: ~p"
+ "~n", [CH]),
{ok, CH, ok};
mtrtaaamc_mg_verify_handle_connect(Else) ->
- io:format("mtrtaaamc_mg_verify_handle_connect -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MG Connect verification failed: unknown"
+ "~n ~p"
+ "~n", [Else]),
{error, Else, ok}.
mtrtaaamc_mg_verify_service_change_reply({handle_trans_reply, _CH, ?VERSION,
{ok, [AR]}, _}) ->
- io:format("mtrtaaamc_mg_verify_service_change_reply -> ok"
- "~n AR: ~p~n", [AR]),
+ i("MG Service Change Reply verification: begin"
+ "~n AR: ~p"
+ "~n", [AR]),
case AR of
#'ActionReply'{commandReply = [SCR]} ->
case SCR of
@@ -4827,37 +4884,73 @@ mtrtaaamc_mg_verify_service_change_reply({handle_trans_reply, _CH, ?VERSION,
{serviceChangeResParms,
#'ServiceChangeResParm'{
serviceChangeMgcId = _RemoteMid}} ->
+ i("MG Service Change Reply verification ok"),
{ok, AR, ok};
{Tag, Val} ->
+ e("MG Service Change Reply "
+ "verification failed: "
+ "invalid service change result"
+ "~n Tag: ~p"
+ "~n Val: ~p"
+ "~n", [Tag, Val]),
Err = {invalid_service_change_result,
Tag, Val},
{error, Err, ok}
end;
_ ->
+ e("MG Service Change Reply verification failed: "
+ "invalid termination id"
+ "~n ~p"
+ "~n", [Tid]),
Err = {invalid_termination_id, Tid},
{error, Err, ok}
end;
{Tag, Val} ->
+ e("MG Service Change Reply verification failed: "
+ "invalid command reply"
+ "~n Tag: ~p"
+ "~n Val: ~p"
+ "~n", [Tag, Val]),
Err = {invalid_command_reply, Tag, Val},
{error, Err, ok}
end;
_ ->
+ e("MG Service Change Reply verification failed: invalid action reply"
+ "~n ~p"
+ "~n", [AR]),
Err = {invalid_action_reply, AR},
{error, Err, ok}
end;
mtrtaaamc_mg_verify_service_change_reply(Else) ->
- io:format("mtrtaaamc_mg_verify_service_change_reply -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MG Service Change Reply verification failed -> unknown"
+ "~n ~p"
+ "~n", [Else]),
{error, Else, ok}.
mtrtaaamc_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
{ok, [AR]}, _}) ->
- io:format("mtrtaaamc_mg_verify_notify_reply -> ok"
- "~n AR: ~p~n", [AR]),
+ i("MG Notify Reply verification ok:"
+ "~n ~p~n", [AR]),
{ok, AR, ok};
+mtrtaaamc_mg_verify_notify_reply({handle_unexpected_trans, CH, PV, T} = Else) ->
+ e("MG Notify Reply verification failed: unexpected transaction"
+ "~n CH: ~p"
+ "~n PV: ~p"
+ "~n T: ~p"
+ "~n", [CH, PV, T]),
+ {error, Else, ok};
+mtrtaaamc_mg_verify_notify_reply({handle_unexpected_trans, CH, PV, E, T} = Else) ->
+ e("MG Notify Reply failed: unexpected transaction"
+ "~n CH: ~p"
+ "~n PV: ~p"
+ "~n E: ~p"
+ "~n T: ~p"
+ "~n", [CH, PV, E, T]),
+ {error, Else, ok};
mtrtaaamc_mg_verify_notify_reply(Else) ->
- io:format("mtrtaaamc_mg_verify_notify_reply -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("MG Notify Reply failed -> unknown"
+ "~n ~p"
+ "~n", [Else]),
{error, Else, ok}.
mtrtaaamc_mg_service_change_request_ar(_Mid, Cid) ->
@@ -4869,13 +4962,6 @@ mtrtaaamc_mg_service_change_request_ar(_Mid, Cid) ->
CR = cre_cmdReq(CMD),
cre_actionReq(Cid, [CR]).
-%% mtrtaaamc_mg_service_change_request_msg(Mid, TransId, Cid) ->
-%% AR = mtrtaaamc_mg_service_change_request_ar(Mid, Cid),
-%% TR = cre_transReq(TransId, [AR]),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
-
mtrtaaamc_mg_notify_request_ar(Rid, Tid, Cid) ->
TT = cre_timeNotation("19990729", "22000000"),
Ev = cre_obsEvent("al/of", TT),
@@ -4885,13 +4971,6 @@ mtrtaaamc_mg_notify_request_ar(Rid, Tid, Cid) ->
CR = cre_cmdReq(CMD),
cre_actionReq(Cid, [CR]).
-%% mtrtaaamc_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
-%% AR = mtrtaaamc_mg_notify_request_ar(Rid, TermId, Cid),
-%% TR = cre_transReq(TransId, [AR]),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
-
%%
%% Common functions for the multi_trans_req_timeout test case
@@ -5376,7 +5455,7 @@ mtrtaarac_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
"~n AR: ~p~n", [AR]),
{ok, AR, ok};
mtrtaarac_mg_verify_notify_reply(Else) ->
- e("mtrtaarac_mg_verify_notify_reply -> invalid notify reply"
+ e("MG Notify Reply verification failed: invalid notify reply"
"~n Expected: handle_trans_reply with ok"
"~n Received: ~p", [Else]),
{error, Else, ok}.
@@ -6946,38 +7025,6 @@ mtraaap_mg_verify_service_change_reply(Else) ->
"~n Else: ~p~n", [Else]),
{error, Else, ok}.
-%% mtraaap_mg_verify_notify_request_fun() ->
-%% fun(Ev) ->
-%% mtraaap_mg_verify_notify_request(Ev)
-%% end.
-
-%% mtraaap_mg_verify_notify_request(
-%% {handle_trans_request, _, ?VERSION, [AR]}) ->
-%% io:format("mtraaap_mg_verify_notify_request -> ok"
-%% "~n AR: ~p~n", [AR]),
-%% case AR of
-%% #'ActionRequest'{contextId = 1 = Cid,
-%% commandRequests = [CR]} ->
-%% #'CommandRequest'{command = Cmd} = CR,
-%% {notifyReq, NR} = Cmd,
-%% #'NotifyRequest'{terminationID = [Tid],
-%% observedEventsDescriptor = OED,
-%% errorDescriptor = asn1_NOVALUE} = NR,
-%% #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
-%% #'ObservedEvent'{eventName = "al/of"} = OE,
-%% Reply = {discard_ack, [mtraaap_mg_notify_reply_ar(Cid, Tid)]},
-%% {ok, 3000, AR, Reply};
-%% _ ->
-%% ED = mtraaap_err_desc(AR),
-%% ErrReply = {discard_ack, ED},
-%% {error, AR, ErrReply}
-%% end;
-%% mtraaap_mg_verify_notify_request(Else) ->
-%% io:format("mtraaap_mg_verify_notify_request:fun -> unknown"
-%% "~n Else: ~p~n", [Else]),
-%% ED = mtraaap_err_desc(Else),
-%% ErrReply = {discard_ack, ED},
-%% {error, Else, ErrReply}.
mtraaap_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
{ok, [AR]}, _}) ->
@@ -8325,7 +8372,7 @@ otp71922_mgc_event_sequence(text, tcp, MgMid) ->
{encoding_config, []},
{transport_module, megaco_tcp}
],
- Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ Tid = #megaco_term_id{id = ["00000000","00000100","01101101"]},
NR = fun(Cid, Rid) ->
[otp71922_mgc_notify_request_ar(Rid, Tid, Cid)]
end,
@@ -8368,12 +8415,14 @@ otp71922_mgc_event_sequence(text, tcp, MgMid) ->
otp71922_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
- io:format("otp71922_mgc_verify_handle_connect -> ok"
- "~n CH: ~p~n", [CH]),
+ i("received expected handle_connect with"
+ "~n CH: ~p"
+ "~n => force a 2 second sleep before return", [CH]),
{ok, timer:seconds(2), CH, ok};
otp71922_mgc_verify_handle_connect(Else) ->
- io:format("otp71922_mgc_verify_handle_connect -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("otp71922_mgc_verify_handle_connect -> invalid handle-connect: "
+ "~n Extected: handle_connect"
+ "~n Received: ~p", [Else]),
{error, Else, ok}.
otp71922_mgc_verify_service_change_req_fun(Mid) ->
@@ -8383,8 +8432,8 @@ otp71922_mgc_verify_service_change_req_fun(Mid) ->
otp71922_mgc_verify_service_change_req(
{handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
- io:format("otp71922_mgc_verify_service_change_req -> ok"
- "~n AR: ~p~n", [AR]),
+ i("otp71922_mgc_verify_service_change_req -> ok"
+ "~n AR: ~p", [AR]),
case AR of
#'ActionRequest'{commandRequests = [CR]} ->
case CR of
@@ -8595,8 +8644,11 @@ otp71922_mg_event_sequence(text, tcp, Mid) ->
{transport_module, megaco_tcp}
],
ServiceChangeReq = [otp71922_mg_service_change_request_ar(Mid, 1)],
- Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
- NR = fun(Cid, Rid) ->
+ %% This is so that we can match notify request and reply
+ Tid1 = #megaco_term_id{id = ["00000000","00000001","01101101"]},
+ Tid2 = #megaco_term_id{id = ["00000000","00000010","01101101"]},
+ Tid3 = #megaco_term_id{id = ["00000000","00000011","01101101"]},
+ NR = fun(Cid, Rid, Tid) ->
[otp71922_mg_notify_request_ar(Rid, Tid, Cid)]
end,
ConnectVerify = ?otp71922_mg_verify_handle_connect_fun(),
@@ -8629,20 +8681,20 @@ otp71922_mg_event_sequence(text, tcp, Mid) ->
{megaco_update_conn_info, trans_ack, true},
{megaco_update_conn_info, trans_req, true},
{megaco_conn_info, all},
- {megaco_cast, NR(1,1), []},
- {megaco_cast, NR(1,2), []},
- {megaco_cast, NR(1,3), []},
+ {megaco_cast, NR(1,1,Tid1), []},
+ {megaco_cast, NR(1,2,Tid2), []},
+ {megaco_cast, NR(1,3,Tid3), []},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
{megaco_callback, handle_trans_reply, NotifyReplyVerify},
{megaco_update_conn_info, trans_timer, 120000},
- {megaco_cast, NR(2,1), []},
- {megaco_cast, NR(2,2), []},
- {megaco_cast, NR(2,3), []},
+ {megaco_cast, NR(2,1,Tid1), []},
+ {megaco_cast, NR(2,2,Tid2), []},
+ {megaco_cast, NR(2,3,Tid3), []},
{megaco_callback, handle_trans_request, NotifyReqVerify},
- {megaco_callback, handle_trans_reply, NotifyReplyVerify},
- {megaco_callback, handle_trans_reply, NotifyReplyVerify},
- {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
{sleep, 3000},
megaco_stop_user,
megaco_stop,
@@ -8651,18 +8703,17 @@ otp71922_mg_event_sequence(text, tcp, Mid) ->
EvSeq.
otp71922_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
- io:format("otp71922_mg_verify_handle_connect -> ok"
- "~n CH: ~p~n", [CH]),
+ i("received expected handle_connect:"
+ "~n CH: ~p", [CH]),
{ok, CH, ok};
otp71922_mg_verify_handle_connect(Else) ->
- io:format("otp71922_mg_verify_handle_connect -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("otp71922_mg_verify_handle_connect -> received unexpected:"
+ "~n Expected: handle_connect"
+ "~n Received: ~p", [Else]),
{error, Else, ok}.
otp71922_mg_verify_service_change_reply({handle_trans_reply, _CH, ?VERSION,
{ok, [AR]}, _}) ->
- io:format("otp71922_mg_verify_service_change_reply -> ok"
- "~n AR: ~p~n", [AR]),
case AR of
#'ActionReply'{commandReply = [SCR]} ->
case SCR of
@@ -8676,70 +8727,55 @@ otp71922_mg_verify_service_change_reply({handle_trans_reply, _CH, ?VERSION,
{serviceChangeResParms,
#'ServiceChangeResParm'{
serviceChangeMgcId = _RemoteMid}} ->
+ i("received expected handle_trans_reply "
+ "(service change) with ok"
+ "~n AR: ~p", [AR]),
{ok, AR, ok};
{Tag, Val} ->
+ e("received expected handle_trans_reply "
+ "(service change) with error"
+ "~n Tag: ~p"
+ "~n Val: ~p", [Tag, Val]),
Err = {invalid_service_change_result,
Tag, Val},
{error, Err, ok}
end;
_ ->
+ e("received expected handle_trans_reply "
+ "(service change) with error"
+ "~n Tid: ~p", [Tid]),
Err = {invalid_termination_id, Tid},
{error, Err, ok}
end;
{Tag, Val} ->
+ e("received expected handle_trans_reply "
+ "(action reply) with error"
+ "~n Tag: ~p"
+ "~n Val: ~p", [Tag, Val]),
Err = {invalid_command_reply, Tag, Val},
{error, Err, ok}
end;
_ ->
+ e("received expected handle_trans_reply with error"
+ "~n AR: ~p", [AR]),
Err = {invalid_action_reply, AR},
{error, Err, ok}
end;
otp71922_mg_verify_service_change_reply(Else) ->
- io:format("otp71922_mg_verify_service_change_reply -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("invalid service change reply:"
+ "~n Expected: handle_trans_reply"
+ "~n Received: ~p", [Else]),
{error, Else, ok}.
-%% otp71922_mg_verify_notify_request_fun() ->
-%% fun(Ev) ->
-%% otp71922_mg_verify_notify_request(Ev)
-%% end.
-
-%% otp71922_mg_verify_notify_request(
-%% {handle_trans_request, _, ?VERSION, [AR]}) ->
-%% io:format("otp71922_mg_verify_notify_request -> ok"
-%% "~n AR: ~p~n", [AR]),
-%% case AR of
-%% #'ActionRequest'{contextId = 1 = Cid,
-%% commandRequests = [CR]} ->
-%% #'CommandRequest'{command = Cmd} = CR,
-%% {notifyReq, NR} = Cmd,
-%% #'NotifyRequest'{terminationID = [Tid],
-%% observedEventsDescriptor = OED,
-%% errorDescriptor = asn1_NOVALUE} = NR,
-%% #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
-%% #'ObservedEvent'{eventName = "al/of"} = OE,
-%% Reply = {discard_ack, [otp71922_mg_notify_reply_ar(Cid, Tid)]},
-%% {ok, AR, Reply};
-%% _ ->
-%% ED = otp71922_err_desc(AR),
-%% ErrReply = {discard_ack, ED},
-%% {error, AR, ErrReply}
-%% end;
-%% otp71922_mg_verify_notify_request(Else) ->
-%% io:format("otp71922_mg_verify_notify_request -> unknown"
-%% "~n Else: ~p~n", [Else]),
-%% ED = otp71922_err_desc(Else),
-%% ErrReply = {discard_ack, ED},
-%% {error, Else, ErrReply}.
-
otp71922_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
{ok, [AR]}, _}) ->
- io:format("otp71922_mg_verify_notify_reply -> ok"
- "~n AR: ~p~n", [AR]),
+ i("received expected handle_notify_reply -> ok"
+ "~n AR: ~p", [AR]),
{ok, AR, ok};
otp71922_mg_verify_notify_reply(Else) ->
- io:format("otp71922_mg_verify_notify_reply -> unknown"
- "~n Else: ~p~n", [Else]),
+ e("otp71922_mg_verify_notify_reply -> invalid notify reply"
+ "~n Expected: handle_trans_reply with ok"
+ "~n Received: ~p", [Else]),
{error, Else, ok}.
otp71922_mg_service_change_request_ar(_Mid, Cid) ->
@@ -8751,18 +8787,6 @@ otp71922_mg_service_change_request_ar(_Mid, Cid) ->
CR = cre_cmdReq(CMD),
cre_actionReq(Cid, [CR]).
-%% otp71922_mg_service_change_request_msg(Mid, TransId, Cid) ->
-%% AR = otp71922_mg_service_change_request_ar(Mid, Cid),
-%% TR = cre_transReq(TransId, [AR]),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
-
-%% otp71922_mg_notify_reply_ar(Cid, TermId) ->
-%% NR = cre_notifyReply([TermId]),
-%% CR = cre_cmdReply(NR),
-%% cre_actionReply(Cid, [CR]).
-
otp71922_mg_notify_request_ar(Rid, Tid, Cid) ->
TT = cre_timeNotation("19990729", "22000000"),
Ev = cre_obsEvent("al/of", TT),
@@ -8772,13 +8796,6 @@ otp71922_mg_notify_request_ar(Rid, Tid, Cid) ->
CR = cre_cmdReq(CMD),
cre_actionReq(Cid, [CR]).
-%% otp71922_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
-%% AR = otp71922_mg_notify_request_ar(Rid, TermId, Cid),
-%% TR = cre_transReq(TransId, [AR]),
-%% Trans = cre_transaction(TR),
-%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
-%% cre_megacoMessage(Mess).
-
%%
%% Common functions for the multi_trans_req_timeout test case
@@ -9632,11 +9649,13 @@ printable(info, info) -> true;
printable(error, _) -> true;
printable(_,_) -> false.
-
print2(true, P, F, A) ->
- S = ?F("*** [~s] ~s ~p ~w ***"
+ S = ?F("*** [~s] ~s ~p~s ***"
"~n " ++ F ++ "~n"
- "~n", [?FTS(), P, self(), get(tc) | A]),
+ "~n", [?FTS(), P, self(), case get(tc) of
+ undefined -> "";
+ TC -> " " ++ atom_to_list(TC)
+ end | A]),
io:format("~s", [S]);
print2(_, _, _, _) ->
ok.
diff --git a/lib/public_key/asn1/PKIX1Algorithms88.asn1 b/lib/public_key/asn1/PKIX1Algorithms88.asn1
index 6cc6745af6..207ab005a9 100644
--- a/lib/public_key/asn1/PKIX1Algorithms88.asn1
+++ b/lib/public_key/asn1/PKIX1Algorithms88.asn1
@@ -283,4 +283,12 @@
sect571k1 OBJECT IDENTIFIER ::= { ellipticCurve 38 }
sect571r1 OBJECT IDENTIFIER ::= { ellipticCurve 39 }
+
+ id-edwards-curve-algs OBJECT IDENTIFIER ::= { 1 3 101 }
+
+ id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 }
+ id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 }
+ id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 }
+ id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 }
+
END
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 6a80874df8..1c79f904f3 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -113,7 +113,8 @@ supportedPublicKeyAlgorithms(?'id-keyExchangeAlgorithm') -> 'KEA-PublicKey';
supportedPublicKeyAlgorithms(?'id-ecPublicKey') -> 'ECPoint'.
supportedCurvesTypes(?'characteristic-two-field') -> characteristic_two_field;
-supportedCurvesTypes(?'prime-field') -> prime_field.
+supportedCurvesTypes(?'prime-field') -> prime_field;
+supportedCurvesTypes(?'id-edwards-curve-algs') -> edwards_curve.
namedCurves(?'sect571r1') -> sect571r1;
namedCurves(?'sect571k1') -> sect571k1;
@@ -148,6 +149,8 @@ namedCurves(?'sect163r1') -> sect163r1;
namedCurves(?'sect163k1') -> sect163k1;
namedCurves(?'secp256r1') -> secp256r1;
namedCurves(?'secp192r1') -> secp192r1;
+namedCurves(?'id-X25519') -> x25519;
+namedCurves(?'id-X448') -> x448;
namedCurves(?'brainpoolP160r1') -> brainpoolP160r1;
namedCurves(?'brainpoolP160t1') -> brainpoolP160t1;
namedCurves(?'brainpoolP192r1') -> brainpoolP192r1;
@@ -162,7 +165,6 @@ namedCurves(?'brainpoolP384r1') -> brainpoolP384r1;
namedCurves(?'brainpoolP384t1') -> brainpoolP384t1;
namedCurves(?'brainpoolP512r1') -> brainpoolP512r1;
namedCurves(?'brainpoolP512t1') -> brainpoolP512t1;
-
namedCurves(sect571r1) -> ?'sect571r1';
namedCurves(sect571k1) -> ?'sect571k1';
namedCurves(sect409r1) -> ?'sect409r1';
@@ -196,6 +198,8 @@ namedCurves(sect163r1) -> ?'sect163r1';
namedCurves(sect163k1) -> ?'sect163k1';
namedCurves(secp256r1) -> ?'secp256r1';
namedCurves(secp192r1) -> ?'secp192r1';
+namedCurves(x25519) -> ?'id-X25519';
+namedCurves(x448) -> ?'id-X448';
namedCurves(brainpoolP160r1) -> ?'brainpoolP160r1';
namedCurves(brainpoolP160t1) -> ?'brainpoolP160t1';
namedCurves(brainpoolP192r1) -> ?'brainpoolP192r1';
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 47266c514c..ce5151750d 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1536,6 +1536,10 @@ ec_curve_spec({ecParameters, ECParams}) ->
ec_curve_spec(ECParams);
ec_curve_spec({namedCurve, OID}) when is_tuple(OID), is_integer(element(1,OID)) ->
ec_curve_spec({namedCurve, pubkey_cert_records:namedCurves(OID)});
+ec_curve_spec({namedCurve, x25519 = Name}) ->
+ Name;
+ec_curve_spec({namedCurve, x448 = Name}) ->
+ Name;
ec_curve_spec({namedCurve, Name}) when is_atom(Name) ->
crypto:ec_curve(Name).
diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml
index a8dea5ab7b..66a1bd900f 100644
--- a/lib/snmp/doc/src/snmp_agent_netif.xml
+++ b/lib/snmp/doc/src/snmp_agent_netif.xml
@@ -36,7 +36,7 @@
<image file="snmp_agent_netif_1.gif">
<icaption>The Purpose of Agent Net if</icaption>
</image>
- <p>The Network Interface (Net if) process delivers SNMP PDUs to a
+ <p>The Network Interface (Net If) process delivers SNMP PDUs to a
master agent, and receives SNMP PDUs from the master agent. The most
common behaviour of a Net if process is that is receives bytes from
a network, decodes them into an SNMP PDU, which it sends to a master
@@ -70,7 +70,7 @@
<marker id="messages"></marker>
<title>Messages</title>
<p>The section <em>Messages</em> describes mandatory messages, which
- Net if must send and be able to receive.
+ Net If must send and be able to receive.
</p>
<p>In this section an <c>Address</c> field is a
<c>{Domain, Addr}</c> tuple where <c>Domain</c> is
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index 54a7eafe76..978aff59b1 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>1997</year><year>2019</year>
+ <year>1997</year><year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -594,7 +594,7 @@ in the snmp_config file!
<tag><marker id="manager_server"></marker>
<c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
- <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()} | {cbproxy, server_cbproxy()}</c></p>
+ <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()} | {cbproxy, server_cbproxy()} | {netif_sup, server_nis()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
@@ -641,6 +641,36 @@ in the snmp_config file!
<p>Default is <c>temporary</c>.</p>
</item>
+ <tag><marker id="manager_server_nis"></marker>
+ <c><![CDATA[server_nis() = none (default) | {PingTO, PongTO} <optional>]]></c></tag>
+ <item>
+ <p>This option specifies if the server should actively supervise the
+ net-if process.
+ Note that this will only work if the used net-if process actually supports
+ the protocol. See
+ <seealso marker="snmpm_network_interface">snmpm_network_interface</seealso> behaviour for more info. </p>
+ <taglist>
+ <tag><marker id="manager_server_nis_none"></marker>
+ <c><![CDATA[none (default)]]></c></tag>
+ <item>
+ <p>No active supervision of the net-if process. </p>
+ </item>
+
+ <tag><marker id="manager_server_nis_active"></marker>
+ <c><![CDATA[{PingTO :: pos_integer(), PongTO :: pos_integer()}]]></c></tag>
+ <item>
+ <p>The <c>PingTO</c> time specifies the between a successful ping
+ (or start) and the time when a ping message is to be sent to the net-if
+ process (basically the time between ping). </p>
+ <p>The <c>PongTO</c> time specifies how long time the net-if process
+ has to respond to a ping message, with a <em>pong</em> message.
+ Its starts counting when the ping message has been sent.</p>
+ <p>Both times are in milli seconds.</p>
+ </item>
+ </taglist>
+ <p>Default is <c>none</c>.</p>
+ </item>
+
<tag><marker id="manager_config"></marker>
<c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index d615edcec0..79c6703c94 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -612,7 +612,7 @@ in so far as it will be converted to the new format if found.
<tag><marker id="manager_server"></marker>
<c><![CDATA[server() = [server_opt()] <optional>]]></c></tag>
<item>
- <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()} | {cbproxy, server_cbproxy()}</c></p>
+ <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()} | {cbproxy, server_cbproxy()} | {netif_sup, server_nis()}</c></p>
<p>Specifies the options for the manager server process.</p>
<p>Default is <c>silence</c>.</p>
</item>
@@ -659,6 +659,40 @@ in so far as it will be converted to the new format if found.
<p>Default is <c>temporary</c>.</p>
</item>
+ <tag><marker id="manager_server_nis"></marker>
+ <c><![CDATA[server_nis() = none (default) | {PingTO, PongTO} <optional>]]></c></tag>
+ <item>
+ <p>This option specifies if the server should actively supervise the
+ net-if process.
+ Note that this will only work if the used net-if process actually supports
+ the protocol. See
+ <seealso marker="snmpm_network_interface">snmpm_network_interface</seealso> behaviour for more info. </p>
+ <taglist>
+ <tag><marker id="manager_server_nis_none"></marker>
+ <c><![CDATA[none (default)]]></c></tag>
+ <item>
+ <p>No active supervision of the net-if process. </p>
+ </item>
+
+ <tag><marker id="manager_server_nis_active"></marker>
+ <c><![CDATA[{PingTO :: pos_integer(), PongTO :: pos_integer()}]]></c></tag>
+ <item>
+ <p>The <c>PingTO</c> time specifies the between a successful ping
+ (or start) and the time when a
+ <seealso marker="snmp_manager_netif#im_ping">ping</seealso>
+ message is to be sent to the net-if
+ process (basically the time between ping:s). </p>
+ <p>The <c>PongTO</c> time specifies how long time the net-if process
+ has to respond to a ping message, with a
+ <seealso marker="snmp_manager_netif#om_pong">pong</seealso>
+ message.
+ It starts counting when the ping message has been sent.</p>
+ <p>Both times are in milli seconds.</p>
+ </item>
+ </taglist>
+ <p>Default is <c>none</c>.</p>
+ </item>
+
<tag><marker id="manager_config"></marker>
<c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag>
<item>
diff --git a/lib/snmp/doc/src/snmp_manager_netif.xml b/lib/snmp/doc/src/snmp_manager_netif.xml
index 0dfcdbda0d..9825f3f3bd 100644
--- a/lib/snmp/doc/src/snmp_manager_netif.xml
+++ b/lib/snmp/doc/src/snmp_manager_netif.xml
@@ -37,7 +37,7 @@
<icaption>The Purpose of Manager Net if</icaption>
</image>
- <p>The Network Interface (Net if) process delivers SNMP PDUs to the
+ <p>The Network Interface (Net If) process delivers SNMP PDUs to the
manager server, and receives SNMP PDUs from the manager server.
The most common behaviour of a Net if process is that is receives
request PDU from the manager server, encodes the PDU into bytes
@@ -54,131 +54,186 @@
both uses UDP as the transport protocol i.e the transport domains
<c>transportDomainUdpIpv4</c> and/or <c>transportDomainUdpIpv6</c>.
The difference between the two modules is that the latter is
- "multi-threaded", i.e. for each message/request a new process
+ "multi-threaded", i.e. for each message/request a new process
is created that processes the message/request and then exits. </p>
+ <p>There is a <c>server</c> config option,
+ <seealso marker="snmp_config#manager_server_nis">netif_sup</seealso>
+ that enables "active" Net If supervision. This is very simple mechanism.
+ The (supervising) process simply sends a
+ <seealso marker="#im_ping">ping</seealso> message and expects a
+ <seealso marker="#om_pong">pong</seealso> message response
+ (withing a specific time).
+ The interval between each <c>ping/pong</c> exhange is user configurable.
+ As is the time that is allowed for the
+ <seealso marker="#om_pong">pong</seealso>
+ message to arrive.
+ Both the NetIf module(s) provided with the app supports active supervision.
+ If a NetIf module/process is used which do not implement this, then
+ the server cannot be configured with active supervision. </p>
+
<p>It is also possible to write your own Net if process and
this section describes how to do that.</p>
<section>
<marker id="mandatory_functions"></marker>
<title>Mandatory Functions</title>
- <p>A Net if process must implement the SNMP manager
+ <p>A Net If process must implement the SNMP manager
<seealso marker="snmpm_network_interface">network interface behaviour</seealso>. </p>
</section>
<section>
<title>Messages</title>
- <p>The section <em>Messages</em> describes mandatory messages, which
- Net if must send to the manager server process.
- </p>
+ <p>The section <em>Messages</em> describes mandatory (with exception
+ for the ping/pong messages) messages,
+ which Net If must send to the manager server process. </p>
<p>In this section a <c>Domain</c> field is the transport domain i.e
one of <c>transportDomainUdpIpv4</c> or <c>transportDomainUdpIpv6</c>,
and an <c>Addr</c> field is an
<c>{</c><seealso marker="kernel:inet#type-ip_address"><c>IpAddr</c></seealso><c>,IpPort}</c> tuple.</p>
- <p>Net if must send the following message when it receives an
- SNMP PDU from the network that is aimed for the MasterAgent:
- </p>
- <pre>
+ <section>
+ <marker id="outgoing_messages"></marker>
+ <title>Outgoing Messages</title>
+
+ <p>Net if must send the following message when it receives an
+ SNMP PDU from the network that is aimed for the MasterAgent: </p>
+ <pre>
Server ! {snmp_pdu, Pdu, Domain, Addr}
- </pre>
- <list type="bulleted">
- <item>
- <p><c>Pdu</c> is an SNMP PDU record, as defined in
- <c>snmp_types.hrl</c>, with the SNMP request.</p>
- </item>
- <item>
- <p><c>Domain</c> is the source transport domain. </p>
- </item>
- <item>
- <p><c>Addr</c> is the source address. </p>
- </item>
- </list>
- <pre>
+ </pre>
+ <list type="bulleted">
+ <item>
+ <p><c>Pdu</c> is an SNMP PDU record, as defined in
+ <c>snmp_types.hrl</c>, with the SNMP request.</p>
+ </item>
+ <item>
+ <p><c>Domain</c> is the source transport domain. </p>
+ </item>
+ <item>
+ <p><c>Addr</c> is the source address. </p>
+ </item>
+ </list>
+
+ <pre>
Server ! {snmp_trap, Trap, Domain, Addr}
- </pre>
- <list type="bulleted">
- <item>
- <p><c>Trap</c> is either an SNMP pdu record or an trappdu record,
- as defined in <c>snmp_types.hrl</c>, with the SNMP request.</p>
- </item>
- <item>
- <p><c>Domain</c> is the source transport domain. </p>
- </item>
- <item>
- <p><c>Addr</c> is the source address. </p>
- </item>
- </list>
- <pre>
+ </pre>
+ <list type="bulleted">
+ <item>
+ <p><c>Trap</c> is either an SNMP pdu record or an trappdu record,
+ as defined in <c>snmp_types.hrl</c>, with the SNMP request.</p>
+ </item>
+ <item>
+ <p><c>Domain</c> is the source transport domain. </p>
+ </item>
+ <item>
+ <p><c>Addr</c> is the source address. </p>
+ </item>
+ </list>
+
+ <pre>
Server ! {snmp_inform, Ref, Pdu, PduMS, Domain, Addr}
- </pre>
- <list type="bulleted">
- <item>
- <p><c>Ref</c> is either the atom <c>ignore</c> or something
- that can be used to identify the inform-request (e.g. request-id).
- <c>ignore</c> is used if the response (acknowledgment) to the
- inform-request has already been sent (this means that the server
- will not make the call to the
- <seealso marker="snmpm_network_interface#inform_response">inform_response</seealso>
- function). See the
- <seealso marker="snmp_config#manager_irb">inform request behaviour</seealso>
- configuration option for more info.</p>
- </item>
- <item>
- <p><c>Pdu</c> is an SNMP PDU record, as defined in
- <c>snmp_types.hrl</c>, with the SNMP request.</p>
- </item>
- <item>
- <p><c>Domain</c> is the source transport domain. </p>
- </item>
- <item>
- <p><c>Addr</c> is the source address. </p>
- </item>
- </list>
- <pre>
+ </pre>
+ <list type="bulleted">
+ <item>
+ <p><c>Ref</c> is either the atom <c>ignore</c> or something
+ that can be used to identify the inform-request (e.g. request-id).
+ <c>ignore</c> is used if the response (acknowledgment) to the
+ inform-request has already been sent (this means that the server
+ will not make the call to the
+ <seealso marker="snmpm_network_interface#inform_response">inform_response</seealso>
+ function). See the
+ <seealso marker="snmp_config#manager_irb">inform request behaviour</seealso>
+ configuration option for more info.</p>
+ </item>
+ <item>
+ <p><c>Pdu</c> is an SNMP PDU record, as defined in
+ <c>snmp_types.hrl</c>, with the SNMP request.</p>
+ </item>
+ <item>
+ <p><c>Domain</c> is the source transport domain. </p>
+ </item>
+ <item>
+ <p><c>Addr</c> is the source address. </p>
+ </item>
+ </list>
+
+ <pre>
Server ! {snmp_report, Data, Domain, Addr}
- </pre>
- <list type="bulleted">
- <item>
- <p><c>Data</c> is either <c>{ok, Pdu}</c> or
- <c>{error, ReqId, ReasonInfo, Pdu}</c>. Which one is used depends
- on the return value from the MPD
- <seealso marker="snmpm_mpd#process_msg">process_msg</seealso> function. If the MsgData is <c>ok</c>,
- the first is used, and if it is <c>{error, ReqId, Reason}</c>
- the latter is used.</p>
- </item>
- <item>
- <p><c>Pdu</c> is an SNMP PDU record, as defined in
- <c>snmp_types.hrl</c>, with the SNMP request.</p>
- </item>
- <item>
- <p><c>ReqId</c> is an integer.</p>
- </item>
- <item>
- <p><c>ReasonInfo</c> is a term().</p>
- </item>
- <item>
- <p><c>Domain</c> is the source transport domain. </p>
- </item>
- <item>
- <p><c>Addr</c> is the source address. </p>
- </item>
- </list>
+ </pre>
+ <list type="bulleted">
+ <item>
+ <p><c>Data</c> is either <c>{ok, Pdu}</c> or
+ <c>{error, ReqId, ReasonInfo, Pdu}</c>. Which one is used depends
+ on the return value from the MPD
+ <seealso marker="snmpm_mpd#process_msg">process_msg</seealso> function. If the MsgData is <c>ok</c>,
+ the first is used, and if it is <c>{error, ReqId, Reason}</c>
+ the latter is used.</p>
+ </item>
+ <item>
+ <p><c>Pdu</c> is an SNMP PDU record, as defined in
+ <c>snmp_types.hrl</c>, with the SNMP request.</p>
+ </item>
+ <item>
+ <p><c>ReqId</c> is an integer.</p>
+ </item>
+ <item>
+ <p><c>ReasonInfo</c> is a term().</p>
+ </item>
+ <item>
+ <p><c>Domain</c> is the source transport domain. </p>
+ </item>
+ <item>
+ <p><c>Addr</c> is the source address. </p>
+ </item>
+ </list>
+
+ <marker id="om_pong"></marker>
+ <pre>
+Supervisor ! {pong, self()}
+ </pre>
+ <list type="bulleted">
+ <item>
+ <p><c>Supervisor</c> is the process that sent the
+ <seealso marker="#im_ping">ping</seealso> message (see below). </p>
+ </item>
+ </list>
+ </section>
<section>
- <title>Notes</title>
- <p>Since the Net if process is responsible for encoding and
- decoding of SNMP messages, it must also update the relevant
- counters in the SNMP group in MIB-II. It can use the functions
- in the module <c>snmpm_mpd</c> for this purpose (refer to the
- Reference Manual, section <c>snmp</c>, module <c>snmpm_mpd</c>
- for more details).
- </p>
- <p>There are also some useful functions for encoding and
- decoding of SNMP messages in the module <c>snmp_pdus</c>.
- </p>
+ <marker id="incoming_messages"></marker>
+ <title>Incoming Messages</title>
+ <p>This section describes the incoming messages which a Net If
+ process may choose to respond to. </p>
+
+ <list type="bulleted">
+ <item>
+ <marker id="im_ping"></marker>
+ <p><c>{ping, Supervisor}</c></p>
+ <p>This message is sent to the Net If process by a process that
+ has been configured to perfor "active supervision" of the Net If
+ process. The Net If process should respond immediately with
+ a <seealso marker="#om_pong">pong</seealso> message. </p>
+ <list type="bulleted">
+ <item>
+ <p><c>Supervisor</c> is a <c>pid()</c>. </p>
+ </item>
+ </list>
+ </item>
+ </list>
</section>
</section>
+
+ <section>
+ <title>Notes</title>
+ <p>Since the Net if process is responsible for encoding and
+ decoding of SNMP messages, it must also update the relevant
+ counters in the SNMP group in MIB-II. It can use the functions
+ in the module <c>snmpm_mpd</c> for this purpose (refer to the
+ Reference Manual, section <c>snmp</c>, module <c>snmpm_mpd</c>
+ for more details). </p>
+
+ <p>There are also some useful functions for encoding and
+ decoding of SNMP messages in the module <c>snmp_pdus</c>. </p>
+ </section>
</chapter>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index c45df98ee0..71308dcf80 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2018</year>
+ <year>2004</year><year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1487,6 +1487,21 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
verbosity <c>silence</c>, nothing is printed. The higher the
verbosity, the more is printed.</p>
+ <marker id="restart"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name since="">restart(Ref) -> void()</name>
+ <fsummary>Restart the indicated process</fsummary>
+ <type>
+ <v>Ref = net_if</v>
+ </type>
+ <desc>
+ <p>Restart the indicated process (<c>Ref</c>). Note that its not
+ without risk to restart a process, and should therefor be used
+ with care. </p>
+
<marker id="format_reason"></marker>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpm_user.xml b/lib/snmp/doc/src/snmpm_user.xml
index c961300490..fe0ac0b0d2 100644
--- a/lib/snmp/doc/src/snmpm_user.xml
+++ b/lib/snmp/doc/src/snmpm_user.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -96,7 +96,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(),
<name since="">handle_error(ReqId, Reason, UserData) -> void()</name>
<fsummary>Handle error</fsummary>
<type>
- <v>ReqId = integer()</v>
+ <v>ReqId = netif | integer()</v>
<v>Reason = {unexpected_pdu, SnmpInfo} | {invalid_sec_info, SecInfo, SnmpInfo} | {empty_message, Addr, Port} | term()</v>
<v>SnmpInfo = snmp_gen_info()</v>
<v>SecInfo = term()</v>
@@ -115,7 +115,11 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(),
<p>If <c>ReqId</c> is less then 0, it means that this
information was not available to the manager (that info was
never retrieved before the message was discarded). </p>
- <p>For <c>SnmpInfo</c> see handle_agent below.</p>
+ <p>For <c>SnmpInfo</c> see handle_agent below.</p>
+ <p>Note that there is a special case when the value of <c>ReqId</c>
+ has the value of the atom <c>netif</c>. This means that the NetIF
+ process has suffered a "fatal" error and been restarted.
+ With possible loss of traffic! </p>
<marker id="handle_agent"></marker>
</desc>
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index 8e60cecaf9..c0859f6fd8 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -89,8 +89,9 @@
system_start_time/0,
sys_up_time/0,
- info/0,
- verbosity/2
+ info/0, info/1,
+ verbosity/2,
+ restart/1
]).
-export([format_reason/1, format_reason/2]).
@@ -297,6 +298,9 @@ oid_to_type(Oid) ->
info() ->
snmpm_server:info().
+info(Key) ->
+ proplists:get_value(Key, info(), {error, not_found}).
+
%% -- Verbosity --
@@ -316,6 +320,16 @@ verbosity(all, V) ->
snmpm_server:verbosity(note_store, V).
+%% -- Restart --
+
+%% Restart various component processes in the manager
+%% Note that the effects of this is diffiult to
+%% predict, so it should be use with *caution*!
+
+restart(net_if = What) ->
+ snmpm_server:restart(What).
+
+
%% -- Users --
%% Register the 'user'.
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index fc6ddc5738..decda09022 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -151,6 +151,7 @@
-define(SERVER_OPT_GCT_DEFAULT, 30000).
-define(SERVER_OPT_MT_DEFAULT, true).
-define(SERVER_OPT_CBP_DEFAULT, temporary). % permanent
+-define(SERVER_OPT_NIS_DEFAULT, none).
%% -define(DEF_ADDR_TAG, default_addr_tag).
-define(DEFAULT_TARGETNAME, default_agent).
@@ -1115,15 +1116,17 @@ do_init(Opts) ->
end,
%% -- Server (optional) --
- ServerOpts = get_opt(server, Opts, []),
+ ServerOpts = get_opt(server, Opts, []),
ServerVerb = get_opt(verbosity, ServerOpts, ?SERVER_OPT_VERB_DEFAULT),
ServerGct = get_opt(timeout, ServerOpts, ?SERVER_OPT_GCT_DEFAULT),
ServerMt = get_opt(multi_threaded, ServerOpts, ?SERVER_OPT_MT_DEFAULT),
ServerCBP = get_opt(cbproxy, ServerOpts, ?SERVER_OPT_CBP_DEFAULT),
+ ServerNIS = get_opt(netif_sup, ServerOpts, ?SERVER_OPT_NIS_DEFAULT),
ets:insert(snmpm_config_table, {server_verbosity, ServerVerb}),
ets:insert(snmpm_config_table, {server_timeout, ServerGct}),
ets:insert(snmpm_config_table, {server_multi_threaded, ServerMt}),
ets:insert(snmpm_config_table, {server_cbproxy, ServerCBP}),
+ ets:insert(snmpm_config_table, {server_nis, ServerNIS}),
%% -- Mibs (optional) --
?vdebug("initiate mini mib", []),
@@ -1132,7 +1135,7 @@ do_init(Opts) ->
init_mini_mib(Mibs),
%% -- Net-if (optional) --
- ?vdebug("net_if options", []),
+ ?vdebug("net-if options", []),
NetIfIrb =
case get_opt(inform_request_behaviour, Opts, ?IRB_DEFAULT) of
user ->
@@ -1421,6 +1424,9 @@ verify_server_opts([{multi_threaded, MT}|Opts]) when is_boolean(MT) ->
verify_server_opts([{cbproxy, CBP}|Opts]) ->
verify_server_cbproxy(CBP),
verify_server_opts(Opts);
+verify_server_opts([{netif_sup, NIS}|Opts]) ->
+ verify_server_nis(NIS),
+ verify_server_opts(Opts);
verify_server_opts([Opt|_]) ->
error({invalid_server_option, Opt}).
@@ -1436,6 +1442,17 @@ verify_server_cbproxy(permanent) ->
verify_server_cbproxy(CBP) ->
error({invalid_server_cbproxy, CBP}).
+verify_server_nis(none) ->
+ ok;
+verify_server_nis({PingTo, PongTo} = V) when is_integer(PingTo) andalso
+ (PingTo > 0) andalso
+ is_integer(PongTo) andalso
+ (PongTo > 0) ->
+ ok;
+verify_server_nis(NIS) ->
+ error({invalid_server_netif_sup, NIS}).
+
+
verify_net_if_opts([]) ->
ok;
verify_net_if_opts([{module, Mod}|Opts]) ->
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index c2e5c6d2f0..0d57bc944a 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -58,6 +58,14 @@
%% -define(VMODULE,"NET_IF").
-include("snmp_verbosity.hrl").
+%% This is for debugging!!
+-ifdef(snmp_debug).
+-define(allow_exec, true).
+-else.
+-define(allow_exec, false).
+-endif.
+
+
-record(state,
{
server,
@@ -67,7 +75,8 @@
log,
irb = auto, % auto | {user, integer()}
irgc,
- filter
+ filter,
+ allow_exec = ?allow_exec
}).
-record(transport,
@@ -92,6 +101,7 @@
-define(ATL_SEQNO_MAX, 2147483647).
+
%%%-------------------------------------------------------------------
%%% API
%%%-------------------------------------------------------------------
@@ -520,6 +530,13 @@ handle_call(info, _From, State) ->
Reply = get_info(State),
{reply, Reply, State};
+%% This is for debugging!!
+handle_call({exec, F}, _From, #state{allow_exec = true} = State)
+ when is_function(F, 0) ->
+ ?vlog("[call] exec", []),
+ {reply, F(), State};
+
+
handle_call(Req, From, State) ->
warning_msg("received unknown request (from ~p): ~n~p", [Req, From]),
{reply, {error, {invalid_request, Req}}, State}.
@@ -556,6 +573,13 @@ handle_cast(filter_reset, State) ->
reset_counters(),
{noreply, State};
+%% This is for debugging!!
+handle_cast({exec, F}, #state{allow_exec = true} = State) when is_function(F, 0) ->
+ ?vlog("[cast] exec", []),
+ F(),
+ {noreply, State};
+
+
handle_cast(Msg, State) ->
warning_msg("received unknown message: ~n~p", [Msg]),
{noreply, State}.
@@ -597,6 +621,20 @@ handle_info({disk_log, _Node, Log, Info}, State) ->
handle_info({'DOWN', _, _, _, _} = Info, State) ->
handle_info_down(Info, State);
+
+handle_info({ping, Pid}, State) ->
+ ?vdebug("received ping message from ~p", [Pid]),
+ Pid ! {pong, self()},
+ {noreply, State};
+
+
+%% This is for debugging!!
+handle_info({exec, F}, #state{allow_exec = true} = State) when is_function(F, 0) ->
+ ?vlog("[info] exec", []),
+ F(),
+ {noreply, State};
+
+
handle_info(Info, State) ->
handle_info_unknown(Info, State).
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index fe2c22d9ba..1a8d09ab9b 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -45,13 +45,13 @@
%% discovery/2, discovery/3, discovery/4, discovery/5, discovery/6,
- %% system_info_updated/2,
get_log_type/0, set_log_type/1,
reconfigure/0,
info/0,
- verbosity/1, verbosity/2
+ verbosity/1, verbosity/2,
+ restart/1
]).
@@ -77,6 +77,9 @@
%% GCT exports
-export([gct_init/1, gct/2]).
+%% NIS exports
+-export([nis_init/2, nis_loop/1]).
+
%% CallBack Proxy exports
-export([cbproxy_loop/1,
do_handle_error/4,
@@ -157,6 +160,24 @@
net_if,
net_if_mod,
net_if_ref,
+
+ %% NetIF supervision
+ %% This (config) option defines if/how the "server"
+ %% shall supervise the net-if process.
+ %% And by "supervise" we don't meant in the way a
+ %% *supervisor" supervisor. This is "active" supervision
+ %% (basically, send ping and expect pong back).
+ %% There are two alternatives:
+ %% none - No supervision (default)
+ %% {PingInterval, PongTimeout}
+ %% PingInterval :: pos_integer()
+ %% Time between a successful test and the next.
+ %% PongInterval :: pos_integer()
+ %% Time the NetIF process has to answer a ping
+ %%
+ nis :: none | {pos_integer(), pos_integer()},
+ nis_pid :: undefined | pid(), % Pid of the process doing the actual sup
+
req, %% ???? Last request id in outgoing message
oid, %% ???? Last oid in request outgoing message
mini_mib,
@@ -492,6 +513,9 @@ cancel_async_request(UserId, ReqId) ->
call({cancel_async_request, UserId, ReqId}).
+info() ->
+ call(info).
+
verbosity(Verbosity) ->
case ?vvalidate(Verbosity) of
Verbosity ->
@@ -500,9 +524,6 @@ verbosity(Verbosity) ->
{error, {invalid_verbosity, Verbosity}}
end.
-info() ->
- call(info).
-
verbosity(net_if = Ref, Verbosity) ->
verbosity2(Ref, Verbosity);
verbosity(note_store = Ref, Verbosity) ->
@@ -516,9 +537,10 @@ verbosity2(Ref, Verbosity) ->
{error, {invalid_verbosity, Verbosity}}
end.
-%% Target -> all | server | net_if
-%% system_info_updated(Target, What) ->
-%% call({system_info_updated, Target, What}).
+
+restart(net_if = What) ->
+ cast({restart, What}).
+
get_log_type() ->
call(get_log_type).
@@ -590,6 +612,15 @@ do_init() ->
{NoteStore, NoteStoreRef} = do_init_note_store(Prio),
{NetIf, NetIfModule, NetIfRef} = do_init_net_if(NoteStore),
+ %% -- (maybe) Start the NetIF "supervisor" --
+ {NIS, NISPid} =
+ case snmpm_config:system_info(server_nis) of
+ {ok, none = V} ->
+ {V, undefined};
+ {ok, {PingTO, PongTO} = V} ->
+ {V, nis_start(NetIf, PingTO, PongTO)}
+ end,
+
MiniMIB = snmpm_config:make_mini_mib(),
State = #state{mini_mib = MiniMIB,
gct = GCT,
@@ -598,6 +629,8 @@ do_init() ->
net_if = NetIf,
net_if_mod = NetIfModule,
net_if_ref = NetIfRef,
+ nis = NIS,
+ nis_pid = NISPid,
cbproxy = CBProxy,
cbproxy_pid = CBPPid},
?vlog("started", []),
@@ -624,7 +657,7 @@ do_init_note_store(Prio) ->
end.
do_init_net_if(NoteStore) ->
- ?vdebug("try start net if", []),
+ ?vdebug("try start net-if", []),
{ok, NetIfModule} = snmpm_config:system_info(net_if_module),
case snmpm_misc_sup:start_net_if(NetIfModule, NoteStore) of
{ok, Pid} ->
@@ -638,6 +671,7 @@ do_init_net_if(NoteStore) ->
throw({error, {failed_starting_net_if, Reason}})
end.
+
%% ---------------------------------------------------------------------
%% ---------------------------------------------------------------------
@@ -1017,6 +1051,13 @@ handle_call(Req, _From, State) ->
{reply, {error, unknown_request}, State}.
+handle_cast({restart, net_if},
+ #state{net_if = Pid} = State) ->
+ ?vlog("received net_if (~p) restart message", [Pid]),
+ %% We will get an exit signel/message, which will trigger a (re-)start
+ exit(Pid, kill),
+ {noreply, State};
+
handle_cast(Msg, State) ->
warning_msg("received unknown message: ~n~p", [Msg]),
{noreply, State}.
@@ -1077,19 +1118,18 @@ handle_info(gc_timeout, #state{gct = GCT} = State) ->
{noreply, State};
-handle_info({'DOWN', _MonRef, process, Pid, _Reason},
- #state{note_store = NoteStore,
- net_if = Pid} = State) ->
- ?vlog("received 'DOWN' message regarding net_if", []),
- {NetIf, _, Ref} = do_init_net_if(NoteStore),
- {noreply, State#state{net_if = NetIf, net_if_ref = Ref}};
+handle_info({'DOWN', _MonRef, process, Pid, Reason},
+ #state{net_if = Pid} = State) ->
+ ?vlog("received 'DOWN' message regarding net_if (~p)", [Pid]),
+ NewState = handle_netif_down(State, Reason),
+ {noreply, NewState};
handle_info({'DOWN', _MonRef, process, Pid, _Reason},
#state{note_store = Pid,
net_if = NetIf,
net_if_mod = Mod} = State) ->
- ?vlog("received 'DOWN' message regarding note_store", []),
+ ?vlog("received 'DOWN' message regarding note_store (~p)", [Pid]),
{ok, Prio} = snmpm_config:system_info(prio),
{NoteStore, Ref} = do_init_note_store(Prio),
Mod:note_store(NetIf, NoteStore),
@@ -1118,8 +1158,17 @@ handle_info({'EXIT', Pid, Reason}, #state{cbproxy_pid = Pid} = State) ->
{noreply, State#state{cbproxy_pid = NewCBP}};
+handle_info({'EXIT', Pid, Reason}, #state{net_if = NetIF,
+ nis = {PingTO, PongTO},
+ nis_pid = Pid} = State) ->
+ warning_msg("NetIF (active) supervisor (~w) process crashed: "
+ "~n ~p", [Pid, Reason]),
+ NewNIS = nis_start(NetIF, PingTO, PongTO),
+ {noreply, State#state{nis_pid = NewNIS}};
+
+
handle_info(Info, State) ->
- warning_msg("received unknown info: ~n~p", [Info]),
+ warning_msg("received unknown info: ~n ~p", [Info]),
{noreply, State}.
@@ -1146,8 +1195,9 @@ code_change(_Vsn, #state{gct = Pid} = State0, _Extra) ->
%% Terminate
%%----------------------------------------------------------
-terminate(Reason, #state{gct = GCT, cbproxy = CBP}) ->
+terminate(Reason, #state{nis_pid = NIS, gct = GCT, cbproxy = CBP}) ->
?vdebug("terminate: ~p",[Reason]),
+ nis_stop(NIS),
cbproxy_stop(CBP),
gct_stop(GCT),
snmpm_misc_sup:stop_note_store(),
@@ -3119,7 +3169,17 @@ handle_invalid_result(Func, Args, InvalidResult) ->
"~n Invalid result: ~p",
[Func, Args, InvalidResult]).
-
+
+handle_netif_down(#state{note_store = NoteStore,
+ nis_pid = NIS} = State,
+ Reason) ->
+ %% Srart a new NetIF
+ {NetIF, _, Ref} = do_init_net_if(NoteStore),
+ %% Inform the (active) supervisor
+ nis_netif(NIS, NetIF),
+ netif_down_inform_users(Reason),
+ State#state{net_if = NetIF, net_if_ref = Ref}.
+
handle_down(MonRef) ->
(catch do_handle_down(MonRef)).
@@ -3608,6 +3668,258 @@ new_timeout(T1, T2) ->
%%----------------------------------------------------------------------
+%% NetIF Supervisor
+%%
+%% The NIS process "supervises" the NetIF process. That does *not* mean
+%% that it takes on the role of a standard erlang 'supervisor' process.
+%% The NIS is instead a process that "actively" supervises by means
+%% of "ping" messages, which the supervised process must respond to
+%% (with a pong message) *in time*.
+%% If it does not, NIS assumes that it has hung, and kills it.
+%% The server process then restarts the NetIF process and informs NIS.
+%%----------------------------------------------------------------------
+
+nis_start(NetIF, PingTO, PongTO) ->
+ ?vdebug("start nis process (~w, ~w)", [PingTO, PongTO]),
+ State = #{parent => self(),
+ netif_pid => NetIF,
+ ping_to => PingTO,
+ ping_tref => undefined,
+ ping_start => undefined, % Time when ping sent
+ ping_max => undefined, % Max roundtrip time
+ pong_to => PongTO,
+ pong_tref => undefined,
+ kill_cnt => 0},
+ proc_lib:start_link(?MODULE, nis_init, [State, get(verbosity)]).
+
+nis_stop(NIS) when is_pid(NIS) ->
+ NIS ! {?MODULE, self(), stop};
+nis_stop(_) ->
+ ok.
+
+
+nis_info(NIS) when is_pid(NIS) ->
+ NIS ! {?MODULE, self(), info},
+ receive
+ {?MODULE, NIS, {info, Info}} ->
+ Info
+ after 1000 ->
+ []
+ end;
+nis_info(_) ->
+ [].
+
+
+nis_netif(NIS, NetIF) when is_pid(NIS) andalso is_pid(NetIF) ->
+ NIS ! {?MODULE, self(), {netif, NetIF}};
+nis_netif(_, _) ->
+ ok.
+
+
+nis_init(#{parent := Parent,
+ netif_pid := NetIF,
+ ping_to := PingTO} = State,
+ Verbosity) ->
+ put(verbosity, Verbosity),
+ put(sname, mnis),
+ ?vlog("starting"),
+ MRef = erlang:monitor(process, NetIF),
+ TRef = erlang:start_timer(PingTO, self(), ping_timeout),
+ erlang:register(snmpm_server_nis, self()),
+ proc_lib:init_ack(Parent, self()),
+ ?vlog("started"),
+ nis_loop(State#{netif_mref => MRef,
+ ping_tref => TRef}).
+
+%% The NetIF is dead. Its up to the server to restart it and inform us
+nis_loop(#{parent := Parent,
+ netif_pid := undefined,
+ ping_tref := undefined,
+ pong_tref := undefined} = State) ->
+ receive
+ {?MODULE, Parent, stop} ->
+ ?vlog("[idle] stop received"),
+ nis_handle_stop(State),
+ exit(normal);
+
+ {?MODULE, Pid, info} ->
+ ?vtrace("[idle] info received"),
+ Info = nis_handle_info(State),
+ Pid ! {?MODULE, self(), {info, Info}},
+ ?MODULE:nis_loop(State);
+
+ {?MODULE, Parent, {netif, NetIF}} ->
+ ?vlog("[idle] (new) netif started: ~p => start ping timer", [NetIF]),
+ MRef = erlang:monitor(process, NetIF),
+ PingTO = maps:get(ping_to, State),
+ TRef = erlang:start_timer(PingTO, self(), ping_timeout),
+ ?MODULE:nis_loop(State#{netif_pid => NetIF,
+ netif_mref => MRef,
+ ping_max => undefined,
+ ping_tref => TRef});
+
+ _Any ->
+ ?MODULE:nis_loop(State)
+
+ after 5000 ->
+ %% This is for code upgrade
+ ?MODULE:nis_loop(State)
+ end;
+
+%% PING timer running (waiting for ping-timeout)
+nis_loop(#{parent := Parent,
+ netif_pid := NetIF,
+ netif_mref := MRef,
+ ping_tref := PingTRef,
+ pong_tref := undefined} = State) when is_pid(NetIF) andalso
+ (PingTRef =/= undefined) ->
+ receive
+ {'DOWN', MRef, process, NetIF, _} ->
+ ?vlog("[ping] netif died => cancel ping timer"),
+ erlang:cancel_timer(PingTRef),
+ ?MODULE:nis_loop(State#{netif_pid => undefined,
+ netif_mref => undefined,
+ ping_tref => undefined});
+
+ {?MODULE, Parent, stop} ->
+ ?vlog("[ping] stop received"),
+ nis_handle_stop(State),
+ exit(normal);
+
+ {?MODULE, Pid, info} ->
+ ?vtrace("[ping] info received"),
+ Info = nis_handle_info(State),
+ Pid ! {?MODULE, self(), {info, Info}},
+ ?MODULE:nis_loop(State);
+
+ %% Time to ping NetIF
+ {timeout, PingTRef, ping_timeout} ->
+ ?vlog("[ping] (ping-) timer timeout => send ping and start pong timer"),
+ NetIF ! {ping, self()},
+ PongTO = maps:get(pong_to, State),
+ TRef = erlang:start_timer(PongTO, self(), pong_timeout),
+ ?MODULE:nis_loop(State#{ping_tref => undefined,
+ ping_start => us(),
+ pong_tref => TRef});
+
+ _Any ->
+ ?MODULE:nis_loop(State)
+
+ after 5000 ->
+ %% This is for code upgrade
+ ?MODULE:nis_loop(State)
+ end;
+
+%% PONG timer running (waiting for pong message)
+nis_loop(#{parent := Parent,
+ netif_pid := NetIF,
+ netif_mref := MRef,
+ ping_tref := undefined,
+ pong_tref := PongTRef} = State) when is_pid(NetIF) andalso
+ (PongTRef =/= undefined) ->
+ receive
+ {'DOWN', MRef, process, NetIF, _} ->
+ ?vlog("[pong] netif died => cancel pong timer"),
+ erlang:cancel_timer(PongTRef),
+ ?MODULE:nis_loop(State#{netif_pid => undefined,
+ netif_mref => undefined,
+ pong_tref => undefined});
+
+ {?MODULE, Parent, stop} ->
+ ?vlog("[pong] stop received"),
+ nis_handle_stop(State),
+ exit(normal);
+
+ {?MODULE, Pid, info} ->
+ ?vlog("[pong] info received"),
+ Info = nis_handle_info(State),
+ Pid ! {?MODULE, self(), {info, Info}},
+ ?MODULE:nis_loop(State);
+
+ {pong, NetIF} ->
+ ?vlog("[pong] received pong => cancel pong timer, start ping timer"),
+ T = us(),
+ erlang:cancel_timer(PongTRef),
+ Start = maps:get(ping_start, State),
+ Max = maps:get(ping_max, State),
+ RT = T - Start,
+ NewMax =
+ if
+ (Max =:= undefined) ->
+ ?vtrace("[pong] Max: ~w", [RT]),
+ RT;
+ (RT > Max) ->
+ ?vtrace("[pong] New Max: ~w", [RT]),
+ RT;
+ true ->
+ Max
+ end,
+ PingTO = maps:get(ping_to, State),
+ PingTRef = erlang:start_timer(PingTO, self(), ping_timeout),
+ ?MODULE:nis_loop(State#{ping_tref => PingTRef,
+ ping_start => undefined,
+ ping_max => NewMax,
+ pong_tref => undefined});
+
+ %% Time to kill NetIF
+ {timeout, PongTRef, pong_timeout} ->
+ ?vinfo("[pong] (pong-) timer timeout => kill NetIF (~p)", [NetIF]),
+ nis_handle_pong_timeout(NetIF, MRef),
+ KCnt = maps:get(kill_cnt, State),
+ ?MODULE:nis_loop(State#{netif_pid => undefined,
+ netif_mref => undefined,
+ pong_tref => undefined,
+ kill_cnt => KCnt + 1});
+
+ _Any ->
+ ?MODULE:nis_loop(State)
+
+ after 5000 ->
+ %% This is for code upgrade
+ ?MODULE:nis_loop(State)
+ end.
+
+
+nis_handle_info(#{ping_max := undefined, kill_cnt := KCnt}) ->
+ [{kcnt, KCnt}];
+nis_handle_info(#{ping_max := Max, kill_cnt := KCnt}) ->
+ [{max, Max}, {kcnt, KCnt}].
+
+
+nis_handle_stop(#{pong_tref := PongTRef,
+ ping_tref := PingTRef}) ->
+ cancel_timer(PongTRef),
+ cancel_timer(PingTRef).
+
+%% Inform all users that the netif process has been killed
+nis_handle_pong_timeout(NetIF, MRef) ->
+ erlang:demonitor(MRef, [flush]),
+ exit(NetIF, kill),
+ netif_down_inform_users({pong, killed}),
+ ok.
+
+
+%%----------------------------------------------------------------------
+
+%% Inform all users that "something" fatal happened to the NetIF process.
+netif_down_inform_users(Reason) ->
+ InformUser = fun(UserId) ->
+ spawn(fun() ->
+ case snmpm_config:user_info(UserId) of
+ {ok, UserMod, UserData} ->
+ UserMod:handle_error(netif,
+ Reason,
+ UserData);
+ {error, _} ->
+ ok
+ end,
+ exit(normal)
+ end)
+ end,
+ lists:foreach(InformUser, snmpm_config:which_users()).
+
+
+%%----------------------------------------------------------------------
maybe_delete(false, ReqId) ->
ets:delete(snmpm_request_table, ReqId);
@@ -3651,6 +3963,9 @@ is_started(#state{net_if = _Pid, net_if_mod = _Mod}) ->
%%----------------------------------------------------------------------
+cast(Req) ->
+ gen_server:cast(?SERVER, Req).
+
call(Req) ->
call(Req, infinity).
@@ -3672,15 +3987,16 @@ get_info(#state{gct = GCT,
net_if = NI,
net_if_mod = NIMod,
note_store = NS,
+ nis_pid = NIS,
cbproxy = CBP}) ->
- Info = [{server, server_info(GCT, CBP)},
+ Info = [{server, server_info(GCT, CBP, NIS)},
{config, config_info()},
{net_if, net_if_info(NI, NIMod)},
{note_store, note_store_info(NS)},
{stats_counters, get_stats_counters()}],
Info.
-server_info(GCT, CBP) ->
+server_info(GCT, CBP, NIS) ->
{CBPInfo, CBPSz} =
if
(CBP =:= permanent) ->
@@ -3689,12 +4005,20 @@ server_info(GCT, CBP) ->
true ->
{[], []}
end,
+ {NISInfo, NISSz} =
+ case NIS of
+ undefined ->
+ {[], []};
+ _ ->
+ {[{nis, nis_info(NIS)}],
+ [{nis, proc_mem(NIS)}]}
+ end,
ProcSize = proc_mem(self()),
GCTSz = proc_mem(GCT),
RTSz = tab_size(snmpm_request_table),
MTSz = tab_size(snmpm_monitor_table),
- [{process_memory, [{server, ProcSize}, {gct, GCTSz}] ++ CBPSz},
- {db_memory, [{request, RTSz}, {monitor, MTSz}]}] ++ CBPInfo.
+ [{process_memory, [{server, ProcSize}, {gct, GCTSz}] ++ CBPSz ++ NISSz},
+ {db_memory, [{request, RTSz}, {monitor, MTSz}]}] ++ CBPInfo ++ NISInfo.
proc_mem(P) when is_pid(P) ->
case (catch erlang:process_info(P, memory)) of
@@ -3744,3 +4068,6 @@ note_store_info(Pid) ->
%%----------------------------------------------------------------------
+
+us() ->
+ erlang:monotonic_time(micro_seconds).
diff --git a/lib/snmp/src/manager/snmpm_user.erl b/lib/snmp/src/manager/snmpm_user.erl
index c0100d372f..9d0077449a 100644
--- a/lib/snmp/src/manager/snmpm_user.erl
+++ b/lib/snmp/src/manager/snmpm_user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -41,7 +41,7 @@
%% An "asynchronous" error has been detected
-callback handle_error(
- ReqId :: integer(),
+ ReqId :: netif | integer(),
Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} |
{invalid_sec_info,
SecInfo :: term(),
diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl
index 9b2676d048..a42a1acb3a 100644
--- a/lib/snmp/src/misc/snmp_verbosity.erl
+++ b/lib/snmp/src/misc/snmp_verbosity.erl
@@ -138,6 +138,7 @@ image_of_sname(mns) -> "M-NOTE-STORE";
image_of_sname(mnif) -> "M-NET-IF";
image_of_sname(mnifl) -> "M-NET-IF-LOGGER";
image_of_sname(mnifw) -> io_lib:format("M-NET-IF-worker(~p)", [self()]);
+image_of_sname(mnis) -> "M-NIS";
image_of_sname(mconf) -> "M-CONF";
image_of_sname(lc) -> io_lib:format("LOG-CONVERTER(~p)", [self()]);
diff --git a/lib/snmp/src/misc/snmp_verbosity.hrl b/lib/snmp/src/misc/snmp_verbosity.hrl
index c79f4c3e88..6aef28a854 100644
--- a/lib/snmp/src/misc/snmp_verbosity.hrl
+++ b/lib/snmp/src/misc/snmp_verbosity.hrl
@@ -24,39 +24,59 @@
-ifdef(VMODULE).
+-define(vinfo(F), ?vinfo(F, [])).
-define(vinfo(F,A), snmp_verbosity:print(get(verbosity),info, ?VMODULE,F,A)).
+-define(vlog(F), ?vlog(F, [])).
-define(vlog(F,A), snmp_verbosity:print(get(verbosity),log, ?VMODULE,F,A)).
+-define(vdebug(F), ?vdebug(F, [])).
-define(vdebug(F,A),snmp_verbosity:print(get(verbosity),debug,?VMODULE,F,A)).
+-define(vtrace(F), ?vtrace(F, [])).
-define(vtrace(F,A),snmp_verbosity:print(get(verbosity),trace,?VMODULE,F,A)).
-else.
+-define(vinfo(F), ?vinfo(F, [])).
-define(vinfo(F,A), snmp_verbosity:print(get(verbosity),info, F,A)).
+-define(vlog(F), ?vlog(F, [])).
-define(vlog(F,A), snmp_verbosity:print(get(verbosity),log, F,A)).
+-define(vdebug(F), ?vdebug(F, [])).
-define(vdebug(F,A),snmp_verbosity:print(get(verbosity),debug,F,A)).
+-define(vtrace(F), ?vtrace(F, [])).
-define(vtrace(F,A),snmp_verbosity:print(get(verbosity),trace,F,A)).
-endif.
-define(vvalidate(V), snmp_verbosity:validate(V)).
+-define(vinfoc(F), ?vinfoc(F, [])).
-define(vinfoc(F,A), snmp_verbosity:printc(get(verbosity),info, F,A)).
+-define(vlogc(F), ?vlogc(F, [])).
-define(vlogc(F,A), snmp_verbosity:printc(get(verbosity),log, F,A)).
+-define(vdebugc(F), ?vdebug(F, [])).
-define(vdebugc(F,A),snmp_verbosity:printc(get(verbosity),debug,F,A)).
+-define(vtracec(F), ?vtracec(F, [])).
-define(vtracec(F,A),snmp_verbosity:printc(get(verbosity),trace,F,A)).
-else.
-define(vvalidate(V),ok).
--define(vinfo(F,A),ok).
--define(vlog(F,A),ok).
--define(vdebug(F,A),ok).
--define(vtrace(F,A),ok).
-
--define(vinfoc(F,A),ok).
--define(vlogc(F,A),ok).
+-define(vinfo(F), ok).
+-define(vinfo(F,A), ok).
+-define(vlog(F), ok).
+-define(vlog(F,A), ok).
+-define(vdebug(F), ok).
+-define(vdebug(F,A), ok).
+-define(vtrace(F), ok).
+-define(vtrace(F,A), ok).
+
+-define(vinfoc(F), ok).
+-define(vinfoc(F,A), ok).
+-define(vlogc(F), ok).
+-define(vlogc(F,A), ok).
+-define(vdebugc(F), ok).
-define(vdebugc(F,A),ok).
+-define(vtracec(F), ok).
-define(vtracec(F,A),ok).
-endif.
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index a9a88ccbfa..0e24506c5d 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
+# Copyright Ericsson AB 1997-2020. 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.
@@ -89,14 +89,8 @@ ifeq ($(SNMP_DEBUG),)
# SNMP_DEBUG = d
endif
-ifeq ($(SNMP_DEBUG),e)
- SNMP_FLAGS += -Dsnmp_error
-endif
-ifeq ($(SNMP_DEBUG),l)
- SNMP_FLAGS += -Dsnmp_error -Dsnmp_log
-endif
ifeq ($(SNMP_DEBUG),d)
- SNMP_FLAGS += -Dsnmp_error -Dsnmp_log -Dsnmp_debug
+ SNMP_FLAGS += -Dsnmp_debug
endif
ifeq ($(DONT_USE_TS),true)
@@ -175,7 +169,7 @@ emakebuild: $(EMAKEFILE)
targets: mib $(EMAKEFILE)
erl -make
-old_targets: mib $(TARGET_FILES) $(TEST_SERVER_TARGETS)
+old_targets: mib $(TARGET_FILES)
$(EMAKEFILE): Makefile
$(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' > $(EMAKEFILE)
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index a1554815d9..ba0aea21dd 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2019. All Rights Reserved.
+# Copyright Ericsson AB 2004-2020. 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.
@@ -35,14 +35,14 @@ SUITE_MODULES = \
snmp_to_snmpnet_SUITE
TEST_UTIL_MODULES = \
- snmp_agent_test_get \
+ snmp_test_lib \
snmp_agent_test_lib \
+ snmp_agent_test_get \
snmp_manager_user \
snmp_manager_user_old \
snmp_manager_user_test_lib \
snmp_test_global_sys_monitor \
snmp_test_sys_monitor \
- snmp_test_lib \
snmp_test_manager \
snmp_test_mgr \
snmp_test_mgr_misc \
@@ -52,10 +52,6 @@ TEST_UTIL_MODULES = \
test1 \
test2
-TEST_SERVER_MODULES = \
- snmp_test_server \
- snmp_test_suite
-
MODULES = \
$(TEST_UTIL_MODULES) \
$(SUITE_MODULES)
diff --git a/lib/snmp/test/snmp_agent_SUITE.erl b/lib/snmp/test/snmp_agent_SUITE.erl
index 609ac6cea8..2a6cfbedbe 100644
--- a/lib/snmp/test/snmp_agent_SUITE.erl
+++ b/lib/snmp/test/snmp_agent_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -481,22 +481,22 @@
-define(expect1(What),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
What)).
-define(expect2(What, ExpVBs),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
What, ExpVBs)).
-define(expect3(Err, Idx, ExpVBs),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
Err, Idx, ExpVBs)).
-define(expect4(Err, Idx, ExpVBs, To),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
Err, Idx, ExpVBs, To)).
-define(expect5(Type, Ent, Gen, Spec, ExpVBs),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
Type, Ent, Gen, Spec, ExpVBs)).
-define(expect6(Type, Ent, Gen, Spec, ExpVBs, To),
- snmp_agent_test_lib:expect(?MODULE, ?LINE,
+ ?ALIB:expect(?MODULE, ?LINE,
Type, Ent, Gen, Spec, ExpVBs, To)).
@@ -578,9 +578,9 @@ all_cases() ->
init_per_suite(Config0) when is_list(Config0) ->
- p("init_per_suite -> entry with"
- "~n Config: ~p"
- "~n Nodes: ~p", [Config0, erlang:nodes()]),
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p", [Config0, erlang:nodes()]),
case ?LIB:init_per_suite(Config0) of
{skip, _} = SKIP ->
@@ -601,33 +601,34 @@ init_per_suite(Config0) when is_list(Config0) ->
snmp_test_mgr_counter_server:start(),
- p("init_per_suite -> end when"
- "~n Config: ~p"
- "~n Nodes: ~p", [Config4, erlang:nodes()]),
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config: ~p"
+ "~n Nodes: ~p", [Config4, erlang:nodes()]),
Config4
end.
end_per_suite(Config0) when is_list(Config0) ->
- p("end_per_suite -> entry with"
- "~n Config0: ~p"
- "~n Nodes: ~p", [Config0, erlang:nodes()]),
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config0: ~p"
+ "~n Nodes: ~p", [Config0, erlang:nodes()]),
case snmp_test_mgr_counter_server:stop() of
{ok, Counters} ->
- p("end_per_suite -> sucessfully stopped counter server"
- "~n Counters: ~p", [Counters]);
+ ?IPRINT("end_per_suite -> sucessfully stopped counter server"
+ "~n Counters: ~p", [Counters]);
{error, Reason} ->
- p("end_per_suite -> failed stopping counter server"
- "~n Reason: ~p", [Reason])
+ ?IPRINT("end_per_suite -> failed stopping counter server"
+ "~n Reason: ~p", [Reason])
end,
snmp_test_sys_monitor:stop(),
Config1 = ?LIB:end_per_suite(Config0),
- p("end_per_suite -> end when"
- "~n Nodes: ~p", [erlang:nodes()]),
+ ?IPRINT("end_per_suite -> end when"
+ "~n Nodes: ~p", [erlang:nodes()]),
+
Config1.
@@ -813,18 +814,35 @@ end_per_group(_GroupName, Config) ->
%% ----- Init Per TestCase -----
%%
+%% T is in number of minutes
+wd_start(T, Config) ->
+ Factor = case ?config(snmp_factor, Config) of
+ F when (F > 0) ->
+ F-1;
+ _ ->
+ 0
+ end,
+ Dog = ?WD_START(?MINS(T + Factor)),
+ [{watchdog, Dog} | Config ].
+
+
+wd_stop(Config) ->
+ Dog = ?config(watchdog, Config),
+ ?WD_STOP(Dog),
+ lists:keydelete(Dog, 2, Config).
+
init_per_testcase(Case, Config) when is_list(Config) ->
- p("init_per_testcase -> entry with"
- "~n Config: ~p"
- "~n Nodes: ~p", [Config, erlang:nodes()]),
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p", [Config, erlang:nodes()]),
Result = init_per_testcase1(Case, Config),
snmp_test_global_sys_monitor:reset_events(),
- p("init_per_testcase -> done when"
- "~n Result: ~p"
- "~n Nodes: ~p", [Result, erlang:nodes()]),
+ ?IPRINT("init_per_testcase -> done when"
+ "~n Result: ~p"
+ "~n Nodes: ~p", [Result, erlang:nodes()]),
Result.
init_per_testcase1(otp8395 = Case, Config) when is_list(Config) ->
@@ -841,8 +859,7 @@ init_per_testcase1(otp_7157 = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase1 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?WD_START(?MINS(1)),
- [{watchdog, Dog} | Config ];
+ wd_start(1, Config);
init_per_testcase1(Case, Config)
when ((Case =:= otp_16092_simple_start_and_stop1) orelse
(Case =:= otp_16092_simple_start_and_stop2) orelse
@@ -852,30 +869,26 @@ init_per_testcase1(Case, Config)
?DBG("init_per_testcase1 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?WD_START(?MINS(1)),
- init_per_testcase2(Case, [{watchdog, Dog} | Config]);
+ init_per_testcase2(Case, wd_start(1, Config));
init_per_testcase1(v2_inform_i = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase1 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?WD_START(?MINS(10)),
- [{watchdog, Dog} | Config ];
+ wd_start(10, Config);
init_per_testcase1(v3_inform_i = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase1 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?WD_START(?MINS(10)),
- [{watchdog, Dog} | Config ];
+ wd_start(10, Config);
init_per_testcase1(_Case, Config) when is_list(Config) ->
?DBG("init_per_testcase -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?WD_START(?MINS(6)),
- [{watchdog, Dog}| Config ].
+ wd_start(6, Config).
init_per_testcase2(Case, Config) ->
- ?DBG("end_per_testcase2 -> entry with"
+ ?DBG("init_per_testcase2 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [Case, Config]),
@@ -911,20 +924,48 @@ init_per_testcase2(Case, Config) ->
%% ---- End Per TestCase ----
end_per_testcase(Case, Config) when is_list(Config) ->
- p("end_per_testcase -> entry with"
- "~n Config: ~p"
- "~n Nodes: ~p", [Config, erlang:nodes()]),
- display_log(Config),
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p",
+ [Config, erlang:nodes()]),
+
+ ?IPRINT("system events during test: "
+ "~n ~p", [snmp_test_global_sys_monitor:events()]),
+
+ %% On some hosts, this operation can take a long time.
+ %% So long, that the timetrap expires and the test case
+ %% will be "failed".
+ %% So, wrap it in a process and for a successful test case,
+ %% give it 30 seconds, then kill it. If the test case has
+ %% already failed, we will want to get as much of the logs
+ %% as possible. So, set no timeout (infinity) and let the
+ %% test framework take care of things...
+ DisplayLogTimeout =
+ case ?config(tc_status, Config) of
+ ok ->
+ ?SECS(30);
+ _ ->
+ infinity
+ end,
+ Flag = process_flag(trap_exit, true),
+ Pid = spawn_link(fun() -> display_log(Config), exit(normal) end),
+ receive
+ {'EXIT', Pid, _} ->
+ process_flag(trap_exit, Flag),
+ ok
+ after DisplayLogTimeout ->
+ ?WPRINT("Display Log process fail to complete in time (~w msec): "
+ "kill it", [DisplayLogTimeout]),
+ process_flag(trap_exit, Flag),
+ exit(Pid, kill)
+ end,
- p("system events during test: "
- "~n ~p", [snmp_test_global_sys_monitor:events()]),
-
Result = end_per_testcase1(Case, Config),
- p("end_per_testcase -> done with"
- "~n Result: ~p"
- "~n Nodes: ~p", [Result, erlang:nodes()]),
+ ?IPRINT("end_per_testcase -> done with"
+ "~n Result: ~p"
+ "~n Nodes: ~p", [Result, erlang:nodes()]),
Result.
end_per_testcase1(otp8395, Config) when is_list(Config) ->
@@ -935,9 +976,7 @@ end_per_testcase1(_Case, Config) when is_list(Config) ->
?DBG("end_per_testcase1 -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
- Dog = ?config(watchdog, Config),
- ?WD_STOP(Dog),
- Config.
+ wd_stop(Config).
@@ -975,37 +1014,37 @@ end_per_testcase1(_Case, Config) when is_list(Config) ->
init_all(Conf) ->
?DISPLAY_SUITE_INFO(),
- snmp_agent_test_lib:init_all(Conf).
+ ?ALIB:init_all(Conf).
finish_all(Conf) ->
- snmp_agent_test_lib:finish_all(Conf).
+ ?ALIB:finish_all(Conf).
start_v1_agent(Config) ->
- snmp_agent_test_lib:start_v1_agent(Config).
+ ?ALIB:start_v1_agent(Config).
start_v1_agent(Config, Opts) ->
- snmp_agent_test_lib:start_v1_agent(Config, Opts).
+ ?ALIB:start_v1_agent(Config, Opts).
start_v2_agent(Config) ->
- snmp_agent_test_lib:start_v2_agent(Config).
+ ?ALIB:start_v2_agent(Config).
start_v2_agent(Config, Opts) ->
- snmp_agent_test_lib:start_v2_agent(Config, Opts).
+ ?ALIB:start_v2_agent(Config, Opts).
%% start_v3_agent(Config) ->
-%% snmp_agent_test_lib:start_v3_agent(Config).
+%% ?ALIB:start_v3_agent(Config).
start_v3_agent(Config, Opts) ->
- snmp_agent_test_lib:start_v3_agent(Config, Opts).
+ ?ALIB:start_v3_agent(Config, Opts).
start_bilingual_agent(Config) ->
- snmp_agent_test_lib:start_bilingual_agent(Config).
+ ?ALIB:start_bilingual_agent(Config).
start_multi_threaded_agent(Config) when is_list(Config) ->
- snmp_agent_test_lib:start_mt_agent(Config).
+ ?ALIB:start_mt_agent(Config).
stop_agent(Config) ->
- snmp_agent_test_lib:stop_agent(Config).
+ ?ALIB:stop_agent(Config).
create_tables(SaNode) ->
@@ -1148,28 +1187,28 @@ varm_mib_storage_mnesia_cases() ->
[msm_varm_mib_start].
init_mib_storage_ets(Config) when is_list(Config) ->
- ?LOG("init_mib_storage_ets -> entry", []),
+ ?IPRINT("init_mib_storage_ets -> entry"),
MibStorage = {mib_storage, [{module, snmpa_mib_storage_ets}]},
init_ms(Config, [MibStorage]).
init_mib_storage_dets(Config) when is_list(Config) ->
- ?LOG("init_mib_storage_dets -> entry", []),
+ ?IPRINT("init_mib_storage_dets -> entry"),
?line AgentDbDir = ?GCONF(agent_db_dir, Config),
MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets},
{options, [{dir, AgentDbDir}]}]},
init_ms(Config, [MibStorage]).
init_mib_storage_mnesia(Config) when is_list(Config) ->
- ?LOG("init_mib_storage_mnesia -> entry", []),
+ ?IPRINT("init_mib_storage_mnesia -> entry"),
?line AgentNode = ?GCONF(snmp_master, Config),
MibStorage = {mib_storage, [{module, snmpa_mib_storage_mnesia},
{options, [{nodes, [AgentNode]}]}]},
init_ms(Config, [MibStorage]).
init_ms(Config, Opts) when is_list(Config) ->
- ?LOG("init_ms -> entry with"
- "~n Config: ~p"
- "~n Opts: ~p", [Config, Opts]),
+ ?IPRINT("init_ms -> entry with"
+ "~n Config: ~p"
+ "~n Opts: ~p", [Config, Opts]),
?line SaNode = ?GCONF(snmp_sa, Config),
?line create_tables(SaNode),
?line AgentConfDir = ?GCONF(agent_conf_dir, Config),
@@ -1206,11 +1245,16 @@ init_size_check_ms(Config, Opts) when is_list(Config) ->
ok ->
case ?CRYPTO_SUPPORT() of
{no, Reason} ->
+ ?WPRINT("crypto support not sufficient:"
+ "~n ~p", [Reason]),
?SKIP({unsupported_encryption, Reason});
yes ->
+ ?IPRINT("crypto started"),
ok
end;
{error, Reason} ->
+ ?IPRINT("crypto not started:"
+ "~n ~p", [Reason]),
?SKIP({failed_starting_crypto, Reason})
end,
create_tables(SaNode),
@@ -1222,7 +1266,7 @@ init_size_check_ms(Config, Opts) when is_list(Config) ->
[{vsn, v3} | start_v3_agent(Config, Opts)].
init_varm_mib_storage_dets(Config) when is_list(Config) ->
- ?LOG("init_varm_mib_storage_dets -> entry", []),
+ ?IPRINT("init_varm_mib_storage_dets -> entry"),
?line SaNode = ?GCONF(snmp_sa, Config),
?line create_tables(SaNode),
?line AgentDbDir = ?GCONF(agent_db_dir, Config),
@@ -1243,7 +1287,7 @@ init_varm_mib_storage_dets(Config) when is_list(Config) ->
[{vsn, v1}, {agent_opts, Opts} | Config].
init_varm_mib_storage_mnesia(Config) when is_list(Config) ->
- ?LOG("init_varm_mib_storage_mnesia -> entry", []),
+ ?IPRINT("init_varm_mib_storage_mnesia -> entry"),
?line SaNode = ?GCONF(snmp_sa, Config),
?line create_tables(SaNode),
?line AgentConfDir = ?GCONF(agent_conf_dir, Config),
@@ -1264,7 +1308,7 @@ init_varm_mib_storage_mnesia(Config) when is_list(Config) ->
[{vsn, v1}, {agent_opts, Opts} | Config].
finish_mib_storage_ets(Config) when is_list(Config) ->
- ?LOG("finish_mib_storage_ets -> entry", []),
+ ?IPRINT("finish_mib_storage_ets -> entry"),
delete_tables(),
C1 = stop_agent(Config),
delete_files(C1),
@@ -1272,7 +1316,7 @@ finish_mib_storage_ets(Config) when is_list(Config) ->
lists:keydelete(agent_opts, 1, C2).
finish_mib_storage_dets(Config) when is_list(Config) ->
- ?LOG("finish_mib_storage_dets -> entry", []),
+ ?IPRINT("finish_mib_storage_dets -> entry"),
delete_tables(),
C1 = stop_agent(Config),
delete_files(C1),
@@ -1280,7 +1324,7 @@ finish_mib_storage_dets(Config) when is_list(Config) ->
lists:keydelete(agent_opts, 1, C2).
finish_mib_storage_mnesia(Config) when is_list(Config) ->
- ?LOG("finish_mib_storage_mnesia -> entry", []),
+ ?IPRINT("finish_mib_storage_mnesia -> entry"),
delete_tables(),
delete_mib_storage_mnesia_tables(),
C1 = stop_agent(Config),
@@ -1289,7 +1333,7 @@ finish_mib_storage_mnesia(Config) when is_list(Config) ->
lists:keydelete(agent_opts, 1, C2).
finish_varm_mib_storage_dets(Config) when is_list(Config) ->
- ?LOG("finish_varm_mib_storage_dets -> entry", []),
+ ?IPRINT("finish_varm_mib_storage_dets -> entry"),
delete_tables(),
%% C1 = stop_agent(Config), % In case something went wrong...
delete_files(Config),
@@ -1297,7 +1341,7 @@ finish_varm_mib_storage_dets(Config) when is_list(Config) ->
lists:keydelete(agent_opts, 1, C2).
finish_varm_mib_storage_mnesia(Config) when is_list(Config) ->
- ?LOG("finish_varm_mib_storage_mnesia -> entry", []),
+ ?IPRINT("finish_varm_mib_storage_mnesia -> entry"),
delete_tables(),
delete_mib_storage_mnesia_tables(),
%% C1 = stop_agent(Config), % In case something went wrong...
@@ -1408,7 +1452,7 @@ ms_size_check(suite) -> [];
ms_size_check(Config) when is_list(Config) ->
?P(ms_size_check),
init_case(Config),
- ?LOG("mib server size check...", []),
+ ?IPRINT("mib server size check..."),
?line load_master("Test2"),
?line load_master("TestTrap"),
@@ -1449,7 +1493,7 @@ ms_size_check(Config) when is_list(Config) ->
varm_mib_start(suite) -> [];
varm_mib_start(Config) when is_list(Config) ->
?P(varm_mib_start),
- ?LOG("varm_mib_start -> entry", []),
+ ?IPRINT("varm_mib_start -> entry"),
init_case(Config),
%% Start the agent
@@ -1694,24 +1738,64 @@ app_dir(App) ->
end.
create_local_db_dir(Config) when is_list(Config) ->
- ?P(create_local_db_dir),
- DataDir = snmp_test_lib:lookup(data_dir, Config),
- UName = erlang:unique_integer([positive]),
- T = {UName, UName, UName},
- [As,Bs,Cs] = [integer_to_list(I) || I <- tuple_to_list(T)],
- DbDir = filename:join([DataDir, As, Bs, Cs]),
- ok = del_dir(DbDir, 3),
- Name = list_to_atom(atom_to_list(create_local_db_dir)
- ++"-"++As++"-"++Bs++"-"++Cs),
- Pa = filename:dirname(code:which(?MODULE)),
- {ok,Node} = ?t:start_node(Name, slave, [{args, "-pa " ++ Pa}]),
+ Pre = fun() ->
+ DataDir = snmp_test_lib:lookup(data_dir, Config),
+ T = {erlang:unique_integer([positive]),
+ erlang:unique_integer([positive]),
+ erlang:unique_integer([positive])},
+ [As,Bs,Cs] = [integer_to_list(I) || I <- tuple_to_list(T)],
+ DbDir = filename:join([DataDir, As, Bs, Cs]),
+ Name = list_to_atom(atom_to_list(create_local_db_dir)
+ ++"_"++As++"_"++Bs++"_"++Cs),
+ ?IPRINT("try ensuring db-dir does not exist"),
+ try del_dir(DbDir, 3) of
+ ok ->
+ ok
+ catch
+ C:E:S ->
+ ?WPRINT("Failed pre db-dir delete: "
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [C, E, S]),
+ throw({skip, "Failed pre db-dir cleanup"})
+ end,
+ ?IPRINT("try start node ~p", [Name]),
+ case ?ALIB:start_node(Name) of
+ {ok, Node} ->
+ {DbDir, Node};
+ {error, Reason} ->
+ ?WPRINT("Failed starting node ~p:"
+ "~n ~p", [Reason]),
+ throw({skip, ?F("Failed starting node ~p", [Name])})
+ end
+ end,
+ Case = fun do_create_local_db_dir/1,
+ Post = fun({DbDir, Node}) ->
+ ?IPRINT("try stop node ~p", [Node]),
+ ?ALIB:stop_node(Node),
+ ?IPRINT("try delete db-dir"),
+ try del_dir(DbDir, 3)
+ catch
+ C:E:S ->
+ ?WPRINT("Failed post db-dir delete: "
+ "~n DbDir ~s"
+ "~n Class: ~p"
+ "~n Error: ~p"
+ "~n Stack: ~p", [DbDir, C, E, S]),
+ ok
+ end
+ end,
+ ?TC_TRY(create_local_db_dir, Pre, Case, Post).
+do_create_local_db_dir({DbDir, Node}) ->
+ ?P(create_local_db_dir),
%% first start with a nonexisting DbDir
Fun1 = fun() ->
false = filelib:is_dir(DbDir),
process_flag(trap_exit,true),
{error, {error, {failed_open_dets, {file_error, _, _}}}} =
- snmpa_local_db:start_link(normal, DbDir, [{verbosity,trace}]),
+ snmpa_local_db:start_link(normal, DbDir,
+ [{verbosity, trace}]),
false = filelib:is_dir(DbDir),
{ok, not_found}
end,
@@ -1729,21 +1813,21 @@ create_local_db_dir(Config) when is_list(Config) ->
{ok, found}
end,
{ok, found} = nodecall(Node, Fun2),
- %% cleanup
- ?t:stop_node(Node),
- ok = del_dir(DbDir, 3),
ok.
nodecall(Node, Fun) ->
Parent = self(),
- Ref = make_ref(),
- spawn_link(Node,
- fun() ->
- Res = Fun(),
- unlink(Parent),
- Parent ! {Ref, Res}
- end),
+ Ref = make_ref(),
+ Pid = spawn_link(Node,
+ fun() ->
+ Res = Fun(),
+ unlink(Parent),
+ Parent ! {Ref, Res}
+ end),
receive
+ %% Just so we are not left hanging
+ {'EXIT', Pid, Reason} ->
+ Reason;
{Ref, Res} ->
Res
end.
@@ -1992,11 +2076,16 @@ init_v3(Config) when is_list(Config) ->
ok ->
case ?CRYPTO_SUPPORT() of
{no, Reason} ->
+ ?WPRINT("crypto support not sufficient:"
+ "~n ~p", [Reason]),
?SKIP({unsupported_encryption, Reason});
yes ->
+ ?IPRINT("crypto started"),
ok
end;
{error, Reason} ->
+ ?IPRINT("crypto not started:"
+ "~n ~p", [Reason]),
?SKIP({failed_starting_crypto, Reason})
end,
SaNode = ?config(snmp_sa, Config),
@@ -2046,7 +2135,7 @@ finish_mt(Config) when is_list(Config) ->
%% This one *must* be run first in each case.
init_case(Config) ->
- snmp_agent_test_lib:init_case(Config).
+ ?ALIB:init_case(Config).
load_master(Mib) ->
@@ -2079,10 +2168,10 @@ unload_mibs(Mibs) ->
ok = snmpa:unload_mibs(snmp_master_agent, Mibs).
start_subagent(SaNode, RegTree, Mib) ->
- snmp_agent_test_lib:start_subagent(SaNode, RegTree, Mib).
+ ?ALIB:start_subagent(SaNode, RegTree, Mib).
stop_subagent(SA) ->
- snmp_agent_test_lib:stop_subagent(SA).
+ ?ALIB:stop_subagent(SA).
%%-----------------------------------------------------------------
@@ -2116,7 +2205,7 @@ simple(Config) when is_list(Config) ->
try_test(simple_standard_test),
- p("done"),
+ ?IPRINT("done"),
ok.
simple_2(X) -> ?P(simple_2), simple(X).
@@ -2143,7 +2232,7 @@ big(Config) when is_list(Config) ->
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("Starting subagent..."),
+ ?NPRINT("Starting subagent..."),
?line pong = net_adm:ping(SaNode),
?line {ok, SA} = start_subagent(SaNode, ?klas1, "Klas1"),
@@ -2172,7 +2261,7 @@ big2(Config) when is_list(Config) ->
%% v2 equivalent of the mibs.
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("Starting subagent..."),
+ ?NPRINT("Starting subagent..."),
?line pong = net_adm:ping(SaNode),
?line {ok, SA} = start_subagent(SaNode, ?klas1, "Klas1-v2"),
@@ -2278,7 +2367,7 @@ opaque_3(X) -> ?P(opaque_2), opaque(X).
change_target_addr_config(suite) -> [];
change_target_addr_config(Config) when is_list(Config) ->
?P(change_target_addr_config),
- ?LOG("change_target_addr_config -> entry",[]),
+ ?IPRINT("change_target_addr_config -> entry"),
init_case(Config),
put(sname,snmp_suite),
@@ -2286,43 +2375,43 @@ change_target_addr_config(Config) when is_list(Config) ->
MA = whereis(snmp_master_agent),
- ?LOG("change_target_addr_config -> load TestTrap",[]),
+ ?IPRINT("change_target_addr_config -> load TestTrap"),
?line load_master("TestTrap"),
- ?LOG("change_target_addr_config -> set trace verbosity for local_db",[]),
+ ?IPRINT("change_target_addr_config -> set trace verbosity for local_db"),
?line snmpa:verbosity(local_db,trace),
%% First send some traps that will arive att the original manager
- ?LOG("change_target_addr_config -> send trap",[]),
+ ?IPRINT("change_target_addr_config -> send trap"),
try_test(ma_trap1, [MA]),
- ?LOG("change_target_addr_config -> set silence verbosity for local_db",[]),
+ ?IPRINT("change_target_addr_config -> set silence verbosity for local_db"),
?line snmpa:verbosity(local_db, silence),
%% Start new dummy listener
- ?LOG("change_target_addr_config -> start dummy manager",[]),
+ ?IPRINT("change_target_addr_config -> start dummy manager"),
?line {ok,Pid,NewPort} = dummy_manager_start(MA),
%% Reconfigure
- ?LOG("change_target_addr_config -> reconfigure",[]),
+ ?IPRINT("change_target_addr_config -> reconfigure"),
AgentConfDir = ?config(agent_conf_dir, Config),
?line rewrite_target_addr_conf(AgentConfDir, NewPort),
?line snmp_target_mib:reconfigure(AgentConfDir),
%% Send the trap again
- ?LOG("change_target_addr_config -> send trap again",[]),
+ ?IPRINT("change_target_addr_config -> send trap again"),
catch dummy_manager_send_trap2(Pid),
- ?LOG("change_target_addr_config -> await trap ack",[]),
+ ?IPRINT("change_target_addr_config -> await trap ack"),
catch dummy_manager_await_trap2_ack(),
- ?LOG("change_target_addr_config -> stop dummy manager",[]),
+ ?IPRINT("change_target_addr_config -> stop dummy manager"),
?line ok = dummy_manager_stop(Pid),
- ?LOG("change_target_addr_config -> reset target address config",[]),
+ ?IPRINT("change_target_addr_config -> reset target address config"),
?line reset_target_addr_conf(AgentConfDir),
- ?LOG("change_target_addr_config -> unload TestTrap",[]),
+ ?IPRINT("change_target_addr_config -> unload TestTrap"),
?line unload_master("TestTrap").
@@ -2338,11 +2427,15 @@ await_dummy_manager_started(Pid) ->
?DBG("dummy_manager_start -> acknowledge received with"
"~n Port: ~p",[Port]),
{ok,Pid,Port};
+
{'EXIT', Pid, Reason} ->
+ ?EPRINT("dummy manager terminated: "
+ "~n ~p", [Reason]),
{error, Pid, Reason};
+
_O ->
- ?LOG("dummy_manager_start -> received unknown message:"
- "~n ~p",[_O]),
+ ?NPRINT("dummy_manager_start -> received unknown message:"
+ "~n ~p", [_O]),
await_dummy_manager_started(Pid)
end.
@@ -2354,7 +2447,7 @@ dummy_manager_stop(Pid) ->
?DBG("dummy_manager_stop -> acknowledge received",[]),
ok
after 10000 ->
- ?ERR("dummy_manager_stop -> timeout",[]),
+ ?EPRINT("dummy_manager_stop -> timeout"),
timeout
end.
@@ -2366,7 +2459,7 @@ dummy_manager_await_trap2_ack() ->
?DBG("dummy_manager_await_trap2 -> entry",[]),
receive
{received_trap, _Trap} ->
- ?LOG("dummy_manager_await_trap2 -> received trap: ~p", [_Trap]),
+ ?IPRINT("dummy_manager_await_trap2 -> received trap: ~p", [_Trap]),
%% Note:
%% Without this sleep the v2_inform_i testcase failes! There
%% is no relation between these two test cases as far as I
@@ -2374,10 +2467,10 @@ dummy_manager_await_trap2_ack() ->
?SLEEP(60000),
ok;
_O ->
- ?ERR("dummy_manager_await_trap2 -> unexpected message: ~p",[_O]),
+ ?WPRINT("dummy_manager_await_trap2 -> unexpected message: ~p",[_O]),
ok
after 10000 ->
- ?ERR("dummy_manager_await_trap2 -> timeout",[]),
+ ?EPRINT("dummy_manager_await_trap2 -> timeout",[]),
timeout
end.
@@ -2393,18 +2486,18 @@ dummy_manager_init(Parent,MA) ->
dummy_manager_loop(Parent,S,MA).
dummy_manager_loop(P,S,MA) ->
- ?LOG("dummy_manager_loop -> ready for receive",[]),
+ ?IPRINT("dummy_manager_loop -> ready for receive"),
receive
{send_trap,Trap} ->
- ?LOG("dummy_manager_loop -> received trap send request"
- "~n Trap: ~p",[Trap]),
+ ?IPRINT("dummy_manager_loop -> received trap send request"
+ "~n Trap: ~p", [Trap]),
snmpa:send_trap(MA, Trap, "standard trap"),
dummy_manager_loop(P,S,MA);
{udp, _UdpId, _Ip, _UdpPort, Bytes} ->
- ?LOG("dummy_manager_loop -> received upd message"
- "~n from: ~p:~p"
- "~n size: ~p",
- [_Ip, _UdpPort, dummy_manager_message_sz(Bytes)]),
+ ?IPRINT("dummy_manager_loop -> received upd message"
+ "~n from: ~p:~p"
+ "~n size: ~p",
+ [_Ip, _UdpPort, dummy_manager_message_sz(Bytes)]),
R = dummy_manager_handle_message(Bytes),
?DBG("dummy_manager_loop -> R: ~p", [R]),
P ! R,
@@ -2415,30 +2508,31 @@ dummy_manager_loop(P,S,MA) ->
gen_udp:close(S),
exit(normal);
_O ->
- ?LOG("dummy_manager_loop -> received unknown message:"
- "~n ~p", [_O]),
+ ?WPRINT("dummy_manager_loop -> received unknown message:"
+ "~n ~p", [_O]),
dummy_manager_loop(P, S, MA)
end.
--ifdef(snmp_log).
+%% -ifdef(snmp_log).
dummy_manager_message_sz(B) when is_binary(B) ->
size(B);
dummy_manager_message_sz(L) when is_list(L) ->
length(L);
dummy_manager_message_sz(_) ->
undefined.
--endif.
+%% -endif.
dummy_manager_handle_message(Bytes) ->
case (catch snmp_pdus:dec_message(Bytes)) of
{'EXIT',Reason} ->
- ?ERR("dummy_manager_handle_message -> "
- "failed decoding message only:~n ~p",[Reason]),
- {error,Reason};
+ ?EPRINT("dummy_manager_handle_message -> "
+ "failed decoding message only:"
+ "~n ~p", [Reason]),
+ {error, Reason};
M ->
?DBG("dummy_manager_handle_message -> decoded message:"
- "~n ~p",[M]),
- {received_trap,M}
+ "~n ~p", [M]),
+ {received_trap, M}
end.
@@ -2465,19 +2559,20 @@ subagent(Config) when is_list(Config) ->
?line {ok, SA} = start_subagent(SaNode, ?klas1, "Klas1"),
try_test(load_test_sa),
- ?P1("Testing unregister subagent..."),
+ ?NPRINT("Testing unregister subagent..."),
MA = whereis(snmp_master_agent),
rpc:call(SaNode, snmp, unregister_subagent, [MA, SA]),
try_test(unreg_test),
- ?P1("Loading previous subagent mib in master and testing..."),
+ ?NPRINT("Loading previous subagent mib in master and testing..."),
?line ok = snmpa:load_mib(MA, join(MibDir, "Klas1")),
try_test(load_test),
- ?P1("Unloading previous subagent mib in master and testing..."),
+ ?NPRINT("Unloading previous subagent mib in master and testing..."),
?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas1")),
try_test(unreg_test),
- ?P1("Testing register subagent..."),
+
+ ?NPRINT("Testing register subagent..."),
rpc:call(SaNode, snmp, register_subagent,
[MA, ?klas1, SA]),
try_test(load_test_sa),
@@ -2503,14 +2598,14 @@ mnesia(Config) when is_list(Config) ->
?P(mnesia),
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("Starting subagent with mnesia impl..."),
+ ?NPRINT("Starting subagent with mnesia impl..."),
{ok, SA} = start_subagent(SaNode, ?klas2, "Klas2"),
?line load_master("OLD-SNMPEA-MIB"),
?line init_old(),
try_test(big_test_2),
- ?P1("Testing unregister subagent..."),
+ ?NPRINT("Testing unregister subagent..."),
MA = whereis(snmp_master_agent),
rpc:call(SaNode, snmp, unregister_subagent, [MA, SA]),
try_test(unreg_test),
@@ -2577,7 +2672,7 @@ mul_get(Config) when is_list(Config) ->
?P(mul_get),
init_case(Config),
- ?P1("Testing multiple get..."),
+ ?NPRINT("Testing multiple get..."),
try_test(do_mul_get).
mul_get_2(X) -> ?P(mul_get_2), mul_get(X).
@@ -2590,7 +2685,7 @@ mul_get_err(Config) when is_list(Config) ->
?P(mul_get_err),
init_case(Config),
- ?P1("Testing multiple get with error..."),
+ ?NPRINT("Testing multiple get with error..."),
try_test(do_mul_get_err).
mul_get_err_2(X) -> ?P(mul_get_err_2), mul_get_err(X).
@@ -2603,7 +2698,7 @@ mul_next(Config) when is_list(Config) ->
?P(mul_next),
init_case(Config),
- ?P1("Testing multiple next..."),
+ ?NPRINT("Testing multiple next..."),
try_test(do_mul_next).
mul_next_2(X) -> ?P(mul_next_2), mul_next(X).
@@ -2616,7 +2711,7 @@ mul_next_err(Config) when is_list(Config) ->
?P(mul_next_err),
init_case(Config),
- ?P1("Testing multiple next..."),
+ ?NPRINT("Testing multiple next..."),
try_test(do_mul_next_err).
mul_next_err_2(X) -> ?P(mul_next_err_2), mul_next_err(X).
@@ -2629,7 +2724,7 @@ mul_set(Config) when is_list(Config) ->
?P(mul_set),
init_case(Config),
- ?P1("Testing multiple set..."),
+ ?NPRINT("Testing multiple set..."),
try_test(do_mul_set).
mul_set_2(X) -> ?P(mul_set_2), mul_set(X).
@@ -2642,7 +2737,7 @@ mul_set_err(Config) when is_list(Config) ->
?P(mul_set_err),
init_case(Config),
- ?P1("Testing multiple set with error..."),
+ ?NPRINT("Testing multiple set with error..."),
try_test(do_mul_set_err).
mul_set_err_2(X) -> ?P(mul_set_err_2), mul_set_err(X).
@@ -2656,30 +2751,30 @@ sa_register(Config) when is_list(Config) ->
{SaNode, _MgrNode, MibDir} = init_case(Config),
?DBG("sa_register -> start subagent", []),
- ?P1("start subagent..."),
+ ?NPRINT("start subagent..."),
?line {ok, SA} = start_subagent(SaNode, ?klas1, "Klas1"),
?DBG("sa_register -> unregister subagent", []),
- ?P1("Testing unregister subagent (2)..."),
+ ?NPRINT("Testing unregister subagent (2)..."),
MA = whereis(snmp_master_agent),
rpc:call(SaNode, snmp, unregister_subagent, [MA, ?klas1]),
try_test(unreg_test),
- ?P1("Unloading Klas1..."),
+ ?NPRINT("Unloading Klas1..."),
?DBG("sa_register -> unload mibs", []),
snmpa:unload_mib(SA, join(MibDir, "Klas1")),
- ?P1("Loading SA-MIB..."),
+ ?NPRINT("Loading SA-MIB..."),
?DBG("sa_register -> unload mibs", []),
snmpa:load_mib(SA, join(MibDir, "SA-MIB")),
- ?P1("register subagent..."),
+ ?NPRINT("register subagent..."),
?DBG("sa_register -> register subagent", []),
rpc:call(SaNode, snmp, register_subagent, [MA, ?sa, SA]),
try_test(sa_mib),
- ?P1("stop subagent..."),
+ ?NPRINT("stop subagent..."),
?DBG("sa_register -> stop subagent", []),
?line stop_subagent(SA).
@@ -2696,32 +2791,32 @@ v1_trap(Config) when is_list(Config) ->
trap1(Config) ->
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("start subagent..."),
+ ?NPRINT("start subagent..."),
?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"),
- ?P1("Testing trap sending from master agent..."),
+ ?NPRINT("Testing trap sending from master agent..."),
MA = whereis(snmp_master_agent),
- ?P1("load TestTrap & TestTrapv2..."),
+ ?NPRINT("load TestTrap & TestTrapv2..."),
?line load_master("TestTrap"),
?line load_master("TestTrapv2"),
- ?P1("Testing trap sending from master-agent..."),
+ ?NPRINT("Testing trap sending from master-agent..."),
try_test(ma_trap1, [MA]),
try_test(ma_trap2, [MA]),
try_test(ma_v2_2_v1_trap, [MA]),
try_test(ma_v2_2_v1_trap2, [MA]),
- ?P1("Testing trap sending from subagent..."),
+ ?NPRINT("Testing trap sending from subagent..."),
try_test(sa_trap1, [SA]),
try_test(sa_trap2, [SA]),
try_test(sa_trap3, [SA]),
- ?P1("unload TestTrap & TestTrapv2..."),
+ ?NPRINT("unload TestTrap & TestTrapv2..."),
?line unload_master("TestTrap"),
?line unload_master("TestTrapv2"),
- ?P1("stop subagent..."),
+ ?NPRINT("stop subagent..."),
?line stop_subagent(SA).
v2_trap(suite) -> [];
@@ -2732,17 +2827,17 @@ v2_trap(Config) when is_list(Config) ->
trap2(Config) ->
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("start subagent..."),
+ ?NPRINT("start subagent..."),
?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"),
- ?P1("Testing trap sending from master agent..."),
+ ?NPRINT("Testing trap sending from master agent..."),
MA = whereis(snmp_master_agent),
- ?P1("load TestTrap & TestTrapv2..."),
+ ?NPRINT("load TestTrap & TestTrapv2..."),
?line load_master("TestTrap"),
?line load_master("TestTrapv2"),
- ?P1("Testing trap sending from master-agent..."),
+ ?NPRINT("Testing trap sending from master-agent..."),
try_test(ma_v2_trap1, [MA]),
try_test(ma_v2_trap2, [MA]),
try_test(ma_v1_2_v2_trap, [MA]),
@@ -2750,16 +2845,16 @@ trap2(Config) ->
try_test(sa_mib),
- ?P1("Testing trap sending from subagent..."),
+ ?NPRINT("Testing trap sending from subagent..."),
try_test(sa_v1_2_v2_trap1, [SA]),
try_test(sa_v1_2_v2_trap2, [SA]),
try_test(sa_v1_2_v2_trap3, [SA]),
- ?P1("unload TestTrap & TestTrapv2..."),
+ ?NPRINT("unload TestTrap & TestTrapv2..."),
?line unload_master("TestTrap"),
?line unload_master("TestTrapv2"),
- ?P1("stop subagent..."),
+ ?NPRINT("stop subagent..."),
?line stop_subagent(SA).
v3_trap(suite) -> [];
@@ -2811,18 +2906,18 @@ inform_i(Config) ->
MA = whereis(snmp_master_agent),
- ?P1("load TestTrap & TestTrapv2..."),
+ ?NPRINT("load TestTrap & TestTrapv2..."),
?line load_master("TestTrap"),
?line load_master("TestTrapv2"),
- ?P1("Testing inform sending from master agent... "
+ ?NPRINT("Testing inform sending from master agent... "
"~nNOTE! This test takes a few minutes (10) to complete."),
try_test(ma_v2_inform1, [MA]),
try_test(ma_v2_inform2, [MA]),
try_test(ma_v2_inform3, [MA]),
- ?P1("unload TestTrap & TestTrapv2..."),
+ ?NPRINT("unload TestTrap & TestTrapv2..."),
?line unload_master("TestTrap"),
?line unload_master("TestTrapv2"),
ok.
@@ -2843,26 +2938,26 @@ sa_error(Config) when is_list(Config) ->
?P(sa_error),
{SaNode, _MgrNode, _MibDir} = init_case(Config),
- ?P1("load OLD-SNMPEA-MIB..."),
+ ?NPRINT("load OLD-SNMPEA-MIB..."),
?line load_master("OLD-SNMPEA-MIB"),
?line init_old(),
- ?P1("start subagent..."),
+ ?NPRINT("start subagent..."),
?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"),
- ?P1("Testing sa bad value (is_set_ok)..."),
+ ?NPRINT("Testing sa bad value (is_set_ok)..."),
try_test(sa_errs_bad_value),
- ?P1("Testing sa gen err (set)..."),
+ ?NPRINT("Testing sa gen err (set)..."),
try_test(sa_errs_gen_err),
- ?P1("Testing too big..."),
+ ?NPRINT("Testing too big..."),
try_test(sa_too_big),
- ?P1("unload OLD-SNMPEA-MIB..."),
+ ?NPRINT("unload OLD-SNMPEA-MIB..."),
?line unload_master("OLD-SNMPEA-MIB"),
- ?P1("stop subagent..."),
+ ?NPRINT("stop subagent..."),
stop_subagent(SA).
sa_error_2(X) ->
@@ -2886,35 +2981,35 @@ next_across_sa(Config) when is_list(Config) ->
{SaNode, _MgrNode, MibDir} = init_case(Config),
MA = whereis(snmp_master_agent),
- ?P1("start subagent (1)..."),
+ ?NPRINT("start subagent (1)..."),
?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"),
- ?P1("Loading another subagent mib (Klas1)..."),
+ ?NPRINT("Loading another subagent mib (Klas1)..."),
?line ok = snmpa:load_mib(SA, MibDir ++ "Klas1"),
- ?P1("register subagent..."),
+ ?NPRINT("register subagent..."),
rpc:call(SaNode, snmp, register_subagent, [MA, ?klas1, SA]),
- ?P1("Load test subagent..."),
+ ?NPRINT("Load test subagent..."),
try_test(load_test_sa),
- ?P1("Testing next across subagent (endOfMibView from SA)..."),
+ ?NPRINT("Testing next across subagent (endOfMibView from SA)..."),
try_test(next_across_sa_test),
- ?P1("Unloading mib (Klas1)"),
+ ?NPRINT("Unloading mib (Klas1)"),
snmpa:unload_mib(SA, join(MibDir, "Klas1")),
rpc:call(SaNode, snmp, unregister_subagent, [MA, ?klas1]),
try_test(unreg_test),
- ?P1("Starting another subagent (2) "),
+ ?NPRINT("Starting another subagent (2) "),
?line {ok, SA2} = start_subagent(SaNode, ?klas1, "Klas1"),
- ?P1("Testing next across subagent (wrong prefix from SA)..."),
+ ?NPRINT("Testing next across subagent (wrong prefix from SA)..."),
try_test(next_across_sa_test),
- ?P1("stop subagent (1)..."),
+ ?NPRINT("stop subagent (1)..."),
stop_subagent(SA),
- ?P1("stop subagent (2)..."),
+ ?NPRINT("stop subagent (2)..."),
stop_subagent(SA2).
next_across_sa_2(X) ->
@@ -2939,27 +3034,27 @@ undo(Config) when is_list(Config) ->
MA = whereis(snmp_master_agent),
- ?P1("start subagent (1)..."),
+ ?NPRINT("start subagent (1)..."),
?line {ok, SA} = start_subagent(SaNode, ?sa, "SA-MIB"),
- ?P1("Load Klas3 & Klas4..."),
+ ?NPRINT("Load Klas3 & Klas4..."),
?line ok = snmpa:load_mib(MA, join(MibDir, "Klas3")),
?line ok = snmpa:load_mib(MA, join(MibDir, "Klas4")),
- ?P1("Testing undo phase at master agent..."),
+ ?NPRINT("Testing undo phase at master agent..."),
try_test(undo_test),
try_test(api_test2),
- ?P1("Unload Klas3..."),
+ ?NPRINT("Unload Klas3..."),
?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas3")),
- ?P1("Testing bad return values from instrum. funcs..."),
+ ?NPRINT("Testing bad return values from instrum. funcs..."),
try_test(bad_return),
- ?P1("Unload Klas4..."),
+ ?NPRINT("Unload Klas4..."),
?line ok = snmpa:unload_mib(MA, join(MibDir, "Klas4")),
- ?P1("Testing undo phase at subagent..."),
+ ?NPRINT("Testing undo phase at subagent..."),
?line ok = snmpa:load_mib(SA, join(MibDir, "Klas3")),
?line ok = snmpa:load_mib(SA, join(MibDir, "Klas4")),
?line ok = snmpa:register_subagent(MA, ?klas3, SA),
@@ -2967,11 +3062,11 @@ undo(Config) when is_list(Config) ->
try_test(undo_test),
try_test(api_test3),
- ?P1("Testing undo phase across master/subagents..."),
+ ?NPRINT("Testing undo phase across master/subagents..."),
try_test(undo_test),
try_test(api_test3),
- ?P1("stop subagent..."),
+ ?NPRINT("stop subagent..."),
stop_subagent(SA).
undo_2(X) ->
@@ -2995,12 +3090,12 @@ v1_processing(Config) when is_list(Config) ->
?DBG("v1_processing -> entry", []),
init_case(Config),
- ?P1("Load Test2..."),
+ ?NPRINT("Load Test2..."),
?line load_master("Test2"),
try_test(v1_proc),
- ?P1("Unload Test2..."),
+ ?NPRINT("Unload Test2..."),
?line unload_master("Test2").
%% Req. Test2
@@ -3009,12 +3104,12 @@ v2_processing(Config) when is_list(Config) ->
?P(v2_processing),
init_case(Config),
- ?P1("Load Test2..."),
+ ?NPRINT("Load Test2..."),
?line load_master("Test2"),
try_test(v2_proc),
- ?P1("Unload Test2..."),
+ ?NPRINT("Unload Test2..."),
?line unload_master("Test2").
%% Req. Test2
@@ -3023,12 +3118,12 @@ v3_processing(Config) when is_list(Config) ->
?P(v3_processing),
init_case(Config),
- ?P1("Load Test2..."),
+ ?NPRINT("Load Test2..."),
?line load_master("Test2"),
try_test(v2_proc), % same as v2!
- ?P1("Unload Test2..."),
+ ?NPRINT("Unload Test2..."),
?line unload_master("Test2").
@@ -3101,7 +3196,7 @@ v3_md5_auth(Config) when is_list(Config) ->
?P(v3_md5_auth),
init_case(Config),
- ?P1("Testing MD5 authentication...takes a few seconds..."),
+ ?NPRINT("Testing MD5 authentication...takes a few seconds..."),
AgentConfDir = ?config(agent_conf_dir, Config),
?line rewrite_target_params_conf(AgentConfDir, "authMD5", authNoPriv),
@@ -3128,7 +3223,7 @@ v3_sha_auth(Config) when is_list(Config) ->
?P(v3_sha_auth),
init_case(Config),
- ?P1("Testing SHA authentication...takes a few seconds..."),
+ ?NPRINT("Testing SHA authentication...takes a few seconds..."),
AgentConfDir = ?config(agent_conf_dir, Config),
?line rewrite_target_params_conf(AgentConfDir, "authSHA", authNoPriv),
@@ -3155,7 +3250,7 @@ v3_des_priv(Config) when is_list(Config) ->
?P(v3_des_priv),
init_case(Config),
- ?P1("Testing DES encryption...takes a few seconds..."),
+ ?NPRINT("Testing DES encryption...takes a few seconds..."),
AgentConfDir = ?config(agent_conf_dir, Config),
?line rewrite_target_params_conf(AgentConfDir, "privDES", authPriv),
@@ -3772,10 +3867,10 @@ big_test() ->
%% Req. system group, Klas2, OLD-SNMPEA-MIB
big_test_2() ->
- ?P1("Testing simple next/get/set @ master agent (2)..."),
+ ?NPRINT("Testing simple next/get/set @ master agent (2)..."),
simple_standard_test(),
- ?P1("Testing simple next/get/set @ subagent (2)..."),
+ ?NPRINT("Testing simple next/get/set @ subagent (2)..."),
gn([[klas2]]),
?line ?expect1([{[fname2,0], ""}]),
g([[fname2,0]]),
@@ -3787,7 +3882,7 @@ big_test_2() ->
otp_1298_test(),
- ?P1("Testing next from last object in master to subagent (2)..."),
+ ?NPRINT("Testing next from last object in master to subagent (2)..."),
gn([[?v1_2(sysServices, sysORLastChange),0]]),
?line ?expect1([{[fname2,0], "test set"}]),
gn([[1,1], [?v1_2(sysServices, sysORLastChange),0]]),
@@ -3796,7 +3891,7 @@ big_test_2() ->
table_test(),
- ?P1("Adding one row in subagent table (2)"),
+ ?NPRINT("Adding one row in subagent table (2)"),
_FTab = [friendsEntry2],
s([{[friendsEntry2, [2, 3]], s, "kompis3"},
{[friendsEntry2, [3, 3]], i, ?createAndGo}]),
@@ -3809,7 +3904,7 @@ big_test_2() ->
s([{[friendsEntry2, [3, 3]], i, ?destroy}]),
?line ?expect1([{[friendsEntry2, [3, 3]], ?destroy}]),
- ?P1("Adding two rows in subagent table with special INDEX (2)"),
+ ?NPRINT("Adding two rows in subagent table with special INDEX (2)"),
s([{[kompissEntry2, [1, 3]], s, "kompis3"},
{[kompissEntry2, [2, 3]], i, ?createAndGo}]),
?line ?expect1([{[kompissEntry2, [1, 3]], "kompis3"},
@@ -3838,7 +3933,7 @@ big_test_2() ->
%% Req. Test1
multi_threaded_test() ->
- ?P1("Testing multi threaded agent..."),
+ ?NPRINT("Testing multi threaded agent..."),
g([[multiStr,0]]),
Pid = get_multi_pid(),
g([[sysUpTime,0]]),
@@ -3865,7 +3960,7 @@ multi_threaded_test() ->
%% Req. Test1, TestTrapv2
mt_trap_test(MA) ->
- ?P1("Testing trap-sending with multi threaded agent..."),
+ ?NPRINT("Testing trap-sending with multi threaded agent..."),
?DBG("mt_trap_test(01) -> issue testTrapv22 (standard trap)", []),
snmpa:send_trap(MA, testTrapv22, "standard trap"),
?DBG("mt_trap_test(02) -> await v2trap", []),
@@ -3911,7 +4006,7 @@ get_multi_pid(N) ->
%% Req. Test1
types_v2_test() ->
- ?P1("Testing v2 types..."),
+ ?NPRINT("Testing v2 types..."),
s([{[bits1,0], 2#10}]),
?line ?expect1([{[bits1,0], ?str(2#10)}]),
@@ -3938,8 +4033,9 @@ types_v2_test() ->
%% Req. Test1
implied_test(MA) ->
- ?LOG("implied_test -> start",[]),
- ?P1("Testing IMPLIED..."),
+ ?IPRINT("implied_test -> start"),
+
+ ?NPRINT("Testing IMPLIED..."),
snmpa:verbosity(MA, trace),
@@ -3997,13 +4093,14 @@ implied_test(MA) ->
snmpa:verbosity(MA, log),
- ?LOG("implied_test -> done", []).
+ ?IPRINT("implied_test -> done", []),
+ ok.
%% Req. Test1
sparse_table_test() ->
- ?P1("Testing sparse table..."),
+ ?NPRINT("Testing sparse table..."),
%% Create two rows, check that they are get-nexted in correct order.
Idx1 = 1,
@@ -4033,11 +4130,12 @@ sparse_table_test() ->
%% Req. Test1
cnt_64_test(MA) ->
- ?LOG("start cnt64 test (~p)",[MA]),
+ ?IPRINT("start cnt64 test (~p)", [MA]),
snmpa:verbosity(MA, trace),
- ?LOG("start cnt64 test",[]),
- ?P1("Testing Counter64, and at the same time, "
- "RowStatus is not last column"),
+ ?IPRINT("start cnt64 test"),
+
+ ?NPRINT("Testing Counter64, and at the same time, "
+ "RowStatus is not last column"),
?DBG("get cnt64",[]),
g([[cnt64,0]]),
@@ -4096,7 +4194,7 @@ cnt_64_test(MA) ->
%% Req. Test1
opaque_test() ->
- ?P1("Testing Opaque datatype..."),
+ ?NPRINT("Testing Opaque datatype..."),
g([[opaqueObj,0]]),
?line ?expect1([{[opaqueObj,0], "opaque-data"}]).
@@ -4238,7 +4336,7 @@ do_mul_next_err() ->
%% Req. system group, Klas1, OLD-SNMPEA-MIB
do_mul_set() ->
- ?P1("Adding one row in subagent table, and one in master table"),
+ ?NPRINT("Adding one row in subagent table, and one in master table"),
NewKeyc3 = [intCommunityEntry,[3],get(mip),is("test")],
NewKeyc4 = [intCommunityEntry,[4],get(mip),is("test")],
NewKeyc5 = [intCommunityEntry,[5],get(mip),is("test")],
@@ -4272,7 +4370,7 @@ do_mul_set_err() ->
NewKeyc3 = [intCommunityEntry,[3],get(mip),is("test")],
NewKeyc4 = [intCommunityEntry,[4],get(mip),is("test")],
NewKeyc5 = [intCommunityEntry,[5],get(mip),is("test")],
- ?P1("Adding one row in subagent table, and one in master table"),
+ ?NPRINT("Adding one row in subagent table, and one in master table"),
s([{[friendsEntry, [2, 3]], s, "kompis3"},
{NewKeyc3, 2},
{[sysUpTime,0], 45}, % sysUpTime (readOnly)
@@ -4435,14 +4533,14 @@ ma_v2_inform1(MA) ->
"~n with receiver: ~p", [_Addr]),
ok;
{snmp_targets, T, Addrs} ->
- ?ERR("ma_v2_inform1 -> "
- "received unexpected snmp_targets"
- "~n with receivers: ~n ~p",[Addrs]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "received unexpected snmp_targets"
+ "~n with receivers: ~n ~p",[Addrs]),
{error, {bad_addrs, Addrs}}
after
5000 ->
- ?ERR("ma_v2_inform1 -> "
- "timeout awaiting snmp_targets [~w]",[T]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "timeout awaiting snmp_targets [~w]",[T]),
{error, snmp_targets_timeout}
end
end,
@@ -4456,16 +4554,16 @@ ma_v2_inform1(MA) ->
"[with manager response] from: ~n ~p", [_Addr]),
ok;
{snmp_notification, Tag03, {no_response, _Addr}} ->
- ?ERR("ma_v2_inform1 -> "
- "received unexpected snmp_notification "
- "[without manager response] from: ~n ~p",
- [_Addr]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "received unexpected snmp_notification "
+ "[without manager response] from: ~n ~p",
+ [_Addr]),
{error, no_response}
after
20000 ->
- ?ERR("ma_v2_inform1 -> "
- "timeout awaiting snmp_notification [~p]",
- [Tag03]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "timeout awaiting snmp_notification [~p]",
+ [Tag03]),
{error, snmp_notification_timeout}
end
end,
@@ -4490,9 +4588,9 @@ ma_v2_inform1(MA) ->
fun() ->
receive
{snmp_notification, Tag07, {got_response, _Addr}} ->
- ?ERR("ma_v2_inform1 -> "
- "received unexpected snmp_notification "
- "[with manager response] from: ~n ~p", [_Addr]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "received unexpected snmp_notification "
+ "[with manager response] from: ~n ~p", [_Addr]),
{error, got_response};
{snmp_notification, Tag07, {no_response, _Addr}} ->
?DBG("ma_v2_inform1 -> "
@@ -4502,9 +4600,9 @@ ma_v2_inform1(MA) ->
ok
after
240000 ->
- ?ERR("ma_v2_inform1 -> "
- "timeout awaiting snmp_notification [~p]",
- [Tag07]),
+ ?EPRINT("ma_v2_inform1 -> "
+ "timeout awaiting snmp_notification [~p]",
+ [Tag07]),
{error, snmp_notification_timeout}
end
end,
@@ -4554,26 +4652,28 @@ ma_v2_inform2(MA) ->
%% Await callback(s)
CmdAwaitDeliveryCallback =
fun(Kind, Ref, Tag) ->
- io:format("CmdAwaitDeliveryCallback -> entry with"
- "~n Kind: ~p"
- "~n Ref: ~p"
- "~n Tag: ~p"
- "~n", [Kind, Ref, Tag]),
+ ?IPRINT("CmdAwaitDeliveryCallback -> entry with"
+ "~n Kind: ~p"
+ "~n Ref: ~p"
+ "~n Tag: ~p", [Kind, Ref, Tag]),
receive
{Kind, Ref, ok} ->
- io:format("CmdAwaitDeliveryCallback(~p,~p) -> received expected result: ok"
- "~n", [Tag, Ref]),
+ ?IPRINT("CmdAwaitDeliveryCallback(~p,~p) -> "
+ "received expected result: ok"
+ "~n", [Tag, Ref]),
ok;
{Kind, Ref, Error} ->
- io:format("CmdAwaitDeliveryCallback(~p,~p) -> received unexpected result: "
- "~n Error: ~p"
- "~n", [Tag, Ref, Error]),
+ ?IPRINT("CmdAwaitDeliveryCallback(~p,~p) -> "
+ "received unexpected result: "
+ "~n Error: ~p"
+ "~n", [Tag, Ref, Error]),
{error, {unexpected_response, Error}}
after
240000 ->
- ?ERR("ma_v2_inform2 -> "
- "timeout awaiting got_response for snmp_notification [~p]",
- [Tag]),
+ ?EPRINT("ma_v2_inform2 -> "
+ "timeout awaiting got_response for "
+ "snmp_notification [~p]",
+ [Tag]),
{error, snmp_notification_timeout}
end
end,
@@ -4645,25 +4745,27 @@ ma_v2_inform3(MA) ->
%% Await callback(s)
CmdAwaitDeliveryCallback =
fun(Kind, Ref, Tag) ->
- io:format("CmdAwaitDeliveryCallback -> entry with"
- "~n Kind: ~p"
- "~n Ref: ~p"
- "~n Tag: ~p"
- "~n", [Kind, Ref, Tag]),
+ ?IPRINT("CmdAwaitDeliveryCallback -> entry with"
+ "~n Kind: ~p"
+ "~n Ref: ~p"
+ "~n Tag: ~p", [Kind, Ref, Tag]),
receive
{Kind, Ref, ok} ->
- io:format("CmdAwaitDeliveryCallback(~p,~p) -> received expected result: ok"
- "~n", [Tag, Ref]),
+ ?IPRINT("CmdAwaitDeliveryCallback(~p,~p) -> "
+ "received expected result: ok"
+ "~n", [Tag, Ref]),
ok;
{Kind, Ref, Error} ->
- io:format("CmdAwaitDeliveryCallback(~p,~p) -> received unexpected result: "
- "~n Error: ~p"
- "~n", [Tag, Ref, Error]),
+ ?IPRINT("CmdAwaitDeliveryCallback(~p,~p) -> "
+ "received unexpected result: "
+ "~n Error: ~p"
+ "~n", [Tag, Ref, Error]),
{error, {unexpected_response, Error}}
after
240000 ->
- ?ERR("ma_v2_inform3 -> "
- "timeout awaiting got_response for snmp_notification [~p]",
+ ?EPRINT("ma_v2_inform3 -> "
+ "timeout awaiting got_response for "
+ "snmp_notification [~p]",
[Tag]),
{error, snmp_notification_timeout}
end
@@ -4746,16 +4848,16 @@ delivery_info(Tag, Address, DeliveryResult, Extra) ->
command_handler([]) ->
ok;
command_handler([{_No, _Desc, Cmd}|Rest]) ->
- ?LOG("command_handler -> command ~w: ~n ~s", [_No, _Desc]),
+ ?IPRINT("command_handler -> command ~w: ~n ~s", [_No, _Desc]),
case (catch Cmd()) of
ok ->
- ?LOG("command_handler -> ~w: ok", [_No]),
+ ?IPRINT("command_handler -> ~w: ok", [_No]),
command_handler(Rest);
{error, Reason} ->
- ?ERR("command_handler -> ~w error: ~n~p", [_No, Reason]),
+ ?EPRINT("command_handler -> ~w error: ~n~p", [_No, Reason]),
?line ?FAIL(Reason);
Error ->
- ?ERR("command_handler -> ~w unexpected: ~n~p", [_No, Error]),
+ ?EPRINT("command_handler -> ~w unexpected: ~n~p", [_No, Error]),
?line ?FAIL({unexpected_command_result, Error})
end.
@@ -5033,7 +5135,7 @@ standard_mibs2_cases() ->
snmpv2_mib_2(suite) -> [];
snmpv2_mib_2(Config) when is_list(Config) ->
?P(snmpv2_mib_2),
- ?LOG("snmpv2_mib_2 -> start",[]),
+ ?IPRINT("snmpv2_mib_2 -> start"),
init_case(Config),
?DBG("snmpv2_mib_2 -> standard mib init",[]),
@@ -5072,7 +5174,7 @@ snmpv2_mib_2(Config) when is_list(Config) ->
"then disable auth traps",[]),
try_test(snmpv2_mib_test_finish, [], [{community, "bad community"}]),
- ?LOG("snmpv2_mib_2 -> done", []),
+ ?IPRINT("snmpv2_mib_2 -> done"),
ok.
@@ -5190,7 +5292,7 @@ snmp_community_mib_2(X) -> ?P(snmp_community_mib_2), snmp_community_mib(X).
%% Req. SNMP-COMMUNITY-MIB
snmp_community_mib_test() ->
- ?INF("NOT YET IMPLEMENTED", []),
+ ?NPRINT("NOT YET IMPLEMENTED"),
nyi.
@@ -5215,41 +5317,69 @@ snmp_framework_mib_3(Config) when is_list(Config) ->
%% Req. SNMP-FRAMEWORK-MIB
+%% snmpEngineID in number of seconds.
+%% In theory, the Engine Time diff of the engine, should be exactly
+%% the same as the number of seconds we sleep (5 in this case).
+%% But because, on some (slow or/and high loaded) hosts, the actual
+%% time we sleep could be a lot larger (due to, for instance, scheduling).
+%% Therefor we must take that into account when we check if the
+%% Engine Time diff (between the two checks) is acceptably.
snmp_framework_mib_test() ->
+ Sleep = 5,
?line ["agentEngine"] = get_req(1, [[snmpEngineID,0]]),
T1 = snmp_misc:now(ms),
?line [EngineTime] = get_req(2, [[snmpEngineTime,0]]),
T2 = snmp_misc:now(ms),
- ?SLEEP(5000),
+ ?SLEEP(?SECS(Sleep)),
T3 = snmp_misc:now(ms),
?line [EngineTime2] = get_req(3, [[snmpEngineTime,0]]),
T4 = snmp_misc:now(ms),
- ?PRINT2("snmp_framework_mib -> time(s): "
- "~n EngineTime 1: ~p"
- "~n Time to acquire: ~w ms"
- "~n EngineTime 2: ~p"
- "~n Time to acquire: ~w ms"
- "~n => (5 sec sleep between get(snmpEngineTime))"
- "~n Total time to acquire: ~w ms",
- [EngineTime, T2-T1, EngineTime2, T4-T3, T4-T1]),
- if
- (EngineTime+7) < EngineTime2 ->
- ?line ?FAIL({too_large_diff, EngineTime, EngineTime2});
- (EngineTime+4) > EngineTime2 ->
- ?line ?FAIL({too_large_diff, EngineTime, EngineTime2});
- true ->
- ok
+
+ %% Ok, we tried to sleep 5 seconds, but how long did we actually sleep
+ ASleep = ((T3-T2) + 500) div 1000,
+ EngineTimeDiff = EngineTime2 - EngineTime,
+ HighEngineTime = EngineTime + ASleep + 2,
+ LowEngineTime = EngineTime + ASleep - 1,
+
+ ?IPRINT("snmp_framework_mib -> time(s): "
+ "~n EngineTime 1: ~p"
+ "~n Time to acquire: ~w msec"
+ "~n EngineTime 2: ~p"
+ "~n Time to acquire: ~w msec"
+ "~n => Total time to acquire: ~w msec"
+ "~n Sleep between get(snmpEngineTime): ~w (~w) sec"
+ "~n Engine Time Diff: ~w sec"
+ "~n Success if:"
+ "~n ~w (low) =< Engine Time 2 =< ~w (high)",
+ [EngineTime, T2-T1,
+ EngineTime2, T4-T3,
+ T4-T1, ASleep, Sleep, EngineTimeDiff, LowEngineTime, HighEngineTime]),
+
+ if
+ (HighEngineTime < EngineTime2) ->
+ ?EPRINT("snmp_framework_mib -> (High) Engine Time diff (~w) too large: "
+ "~n ~w < ~w",
+ [EngineTimeDiff, HighEngineTime, EngineTime2]),
+ ?line ?FAIL({too_large_diff, EngineTime, EngineTime2});
+ (LowEngineTime > EngineTime2) ->
+ ?EPRINT("snmp_framework_mib -> (Low) Engine Time diff (~w) too large: "
+ "~n ~w > ~w",
+ [EngineTimeDiff, LowEngineTime, EngineTime2]),
+ ?line ?FAIL({too_large_diff, EngineTime, EngineTime2});
+ true ->
+ ok
end,
+
T5 = snmp_misc:now(ms),
?line case get_req(4, [[snmpEngineBoots,0]]) of
[Boots] when is_integer(Boots) ->
T6 = snmp_misc:now(ms),
- ?PRINT2("snmp_framework_mib -> "
+ ?IPRINT("snmp_framework_mib -> "
"~n boots: ~p"
"~n Time to acquire: ~w ms", [Boots, T6-T5]),
ok;
Else ->
- ?PRINT2("snmp_framework_mib -> failed get proper boots:"
+ ?EPRINT("snmp_framework_mib -> failed get proper boots:"
"~n ~p", [Else]),
?FAIL({invalid_boots, Else})
end,
@@ -5339,7 +5469,7 @@ snmp_target_mib_2(X) -> ?P(snmp_target_mib_2), snmp_target_mib(X).
snmp_target_mib_3(X) -> ?P(snmp_target_mib_3), snmp_target_mib(X).
snmp_target_mib_test() ->
- ?INF("NOT YET IMPLEMENTED", []),
+ ?NPRINT("NOT YET IMPLEMENTED"),
nyi.
snmp_notification_mib(suite) -> [];
@@ -5357,7 +5487,7 @@ snmp_notification_mib_3(X) -> ?P(snmp_notification_mib_3),
snmp_notification_mib(X).
snmp_notification_mib_test() ->
- ?INF("NOT YET IMPLEMENTED", []),
+ ?NPRINT("NOT YET IMPLEMENTED"),
nyi.
@@ -5393,7 +5523,7 @@ snmp_view_based_acm_mib_3(X) ->
snmp_view_based_acm_mib() ->
snmpa:verbosity(net_if,trace),
snmpa:verbosity(master_agent,trace),
- ?LOG("start snmp_view_based_acm_mib test",[]),
+ ?IPRINT("start snmp_view_based_acm_mib test"),
%% The user "no-rights" is present in USM, and is mapped to security
%% name 'no-rights", which is not present in VACM.
%% So, we'll add rights for it, try them and delete them.
@@ -5790,7 +5920,7 @@ usm_bad() ->
loop_mib_1(suite) -> [];
loop_mib_1(Config) when is_list(Config) ->
?P(loop_mib_1),
- ?LOG("loop_mib_1 -> initiate case",[]),
+ ?IPRINT("loop_mib_1 -> initiate case"),
{_SaNode, _MgrNode, _MibDir} = init_case(Config),
?DBG("loop_mib_1 -> ~n"
@@ -5827,14 +5957,14 @@ loop_mib_1(Config) when is_list(Config) ->
?line unload_master("SNMP-VIEW-BASED-ACM-MIB"),
%% snmpa:verbosity(master_agent,log),
%% snmpa:verbosity(mib_server,silence),
- ?LOG("loop_mib_1 -> done",[]),
+ ?IPRINT("loop_mib_1 -> done"),
ok.
loop_mib_2(suite) -> [];
loop_mib_2(Config) when is_list(Config) ->
?P(loop_mib_2),
- ?LOG("loop_mib_2 -> initiate case",[]),
+ ?IPRINT("loop_mib_2 -> initiate case"),
{_SaNode, _MgrNode, _MibDir} = init_case(Config),
?DBG("do_loop_mib_2 -> ~n"
"\tSaNode: ~p~n"
@@ -5857,14 +5987,14 @@ loop_mib_2(Config) when is_list(Config) ->
?line unload_master("SNMP-NOTIFICATION-MIB"),
?line unload_master("SNMP-FRAMEWORK-MIB"),
?line unload_master("SNMP-VIEW-BASED-ACM-MIB"),
- ?LOG("loop_mib_2 -> done",[]),
+ ?IPRINT("loop_mib_2 -> done"),
ok.
loop_mib_3(suite) -> [];
loop_mib_3(Config) when is_list(Config) ->
?P(loop_mib_3),
- ?LOG("loop_mib_3 -> initiate case",[]),
+ ?IPRINT("loop_mib_3 -> initiate case"),
{_SaNode, _MgrNode, _MibDir} = init_case(Config),
?DBG("loop_mib_3 -> ~n"
"\tSaNode: ~p~n"
@@ -5883,7 +6013,7 @@ loop_mib_3(Config) when is_list(Config) ->
?line unload_master("SNMP-NOTIFICATION-MIB"),
?line unload_master("SNMP-VIEW-BASED-ACM-MIB"),
?line unload_master("SNMP-USER-BASED-SM-MIB"),
- ?LOG("loop_mib_3 -> done",[]),
+ ?IPRINT("loop_mib_3 -> done"),
ok.
@@ -6378,7 +6508,7 @@ otp_1366_2(X) -> ?P(otp_1366_2), otp_1366(X).
otp_1366_3(X) -> ?P(otp_1366_3), otp_1366(X).
otp_1366_test() ->
- ?INF("NOT YET IMPLEMENTED", []),
+ ?NPRINT("NOT YET IMPLEMENTED"),
'NYI'.
@@ -6397,7 +6527,7 @@ otp_2776_2(X) -> ?P(otp_2776_2), otp_2776(X).
otp_2776_3(X) -> ?P(otp_2776_3), otp_2776(X).
otp_2776_test() ->
- io:format("Testing bug reported in ticket OTP-2776...~n"),
+ ?NPRINT("Testing bug reported in ticket OTP-2776..."),
Dt01_valid = [19,98,9,1,1,0,23,0,43,0,0],
Dt02_valid = [19,98,9,1,0,0,0,0,43,0,0], % This is what is fixed: 00:00
@@ -6716,10 +6846,11 @@ otp_7157(Config) ->
%% ts:run(snmp, snmp_agent_test, [batch]).
otp_7157_test(MA) ->
- ?LOG("start otp_7157_test test (~p)",[MA]),
+ ?IPRINT("start otp_7157_test test (~p)", [MA]),
snmpa:verbosity(MA, trace),
- ?LOG("start otp_7157_test test",[]),
- ?P1("Testing that varbinds in traps/notifications are not reordered"),
+ ?IPRINT("start otp_7157_test test"),
+
+ ?NPRINT("Testing that varbinds in traps/notifications are not reordered"),
?DBG("send cntTrap",[]),
snmpa:send_trap(MA, cntTrap, "standard trap"),
@@ -6837,8 +6968,7 @@ otp_16092_simple_start_and_stop(Config, ESO, Expected) ->
?line ConfDir = ?config(agent_conf_dir, Config),
?line DbDir = ?config(agent_db_dir, Config),
- p("try start agent node~n"),
- p(user, "try start agent node~n"),
+ ?NPRINT("try start agent node"),
{ok, Node} = ?ALIB:start_node(agent_16092),
Vsns = [v1],
@@ -6870,27 +7000,27 @@ otp_16092_simple_start_and_stop(Config, ESO, Expected) ->
otp16092_try_start_and_stop_agent(Node, Opts, Expected),
- p("try stop agent node ~p~n", [Node]),
- p(user, "try stop agent node ~p~n", [Node]),
+ ?NPRINT("try stop agent node ~p", [Node]),
?ALIB:stop_node(Node),
?SLEEP(1000),
- p("done~n"),
- p(user, "done~n"),
+ ?NPRINT("done"),
ok.
otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
- i("try start snmp (agent) supervisor (on ~p) - expect ~p~n", [Node, Expected]),
+ ?IPRINT("try start snmp (agent) supervisor (on ~p) - expect ~p",
+ [Node, Expected]),
case start_standalone_agent(Node, Opts) of
Pid when is_pid(Pid) andalso (Expected =:= success) ->
- i("Expected success starting snmp (agent) supervisor~n"),
+ ?IPRINT("Expected success starting snmp (agent) supervisor"),
?SLEEP(1000),
stop_standalone_agent(Pid),
ok;
Pid when is_pid(Pid) andalso (Expected =:= failure) ->
- e("Unexpected success starting snmp (agent) supervisor: (~p)~n", [Pid]),
+ ?EPRINT("Unexpected success starting snmp (agent) supervisor: (~p)",
+ [Pid]),
?SLEEP(1000),
stop_standalone_agent(Pid),
?FAIL('unexpected-start-success');
@@ -6901,18 +7031,18 @@ otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
{shutdown,
{failed_to_start_child, snmpa_agent,
{net_if_error, Reason}}}}} when (Expected =:= failure) ->
- p("Expected (shutdown, net-if) error starting "
- "snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected (shutdown, net-if) error starting "
+ "snmp (agent) supervisor (on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{error, {shutdown, Reason}} when (Expected =:= failure) ->
- p("Expected (shutdown) error starting "
- "snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected (shutdown) error starting "
+ "snmp (agent) supervisor (on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{error, Reason} when (Expected =:= failure) ->
- p("Expected error starting snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected error starting snmp (agent) supervisor (on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{badrpc,
@@ -6922,23 +7052,24 @@ otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
{shutdown,
{failed_to_start_child, snmpa_agent,
{net_if_error, Reason}}}}}}} when (Expected =:= failure) ->
- p("Expected (badrpc, shutdown, net-if) error starting "
- "snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected (badrpc, shutdown, net-if) error starting "
+ "snmp (agent) supervisor (on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{badrpc, {'EXIT', {shutdown, Reason}}} when (Expected =:= failure) ->
- p("Expected (badrpc, shutdown) error starting "
- "snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected (badrpc, shutdown) error starting "
+ "snmp (agent) supervisor (on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{badrpc, {'EXIT', Reason}} when (Expected =:= failure) ->
- p("Expected (badrpc) error starting snmp (agent) supervisor (on ~p):"
- "~n ~p", [Node, Reason]),
+ ?IPRINT("Expected (badrpc) error starting snmp (agent) supervisor "
+ "(on ~p):"
+ "~n ~p", [Node, Reason]),
ok;
{badrpc, Reason} = BADRPC ->
- e("Bad RPC to node ~p failed:"
- "~n ~p", [Node, Reason]),
+ ?WPRINT("Bad RPC to node ~p failed:"
+ "~n ~p", [Node, Reason]),
?SKIP({BADRPC, Node})
end,
@@ -7032,9 +7163,7 @@ otp8395({init, Config}) when is_list(Config) ->
%% Create watchdog
%%
- Dog = ?WD_START(?MINS(1)),
-
- [{watchdog, Dog} | Config2];
+ wd_start(1, Config2);
otp8395({fin, Config}) when is_list(Config) ->
?DBG("otp8395(fin) -> entry with"
@@ -7073,9 +7202,7 @@ otp8395({fin, Config}) when is_list(Config) ->
?DBG("otp8395(fin) -> stop manager node", []),
stop_node(ManagerNode),
- Dog = ?config(watchdog, Config),
- ?WD_STOP(Dog),
- lists:keydelete(watchdog, 1, Config);
+ wd_stop(Config);
otp8395(doc) ->
"OTP-8395 - ATL with sequence numbering. ";
@@ -7153,15 +7280,15 @@ otp9884(Config) when is_list(Config) ->
otp9884_backup(Node, Pid, Tag, Dir) ->
- i("[~w] backup - await continue", [Tag]),
+ ?IPRINT("[~w] backup - await continue", [Tag]),
Pid ! {otp9884_backup_started, Tag, self()},
receive
{otp9884_backup_continue, Tag, Pid} ->
ok
end,
- i("[~w] backup start", [Tag]),
+ ?IPRINT("[~w] backup start", [Tag]),
Res = rpc:call(Node, snmpa, backup, [Dir]),
- i("[~w] backup result: ~p", [Tag, Res]),
+ ?IPRINT("[~w] backup result: ~p", [Tag, Res]),
Pid ! {otp9884_backup_complete, Tag, Res}.
@@ -7170,30 +7297,30 @@ otp9884_await_backup_started() ->
otp9884_await_backup_started(First, Second)
when is_pid(First) andalso is_pid(Second) ->
- i("otp9884_await_backup_started -> order first continue"),
+ ?IPRINT("otp9884_await_backup_started -> order first continue"),
First ! {otp9884_backup_continue, first, self()},
- i("otp9884_await_backup_started -> order second continue"),
+ ?IPRINT("otp9884_await_backup_started -> order second continue"),
Second ! {otp9884_backup_continue, second, self()},
ok;
otp9884_await_backup_started(First, Second) ->
receive
{otp9884_backup_started, first, Pid} when (First =:= undefined) ->
- i("otp9884_await_backup_started -> received started from first"),
+ ?IPRINT("otp9884_await_backup_started -> received started from first"),
otp9884_await_backup_started(Pid, Second);
{otp9884_backup_started, second, Pid} when (Second =:= undefined) ->
- i("otp9884_await_backup_started -> received started from second"),
+ ?IPRINT("otp9884_await_backup_started -> received started from second"),
otp9884_await_backup_started(First, Pid)
end.
otp9884_await_backup_completion(ok, Second)
when ((Second =/= ok) andalso (Second =/= undefined)) ->
- i("otp9884_await_backup_completion -> "
- "first backup succeed and second failed (~p)", [Second]),
+ ?IPRINT("otp9884_await_backup_completion -> "
+ "first backup succeed and second failed (~p)", [Second]),
ok;
otp9884_await_backup_completion(First, ok)
when ((First =/= ok) andalso (First =/= undefined)) ->
- i("otp9884_await_backup_completion -> "
- "second backup succeed and first failed (~p)", [First]),
+ ?IPRINT("otp9884_await_backup_completion -> "
+ "second backup succeed and first failed (~p)", [First]),
ok;
otp9884_await_backup_completion(First, Second)
when (((First =:= undefined) andalso (Second =:= undefined))
@@ -7201,24 +7328,25 @@ otp9884_await_backup_completion(First, Second)
((First =:= undefined) andalso (Second =/= undefined))
orelse
((First =/= undefined) andalso (Second =:= undefined))) ->
- i("otp9884_await_backup_completion -> await complete messages"),
+ ?IPRINT("otp9884_await_backup_completion -> await complete messages"),
receive
{otp9884_backup_complete, first, Res} ->
- i("otp9884_await_backup_completion -> "
- "received complete message for first: ~p", [Res]),
+ ?IPRINT("otp9884_await_backup_completion -> "
+ "received complete message for first: ~p", [Res]),
otp9884_await_backup_completion(Res, Second);
{otp9884_backup_complete, second, Res} ->
- i("otp9884_await_backup_completion -> "
- "received complete message for second: ~p", [Res]),
+ ?IPRINT("otp9884_await_backup_completion -> "
+ "received complete message for second: ~p", [Res]),
otp9884_await_backup_completion(First, Res)
after 10000 ->
%% we have waited long enough
+ ?EPRINT("otp9884_await_backup_completion -> timeout"),
throw({error, {timeout, First, Second}})
end;
otp9884_await_backup_completion(First, Second) ->
- e("Bad Completion: "
- "~n First: ~p"
- "~n Second: ~p", [First, Second]),
+ ?EPRINT("Bad Completion: "
+ "~n First: ~p"
+ "~n Second: ~p", [First, Second]),
throw({error, {bad_completion, First, Second}}).
@@ -7445,16 +7573,16 @@ verify_subinfo(Info0, [Key|Keys]) ->
is(S) -> [length(S) | S].
try_test(Func) ->
- ?P2("try test ~w...", [Func]),
- snmp_agent_test_lib:try_test(?MODULE, Func).
+ ?NPRINT("try test ~w...", [Func]),
+ ?ALIB:try_test(?MODULE, Func).
try_test(Func, A) ->
- ?P2("try test ~w...", [Func]),
- snmp_agent_test_lib:try_test(?MODULE, Func, A).
+ ?NPRINT("try test ~w...", [Func]),
+ ?ALIB:try_test(?MODULE, Func, A).
try_test(Func, A, Opts) ->
- ?P2("try test ~w...", [Func]),
- snmp_agent_test_lib:try_test(?MODULE, Func, A, Opts).
+ ?NPRINT("try test ~w...", [Func]),
+ ?ALIB:try_test(?MODULE, Func, A, Opts).
%% Test manager wrapperfunctions:
@@ -7465,77 +7593,80 @@ gb(NR, MR, Oids) -> snmp_test_mgr:gb(NR, MR, Oids).
s(VAV) -> snmp_test_mgr:s(VAV).
get_req(Id, Vars) ->
- snmp_agent_test_lib:get_req(Id, Vars).
+ ?ALIB:get_req(Id, Vars).
get_next_req(Vars) ->
- snmp_agent_test_lib:get_next_req(Vars).
+ ?ALIB:get_next_req(Vars).
start_node(Name) ->
- snmp_agent_test_lib:start_node(Name).
+ ?ALIB:start_node(Name).
+stop_node(undefined) ->
+ ok;
stop_node(Node) ->
- snmp_agent_test_lib:stop_node(Node).
+ ?ALIB:stop_node(Node).
%%%-----------------------------------------------------------------
%%% Configuration
%%%-----------------------------------------------------------------
delete_files(Config) ->
- snmp_agent_test_lib:delete_files(Config).
+ ?ALIB:delete_files(Config).
config(Vsns, MgrDir, AgentDir, MIp, AIp) ->
- snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp).
+ ?ALIB:config(Vsns, MgrDir, AgentDir, MIp, AIp).
config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily) ->
- snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily).
+ ?ALIB:config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily).
update_usm(Vsns, Dir) ->
- snmp_agent_test_lib:update_usm(Vsns, Dir).
+ ?ALIB:update_usm(Vsns, Dir).
update_usm_mgr(Vsns, Dir) ->
- snmp_agent_test_lib:update_usm_mgr(Vsns, Dir).
+ ?ALIB:update_usm_mgr(Vsns, Dir).
rewrite_usm_mgr(Dir, ShaKey, DesKey) ->
- snmp_agent_test_lib:rewrite_usm_mgr(Dir, ShaKey, DesKey).
+ ?ALIB:rewrite_usm_mgr(Dir, ShaKey, DesKey).
reset_usm_mgr(Dir) ->
- snmp_agent_test_lib:reset_usm_mgr(Dir).
+ ?ALIB:reset_usm_mgr(Dir).
update_vacm(Vsn, Dir) ->
- snmp_agent_test_lib:update_vacm(Vsn, Dir).
+ ?ALIB:update_vacm(Vsn, Dir).
write_community_conf(Dir, Conf) ->
- snmp_agent_test_lib:write_community_conf(Dir, Conf).
+ ?ALIB:write_community_conf(Dir, Conf).
write_target_addr_conf(Dir, Conf) ->
- snmp_agent_test_lib:write_target_addr_conf(Dir, Conf).
+ ?ALIB:write_target_addr_conf(Dir, Conf).
rewrite_target_addr_conf(Dir, NewPort) ->
- snmp_agent_test_lib:rewrite_target_addr_conf(Dir, NewPort).
+ ?ALIB:rewrite_target_addr_conf(Dir, NewPort).
reset_target_addr_conf(Dir) ->
- snmp_agent_test_lib:reset_target_addr_conf(Dir).
+ ?ALIB:reset_target_addr_conf(Dir).
write_target_params_conf(Dir, Vsns) ->
- snmp_agent_test_lib:write_target_params_conf(Dir, Vsns).
+ ?ALIB:write_target_params_conf(Dir, Vsns).
rewrite_target_params_conf(Dir, SecName, SecLevel) ->
- snmp_agent_test_lib:rewrite_target_params_conf(Dir, SecName, SecLevel).
+ ?ALIB:rewrite_target_params_conf(Dir, SecName, SecLevel).
reset_target_params_conf(Dir) ->
- snmp_agent_test_lib:reset_target_params_conf(Dir).
+ ?ALIB:reset_target_params_conf(Dir).
write_notify_conf(Dir) ->
- snmp_agent_test_lib:write_notify_conf(Dir).
+ ?ALIB:write_notify_conf(Dir).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
copy_file(From, To) ->
- snmp_agent_test_lib:copy_file(From, To).
+ ?ALIB:copy_file(From, To).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -7548,25 +7679,25 @@ display_log(Config) ->
LogDir = Dir,
Mibs = [],
OutFile = join(LogDir, "snmpa_log.txt"),
- p("~n"
- "========================="
- " < Audit Trail Log > "
- "========================="
- "~n"),
+ ?IPRINT("~n"
+ "========================="
+ " < Audit Trail Log > "
+ "========================="
+ "~n"),
rcall(Node, snmpa, log_to_txt, [LogDir, Mibs, OutFile]),
rcall(Node, snmpa, log_to_io, [LogDir, Mibs]),
- p("~n"
- "========================="
- " < / Audit Trail Log > "
- "========================="
- "~n", []);
+ ?IPRINT("~n"
+ "========================="
+ " < / Audit Trail Log > "
+ "========================="
+ "~n");
false ->
- p("display_log -> no agent node found"),
+ ?IPRINT("display_log -> no agent node found"),
ok
end;
false ->
- p("display_log -> no agent log dir found: "
- "~n ~p", [Config]),
+ ?IPRINT("display_log -> no agent log dir found: "
+ "~n ~p", [Config]),
ok
end.
@@ -7581,8 +7712,7 @@ display_memory_usage() ->
SSMU = display_symbolic_store_memory_usage(Info),
LDBMU = display_local_db_memory_usage(Info),
MSMU = display_mib_server_memory_usage(Info),
- ?INF("Memory usage: ~n" ++
- AMU ++ NIMU ++ NSMU ++ SSMU ++ LDBMU ++ MSMU, []),
+ ?NPRINT("Memory usage: ~n" ++ AMU ++ NIMU ++ NSMU ++ SSMU ++ LDBMU ++ MSMU),
ok.
display_agent_memory_usage(Info) ->
@@ -7599,62 +7729,57 @@ display_agent_memory_usage(Info) ->
lists_key1search([db_memory,community_cache], AgentInfo),
VacmSize =
lists_key1search([db_memory,vacm], AgentInfo),
- lists:flatten(
- io_lib:format(" Agent memory usage: "
- "~n Master process memory size: ~p"
- "~n Worker process memory size: ~p"
- "~n Set-worker process memory size: ~p"
- "~n Agent tab size: ~p"
- "~n Community cache size: ~p"
- "~n Vacm tab size: ~p"
- "~n",
- [ProcMem, WProcMem, SWProcMem,
- TabSize, CCSize, VacmSize])).
+ ?F(" Agent memory usage: "
+ "~n Master process memory size: ~p"
+ "~n Worker process memory size: ~p"
+ "~n Set-worker process memory size: ~p"
+ "~n Agent tab size: ~p"
+ "~n Community cache size: ~p"
+ "~n Vacm tab size: ~p"
+ "~n",
+ [ProcMem, WProcMem, SWProcMem,
+ TabSize, CCSize, VacmSize]).
display_net_if_memory_usage(Info) ->
NiInfo = lists_key1search(net_if, Info),
ProcMem = lists_key1search(process_memory, NiInfo),
- lists:flatten(
- io_lib:format(" Net if memory usage: "
- "~n Process memory size: ~p"
- "~n",[ProcMem])).
+ ?F(" Net if memory usage: "
+ "~n Process memory size: ~p"
+ "~n", [ProcMem]).
display_note_store_memory_usage(Info) ->
NsInfo = lists_key1search(note_store, Info),
ProcMem = lists_key1search([process_memory,notes], NsInfo),
ProcTmrMem = lists_key1search([process_memory,timer], NsInfo),
TabSize = lists_key1search([db_memory,notes], NsInfo),
- lists:flatten(
- io_lib:format(" Note store memory usage: "
- "~n Notes process memory size: ~p"
- "~n Timer process memory size: ~p"
- "~n Notes tab size: ~p"
- "~n",
- [ProcMem, ProcTmrMem, TabSize])).
+ ?F(" Note store memory usage: "
+ "~n Notes process memory size: ~p"
+ "~n Timer process memory size: ~p"
+ "~n Notes tab size: ~p"
+ "~n",
+ [ProcMem, ProcTmrMem, TabSize]).
display_symbolic_store_memory_usage(Info) ->
SsInfo = lists_key1search(symbolic_store, Info),
ProcMem = lists_key1search(process_memory, SsInfo),
DbMem = lists_key1search(db_memory, SsInfo),
- lists:flatten(
- io_lib:format(" Symbolic store memory usage: "
- "~n Process memory size: ~p"
- "~n DB size: ~p"
- "~n",
- [ProcMem, DbMem])).
+ ?F(" Symbolic store memory usage: "
+ "~n Process memory size: ~p"
+ "~n DB size: ~p"
+ "~n",
+ [ProcMem, DbMem]).
display_local_db_memory_usage(Info) ->
LdInfo = lists_key1search(local_db, Info),
ProcMem = lists_key1search(process_memory, LdInfo),
EtsSize = lists_key1search([db_memory,ets], LdInfo),
DetsSize = lists_key1search([db_memory,dets], LdInfo),
- lists:flatten(
- io_lib:format(" Local DB memory usage: "
- "~n Process memory size: ~p"
- "~n DB [ets] size: ~p"
- "~n DB [dets] size: ~p"
- "~n",
- [ProcMem, EtsSize, DetsSize])).
+ ?F(" Local DB memory usage: "
+ "~n Process memory size: ~p"
+ "~n DB [ets] size: ~p"
+ "~n DB [dets] size: ~p"
+ "~n",
+ [ProcMem, EtsSize, DetsSize]).
display_mib_server_memory_usage(Info) ->
MibInfo = lists_key1search(mib_server, Info),
@@ -7663,15 +7788,14 @@ display_mib_server_memory_usage(Info) ->
MibDbSize = lists_key1search([db_memory,mib], MibInfo),
NodeDbSize = lists_key1search([db_memory,node], MibInfo),
TreeDbSize = lists_key1search([db_memory,tree], MibInfo),
- lists:flatten(
- io_lib:format(" MIB server memory usage: "
- "~n Process memory size: ~p"
- "~n Tree size: ~p"
- "~n Mib db size: ~p"
- "~n Node db size: ~p"
- "~n Tree db size: ~p"
- "~n",
- [ProcMem, TreeSize, MibDbSize, NodeDbSize, TreeDbSize])).
+ ?F(" MIB server memory usage: "
+ "~n Process memory size: ~p"
+ "~n Tree size: ~p"
+ "~n Mib db size: ~p"
+ "~n Node db size: ~p"
+ "~n Tree db size: ~p"
+ "~n",
+ [ProcMem, TreeSize, MibDbSize, NodeDbSize, TreeDbSize]).
lists_key1search([], Res) ->
Res;
@@ -7693,56 +7817,6 @@ lists_key1search(Key, List) when is_atom(Key) ->
%% ------
-join(Parts) ->
- filename:join(Parts).
-
-join(Dir, File) ->
- filename:join(Dir, File).
-
-
-%% ------
-
-rcall(Node, Mod, Func, Args) ->
- case rpc:call(Node, Mod, Func, Args) of
- {badrpc, nodedown} ->
- ?FAIL({rpc_failure, Node});
- Else ->
- Else
- end.
-
-
-%% ------
-
-%% e(F) ->
-%% e(F, []).
-
-e(F, A) ->
- p(user, "<ERROR> " ++ F, A),
- p(standard_io, "<ERROR> " ++ F, A).
-
-i(F) ->
- i(F, []).
-i(F, A) ->
- p(user, F, A),
- p(standard_io, F, A).
-
-p(F) ->
- p(F, []).
-
-p(Dev, F) when is_atom(Dev) ->
- p(Dev, F, []);
-p(F, A) ->
- p(standard_io, F, A).
-
-p(Dev, F, A) ->
- io:format(Dev,
- "*** [~s] ***"
- "~n" ++ F ++ "~n", [formated_timestamp()|A]).
-
-formated_timestamp() ->
- snmp_test_lib:formated_timestamp().
-
-
init_v1_agent(Config) ->
%% --
%% Start nodes
@@ -7813,9 +7887,7 @@ init_v1_agent(Config) ->
%% Create watchdog
%%
- Dog = ?WD_START(?MINS(1)),
-
- [{watchdog, Dog} | Config2].
+ wd_start(1, Config2).
fin_v1_agent(Config) ->
AgentNode = ?config(agent_node, Config),
@@ -7850,10 +7922,7 @@ fin_v1_agent(Config) ->
%%
stop_node(ManagerNode),
- Dog = ?config(watchdog, Config),
- ?WD_STOP(Dog),
- lists:keydelete(watchdog, 1, Config).
-
+ wd_stop(Config).
config_ipfamily(Config) ->
@@ -7863,3 +7932,25 @@ config_ipfamily(Config) ->
Value ->
Value
end.
+
+
+%% ------
+
+join(Parts) ->
+ filename:join(Parts).
+
+join(Dir, File) ->
+ filename:join(Dir, File).
+
+
+%% ------
+
+rcall(Node, Mod, Func, Args) ->
+ case rpc:call(Node, Mod, Func, Args) of
+ {badrpc, nodedown} ->
+ ?FAIL({rpc_failure, Node});
+ Else ->
+ Else
+ end.
+
+
diff --git a/lib/snmp/test/snmp_agent_conf_SUITE.erl b/lib/snmp/test/snmp_agent_conf_SUITE.erl
index 889af630a4..1f0ad3708b 100644
--- a/lib/snmp/test/snmp_agent_conf_SUITE.erl
+++ b/lib/snmp/test/snmp_agent_conf_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -101,7 +101,7 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
end_per_testcase(_Case, Config) when is_list(Config) ->
- ?PRINT2("system events during test: "
+ ?IPRINT("system events during test: "
"~n ~p", [snmp_test_global_sys_monitor:events()]),
Config.
diff --git a/lib/snmp/test/snmp_agent_mibs_SUITE.erl b/lib/snmp/test/snmp_agent_mibs_SUITE.erl
index 9545dfdcc9..150e015554 100644
--- a/lib/snmp/test/snmp_agent_mibs_SUITE.erl
+++ b/lib/snmp/test/snmp_agent_mibs_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -67,6 +67,9 @@
]).
+-define(ALIB, snmp_agent_test_lib).
+
+
%%======================================================================
%% Common Test interface functions
%%======================================================================
@@ -166,27 +169,18 @@ init_per_testcase(Case, Config0) when is_list(Config0) ->
init_per_testcase2(size_check_ets2_bad_file1, Config) when is_list(Config) ->
DbDir = ?config(db_dir, Config),
- %% Create a ad file
+ %% Create a bad file
ok = file:write_file(join(DbDir, "snmpa_symbolic_store.db"),
"calvin and hoppes play chess"),
Config;
init_per_testcase2(size_check_ets3_bad_file1, Config) when is_list(Config) ->
DbDir = ?config(db_dir, Config),
- %% Create a ad file
+ %% Create a bad file
ok = file:write_file(join(DbDir, "snmpa_symbolic_store.db"),
"calvin and hoppes play chess"),
Config;
init_per_testcase2(size_check_mnesia, Config) when is_list(Config) ->
- DbDir = ?config(db_dir, Config),
- try
- begin
- mnesia_start([{dir, DbDir}]),
- Config
- end
- catch
- throw:{skip, _} = SKIP ->
- SKIP
- end;
+ Config;
init_per_testcase2(cache_test, Config) when is_list(Config) ->
Min = timer:minutes(5),
Timeout =
@@ -205,7 +199,7 @@ init_per_testcase2(_Case, Config) when is_list(Config) ->
end_per_testcase(Case, Config) when is_list(Config) ->
- ?PRINT2("system events during test: "
+ ?IPRINT("system events during test: "
"~n ~p", [snmp_test_global_sys_monitor:events()]),
end_per_testcase1(Case, Config).
@@ -301,7 +295,8 @@ size_check_ets1(suite) ->
[];
size_check_ets1(Config) when is_list(Config) ->
MibStorage = [{module, snmpa_mib_storage_ets}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_ets1,
+ [{mib_storage, MibStorage}|Config]).
size_check_ets2(suite) ->
[];
@@ -309,7 +304,8 @@ size_check_ets2(Config) when is_list(Config) ->
Dir = ?config(db_dir, Config),
MibStorage = [{module, snmpa_mib_storage_ets},
{options, [{dir, Dir}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_ets2,
+ [{mib_storage, MibStorage}|Config]).
size_check_ets2_bad_file1(suite) ->
[];
@@ -319,7 +315,8 @@ size_check_ets2_bad_file1(Config) when is_list(Config) ->
MibStorage = [{module, snmpa_mib_storage_ets},
{options, [{dir, Dir},
{action, clear}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_ets2_bad_file1,
+ [{mib_storage, MibStorage}|Config]).
size_check_ets3(suite) ->
[];
@@ -328,7 +325,8 @@ size_check_ets3(Config) when is_list(Config) ->
MibStorage = [{module, snmpa_mib_storage_ets},
{options, [{dir, Dir},
{checksum, true}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_ets3,
+ [{mib_storage, MibStorage}|Config]).
size_check_ets3_bad_file1(suite) ->
[];
@@ -339,7 +337,8 @@ size_check_ets3_bad_file1(Config) when is_list(Config) ->
{options, [{dir, Dir},
{action, clear},
{checksum, true}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_ets3_bad_file1,
+ [{mib_storage, MibStorage}|Config]).
size_check_dets(suite) ->
[];
@@ -347,18 +346,72 @@ size_check_dets(Config) when is_list(Config) ->
Dir = ?config(db_dir, Config),
MibStorage = [{module, snmpa_mib_storage_dets},
{options, [{dir, Dir}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ do_size_check(size_check_dets,
+ [{mib_storage, MibStorage}|Config]).
size_check_mnesia(suite) ->
[];
size_check_mnesia(Config) when is_list(Config) ->
MibStorage = [{module, snmpa_mib_storage_mnesia},
- {options, [{nodes, [node()]}]}],
- do_size_check([{mib_storage, MibStorage}|Config]).
+ {options, [{nodes, []}]}],
+ DbDir = ?config(db_dir, Config),
+ Init = fun() -> mnesia_start([{dir, DbDir}]), ok end,
+ do_size_check(size_check_mnesia,
+ Init,
+ [{mib_storage, MibStorage}|Config]).
+
+do_size_check(Name, Config) ->
+ Init = fun() -> ok end,
+ do_size_check(Name, Init, Config).
+
+do_size_check(Name, Init, Config) ->
+ Pre = fun() ->
+ {ok, Node} = ?ALIB:start_node(unique(Name)),
+ ok = run_on(Node, Init),
+ Node
+ end,
+ Case = fun(Node) ->
+ monitor_node(Node, true),
+ Pid = spawn_link(Node, fun() -> do_size_check(Config) end),
+ receive
+ {nodedown, Node} = N ->
+ exit(N);
+ {'EXIT', Pid, normal} ->
+ monitor_node(Node, false),
+ ok;
+ {'EXIT', Pid, ok} ->
+ monitor_node(Node, false),
+ ok;
+ {'EXIT', Pid, Reason} ->
+ monitor_node(Node, false),
+ exit(Reason)
+ end
+ end,
+ Post = fun({Node, _}) ->
+ ?STOP_NODE(Node)
+ end,
+ ?TC_TRY(Name, Pre, Case, Post).
+
+run_on(Node, F) when is_atom(Node) andalso is_function(F, 0) ->
+ monitor_node(Node, true),
+ Pid = spawn_link(Node, F),
+ receive
+ {nodedown, Node} = N ->
+ exit(N);
+ {'EXIT', Pid, normal} ->
+ monitor_node(Node, false),
+ ok;
+ {'EXIT', Pid, Reason} ->
+ monitor_node(Node, false),
+ Reason
+ end.
+
+unique(PreName) ->
+ list_to_atom(?F("~w_~w", [PreName, erlang:system_time(millisecond)])).
do_size_check(Config) ->
- ?DBG("do_size_check -> start with"
- "~n Config: ~p", [Config]),
+ ?IPRINT("do_size_check -> start with"
+ "~n Config: ~p", [Config]),
Prio = normal,
Verbosity = trace,
@@ -404,7 +457,7 @@ do_size_check(Config) ->
?DBG("do_size_check -> stop symbolic store", []),
?line sym_stop(),
- ?DBG("do_size_check -> done", []),
+ ?IPRINT("do_size_check -> done", []),
ok.
@@ -635,7 +688,7 @@ mnesia_start(Opts, Nodes) ->
%% We can accept mnesia beeing loaded but *not* started.
%% If its started it *may* contain data that will invalidate
%% this test case.
- ?PRINT2("mnesia_start -> try load mnesia when:"
+ ?IPRINT("mnesia_start -> try load mnesia when:"
"~n Loaded: ~p"
"~n Running: ~p", [apps_loaded(), apps_running()]),
?line ok = case application:load(mnesia) of
@@ -647,12 +700,12 @@ mnesia_start(Opts, Nodes) ->
ERROR
end,
F = fun({Key, Val}) ->
- ?PRINT2("mnesia_start -> try set mnesia env: "
+ ?IPRINT("mnesia_start -> try set mnesia env: "
"~n ~p -> ~p", [Key, Val]),
?line application_controller:set_env(mnesia, Key, Val)
end,
lists:foreach(F, Opts),
- ?PRINT2("mnesia_start -> create mnesia schema on ~p", [Nodes]),
+ ?IPRINT("mnesia_start -> create mnesia schema on ~p", [Nodes]),
?line case mnesia:create_schema(Nodes) of
ok ->
ok;
@@ -662,7 +715,7 @@ mnesia_start(Opts, Nodes) ->
throw({skip,
?F("Failed create mnesia schema: ~p", [SchemaReason])})
end,
- ?PRINT2("mnesia_start -> start mnesia", []),
+ ?IPRINT("mnesia_start -> start mnesia", []),
?line case application:start(mnesia) of
ok ->
ok;
@@ -672,19 +725,19 @@ mnesia_start(Opts, Nodes) ->
throw({skip,
?F("Failed starting mnesia: ~p", [StartReason])})
end,
- ?PRINT2("mnesia_start -> mnesia started", []),
+ ?IPRINT("mnesia_start -> mnesia started", []),
ok.
mnesia_stop() ->
- ?PRINT2("mnesia_stop -> try stop mnesia when:"
+ ?IPRINT("mnesia_stop -> try stop mnesia when:"
"~n Loaded: ~p"
"~n Running: ~p", [apps_loaded(), apps_running()]),
application:stop(mnesia),
- ?PRINT2("mnesia_stop -> try unload mnesia when"
+ ?IPRINT("mnesia_stop -> try unload mnesia when"
"~n Loaded: ~p"
"~n Running: ~p", [apps_loaded(), apps_running()]),
application:unload(mnesia),
- ?PRINT2("mnesia_stop -> done when:"
+ ?IPRINT("mnesia_stop -> done when:"
"~n Loaded: ~p"
"~n Running: ~p", [apps_loaded(), apps_running()]),
ok.
@@ -856,19 +909,19 @@ display_memory_usage(MibsPid) ->
MibDbSize = key1search([db_memory,mib], MibsInfo),
NodeDbSize = key1search([db_memory,node], MibsInfo),
TreeDbSize = key1search([db_memory,tree], MibsInfo),
- ?INF("Symbolic store memory usage: "
- "~n Process memory size: ~p"
- "~n Db size: ~p"
- "~n"
- "~nMib server memory usage: "
- "~n Tree size: ~p"
- "~n Process memory size: ~p"
- "~n Mib db size: ~p"
- "~n Node db size: ~p"
- "~n Tree db size: ~p"
- "~n",
- [SymProcSize, DbSize,
- TreeSize, MibsProcMem, MibDbSize, NodeDbSize, TreeDbSize]).
+ ?IPRINT("Symbolic store memory usage: "
+ "~n Process memory size: ~p"
+ "~n Db size: ~p"
+ "~n"
+ "~nMib server memory usage: "
+ "~n Tree size: ~p"
+ "~n Process memory size: ~p"
+ "~n Mib db size: ~p"
+ "~n Node db size: ~p"
+ "~n Tree db size: ~p"
+ "~n",
+ [SymProcSize, DbSize,
+ TreeSize, MibsProcMem, MibDbSize, NodeDbSize, TreeDbSize]).
key1search([], Res) ->
Res;
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 5dc544d1a7..6a4c582f36 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2020. 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.
@@ -122,8 +122,8 @@
init_all(Config) when is_list(Config) ->
- ?LOG("init_all -> entry with"
- "~n Config: ~p",[Config]),
+ ?IPRINT("init_all -> entry with"
+ "~n Config: ~p",[Config]),
%% --
%% Start nodes
@@ -300,7 +300,7 @@ try_test(TcRunMod, TcRunFunc, TcRunArgs, TcRunOpts) ->
%% process as well.
tc_try(N, M, F, A) ->
- ?PRINT2("tc_try -> entry with"
+ ?IPRINT("tc_try -> entry with"
"~n N: ~p"
"~n M: ~p"
"~n F: ~p"
@@ -312,32 +312,32 @@ tc_try(N, M, F, A) ->
get()]),
case net_adm:ping(N) of
pong ->
- ?PRINT2("tc_try -> ~p still running - start runner~n", [N]),
+ ?IPRINT("tc_try -> ~p still running - start runner~n", [N]),
OldFlag = trap_exit(true), % Make sure we catch it
Runner = spawn_link(N, ?MODULE, tc_wait, [self(), get(), M, F, A]),
await_tc_runner_started(Runner, OldFlag),
await_tc_runner_done(Runner, OldFlag);
pang ->
- ?EPRINT2("tc_try -> ~p *not* running~n", [N]),
+ ?WPRINT("tc_try -> ~p *not* running~n", [N]),
skip({node_not_running, N})
end.
await_tc_runner_started(Runner, OldFlag) ->
- ?PRINT2("await tc-runner (~p) start ack~n", [Runner]),
+ ?IPRINT("await tc-runner (~p) start ack~n", [Runner]),
receive
{'EXIT', Runner, Reason} ->
- ?EPRINT2("TC runner start failed: "
- "~n ~p~n", [Reason]),
+ ?EPRINT("TC runner start failed: "
+ "~n ~p~n", [Reason]),
exit({tx_runner_start_failed, Reason});
{tc_runner_started, Runner} ->
- ?PRINT2("TC runner start acknowledged~n"),
+ ?IPRINT("TC runner start acknowledged~n"),
ok
after 10000 -> %% We should *really* not have to wait this long, but...
trap_exit(OldFlag),
unlink_and_flush_exit(Runner),
- RunnerInfo = process_info(Runner),
- ?EPRINT2("TC runner start timeout: "
- "~n ~p", [RunnerInfo]),
+ RunnerInfo = ?PINFO(Runner),
+ ?EPRINT("TC runner start timeout: "
+ "~n ~p", [RunnerInfo]),
%% If we don't get a start ack within 10 seconds, we are f*ed
exit(Runner, kill),
exit({tc_runner_start, timeout, RunnerInfo})
@@ -352,18 +352,18 @@ await_tc_runner_done(Runner, OldFlag) ->
SysEvs = snmp_test_global_sys_monitor:events(),
if
(SysEvs =:= []) ->
- ?EPRINT2("TC runner failed: "
- "~n ~p~n", [Reason]),
+ ?EPRINT("TC runner failed: "
+ "~n ~p~n", [Reason]),
exit({tx_runner_failed, Reason});
true ->
- ?EPRINT2("TC runner failed when we got system events: "
- "~n Reason: ~p"
- "~n Sys Events: ~p"
- "~n", [Reason, SysEvs]),
+ ?WPRINT("TC runner failed when we got system events: "
+ "~n Reason: ~p"
+ "~n Sys Events: ~p"
+ "~n", [Reason, SysEvs]),
skip([{reason, Reason}, {system_events, SysEvs}])
end;
{tc_runner_done, Runner, {'EXIT', {skip, Reason}}, Loc} ->
- ?PRINT2("call -> done with skip: "
+ ?WPRINT("call -> done with skip: "
"~n Reason: ~p"
"~n Loc: ~p"
"~n", [Reason, Loc]),
@@ -372,7 +372,7 @@ await_tc_runner_done(Runner, OldFlag) ->
put(test_server_loc, Loc),
skip(Reason);
{tc_runner_done, Runner, {'EXIT', Rn}, Loc} ->
- ?PRINT2("call -> done with exit: "
+ ?EPRINT("call -> done with exit: "
"~n Rn: ~p"
"~n Loc: ~p"
"~n", [Rn, Loc]),
@@ -409,7 +409,7 @@ unlink_and_flush_exit(Pid) ->
end.
tc_wait(From, Env, M, F, A) ->
- ?PRINT2("tc_wait -> entry with"
+ ?IPRINT("tc_wait -> entry with"
"~n From: ~p"
"~n Env: ~p"
"~n M: ~p"
@@ -417,9 +417,9 @@ tc_wait(From, Env, M, F, A) ->
"~n A: ~p", [From, Env, M, F, A]),
From ! {tc_runner_started, self()},
lists:foreach(fun({K,V}) -> put(K,V) end, Env),
- ?PRINT2("tc_wait -> env set - now run tc~n"),
+ ?IPRINT("tc_wait -> env set - now run tc~n"),
Res = (catch apply(M, F, A)),
- ?PRINT2("tc_wait -> tc run done: "
+ ?IPRINT("tc_wait -> tc run done: "
"~n ~p"
"~n", [Res]),
From ! {tc_runner_done, self(), Res, get(test_server_loc)},
@@ -437,7 +437,7 @@ tc_wait(From, Env, M, F, A) ->
end.
tc_run(Mod, Func, Args, Opts) ->
- ?PRINT2("tc_run -> entry with"
+ ?IPRINT("tc_run -> entry with"
"~n Mod: ~p"
"~n Func: ~p"
"~n Args: ~p"
@@ -456,7 +456,7 @@ tc_run(Mod, Func, Args, Opts) ->
?DBG("tc_run -> Crypto: ~p", [_CryptoRes]),
StdM = join(code:priv_dir(snmp), "mibs") ++ "/",
Vsn = get(vsn),
- ?PRINT2("tc_run -> config:"
+ ?IPRINT("tc_run -> config:"
"~n M: ~p"
"~n Vsn: ~p"
"~n Dir: ~p"
@@ -469,7 +469,7 @@ tc_run(Mod, Func, Args, Opts) ->
"~n", [M,Vsn,Dir,User,SecLevel,EngineID,CtxEngineID,Community,StdM]),
case snmp_test_mgr:start([%% {agent, snmp_test_lib:hostname()},
{packet_server_debug, true},
- {debug, true},
+ {debug, false},
{agent, get(master_host)},
{ipfamily, get(ipfamily)},
{agent_udp, 4000},
@@ -487,7 +487,7 @@ tc_run(Mod, Func, Args, Opts) ->
{ok, _Pid} ->
case (catch apply(Mod, Func, Args)) of
{'EXIT', {skip, Reason}} ->
- ?EPRINT2("apply skip detected: "
+ ?WPRINT("apply skip detected: "
"~n ~p", [Reason]),
(catch snmp_test_mgr:stop()),
?SKIP(Reason);
@@ -500,11 +500,11 @@ tc_run(Mod, Func, Args, Opts) ->
(catch snmp_test_mgr:stop()),
if
(SysEvs =:= []) ->
- ?EPRINT2("TC runner failed: "
- "~n ~p~n", [Reason]),
+ ?EPRINT("TC runner failed: "
+ "~n ~p~n", [Reason]),
?FAIL({apply_failed, {Mod, Func, Args}, Reason});
true ->
- ?EPRINT2("apply exit catched when we got system events: "
+ ?WPRINT("apply exit catched when we got system events: "
"~n Reason: ~p"
"~n Sys Events: ~p"
"~n", [Reason, SysEvs]),
@@ -516,14 +516,14 @@ tc_run(Mod, Func, Args, Opts) ->
end;
{error, Reason} ->
- ?EPRINT2("Failed starting (test) manager: "
- "~n ~p", [Reason]),
+ ?EPRINT("Failed starting (test) manager: "
+ "~n ~p", [Reason]),
(catch snmp_test_mgr:stop()),
?line ?FAIL({mgr_start_error, Reason});
Err ->
- ?EPRINT2("Failed starting (test) manager: "
- "~n ~p", [Err]),
+ ?EPRINT("Failed starting (test) manager: "
+ "~n ~p", [Err]),
(catch snmp_test_mgr:stop()),
?line ?FAIL({mgr_start_failure, Err})
end.
@@ -570,10 +570,10 @@ start_agent(Config, Vsns) ->
start_agent(Config, Vsns, []).
start_agent(Config, Vsns, Opts) ->
- ?LOG("start_agent -> entry (~p) with"
- "~n Config: ~p"
- "~n Vsns: ~p"
- "~n Opts: ~p", [node(), Config, Vsns, Opts]),
+ ?IPRINT("start_agent -> entry (~p) with"
+ "~n Config: ~p"
+ "~n Vsns: ~p"
+ "~n Opts: ~p", [node(), Config, Vsns, Opts]),
?line AgentLogDir = ?config(agent_log_dir, Config),
?line AgentConfDir = ?config(agent_conf_dir, Config),
@@ -603,17 +603,17 @@ start_agent(Config, Vsns, Opts) ->
process_flag(trap_exit,true),
- ?PRINT2("start_agent -> try start snmp app supervisor", []),
+ ?IPRINT("start_agent -> try start snmp app supervisor", []),
{ok, AppSup} = snmp_app_sup:start_link(),
unlink(AppSup),
?DBG("start_agent -> snmp app supervisor: ~p", [AppSup]),
- ?PRINT2("start_agent -> try start master agent",[]),
+ ?IPRINT("start_agent -> try start master agent",[]),
?line Sup = start_sup(Env),
?line unlink(Sup),
?DBG("start_agent -> snmp supervisor: ~p", [Sup]),
- ?PRINT2("start_agent -> try (rpc) start sub agent on ~p", [SaNode]),
+ ?IPRINT("start_agent -> try (rpc) start sub agent on ~p", [SaNode]),
?line SaDir = ?config(sa_dir, Config),
?line {ok, Sub} = start_sub_sup(SaNode, SaDir),
?DBG("start_agent -> done", []),
@@ -813,36 +813,33 @@ merge_agent_options([{Key, _Value} = Opt|Opts], Options) ->
stop_agent(Config) when is_list(Config) ->
- ?PRINT2("stop_agent -> entry with"
+ ?IPRINT("stop_agent -> entry with"
"~n Config: ~p",[Config]),
%% Stop the sub-agent (the agent supervisor)
{SubSup, SubPar} = ?config(snmp_sub, Config),
- ?PRINT2("stop_agent -> attempt to stop sub agent (~p)"
+ ?IPRINT("stop_agent -> attempt to stop sub agent (~p)"
"~n Sub Sup info: "
"~n ~p"
"~n Sub Par info: "
"~n ~p",
- [SubSup,
- (catch process_info(SubSup)),
- (catch process_info(SubPar))]),
+ [SubSup, ?PINFO(SubSup), ?PINFO(SubPar)]),
stop_sup(SubSup, SubPar),
Config2 = lists:keydelete(snmp_sub, 1, Config),
%% Stop the master-agent (the top agent supervisor)
{MasterSup, MasterPar} = ?config(snmp_sup, Config),
- ?PRINT2("stop_agent -> attempt to stop master agent (~p)"
+ ?IPRINT("stop_agent -> attempt to stop master agent (~p)"
"~n Master Sup: "
"~n ~p"
"~n Master Par: "
"~n ~p"
"~n Agent Info: "
"~n ~p",
- [MasterSup,
- (catch process_info(MasterSup)),
- (catch process_info(MasterPar)),
+ [MasterSup,
+ ?PINFO(MasterSup), ?PINFO(MasterPar),
agent_info(MasterSup)]),
stop_sup(MasterSup, MasterPar),
Config3 = lists:keydelete(snmp_sup, 1, Config2),
@@ -850,25 +847,24 @@ stop_agent(Config) when is_list(Config) ->
%% Stop the top supervisor (of the snmp app)
AppSup = ?config(snmp_app_sup, Config),
- ?PRINT2("stop_agent -> attempt to app sup ~p"
+ ?IPRINT("stop_agent -> attempt to app sup ~p"
"~n App Sup: ~p",
- [AppSup,
- (catch process_info(AppSup))]),
+ [AppSup, ?PINFO(AppSup)]),
Config4 = lists:keydelete(snmp_app_sup, 1, Config3),
- ?PRINT2("stop_agent -> done", []),
+ ?IPRINT("stop_agent -> done", []),
Config4.
start_sup(Env) ->
case (catch snmp_app_sup:start_agent(normal, Env)) of
{ok, S} ->
- ?DBG("start_agent -> started, Sup: ~p",[S]),
+ ?DBG("start_agent -> started, Sup: ~p", [S]),
S;
Else ->
- ?DBG("start_agent -> unknown result: ~n~p",[Else]),
+ ?EPRINT("start_agent -> unknown result: ~n~p", [Else]),
%% Get info about the apps we depend on
?FAIL({start_failed, Else, ?IS_MNESIA_RUNNING()})
end.
@@ -876,18 +872,18 @@ start_sup(Env) ->
stop_sup(Pid, _) when (node(Pid) =:= node()) ->
case (catch process_info(Pid)) of
PI when is_list(PI) ->
- ?LOG("stop_sup -> attempt to stop ~p", [Pid]),
+ ?IPRINT("stop_sup -> attempt to stop ~p", [Pid]),
Ref = erlang:monitor(process, Pid),
exit(Pid, kill),
await_stopped(Pid, Ref);
{'EXIT', _Reason} ->
- ?LOG("stop_sup -> ~p not running", [Pid]),
+ ?IPRINT("stop_sup -> ~p not running", [Pid]),
ok
end;
stop_sup(Pid, _) ->
- ?LOG("stop_sup -> attempt to stop ~p", [Pid]),
+ ?IPRINT("stop_sup -> attempt to stop ~p", [Pid]),
Ref = erlang:monitor(process, Pid),
- ?LOG("stop_sup -> Ref: ~p", [Ref]),
+ ?IPRINT("stop_sup -> Ref: ~p", [Ref]),
exit(Pid, kill),
await_stopped(Pid, Ref).
@@ -897,7 +893,7 @@ await_stopped(Pid, Ref) ->
?DBG("received down message for ~p", [Pid]),
ok
after 10000 ->
- ?INF("await_stopped -> timeout for ~p",[Pid]),
+ ?EPRINT("await_stopped -> timeout for ~p",[Pid]),
erlang:demonitor(Ref),
?FAIL({failed_stop,Pid})
end.
@@ -1076,7 +1072,7 @@ io_format_expect(F) ->
io_format_expect(F, []).
io_format_expect(F, A) ->
- ?PRINT2("EXPECT " ++ F, A).
+ ?IPRINT("EXPECT " ++ F, A).
do_expect(Expect) when is_atom(Expect) ->
@@ -1529,11 +1525,11 @@ get_next_req(Vars) ->
%% --- start and stop nodes ---
start_node(Name) ->
- ?LOG("start_node -> entry with"
- "~n Name: ~p"
- "~n when"
- "~n hostname of this node: ~p",
- [Name, list_to_atom(?HOSTNAME(node()))]),
+ ?IPRINT("start_node -> entry with"
+ "~n Name: ~p"
+ "~n when"
+ "~n hostname of this node: ~p",
+ [Name, list_to_atom(?HOSTNAME(node()))]),
Pa = filename:dirname(code:which(?MODULE)),
?DBG("start_node -> Pa: ~p", [Pa]),
@@ -1547,19 +1543,19 @@ start_node(Name) ->
global:sync(),
{ok, Node};
{error, Reason} ->
- ?ERR("start_node -> failed starting node ~p:"
- "~n Reason: ~p", [Name, Reason]),
+ ?WPRINT("start_node -> failed starting node ~p:"
+ "~n Reason: ~p", [Name, Reason]),
?line ?SKIP({failed_start_node, Reason});
Else ->
- ?ERR("start_node -> failed starting node ~p:"
- "~n ~p", [Name, Else]),
+ ?EPRINT("start_node -> failed starting node ~p:"
+ "~n ~p", [Name, Else]),
?line ?FAIL(Else)
end.
stop_node(Node) ->
- ?LOG("stop_node -> Node: ~p", [Node]),
- rpc:cast(Node, erlang, halt, []).
+ ?IPRINT("stop_node -> Node: ~p", [Node]),
+ ?STOP_NODE(Node).
%%%-----------------------------------------------------------------
@@ -1570,14 +1566,14 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp) ->
config(Vsns, MgrDir, AgentConfDir, MIp, AIp, inet).
config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) ->
- ?LOG("config -> entry with"
- "~n Vsns: ~p"
- "~n MgrDir: ~p"
- "~n AgentConfDir: ~p"
- "~n MIp: ~p"
- "~n AIp: ~p"
- "~n IpFamily: ~p",
- [Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily]),
+ ?IPRINT("config -> entry with"
+ "~n Vsns: ~p"
+ "~n MgrDir: ~p"
+ "~n AgentConfDir: ~p"
+ "~n MIp: ~p"
+ "~n AIp: ~p"
+ "~n IpFamily: ~p",
+ [Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily]),
?line {Domain, ManagerAddr} =
case IpFamily of
inet6 ->
@@ -1748,8 +1744,8 @@ rewrite_target_addr_conf(Dir, NewPort) ->
{ok, _} ->
ok;
{error, _R} ->
- ?ERR("failure reading file info of "
- "target address config file: ~p", [_R]),
+ ?WPRINT("failure reading file info of "
+ "target address config file: ~p", [_R]),
ok
end,
@@ -1773,10 +1769,10 @@ rewrite_target_addr_conf_check(O) ->
rewrite_target_addr_conf2(NewPort,
{Name, Ip, _Port, Timeout, Retry,
"std_trap", EngineId}) ->
- ?LOG("rewrite_target_addr_conf2 -> entry with std_trap",[]),
+ ?IPRINT("rewrite_target_addr_conf2 -> entry with std_trap",[]),
{Name,Ip,NewPort,Timeout,Retry,"std_trap",EngineId};
rewrite_target_addr_conf2(_NewPort,O) ->
- ?LOG("rewrite_target_addr_conf2 -> entry with "
+ ?IPRINT("rewrite_target_addr_conf2 -> entry with "
"~n O: ~p",[O]),
O.
@@ -1830,12 +1826,12 @@ display_memory_usage() ->
MibDbSize = key1search([db_memory,mib], Info),
NodeDbSize = key1search([db_memory,node], Info),
TreeDbSize = key1search([db_memory,tree], Info),
- ?INF("Memory usage: "
- "~n Tree size: ~p"
- "~n Process memory size: ~p"
- "~n Mib db size: ~p"
- "~n Node db size: ~p"
- "~n Tree db size: ~p",
+ ?IPRINT("Memory usage: "
+ "~n Tree size: ~p"
+ "~n Process memory size: ~p"
+ "~n Mib db size: ~p"
+ "~n Node db size: ~p"
+ "~n Tree db size: ~p",
[TreeSize, ProcMem, MibDbSize, NodeDbSize, TreeDbSize]).
key1search([], Res) ->
@@ -1871,51 +1867,3 @@ join(Dir, File) ->
skip(R) ->
exit({skip, R}).
-%% await_pdu(To) ->
-%% await_response(To, pdu).
-%%
-%% await_trap(To) ->
-%% await_response(To, trap).
-%%
-%% await_any(To) ->
-%% await_response(To, any).
-%%
-%%
-%% await_response(To, What) ->
-%% await_response(To, What, []).
-%%
-%% await_response(To, What, Stuff) when is_integer(To) andalso (To >= 0) ->
-%% T = t(),
-%% receive
-%% {snmp_pdu, PDU} when is_record(Trap, pdu) andalso (What =:= pdu) ->
-%% {ok, PDU};
-%% {snmp_pdu, Trap} is_when record(Trap, trappdu) andalso (What =:= trap) ->
-%% {ok, Trap};
-%% Any when What =:= any ->
-%% {ok, Any};
-%% Any ->
-%% %% Recalc time
-%% NewTo = To - (t() - T)
-%% await_reponse(NewTo, What, [{NewTo, Any}|Stuff])
-%% after To ->
-%% {error, {timeout, Stuff}}
-%% end;
-%% await_response(_, Stuff) ->
-%% {error, {timeout, Stuff}}.
-%%
-%%
-%% t() ->
-%% {A,B,C} = os:timestamp(),
-%% A*1000000000+B*1000+(C div 1000).
-%%
-%%
-%% timeout() ->
-%% timeout(os:type()).
-%%
-%% timeout(_) -> 3500.
-
-
-%% Time in milli seconds
-%% t() ->
-%% {A,B,C} = os:timestamp(),
-%% A*1000000000+B*1000+(C div 1000).
diff --git a/lib/snmp/test/snmp_compiler_SUITE.erl b/lib/snmp/test/snmp_compiler_SUITE.erl
index aeb055742e..f4ba914919 100644
--- a/lib/snmp/test/snmp_compiler_SUITE.erl
+++ b/lib/snmp/test/snmp_compiler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -106,26 +106,48 @@ tickets_cases() ->
init_per_suite(Config0) when is_list(Config0) ->
- ?DBG("init_per_suite -> entry with"
- "~n Config0: ~p", [Config0]),
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p", [Config0, erlang:nodes()]),
- Config1 = snmp_test_lib:init_suite_top_dir(?MODULE, Config0),
- Config2 = snmp_test_lib:fix_data_dir(Config1),
+ case ?LIB:init_per_suite(Config0) of
+ {skip, _} = SKIP ->
+ SKIP;
- %% Mib-dirs
- %% data_dir is trashed by the test-server / common-test
- %% so there is no point in fixing it...
- MibDir = snmp_test_lib:lookup(data_dir, Config2),
- StdMibDir = filename:join([code:priv_dir(snmp), "mibs"]),
+ Config1 when is_list(Config1) ->
+ Config2 = snmp_test_lib:init_suite_top_dir(?MODULE, Config1),
+ Config3 = snmp_test_lib:fix_data_dir(Config2),
- [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config2].
+ %% Mib-dirs
+ %% data_dir is trashed by the test-server / common-test
+ %% so there is no point in fixing it...
+ MibDir = snmp_test_lib:lookup(data_dir, Config3),
+ StdMibDir = filename:join([code:priv_dir(snmp), "mibs"]),
-end_per_suite(Config) when is_list(Config) ->
+ Config4 = [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config3],
+
+ %% We need a monitor on this node also
+ snmp_test_sys_monitor:start(),
- ?DBG("end_per_suite -> entry with"
- "~n Config: ~p", [Config]),
+ snmp_test_mgr_counter_server:start(),
- Config.
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config: ~p", [Config4]),
+
+ Config4
+ end.
+
+
+end_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
+
+ snmp_test_sys_monitor:stop(),
+ Config1 = ?LIB:end_per_suite(Config0),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
%%
@@ -165,7 +187,8 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
description(suite) -> [];
description(Config) when is_list(Config) ->
put(tname,desc),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
Filename = join(Dir,"test"),
@@ -179,14 +202,14 @@ description(Config) when is_list(Config) ->
{warnings, false},
{description, false}]),
MIB1 = read_mib(MibBinName),
- %% io:format("description -> MIB1: ~n~p~n", [MIB1]),
+ %% ?IPRINT("description -> MIB1: ~n~p~n", [MIB1]),
check_mib(MIB1#mib.mes, Oid, undefined),
?line {ok,_} = snmpc:compile(MibSrcName, [{outdir, Dir},
{group_check, false},
{warnings, false},
{description, true}]),
MIB2 = read_mib(MibBinName),
- %% io:format("description -> MIB2: ~n~p~n", [MIB2]),
+ %% ?IPRINT("description -> MIB2: ~n~p~n", [MIB2]),
check_mib(MIB2#mib.mes, Oid, Desctext),
%% Cleanup
@@ -200,7 +223,8 @@ description(Config) when is_list(Config) ->
oid_conflicts(suite) -> [];
oid_conflicts(Config) when is_list(Config) ->
put(tname,oid_conflicts),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
Mib = join(Dir,"TESTv2.mib"),
@@ -232,7 +256,8 @@ agent_capabilities(suite) ->
[];
agent_capabilities(Config) when is_list(Config) ->
put(tname,agent_capabilities),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
SnmpPrivDir = which_priv_dir(snmp),
SnmpMibsDir = join(SnmpPrivDir, "mibs"),
@@ -253,11 +278,10 @@ agent_capabilities(Config) when is_list(Config) ->
?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
%% This is a rather pathetic test, but it is somthing...
- io:format("agent_capabilities -> "
- "~n MEDiff: ~p"
- "~n Mib1: ~p"
- "~n Mib2: ~p"
- "~n", [MEDiff, Mib1, Mib2]),
+ ?IPRINT("agent_capabilities -> "
+ "~n MEDiff: ~p"
+ "~n Mib1: ~p"
+ "~n Mib2: ~p", [MEDiff, Mib1, Mib2]),
case length(MEDiff) of
2 ->
ok;
@@ -272,8 +296,9 @@ agent_capabilities(Config) when is_list(Config) ->
module_compliance(suite) ->
[];
module_compliance(Config) when is_list(Config) ->
- put(tname,module_compliance),
- p("starting with Config: ~p~n", [Config]),
+ put(tname, module_compliance),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
SnmpPrivDir = which_priv_dir(snmp),
SnmpMibsDir = join(SnmpPrivDir, "mibs"),
@@ -294,11 +319,10 @@ module_compliance(Config) when is_list(Config) ->
?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
%% This is a rather pathetic test, but it is somthing...
- io:format("module_compliance -> "
- "~n MEDiff: ~p"
- "~n Mib1: ~p"
- "~n Mib2: ~p"
- "~n", [MEDiff, Mib1, Mib2]),
+ ?IPRINT("module_compliance -> "
+ "~n MEDiff: ~p"
+ "~n Mib1: ~p"
+ "~n Mib2: ~p", [MEDiff, Mib1, Mib2]),
case length(MEDiff) of
1 ->
ok;
@@ -314,7 +338,8 @@ warnings_as_errors(suite) ->
["OTP-9437"];
warnings_as_errors(Config) when is_list(Config) ->
put(tname,warnings_as_errors),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
MibFile = join(MibDir, "OTP8574-MIB.mib"),
@@ -338,14 +363,16 @@ otp_6150(suite) ->
[];
otp_6150(Config) when is_list(Config) ->
put(tname, otp6150),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
MibFile = join(MibDir, "ERICSSON-TOP-MIB.mib"),
?line {ok, Mib} =
snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
- io:format("otp_6150 -> Mib: ~n~p~n", [Mib]),
+ ?IPRINT("otp_6150 -> Mib: "
+ "~n ~p", [Mib]),
ok.
@@ -355,29 +382,30 @@ otp_8574(suite) ->
[];
otp_8574(Config) when is_list(Config) ->
put(tname, otp8574),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
MibFile = join(MibDir, "OTP8574-MIB.mib"),
- p("ensure compile fail without relaxed assign check"),
+ ?IPRINT("ensure compile fail without relaxed assign check"),
case snmpc:compile(MibFile, [{group_check, false}, {outdir, Dir}]) of
{error, compilation_failed} ->
- p("with relaxed assign check MIB compiles with warning"),
+ ?IPRINT("with relaxed assign check MIB compiles with warning"),
case snmpc:compile(MibFile, [{group_check, false},
{outdir, Dir},
relaxed_row_name_assign_check]) of
{ok, _Mib} ->
ok;
{error, Reason} ->
- p("unexpected compile failure: "
- "~n Reason: ~p", [Reason]),
+ ?EPRINT("unexpected compile failure: "
+ "~n Reason: ~p", [Reason]),
exit({unexpected_compile_failure, Reason})
end;
{ok, _} ->
- p("unexpected compile success"),
+ ?EPRINT("unexpected compile success"),
exit(unexpected_compile_success)
end.
@@ -388,7 +416,8 @@ otp_8595(suite) ->
[];
otp_8595(Config) when is_list(Config) ->
put(tname, otp8595),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
@@ -397,7 +426,7 @@ otp_8595(Config) when is_list(Config) ->
snmpc:compile(MibFile, [{outdir, Dir},
{verbosity, trace},
{group_check, false}]),
- p("Mib: ~n~p~n", [Mib]),
+ ?IPRINT("Mib: ~n~p~n", [Mib]),
ok.
@@ -407,14 +436,16 @@ otp_10799(suite) ->
[];
otp_10799(Config) when is_list(Config) ->
put(tname, otp10799),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
MibFile = join(MibDir, "OTP10799-MIB.mib"),
?line {ok, Mib} =
snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
- p("Mib: ~n~p~n", [Mib]),
+ ?IPRINT("Mib: "
+ "~n ~p", [Mib]),
ok.
@@ -424,7 +455,8 @@ otp_10808(suite) ->
[];
otp_10808(Config) when is_list(Config) ->
put(tname, otp10808),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
@@ -433,7 +465,8 @@ otp_10808(Config) when is_list(Config) ->
snmpc:compile(MibFile, [{outdir, Dir},
{verbosity, trace},
{group_check, false}]),
- p("Mib: ~n~p~n", [Mib]),
+ ?IPRINT("Mib: "
+ "~n ~p", [Mib]),
ok.
@@ -443,7 +476,8 @@ otp_14145(suite) ->
[];
otp_14145(Config) when is_list(Config) ->
put(tname, otp14145),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
@@ -454,7 +488,8 @@ otp_14145(Config) when is_list(Config) ->
{verbosity, trace},
{group_check, false},
module_compliance]),
- p("Mib: ~n~p~n", [MibBin]),
+ ?IPRINT("Mib: "
+ "~n ~p", [MibBin]),
MIB = read_mib(MibBin),
Oid = [1,3,6,1,2,1,67,4],
check_mib(MIB#mib.mes, Oid, undefined),
@@ -467,7 +502,8 @@ otp_13014(suite) ->
[];
otp_13014(Config) when is_list(Config) ->
put(tname, otp13014),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
@@ -478,7 +514,8 @@ otp_13014(Config) when is_list(Config) ->
{verbosity, log},
{group_check, false},
module_compliance]),
- p("Mib: ~n~p~n", [MibBin]),
+ ?IPRINT("Mib: "
+ "~n ~p", [MibBin]),
#mib{mes = MEs} = read_mib(MibBin),
Oid = [1,0,8802,1,1,2,1,1,7],
#me{
@@ -494,20 +531,23 @@ otp_13014(Config) when is_list(Config) ->
TableInfo,
ok.
+
%%======================================================================
otp_14196(suite) ->
[];
otp_14196(Config) when is_list(Config) ->
put(tname, otp14196),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
MibFile = join(MibDir, "OTP14196-MIB.mib"),
?line {ok, Mib} =
snmpc:compile(MibFile, [{outdir, Dir}, {verbosity, trace}]),
- p("Mib: ~n~p~n", [Mib]),
+ ?IPRINT("Mib: "
+ "~n ~p", [Mib]),
ok.
@@ -517,7 +557,8 @@ augments_extra_info(suite) ->
[];
augments_extra_info(Config) when is_list(Config) ->
put(tname, augments_extra_info),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Dir = ?config(case_top_dir, Config),
MibDir = ?config(mib_dir, Config),
@@ -527,28 +568,30 @@ augments_extra_info(Config) when is_list(Config) ->
snmpc:compile(Test2File, [{outdir, Dir},
{verbosity, silence},
{group_check, false}]),
- io:format("Test2BinFile: ~n~p~n", [Test2BinFile]),
+ ?IPRINT("Test2BinFile: "
+ "~n ~p", [Test2BinFile]),
?line {ok, Test3BinFile} =
snmpc:compile(Test3File, [{i, [MibDir]},
{outdir, Dir},
{verbosity, silence},
{group_check, true}]),
- io:format("Test3BinFile: ~n~p~n", [Test3BinFile]),
+ ?IPRINT("Test3BinFile: "
+ "~n ~p", [Test3BinFile]),
{ok, Test3Mib} = snmp_misc:read_mib(Test3BinFile),
- io:format("Test3Mib: ~n~p~n", [Test3Mib]),
+ ?IPRINT("Test3Mib: "
+ "~n ~p", [Test3Mib]),
%% There is only one table in this mib
#mib{table_infos = [{TableName, TI}]} = Test3Mib,
- io:format("TableName: ~p"
- "~n Table Info: ~p"
- "~n", [TableName, TI]),
+ ?IPRINT("TableName: ~p"
+ "~n Table Info: ~p", [TableName, TI]),
#table_info{nbr_of_cols = 4,
defvals = DefVals,
not_accessible = [2,4],
index_types = {augments, {tEntry, undefined}},
first_accessible = 1} = TI,
- io:format("Table info: ~p"
- "~n DefVals: ~p"
- "~n", [TableName, DefVals]),
+ ?IPRINT("Table info: ~p"
+ "~n DefVals: ~p"
+ "~n", [TableName, DefVals]),
ok.
@@ -750,21 +793,3 @@ which_priv_dir(App) ->
join(A,B) ->
filename:join(A,B).
-
-%% ------
-
-%% p(F) ->
-%% p(F, []).
-
-p(F) ->
- p(F, []).
-
-p(F, A) ->
- p(get(tname), F, A).
-
-p(TName, F, A) ->
- io:format("*** [~w][~s] ***"
- "~n" ++ F ++ "~n", [TName, formated_timestamp()|A]).
-
-formated_timestamp() ->
- snmp_test_lib:formated_timestamp().
diff --git a/lib/snmp/test/snmp_conf_SUITE.erl b/lib/snmp/test/snmp_conf_SUITE.erl
index bd8375b400..7d60485060 100644
--- a/lib/snmp/test/snmp_conf_SUITE.erl
+++ b/lib/snmp/test/snmp_conf_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -97,11 +97,34 @@ groups() ->
%% -----
%%
-init_per_suite(Config) when is_list(Config) ->
- Config.
+init_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
-end_per_suite(Config) when is_list(Config) ->
- Config.
+ case ?LIB:init_per_suite(Config0) of
+ {skip, _} = SKIP ->
+ SKIP;
+
+ Config1 when is_list(Config1) ->
+ %% We need a monitor on this node also
+ snmp_test_sys_monitor:start(),
+
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config: ~p", [Config1]),
+
+ Config1
+ end.
+
+end_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
+
+ snmp_test_sys_monitor:stop(),
+ Config1 = ?LIB:end_per_suite(Config0),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
@@ -136,7 +159,7 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
check_mandatory(suite) -> [];
check_mandatory(Config) when is_list(Config) ->
?P(check_mandatory),
- %% d("check_mandatory -> entry"),
+ %% ?IPRINT("check_mandatory -> entry"),
A1 = [{a, hej}, {b, hopp}, {c, 10}, {d, 10101}, {f, 10.88}],
B1 = [{a, {value, hejsan}},
{b, mandatory},
@@ -696,8 +719,3 @@ read_files(Config) when is_list(Config) ->
%% Internal functions
%%======================================================================
-% d(F) ->
-% d(F, []).
-
-% d(F, A) ->
-% io:format("~w:" ++ F ++ "~n", [?MODULE|A]).
diff --git a/lib/snmp/test/snmp_log_SUITE.erl b/lib/snmp/test/snmp_log_SUITE.erl
index 01a1d9ce8c..b63c9e3b34 100644
--- a/lib/snmp/test/snmp_log_SUITE.erl
+++ b/lib/snmp/test/snmp_log_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -175,7 +175,7 @@ init_per_testcase(Case, Config) when is_list(Config) ->
end_per_testcase(_Case, Config) when is_list(Config) ->
- ?PRINT2("system events during test: "
+ ?IPRINT("system events during test: "
"~n ~p", [snmp_test_global_sys_monitor:events()]),
%% Leave the dirs created above (enable debugging of the test case(s))
@@ -191,7 +191,7 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
open_and_close(suite) -> [];
open_and_close(Config) when is_list(Config) ->
- p(open_and_close),
+ ?P(open_and_close),
put(sname,open_and_close),
put(verbosity,trace),
Dir = ?config(log_dir, Config),
@@ -213,7 +213,7 @@ open_write_and_close1(suite) ->
open_write_and_close1(doc) ->
"Open a plain (no sequence-numbering) log file";
open_write_and_close1(Config) when is_list(Config) ->
- p(open_write_and_close1),
+ ?P(open_write_and_close1),
put(sname,open_write_and_close1),
put(verbosity,trace),
?DBG("open_write_and_close1 -> start", []),
@@ -232,7 +232,7 @@ open_write_and_close2(suite) ->
open_write_and_close2(doc) ->
"Open a log file with sequence-numbering explicitly disabled";
open_write_and_close2(Config) when is_list(Config) ->
- p(open_write_and_close2),
+ ?P(open_write_and_close2),
put(sname,open_write_and_close2),
put(verbosity,trace),
?DBG("open_write_and_close2 -> start", []),
@@ -251,7 +251,7 @@ open_write_and_close3(suite) ->
open_write_and_close3(doc) ->
"Open a log file with sequence-numbering using MFA";
open_write_and_close3(Config) when is_list(Config) ->
- p(open_write_and_close3),
+ ?P(open_write_and_close3),
put(sname,open_write_and_close3),
put(verbosity,trace),
?DBG("open_write_and_close2 -> start", []),
@@ -272,7 +272,7 @@ open_write_and_close4(suite) ->
open_write_and_close4(doc) ->
"Open a log file with sequence-numbering using fun";
open_write_and_close4(Config) when is_list(Config) ->
- p(open_write_and_close4),
+ ?P(open_write_and_close4),
put(sname,open_write_and_close4),
put(verbosity,trace),
?DBG("open_write_and_close2 -> start", []),
@@ -371,7 +371,7 @@ log_to_io1(suite) -> [];
log_to_io1(doc) -> "Log to io from the same process that opened "
"and wrote the log";
log_to_io1(Config) when is_list(Config) ->
- p(log_to_io1),
+ ?P(log_to_io1),
put(sname,l2i1),
put(verbosity,debug),
?DBG("log_to_io1 -> start", []),
@@ -426,7 +426,7 @@ log_to_io2(doc) -> "Log to io from a different process than which "
"opened and wrote the log";
log_to_io2(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- p(log_to_io2),
+ ?P(log_to_io2),
put(sname, l2i2),
put(verbosity,debug),
?DBG("log_to_io2 -> start", []),
@@ -487,7 +487,7 @@ log_to_io2(Config) when is_list(Config) ->
log_to_txt1(suite) -> [];
log_to_txt1(Config) when is_list(Config) ->
- p(log_to_txt1),
+ ?P(log_to_txt1),
put(sname,l2t1),
put(verbosity,debug),
?DBG("log_to_txt1 -> start", []),
@@ -505,7 +505,7 @@ log_to_txt1(Config) when is_list(Config) ->
log_to_txt2(suite) -> [];
log_to_txt2(Config) when is_list(Config) ->
- p(log_to_txt2),
+ ?P(log_to_txt2),
put(sname,l2t2),
put(verbosity,debug),
?DBG("log_to_txt2 -> start", []),
@@ -642,7 +642,7 @@ log_to_txt3(doc) ->
"opened and wrote the log";
log_to_txt3(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- p(log_to_txt3),
+ ?P(log_to_txt3),
put(sname,l2t3),
put(verbosity,debug),
?DBG("log_to_txt3 -> start", []),
@@ -683,9 +683,7 @@ log_to_txt3(Config) when is_list(Config) ->
R = snmp_log:log_to_txt(Log, LogFile, Dir,
Mibs, TxtFile),
T2 = snmp_misc:now(ms),
- io:format(user,
- "Time converting file: ~w ms~n",
- [T2 - T1]),
+ ?IPRINT("Time converting file: ~w ms", [T2 - T1]),
{R, I}
end),
@@ -697,9 +695,9 @@ log_to_txt3(Config) when is_list(Config) ->
?DBG("log_to_txt3 -> text file size: ~p", [FileSize]),
validate_size(FileSize);
{Error, Info} ->
- ?DBG("log_to_txt3 -> log to txt failed: "
- "~n Error: ~p"
- "~n Info: ~p", [Error, Info]),
+ ?EPRINT("log to txt failed: "
+ "~n Error: ~p"
+ "~n Info: ~p", [Error, Info]),
?line ?FAIL({log_lo_txt_failed, Error, Info})
end,
@@ -709,7 +707,7 @@ log_to_txt3(Config) when is_list(Config) ->
?DBG("log_to_txt3 -> instruct the log reader to stop", []),
?line log_reader_stop(Reader),
- ?DBG("log_to_txt3 -> done", []),
+ ?IPRINT("log_to_txt3 -> done", []),
ok.
@@ -754,8 +752,7 @@ log_writer_stop(Pid) ->
receive
{'EXIT', Pid, normal} ->
_T2 = snmp_misc:now(ms),
- io:format("[~s] it took ~w ms to stop the writer~n",
- [?FTS(), _T2 - _T1]),
+ ?IPRINT("it took ~w ms to stop the writer", [_T2 - _T1]),
ok
after 60000 ->
Msg = receive Any -> Any after 0 -> nothing end,
@@ -772,8 +769,7 @@ log_writer_sleep(Pid, Time) ->
receive
{sleeping, Pid} ->
_T2 = snmp_misc:now(ms),
- io:format("[~s] it took ~w ms to put the writer to sleep~n",
- [?FTS(), _T2 - _T1]),
+ ?IPRINT("it took ~w ms to put the writer to sleep", [_T2 - _T1]),
ok;
{'EXIT', Pid, Reason} ->
{error, Reason}
@@ -785,8 +781,7 @@ log_writer_sleep(Pid, Time) ->
log_writer_main(Name, File, Size, Repair, P, Factor) ->
process_flag(trap_exit, true),
- %% put(sname,log_writer),
- %% put(verbosity,trace),
+ put(tname, "LOG-WRITER"),
{ok, Log} = snmp_log:create(Name, File, Size, Repair),
P ! {log, Log, self()},
Msgs = lists:flatten(lists:duplicate(if
@@ -807,39 +802,34 @@ log_writer_main(Name, File, Size, Repair, P, Factor) ->
log_writer(Log, BatchLogger, P).
log_writer(Log, Fun, P) ->
- lp("entry"),
+ ?IPRINT("entry"),
receive
{stop, P} ->
- lp("received stop request"),
+ ?IPRINT("received stop request"),
ok = snmp_log:close(Log),
exit(normal);
{info, P} ->
- lp("received info request"),
+ ?IPRINT("received info request"),
{ok, Info} = snmp_log:info(Log),
display_info(Info),
log_writer(Log, Fun, P);
{sleep, Time, P} ->
- lp("received sleep (~w) request", [Time]),
+ ?IPRINT("received sleep (~w) request", [Time]),
P ! {sleeping, self()},
?SLEEP(Time),
- lp("done sleeping"),
+ ?IPRINT("done sleeping"),
log_writer(Log, Fun, P);
ELSE ->
- error_logger:error_msg("ERROR:logger - received unknown message: "
- "~n ~p~n", [ELSE]),
+ ?EPRINT("Received unknown message: "
+ "~n ~p", [ELSE]),
log_writer(Log, Fun, P)
after 1000 ->
- lp("log some messages"),
+ ?IPRINT("log some messages"),
To = lists:duplicate(100, 100),
lists:foreach(Fun, To),
log_writer(Log, Fun, P)
end.
-lp(F) ->
- lp(F, []).
-
-lp(F, A) ->
- io:format("[~s] writer [~w] " ++ F ++ "~n", [?FTS(),self()|A]).
%% --
@@ -849,8 +839,7 @@ log_reader_start() ->
receive
{started, Pid} ->
_T2 = snmp_misc:now(ms),
- io:format("[~s] it took ~w ms to start the reader~n",
- [?FTS(), _T2 - _T1]),
+ ?IPRINT("it took ~w ms to start the reader", [_T2 - _T1]),
{ok, Pid};
{'EXIT', Pid, Reason} ->
{error, Reason}
@@ -864,8 +853,7 @@ log_reader_stop(Pid) ->
receive
{'EXIT', Pid, normal} ->
_T2 = snmp_misc:now(ms),
- io:format("[~s] it took ~w ms to stop the reader~n",
- [?FTS(), _T2 - _T1]),
+ ?IPRINT("it took ~w ms to stop the reader", [_T2 - _T1]),
ok
after 1000 ->
Msg = receive Any -> Any after 0 -> nothing end,
@@ -880,35 +868,28 @@ log_reader_log_to(Pid, LogToFun) when is_function(LogToFun) ->
end.
log_reader_main(P) ->
- put(sname,log_reader),
- put(verbosity,trace),
+ put(tname, "LOG-READER"),
P ! {started, self()},
log_reader(P).
log_reader(P) ->
- rp("entry"),
+ ?IPRINT("entry"),
receive
{stop, P} ->
- rp("received stop request"),
+ ?IPRINT("received stop request"),
exit(normal);
{log_to, F, P} ->
- rp("received log_to request"),
+ ?IPRINT("received log_to request"),
Res = F(),
- rp("done with log_to - sending reply"),
+ ?IPRINT("done with log_to - sending reply"),
P ! {log_to_reply, Res, self()},
log_reader(P);
ELSE ->
- error_logger:error_msg("reader - received unknown message: "
- "~n ~p~n", [ELSE]),
+ ?EPRINT("Received unknown message: "
+ "~n ~p", [ELSE]),
log_reader(P)
end.
-rp(F) ->
- rp(F, []).
-
-rp(F, A) ->
- io:format("[~s] reader [~w] " ++ F ++ "~n", [?FTS(),self()|A]).
-
%%======================================================================
@@ -1127,23 +1108,6 @@ varbinds([{Oid, Type, Value, Idx}|T], Acc) ->
org_index = Idx},
varbinds(T, [Varbind|Acc]).
-% enc_message('version-3' = Vsn, Community, Pdu) ->
-% ScopedPDU = #scopedPdu{contextEngineID = ContextEngineID,
-% contextName = ContextName,
-% data = Pdu},
-% NUsmSecParams =
-% UsmSecParams#usmSecurityParameters{msgAuthenticationParameters =
-% AuthParams},
-% SecBytes = snmp_pdus:enc_usm_security_parameters(NUsmSecParams),
-% V3Hdr = #v3_hdr{msgID = MsgID,
-% msgMaxSize = AgentMS,
-% msgFlags = snmp_misc:mk_msg_flags(Type, SecLevel),
-% msgSecurityParameters = SecBytes
-% msgSecurityModel = MsgSecurityModel},
-% Msg = #message{version = Vsn, vsn_hdr = V3Hdr,
-% data = ScopedPDUBytes},
-% snmp_pdus:enc_message_only(Message2);
-
enc_message(Vsn, Community, Pdu) ->
PduBytes = snmp_pdus:enc_pdu(Pdu),
Msg = #message{version = Vsn,
@@ -1156,14 +1120,13 @@ display_info(Info) ->
CurrentFile = get_info(current_file, Info, -1),
NoItems = get_info(no_current_items, Info, -1),
NoBytes = get_info(no_current_bytes, Info, -1),
- io:format(user, "Disk log info: "
- "~n Number of filled since opened: ~p"
- "~n Number of filled since last info: ~p"
- "~n Current file: ~p"
- "~n Number of items in file: ~p"
- "~n Number of bytes in file: ~p"
- "~n",
- [SinceOpened, SinceLastInfo, CurrentFile, NoItems, NoBytes]).
+ ?NPRINT("Disk log info: "
+ "~n Number of filled since opened: ~p"
+ "~n Number of filled since last info: ~p"
+ "~n Current file: ~p"
+ "~n Number of items in file: ~p"
+ "~n Number of bytes in file: ~p",
+ [SinceOpened, SinceLastInfo, CurrentFile, NoItems, NoBytes]).
get_info(Key, Info, Def) ->
case lists:keysearch(Key, 1, Info) of
@@ -1176,5 +1139,3 @@ get_info(Key, Info, Def) ->
join(D, F) ->
filename:join(D, F).
-p(Case) ->
- io:format(user, "test case: ~w~n", [Case]).
diff --git a/lib/snmp/test/snmp_manager_SUITE.erl b/lib/snmp/test/snmp_manager_SUITE.erl
index bc7c5cd46d..9d8e2efacf 100644
--- a/lib/snmp/test/snmp_manager_SUITE.erl
+++ b/lib/snmp/test/snmp_manager_SUITE.erl
@@ -337,8 +337,8 @@ ipv6_tests() ->
init_per_suite(Config0) when is_list(Config0) ->
- p("init_per_suite -> entry with"
- "~n Config0: ~p", [Config0]),
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
case ?LIB:init_per_suite(Config0) of
{skip, _} = SKIP ->
@@ -346,8 +346,8 @@ init_per_suite(Config0) when is_list(Config0) ->
Config1 ->
- p("init_per_suite -> common init done"
- "~n Config1: ~p", [Config1]),
+ ?IPRINT("init_per_suite -> common init done"
+ "~n Config1: ~p", [Config1]),
%% Preferably this test SUITE should be divided into groups
%% so that if crypto does not work only v3 tests that
@@ -375,15 +375,15 @@ init_per_suite(Config0) when is_list(Config0) ->
end_per_suite(Config0) when is_list(Config0) ->
- p("end_per_suite -> entry with"
- "~n Config0: ~p"
- "~n Nodes: ~p", [Config0, erlang:nodes()]),
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config0: ~p"
+ "~n Nodes: ~p", [Config0, erlang:nodes()]),
snmp_test_sys_monitor:stop(),
Config1 = ?LIB:end_per_suite(Config0),
- p("end_per_suite -> end when"
- "~n Nodes: ~p", [erlang:nodes()]),
+ ?IPRINT("end_per_suite -> end when"
+ "~n Nodes: ~p", [erlang:nodes()]),
Config1.
@@ -453,8 +453,10 @@ end_per_group(_GroupName, Config) ->
%%
init_per_testcase(Case, Config) when is_list(Config) ->
- p(Case, "init_per_testcase begin when"
- "~n Nodes: ~p~n~n", [erlang:nodes()]),
+
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p", [Config, erlang:nodes()]),
snmp_test_global_sys_monitor:reset_events(),
@@ -472,15 +474,19 @@ init_per_testcase(Case, Config) when is_list(Config) ->
C:{skip, _} = E:_ when ((C =:= throw) orelse
(C =:= exit)) ->
E;
+ exit:{suite_failed, {{Reason, _CS},_MFA}, Mod, Line}:_ ->
+ {skip, {Reason, Mod, Line}};
+ exit:{suite_failed, Reason, Mod, Line}:_ ->
+ {skip, {Reason, Mod, Line}};
C:E:_ when ((C =:= throw) orelse
(C =:= exit)) ->
{skip, {catched, C, E}}
end
end,
- p(Case, "init_per_testcase end when"
- "~n Nodes: ~p"
- "~n Result: ~p"
- "~n~n", [Result, erlang:nodes()]),
+ ?IPRINT("init_per_testcase end when"
+ "~n Nodes: ~p"
+ "~n Result: ~p"
+ "~n~n", [erlang:nodes(), Result]),
Result.
init_per_testcase2(Case, Config) ->
@@ -527,10 +533,14 @@ init_per_testcase2(Case, Config) ->
InformSwarm when (InformSwarm =:= inform_swarm_cbp_def) orelse
(InformSwarm =:= inform_swarm_cbp_temp) orelse
(InformSwarm =:= inform_swarm_cbp_perm) ->
- ?MINS(60);
+ case ?config(snmp_factor, Config) of
+ N when is_integer(N) -> ?MINS(2*N);
+ _ -> ?MINS(2)
+ end;
_ ->
?MINS(1)
end,
+ ?IPRINT("Set test case timetrap: ~p", [TO]),
ct:timetrap(TO),
Conf = [{ipfamily, Family},
@@ -609,12 +619,12 @@ init_per_testcase3(Case, Config) ->
(Case =:= inform_swarm_cbp_temp) orelse
(Case =:= inform_swarm_cbp_perm) ->
Verb = [{manager_config_verbosity, silence},
- {manager_note_store_verbosity, silence},
- {manager_server_verbosity, info},
- {manager_net_if_verbosity, info},
- {agent_verbosity, info},
- {agent_net_if_verbosity, info}],
- Verb ++ Config;
+ {manager_note_store_verbosity, silence},
+ {manager_server_verbosity, info},
+ {manager_net_if_verbosity, info},
+ {agent_verbosity, info},
+ {agent_net_if_verbosity, info}],
+ Verb ++ Config;
Case =:= otp8395_1 ->
[{manager_atl_seqno, true} | Config];
true ->
@@ -670,20 +680,21 @@ init_per_testcase_fail_agent_cleanup(Conf) ->
(catch fin_agent(Conf)).
end_per_testcase(Case, Config) when is_list(Config) ->
- p(Case, "end_per_testcase begin when"
- "~n Nodes: ~p~n~n", [erlang:nodes()]),
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p"
+ "~n Nodes: ~p",
+ [Config, erlang:nodes()]),
- ?PRINT2("system events during test: "
+ ?IPRINT("system events during test: "
"~n ~p", [snmp_test_global_sys_monitor:events()]),
- %% Dog = ?config(watchdog, Config),
- %% ?WD_STOP(Dog),
- %% Conf1 = lists:keydelete(watchdog, 1, Config),
Conf1 = Config,
Conf2 = end_per_testcase2(Case, Conf1),
- p(Case, "end_per_testcase end when"
- "~n Nodes: ~p~n~n", [erlang:nodes()]),
+ ?IPRINT("end_per_testcase -> done with"
+ "~n Condif: ~p"
+ "~n Nodes: ~p", [Conf2, erlang:nodes()]),
+
Conf2.
end_per_testcase2(Case, Config) ->
@@ -763,7 +774,8 @@ simple_start_and_stop1(Config) when is_list(Config) ->
fun() -> do_simple_start_and_stop1(Config) end).
do_simple_start_and_stop1(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -774,12 +786,12 @@ do_simple_start_and_stop1(Config) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
- p("manager started, now try to stop"),
+ ?IPRINT("manager started, now try to stop"),
ok = snmpm:stop(),
?SLEEP(1000),
@@ -800,7 +812,9 @@ simple_start_and_stop2(Config) when is_list(Config) ->
?TC_TRY(simple_start_and_stop2, Pre, Case, Post).
do_simple_start_and_stop2([ManagerNode], Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -813,23 +827,24 @@ do_simple_start_and_stop2([ManagerNode], Config) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try load snmp application"),
+ ?IPRINT("try load snmp application"),
?line ok = load_snmp(ManagerNode),
- p("try set manager env for the snmp application"),
+ ?IPRINT("try set manager env for the snmp application"),
?line ok = set_mgr_env(ManagerNode, Opts),
- p("try starting snmp application (with only manager)"),
+ ?IPRINT("try starting snmp application (with only manager)"),
?line ok = start_snmp(ManagerNode),
- p("started"),
+ ?IPRINT("started"),
?SLEEP(1000),
- p("try stopping snmp application (with only manager)"),
+ ?IPRINT("try stopping snmp application (with only manager)"),
?line ok = stop_snmp(ManagerNode),
?SLEEP(1000),
+ ?IPRINT("end"),
ok.
@@ -842,7 +857,9 @@ simple_start_and_stop3(Config) when is_list(Config) ->
fun() -> do_simple_start_and_stop3(Config) end).
do_simple_start_and_stop3(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
+
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -853,17 +870,19 @@ do_simple_start_and_stop3(Config) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
try snmpm:start_link(Opts) of
ok ->
+ (catch snmpm:stop()),
?FAIL('unexpected-success')
catch
_:_:_ ->
- p("expected start failure"),
+ ?IPRINT("expected start failure"),
ok
end,
?SLEEP(1000),
+ ?IPRINT("end"),
ok.
@@ -876,7 +895,8 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) ->
fun() -> do_simple_start_and_monitor_crash1(Config) end).
do_simple_start_and_monitor_crash1(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -888,15 +908,15 @@ do_simple_start_and_monitor_crash1(Config) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start(Opts),
?SLEEP(1000),
- p("create the monitor"),
+ ?IPRINT("create the monitor"),
Ref = snmpm:monitor(),
- p("make sure it has not already crashed..."),
+ ?IPRINT("make sure it has not already crashed..."),
receive
{'DOWN', Ref, process, Obj1, Reason1} ->
?FAIL({unexpected_down, Obj1, Reason1})
@@ -904,20 +924,28 @@ do_simple_start_and_monitor_crash1(Config) ->
ok
end,
- p("stop the manager"),
+ ?IPRINT("stop the manager"),
ok = snmpm:stop(),
- p("await the down-message"),
+ ?IPRINT("await the down-message"),
receive
{'DOWN', Ref, process, Obj2, Reason2} ->
- p("received expected down-message: "
- "~n Obj2: ~p"
- "~n Reason2: ~p",
- [Obj2, Reason2]),
+ ?IPRINT("received expected down-message: "
+ "~n Obj2: ~p"
+ "~n Reason2: ~p",
+ [Obj2, Reason2]),
ok
after 1000 ->
+ %% The manager is an entire process tree and we can't
+ %% wait for all of them. Instead, we assume that if
+ %% we deal with the top supervisor, all the other procs
+ %% will also follow...
+ ?ENSURE_NOT_RUNNING(snmpm_supervisor,
+ fun() -> snmpm:stop() end,
+ 1000),
?FAIL(timeout)
end,
+ ?IPRINT("end"),
ok.
@@ -926,11 +954,22 @@ do_simple_start_and_monitor_crash1(Config) ->
simple_start_and_monitor_crash2(suite) -> [];
simple_start_and_monitor_crash2(Config) when is_list(Config) ->
+ Cond = fun() -> case os:type() of
+ {unix, netbsd} ->
+ {skip, "Unstable on NetBSD"};
+ _ ->
+ ok
+ end
+ end,
+ Pre = fun() -> undefined end,
+ Case = fun(_) -> do_simple_start_and_monitor_crash2(Config) end,
+ Post = fun(_) -> ok end,
?TC_TRY(simple_start_and_monitor_crash2,
- fun() -> do_simple_start_and_monitor_crash2(Config) end).
+ Cond, Pre, Case, Post).
do_simple_start_and_monitor_crash2(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -943,15 +982,15 @@ do_simple_start_and_monitor_crash2(Config) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start(Opts),
?SLEEP(1000),
- p("create the monitor"),
+ ?IPRINT("create the monitor"),
Ref = snmpm:monitor(),
- p("make sure it has not already crashed..."),
+ ?IPRINT("make sure it has not already crashed..."),
receive
{'DOWN', Ref, process, Obj1, Reason1} ->
?FAIL({unexpected_down, Obj1, Reason1})
@@ -959,16 +998,16 @@ do_simple_start_and_monitor_crash2(Config) ->
ok
end,
- p("crash the manager"),
+ ?IPRINT("crash the manager"),
simulate_crash(),
- p("await the down-message"),
+ ?IPRINT("await the down-message"),
receive
{'DOWN', Ref, process, Obj2, Reason2} ->
- p("received expected down-message: "
- "~n Obj2: ~p"
- "~n Reason2: ~p",
- [Obj2, Reason2]),
+ ?IPRINT("received expected down-message: "
+ "~n Obj2: ~p"
+ "~n Reason2: ~p",
+ [Obj2, Reason2]),
ok
after 1000 ->
?FAIL(timeout)
@@ -995,16 +1034,17 @@ simulate_crash(?MAX_KILLS, _) ->
ok
end;
simulate_crash(NumKills, Pid) when (NumKills < ?MAX_KILLS) and is_pid(Pid) ->
- p("similate_crash -> ~w, ~p", [NumKills, Pid]),
+ ?IPRINT("similate_crash -> ~w, ~p", [NumKills, Pid]),
Ref = erlang:monitor(process, Pid),
exit(Pid, kill),
receive
{'DOWN', Ref, process, _Object, _Info} ->
- p("received expected 'DOWN' message"),
+ ?IPRINT("received expected 'DOWN' message"),
simulate_crash(NumKills + 1, server_pid())
after 1000 ->
case server_pid() of
P when is_pid(P) ->
+ ?EPRINT("received expected 'DOWN' message"),
exit({error, {no_down_from_server, P}});
_ ->
ok
@@ -1023,7 +1063,8 @@ notify_started01(Config) when is_list(Config) ->
fun() -> do_notify_started01(Config) end).
do_notify_started01(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -1035,11 +1076,11 @@ do_notify_started01(Config) ->
{note_store, [{verbosity, silence}]},
{config, [{verbosity, log}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("request start notification (1)"),
+ ?IPRINT("request start notification (1)"),
Pid1 = snmpm:notify_started(10000),
receive
{snmpm_start_timeout, Pid1} ->
- p("received expected start timeout"),
+ ?IPRINT("received expected start timeout"),
ok;
Any1 ->
?FAIL({unexpected_message, Any1})
@@ -1047,17 +1088,17 @@ do_notify_started01(Config) ->
?FAIL({unexpected_timeout, Pid1})
end,
- p("request start notification (2)"),
+ ?IPRINT("request start notification (2)"),
Pid2 = snmpm:notify_started(10000),
- p("start the snmpm starter"),
+ ?IPRINT("start the snmpm starter"),
Pid = snmpm_starter(Opts, 5000),
- p("await the start notification"),
+ ?IPRINT("await the start notification"),
Ref =
receive
{snmpm_started, Pid2} ->
- p("received started message -> create the monitor"),
+ ?IPRINT("received started message -> create the monitor"),
snmpm:monitor();
Any2 ->
?FAIL({unexpected_message, Any2})
@@ -1065,7 +1106,7 @@ do_notify_started01(Config) ->
?FAIL({unexpected_timeout, Pid2})
end,
- p("[~p] make sure it has not already crashed...", [Ref]),
+ ?IPRINT("[~p] make sure it has not already crashed...", [Ref]),
receive
{'DOWN', Ref, process, Obj1, Reason1} ->
?FAIL({unexpected_down, Obj1, Reason1})
@@ -1073,22 +1114,22 @@ do_notify_started01(Config) ->
ok
end,
- p("stop the manager"),
+ ?IPRINT("stop the manager"),
Pid ! {stop, self()}, %ok = snmpm:stop(),
- p("await the down-message"),
+ ?IPRINT("await the down-message"),
receive
{'DOWN', Ref, process, Obj2, Reason2} ->
- p("received expected down-message: "
- "~n Obj2: ~p"
- "~n Reason2: ~p",
- [Obj2, Reason2]),
+ ?IPRINT("received expected down-message: "
+ "~n Obj2: ~p"
+ "~n Reason2: ~p",
+ [Obj2, Reason2]),
ok
after 5000 ->
?FAIL(down_timeout)
end,
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -1137,7 +1178,8 @@ notify_started02_cond(Config) ->
?NON_PC_TC_MAYBE_SKIP(Config, Condition).
do_notify_started02(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -1149,11 +1191,11 @@ do_notify_started02(Config) ->
{note_store, [{verbosity, silence}]},
{config, [{verbosity, debug}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start snmpm client process"),
+ ?IPRINT("start snmpm client process"),
NumIterations = 5,
Pid1 = ns02_client_start(NumIterations),
- p("start snmpm ctrl (starter) process"),
+ ?IPRINT("start snmpm ctrl (starter) process"),
Pid2 = ns02_ctrl_start(Opts, NumIterations),
%% On a reasonably fast machine, one iteration takes approx 4 seconds.
@@ -1175,7 +1217,8 @@ do_notify_started02(Config) ->
?SKIP(Reason)
end,
- p("await snmpm client process exit (max ~p+10000 msec)", [ApproxStartTime]),
+ ?IPRINT("await snmpm client process exit (max ~p+10000 msec)",
+ [ApproxStartTime]),
receive
%% We take this opportunity to check if we got a skip from
%% the ctrl process.
@@ -1193,7 +1236,7 @@ do_notify_started02(Config) ->
?FAIL(timeout)
end,
- p("await snmpm starter process exit"),
+ ?IPRINT("await snmpm starter process exit"),
receive
{'EXIT', Pid2, normal} ->
ok;
@@ -1207,7 +1250,7 @@ do_notify_started02(Config) ->
?FAIL(timeout)
end,
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -1220,8 +1263,8 @@ ns02_client_await_approx_runtime(Pid) ->
{?MODULE, client_time, Time} ->
{ok, Time};
{'EXIT', Pid, Reason} ->
- p("client (~p) failed: "
- "~n ~p", [Pid, Reason]),
+ ?EPRINT("client (~p) failed: "
+ "~n ~p", [Pid, Reason]),
{error, Reason}
after 30000 ->
@@ -1233,48 +1276,48 @@ ns02_client_await_approx_runtime(Pid) ->
ns02_client(Parent, N) when is_pid(Parent) ->
put(tname, ns02_client),
- p("starting"),
+ ?IPRINT("starting"),
ns02_client_loop(Parent,
dummy, snmpm:notify_started(?NS_TIMEOUT),
snmp_misc:now(ms), undefined,
N).
ns02_client_loop(_Parent, _Ref, _Pid, _Begin, _End, 0) ->
- %% p("loop -> done"),
+ %% ?IPRINT("loop -> done"),
exit(normal);
ns02_client_loop(Parent, Ref, Pid, Begin, End, N)
when is_pid(Parent) andalso is_integer(Begin) andalso is_integer(End) ->
- %% p("loop -> [~w] inform parent: ~w, ~w => ~w", [N, Begin, End, End-Begin]),
+ %% ?IPRINT("loop -> [~w] inform parent: ~w, ~w => ~w", [N, Begin, End, End-Begin]),
Parent ! {?MODULE, client_time, N*(End-Begin)},
ns02_client_loop(undefined, Ref, Pid, snmp_misc:now(ms), undefined, N);
ns02_client_loop(Parent, Ref, Pid, Begin, End, N)
when is_integer(Begin) andalso is_integer(End) ->
- %% p("loop -> [~w] entry when"
+ %% ?IPRINT("loop -> [~w] entry when"
%% "~n Ref: ~p"
%% "~n Pid: ~p"
%% "~n Begin: ~p"
%% "~n End: ~p", [N, Ref, Pid, Begin, End]),
ns02_client_loop(Parent, Ref, Pid, snmp_misc:now(ms), undefined, N);
ns02_client_loop(Parent, Ref, Pid, Begin, End, N) ->
- %% p("loop(await message) -> [~w] entry when"
+ %% ?IPRINT("loop(await message) -> [~w] entry when"
%% "~n Ref: ~p"
%% "~n Pid: ~p"
%% "~n Begin: ~p"
%% "~n End: ~p", [N, Ref, Pid, Begin, End]),
receive
{snmpm_started, Pid} ->
- p("received expected started message (~w)", [N]),
+ ?IPRINT("received expected started message (~w)", [N]),
ns02_client_loop(Parent,
snmpm:monitor(), dummy,
Begin, End,
N);
{snmpm_start_timeout, Pid} ->
- p("unexpected timout"),
+ ?EPRINT("unexpected timeout"),
?FAIL({unexpected_start_timeout, Pid});
{'DOWN', Ref, process, Obj, Reason} ->
- p("received expected DOWN message (~w) with"
- "~n Obj: ~p"
- "~n Reason: ~p", [N, Obj, Reason]),
+ ?IPRINT("received expected DOWN message (~w) with"
+ "~n Obj: ~p"
+ "~n Reason: ~p", [N, Obj, Reason]),
ns02_client_loop(Parent,
dummy, snmpm:notify_started(?NS_TIMEOUT),
Begin, snmp_misc:now(ms),
@@ -1286,7 +1329,7 @@ ns02_ctrl_start(Opts, N) ->
ns02_ctrl(Opts, N) ->
put(tname, ns02_ctrl),
- p("starting"),
+ ?IPRINT("starting"),
ns02_ctrl_loop(Opts, N).
@@ -1296,36 +1339,36 @@ ns02_ctrl(Opts, N) ->
%% So, we try to monitor each start attempt. We allow 5 sec (just
%% to give slow boxes a chance).
ns02_ctrl_loop(_Opts, 0) ->
- p("done"),
+ ?IPRINT("done"),
exit(normal);
ns02_ctrl_loop(Opts, N) ->
- p("entry when N: ~p", [N]),
+ ?IPRINT("entry when N: ~p", [N]),
?SLEEP(2000),
- p("start manager"),
+ ?IPRINT("start manager"),
TS1 = erlang:system_time(millisecond),
{StarterPid, StarterMRef} =
erlang:spawn_monitor(fun() -> exit(snmpm:start(Opts)) end),
receive
{'DOWN', StarterMRef, process, StarterPid, ok} ->
TS2 = erlang:system_time(millisecond),
- p("manager started: ~w ms", [TS2-TS1]),
+ ?IPRINT("manager started: ~w ms", [TS2-TS1]),
ok
after 5000 ->
- p("manager (~p) start timeout - kill", [StarterPid]),
+ ?EPRINT("manager (~p) start timeout - kill", [StarterPid]),
exit(StarterPid, kill),
exit({skip, start_timeout})
end,
?SLEEP(2000),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?SLEEP(100), % Give the verbosity to take effect...
TS3 = erlang:system_time(millisecond),
case snmpm:stop(5000) of
ok ->
TS4 = erlang:system_time(millisecond),
- p("manager stopped: ~p ms", [TS4-TS3]),
+ ?IPRINT("manager stopped: ~p ms", [TS4-TS3]),
ok;
{error, timeout} ->
- p("manager stop timeout - kill (cleanup) and skip"),
+ ?EPRINT("manager stop timeout - kill (cleanup) and skip"),
exit(whereis(snmpm_supervisor), kill),
exit({skip, stop_timeout})
end,
@@ -1337,37 +1380,44 @@ ns02_ctrl_loop(Opts, N) ->
info(suite) -> [];
info(Config) when is_list(Config) ->
- ?TC_TRY(info,
- fun() -> do_info(Config) end).
-
-do_info(Config) ->
- p("starting with Config: ~n~p", [Config]),
-
- ConfDir = ?config(manager_conf_dir, Config),
- DbDir = ?config(manager_db_dir, Config),
-
- write_manager_conf(ConfDir),
-
- Opts = [{server, [{verbosity, trace}]},
- {net_if, [{verbosity, trace}]},
- {note_store, [{verbosity, trace}]},
- {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
+ Pre = fun() ->
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
+
+ write_manager_conf(ConfDir),
+
+ Opts = [{server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {note_store, [{verbosity, trace}]},
+ {config, [{verbosity, trace},
+ {dir, ConfDir},
+ {db_dir, DbDir}]}],
+ ?IPRINT("try starting manager"),
+ ok = snmpm:start(Opts),
+ ?SLEEP(1000),
+ ok
+ end,
+ Case = fun(_) -> do_info(Config) end,
+ Post = fun(_) ->
+ ?IPRINT("info verified, now try to stop"),
+ snmpm:stop(),
+ ?SLEEP(1000),
+ ok
+ end,
+ ?TC_TRY(info, Pre, Case, Post).
- p("try starting manager"),
- ok = snmpm:start(Opts),
- ?SLEEP(1000),
+do_info(Config) ->
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
- p("manager started, now get info"),
+ ?IPRINT("get info"),
Info = snmpm:info(),
- p("got info, now verify: ~n~p", [Info]),
+ ?IPRINT("got info, now verify: "
+ "~n ~p", [Info]),
ok = verify_info( Info ),
- p("info verified, now try to stop"),
- ok = snmpm:stop(),
-
- ?SLEEP(1000),
-
+ ?IPRINT("end"),
ok.
verify_info(Info) when is_list(Info) ->
@@ -1416,7 +1466,9 @@ register_user1(Config) when is_list(Config) ->
?TC_TRY(register_user1, Pre, Case, Post).
do_register_user1([ManagerNode], Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -1429,56 +1481,56 @@ do_register_user1([ManagerNode], Config) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("load snmp application"),
+ ?IPRINT("load snmp application"),
?line ok = load_snmp(ManagerNode),
- p("set manager env for the snmp application"),
+ ?IPRINT("set manager env for the snmp application"),
?line ok = set_mgr_env(ManagerNode, Opts),
- p("starting snmp application (with only manager)"),
+ ?IPRINT("starting snmp application (with only manager)"),
?line ok = start_snmp(ManagerNode),
- p("started"),
+ ?IPRINT("started"),
?SLEEP(1000),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("try register user(s)"),
+ ?IPRINT("try register user(s)"),
?line ok = mgr_register_user(ManagerNode, calvin, snmpm_user_default,
[self(), "various misc info"]),
Users1 = mgr_which_users(ManagerNode),
- p("users: ~p~n", [Users1]),
+ ?IPRINT("users: ~p~n", [Users1]),
?line ok = verify_users(Users1, [calvin]),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
?line ok = mgr_register_user(ManagerNode, hobbe, snmpm_user_default,
{"misc info", self()}),
Users2 = mgr_which_users(ManagerNode),
- p("users: ~p~n", [Users2]),
+ ?IPRINT("users: ~p~n", [Users2]),
?line ok = verify_users(Users2, [calvin, hobbe]),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("try unregister user(s)"),
+ ?IPRINT("try unregister user(s)"),
?line ok = mgr_unregister_user(ManagerNode, calvin),
Users3 = mgr_which_users(ManagerNode),
- p("users: ~p~n", [Users3]),
+ ?IPRINT("users: ~p~n", [Users3]),
?line ok = verify_users(Users3, [hobbe]),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
?line ok = mgr_unregister_user(ManagerNode, hobbe),
Users4 = mgr_which_users(ManagerNode),
- p("users: ~p~n", [Users4]),
+ ?IPRINT("users: ~p~n", [Users4]),
?line ok = verify_users(Users4, []),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
?SLEEP(1000),
- p("stop snmp application (with only manager)"),
+ ?IPRINT("stop snmp application (with only manager)"),
?line ok = stop_snmp(ManagerNode),
?SLEEP(1000),
@@ -1514,7 +1566,9 @@ register_agent_old(Config) when is_list(Config) ->
?TC_TRY(register_agent_old, Pre, Case, Post).
do_register_agent_old([ManagerNode], Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -1527,100 +1581,105 @@ do_register_agent_old([ManagerNode], Config) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("load snmp application"),
+ ?IPRINT("load snmp application"),
?line ok = load_snmp(ManagerNode),
- p("set manager env for the snmp application"),
+ ?IPRINT("set manager env for the snmp application"),
?line ok = set_mgr_env(ManagerNode, Opts),
- p("starting snmp application (with only manager)"),
+ ?IPRINT("starting snmp application (with only manager)"),
?line ok = start_snmp(ManagerNode),
- p("started"),
+ ?IPRINT("started"),
?SLEEP(1000),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) user_alfa & user_beta"),
+ ?IPRINT("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register agent(s)"),
+ ?IPRINT("register agent(s)"),
?line ok = mgr_register_agent(ManagerNode, user_alfa, 5000, []),
?line ok = mgr_register_agent(ManagerNode, user_alfa, 5001, []),
?line ok = mgr_register_agent(ManagerNode, user_beta, 5002, []),
?line ok = mgr_register_agent(ManagerNode, user_beta, 5003, []),
- p("verify all agent(s): expect 4"),
+ ?IPRINT("verify all agent(s): expect 4"),
case mgr_which_agents(ManagerNode) of
Agents1 when length(Agents1) =:= 4 ->
- p("all agents: ~p~n", [Agents1]),
+ ?IPRINT("all agents: ~p~n", [Agents1]),
ok;
Agents1 ->
?FAIL({agent_registration_failure, Agents1})
end,
- p("verify user_alfa agent(s)"),
+ ?IPRINT("verify user_alfa agent(s)"),
case mgr_which_agents(ManagerNode, user_alfa) of
Agents2 when length(Agents2) =:= 2 ->
- p("calvin agents: ~p~n", [Agents2]),
+ ?IPRINT("calvin agents: ~p", [Agents2]),
ok;
Agents2 ->
?FAIL({agent_registration_failure, Agents2})
end,
- p("verify user_beta agent(s)"),
+ ?IPRINT("verify user_beta agent(s)"),
case mgr_which_agents(ManagerNode, user_beta) of
Agents3 when length(Agents3) =:= 2 ->
- p("hobbe agents: ~p~n", [Agents3]),
+ ?IPRINT("hobbe agents: ~p", [Agents3]),
ok;
Agents3 ->
?FAIL({agent_registration_failure, Agents3})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(ManagerNode)]),
- p("unregister user user_alfa"),
+ ?IPRINT("unregister user user_alfa"),
?line ok = mgr_unregister_user(ManagerNode, user_alfa),
- p("verify all agent(s): expect 2"),
+ ?IPRINT("verify all agent(s): expect 2"),
case mgr_which_agents(ManagerNode) of
Agents4 when length(Agents4) =:= 2 ->
- p("all agents: ~p~n", [Agents4]),
+ ?IPRINT("all agents: ~p", [Agents4]),
ok;
Agents4 ->
?FAIL({agent_unregistration_failure, Agents4})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user_beta agents"),
+ ?IPRINT("unregister user_beta agents"),
?line ok = mgr_unregister_agent(ManagerNode, user_beta, 5002),
?line ok = mgr_unregister_agent(ManagerNode, user_beta, 5003),
- p("verify all agent(s): expect 0"),
+ ?IPRINT("verify all agent(s): expect 0"),
case mgr_which_agents(ManagerNode) of
[] ->
ok;
Agents5 ->
- p("all agents: ~p~n", [Agents5]),
+ ?IPRINT("all agents: ~p~n", [Agents5]),
?FAIL({agent_unregistration_failure, Agents5})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(ManagerNode)]),
- p("unregister user hobbe"),
+ ?IPRINT("unregister user hobbe"),
?line ok = mgr_unregister_user(ManagerNode, user_beta),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(ManagerNode)]),
?SLEEP(1000),
- p("stop snmp application (with only manager)"),
+ ?IPRINT("stop snmp application (with only manager)"),
?line ok = stop_snmp(ManagerNode),
?SLEEP(1000),
+ ?IPRINT("end"),
ok.
@@ -1641,7 +1700,8 @@ register_agent2(Config) when is_list(Config) ->
?TC_TRY(register_agent2, Pre, Case, Post).
do_register_agent2([ManagerNode], Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
@@ -1654,27 +1714,27 @@ do_register_agent2([ManagerNode], Config) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("load snmp application"),
+ ?IPRINT("load snmp application"),
?line ok = load_snmp(ManagerNode),
- p("set manager env for the snmp application"),
+ ?IPRINT("set manager env for the snmp application"),
?line ok = set_mgr_env(ManagerNode, Opts),
- p("starting snmp application (with only manager)"),
+ ?IPRINT("starting snmp application (with only manager)"),
?line ok = start_snmp(ManagerNode),
- p("started"),
+ ?IPRINT("started"),
?SLEEP(1000),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) user_alfa & user_beta"),
+ ?IPRINT("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register agent(s)"),
+ ?IPRINT("register agent(s)"),
TargetName1 = "agent1",
?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName1,
[{address, LocalHost},
@@ -1696,71 +1756,71 @@ do_register_agent2([ManagerNode], Config) ->
{port, 5004},
{engine_id, "agentEngineId-4"}]),
- p("verify all agent(s): expect 4"),
+ ?IPRINT("verify all agent(s): expect 4"),
case mgr_which_agents(ManagerNode) of
Agents1 when length(Agents1) =:= 4 ->
- p("all agents: ~p~n", [Agents1]),
+ ?IPRINT("all agents: ~p~n", [Agents1]),
ok;
Agents1 ->
?FAIL({agent_registration_failure, Agents1})
end,
- p("verify user_alfa agent(s)"),
+ ?IPRINT("verify user_alfa agent(s)"),
case mgr_which_agents(ManagerNode, user_alfa) of
Agents2 when length(Agents2) =:= 2 ->
- p("calvin agents: ~p~n", [Agents2]),
+ ?IPRINT("calvin agents: ~p~n", [Agents2]),
ok;
Agents2 ->
?FAIL({agent_registration_failure, Agents2})
end,
- p("verify user_beta agent(s)"),
+ ?IPRINT("verify user_beta agent(s)"),
case mgr_which_agents(ManagerNode, user_beta) of
Agents3 when length(Agents3) =:= 2 ->
- p("hobbe agents: ~p~n", [Agents3]),
+ ?IPRINT("hobbe agents: ~p~n", [Agents3]),
ok;
Agents3 ->
?FAIL({agent_registration_failure, Agents3})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user user_alfa"),
+ ?IPRINT("unregister user user_alfa"),
?line ok = mgr_unregister_user(ManagerNode, user_alfa),
- p("verify all agent(s): expect 2"),
+ ?IPRINT("verify all agent(s): expect 2"),
case mgr_which_agents(ManagerNode) of
Agents4 when length(Agents4) =:= 2 ->
- p("all agents: ~p~n", [Agents4]),
+ ?IPRINT("all agents: ~p~n", [Agents4]),
ok;
Agents4 ->
?FAIL({agent_unregistration_failure, Agents4})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user_beta agents"),
+ ?IPRINT("unregister user_beta agents"),
?line ok = mgr_unregister_agent(ManagerNode, user_beta, TargetName3),
?line ok = mgr_unregister_agent(ManagerNode, user_beta, TargetName4),
- p("verify all agent(s): expect 0"),
+ ?IPRINT("verify all agent(s): expect 0"),
case mgr_which_agents(ManagerNode) of
[] ->
ok;
Agents5 ->
- p("all agents: ~p~n", [Agents5]),
+ ?IPRINT("all agents: ~p~n", [Agents5]),
?FAIL({agent_unregistration_failure, Agents5})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user user_beta"),
+ ?IPRINT("unregister user user_beta"),
?line ok = mgr_unregister_user(ManagerNode, user_beta),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
?SLEEP(1000),
- p("stop snmp application (with only manager)"),
+ ?IPRINT("stop snmp application (with only manager)"),
?line ok = stop_snmp(ManagerNode),
?SLEEP(1000),
@@ -1785,10 +1845,11 @@ register_agent3(Config) when is_list(Config) ->
?TC_TRY(register_agent3, Pre, Case, Post).
do_register_agent3([ManagerNode], Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
- ConfDir = ?config(manager_conf_dir, Config),
- DbDir = ?config(manager_db_dir, Config),
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
LocalHost = snmp_test_lib:localhost(),
@@ -1800,27 +1861,27 @@ do_register_agent3([ManagerNode], Config) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("load snmp application"),
+ ?IPRINT("load snmp application"),
?line ok = load_snmp(ManagerNode),
- p("set manager env for the snmp application"),
+ ?IPRINT("set manager env for the snmp application"),
?line ok = set_mgr_env(ManagerNode, Opts),
- p("starting snmp application (with only manager)"),
+ ?IPRINT("starting snmp application (with only manager)"),
?line ok = start_snmp(ManagerNode),
- p("started"),
+ ?IPRINT("started"),
?SLEEP(1000),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) user_alfa & user_beta"),
+ ?IPRINT("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register agent(s)"),
+ ?IPRINT("register agent(s)"),
TargetName1 = "agent2",
?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName1,
[{tdomain, transportDomainUdpIpv4},
@@ -1840,7 +1901,7 @@ do_register_agent3([ManagerNode], Config) ->
{address, LocalHost},
{port, 5003},
{engine_id, "agentEngineId-3"}]),
- p("Expected registration failure: ~p", [Reason4]),
+ ?IPRINT("Expected registration failure: ~p", [Reason4]),
TargetName4 = "agent5",
?line {error, {unknown_domain, _} = Reason5} =
mgr_register_agent(ManagerNode, user_beta, TargetName4,
@@ -1848,69 +1909,69 @@ do_register_agent3([ManagerNode], Config) ->
{address, LocalHost},
{port, 5004},
{engine_id, "agentEngineId-4"}]),
- p("Expected registration failure: ~p", [Reason5]),
+ ?IPRINT("Expected registration failure: ~p", [Reason5]),
- p("verify all agent(s): expect 2"),
+ ?IPRINT("verify all agent(s): expect 2"),
case mgr_which_agents(ManagerNode) of
Agents1 when length(Agents1) =:= 2 ->
- p("all agents: ~p~n", [Agents1]),
+ ?IPRINT("all agents: ~p~n", [Agents1]),
ok;
Agents1 ->
?FAIL({agent_registration_failure, Agents1})
end,
- p("verify user_alfa agent(s)"),
+ ?IPRINT("verify user_alfa agent(s)"),
case mgr_which_agents(ManagerNode, user_alfa) of
Agents2 when length(Agents2) =:= 2 ->
- p("calvin agents: ~p~n", [Agents2]),
+ ?IPRINT("calvin agents: ~p~n", [Agents2]),
ok;
Agents2 ->
?FAIL({agent_registration_failure, Agents2})
end,
- p("verify user_beta agent(s)"),
+ ?IPRINT("verify user_beta agent(s)"),
case mgr_which_agents(ManagerNode, user_beta) of
Agents3 when length(Agents3) =:= 0 ->
- p("hobbe agents: ~p~n", [Agents3]),
+ ?IPRINT("hobbe agents: ~p~n", [Agents3]),
ok;
Agents3 ->
?FAIL({agent_registration_failure, Agents3})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user user_alfa"),
+ ?IPRINT("unregister user user_alfa"),
?line ok = mgr_unregister_user(ManagerNode, user_alfa),
- p("verify all agent(s): expect 0"),
+ ?IPRINT("verify all agent(s): expect 0"),
case mgr_which_agents(ManagerNode) of
Agents4 when length(Agents4) =:= 0 ->
- p("all agents: ~p~n", [Agents4]),
+ ?IPRINT("all agents: ~p~n", [Agents4]),
ok;
Agents4 ->
?FAIL({agent_unregistration_failure, Agents4})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("verify all agent(s): expect 0"),
+ ?IPRINT("verify all agent(s): expect 0"),
case mgr_which_agents(ManagerNode) of
[] ->
ok;
Agents5 ->
- p("all agents: ~p~n", [Agents5]),
+ ?EPRINT("all agents: ~p~n", [Agents5]),
?FAIL({agent_unregistration_failure, Agents5})
end,
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user user_beta"),
+ ?IPRINT("unregister user user_beta"),
?line ok = mgr_unregister_user(ManagerNode, user_beta),
- p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+ ?IPRINT("manager info: ~p~n", [mgr_info(ManagerNode)]),
?SLEEP(1000),
- p("stop snmp application (with only manager)"),
+ ?IPRINT("stop snmp application (with only manager)"),
?line ok = stop_snmp(ManagerNode),
?SLEEP(1000),
@@ -1928,7 +1989,8 @@ simple_sync_get2(Config) when is_list(Config) ->
fun() -> do_simple_sync_get2(Config) end).
do_simple_sync_get2(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Get = fun(Node, TargetName, Oids) ->
mgr_user_sync_get(Node, TargetName, Oids)
end,
@@ -1938,16 +2000,17 @@ do_simple_sync_get2(Config) ->
Res.
do_simple_sync_get2(Config, Get, PostVerify) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Node = ?config(manager_node, Config),
TargetName = ?config(manager_agent_target_name, Config),
- p("issue get-request without loading the mib"),
+ ?IPRINT("issue get-request without loading the mib"),
Oids1 = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance],
?line ok = do_simple_sync_get2(Node, TargetName, Oids1, Get, PostVerify),
- p("issue get-request after first loading the mibs"),
+ ?IPRINT("issue get-request after first loading the mibs"),
?line ok = mgr_user_load_mib(Node, std_mib()),
Oids2 = [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]],
?line ok = do_simple_sync_get2(Node, TargetName, Oids2, Get, PostVerify),
@@ -1969,17 +2032,19 @@ do_simple_sync_get2(Node, TargetName, Oids, Get, PostVerify)
value = SysDescr},
#varbind{oid = ?sysUpTime_instance,
value = SysUpTime}]} ->
- p("expected result from get: "
- "~n SysObjectID: ~p"
- "~n SysDescr: ~s"
- "~n SysUpTime: ~w",
- [SysObjectID, SysDescr, SysUpTime]),
+ ?IPRINT("expected result from get: "
+ "~n SysObjectID: ~p"
+ "~n SysDescr: ~s"
+ "~n SysUpTime: ~w",
+ [SysObjectID, SysDescr, SysUpTime]),
PostVerify();
{noError, 0, Vbs} ->
- p("unexpected varbinds: ~n~p", [Vbs]),
+ ?EPRINT("unexpected varbinds: "
+ "~n ~p", [Vbs]),
{error, {unexpected_vbs, Vbs}};
Else ->
- p("unexpected reply: ~n~p", [Else]),
+ ?EPRINT("unexpected reply: "
+ "~n ~p", [Else]),
{error, {unexpected_response, Else}}
end,
ok.
@@ -1995,7 +2060,8 @@ simple_sync_get3(Config) when is_list(Config) ->
fun() -> do_simple_sync_get3(Config) end).
do_simple_sync_get3(Config) ->
- p("starting with Config: ~n~p", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Self = self(),
Msg = simple_sync_get3,
Fun = fun() -> Self ! Msg end,
@@ -2024,7 +2090,7 @@ do_simple_sync_get3(Config) ->
%%======================================================================
sag_verify({noError, 0, _Vbs}, any) ->
- p("verified [any]"),
+ ?IPRINT("verified [any]"),
ok;
sag_verify({noError, 0, Vbs}, Exp) ->
?DBG("verified first stage ok: "
@@ -2042,13 +2108,13 @@ sag_verify_vbs(Vbs, []) ->
sag_verify_vbs([], Exp) ->
{error, {expected_vbs, Exp}};
sag_verify_vbs([#varbind{oid = Oid}|Vbs], [any|Exp]) ->
- p("verified [any] oid ~w", [Oid]),
+ ?IPRINT("verified [any] oid ~w", [Oid]),
sag_verify_vbs(Vbs, Exp);
sag_verify_vbs([#varbind{oid = Oid, value = Value}|Vbs], [Oid|Exp]) ->
- p("verified oid ~w [~p]", [Oid, Value]),
+ ?IPRINT("verified oid ~w [~p]", [Oid, Value]),
sag_verify_vbs(Vbs, Exp);
sag_verify_vbs([#varbind{oid = Oid, value = Value}|Vbs], [{Oid,Value}|Exp]) ->
- p("verified oid ~w and ~p", [Oid, Value]),
+ ?IPRINT("verified oid ~w and ~p", [Oid, Value]),
sag_verify_vbs(Vbs, Exp);
sag_verify_vbs([Vb|_], [E|_]) ->
{error, {unexpected_vb, Vb, E}}.
@@ -2064,7 +2130,8 @@ simple_async_get2(Config) when is_list(Config) ->
fun() -> do_simple_async_get2(Config) end).
do_simple_async_get2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
TargetName = ?config(manager_agent_target_name, Config),
@@ -2123,13 +2190,17 @@ do_simple_async_sync_get2(MgrInfo, AgentInfo, Get, PostVerify)
end}
],
- p("manager info when starting test: ~n~p", [MgrInfo()]),
- p("agent info when starting test: ~n~p", [AgentInfo()]),
+ ?IPRINT("manager info when starting test: "
+ "~n ~p", [MgrInfo()]),
+ ?IPRINT("agent info when starting test: "
+ "~n ~p", [AgentInfo()]),
?line ok = async_exec(Requests, []),
- p("manager info when ending test: ~n~p", [MgrInfo()]),
- p("agent info when ending test: ~n~p", [AgentInfo()]),
+ ?IPRINT("manager info when ending test: "
+ "~n ~p", [MgrInfo()]),
+ ?IPRINT("agent info when ending test: "
+ "~n ~p", [AgentInfo()]),
ok.
@@ -2147,7 +2218,8 @@ simple_async_get3(Config) when is_list(Config) ->
fun() -> do_simple_async_get3(Config) end).
do_simple_async_get3(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
TargetName = ?config(manager_agent_target_name, Config),
@@ -2215,7 +2287,8 @@ simple_sync_get_next2(Config) when is_list(Config) ->
fun() -> do_simple_sync_get_next2(Config) end).
do_simple_sync_get_next2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
GetNext = fun(Node, TargetName, Oids) ->
mgr_user_sync_get_next(Node, TargetName, Oids)
@@ -2318,7 +2391,7 @@ do_simple_sync_get_next2(Config, GetNext, PostVerify)
do_simple_get_next(N, Node, TargetName, Oids, Verify, GetNext, PostVerify) ->
- p("issue get-next command ~w", [N]),
+ ?IPRINT("issue get-next command ~w", [N]),
case GetNext(Node, TargetName, Oids) of
{ok, Reply, _Rem} ->
?DBG("get-next ok:"
@@ -2340,7 +2413,8 @@ simple_sync_get_next3(suite) -> [];
simple_sync_get_next3(Config) when is_list(Config) ->
process_flag(trap_exit, true),
put(tname, ssgn3),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Self = self(),
Msg = simple_sync_get_next3,
Fun = fun() -> Self ! Msg end,
@@ -2370,7 +2444,8 @@ simple_async_get_next2(Config) when is_list(Config) ->
fun() -> do_simple_async_get_next2(Config) end).
do_simple_async_get_next2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2457,13 +2532,17 @@ do_simple_async_get_next2(MgrNode, AgentNode, GetNext, PostVerify)
end}
],
- p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when starting test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when starting test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when starting test: "
+ "~n ~p", [agent_info(AgentNode)]),
?line ok = async_exec(Requests, []),
- p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when ending test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when ending test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when ending test: "
+ "~n ~p", [agent_info(AgentNode)]),
ok.
@@ -2501,7 +2580,8 @@ simple_async_get_next3(Case, Config) when is_list(Config) ->
do_simple_async_get_next3(Config) ->
%% process_flag(trap_exit, true),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2559,7 +2639,8 @@ simple_sync_set2(Config) when is_list(Config) ->
fun() -> do_simple_sync_set2(Config) end).
do_simple_sync_set2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Set = fun(Node, TargetName, VAVs) ->
mgr_user_sync_set(Node, TargetName, VAVs)
@@ -2576,7 +2657,7 @@ do_simple_sync_set2(Config, Set, PostVerify)
Node = ?config(manager_node, Config),
TargetName = ?config(manager_agent_target_name, Config),
- p("issue set-request without loading the mib"),
+ ?IPRINT("issue set-request without loading the mib"),
Val11 = "Arne Anka",
Val12 = "Stockholm",
VAVs1 = [
@@ -2585,7 +2666,7 @@ do_simple_sync_set2(Config, Set, PostVerify)
],
?line ok = do_simple_set2(Node, TargetName, VAVs1, Set, PostVerify),
- p("issue set-request after first loading the mibs"),
+ ?IPRINT("issue set-request after first loading the mibs"),
?line ok = mgr_user_load_mib(Node, std_mib()),
Val21 = "Sune Anka",
Val22 = "Gothenburg",
@@ -2615,7 +2696,8 @@ do_simple_set2(Node, TargetName, VAVs, Set, PostVerify) ->
{noError, 0, Vbs} ->
{error, {unexpected_vbs, Vbs}};
Else ->
- p("unexpected reply: ~n~p", [Else]),
+ ?EPRINT("unexpected reply: "
+ "~n ~p", [Else]),
{error, {unexpected_response, Else}}
end,
ok.
@@ -2631,7 +2713,8 @@ simple_sync_set3(Config) when is_list(Config) ->
fun() -> do_simple_sync_set3(Config) end).
do_simple_sync_set3(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p", [Config]),
Self = self(),
Msg = simple_sync_set3,
@@ -2655,7 +2738,7 @@ do_simple_sync_set3(Config) ->
%%======================================================================
sas_verify({noError, 0, _Vbs}, any) ->
- p("verified [any]"),
+ ?IPRINT("verified [any]"),
ok;
sas_verify({noError, 0, Vbs}, Expected) ->
?DBG("verified stage 1: "
@@ -2672,13 +2755,13 @@ sas_verify_vbs(Vbs, []) ->
sas_verify_vbs([], Exp) ->
{error, {expected_vbs, Exp}};
sas_verify_vbs([#varbind{oid = Oid}|Vbs], [any|Exp]) ->
- p("verified [any] oid ~w", [Oid]),
+ ?IPRINT("verified [any] oid ~w", [Oid]),
sas_verify_vbs(Vbs, Exp);
sas_verify_vbs([#varbind{oid = Oid, value = Value}|Vbs], [Oid|Exp]) ->
- p("verified oid ~w [~p]", [Oid, Value]),
+ ?IPRINT("verified oid ~w [~p]", [Oid, Value]),
sas_verify_vbs(Vbs, Exp);
sas_verify_vbs([#varbind{oid = Oid, value = Value}|Vbs], [{Oid,Value}|Exp]) ->
- p("verified oid ~w and ~p", [Oid, Value]),
+ ?IPRINT("verified oid ~w and ~p", [Oid, Value]),
sas_verify_vbs(Vbs, Exp);
sas_verify_vbs([Vb|_], [E|_]) ->
{error, {unexpected_vb, Vb, E}}.
@@ -2694,7 +2777,9 @@ simple_async_set2(Config) when is_list(Config) ->
fun() -> do_simple_async_set2(Config) end).
do_simple_async_set2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2744,13 +2829,17 @@ do_simple_async_set2(MgrNode, AgentNode, Set, PostVerify) ->
end}
],
- p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when starting test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when starting test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when starting test: "
+ "~n ~p", [agent_info(AgentNode)]),
?line ok = async_exec(Requests, []),
- p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when ending test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when ending test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when ending test: "
+ "~n ~p", [agent_info(AgentNode)]),
ok.
@@ -2784,7 +2873,8 @@ simple_async_set3(Case, Config) ->
fun() -> do_simple_async_set3(Config) end).
do_simple_async_set3(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2867,7 +2957,8 @@ simple_sync_get_bulk2(Config) when is_list(Config) ->
fun() -> do_simple_sync_get_bulk2(Config) end).
do_simple_sync_get_bulk2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -2982,7 +3073,7 @@ do_simple_sync_get_bulk2(Config, MgrNode, AgentNode, GetBulk, PostVerify) ->
%% -- 11 --
?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2),
- p("TCnt2: ~p", [TCnt2]),
+ ?IPRINT("TCnt2: ~p", [TCnt2]),
VF11 = fun(X) ->
verify_ssgb_reply2(X,
[{fl([TCnt2,2]), 100},
@@ -3001,7 +3092,7 @@ do_simple_get_bulk2(N,
when is_function(Verify, 1) andalso
is_function(GetBulk, 3) andalso
is_function(PostVerify) ->
- p("issue get-bulk command ~w", [N]),
+ ?IPRINT("issue get-bulk command ~w", [N]),
case GetBulk(NonRep, MaxRep, Oids) of
{ok, Reply, _Rem} ->
?DBG("get-bulk ok:"
@@ -3025,7 +3116,8 @@ simple_sync_get_bulk3(Config) when is_list(Config) ->
fun() -> do_simple_sync_get_bulk3(Config) end).
do_simple_sync_get_bulk3(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3064,7 +3156,8 @@ simple_async_get_bulk2(Config) when is_list(Config) ->
fun() -> do_simple_async_get_bulk2(Config) end).
do_simple_async_get_bulk2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~p ~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3196,13 +3289,17 @@ do_simple_async_get_bulk2(MgrNode, AgentNode, GetBulk, PostVerify) ->
VF10}
],
- p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when starting test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when starting test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when starting test: "
+ "~n ~p", [agent_info(AgentNode)]),
?line ok = async_exec(Requests, []),
- p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when ending test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when ending test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when ending test: "
+ "~n ~p", [agent_info(AgentNode)]),
ok.
@@ -3226,7 +3323,8 @@ simple_async_get_bulk3(Case, Config) ->
do_simple_async_get_bulk3(Config) ->
process_flag(trap_exit, true),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3292,7 +3390,9 @@ misc_async2(Config) when is_list(Config) ->
fun() -> do_misc_async2(Config) end).
do_misc_async2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3461,13 +3561,17 @@ do_misc_async2(Config) ->
end}
],
- p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when starting test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when starting test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when starting test: "
+ "~n ~p", [agent_info(AgentNode)]),
?line ok = async_exec(Requests, []),
- p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]),
- p("agent info when ending test: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info when ending test: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info when ending test: "
+ "~n ~p", [agent_info(AgentNode)]),
display_log(Config),
ok.
@@ -3493,45 +3597,47 @@ collect_traps(0, TrapInfo) ->
collect_traps(N, Acc) ->
receive
{async_event, _From, {trap, TrapInfo}} ->
- p("collect_traps -> received trap: ~n ~p", [TrapInfo]),
+ ?IPRINT("collect_traps -> received trap: "
+ "~n ~p", [TrapInfo]),
collect_traps(N-1, [TrapInfo|Acc])
after 10000 ->
- p("collect_traps -> still awaiting ~w trap(s) - giving up", [N]),
+ ?WPRINT("collect_traps -> still awaiting ~w trap(s) - giving up", [N]),
Acc
end.
verify_traps([], []) ->
- p("verify_traps -> done"),
+ ?IPRINT("verify_traps -> done"),
ok;
verify_traps([], Verifiers) ->
- p("verify_traps -> done when ~w verifiers remain", [length(Verifiers)]),
+ ?IPRINT("verify_traps -> done when ~w verifiers remain", [length(Verifiers)]),
{error, {failed_verify, [Id || {Id, _} <- Verifiers]}};
verify_traps([Trap|Traps], Verifiers0) ->
- p("verify_traps -> entry"),
+ ?IPRINT("verify_traps -> entry"),
case verify_trap(Trap, Verifiers0) of
{ok, Id} ->
- p("verify_traps -> trap verified: ~p", [Id]),
+ ?IPRINT("verify_traps -> trap verified: ~p", [Id]),
Verifiers = lists:keydelete(Id, 1, Verifiers0),
verify_traps(Traps, Verifiers);
error ->
- p("verify_traps -> failed verifying trap: ~n ~p", [Trap]),
+ ?EPRINT("verify_traps -> failed verifying trap: "
+ "~n ~p", [Trap]),
{error, {failed_verifying_trap, Trap}}
end.
verify_trap(Trap, []) ->
- p("verify_trap -> could not verify trap:"
- "~n Trap: ~p", [Trap]),
+ ?EPRINT("verify_trap -> could not verify trap:"
+ "~n Trap: ~p", [Trap]),
error;
verify_trap(Trap, [{Id, Verifier}|Verifiers]) ->
- p("verify_trap -> entry with"
- "~n Id: ~p"
- "~n Trap: ~p", [Id, Trap]),
+ ?IPRINT("verify_trap -> entry with"
+ "~n Id: ~p"
+ "~n Trap: ~p", [Id, Trap]),
case Verifier(Trap) of
ok ->
- p("verify_trap -> verified"),
+ ?IPRINT("verify_trap -> verified"),
{ok, Id};
{error, _} ->
- p("verify_trap -> not verified"),
+ ?NPRINT("verify_trap -> not verified"),
verify_trap(Trap, Verifiers)
end.
@@ -3544,7 +3650,9 @@ trap1(Config) when is_list(Config) ->
fun() -> do_trap1(Config) end).
do_trap1(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3565,32 +3673,33 @@ do_trap1(Config) ->
fun(Ent, Gen, Spec, ExpVBs, Trap) ->
case Trap of
{Ent, Gen, Spec, _Timestamp, VBs} ->
- p("trap info as expected"),
+ ?IPRINT("trap info as expected"),
case (catch validate_vbs(MgrNode,
ExpVBs, VBs)) of
ok ->
- p("valid trap"),
+ ?IPRINT("valid trap"),
ok;
Error ->
- p("invalid trap: ~n Error: ~p", [Error]),
+ ?EPRINT("invalid trap: "
+ "~n ~p", [Error]),
Error
end;
{Enteprise, Generic, Spec, Timestamp, VBs} ->
- p("unepxected v1 trap info:"
- "~n Enteprise: ~p"
- "~n Generic: ~p"
- "~n Spec: ~p"
- "~n Timestamp: ~p"
- "~n VBs: ~p",
- [Enteprise, Generic, Spec, Timestamp, VBs]),
+ ?EPRINT("unepxected v1 trap info:"
+ "~n Enteprise: ~p"
+ "~n Generic: ~p"
+ "~n Spec: ~p"
+ "~n Timestamp: ~p"
+ "~n VBs: ~p",
+ [Enteprise, Generic, Spec, Timestamp, VBs]),
ExpTrap = {Ent, Gen, Spec, ignore, ExpVBs},
Reason = {unexpected_trap, {ExpTrap, Trap}},
{error, Reason};
{Err, Idx, VBs} ->
- p("unexpected trap info: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected trap info: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -3601,24 +3710,25 @@ do_trap1(Config) ->
fun(ExpVBs, Trap) ->
case Trap of
{noError, 0, VBs0} ->
- p("trap info as expected: ~n~p", [VBs0]),
+ ?IPRINT("trap info as expected: "
+ "~n ~p", [VBs0]),
%% The first two are a timestamp and oid
[_,_|VBs] = VBs0,
case (catch validate_vbs(MgrNode,
ExpVBs, VBs)) of
ok ->
- p("valid trap"),
+ ?IPRINT("valid trap"),
ok;
Error ->
- p("invalid trap: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid trap: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -3629,8 +3739,10 @@ do_trap1(Config) ->
%% Collect various info about the manager and the agent
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -3699,7 +3811,9 @@ trap2(Config) when is_list(Config) ->
fun() -> do_trap2(Config) end).
do_trap2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3720,32 +3834,32 @@ do_trap2(Config) ->
fun(Ent, Gen, Spec, ExpVBs, Trap) ->
case Trap of
{Ent, Gen, Spec, _Timestamp, VBs} ->
- p("trap info as expected"),
+ ?IPRINT("trap info as expected"),
case (catch validate_vbs(MgrNode,
ExpVBs, VBs)) of
ok ->
- p("valid trap"),
+ ?IPRINT("valid trap"),
ok;
Error ->
- p("invalid trap: ~n Error: ~p", [Error]),
+ ?EPRINT("invalid trap: ~n Error: ~p", [Error]),
Error
end;
{Enteprise, Generic, Spec, Timestamp, VBs} ->
- p("unepxected v1 trap info:"
- "~n Enteprise: ~p"
- "~n Generic: ~p"
- "~n Spec: ~p"
- "~n Timestamp: ~p"
- "~n VBs: ~p",
- [Enteprise, Generic, Spec, Timestamp, VBs]),
+ ?EPRINT("unepxected v1 trap info:"
+ "~n Enteprise: ~p"
+ "~n Generic: ~p"
+ "~n Spec: ~p"
+ "~n Timestamp: ~p"
+ "~n VBs: ~p",
+ [Enteprise, Generic, Spec, Timestamp, VBs]),
ExpTrap = {Ent, Gen, Spec, ignore, ExpVBs},
Reason = {unexpected_trap, {ExpTrap, Trap}},
{error, Reason};
{Err, Idx, VBs} ->
- p("unexpected trap info: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected trap info: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -3756,24 +3870,24 @@ do_trap2(Config) ->
fun(ExpVBs, Trap) ->
case Trap of
{noError, 0, VBs0} ->
- p("trap info as expected: ~n~p", [VBs0]),
+ ?IPRINT("trap info as expected: ~n~p", [VBs0]),
%% The first two are a timestamp and oid
[_,_|VBs] = VBs0,
case (catch validate_vbs(MgrNode,
ExpVBs, VBs)) of
ok ->
- p("valid trap"),
+ ?IPRINT("valid trap"),
ok;
Error ->
- p("invalid trap: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid trap: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -3783,8 +3897,10 @@ do_trap2(Config) ->
%% Collect various info about the manager and the agent
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -3894,7 +4010,9 @@ inform1(Config) when is_list(Config) ->
fun() -> do_inform1(Config) end).
do_inform1(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -3913,9 +4031,12 @@ do_inform1(Config) ->
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("manager system info: ~n~p", [mgr_sys_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("manager system info: "
+ "~n ~p", [mgr_sys_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -3929,26 +4050,26 @@ do_inform1(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
+ ?IPRINT("valid inform"),
Pid ! {handle_inform_no_response,
From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -3966,25 +4087,25 @@ do_inform1(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
+ ?IPRINT("valid inform"),
Pid ! {handle_inform_response, From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -4023,7 +4144,9 @@ inform2(Config) when is_list(Config) ->
fun() -> do_inform2(Config) end).
do_inform2(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -4043,8 +4166,10 @@ do_inform2(Config) ->
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -4062,7 +4187,7 @@ do_inform2(Config) ->
fun() ->
receive
{snmp_targets, inform2_tag1, Addrs} ->
- p("sent inform to ~p", [Addrs]),
+ ?IPRINT("sent inform to ~p", [Addrs]),
ok
after 10000 ->
receive
@@ -4078,26 +4203,26 @@ do_inform2(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
+ ?IPRINT("valid inform"),
Pid ! {handle_inform_no_response,
From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?IPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -4115,25 +4240,25 @@ do_inform2(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
+ ?IPRINT("valid inform"),
Pid ! {handle_inform_response, From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -4151,14 +4276,14 @@ do_inform2(Config) ->
fun() ->
receive
{snmp_notification, inform2_tag1, {got_response, Addr}} ->
- p("received expected \"got response\" notification "
- "from: "
- "~n ~p", [Addr]),
+ ?IPRINT("received expected \"got response\" notification "
+ "from: "
+ "~n ~p", [Addr]),
ok;
{snmp_notification, inform2_tag1, {no_response, Addr}} ->
- e("Received unexpected \"no response\" "
- "notification from: "
- "~n ~p", [Addr]),
+ ?EPRINT("Received unexpected \"no response\" "
+ "notification from: "
+ "~n ~p", [Addr]),
{error, no_response}
after 10000 ->
receive
@@ -4197,7 +4322,8 @@ inform3(Config) when is_list(Config) ->
fun() -> do_inform3(Config) end).
do_inform3(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -4215,8 +4341,10 @@ do_inform3(Config) ->
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -4234,7 +4362,7 @@ do_inform3(Config) ->
fun() ->
receive
{snmp_targets, inform3_tag1, [_Addr]} ->
- p("received inform-sent acknowledgement", []),
+ ?IPRINT("received inform-sent ack"),
ok
after 10000 ->
receive
@@ -4250,26 +4378,25 @@ do_inform3(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
- Pid ! {handle_inform_no_response,
- From},
+ ?IPRINT("valid inform"),
+ Pid ! {handle_inform_no_response, From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -4287,15 +4414,15 @@ do_inform3(Config) ->
fun() ->
receive
{snmp_notification, inform3_tag1, {no_response, Addr}} ->
- p("received expected \"no response\" notification "
- "from: "
- "~n ~p", [Addr]),
+ ?IPRINT("received expected \"no response\" notification "
+ "from: "
+ "~n ~p", [Addr]),
ok;
{snmp_notification, inform3_tag1, {got_response, Addr}} ->
- e("Received unexpected \"got response\" "
- "notification from: "
- "~n ~p",
- [Addr]),
+ ?EPRINT("Received unexpected \"got response\" "
+ "notification from: "
+ "~n ~p",
+ [Addr]),
{error, {got_response, Addr}}
after 120000 ->
receive
@@ -4335,7 +4462,8 @@ inform4(Config) when is_list(Config) ->
fun() -> do_inform4(Config) end).
do_inform4(Config) ->
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~n ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -4353,8 +4481,10 @@ do_inform4(Config) ->
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -4368,13 +4498,13 @@ do_inform4(Config) ->
fun() ->
receive
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
case (catch validate_testTrapv22_vbs(MgrNode,
VBs)) of
ok ->
- p("valid inform"),
+ ?IPRINT("valid inform"),
%% Actually, as we have
%% configured the manager in
%% this test case (irb = auto)
@@ -4382,15 +4512,15 @@ do_inform4(Config) ->
Pid ! {handle_inform_response, From},
ok;
Error ->
- p("invalid inform: ~n Error: ~p",
- [Error]),
+ ?EPRINT("invalid inform: "
+ "~n ~p", [Error]),
Error
end;
{Err, Idx, VBs} ->
- p("unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end
@@ -4409,11 +4539,11 @@ do_inform4(Config) ->
%% fun() ->
%% receive
%% {async_event, _ReqId, {error, Reason}} ->
-%% p("received error"),
+%% ?IPRINT("received error"),
%% case Reason of
%% {failed_processing_message,
%% {securityError, usmStatsUnknownEngineIDs}} ->
-%% p("expected error"),
+%% ?IPRINT("expected error"),
%% ok;
%% _ ->
%% p("unexpected error: "
@@ -4469,7 +4599,8 @@ inform_swarm(Case, Config) ->
do_inform_swarm(Config) ->
%% process_flag(trap_exit, true),
- p("starting with Config: ~p~n", [Config]),
+ ?IPRINT("starting with Config: "
+ "~p ~n", [Config]),
MgrNode = ?config(manager_node, Config),
AgentNode = ?config(agent_node, Config),
@@ -4498,7 +4629,7 @@ do_inform_swarm(Config) ->
Seqs = lists:seq(1, NumInforms),
lists:foreach(
fun(N) ->
- p("send notification ~w", [N]),
+ ?IPRINT("send notification ~w", [N]),
agent_send_notif(AgentNode,
testTrapv22,
{{inform2_tag1, N}, Collector},
@@ -4509,11 +4640,11 @@ do_inform_swarm(Config) ->
if
N rem 100 == 0 ->
Sleep = 1000,
- p("sleep ~w [~w]", [Sleep, N]),
+ ?IPRINT("sleep ~w [~w]", [Sleep, N]),
?SLEEP(Sleep);
N rem 10 == 0 ->
Sleep = 100,
- p("sleep ~w [~w]", [Sleep, N]),
+ ?IPRINT("sleep ~w [~w]", [Sleep, N]),
?SLEEP(Sleep);
true ->
ok
@@ -4525,8 +4656,10 @@ do_inform_swarm(Config) ->
Cmd1 =
fun() ->
- p("manager info: ~n~p", [mgr_info(MgrNode)]),
- p("agent info: ~n~p", [agent_info(AgentNode)]),
+ ?IPRINT("manager info: "
+ "~n ~p", [mgr_info(MgrNode)]),
+ ?IPRINT("agent info: "
+ "~n ~p", [agent_info(AgentNode)]),
ok
end,
@@ -4555,7 +4688,7 @@ do_inform_swarm(Config) ->
inform_swarm_collector(N) ->
- inform_swarm_collector(N, 0, 0, 0, 10000).
+ inform_swarm_collector(N, 0, 0, 0, ?SECS(60)).
%% Note that we need to deal with re-transmissions!
%% That is, the agent did not receive the ack in time,
@@ -4571,60 +4704,65 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, _)
when ((N == SentAckCnt) and
(N == RespCnt) and
(N =< RecvCnt)) ->
- p("inform_swarm_collector -> done when"
- "~n N: ~w"
- "~n SentAckCnt: ~w"
- "~n RecvCnt: ~w"
- "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]),
+ ?IPRINT("inform_swarm_collector -> done when"
+ "~n N: ~w"
+ "~n SentAckCnt: ~w"
+ "~n RecvCnt: ~w"
+ "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]),
ok;
inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) ->
- p("inform_swarm_collector -> entry with"
- "~n N: ~w"
- "~n SentAckCnt: ~w"
- "~n RecvCnt: ~w"
- "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]),
+ %% ?IPRINT("inform_swarm_collector -> entry with"
+ %% "~n N: ~w"
+ %% "~n SentAckCnt: ~w"
+ %% "~n RecvCnt: ~w"
+ %% "~n RespCnt: ~w", [N, SentAckCnt, RecvCnt, RespCnt]),
receive
{snmp_targets, {inform2_tag1, Id}, [_Addr]} ->
- p("received inform-sent acknowledgement for ~w", [Id]),
+ ?IPRINT("received inform-sent acknowledgement for ~w", [Id]),
inform_swarm_collector(N, SentAckCnt+1, RecvCnt, RespCnt,
Timeout);
%% The manager has received the actual inform
{async_event, From, {inform, Pid, Inform}} ->
- p("received inform"),
+ ?IPRINT("received inform"),
case Inform of
{noError, 0, VBs} when is_list(VBs) ->
Pid ! {handle_inform_response, From},
inform_swarm_collector(N, SentAckCnt, RecvCnt+1, RespCnt,
Timeout);
{Err, Idx, VBs} ->
- e("Unexpected error status: "
- "~n Err: ~p"
- "~n Idx: ~p"
- "~n VBs: ~p", [Err, Idx, VBs]),
+ ?EPRINT("Unexpected error status: "
+ "~n Err: ~p"
+ "~n Idx: ~p"
+ "~n VBs: ~p", [Err, Idx, VBs]),
Reason = {unexpected_status, {Err, Idx, VBs}},
{error, Reason}
end;
%% The agent has received ack from the manager
{snmp_notification, {inform2_tag1, Id}, {got_response, Addr}} ->
- p("received expected \"got response\" for ~w "
- "notification from: "
- "~n ~p",
- [Id, Addr]),
+ ?IPRINT("received expected \"got response\" for ~w "
+ "notification from: "
+ "~n ~p", [Id, Addr]),
inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt+1,
Timeout);
%% The agent did not received ack from the manager in time
{snmp_notification, inform2_tag1, {no_response, Addr}} ->
- e("Received expected \"no response\" notification "
- "from: "
- "~n ~p", [Addr]),
+ ?EPRINT("Received expected \"no response\" notification "
+ "from: "
+ "~n ~p", [Addr]),
Reason = {no_response, Addr, {N, SentAckCnt, RecvCnt, RespCnt}},
{error, Reason}
after Timeout ->
%% Give up when we have been dead in the water for Timeout ms
+ ?EPRINT("timeout when"
+ "~n N: ~p"
+ "~n SentAckCnt: ~p"
+ "~n RecvCnt: ~p"
+ "~n RespCnt: ~p",
+ [N, SentAckCnt, RecvCnt, RespCnt]),
{error, {timeout, N, SentAckCnt, RecvCnt, RespCnt}}
end.
@@ -4642,48 +4780,54 @@ report(Config) when is_list(Config) ->
otp8015_1(doc) -> ["OTP-8015:1 - testing the new api-function."];
otp8015_1(suite) -> [];
otp8015_1(Config) when is_list(Config) ->
- ?TC_TRY(otp8015_1,
- fun() -> do_otp8015_1(Config) end).
+ Pre = fun() ->
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
+
+ write_manager_conf(ConfDir),
+
+ Opts = [{server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {note_store, [{verbosity, trace}]},
+ {config, [{verbosity, trace},
+ {dir, ConfDir},
+ {db_dir, DbDir}]}],
+
+ ?IPRINT("starting manager"),
+ ok = snmpm:start_link(Opts),
+
+ ?SLEEP(1000),
+ ok
+ end,
+ Case = fun(_) -> do_otp8015_1(Config) end,
+ Post = fun(_) ->
+ ?IPRINT("stop manager"),
+ ok = snmpm:stop(),
+ ?SLEEP(1000),
+ ok
+ end,
+ ?TC_TRY(otp8015_1, Pre, Case, Post).
do_otp8015_1(Config) ->
- p("starting with Config: ~p~n", [Config]),
-
- ConfDir = ?config(manager_conf_dir, Config),
- DbDir = ?config(manager_db_dir, Config),
-
- write_manager_conf(ConfDir),
-
- Opts = [{server, [{verbosity, trace}]},
- {net_if, [{verbosity, trace}]},
- {note_store, [{verbosity, trace}]},
- {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
-
- p("starting manager"),
- ok = snmpm:start_link(Opts),
-
- ?SLEEP(1000),
+ ?IPRINT("starting with Config: "
+ "~n ~p"
+ "~n", [Config]),
snmpm:load_mib(std_mib()),
snmpm:load_mib(test_trap_mib(Config)),
- p("manager started, now sleep some"),
+ ?IPRINT("manager started, now sleep some"),
?SLEEP(1000),
- p("loaded mibs: ~p", [snmpm:which_mibs()]),
+ ?IPRINT("loaded mibs: ~p", [snmpm:which_mibs()]),
- p("get some type(s) from the mibs"),
+ ?IPRINT("get some type(s) from the mibs"),
{ok, 'Counter32'} = snmpm:oid_to_type(?snmpOutTraps),
- {ok, [IfIndex]} = snmpm:name_to_oid(ifIndex),
- {ok, 'INTEGER'} = snmpm:oid_to_type(IfIndex),
+ {ok, [IfIndex]} = snmpm:name_to_oid(ifIndex),
+ {ok, 'INTEGER'} = snmpm:oid_to_type(IfIndex),
-
- p("stop manager"),
- ok = snmpm:stop(),
-
- ?SLEEP(1000),
-
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -4704,27 +4848,30 @@ do_otp8395_1(Config) ->
%%======================================================================
async_exec([], Acc) ->
- p("all async request's sent => now await reponses"),
+ ?IPRINT("all async request's sent => now await responses"),
async_verify(async_collector(Acc, []));
async_exec([{Id, Data, Exec, Ver}|Reqs], Acc) ->
- p("issue async request ~w", [Id]),
+ ?IPRINT("issue async request ~w", [Id]),
?line {ok, ReqId} = Exec(Data),
async_exec(Reqs, [{ReqId, Id, Ver}|Acc]).
async_collector([], Acc) ->
- p("received replies for all requests - now sort"),
+ ?IPRINT("received replies for all requests - now sort"),
lists:keysort(1, Acc);
async_collector(Expected, Acc) ->
receive
{async_event, ReqId, Reply} ->
- p("received async event with request-id ~w", [ReqId]),
+ ?IPRINT("received async event with request-id ~w", [ReqId]),
case lists:keysearch(ReqId, 1, Expected) of
{value, {_, Id, Ver}} ->
- p("event was for request ~w", [Id]),
+ ?IPRINT("event was for request ~w", [Id]),
Expected2 = lists:keydelete(ReqId, 1, Expected),
async_collector(Expected2, [{Id, Ver, Reply}|Acc]);
false ->
% Duplicate reply?
+ ?EPRINT("unexpected async event: "
+ "~n ReqId: ~p"
+ "~n Reply: ~p", [ReqId, Reply]),
?FAIL({unexpected_async_event, ReqId, Reply})
end
after 10000 ->
@@ -4734,7 +4881,7 @@ async_collector(Expected, Acc) ->
async_verify([]) ->
ok;
async_verify([{Id, Verify, Reply}|Replies]) ->
- p("verify reply ~w", [Id]),
+ ?IPRINT("verify reply ~w", [Id]),
Verify(Reply),
async_verify(Replies).
@@ -4791,17 +4938,19 @@ purify_oid(Node, Oid) ->
command_handler([]) ->
ok;
command_handler([{No, Desc, Cmd}|Cmds]) ->
- p("command_handler -> command ~w: "
- "~n ~s", [No, Desc]),
+ ?IPRINT("command_handler -> command ~w: "
+ "~n ~s", [No, Desc]),
case (catch Cmd()) of
ok ->
- p("command_handler -> ~w: ok",[No]),
+ ?IPRINT("command_handler -> ~w: ok", [No]),
command_handler(Cmds);
{error, Reason} ->
- e("Command_handler -> ~w error: ~n~p",[No, Reason]),
+ ?EPRINT("Command_handler -> ~w error: "
+ "~n ~p", [No, Reason]),
?line ?FAIL({command_failed, No, Reason});
Error ->
- e("Command_handler -> ~w unexpected: ~n~p",[No, Error]),
+ ?EPRINT("Command_handler -> ~w unexpected: "
+ "~n ~p", [No, Error]),
?line ?FAIL({unexpected_command_result, No, Error})
end.
@@ -4810,9 +4959,9 @@ command_handler([{No, Desc, Cmd}|Cmds]) ->
init_manager(AutoInform, Config) ->
- ?LOG("init_manager -> entry with"
- "~n AutoInform: ~p"
- "~n Config: ~p", [AutoInform, Config]),
+ ?IPRINT("init_manager -> entry with"
+ "~n AutoInform: ~p"
+ "~n Config: ~p", [AutoInform, Config]),
%% --
%% Start node
@@ -4852,11 +5001,18 @@ init_manager(AutoInform, Config) ->
start_manager(Node, Vsns, Conf)
end
catch
+ C:{suite_failed, Reason, _M, _L} = E:S when (C =:= exit) ->
+ ?EPRINT("Failure during manager start (suite-failed):"
+ "~n Reason: ~p"
+ "~n StackTrace: ~p", [Reason, S]),
+ %% And now, *try* to cleanup
+ (catch stop_node(Node)),
+ erlang:raise(C, E, S);
C:E:S ->
- p("Failure during manager start: "
- "~n Error Class: ~p"
- "~n Error: ~p"
- "~n StackTrace: ~p", [C, E, S]),
+ ?EPRINT("Failure during manager start: "
+ "~n Error Class: ~p"
+ "~n Error: ~p"
+ "~n StackTrace: ~p", [C, E, S]),
%% And now, *try* to cleanup
(catch stop_node(Node)),
?FAIL({failed_starting_manager, C, E, S})
@@ -4867,19 +5023,19 @@ fin_manager(Config) ->
StopMgrRes = stop_manager(Node),
StopCryptoRes = fin_crypto(Node),
StopNode = stop_node(Node),
- p("fin_manager -> stop apps and (mgr node ~p) node results: "
- "~n SNMP Mgr: ~p"
- "~n Crypto: ~p"
- "~n Node: ~p",
- [Node, StopMgrRes, StopCryptoRes, StopNode]),
+ ?IPRINT("fin_manager -> stop apps and (mgr node ~p) node results: "
+ "~n SNMP Mgr: ~p"
+ "~n Crypto: ~p"
+ "~n Node: ~p",
+ [Node, StopMgrRes, StopCryptoRes, StopNode]),
Config.
%% -- Misc agent functions --
init_agent(Config) ->
- ?LOG("init_agent -> entry with"
- "~n Config: ~p", [Config]),
+ ?IPRINT("init_agent -> entry with"
+ "~n Config: ~p", [Config]),
%% --
%% Retrieve some dir's
@@ -4933,11 +5089,18 @@ init_agent(Config) ->
start_agent(Node, Vsns, Conf)
end
catch
+ C:{suite_failed, Reason, _M, _L} = E:S when (C =:= exit) ->
+ ?EPRINT("Failure during agent start (suite-failed):"
+ "~n Reason: ~p"
+ "~n StackTrace: ~p", [Reason, S]),
+ %% And now, *try* to cleanup
+ (catch stop_node(Node)),
+ erlang:raise(C, E, S);
C:E:S ->
- p("Failure during agent start: "
- "~n Error Class: ~p"
- "~n Error: ~p"
- "~n StackTrace: ~p", [C, E, S]),
+ ?EPRINT("Failure during agent start: "
+ "~n Error Class: ~p"
+ "~n Error: ~p"
+ "~n StackTrace: ~p", [C, E, S]),
%% And now, *try* to cleanup
(catch stop_node(Node)),
?FAIL({failed_starting_agent, C, E, S})
@@ -4945,17 +5108,17 @@ init_agent(Config) ->
fin_agent(Config) ->
- Node = ?config(agent_node, Config),
+ Node = ?config(agent_node, Config),
StopAgentRes = stop_agent(Node),
StopCryptoRes = fin_crypto(Node),
StopMnesiaRes = fin_mnesia(Node),
StopNode = stop_node(Node),
- p("fin_agent -> stop apps and (agent node ~p) node results: "
- "~n SNMP Agent: ~p"
- "~n Crypto: ~p"
- "~n Mnesia: ~p"
- "~n Node: ~p",
- [Node, StopAgentRes, StopCryptoRes, StopMnesiaRes, StopNode]),
+ ?IPRINT("fin_agent -> stop apps and (agent node ~p) node results: "
+ "~n SNMP Agent: ~p"
+ "~n Crypto: ~p"
+ "~n Mnesia: ~p"
+ "~n Node: ~p",
+ [Node, StopAgentRes, StopCryptoRes, StopMnesiaRes, StopNode]),
Config.
init_mnesia(Node, Dir, MnesiaDebug)
@@ -5021,8 +5184,8 @@ load_app(Node, App) ->
({error, {already_loaded, LoadedApp}}) when (LoadedApp =:= App) ->
ok;
({error, Reason}) ->
- p("failed loading app ~w on ~p: "
- "~n ~p", [App, Node, Reason]),
+ ?EPRINT("failed loading app ~w on ~p: "
+ "~n ~p", [App, Node, Reason]),
?FAIL({failed_load, Node, App, Reason})
end,
do_load_app(Node, App, VerifySuccess).
@@ -5042,8 +5205,8 @@ start_app(Node, App) ->
({error, {already_started, LoadedApp}}) when (LoadedApp =:= App) ->
ok;
({error, Reason}) ->
- p("failed starting app ~w on ~p: "
- "~n ~p", [App, Node, Reason]),
+ ?EPRINT("failed starting app ~w on ~p: "
+ "~n Reason: ~p", [App, Node, Reason]),
?FAIL({failed_start, Node, App, Reason})
end,
start_app(Node, App, VerifySuccess).
@@ -5061,8 +5224,8 @@ stop_app(Node, App) ->
({error, {not_started, LoadedApp}}) when (LoadedApp =:= App) ->
ok;
({error, Reason}) ->
- p("failed stopping app ~w on ~p: "
- "~n ~p", [App, Node, Reason]),
+ ?EPRINT("failed stopping app ~w on ~p: "
+ "~n ~p", [App, Node, Reason]),
?FAIL({failed_stop, Node, App, Reason})
end,
stop_app(Node, App, VerifySuccess).
@@ -5078,11 +5241,11 @@ set_app_env(Node, App, Key, Val) ->
VerifySuccess = fun(ok) ->
ok;
({error, Reason}) ->
- p("failed setting app ~w env on ~p"
- "~n Key: ~p"
- "~n Val: ~p"
- "~n Reason: ~p"
- "~n ~p", [App, Node, Key, Val, Reason]),
+ ?EPRINT("failed setting app ~w env on ~p"
+ "~n Key: ~p"
+ "~n Val: ~p"
+ "~n Reason: ~p",
+ [App, Node, Key, Val, Reason]),
?FAIL({failed_set_app_env,
Node, App, Key, Val, Reason})
end,
@@ -5484,12 +5647,13 @@ start_manager(Node, Vsns, Conf0, _Opts) ->
ConfigVerbosity = get_opt(manager_config_verbosity, Conf0, trace),
NoteStoreVerbosity = get_opt(manager_note_store_verbosity, Conf0, log),
- ServerVerbosity = get_opt(manager_server_verbosity, Conf0, trace),
NetIfVerbosity = get_opt(manager_net_if_verbosity, Conf0, trace),
AtlSeqNo = get_opt(manager_atl_seqno, Conf0, false),
+ ServerVerbosity = get_opt(manager_server_verbosity, Conf0, trace),
CBP = get_opt(manager_server_cbproxy, Conf0, temporary),
+ NIS = get_opt(manager_server_nis, Conf0, none),
NetIfConf =
case get_opt(manager_net_if_module, Conf0, no_module) of
@@ -5512,12 +5676,22 @@ start_manager(Node, Vsns, Conf0, _Opts) ->
{verbosity, ConfigVerbosity}]},
{note_store, [{verbosity, NoteStoreVerbosity}]},
{server, [{verbosity, ServerVerbosity},
- {cbproxy, CBP}]},
+ {cbproxy, CBP},
+ {netif_sup, NIS}]},
{net_if, NetIfConf}],
?line ok = set_mgr_env(Node, Env),
- ?line ok = start_snmp(Node),
-
+ ?line ok = try start_snmp(Node) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ ?FAIL({failed_start_manager, Reason})
+ catch
+ exit:{suite_failed, {failed_start, _, _, Reason}, _M, _L}:_ ->
+ ?FAIL({failed_start_manager, Reason});
+ C:E:S ->
+ erlang:raise(C, E, S)
+ end,
Conf0.
stop_manager(Node) ->
@@ -5573,7 +5747,17 @@ start_agent(Node, Vsns, Conf0, _Opts) ->
{multi_threaded, true}],
?line ok = set_agent_env(Node, Env),
- ?line ok = start_snmp(Node),
+ ?line try start_snmp(Node) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ ?FAIL({failed_start_agent, Reason})
+ catch
+ exit:{suite_failed, {failed_start, _, _, Reason}, _M, _L}:_ ->
+ ?FAIL({failed_start_agent, Reason});
+ C:E:S ->
+ erlang:raise(C, E, S)
+ end,
Conf0.
stop_agent(Node) ->
@@ -5637,7 +5821,7 @@ start_node(Name, Retry) ->
global:sync(),
Node;
{error, timeout} ->
- e("Failed starting node ~p: timeout", [Name]),
+ ?EPRINT("Failed starting node ~p: timeout", [Name]),
?line ?FAIL({error_starting_node, Name, timeout});
{error, {already_running, Node}} when (Retry =:= true) ->
%% Ouch
@@ -5646,24 +5830,24 @@ start_node(Name, Retry) ->
%% timeout) but actually succeeded. Regardless, we don't know
%% the state of this node, so (try) stop it and then (re-) try
%% start again.
- e("Failed starting node ~p: Already Running - try stop", [Node]),
+ ?WPRINT("Failed starting node ~p: Already Running - try stop", [Node]),
case ?STOP_NODE(Node) of
true ->
- p("Successfully stopped old node ~p", [Node]),
+ ?IPRINT("Successfully stopped old node ~p", [Node]),
start_node(Name, false);
false ->
- e("Failed stop old node ~p", [Node]),
+ ?EPRINT("Failed stop old node ~p", [Node]),
?line ?FAIL({error_starting_node, Node, Retry, already_running})
end;
{error, {already_running, Node}} ->
- e("Failed starting node ~p: Already Running", [Node]),
+ ?EPRINT("Failed starting node ~p: Already Running", [Node]),
?line ?FAIL({error_starting_node, Node, Retry, already_running});
{error, Reason} ->
- e("Failed starting node ~p: ~p", [Name, Reason]),
+ ?EPRINT("Failed starting node ~p: ~p", [Name, Reason]),
?line ?FAIL({error_starting_node, Name, Reason})
catch
exit:{suite_failed, Reason} ->
- e("(suite) Failed starting node ~p: ~p", [Name, Reason]),
+ ?EPRINT("(suite) Failed starting node ~p: ~p", [Name, Reason]),
?line ?FAIL({failed_starting_node, Name, Reason})
end.
@@ -5842,24 +6026,24 @@ display_log(Config) ->
LogDir = Dir,
Mibs = [],
OutFile = j(LogDir, "snmpm_log.txt"),
- p("~n"
- "========================="
- " < Audit Trail Log > "
- "========================="
- "~n"),
+ ?IPRINT("~n"
+ "========================="
+ " < Audit Trail Log > "
+ "========================="
+ "~n"),
rcall(Node, snmpm, log_to_txt, [LogDir, Mibs, OutFile]),
rcall(Node, snmpm, log_to_io, [LogDir, Mibs]),
- p("~n"
- "========================="
- " < / Audit Trail Log > "
- "========================="
- "~n");
+ ?IPRINT("~n"
+ "========================="
+ " < / Audit Trail Log > "
+ "========================="
+ "~n");
false ->
- p("display_log -> no manager node found"),
+ ?IPRINT("display_log -> no manager node found"),
ok
end;
false ->
- p("display_log -> no manager log dir found"),
+ ?IPRINT("display_log -> no manager log dir found"),
ok
end.
@@ -5910,35 +6094,5 @@ rcall(Node, Mod, Func, Args) ->
%% ------
-%% Time in milli sec
-%% t() ->
-%% {A,B,C} = os:timestamp(),
-%% A*1000000000+B*1000+(C div 1000).
-
-
-%% ------
-
-e(F, A) ->
- p("<ERROR> " ++ F, A).
-
-p(F) ->
- p(F, []).
-
-p(F, A) ->
- p(get(tname), F, A).
-
-p(undefined, F, A) ->
- io:format("*** [~s] ***"
- "~n " ++ F ++ "~n", [formated_timestamp()|A]);
-p(TName, F, A) ->
- io:format("*** [~s][~w] ***"
- "~n " ++ F ++ "~n", [formated_timestamp(),TName|A]).
-
-formated_timestamp() ->
- snmp_test_lib:formated_timestamp().
-
-%% p(TName, F, A) ->
-%% io:format("~w -> " ++ F ++ "~n", [TName|A]).
-
ipv6_init(Config) when is_list(Config) ->
[{ipfamily, inet6} | Config].
diff --git a/lib/snmp/test/snmp_manager_config_SUITE.erl b/lib/snmp/test/snmp_manager_config_SUITE.erl
index b5c1894294..9a7b485a60 100644
--- a/lib/snmp/test/snmp_manager_config_SUITE.erl
+++ b/lib/snmp/test/snmp_manager_config_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -29,6 +29,7 @@
%%----------------------------------------------------------------------
-module(snmp_manager_config_SUITE).
+
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
@@ -97,6 +98,7 @@
]).
+
%%----------------------------------------------------------------------
%% Internal exports
%%----------------------------------------------------------------------
@@ -219,24 +221,40 @@ otp_8395_cases() ->
otp_8395_4
].
+
init_per_suite(Config0) when is_list(Config0) ->
- ?DBG("init_per_suite -> entry with"
- "~n Config0: ~p", [Config0]),
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
- Config1 = snmp_test_lib:init_suite_top_dir(?MODULE, Config0),
+ case ?LIB:init_per_suite(Config0) of
+ {skip, _} = SKIP ->
+ SKIP;
- ?DBG("init_per_suite -> done when"
- "~n Config1: ~p", [Config1]),
+ Config1 ->
- Config1.
+ Config2 = snmp_test_lib:init_suite_top_dir(?MODULE, Config1),
-end_per_suite(Config) when is_list(Config) ->
+ %% We need one on this node also
+ snmp_test_sys_monitor:start(),
- ?DBG("end_per_suite -> entry with"
- "~n Config: ~p", [Config]),
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config: ~p", [Config2]),
- Config.
+ Config2
+ end.
+
+end_per_suite(Config0) when is_list(Config0) ->
+
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
+
+ snmp_test_sys_monitor:stop(),
+ Config1 = ?LIB:end_per_suite(Config0),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
init_per_group(_GroupName, Config) ->
@@ -247,11 +265,16 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(Case, Config) when is_list(Config) ->
- p("init_per_testcase -> Case: ~p", [Case]),
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
+
+ snmp_test_global_sys_monitor:reset_events(),
+
SuiteTopDir = ?config(snmp_suite_top_dir, Config),
CaseTopDir = filename:join(SuiteTopDir, atom_to_list(Case)),
?line ok = file:make_dir(CaseTopDir),
- p("init_per_testcase -> CaseTopDir: ~p", [CaseTopDir]),
+
+ ?IPRINT("init_per_testcase -> CaseTopDir: ~p", [CaseTopDir]),
MgrTopDir = filename:join(CaseTopDir, "manager/"),
?line ok = file:make_dir(MgrTopDir),
MgrConfDir = filename:join(MgrTopDir, "conf/"),
@@ -265,15 +288,26 @@ init_per_testcase(Case, Config) when is_list(Config) ->
end,
MgrLogDir = filename:join(MgrTopDir, "log/"),
?line ok = file:make_dir(MgrLogDir),
- [{case_top_dir, CaseTopDir},
- {manager_dir, MgrTopDir},
- {manager_conf_dir, MgrConfDir},
- {manager_db_dir, MgrDbDir},
- {manager_log_dir, MgrLogDir} | Config].
+ Config1 = [{case_top_dir, CaseTopDir},
+ {manager_dir, MgrTopDir},
+ {manager_conf_dir, MgrConfDir},
+ {manager_db_dir, MgrDbDir},
+ {manager_log_dir, MgrLogDir} | Config],
+
+ ?IPRINT("init_per_testcase -> done when"
+ "~n Config1: ~p", [Config1]),
+ Config1.
+
+
+end_per_testcase(_Case, Config) when is_list(Config) ->
+
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
+
+ ?IPRINT("system events during test: "
+ "~n ~p", [snmp_test_global_sys_monitor:events()]),
-end_per_testcase(Case, Config) when is_list(Config) ->
- p("end_per_testcase -> Case: ~p", [Case]),
%% The cleanup is removed due to some really discusting NFS behaviour...
%% Also, it can always be useful to retain "all the stuff" after
%% the test case in case of debugging...
@@ -293,8 +327,8 @@ simple_start_and_stop(doc) ->
"Start the snmp manager config process with the \n"
"minimum setof options (config dir).";
simple_start_and_stop(Conf) when is_list(Conf) ->
- put(tname,ssas),
- p("start"),
+ put(tname, "SIME-START_AND_STOP"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -319,9 +353,9 @@ start_without_mandatory_opts1(doc) ->
"Start the snmp manager config process with some of the \n"
"mandatory options missing.";
start_without_mandatory_opts1(Conf) when is_list(Conf) ->
- put(tname,swomo1),
- put(verbosity,trace),
- p("start"),
+ put(tname, "START-WO-MAND-OPTS-1"),
+ put(verbosity, trace),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -330,12 +364,12 @@ start_without_mandatory_opts1(Conf) when is_list(Conf) ->
%% config, but no dir:
- p("config option, but no dir"),
+ ?IPRINT("config option, but no dir"),
Opts = [{priority, normal},
{config, [{verbosity, trace}, {db_dir, DbDir}]}, {mibs, []}],
?line {error, {missing_mandatory,dir}} = config_start(Opts),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -348,9 +382,9 @@ start_without_mandatory_opts2(doc) ->
"Start the snmp manager config process with some of the \n"
"mandatory options missing.";
start_without_mandatory_opts2(Conf) when is_list(Conf) ->
- put(tname,swomo2),
+ put(tname, "START-WO-MAND-OPTS-2"),
put(verbosity,trace),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -358,13 +392,13 @@ start_without_mandatory_opts2(Conf) when is_list(Conf) ->
%% Second set of options (no config):
- p("no config option"),
+ ?IPRINT("no config option"),
Opts = [{priority, normal},
{mibs, []}],
?line {error, {missing_mandatory,config,[dir, db_dir]}} =
config_start(Opts),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -377,8 +411,9 @@ start_with_all_valid_opts(doc) ->
"Start the snmp manager config process with the \n"
"complete set of all the valid options.";
start_with_all_valid_opts(Conf) when is_list(Conf) ->
+ put(tname, "START-W-ALL-VALID-OPTS"),
put(tname,swavo),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -389,16 +424,22 @@ start_with_all_valid_opts(Conf) when is_list(Conf) ->
%% Third set of options (no versions):
- p("all options"),
+ ?IPRINT("all options"),
NetIfOpts = [{module, snmpm_net_if},
{verbosity, trace},
{options, [{recbuf, 30000},
{bind_to, false},
{no_reuse, false}]}],
- ServerOpts = [{timeout, 10000}, {verbosity, trace}],
- NoteStoreOpts = [{timeout, 20000}, {verbosity, trace}],
- ConfigOpts = [{dir, ConfDir}, {verbosity, trace},
- {db_dir, DbDir}, {db_init_error, create}],
+ ServerOpts = [{timeout, ?SECS(10)},
+ {verbosity, trace},
+ {cbproxy, permanent},
+ {netif_sup, {?SECS(60), ?SECS(5)}}],
+ NoteStoreOpts = [{timeout, ?SECS(20)},
+ {verbosity, trace}],
+ ConfigOpts = [{dir, ConfDir},
+ {verbosity, trace},
+ {db_dir, DbDir},
+ {db_init_error, create}],
Mibs = [join(StdMibDir, "SNMP-NOTIFICATION-MIB"),
join(StdMibDir, "SNMP-USER-BASED-SM-MIB")],
Prio = normal,
@@ -418,7 +459,7 @@ start_with_all_valid_opts(Conf) when is_list(Conf) ->
?line {ok, _Pid} = config_start(Opts),
?line ok = config_stop(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -431,8 +472,8 @@ start_with_unknown_opts(doc) ->
"Start the snmp manager config process when some of\n"
"the options are unknown.";
start_with_unknown_opts(Conf) when is_list(Conf) ->
- put(tname,swuo),
- p("start"),
+ put(tname, "START-W-UNKNOWN-OPTS"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -443,7 +484,7 @@ start_with_unknown_opts(Conf) when is_list(Conf) ->
%% Third set of options (no versions):
- p("all options"),
+ ?IPRINT("all options"),
NetIfOpts = [{module, snmpm_net_if},
{verbosity, trace},
{options, [{recbuf, 30000},
@@ -471,7 +512,10 @@ start_with_unknown_opts(Conf) when is_list(Conf) ->
{versions, Vsns}],
?line {ok, _Pid} = config_start(Opts),
- p("done"),
+ ?IPRINT("(config) started - now stop"),
+ ?line ok = config_stop(),
+
+ ?IPRINT("done"),
ok.
@@ -484,8 +528,8 @@ start_with_incorrect_opts(doc) ->
"Start the snmp manager config process when some of\n"
"the options has incorrect values.";
start_with_incorrect_opts(Conf) when is_list(Conf) ->
- put(tname,swio),
- p("start"),
+ put(tname, "START-W-INCORRECT-OPTS"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -496,135 +540,135 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
ConfigOpts = [{verbosity,trace}, {dir, ConfDir}, {db_dir, DbDir}],
- p("net-if - incorrect module"),
+ ?IPRINT("net-if - incorrect module"),
NetIfOpts1 = [{module, snmpm_user}], %% Behaviour check will fail
Opts01 = [{config, ConfigOpts}, {versions, [v1]},
{net_if, NetIfOpts1}],
?line {error, Reason01} = config_start(Opts01),
- p("net-if (module) res: ~p", [Reason01]),
+ ?IPRINT("net-if (module) res: ~p", [Reason01]),
- p("net-if - incorrect verbosity"),
+ ?IPRINT("net-if - incorrect verbosity"),
NetIfOpts2 = [{verbosity, invalid_verbosity}],
Opts02 = [{config, ConfigOpts}, {versions, [v1]},
{net_if, NetIfOpts2}],
?line {error, Reason02} = config_start(Opts02),
- p("net-if (verbosity) res: ~p", [Reason02]),
+ ?IPRINT("net-if (verbosity) res: ~p", [Reason02]),
- p("net-if - incorrect options"),
+ ?IPRINT("net-if - incorrect options"),
NetIfOpts3 = [{options, invalid_options}],
Opts03 = [{config, ConfigOpts}, {versions, [v1]},
{net_if, NetIfOpts3}],
?line {error, Reason03} = config_start(Opts03),
- p("net-if (options) res: ~p", [Reason03]),
+ ?IPRINT("net-if (options) res: ~p", [Reason03]),
- p("server - incorrect timeout (1)"),
+ ?IPRINT("server - incorrect timeout (1)"),
ServerOpts1 = [{timeout, invalid_timeout}],
Opts08 = [{config, ConfigOpts}, {versions, [v1]},
{server, ServerOpts1}],
?line {error, Reason08} = config_start(Opts08),
- p("server (timeout) res: ~p", [Reason08]),
+ ?IPRINT("server (timeout) res: ~p", [Reason08]),
- p("server - incorrect timeout (2)"),
+ ?IPRINT("server - incorrect timeout (2)"),
ServerOpts2 = [{timeout, 0}],
Opts09 = [{config, ConfigOpts}, {versions, [v1]},
{server, ServerOpts2}],
?line {error, Reason09} = config_start(Opts09),
- p("server (timeout) res: ~p", [Reason09]),
+ ?IPRINT("server (timeout) res: ~p", [Reason09]),
- p("server - incorrect timeout (3)"),
+ ?IPRINT("server - incorrect timeout (3)"),
ServerOpts3 = [{timeout, -1000}],
Opts10 = [{config, ConfigOpts},
{versions, [v1]},
{server, ServerOpts3}],
?line {error, Reason10} = config_start(Opts10),
- p("server (timeout) res: ~p", [Reason10]),
+ ?IPRINT("server (timeout) res: ~p", [Reason10]),
- p("server - incorrect verbosity"),
+ ?IPRINT("server - incorrect verbosity"),
ServerOpts4 = [{verbosity, invalid_verbosity}],
Opts11 = [{config, ConfigOpts},
{versions, [v1]},
{server, ServerOpts4}],
?line {error, Reason11} = config_start(Opts11),
- p("server (verbosity) res: ~p", [Reason11]),
+ ?IPRINT("server (verbosity) res: ~p", [Reason11]),
- p("note-store - incorrect timeout (1)"),
+ ?IPRINT("note-store - incorrect timeout (1)"),
NoteStoreOpts1 = [{timeout, invalid_timeout}],
Opts12 = [{config, ConfigOpts},
{versions, [v1]},
{note_store, NoteStoreOpts1}],
?line {error, Reason12} = config_start(Opts12),
- p("note-store (timeout) res: ~p", [Reason12]),
+ ?IPRINT("note-store (timeout) res: ~p", [Reason12]),
- p("note-store - incorrect timeout (2)"),
+ ?IPRINT("note-store - incorrect timeout (2)"),
NoteStoreOpts2 = [{timeout, 0}],
Opts13 = [{config, ConfigOpts},
{versions, [v1]},
{note_store, NoteStoreOpts2}],
?line {error, Reason13} = config_start(Opts13),
- p("note-store (timeout) res: ~p", [Reason13]),
+ ?IPRINT("note-store (timeout) res: ~p", [Reason13]),
- p("note-store - incorrect timeout (3)"),
+ ?IPRINT("note-store - incorrect timeout (3)"),
NoteStoreOpts3 = [{timeout, -2000}],
Opts14 = [{config, ConfigOpts},
{versions, [v1]},
{note_store, NoteStoreOpts3}],
?line {error, Reason14} = config_start(Opts14),
- p("note-store (timeout) res: ~p", [Reason14]),
+ ?IPRINT("note-store (timeout) res: ~p", [Reason14]),
- p("note-store - incorrect verbosity"),
+ ?IPRINT("note-store - incorrect verbosity"),
NoteStoreOpts4 = [{timeout, 20000}, {verbosity, invalid_verbosity}],
Opts15 = [{config, ConfigOpts},
{versions, [v1]},
{note_store, NoteStoreOpts4}],
?line {error, Reason15} = config_start(Opts15),
- p("note-store (verbosity) res: ~p", [Reason15]),
+ ?IPRINT("note-store (verbosity) res: ~p", [Reason15]),
- p("config - incorrect dir (1)"),
+ ?IPRINT("config - incorrect dir (1)"),
ConfigOpts1 = [{dir, invalid_dir}],
Opts16 = [{config, ConfigOpts1},
{versions, [v1]}],
?line {error, Reason16} = config_start(Opts16),
- p("config (dir) res: ~p", [Reason16]),
+ ?IPRINT("config (dir) res: ~p", [Reason16]),
- p("config - incorrect dir (2)"),
+ ?IPRINT("config - incorrect dir (2)"),
ConfigOpts2 = [{dir, "/invalid/dir"}],
Opts17 = [{config, ConfigOpts2},
{versions, [v1]}],
?line {error, Reason17} = config_start(Opts17),
- p("config (dir) res: ~p", [Reason17]),
+ ?IPRINT("config (dir) res: ~p", [Reason17]),
- p("config - incorrect verbosity"),
+ ?IPRINT("config - incorrect verbosity"),
ConfigOpts3 = [{dir, ConfDir}, {verbosity, invalid_verbosity}],
Opts18 = [{config, ConfigOpts3},
{versions, [v1]}],
?line {error, Reason18} = config_start(Opts18),
- p("config (verbosity) res: ~p", [Reason18]),
+ ?IPRINT("config (verbosity) res: ~p", [Reason18]),
- p("mibs - incorrect mibs (1)"),
+ ?IPRINT("mibs - incorrect mibs (1)"),
Mibs1 = invalid_mibs,
Opts19 = [{config, ConfigOpts},
{versions, [v1]},
{mibs, Mibs1}],
?line {error, Reason19} = config_start(Opts19),
- p("mibs (mibs) res: ~p", [Reason19]),
+ ?IPRINT("mibs (mibs) res: ~p", [Reason19]),
- p("mibs - incorrect mibs (2)"),
+ ?IPRINT("mibs - incorrect mibs (2)"),
Mibs2 = [join(StdMibDir, "INVALID-MIB")],
Opts20 = [{config, ConfigOpts},
{versions, [v1]},
{mibs, Mibs2}],
?line {error, Reason20} = config_start(Opts20),
- p("mibs (mibs) res: ~p", [Reason20]),
+ ?IPRINT("mibs (mibs) res: ~p", [Reason20]),
- p("prio - incorrect prio"),
+ ?IPRINT("prio - incorrect prio"),
Prio1 = invalid_prio,
Opts21 = [{config, ConfigOpts},
{versions, [v1]},
{priority, Prio1}],
?line {error, Reason21} = config_start(Opts21),
- p("prio (prio) res: ~p", [Reason21]),
+ ?IPRINT("prio (prio) res: ~p", [Reason21]),
- p("atl - incorrect type"),
+ ?IPRINT("atl - incorrect type"),
ATL1 = [{type, invalid_type},
{dir, LogDir},
{size, {10,10240}},
@@ -633,9 +677,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL1}],
?line {error, Reason22} = config_start(Opts22),
- p("atl (type) res: ~p", [Reason22]),
+ ?IPRINT("atl (type) res: ~p", [Reason22]),
- p("atl - incorrect dir (1)"),
+ ?IPRINT("atl - incorrect dir (1)"),
ATL2 = [{type, read_write},
{dir, invalid_dir},
{size, {10,10240}},
@@ -644,9 +688,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL2}],
?line {error, Reason23} = config_start(Opts23),
- p("atl (dir) res: ~p", [Reason23]),
+ ?IPRINT("atl (dir) res: ~p", [Reason23]),
- p("atl - incorrect dir (2)"),
+ ?IPRINT("atl - incorrect dir (2)"),
ATL3 = [{type, read_write},
{dir, "/invalid/dir"},
{size, {10,10240}},
@@ -655,9 +699,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL3}],
?line {error, Reason24} = config_start(Opts24),
- p("atl (dir) res: ~p", [Reason24]),
+ ?IPRINT("atl (dir) res: ~p", [Reason24]),
- p("atl - incorrect size (1)"),
+ ?IPRINT("atl - incorrect size (1)"),
ATL4 = [{type, read_write},
{dir, LogDir},
{size, invalid_size},
@@ -666,9 +710,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL4}],
?line {error, Reason25} = config_start(Opts25),
- p("atl (size) res: ~p", [Reason25]),
+ ?IPRINT("atl (size) res: ~p", [Reason25]),
- p("atl - incorrect size (2)"),
+ ?IPRINT("atl - incorrect size (2)"),
ATL5 = [{type, read_write},
{dir, LogDir},
{size, {10,invalid_file_size}},
@@ -677,9 +721,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL5}],
?line {error, Reason26} = config_start(Opts26),
- p("atl (size) res: ~p", [Reason26]),
+ ?IPRINT("atl (size) res: ~p", [Reason26]),
- p("atl - incorrect size (3)"),
+ ?IPRINT("atl - incorrect size (3)"),
ATL6 = [{type, read_write},
{dir, LogDir},
{size, {invalid_file_num,10240}},
@@ -688,9 +732,9 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL6}],
?line {error, Reason27} = config_start(Opts27),
- p("atl (size) res: ~p", [Reason27]),
+ ?IPRINT("atl (size) res: ~p", [Reason27]),
- p("atl - incorrect repair"),
+ ?IPRINT("atl - incorrect repair"),
ATL7 = [{type, read_write},
{dir, LogDir},
{size, {10,10240}},
@@ -699,23 +743,23 @@ start_with_incorrect_opts(Conf) when is_list(Conf) ->
{versions, [v1]},
{audit_trail_log, ATL7}],
?line {error, Reason28} = config_start(Opts28),
- p("atl (repair) res: ~p", [Reason28]),
+ ?IPRINT("atl (repair) res: ~p", [Reason28]),
- p("version - incorrect versions (1)"),
+ ?IPRINT("version - incorrect versions (1)"),
Vsns1 = invalid_vsns,
Opts29 = [{config, ConfigOpts},
{versions, Vsns1}],
?line {error, Reason29} = config_start(Opts29),
- p("versions (versions) res: ~p", [Reason29]),
+ ?IPRINT("versions (versions) res: ~p", [Reason29]),
- p("version - incorrect versions (2)"),
+ ?IPRINT("version - incorrect versions (2)"),
Vsns2 = [v1,v2,v3,v9],
Opts30 = [{config, ConfigOpts},
{versions, Vsns2}],
?line {error, Reason30} = config_start(Opts30),
- p("versions (versions) res: ~p", [Reason30]),
+ ?IPRINT("versions (versions) res: ~p", [Reason30]),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -727,8 +771,8 @@ start_with_invalid_manager_conf_file1(suite) -> [];
start_with_invalid_manager_conf_file1(doc) ->
"Start with invalid manager config file (1).";
start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
- put(tname,swimcf),
- p("start"),
+ put(tname, "START-W-INV-MGR-CONF-FILE-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -737,142 +781,142 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
%% --
- p("write manager config file with invalid IP address (1)"),
+ ?IPRINT("write manager config file with invalid IP address (1)"),
write_manager_conf(ConfDir,
"arne-anka", "4001", "500", "\"bmkEngine\""),
?line {error, Reason11} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason11]),
+ ?IPRINT("start failed (as expected): ~p", [Reason11]),
?line {failed_reading, _, _, 1, {parse_error, _}} = Reason11,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid IP address (2)"),
+ ?IPRINT("write manager config file with invalid IP address (2)"),
write_manager_conf(ConfDir,
"arne_anka", "4001", "500", "\"bmkEngine\""),
?line {error, Reason12} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason12]),
+ ?IPRINT("start failed (as expected): ~p", [Reason12]),
?line {failed_check, _, _, 2, {bad_address, _}} = Reason12,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid IP address (3)"),
+ ?IPRINT("write manager config file with invalid IP address (3)"),
write_manager_conf(ConfDir,
"9999", "4001", "500", "\"bmkEngine\""),
?line {error, Reason13} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason13]),
+ ?IPRINT("start failed (as expected): ~p", [Reason13]),
?line {failed_check, _, _, 2, {bad_address, _}} = Reason13,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid port (2)"),
+ ?IPRINT("write manager config file with invalid port (2)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "kalle-anka", "500", "\"bmkEngine\""),
?line {error, Reason21} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason21]),
+ ?IPRINT("start failed (as expected): ~p", [Reason21]),
?line {failed_reading, _, _, 2, {parse_error, _}} = Reason21,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid port (1)"),
+ ?IPRINT("write manager config file with invalid port (1)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "-1", "500", "\"bmkEngine\""),
?line {error, Reason22} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason22]),
+ ?IPRINT("start failed (as expected): ~p", [Reason22]),
io:format("Reason22: ~p~n", [Reason22]),
?line {failed_check, _, _, 3, {bad_port, _}} = Reason22,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid port (3)"),
+ ?IPRINT("write manager config file with invalid port (3)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "\"kalle-anka\"", "500", "\"bmkEngine\""),
?line {error, Reason23} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason23]),
+ ?IPRINT("start failed (as expected): ~p", [Reason23]),
?line {failed_check, _, _, 3, {bad_port, _}} = Reason23,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid EngineID (1)"),
+ ?IPRINT("write manager config file with invalid EngineID (1)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "500", "bmkEngine"),
?line {error, Reason31} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason31]),
+ ?IPRINT("start failed (as expected): ~p", [Reason31]),
?line {failed_check, _, _, 5, {invalid_string, _}} = Reason31,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid EngineID (2)"),
+ ?IPRINT("write manager config file with invalid EngineID (2)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "500", "{1,2,3}"),
?line {error, Reason32} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason32]),
+ ?IPRINT("start failed (as expected): ~p", [Reason32]),
?line {failed_check, _, _, 5, {invalid_string, _}} = Reason32,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid EngineID (3)"),
+ ?IPRINT("write manager config file with invalid EngineID (3)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "500", "10101"),
?line {error, Reason33} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason33]),
+ ?IPRINT("start failed (as expected): ~p", [Reason33]),
?line {failed_check, _, _, 5, {invalid_string, _}} = Reason33,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid MMS (1)"),
+ ?IPRINT("write manager config file with invalid MMS (1)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "483", "\"bmkEngine\""),
?line {error, Reason41} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason41]),
+ ?IPRINT("start failed (as expected): ~p", [Reason41]),
?line {failed_check, _, _, 4, {invalid_integer, _}} = Reason41,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid MMS (2)"),
+ ?IPRINT("write manager config file with invalid MMS (2)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "-1", "\"bmkEngine\""),
?line {error, Reason42} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason42]),
+ ?IPRINT("start failed (as expected): ~p", [Reason42]),
?line {failed_check, _, _, 4, {invalid_integer, _}} = Reason42,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid MMS (3)"),
+ ?IPRINT("write manager config file with invalid MMS (3)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "\"kalle-anka\"", "\"bmkEngine\""),
?line {error, Reason43} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason43]),
+ ?IPRINT("start failed (as expected): ~p", [Reason43]),
?line {failed_check, _, _, 4, {invalid_integer, _}} = Reason43,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with invalid MMS (4)"),
+ ?IPRINT("write manager config file with invalid MMS (4)"),
write_manager_conf(ConfDir,
"[134,138,177,189]", "4001", "kalle_anka", "\"bmkEngine\""),
?line {error, Reason44} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason44]),
+ ?IPRINT("start failed (as expected): ~p", [Reason44]),
?line {failed_check, _, _, 4, {invalid_integer, _}} = Reason44,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with unknown option"),
+ ?IPRINT("write manager config file with unknown option"),
write_manager_conf(ConfDir,
"{kalle, anka}."),
?line {error, Reason51} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason51]),
+ ?IPRINT("start failed (as expected): ~p", [Reason51]),
?line {failed_check, _, _, 1, {unknown_config, _}} = Reason51,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write manager config file with unknown option"),
+ ?IPRINT("write manager config file with unknown option"),
write_manager_conf(ConfDir,
"kalle_anka."),
?line {error, Reason52} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason52]),
+ ?IPRINT("start failed (as expected): ~p", [Reason52]),
?line {failed_check, _, _, 1, {unknown_config, _}} = Reason52,
- await_config_not_running(),
+ config_ensure_not_running(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -884,8 +928,8 @@ start_with_invalid_users_conf_file1(suite) -> [];
start_with_invalid_users_conf_file1(doc) ->
"Start with invalid users config file.";
start_with_invalid_users_conf_file1(Conf) when is_list(Conf) ->
- put(tname,swiucf),
- p("start"),
+ put(tname, "START-W-INV-USER-CONF-FILE-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -899,74 +943,74 @@ start_with_invalid_users_conf_file1(Conf) when is_list(Conf) ->
write_manager_conf(ConfDir),
%% --
- p("write users config file with invalid module (1)"),
+ ?IPRINT("write users config file with invalid module (1)"),
write_users_conf(ConfDir, [{"kalle", "kalle", "dummy"}]),
?line {error, Reason11} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason11]),
+ ?IPRINT("start failed (as expected): ~p", [Reason11]),
?line {failed_check, _, _, _, {bad_module, kalle}} = Reason11,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid module (1)"),
+ ?IPRINT("write users config file with invalid module (1)"),
write_users_conf(ConfDir, [{"kalle", "snmpm", "dummy"}]),
?line {error, Reason12} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason12]),
+ ?IPRINT("start failed (as expected): ~p", [Reason12]),
?line {failed_check, _, _, _, {bad_module, _}} = Reason12,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid module (2)"),
+ ?IPRINT("write users config file with invalid module (2)"),
write_users_conf(ConfDir, [{"kalle1", "10101", "dummy"}]),
?line {error, Reason13} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason13]),
+ ?IPRINT("start failed (as expected): ~p", [Reason13]),
?line {failed_check, _, _, _, {bad_module, _}} = Reason13,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user tuple (1)"),
+ ?IPRINT("write users config file with invalid user tuple (1)"),
write_users_conf2(ConfDir, "{kalle, snmpm_user_default}."),
?line {error, Reason21} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason21]),
+ ?IPRINT("start failed (as expected): ~p", [Reason21]),
?line {failed_check, _, _, _, {bad_user_config, _}} = Reason21,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user tuple (2)"),
+ ?IPRINT("write users config file with invalid user tuple (2)"),
write_users_conf2(ConfDir, "{kalle, snmpm_user_default, kalle, [], olle}."),
?line {error, Reason22} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason22]),
+ ?IPRINT("start failed (as expected): ~p", [Reason22]),
?line {failed_check, _, _, _, {bad_user_config, _}} = Reason22,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user tuple (3)"),
+ ?IPRINT("write users config file with invalid user tuple (3)"),
write_users_conf2(ConfDir, "snmpm_user_default."),
?line {error, Reason23} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason23]),
+ ?IPRINT("start failed (as expected): ~p", [Reason23]),
?line {failed_check, _, _, _, {bad_user_config, _}} = Reason23,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user tuple (4)"),
+ ?IPRINT("write users config file with invalid user tuple (4)"),
write_users_conf2(ConfDir, "[kalle, snmpm_user_default, kalle]."),
?line {error, Reason24} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason24]),
+ ?IPRINT("start failed (as expected): ~p", [Reason24]),
?line {failed_check, _, _, _, {bad_user_config, _}} = Reason24,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user agent default config (1)"),
+ ?IPRINT("write users config file with invalid user agent default config (1)"),
write_users_conf2(ConfDir, "{kalle, snmpm_user_default, kalle, olle}."),
?line {error, Reason31} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason31]),
+ ?IPRINT("start failed (as expected): ~p", [Reason31]),
?line {failed_check, _, _, _, {bad_default_agent_config, _}} = Reason31,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("write users config file with invalid user agent default config (2)"),
+ ?IPRINT("write users config file with invalid user agent default config (2)"),
write_users_conf2(ConfDir, "{kalle, snmpm_user_default, kalle, [olle]}."),
?line {error, Reason32} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason32]),
+ ?IPRINT("start failed (as expected): ~p", [Reason32]),
%% ?line {failed_check, _, _, _, {bad_default_agent_config, _}} = Reason32,
case Reason32 of
{failed_check, _, _, _, {bad_default_agent_config, _}} ->
@@ -974,9 +1018,9 @@ start_with_invalid_users_conf_file1(Conf) when is_list(Conf) ->
{A, B, C, D} ->
exit({bad_error, A, B, C, D})
end,
- await_config_not_running(),
+ config_ensure_not_running(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -988,8 +1032,8 @@ start_with_invalid_agents_conf_file1(suite) -> [];
start_with_invalid_agents_conf_file1(doc) ->
"Start with invalid agents config file.";
start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
- put(tname, swiacf),
- p("start"),
+ put(tname, "START-W-INV-AGS-CONF-FILE-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -1009,375 +1053,391 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
"any", "\"initial\"", "noAuthNoPriv"},
%% --
- p("[test 11] write agents config file with invalid user (1)"),
+ ?IPRINT("[test 11] write agents config file with invalid user (1)"),
Agent11 = setelement(1, Agent0, "kalle-anka"),
write_agents_conf(ConfDir, [Agent11]),
case config_start(Opts) of
{error, Reason11} ->
- p("start failed (as expected): ~p", [Reason11]),
+ ?IPRINT("start failed (as expected): ~p", [Reason11]),
?line {failed_reading, _, _, _, {parse_error, _}} = Reason11,
- await_config_not_running();
+ config_ensure_not_running();
OK_11 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "11", OK_11}})
end,
%% --
- p("[test 21] write agents config file with invalid target name (1)"),
+ ?IPRINT("[test 21] write agents config file with invalid target name (1)"),
Agent21 = setelement(2, Agent0, "targ-hobbes"),
write_agents_conf(ConfDir, [Agent21]),
case config_start(Opts) of
{error, Reason21} ->
- p("start failed (as expected): ~p", [Reason21]),
+ ?IPRINT("start failed (as expected): ~p", [Reason21]),
?line {failed_reading, _, _, _, {parse_error, _}} = Reason21,
- await_config_not_running();
+ config_ensure_not_running();
OK_21 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "21", OK_21}})
end,
%% --
- p("[test 22] write agents config file with invalid target name (2)"),
+ ?IPRINT("[test 22] write agents config file with invalid target name (2)"),
Agent22 = setelement(2, Agent0, "targ_hobbes"),
write_agents_conf(ConfDir, [Agent22]),
case config_start(Opts) of
{error, Reason22} ->
- p("start failed (as expected): ~p", [Reason22]),
+ ?IPRINT("start failed (as expected): ~p", [Reason22]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason22,
- await_config_not_running();
+ config_ensure_not_running();
OK_22 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "22", OK_22}})
end,
%% --
- p("[test 23] write agents config file with invalid target name (3)"),
+ ?IPRINT("[test 23] write agents config file with invalid target name (3)"),
Agent23 = setelement(2, Agent0, "10101"),
write_agents_conf(ConfDir, [Agent23]),
case config_start(Opts) of
{error, Reason23} ->
- p("start failed (as expected): ~p", [Reason23]),
+ ?IPRINT("start failed (as expected): ~p", [Reason23]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason23,
- await_config_not_running();
+ config_ensure_not_running();
OK_23 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "23", OK_23}})
end,
%% --
- p("[test 31] write agents config file with invalid community (1)"),
+ ?IPRINT("[test 31] write agents config file with invalid community (1)"),
Agent31 = setelement(3, Agent0, "targ-hobbes"),
write_agents_conf(ConfDir, [Agent31]),
case config_start(Opts) of
{error, Reason31} ->
- p("start failed (as expected): ~p", [Reason31]),
+ ?IPRINT("start failed (as expected): ~p", [Reason31]),
?line {failed_reading, _, _, _, {parse_error, _}} = Reason31,
- await_config_not_running();
+ config_ensure_not_running();
OK_31 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "31", OK_31}})
end,
%% --
- p("[test 32] write agents config file with invalid community (2)"),
+ ?IPRINT("[test 32] write agents config file with invalid community (2)"),
Agent32 = setelement(3, Agent0, "targ_hobbes"),
write_agents_conf(ConfDir, [Agent32]),
case config_start(Opts) of
{error, Reason32} ->
- p("start failed (as expected): ~p", [Reason32]),
+ ?IPRINT("start failed (as expected): ~p", [Reason32]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason32,
- await_config_not_running();
+ config_ensure_not_running();
OK_32 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "32", OK_32}})
end,
%% --
- p("[test 33] write agents config file with invalid community (3)"),
+ ?IPRINT("[test 33] write agents config file with invalid community (3)"),
Agent33 = setelement(3, Agent0, "10101"),
write_agents_conf(ConfDir, [Agent33]),
case config_start(Opts) of
{error, Reason33} ->
- p("start failed (as expected): ~p", [Reason33]),
+ ?IPRINT("start failed (as expected): ~p", [Reason33]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason33,
- await_config_not_running();
+ config_ensure_not_running();
OK_33 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "33", OK_33}})
end,
%% --
- p("[test 51] write agents config file with invalid ip (1)"),
+ ?IPRINT("[test 51] write agents config file with invalid ip (1)"),
Agent51 = setelement(4, Agent0, "kalle_anka"),
write_agents_conf(ConfDir, [Agent51]),
case config_start(Opts) of
{error, Reason51} ->
- p("start failed (as expected): ~p", [Reason51]),
+ ?IPRINT("start failed (as expected): ~p", [Reason51]),
?line {failed_check, _, _, _, {bad_domain, _}} = Reason51,
- await_config_not_running();
+ config_ensure_not_running();
OK_51 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "51", OK_51}})
end,
%% --
- p("[test 52] write agents config file with invalid ip (2)"),
+ ?IPRINT("[test 52] write agents config file with invalid ip (2)"),
Agent52 = setelement(4, Agent0, "10101"),
write_agents_conf(ConfDir, [Agent52]),
case config_start(Opts) of
{error, Reason52} ->
- p("start failed (as expected): ~p", [Reason52]),
+ ?IPRINT("start failed (as expected): ~p", [Reason52]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason52,
- await_config_not_running();
+ config_ensure_not_running();
OK_52 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "52", OK_52}})
end,
%% --
- p("[test 53] write agents config file with invalid ip (3)"),
+ ?IPRINT("[test 53] write agents config file with invalid ip (3)"),
Agent53 = setelement(4, Agent0, "[192,168,0]"),
write_agents_conf(ConfDir, [Agent53]),
case config_start(Opts) of
{error, Reason53} ->
- p("start failed (as expected): ~p", [Reason53]),
+ ?IPRINT("start failed (as expected): ~p", [Reason53]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason53,
- await_config_not_running();
+ config_ensure_not_running();
OK_53 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "53", OK_53}})
end,
%% --
- p("[test 54] write agents config file with invalid ip (4)"),
+ ?IPRINT("[test 54] write agents config file with invalid ip (4)"),
Agent54 = setelement(4, Agent0, "[192,168,0,100,99]"),
write_agents_conf(ConfDir, [Agent54]),
case config_start(Opts) of
{error, Reason54} ->
- p("start failed (as expected): ~p", [Reason54]),
+ ?IPRINT("start failed (as expected): ~p", [Reason54]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason54,
- await_config_not_running();
+ config_ensure_not_running();
OK_54 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "54", OK_54}})
end,
%% --
- p("[test 55] write agents config file with invalid ip (5)"),
+ ?IPRINT("[test 55] write agents config file with invalid ip (5)"),
Agent55 = setelement(4, Agent0, "[192,168,0,arne]"),
write_agents_conf(ConfDir, [Agent55]),
?line {error, Reason55} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason55]),
+ ?IPRINT("start failed (as expected): ~p", [Reason55]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason55,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 61] write agents config file with invalid port (1)"),
+ ?IPRINT("[test 61] write agents config file with invalid port (1)"),
Agent61 = setelement(5, Agent0, "kalle_anka"),
write_agents_conf(ConfDir, [Agent61]),
?line {error, Reason61} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason61]),
+ ?IPRINT("start failed (as expected): ~p", [Reason61]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason61,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 62] write agents config file with invalid port (2)"),
+ ?IPRINT("[test 62] write agents config file with invalid port (2)"),
Agent62 = setelement(5, Agent0, "-1"),
write_agents_conf(ConfDir, [Agent62]),
?line {error, Reason62} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason62]),
+ ?IPRINT("start failed (as expected): ~p", [Reason62]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason62,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 63] write agents config file with invalid port (3)"),
+ ?IPRINT("[test 63] write agents config file with invalid port (3)"),
Agent63 = setelement(5, Agent0, "\"100\""),
write_agents_conf(ConfDir, [Agent63]),
?line {error, Reason63} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason63]),
+ ?IPRINT("start failed (as expected): ~p", [Reason63]),
?line {failed_check, _, _, _, {bad_address, _}} = Reason63,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 71] write agents config file with invalid engine-id (1)"),
+ ?IPRINT("[test 71] write agents config file with invalid engine-id (1)"),
Agent71 = setelement(6, Agent0, "kalle_anka"),
write_agents_conf(ConfDir, [Agent71]),
?line {error, Reason71} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason71]),
+ ?IPRINT("start failed (as expected): ~p", [Reason71]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason71,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 72] write agents config file with invalid engine-id (2)"),
+ ?IPRINT("[test 72] write agents config file with invalid engine-id (2)"),
Agent72 = setelement(6, Agent0, "10101"),
write_agents_conf(ConfDir, [Agent72]),
?line {error, Reason72} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason72]),
+ ?IPRINT("start failed (as expected): ~p", [Reason72]),
?line {failed_check, _, _, _, {invalid_string, _}} = Reason72,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 81] write agents config file with invalid timeout (1)"),
+ ?IPRINT("[test 81] write agents config file with invalid timeout (1)"),
Agent81 = setelement(7, Agent0, "kalle_anka"),
write_agents_conf(ConfDir, [Agent81]),
?line {error, Reason81} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason81]),
+ ?IPRINT("start failed (as expected): ~p", [Reason81]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason81,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 82] write agents config file with invalid timeout (2)"),
+ ?IPRINT("[test 82] write agents config file with invalid timeout (2)"),
Agent82 = setelement(7, Agent0, "-1"),
write_agents_conf(ConfDir, [Agent82]),
?line {error, Reason82} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason82]),
+ ?IPRINT("start failed (as expected): ~p", [Reason82]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason82,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 83] write agents config file with invalid timeout (3)"),
+ ?IPRINT("[test 83] write agents config file with invalid timeout (3)"),
Agent83 = setelement(7, Agent0, "{1000, 1, 10, kalle}"),
write_agents_conf(ConfDir, [Agent83]),
?line {error, Reason83} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason83]),
+ ?IPRINT("start failed (as expected): ~p", [Reason83]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason83,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 84] write agents config file with invalid timeout (4)"),
+ ?IPRINT("[test 84] write agents config file with invalid timeout (4)"),
Agent84 = setelement(7, Agent0, "{1000, -1, 10, 10}"),
write_agents_conf(ConfDir, [Agent84]),
?line {error, Reason84} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason84]),
+ ?IPRINT("start failed (as expected): ~p", [Reason84]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason84,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 85] write agents config file with invalid timeout (5)"),
+ ?IPRINT("[test 85] write agents config file with invalid timeout (5)"),
Agent85 = setelement(7, Agent0, "{1000, 1, -100, 10}"),
write_agents_conf(ConfDir, [Agent85]),
?line {error, Reason85} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason85]),
+ ?IPRINT("start failed (as expected): ~p", [Reason85]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason85,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 86] write agents config file with invalid timeout (6)"),
+ ?IPRINT("[test 86] write agents config file with invalid timeout (6)"),
Agent86 = setelement(7, Agent0, "{1000, 1, 100, -1}"),
write_agents_conf(ConfDir, [Agent86]),
?line {error, Reason86} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason86]),
+ ?IPRINT("start failed (as expected): ~p", [Reason86]),
?line {failed_check, _, _, _, {invalid_timer, _}} = Reason86,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 91] write agents config file with invalid max-message-size (1)"),
+ ?IPRINT("[test 91] write agents config file with invalid max-message-size (1)"),
Agent91 = setelement(8, Agent0, "483"),
write_agents_conf(ConfDir, [Agent91]),
?line {error, Reason91} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason91]),
+ ?IPRINT("start failed (as expected): ~p", [Reason91]),
?line {failed_check, _, _, _, {invalid_packet_size, _}} = Reason91,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 92] write agents config file with invalid max-message-size (2)"),
+ ?IPRINT("[test 92] write agents config file with invalid max-message-size (2)"),
Agent92 = setelement(8, Agent0, "kalle_anka"),
write_agents_conf(ConfDir, [Agent92]),
?line {error, Reason92} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason92]),
+ ?IPRINT("start failed (as expected): ~p", [Reason92]),
?line {failed_check, _, _, _, {invalid_packet_size, _}} = Reason92,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test A1] write agents config file with invalid version (1)"),
+ ?IPRINT("[test A1] write agents config file with invalid version (1)"),
AgentA1 = setelement(9, Agent0, "1"),
write_agents_conf(ConfDir, [AgentA1]),
?line {error, ReasonA1} = config_start(Opts),
- p("start failed (as expected): ~p", [ReasonA1]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonA1]),
?line {failed_check, _, _, _, {bad_version, _}} = ReasonA1,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test A2] write agents config file with invalid version (2)"),
+ ?IPRINT("[test A2] write agents config file with invalid version (2)"),
AgentA2 = setelement(9, Agent0, "v30"),
write_agents_conf(ConfDir, [AgentA2]),
?line {error, ReasonA2} = config_start(Opts),
- p("start failed (as expected): ~p", [ReasonA2]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonA2]),
?line {failed_check, _, _, _, {bad_version, _}} = ReasonA2,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test B1] write agents config file with invalid sec-model (1)"),
+ ?IPRINT("[test B1] write agents config file with invalid sec-model (1)"),
AgentB1 = setelement(10, Agent0, "\"any\""),
write_agents_conf(ConfDir, [AgentB1]),
?line {error, ReasonB1} = config_start(Opts),
- p("start failed (as expected): ~p", [ReasonB1]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonB1]),
?line {failed_check, _, _, _, {invalid_sec_model, _}} = ReasonB1,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test B2] write agents config file with invalid sec-model (2)"),
+ ?IPRINT("[test B2] write agents config file with invalid sec-model (2)"),
AgentB2 = setelement(10, Agent0, "v3"),
write_agents_conf(ConfDir, [AgentB2]),
?line {error, ReasonB2} = config_start(Opts),
- p("start failed (as expected): ~p", [ReasonB2]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonB2]),
?line {failed_check, _, _, _, {invalid_sec_model, _}} = ReasonB2,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test C1] write agents config file with invalid sec-name (1)"),
+ ?IPRINT("[test C1] write agents config file with invalid sec-name (1)"),
AgentC1 = setelement(11, Agent0, "initial"),
write_agents_conf(ConfDir, [AgentC1]),
case config_start(Opts) of
{error, ReasonC1} ->
- p("start failed (as expected): ~p", [ReasonC1]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonC1]),
?line {failed_check, _, _, _, {bad_sec_name, _}} = ReasonC1,
- await_config_not_running();
+ config_ensure_not_running();
OK_C1 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "C1", OK_C1}})
end,
%% --
- p("[test C2] write agents config file with invalid sec-name (2)"),
+ ?IPRINT("[test C2] write agents config file with invalid sec-name (2)"),
AgentC2 = setelement(11, Agent0, "10101"),
write_agents_conf(ConfDir, [AgentC2]),
case config_start(Opts) of
{error, ReasonC2} ->
- p("start failed (as expected): ~p", [ReasonC2]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonC2]),
?line {failed_check, _, _, _, {bad_sec_name, _}} = ReasonC2,
- await_config_not_running();
+ config_ensure_not_running();
OK_C2 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "C2", OK_C2}})
end,
%% --
- p("[test D1] write agents config file with invalid sec-level (1)"),
+ ?IPRINT("[test D1] write agents config file with invalid sec-level (1)"),
AgentD1 = setelement(12, Agent0, "\"noAuthNoPriv\""),
write_agents_conf(ConfDir, [AgentD1]),
case config_start(Opts) of
{error, ReasonD1} ->
- p("start failed (as expected): ~p", [ReasonD1]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonD1]),
?line {failed_check, _, _, _, {invalid_sec_level, _}} = ReasonD1,
- await_config_not_running();
+ config_ensure_not_running();
OK_D1 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "D1", OK_D1}})
end,
%% --
- p("[test D2] write agents config file with invalid sec-level (2)"),
+ ?IPRINT("[test D2] write agents config file with invalid sec-level (2)"),
AgentD2 = setelement(12, Agent0, "99"),
write_agents_conf(ConfDir, [AgentD2]),
case config_start(Opts) of
{error, ReasonD2} ->
- p("start failed (as expected): ~p", [ReasonD2]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonD2]),
?line {failed_check, _, _, _, {invalid_sec_level, _}} = ReasonD2,
- await_config_not_running();
+ config_ensure_not_running();
OK_D2 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "D2", OK_D2}})
end,
%% --
- p("[test E1] write agents config file with invalid agent (1)"),
+ ?IPRINT("[test E1] write agents config file with invalid agent (1)"),
write_agents_conf2(ConfDir, "{swiacf, \"targ-hobbes\"}."),
case config_start(Opts) of
{error, ReasonE1} ->
- p("start failed (as expected): ~p", [ReasonE1]),
+ ?IPRINT("start failed (as expected): ~p", [ReasonE1]),
?line {failed_check, _, _, _, {bad_agent_config, _}} = ReasonE1,
- await_config_not_running();
+ config_ensure_not_running();
OK_E1 ->
+ config_ensure_not_running(),
exit({error, {unexpected_success, "E1", OK_E1}})
end,
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -1389,8 +1449,8 @@ start_with_invalid_usm_conf_file1(suite) -> [];
start_with_invalid_usm_conf_file1(doc) ->
"Start with invalid usm config file.";
start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
- put(tname,swiusmcf),
- p("start"),
+ put(tname, "START-W-INV-USM-CONF-FILE-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
case ?CRYPTO_START() of
@@ -1424,179 +1484,179 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
"usmNoPrivProtocol", "[]"},
%% --
- p("[test 11] write usm config file with invalid engine-id (1)"),
+ ?IPRINT("[test 11] write usm config file with invalid engine-id (1)"),
Usm11 = setelement(1, Usm0, "kalle-anka"),
write_usm_conf(ConfDir, [Usm11]),
?line {error, Reason11} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason11]),
+ ?IPRINT("start failed (as expected): ~p", [Reason11]),
?line {failed_reading, _, _, _, {parse_error, _}} = Reason11,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 12] write usm config file with invalid engine-id (2)"),
+ ?IPRINT("[test 12] write usm config file with invalid engine-id (2)"),
Usm12 = setelement(1, Usm0, "kalle_anka"),
write_usm_conf(ConfDir, [Usm12]),
?line {error, Reason12} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason12]),
+ ?IPRINT("start failed (as expected): ~p", [Reason12]),
?line {failed_check, _, _, _, {bad_usm_engine_id, _}} = Reason12,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 13] write usm config file with invalid engine-id (3)"),
+ ?IPRINT("[test 13] write usm config file with invalid engine-id (3)"),
Usm13 = setelement(1, Usm1, "10101"),
write_usm_conf(ConfDir, [Usm13]),
?line {error, Reason13} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason13]),
+ ?IPRINT("start failed (as expected): ~p", [Reason13]),
?line {failed_check, _, _, _, {bad_usm_engine_id, _}} = Reason13,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 21] write usm config file with invalid user-name (1)"),
+ ?IPRINT("[test 21] write usm config file with invalid user-name (1)"),
Usm21 = setelement(2, Usm0, "kalle_anka"),
write_usm_conf(ConfDir, [Usm21]),
?line {error, Reason21} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason21]),
+ ?IPRINT("start failed (as expected): ~p", [Reason21]),
?line {failed_check, _, _, _, {bad_usm_user_name, _}} = Reason21,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 22] write usm config file with invalid user-name (1)"),
+ ?IPRINT("[test 22] write usm config file with invalid user-name (1)"),
Usm22 = setelement(2, Usm1, "10101"),
write_usm_conf(ConfDir, [Usm22]),
?line {error, Reason22} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason22]),
+ ?IPRINT("start failed (as expected): ~p", [Reason22]),
?line {failed_check, _, _, _, {bad_usm_user_name, _}} = Reason22,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 31] write usm config file with invalid sec-name (1)"),
+ ?IPRINT("[test 31] write usm config file with invalid sec-name (1)"),
Usm31 = setelement(3, Usm1, "kalle_anka"),
write_usm_conf(ConfDir, [Usm31]),
?line {error, Reason31} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason31]),
+ ?IPRINT("start failed (as expected): ~p", [Reason31]),
?line {failed_check, _, _, _, {bad_usm_sec_name, _}} = Reason31,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 32] write usm config file with invalid sec-name (2)"),
+ ?IPRINT("[test 32] write usm config file with invalid sec-name (2)"),
Usm32 = setelement(3, Usm1, "10101"),
write_usm_conf(ConfDir, [Usm32]),
?line {error, Reason32} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason32]),
+ ?IPRINT("start failed (as expected): ~p", [Reason32]),
?line {failed_check, _, _, _, {bad_usm_sec_name, _}} = Reason32,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 41] write usm config file with invalid auth-protocol (1)"),
+ ?IPRINT("[test 41] write usm config file with invalid auth-protocol (1)"),
Usm41 = setelement(3, Usm0, "\"usmNoAuthProtocol\""),
write_usm_conf(ConfDir, [Usm41]),
?line {error, Reason41} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason41]),
+ ?IPRINT("start failed (as expected): ~p", [Reason41]),
?line {failed_check, _, _, _, {invalid_auth_protocol, _}} = Reason41,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 42] write usm config file with invalid auth-protocol (2)"),
+ ?IPRINT("[test 42] write usm config file with invalid auth-protocol (2)"),
Usm42 = setelement(3, Usm0, "kalle"),
write_usm_conf(ConfDir, [Usm42]),
?line {error, Reason42} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason42]),
+ ?IPRINT("start failed (as expected): ~p", [Reason42]),
?line {failed_check, _, _, _, {invalid_auth_protocol, _}} = Reason42,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 43] write usm config file with invalid auth-protocol (3)"),
+ ?IPRINT("[test 43] write usm config file with invalid auth-protocol (3)"),
Usm43 = setelement(3, Usm0, "10101"),
write_usm_conf(ConfDir, [Usm43]),
?line {error, Reason43} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason43]),
+ ?IPRINT("start failed (as expected): ~p", [Reason43]),
?line {failed_check, _, _, _, {invalid_auth_protocol, _}} = Reason43,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 51] write usm config file with invalid auth-key (1)"),
+ ?IPRINT("[test 51] write usm config file with invalid auth-key (1)"),
Usm51 = setelement(3, Usm0, "usmHMACMD5AuthProtocol"),
write_usm_conf(ConfDir, [Usm51]),
?line {error, Reason51} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason51]),
+ ?IPRINT("start failed (as expected): ~p", [Reason51]),
?line {failed_check, _, _, _, {invalid_auth_key, _, _}} = Reason51,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 52] write usm config file with invalid auth-key (2)"),
+ ?IPRINT("[test 52] write usm config file with invalid auth-key (2)"),
Usm52 = setelement(4, Usm51, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]"),
write_usm_conf(ConfDir, [Usm52]),
?line {error, Reason52} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason52]),
+ ?IPRINT("start failed (as expected): ~p", [Reason52]),
?line {failed_check, _, _, _, {invalid_auth_key, _, 15}} = Reason52,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 53] write usm config file with invalid auth-key (3)"),
+ ?IPRINT("[test 53] write usm config file with invalid auth-key (3)"),
Usm53 = setelement(4, Usm51, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7]"),
write_usm_conf(ConfDir, [Usm53]),
?line {error, Reason53} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason53]),
+ ?IPRINT("start failed (as expected): ~p", [Reason53]),
?line {failed_check, _, _, _, {invalid_auth_key, _, 17}} = Reason53,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 54] write usm config file with invalid auth-key (4)"),
+ ?IPRINT("[test 54] write usm config file with invalid auth-key (4)"),
Usm54 = setelement(4, Usm51, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,kalle]"),
write_usm_conf(ConfDir, [Usm54]),
?line maybe_start_crypto(), %% Make sure it's started...
?line {error, Reason54} = config_start(Opts),
?line ok = maybe_stop_crypto(),
- p("start failed (as expected): ~p", [Reason54]),
+ ?IPRINT("start failed (as expected): ~p", [Reason54]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason54,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 55] write usm config file with invalid auth-key (5)"),
+ ?IPRINT("[test 55] write usm config file with invalid auth-key (5)"),
Usm55 = setelement(4, Usm51, "arne_anka"),
write_usm_conf(ConfDir, [Usm55]),
?line {error, Reason55} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason55]),
+ ?IPRINT("start failed (as expected): ~p", [Reason55]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason55,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 56] write usm config file with invalid auth-key (6)"),
+ ?IPRINT("[test 56] write usm config file with invalid auth-key (6)"),
Usm56 = setelement(4, Usm51, "10101"),
write_usm_conf(ConfDir, [Usm56]),
?line {error, Reason56} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason56]),
+ ?IPRINT("start failed (as expected): ~p", [Reason56]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason56,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 57] write usm config file with invalid auth-key (7)"),
+ ?IPRINT("[test 57] write usm config file with invalid auth-key (7)"),
Usm57 = setelement(3, Usm0, "usmHMACSHAAuthProtocol"),
write_usm_conf(ConfDir, [Usm57]),
?line {error, Reason57} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason57]),
+ ?IPRINT("start failed (as expected): ~p", [Reason57]),
?line {failed_check, _, _, _, {invalid_auth_key, _, _}} = Reason57,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 58] write usm config file with invalid auth-key (8)"),
+ ?IPRINT("[test 58] write usm config file with invalid auth-key (8)"),
Usm58 = setelement(4, Usm57, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]"),
write_usm_conf(ConfDir, [Usm58]),
?line {error, Reason58} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason58]),
+ ?IPRINT("start failed (as expected): ~p", [Reason58]),
?line {failed_check, _, _, _, {invalid_auth_key, _, 16}} = Reason58,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 59] write usm config file with invalid auth-key (9)"),
+ ?IPRINT("[test 59] write usm config file with invalid auth-key (9)"),
Usm59 = setelement(4, Usm57, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,ka]"),
write_usm_conf(ConfDir, [Usm59]),
?line ok = maybe_start_crypto(),
?line {error, Reason59} = config_start(Opts),
?line ok = maybe_stop_crypto(),
- p("start failed (as expected): ~p", [Reason59]),
+ ?IPRINT("start failed (as expected): ~p", [Reason59]),
?line {failed_check, _, _, _, {invalid_auth_key, _}} = Reason59,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
%% <CRYPTO-MODIFICATIONS>
@@ -1604,16 +1664,16 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
%% explicitly (all of it is as of R14 implemented with NIFs).
case (catch crypto:version()) of
{'EXIT', {undef, _}} ->
- p("[test 5A] write usm config file with valid auth-key "
+ ?IPRINT("[test 5A] write usm config file with valid auth-key "
"when crypto not started (10)"),
Usm5A = setelement(4,
Usm57,
"[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0]"),
write_usm_conf(ConfDir, [Usm5A]),
?line {error, Reason5A} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason5A]),
+ ?IPRINT("start failed (as expected): ~p", [Reason5A]),
?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason5A,
- await_config_not_running();
+ config_ensure_not_running();
_ ->
%% This function is only present in version 2.0 or greater.
%% The crypto app no longer needs to be explicitly started
@@ -1622,87 +1682,87 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
%% </CRYPTO-MODIFICATIONS>
%% --
- p("[test 61] write usm config file with invalid priv-protocol (1)"),
+ ?IPRINT("[test 61] write usm config file with invalid priv-protocol (1)"),
Usm61 = setelement(5, Usm0, "\"usmNoPrivProtocol\""),
write_usm_conf(ConfDir, [Usm61]),
?line {error, Reason61} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason61]),
+ ?IPRINT("start failed (as expected): ~p", [Reason61]),
?line {failed_check, _, _, _, {invalid_priv_protocol, _}} = Reason61,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 62] write usm config file with invalid priv-protocol (2)"),
+ ?IPRINT("[test 62] write usm config file with invalid priv-protocol (2)"),
Usm62 = setelement(5, Usm0, "kalle"),
write_usm_conf(ConfDir, [Usm62]),
?line {error, Reason62} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason62]),
+ ?IPRINT("start failed (as expected): ~p", [Reason62]),
?line {failed_check, _, _, _, {invalid_priv_protocol, _}} = Reason62,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 63] write usm config file with invalid priv-protocol (3)"),
+ ?IPRINT("[test 63] write usm config file with invalid priv-protocol (3)"),
Usm63 = setelement(5, Usm0, "10101"),
write_usm_conf(ConfDir, [Usm63]),
?line {error, Reason63} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason63]),
+ ?IPRINT("start failed (as expected): ~p", [Reason63]),
?line {failed_check, _, _, _, {invalid_priv_protocol, _}} = Reason63,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 71] write usm config file with invalid priv-key (1)"),
+ ?IPRINT("[test 71] write usm config file with invalid priv-key (1)"),
Usm71 = setelement(5, Usm0, "usmDESPrivProtocol"),
write_usm_conf(ConfDir, [Usm71]),
?line {error, Reason71} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason71]),
+ ?IPRINT("start failed (as expected): ~p", [Reason71]),
?line {failed_check, _, _, _, {invalid_priv_key, _, _}} = Reason71,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 72] write usm config file with invalid priv-key (2)"),
+ ?IPRINT("[test 72] write usm config file with invalid priv-key (2)"),
Usm72 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5]"),
write_usm_conf(ConfDir, [Usm72]),
?line {error, Reason72} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason72]),
+ ?IPRINT("start failed (as expected): ~p", [Reason72]),
?line {failed_check, _, _, _, {invalid_priv_key, _, 15}} = Reason72,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 73] write usm config file with invalid priv-key (3)"),
+ ?IPRINT("[test 73] write usm config file with invalid priv-key (3)"),
Usm73 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7]"),
write_usm_conf(ConfDir, [Usm73]),
?line {error, Reason73} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason73]),
+ ?IPRINT("start failed (as expected): ~p", [Reason73]),
?line {failed_check, _, _, _, {invalid_priv_key, _, 17}} = Reason73,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 74] write usm config file with invalid priv-key (4)"),
+ ?IPRINT("[test 74] write usm config file with invalid priv-key (4)"),
Usm74 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,kalle]"),
write_usm_conf(ConfDir, [Usm74]),
?line ok = maybe_start_crypto(),
?line {error, Reason74} = config_start(Opts),
?line ok = maybe_stop_crypto(),
- p("start failed (as expected): ~p", [Reason74]),
+ ?IPRINT("start failed (as expected): ~p", [Reason74]),
?line {failed_check, _, _, _, {invalid_priv_key, _}} = Reason74,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 75] write usm config file with invalid priv-key (5)"),
+ ?IPRINT("[test 75] write usm config file with invalid priv-key (5)"),
Usm75 = setelement(6, Usm71, "arne_anka"),
write_usm_conf(ConfDir, [Usm75]),
?line {error, Reason75} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason75]),
+ ?IPRINT("start failed (as expected): ~p", [Reason75]),
?line {failed_check, _, _, _, {invalid_priv_key, _}} = Reason75,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("[test 76] write usm config file with invalid priv-key (6)"),
+ ?IPRINT("[test 76] write usm config file with invalid priv-key (6)"),
Usm76 = setelement(6, Usm71, "10101"),
write_usm_conf(ConfDir, [Usm76]),
?line {error, Reason76} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason76]),
+ ?IPRINT("start failed (as expected): ~p", [Reason76]),
?line {failed_check, _, _, _, {invalid_priv_key, _}} = Reason76,
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
%% <CRYPTO-MODIFICATIONS>
@@ -1710,14 +1770,14 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
%% explicitly (all of it is as of R14 implemented with NIFs).
case (catch crypto:version()) of
{'EXIT', {undef, _}} ->
- p("[test 77] write usm config file with valid priv-key "
+ ?IPRINT("[test 77] write usm config file with valid priv-key "
"when crypto not started (7)"),
Usm77 = setelement(6, Usm71, "[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]"),
write_usm_conf(ConfDir, [Usm77]),
?line {error, Reason77} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason77]),
+ ?IPRINT("start failed (as expected): ~p", [Reason77]),
?line {failed_check, _, _, _, {unsupported_crypto, _}} = Reason77,
- await_config_not_running();
+ config_ensure_not_running();
_ ->
%% This function is only present in version 2.0 or greater.
%% The crypto app no longer needs to be explicitly started
@@ -1726,14 +1786,14 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
%% </CRYPTO-MODIFICATIONS>
%% --
- p("[test 78] write usm config file with invalid usm (1)"),
+ ?IPRINT("[test 78] write usm config file with invalid usm (1)"),
write_usm_conf2(ConfDir, "{\"bmkEngine\", \"swiusmcf\"}."),
?line {error, Reason81} = config_start(Opts),
- p("start failed (as expected): ~p", [Reason81]),
+ ?IPRINT("start failed (as expected): ~p", [Reason81]),
?line {failed_check, _, _, _, {bad_usm_config, _}} = Reason81,
- await_config_not_running(),
+ config_ensure_not_running(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -1746,28 +1806,28 @@ start_with_create_db_and_dir_opt(doc) ->
"Start the snmp manager config process with the\n"
"create_db_and_dir option.";
start_with_create_db_and_dir_opt(Conf) when is_list(Conf) ->
- put(tname, swcdado),
- p("start"),
+ put(tname, "START-W-CRE-DB-AND-DIR-OPT"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
true = not filelib:is_dir(DbDir) and not filelib:is_file(DbDir),
write_manager_conf(ConfDir),
- p("verify nonexistent db_dir"),
+ ?IPRINT("verify nonexistent db_dir"),
ConfigOpts01 = [{verbosity,trace}, {dir, ConfDir}, {db_dir, DbDir}],
{error, Reason01} = config_start([{config, ConfigOpts01}]),
- p("nonexistent db_dir res: ~p", [Reason01]),
+ ?IPRINT("nonexistent db_dir res: ~p", [Reason01]),
{invalid_conf_db_dir, _, not_found} = Reason01,
- p("verify nonexistent db_dir gets created"),
+ ?IPRINT("verify nonexistent db_dir gets created"),
ConfigOpts02 = [{db_init_error, create_db_and_dir} | ConfigOpts01],
{ok, _Pid} = config_start([{config, ConfigOpts02}]),
true = filelib:is_dir(DbDir),
- p("verified: nonexistent db_dir was correctly created"),
+ ?IPRINT("verified: nonexistent db_dir was correctly created"),
ok = config_stop(),
- p("done"),
+ ?IPRINT("done"),
ok.
%%
@@ -1780,8 +1840,8 @@ simple_system_op(doc) ->
"Access some of the known system info and some \n"
"system info that does not exist.";
simple_system_op(Conf) when is_list(Conf) ->
- put(tname,sso),
- p("start"),
+ put(tname, "SIMPLE-SYS-OP"),
+ ?IPRINT("start"),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -1790,21 +1850,21 @@ simple_system_op(Conf) when is_list(Conf) ->
Opts = [{versions, [v1]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start config"),
+ ?IPRINT("start config"),
?line {ok, _Pid} = config_start(Opts),
- p("retreive various configs"),
+ ?IPRINT("retreive various configs"),
?line {ok, _Time} = snmpm_config:system_start_time(),
?line {ok, _EngineId} = snmpm_config:get_engine_id(),
?line {ok, _MMS} = snmpm_config:get_engine_max_message_size(),
- p("attempt to retreive nonexisting"),
+ ?IPRINT("attempt to retreive nonexisting"),
?line {error, not_found} = snmpm_config:system_info(kalle),
?line ok = config_stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -1822,8 +1882,8 @@ register_user_using_file(suite) -> [];
register_user_using_file(doc) ->
"Register user using the 'users.conf' file.";
register_user_using_file(Conf) when is_list(Conf) ->
- put(tname,ruufi),
- p("start"),
+ put(tname, "REG-USER-USING-FILE"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
_ConfDir = ?config(manager_conf_dir, Conf),
_DbDir = ?config(manager_db_dir, Conf),
@@ -1838,8 +1898,8 @@ register_user_using_function(suite) -> [];
register_user_using_function(doc) ->
"Register user using the API (function).";
register_user_using_function(Conf) when is_list(Conf) ->
- put(tname,ruufu),
- p("start"),
+ put(tname, "REG-USER-USING-FUNC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
_ConfDir = ?config(manager_conf_dir, Conf),
_DbDir = ?config(manager_db_dir, Conf),
@@ -1854,8 +1914,8 @@ register_user_failed_using_function1(suite) -> [];
register_user_failed_using_function1(doc) ->
"Register user failed using incorrect arguments to API (function).";
register_user_failed_using_function1(Conf) when is_list(Conf) ->
- put(tname,rufufu1),
- p("start"),
+ put(tname, "REG-USER-FAIL-USING-FUNC-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
_ConfDir = ?config(manager_conf_dir, Conf),
_DbDir = ?config(manager_db_dir, Conf),
@@ -1872,13 +1932,29 @@ register_user_failed_using_function1(Conf) when is_list(Conf) ->
%% ---
%%
+%% This test case tests that we can "register" agents using a config file.
+%% So, starting the config process is part of the actual test, but even
+%% if the test fails, we want to make sure the config process is actually
+%% stop'ed. So, we put config stop in the post.
+
register_agent_using_file(suite) -> [];
register_agent_using_file(doc) ->
"Register agents using the 'agents'conf' file.";
register_agent_using_file(Conf) when is_list(Conf) ->
- put(tname,raufi),
- p("start"),
+ put(tname, "REG-AG-USING-FILE"),
process_flag(trap_exit, true),
+ Pre = fun() -> ok end,
+ Case = fun(_) -> do_register_agent_using_file(Conf) end,
+ Post = fun(_) ->
+ ?IPRINT("stop config process"),
+ ?line ok = snmpm_config:stop(),
+ config_ensure_not_running(),
+ ok
+ end,
+ ?TC_TRY(register_agent_using_file, Pre, Case, Post).
+
+do_register_agent_using_file(Conf) ->
+ ?IPRINT("start"),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -1887,11 +1963,11 @@ register_agent_using_file(Conf) when is_list(Conf) ->
%% --
- p("write manager config file"),
+ ?IPRINT("write manager config file"),
write_manager_conf(ConfDir),
%% --
- p("write users config file"),
+ ?IPRINT("write users config file"),
UserId1 = raufi1,
UserId1Str = str(UserId1),
UserId2 = raufi2,
@@ -1901,7 +1977,7 @@ register_agent_using_file(Conf) when is_list(Conf) ->
write_users_conf(ConfDir, [User1, User2]),
%% --
- p("write agents config file"),
+ ?IPRINT("write agents config file"),
AgentAddr1 = [192,168,0,101],
AgentAddr1Str = str(AgentAddr1),
AgentPort1 = 162,
@@ -1929,38 +2005,38 @@ register_agent_using_file(Conf) when is_list(Conf) ->
write_agents_conf(ConfDir, [Agent1Str, Agent2Str]),
%% --
- p("start the config process"),
+ ?IPRINT("start the config process"),
?line {ok, _Pid} = config_start(Opts),
%% --
- p("which agents"),
+ ?IPRINT("which agents"),
?line [_, _] = All = snmpm_config:which_agents(),
- p("all agents: ~n ~p", [All]),
+ ?IPRINT("all agents: ~n ~p", [All]),
?line [A1] = snmpm_config:which_agents(UserId1),
- p("agents belonging to ~w: ~n ~p", [UserId1, A1]),
+ ?IPRINT("agents belonging to ~w: ~n ~p", [UserId1, A1]),
?line [A2] = snmpm_config:which_agents(UserId2),
- p("agents belonging to ~w: ~n ~p", [UserId2, A2]),
+ ?IPRINT("agents belonging to ~w: ~n ~p", [UserId2, A2]),
%% --
- p("All info for agent <~w,~w>", [AgentAddr1, AgentPort1]),
+ ?IPRINT("All info for agent <~w,~w>", [AgentAddr1, AgentPort1]),
?line {ok, AllInfo1} =
snmpm_config:agent_info(AgentAddr1, AgentPort1, all),
- p("all agent info for agent: ~n ~p", [AllInfo1]),
+ ?IPRINT("all agent info for agent: ~n ~p", [AllInfo1]),
%% --
- p("EngineID (~p) for agent <~w,~w>", [EngineID1, AgentAddr1, AgentPort1]),
+ ?IPRINT("EngineID (~p) for agent <~w,~w>", [EngineID1, AgentAddr1, AgentPort1]),
?line {ok, EngineID1} =
snmpm_config:agent_info(AgentAddr1, AgentPort1, engine_id),
%% --
- p("All info for agent <~w,~w>", [AgentAddr2, AgentPort2]),
+ ?IPRINT("All info for agent <~w,~w>", [AgentAddr2, AgentPort2]),
?line {ok, AllInfo2} =
snmpm_config:agent_info(AgentAddr2, AgentPort2, all),
- p("all agent info for agent: ~n ~p", [AllInfo2]),
+ ?IPRINT("all agent info for agent: ~n ~p", [AllInfo2]),
%% --
- p("EngineID (~p) for agent <~w,~w>", [EngineID2, AgentAddr2, AgentPort2]),
+ ?IPRINT("EngineID (~p) for agent <~w,~w>", [EngineID2, AgentAddr2, AgentPort2]),
?line {ok, EngineID2} =
snmpm_config:agent_info(AgentAddr2, AgentPort2, engine_id),
@@ -1968,7 +2044,7 @@ register_agent_using_file(Conf) when is_list(Conf) ->
?line {ok, MMS2} =
snmpm_config:agent_info(AgentAddr2, AgentPort2, max_message_size),
NewMMS21 = 2048,
- p("try update agent info max-message-size to ~w for agent <~w,~w>",
+ ?IPRINT("try update agent info max-message-size to ~w for agent <~w,~w>",
[NewMMS21, AgentAddr2, AgentPort2]),
?line ok = snmpm_config:update_agent_info(UserId2, AgentAddr2, AgentPort2,
max_message_size, NewMMS21),
@@ -1976,34 +2052,29 @@ register_agent_using_file(Conf) when is_list(Conf) ->
snmpm_config:agent_info(AgentAddr2, AgentPort2, max_message_size),
%% --
- p("try (and fail) to update agent info max-message-size to ~w "
+ ?IPRINT("try (and fail) to update agent info max-message-size to ~w "
"for agent <~w,~w> "
"with user ~w (not owner)",
[NewMMS21, AgentAddr2, AgentPort2, UserId1]),
?line {error, Reason01} =
snmpm_config:update_agent_info(UserId1, AgentAddr2, AgentPort2,
max_message_size, NewMMS21),
- p("expected failure. Reason01: ~p", [Reason01]),
+ ?IPRINT("expected failure. Reason01: ~p", [Reason01]),
?line {ok, NewMMS21} =
snmpm_config:agent_info(AgentAddr2, AgentPort2, max_message_size),
%% --
NewMMS22 = 400,
- p("try (and fail) to update agent info max-message-size to ~w "
+ ?IPRINT("try (and fail) to update agent info max-message-size to ~w "
"for agent <~w,~w>",
[NewMMS22, AgentAddr2, AgentPort2]),
?line {error, Reason02} =
snmpm_config:update_agent_info(UserId1, AgentAddr2, AgentPort2,
max_message_size, NewMMS22),
- p("expected failure. Reason02: ~p", [Reason02]),
+ ?IPRINT("expected failure. Reason02: ~p", [Reason02]),
%% --
- p("stop config process"),
- ?line ok = snmpm_config:stop(),
- await_config_not_running(),
-
- %% --
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2015,8 +2086,8 @@ register_agent_using_function(suite) -> [];
register_agent_using_function(doc) ->
"Register agents using the API (function).";
register_agent_using_function(Conf) when is_list(Conf) ->
- put(tname,raufu),
- p("start"),
+ put(tname, "REG-AG-USING-FUNC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
_ConfDir = ?config(manager_conf_dir, Conf),
_DbDir = ?config(manager_db_dir, Conf),
@@ -2032,8 +2103,8 @@ register_agent_failed_using_function1(doc) ->
"Register agents failng using the API (function) with incorrect "
"config (1).";
register_agent_failed_using_function1(Conf) when is_list(Conf) ->
- put(tname,rafuf1),
- p("start"),
+ put(tname, "REG-AG-FAIL-USING-FUNC-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
_ConfDir = ?config(manager_conf_dir, Conf),
_DbDir = ?config(manager_db_dir, Conf),
@@ -2054,8 +2125,8 @@ register_usm_user_using_file(suite) -> [];
register_usm_user_using_file(doc) ->
"Register usm user using the 'usm.conf' file.";
register_usm_user_using_file(Conf) when is_list(Conf) ->
- put(tname,ruuufi),
- p("start"),
+ put(tname, "REG-USM-USER-USING-FILE"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
case ?CRYPTO_START() of
@@ -2077,11 +2148,11 @@ register_usm_user_using_file(Conf) when is_list(Conf) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
%% --
- p("write manager config file"),
+ ?IPRINT("write manager config file"),
write_manager_conf(ConfDir),
%% --
- p("write usm user config file"),
+ ?IPRINT("write usm user config file"),
SecEngineID = "loctzp's engine",
SecName1 = "samu_auth1",
UserName1 = SecName1,
@@ -2101,31 +2172,31 @@ register_usm_user_using_file(Conf) when is_list(Conf) ->
write_usm_conf(ConfDir, [UsmUser1, UsmUser2]),
%% --
- p("start the config process"),
+ ?IPRINT("start the config process"),
?line {ok, _Pid} = config_start(Opts),
%% --
- p("lookup 1 (ok)"),
+ ?IPRINT("lookup 1 (ok)"),
?line {ok, #usm_user{name = UserName1} = User1} =
snmpm_config:get_usm_user_from_sec_name(SecEngineID, SecName1),
- p("User: ~p", [User1]),
+ ?IPRINT("User: ~p", [User1]),
- p("lookup 2 (ok)"),
+ ?IPRINT("lookup 2 (ok)"),
?line {ok, #usm_user{name = UserName2} = User2} =
snmpm_config:get_usm_user_from_sec_name(SecEngineID, SecName2),
- p("User: ~p", [User2]),
+ ?IPRINT("User: ~p", [User2]),
- p("lookup 3 (error)"),
+ ?IPRINT("lookup 3 (error)"),
?line {error, not_found} =
snmpm_config:get_usm_user_from_sec_name(SecEngineID, SecName2 ++ "_1"),
%% --
- p("stop config process"),
+ ?IPRINT("stop config process"),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2137,8 +2208,8 @@ register_usm_user_using_function(suite) -> [];
register_usm_user_using_function(doc) ->
"Register usm user using the API (function).";
register_usm_user_using_function(Conf) when is_list(Conf) ->
- put(tname,ruuufu),
- p("start"),
+ put(tname, "REG-USM-USER-USING-FUNC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
case ?CRYPTO_START() of
@@ -2160,18 +2231,18 @@ register_usm_user_using_function(Conf) when is_list(Conf) ->
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
%% --
- p("write manager config file"),
+ ?IPRINT("write manager config file"),
write_manager_conf(ConfDir),
%% --
- p("start the config process"),
+ ?IPRINT("start the config process"),
?line {ok, _Pid} = config_start(Opts),
%% --
- p("register usm user's"),
+ ?IPRINT("register usm user's"),
EngineID = "loctzp's engine",
- p("register user 1 (ok)"),
+ ?IPRINT("register user 1 (ok)"),
UserName1 = "samu_auth1",
SecName1 = UserName1,
UsmConfig1 = [{sec_name, SecName1},
@@ -2179,11 +2250,11 @@ register_usm_user_using_function(Conf) when is_list(Conf) ->
{auth_key, [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6]},
{priv, usmNoPrivProtocol}],
?line ok = snmpm_config:register_usm_user(EngineID, UserName1, UsmConfig1),
- p("try register user 1 again (error)"),
+ ?IPRINT("try register user 1 again (error)"),
?line {error, {already_registered, EngineID, UserName1}} =
snmpm_config:register_usm_user(EngineID, UserName1, UsmConfig1),
- p("register user 2 (ok)"),
+ ?IPRINT("register user 2 (ok)"),
UserName2 = "samu_auth2",
SecName2 = UserName2,
UsmConfig2 = [{auth, usmHMACMD5AuthProtocol},
@@ -2191,7 +2262,7 @@ register_usm_user_using_function(Conf) when is_list(Conf) ->
{priv, usmNoPrivProtocol}],
?line ok = snmpm_config:register_usm_user(EngineID, UserName2, UsmConfig2),
- p("register user 3 (ok)"),
+ ?IPRINT("register user 3 (ok)"),
UserName3 = "samu3",
SecName3 = "samu_auth3",
UsmConfig3 = [{sec_name, SecName3},
@@ -2200,32 +2271,32 @@ register_usm_user_using_function(Conf) when is_list(Conf) ->
{priv, usmNoPrivProtocol}],
?line ok = snmpm_config:register_usm_user(EngineID, UserName3, UsmConfig3),
- p("lookup 1 (ok)"),
+ ?IPRINT("lookup 1 (ok)"),
?line {ok, #usm_user{name = UserName1} = User1} =
snmpm_config:get_usm_user_from_sec_name(EngineID, SecName1),
- p("User: ~p", [User1]),
+ ?IPRINT("User: ~p", [User1]),
- p("lookup 2 (ok)"),
+ ?IPRINT("lookup 2 (ok)"),
?line {ok, #usm_user{name = UserName2} = User2} =
snmpm_config:get_usm_user_from_sec_name(EngineID, SecName2),
- p("User: ~p", [User2]),
+ ?IPRINT("User: ~p", [User2]),
- p("lookup 3 (ok)"),
+ ?IPRINT("lookup 3 (ok)"),
?line {ok, #usm_user{name = UserName3} = User3} =
snmpm_config:get_usm_user_from_sec_name(EngineID, SecName3),
- p("User: ~p", [User3]),
+ ?IPRINT("User: ~p", [User3]),
- p("lookup 4 (error)"),
+ ?IPRINT("lookup 4 (error)"),
?line {error, not_found} =
snmpm_config:get_usm_user_from_sec_name(EngineID, SecName3 ++ "_1"),
%% --
- p("stop config process"),
+ ?IPRINT("stop config process"),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
%% --
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2237,8 +2308,8 @@ register_usm_user_failed_using_function1(suite) -> [];
register_usm_user_failed_using_function1(doc) ->
"Register usm user failed using incorrect arguments to API (function).";
register_usm_user_failed_using_function1(Conf) when is_list(Conf) ->
- put(tname,ruufufu1),
- p("start"),
+ put(tname, "REG-USM-USER-FAIL-USING-FUNC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
case ?CRYPTO_START() of
@@ -2266,8 +2337,8 @@ update_usm_user_info(suite) -> [];
update_usm_user_info(doc) ->
"Update usm user info.";
update_usm_user_info(Conf) when is_list(Conf) ->
- put(tname,ruufufu1),
- p("start"),
+ put(tname, "UPD-USM-USER-INFO"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
case ?CRYPTO_START() of
@@ -2301,8 +2372,8 @@ create_and_increment(suite) -> [];
create_and_increment(doc) ->
"Craete and increment counters.";
create_and_increment(Conf) when is_list(Conf) ->
- put(tname,cai),
- p("start"),
+ put(tname, "CRE-AND-INC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -2317,10 +2388,6 @@ create_and_increment(Conf) when is_list(Conf) ->
%% Random init
?SNMP_RAND_SEED(),
- %% rand:seed(exrop,
- %% {erlang:phash2([node()]),
- %% erlang:monotonic_time(),
- %% erlang:unique_integer()}),
StartVal = rand:uniform(2147483647),
IncVal = 42,
@@ -2330,7 +2397,7 @@ create_and_increment(Conf) when is_list(Conf) ->
?line EndVal = snmpm_config:incr_counter(test_id, IncVal),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
ok.
@@ -2348,8 +2415,8 @@ stats_create_and_increment(suite) -> [];
stats_create_and_increment(doc) ->
"Create and increment statistics counters.";
stats_create_and_increment(Conf) when is_list(Conf) ->
- put(tname,scai),
- p("start"),
+ put(tname, "STATS-CRE-AND-INC"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -2362,26 +2429,26 @@ stats_create_and_increment(Conf) when is_list(Conf) ->
?line {ok, _Pid} = snmpm_config:start_link(Opts),
- p("stats table (1): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (1): ~p", [ets:tab2list(snmpm_stats_table)]),
?line 0 = snmpm_config:maybe_cre_stats_counter(stats1, 0),
- p("stats table (2): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (2): ~p", [ets:tab2list(snmpm_stats_table)]),
?line ok = snmpm_config:maybe_cre_stats_counter(stats1, 0),
- p("stats table (3): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (3): ~p", [ets:tab2list(snmpm_stats_table)]),
?line 1 = snmpm_config:maybe_cre_stats_counter(stats2, 1),
- p("stats table (4): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (4): ~p", [ets:tab2list(snmpm_stats_table)]),
?line 10 = snmpm_config:cre_stats_counter(stats3, 10),
- p("stats table (5): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (5): ~p", [ets:tab2list(snmpm_stats_table)]),
Stats1Inc = fun() -> snmpm_config:incr_stats_counter(stats1, 1) end,
?line 10 = loop(10, -1, Stats1Inc),
- p("stats table (6): ~p", [ets:tab2list(snmpm_stats_table)]),
+ ?IPRINT("stats table (6): ~p", [ets:tab2list(snmpm_stats_table)]),
?line ok = snmpm_config:reset_stats_counter(stats1),
?line 10 = loop(10, -1, Stats1Inc),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
ok.
@@ -2403,46 +2470,46 @@ otp_7219(suite) ->
otp_7219(doc) ->
"Test-case for ticket OTP-7219";
otp_7219(Config) when is_list(Config) ->
- put(tname, otp7219),
- p("start"),
+ put(tname, "OTP-7219"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Config),
DbDir = ?config(manager_db_dir, Config),
- p("write manager configuration"),
+ ?IPRINT("write manager configuration"),
write_manager_conf(ConfDir),
Opts1 = [{versions, [v1]},
{inform_request_behaviour, user},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start manager config"),
+ ?IPRINT("start manager config"),
?line {ok, _Pid1} = snmpm_config:start_link(Opts1),
- p("get some manager config"),
+ ?IPRINT("get some manager config"),
{ok, {user, _}} = snmpm_config:system_info(net_if_irb),
- p("stop manager config"),
+ ?IPRINT("stop manager config"),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
IRB_TO = 15322,
Opts2 = [{versions, [v1]},
{inform_request_behaviour, {user, IRB_TO}},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start manager config"),
+ ?IPRINT("start manager config"),
?line {ok, _Pid2} = snmpm_config:start_link(Opts2),
- p("get some manager config"),
+ ?IPRINT("get some manager config"),
{ok, {user, IRB_TO}} = snmpm_config:system_info(net_if_irb),
- p("stop manager config"),
+ ?IPRINT("stop manager config"),
?line ok = snmpm_config:stop(),
- await_config_not_running(),
+ config_ensure_not_running(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2452,8 +2519,8 @@ otp_8395_1(suite) -> [];
otp_8395_1(doc) ->
"OTP-8395(1)";
otp_8395_1(Conf) when is_list(Conf) ->
- put(tname, otp_8395_1),
- p("start"),
+ put(tname, "OTP-8395-1"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
otp8395(Conf, false, ok),
ok.
@@ -2462,8 +2529,8 @@ otp_8395_2(suite) -> [];
otp_8395_2(doc) ->
"OTP-8395(2)";
otp_8395_2(Conf) when is_list(Conf) ->
- put(tname, otp_8395_2),
- p("start"),
+ put(tname, "OTP-8395-2"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
otp8395(Conf, true, ok),
ok.
@@ -2472,8 +2539,8 @@ otp_8395_3(suite) -> [];
otp_8395_3(doc) ->
"OTP-8395(3)";
otp_8395_3(Conf) when is_list(Conf) ->
- put(tname, otp_8395_3),
- p("start"),
+ put(tname, "OTP-8395-3"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
otp8395(Conf, gurka, error),
ok.
@@ -2487,7 +2554,7 @@ otp8395(Conf, SeqNoVal, Expect) ->
write_manager_conf(ConfDir),
%% Third set of options (no versions):
- p("all options"),
+ ?IPRINT("all options"),
NetIfOpts = [{module, snmpm_net_if},
{verbosity, trace},
{options, [{recbuf, 30000},
@@ -2526,7 +2593,7 @@ otp8395(Conf, SeqNoVal, Expect) ->
Error when (Expect =:= ok) ->
exit({unexpected_failed_starting_config, SeqNoVal, Error})
end,
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2534,8 +2601,8 @@ otp_8395_4(suite) -> [];
otp_8395_4(doc) ->
"OTP-8395(4)";
otp_8395_4(Conf) when is_list(Conf) ->
- put(tname, otp_8395_4),
- p("start"),
+ put(tname, "OTP-8395-4"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
snmp:print_version_info(),
@@ -2548,7 +2615,7 @@ otp_8395_4(Conf) when is_list(Conf) ->
write_manager_conf(ConfDir),
%% Third set of options (no versions):
- p("all options"),
+ ?IPRINT("all options"),
NetIfOpts = [{module, snmpm_net_if},
{verbosity, trace},
{options, [{recbuf, 30000},
@@ -2595,7 +2662,7 @@ otp_8395_4(Conf) when is_list(Conf) ->
?line ok = config_stop(),
- p("done"),
+ ?IPRINT("done"),
ok.
@@ -2607,52 +2674,17 @@ otp8395_incr_counter(Counter, Initial, Increment, Max) ->
%% Internal functions
%%======================================================================
-await_config_not_running() ->
- await_not_running(snmpm_config, 5).
-
-await_not_running(Name, 0) ->
- p("await_not_running -> done waiting for ~w to die - try kill it", [Name]),
- %% Ok, we tried it the nice way, now use brute force
- await_killed(Name, 5);
-await_not_running(Name, N) when N > 0 ->
- p("await_not_running -> is process ~w still running (~w)", [Name, N]),
- case erlang:whereis(Name) of
- undefined ->
- p("await_not_running -> no such (~w) process - sleep some",[Name]),
- ?SLEEP(1000),
- p("await_not_running -> no such (~w) process - done", [Name]),
- ok;
- Pid when is_pid(Pid) ->
- p("~w process still running", [Name]),
- ?SLEEP(500),
- await_not_running(Name, N-1)
- end.
-
-await_killed(Name, 0) ->
- p("await_killed -> could not kill ~w => giving up", [Name]),
- exit({error, {failed_terminating, Name}});
-await_killed(Name, N) when N > 0 ->
- p("await_killed -> is process ~w still running (~w)", [Name, N]),
- case whereis(Name) of
- undefined ->
- p("await_killed -> no such (~w) process - sleep some", [Name]),
- ?SLEEP(1000),
- p("await_killed -> no such (~w) process - done", [Name]),
- ok;
- Pid when is_pid(Pid) ->
- p("await_killed -> ~w still running - try kill it", [Name]),
- exit(Pid, kill),
- ?SLEEP(1000),
- await_killed(Name, N-1)
- end.
-
-
config_start(Opts) ->
(catch snmpm_config:start_link(Opts)).
config_stop() ->
(catch snmpm_config:stop()).
+config_ensure_not_running() ->
+ ?ENSURE_NOT_RUNNING(snmpm_config,
+ fun() -> snmpm_config:stop() end,
+ 1000).
+
%% ------
@@ -2809,20 +2841,5 @@ verify_dir_existing(DirName, Dir) ->
%% ------
str(X) ->
- lists:flatten(io_lib:format("~w", [X])).
-
-
-%% ------
-
-p(F) ->
- p(F, []).
-
-p(F, A) ->
- p(get(tname), F, A).
-
-p(TName, F, A) ->
- io:format("*** [~s] ***"
- " ~w -> " ++ F ++ "~n", [formated_timestamp(),TName|A]).
+ ?F("~w", [X]).
-formated_timestamp() ->
- snmp_test_lib:formated_timestamp().
diff --git a/lib/snmp/test/snmp_manager_user_SUITE.erl b/lib/snmp/test/snmp_manager_user_SUITE.erl
index 353f1b21f3..eca0d8a4f9 100644
--- a/lib/snmp/test/snmp_manager_user_SUITE.erl
+++ b/lib/snmp/test/snmp_manager_user_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -143,8 +143,8 @@ tickets_cases() ->
init_per_suite(Config0) when is_list(Config0) ->
- p("init_per_suite -> entry with"
- "~n Config0: ~p", [Config0]),
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config0: ~p", [Config0]),
case ?LIB:init_per_suite(Config0) of
{skip, _} = SKIP ->
@@ -153,19 +153,23 @@ init_per_suite(Config0) when is_list(Config0) ->
snmp_test_sys_monitor:start(),
Config2 = snmp_test_lib:init_suite_top_dir(?MODULE, Config1),
- p("init_per_suite -> done when"
- "~n Config: ~p", [Config2]),
+ ?IPRINT("init_per_suite -> done when"
+ "~n Config: ~p", [Config2]),
Config2
end.
end_per_suite(Config) when is_list(Config) ->
- p("end_per_suite -> entry with"
- "~n Config: ~p", [Config]),
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config: ~p", [Config]),
snmp_test_sys_monitor:stop(),
- ?LIB:end_per_suite(Config).
+ Config1 = ?LIB:end_per_suite(Config),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
@@ -186,14 +190,15 @@ end_per_group(_GroupName, Config) ->
%%
init_per_testcase(Case, Config) when is_list(Config) ->
- p("init_per_testcase -> Case: ~p", [Case]),
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
snmp_test_global_sys_monitor:reset_events(),
SuiteTopDir = ?config(snmp_suite_top_dir, Config),
CaseTopDir = filename:join(SuiteTopDir, atom_to_list(Case)),
?line ok = file:make_dir(CaseTopDir),
- p("init_per_testcase -> CaseTopDir: ~p", [CaseTopDir]),
+ ?IPRINT("init_per_testcase -> CaseTopDir: ~p", [CaseTopDir]),
MgrTopDir = filename:join(CaseTopDir, "manager/"),
?line ok = file:make_dir(MgrTopDir),
MgrConfDir = filename:join(MgrTopDir, "conf/"),
@@ -202,18 +207,27 @@ init_per_testcase(Case, Config) when is_list(Config) ->
?line ok = file:make_dir(MgrDbDir),
MgrLogDir = filename:join(MgrTopDir, "log/"),
?line ok = file:make_dir(MgrLogDir),
- [{case_top_dir, CaseTopDir},
- {manager_dir, MgrTopDir},
- {manager_conf_dir, MgrConfDir},
- {manager_db_dir, MgrDbDir},
- {manager_log_dir, MgrLogDir} | Config].
+ Config1 = [{case_top_dir, CaseTopDir},
+ {manager_dir, MgrTopDir},
+ {manager_conf_dir, MgrConfDir},
+ {manager_db_dir, MgrDbDir},
+ {manager_log_dir, MgrLogDir} | Config],
+
+ ?IPRINT("init_per_testcase -> done when"
+ "~n Config: ~p", [Config1]),
+
+ Config1.
+
+
+end_per_testcase(_Case, Config) when is_list(Config) ->
-end_per_testcase(Case, Config) when is_list(Config) ->
- p("end_per_testcase -> Case: ~p", [Case]),
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p",
+ [Config]),
- p("system events during test: "
- "~n ~p~n", [snmp_test_global_sys_monitor:events()]),
+ ?IPRINT("system events during test: ~p",
+ [snmp_test_global_sys_monitor:events()]),
Config.
@@ -228,7 +242,7 @@ simple_register_and_unregister1(doc) ->
"Start a user, register and unregister the user.";
simple_register_and_unregister1(Conf) when is_list(Conf) ->
put(tname,srar1),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -241,7 +255,7 @@ simple_register_and_unregister1(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -251,23 +265,23 @@ simple_register_and_unregister1(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id),
?line [Id] = Users2 = which_users(),
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = unregister_user(Pid),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -279,7 +293,7 @@ simple_register_and_unregister2(doc) ->
"register 2 users (per that process) and unregister the 2 users.";
simple_register_and_unregister2(Conf) when is_list(Conf) ->
put(tname,srar2),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -292,7 +306,7 @@ simple_register_and_unregister2(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -303,7 +317,7 @@ simple_register_and_unregister2(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id1),
?line ok = register_user(Pid, Id2),
@@ -316,20 +330,20 @@ simple_register_and_unregister2(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = unregister_user(Pid, Id1),
?line ok = unregister_user(Pid, Id2),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -341,7 +355,7 @@ simple_register_and_unregister3(doc) ->
"register one users per process and unregister the 2 users.";
simple_register_and_unregister3(Conf) when is_list(Conf) ->
put(tname,srar2),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -354,7 +368,7 @@ simple_register_and_unregister3(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -366,7 +380,7 @@ simple_register_and_unregister3(Conf) when is_list(Conf) ->
?line Pid2 = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid1, Id1),
?line ok = register_user(Pid2, Id2),
@@ -379,21 +393,21 @@ simple_register_and_unregister3(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = unregister_user(Pid1, Id1),
?line ok = unregister_user(Pid2, Id2),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid1),
?line stop_user(Pid2),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -404,7 +418,7 @@ register_and_crash1(doc) ->
"Start a user, register and crash user.";
register_and_crash1(Conf) when is_list(Conf) ->
put(tname,racau1),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -417,7 +431,7 @@ register_and_crash1(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -427,22 +441,22 @@ register_and_crash1(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id),
?line [Id] = Users2 = which_users(),
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid),
?line [Id] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -454,7 +468,7 @@ register_and_crash2(doc) ->
"register 2 users (per that process) and crash the process.";
register_and_crash2(Conf) when is_list(Conf) ->
put(tname,racau2),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -467,7 +481,7 @@ register_and_crash2(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -478,7 +492,7 @@ register_and_crash2(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id1),
?line ok = register_user(Pid, Id2),
@@ -491,7 +505,7 @@ register_and_crash2(Conf) when is_list(Conf) ->
Else1 ->
?FAIL({invalid_users, Else1})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid),
@@ -503,12 +517,12 @@ register_and_crash2(Conf) when is_list(Conf) ->
Else2 ->
?FAIL({invalid_users, Else2})
end,
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -521,7 +535,7 @@ register_and_crash3(doc) ->
"crash the first user process.";
register_and_crash3(Conf) when is_list(Conf) ->
%% put(tname,rac3),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -534,7 +548,7 @@ register_request_and_crash1(doc) ->
"register user, send request and crash user.";
register_request_and_crash1(Conf) when is_list(Conf) ->
%% put(tname,rrac1),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -548,7 +562,7 @@ register_request_and_crash2(doc) ->
"send a request for each user and crash the single user process.";
register_request_and_crash2(Conf) when is_list(Conf) ->
%% put(tname,rrac2),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -562,7 +576,7 @@ register_request_and_crash3(doc) ->
"send a request for each user and crash the first user process.";
register_request_and_crash3(Conf) when is_list(Conf) ->
%% put(tname,rrac3),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -574,7 +588,7 @@ simple_register_monitor_and_unregister1(doc) ->
"Start a user, register-link and unregister the user.";
simple_register_monitor_and_unregister1(Conf) when is_list(Conf) ->
put(tname,srlau1),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -587,41 +601,41 @@ simple_register_monitor_and_unregister1(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
Id = make_ref(),
- p("start user"),
+ ?IPRINT("start user"),
?line Pid = start_user(),
- p("get users (=0)"),
+ ?IPRINT("get users (=0)"),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
- p("register monitored user"),
+ ?IPRINT("register monitored user"),
?line ok = register_user_monitor(Pid, Id),
- p("get users (=1)"),
+ ?IPRINT("get users (=1)"),
?line [Id] = Users2 = which_users(),
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
- p("unregister monitored user"),
+ ?IPRINT("unregister monitored user"),
?line unregister_user(Pid),
- p("get users (=0)"),
+ ?IPRINT("get users (=0)"),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("start user"),
+ ?IPRINT("start user"),
?line stop_user(Pid),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -634,7 +648,7 @@ simple_register_monitor_and_unregister2(doc) ->
"unregister the 2 users.";
simple_register_monitor_and_unregister2(Conf) when is_list(Conf) ->
put(tname,srlau2),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -647,7 +661,7 @@ simple_register_monitor_and_unregister2(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -658,7 +672,7 @@ simple_register_monitor_and_unregister2(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user_monitor(Pid, Id1),
?line ok = register_user_monitor(Pid, Id2),
@@ -671,19 +685,19 @@ simple_register_monitor_and_unregister2(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = unregister_user(Pid, Id1),
?line ok = unregister_user(Pid, Id2),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -697,7 +711,7 @@ simple_register_monitor_and_unregister3(doc) ->
"unregister the 2 users.";
simple_register_monitor_and_unregister3(Conf) when is_list(Conf) ->
put(tname,srlau3),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -710,7 +724,7 @@ simple_register_monitor_and_unregister3(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -721,7 +735,7 @@ simple_register_monitor_and_unregister3(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id1),
?line ok = register_user_monitor(Pid, Id2),
@@ -734,18 +748,18 @@ simple_register_monitor_and_unregister3(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line unregister_user(Pid),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -756,7 +770,7 @@ register_monitor_and_crash1(doc) ->
"Start a user, register-monitor and crash the user.";
register_monitor_and_crash1(Conf) when is_list(Conf) ->
put(tname,rlac1),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -769,7 +783,7 @@ register_monitor_and_crash1(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -779,24 +793,24 @@ register_monitor_and_crash1(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user_monitor(Pid, Id),
?line [Id] = Users2 = which_users(),
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid),
?SLEEP(1000),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -809,7 +823,7 @@ register_monitor_and_crash2(doc) ->
"and crash the single user process.";
register_monitor_and_crash2(Conf) when is_list(Conf) ->
put(tname,rlac2),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -822,7 +836,7 @@ register_monitor_and_crash2(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -833,7 +847,7 @@ register_monitor_and_crash2(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user_monitor(Pid, Id1),
?line ok = register_user_monitor(Pid, Id2),
@@ -846,19 +860,19 @@ register_monitor_and_crash2(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid),
?SLEEP(1000),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -901,7 +915,7 @@ register_monitor_and_crash3(Conf) when is_list(Conf) ->
?NON_PC_TC_MAYBE_SKIP(Conf, Condition),
%% </CONDITIONAL-SKIP>
- p("start"),
+ ?IPRINT("start"),
ConfDir = ?config(manager_conf_dir, Conf),
DbDir = ?config(manager_db_dir, Conf),
@@ -913,7 +927,7 @@ register_monitor_and_crash3(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -924,7 +938,7 @@ register_monitor_and_crash3(Conf) when is_list(Conf) ->
?line Pid = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user(Pid, Id1),
?line ok = register_user_monitor(Pid, Id2),
@@ -937,19 +951,19 @@ register_monitor_and_crash3(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid),
?SLEEP(1000),
?line [Id1] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -962,7 +976,7 @@ register_monitor_and_crash4(doc) ->
"and crash the first user process.";
register_monitor_and_crash4(Conf) when is_list(Conf) ->
put(tname,rlac4),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -975,7 +989,7 @@ register_monitor_and_crash4(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start manager"),
+ ?IPRINT("start manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -983,12 +997,12 @@ register_monitor_and_crash4(Conf) when is_list(Conf) ->
Id1 = make_ref(),
Id2 = make_ref(),
- p("start user processes"),
+ ?IPRINT("start user processes"),
?line Pid1 = start_user(),
?line Pid2 = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user_monitor(Pid1, Id1),
?line ok = register_user_monitor(Pid2, Id2),
@@ -1001,21 +1015,21 @@ register_monitor_and_crash4(Conf) when is_list(Conf) ->
Else ->
?FAIL({invalid_users, Else})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = simulate_crash(Pid1),
?SLEEP(1000),
?line [Id2] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line stop_user(Pid2),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -1030,7 +1044,7 @@ register_monitor_and_crash5(doc) ->
"and crash the first user process.";
register_monitor_and_crash5(Conf) when is_list(Conf) ->
put(tname,rlac4),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -1043,7 +1057,7 @@ register_monitor_and_crash5(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("start manager"),
+ ?IPRINT("start manager"),
?line ok = snmpm:start_link(Opts),
?SLEEP(1000),
@@ -1051,12 +1065,12 @@ register_monitor_and_crash5(Conf) when is_list(Conf) ->
Id1 = gurka, %% make_ref(),
Id2 = tomat, %% make_ref(),
- p("start user processes"),
+ ?IPRINT("start user processes"),
?line Pid1 = start_user(),
?line Pid2 = start_user(),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = register_user_monitor(Pid1, Id1),
?line ok = register_user_monitor(Pid2, Id2),
@@ -1090,9 +1104,9 @@ register_monitor_and_crash5(Conf) when is_list(Conf) ->
U3 ->
?FAIL({invalid_users, U3})
end,
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
- p("verify all agent(s): expect 2"),
+ ?IPRINT("verify all agent(s): expect 2"),
?line Agents1 = case which_agents() of
[TargetName1, TargetName2] = A1 ->
A1;
@@ -1101,25 +1115,25 @@ register_monitor_and_crash5(Conf) when is_list(Conf) ->
A3 ->
?FAIL({invalid_agents, A3})
end,
- p("Agents1: ~p", [Agents1]),
+ ?IPRINT("Agents1: ~p", [Agents1]),
?line ok = simulate_crash(Pid1),
- p("wait some time"),
+ ?IPRINT("wait some time"),
?SLEEP(1000),
?line [Id2] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line [TargetName2] = Agents2 = which_agents(),
- p("Agents2: ~p", [Agents2]),
+ ?IPRINT("Agents2: ~p", [Agents2]),
?line stop_user(Pid2),
- p("stop manager"),
+ ?IPRINT("stop manager"),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -1132,7 +1146,7 @@ register_monitor_request_and_crash1(doc) ->
"send request and crash the user.";
register_monitor_request_and_crash1(Conf) when is_list(Conf) ->
%% put(tname,rlrac1),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -1146,7 +1160,7 @@ register_monitor_request_and_crash2(doc) ->
"send a request for each user and crash the single user process.";
register_monitor_request_and_crash2(Conf) when is_list(Conf) ->
%% put(tname,rlrac2),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -1160,7 +1174,7 @@ register_monitor_request_and_crash3(doc) ->
"send a request for each user and crash the single user process.";
register_monitor_request_and_crash3(Conf) when is_list(Conf) ->
%% put(tname,rlrac3),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -1176,7 +1190,7 @@ register_monitor_request_and_crash4(doc) ->
"crash the first user process.";
register_monitor_request_and_crash4(Conf) when is_list(Conf) ->
%% put(tname,rlrac4),
- %% p("start"),
+ %% ?IPRINT("start"),
%% process_flag(trap_exit, true),
?SKIP(not_yet_implemented).
@@ -1189,7 +1203,7 @@ otp7902(doc) ->
"OTP-7902 - Start old user and make sure it wors.";
otp7902(Conf) when is_list(Conf) ->
put(tname, otp7902),
- p("start"),
+ ?IPRINT("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
@@ -1202,27 +1216,27 @@ otp7902(Conf) when is_list(Conf) ->
{note_store, [{verbosity, trace}]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
- p("try starting manager"),
+ ?IPRINT("try starting manager"),
ok = snmpm:start_link(Opts),
?SLEEP(1000),
?line [] = Users1 = which_users(),
- p("Users1: ~p", [Users1]),
+ ?IPRINT("Users1: ~p", [Users1]),
?line ok = snmp_manager_user_old:start(),
?line [_] = Users2 = which_users(),
- p("Users2: ~p", [Users2]),
+ ?IPRINT("Users2: ~p", [Users2]),
?line ok = snmp_manager_user_old:stop(),
?line [] = Users3 = which_users(),
- p("Users3: ~p", [Users3]),
+ ?IPRINT("Users3: ~p", [Users3]),
?line ok = snmpm:stop(),
- p("end"),
+ ?IPRINT("end"),
ok.
@@ -1306,15 +1320,3 @@ write_conf_file(Dir, File, Str) ->
?line ok = io:format(Fd, "~s", [Str]),
file:close(Fd).
-
-%% ------
-
-p(F) ->
- p(F, []).
-
-p(F, A) ->
- p(get(tname), F, A).
-
-p(TName, F, A) ->
- io:format("~w -> " ++ F ++ "~n", [TName|A]).
-
diff --git a/lib/snmp/test/snmp_note_store_SUITE.erl b/lib/snmp/test/snmp_note_store_SUITE.erl
index 832c03029e..3b6d9f9fcd 100644
--- a/lib/snmp/test/snmp_note_store_SUITE.erl
+++ b/lib/snmp/test/snmp_note_store_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2020. 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.
@@ -81,11 +81,34 @@ groups() ->
%% -----
%%
-init_per_suite(Config) when is_list(Config) ->
- Config.
+init_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config: ~p", [Config0]),
-end_per_suite(Config) when is_list(Config) ->
- Config.
+ case ?LIB:init_per_suite(Config0) of
+ {skip, _} = SKIP ->
+ SKIP;
+
+ Config1 when is_list(Config1) ->
+ %% We need a monitor on this node also
+ snmp_test_sys_monitor:start(),
+
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config1: ~p", [Config1]),
+
+ Config1
+ end.
+
+end_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config: ~p", [Config0]),
+
+ snmp_test_sys_monitor:stop(),
+ Config1 = ?LIB:end_per_suite(Config0),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
@@ -106,9 +129,24 @@ end_per_group(_GroupName, Config) ->
%%
init_per_testcase(_Case, Config) when is_list(Config) ->
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
+
+ snmp_test_global_sys_monitor:reset_events(),
+
+ ?IPRINT("init_per_testcase -> end"),
+
Config.
end_per_testcase(_Case, Config) when is_list(Config) ->
+
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p",
+ [Config]),
+
+ ?IPRINT("system events during test: ~p",
+ [snmp_test_global_sys_monitor:events()]),
+
Config.
@@ -143,42 +181,55 @@ notes(doc) ->
["Testing that it does what it is actually supposed to do, "
"namilly to handle notes. "];
notes(Config) when is_list(Config) ->
-
- {ok, Handler, Pid} = note_store_handler_start(),
-
- io:format("sleep some before we begin the tests~n", []),
- ?SLEEP(timer:seconds(1)),
+ Pre = fun() ->
+ ?IPRINT("try start note-store"),
+ case note_store_handler_start() of
+ {ok, Handler, Pid} ->
+ ?IPRINT("started - sleep some before we begin the tests"),
+ ?SLEEP(?SECS(1)),
+ {Handler, Pid};
+ {error, Reason} ->
+ {skip, ?F("Failed starting note-store: ~p", [Reason])}
+ end
+ end,
+ Case = fun(State) -> do_notes(State, Config) end,
+ Post = fun({Handler, _Pid}) ->
+ note_store_handler_stop(Handler)
+ end,
+ ?TC_TRY(notes, Pre, Case, Post).
+
+do_notes({_, Pid}, _Config) ->
%% Default lifetime is infinity. A note with lifetime
%% infinity is permanent
- io:format("create permanent note sune~n", []),
+ ?IPRINT("create permanent note: sune"),
true = snmp_note_store:set_note(Pid, sune, 10),
10 = snmp_note_store:get_note(Pid, sune),
10 = snmp_note_store:get_note(Pid, sune),
%% Lifetime is in 1/100 sec ticks, so 500 equals 5 seconds
- io:format("create 5 sec note kalle~n", []),
+ ?IPRINT("create 5 sec note kalle"),
true = snmp_note_store:set_note(Pid, 500, kalle, hobbe),
- io:format("wait 1 sec~n", []),
+ ?IPRINT("wait 1 sec"),
?SLEEP(timer:seconds(1)),
- io:format("get note kalle~n", []),
+ ?IPRINT("get note kalle"),
hobbe = snmp_note_store:get_note(Pid, kalle),
- io:format("wait 5 sec~n", []),
+ ?IPRINT("wait 5 sec"),
?SLEEP(timer:seconds(5)),
- io:format("get note kalle again (now it should not exist)~n", []),
+ ?IPRINT("get note kalle again (now it should not exist)"),
undefined = snmp_note_store:get_note(Pid, kalle),
- io:format("create 5 sec note kalle~n", []),
+ ?IPRINT("create 5 sec note kalle"),
true = snmp_note_store:set_note(Pid, 500, kalle, hobbe),
- io:format("wait 6 sec (to allow timer to clean up note)~n", []),
+ ?IPRINT("wait 6 sec (to allow timer to clean up note)"),
?SLEEP(timer:seconds(6)),
- io:format("get note kalle - should not exist~n", []),
+ ?IPRINT("get note kalle - should not exist"),
undefined = snmp_note_store:get_note(Pid, kalle),
- io:format("read the permanent note sune again~n", []),
+ ?IPRINT("read the permanent note sune again"),
10 = snmp_note_store:get_note(Pid, sune),
- note_store_handler_stop(Handler),
+ ?IPRINT("done"),
ok.
@@ -190,47 +241,65 @@ info(suite) ->
info(doc) ->
["Testing that we can retreive process info."];
info(Config) when is_list(Config) ->
-
- Prio = normal,
- Mod = ?MODULE,
- Opts = [{verbosity, trace}],
- {ok, Pid} = snmp_note_store:start_link(Prio, Mod, Opts),
+ Pre = fun() ->
+ ?IPRINT("try start note-store"),
+ Prio = normal,
+ Mod = ?MODULE,
+ Opts = [{verbosity, trace}],
+ case snmp_note_store:start_link(Prio, Mod, Opts) of
+ {ok, Pid} ->
+ ?IPRINT("note-store started: ~p", [Pid]),
+ Pid;
+ {error, Reason} ->
+ {skip, ?F("Failed starting note-store: ~p", [Reason])}
+ end
+ end,
+ Case = fun(State) -> do_info(State, Config) end,
+ Post = fun(Pid) ->
+ ?IPRINT("attempt stop note-store"),
+ snmp_note_store:stop(Pid)
+ end,
+ ?TC_TRY(info, Pre, Case, Post).
+
+do_info(Pid, _Config) ->
%% Get the info:
+ ?IPRINT("get initial info"),
Info = snmp_note_store:info(Pid),
- io:format("Info: ~p~n", [Info]),
+ ?IPRINT("Info: "
+ "~n ~p", [Info]),
%% Verify content
- io:format("get process memory~n", []),
+ ?IPRINT("verify content: get notes process memory"),
{value, {process_memory, ProcMem}} =
lists:keysearch(process_memory, 1, Info),
- io:format("get notes process memory~n", []),
+ ?IPRINT("get notes process memory"),
{value, {notes, NotesProcMem}} =
lists:keysearch(notes, 1, ProcMem),
- io:format("verify notes process memory~n", []),
+ ?IPRINT("verify notes process memory"),
if
is_integer(NotesProcMem) andalso (NotesProcMem > 0) ->
ok;
true ->
throw({error, {bad_notes_proc_memery, NotesProcMem}})
end,
- io:format("get timer process memory~n", []),
+ ?IPRINT("verify content: get timer process memory"),
{value, {timer, TmrProcMem}} =
lists:keysearch(timer, 1, ProcMem),
- io:format("verify timer process memory~n", []),
+ ?IPRINT("verify content: timer process memory"),
if
is_integer(TmrProcMem) andalso (TmrProcMem > 0) ->
ok;
true ->
throw({error, {bad_timer_proc_memery, TmrProcMem}})
end,
- io:format("get db memory~n", []),
+ ?IPRINT("verify content: get db memory"),
{value, {db_memory, DbMem}} =
lists:keysearch(db_memory, 1, Info),
- io:format("get notes db memory~n", []),
+ ?IPRINT("verify content: get notes db memory"),
{value, {notes, NotesDbMem}} =
lists:keysearch(notes, 1, DbMem),
- io:format("verify notes db memory~n", []),
+ ?IPRINT("verify content: notes db memory"),
if
is_integer(NotesDbMem) andalso (NotesDbMem > 0) ->
ok;
@@ -238,9 +307,7 @@ info(Config) when is_list(Config) ->
throw({error, {bad_notes_db_memery, NotesDbMem}})
end,
-
- snmp_note_store:stop(Pid),
-
+ ?IPRINT("done"),
ok.
@@ -251,23 +318,38 @@ garbage_in(suite) ->
garbage_in(doc) ->
["Test that the process handles garbage sent to it."];
garbage_in(Config) when is_list(Config) ->
-
- io:format("start note_store server~n", []),
- Prio = normal,
- Mod = ?MODULE,
- Opts = [{verbosity, trace}],
- {ok, Pid} = snmp_note_store:start_link(Prio, Mod, Opts),
-
- io:format("issue bad request~n", []),
+ Pre = fun() ->
+ ?IPRINT("try start note-store"),
+ Prio = normal,
+ Mod = ?MODULE,
+ Opts = [{verbosity, trace}],
+ case snmp_note_store:start_link(Prio, Mod, Opts) of
+ {ok, Pid} ->
+ ?IPRINT("note-store started: ~p", [Pid]),
+ Pid;
+ {error, Reason} ->
+ {skip, ?F("Failed starting note-store: ~p", [Reason])}
+ end
+ end,
+ Case = fun(State) -> do_garbage_in(State, Config) end,
+ Post = fun(Pid) ->
+ ?IPRINT("attempt stop note-store"),
+ snmp_note_store:stop(Pid)
+ end,
+ ?TC_TRY(garbage_in, Pre, Case, Post).
+
+do_garbage_in(Pid, _Config) ->
+
+ ?IPRINT("issue bad request"),
{error, _} = gen_server:call(Pid, bad_request),
- io:format("cast bad message~n", []),
+ ?IPRINT("cast bad message"),
gen_server:cast(Pid, bad_message),
- io:format("bang bad info~n", []),
+ ?IPRINT("bang bad info"),
Pid ! bad_info,
- io:format("verify note_Store server still alive and kicking~n", []),
+ ?IPRINT("verify note-store server still alive and kicking"),
Info = snmp_note_store:info(Pid),
if
is_list(Info) andalso (length(Info) > 0) ->
@@ -276,10 +358,7 @@ garbage_in(Config) when is_list(Config) ->
throw({error, {bad_info, Info}})
end,
- io:format("stop note_store server~n", []),
- snmp_note_store:stop(Pid),
-
- io:format("done~n", []),
+ ?IPRINT("done"),
ok.
diff --git a/lib/snmp/test/snmp_pdus_SUITE.erl b/lib/snmp/test/snmp_pdus_SUITE.erl
index f49e2eb602..d70e7aebd0 100644
--- a/lib/snmp/test/snmp_pdus_SUITE.erl
+++ b/lib/snmp/test/snmp_pdus_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2020. 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.
@@ -75,11 +75,34 @@ tickets_cases() ->
%% -----
%%
-init_per_suite(Config) when is_list(Config) ->
- Config.
+init_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config: ~p", [Config0]),
-end_per_suite(Config) when is_list(Config) ->
- Config.
+ case ?LIB:init_per_suite(Config0) of
+ {skip, _} = SKIP ->
+ SKIP;
+
+ Config1 when is_list(Config1) ->
+ %% We need a monitor on this node also
+ snmp_test_sys_monitor:start(),
+
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config1: ~p", [Config1]),
+
+ Config1
+ end.
+
+end_per_suite(Config0) when is_list(Config0) ->
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config: ~p", [Config0]),
+
+ snmp_test_sys_monitor:stop(),
+ Config1 = ?LIB:end_per_suite(Config0),
+
+ ?IPRINT("end_per_suite -> end"),
+
+ Config1.
@@ -100,9 +123,24 @@ end_per_group(_GroupName, Config) ->
%%
init_per_testcase(_Case, Config) when is_list(Config) ->
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
+
+ snmp_test_global_sys_monitor:reset_events(),
+
+ ?IPRINT("init_per_testcase -> end"),
+
Config.
end_per_testcase(_Case, Config) when is_list(Config) ->
+
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p",
+ [Config]),
+
+ ?IPRINT("system events during test: ~p",
+ [snmp_test_global_sys_monitor:events()]),
+
Config.
@@ -114,7 +152,7 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
otp7575(suite) -> [];
otp7575(doc) -> ["OTP-7575 - Message version"];
otp7575(Config) when is_list(Config) ->
- io:format("attempt to decode message with valid version~n", []),
+ ?IPRINT("attempt to decode message with valid version"),
MsgWithOkVersion = <<48,39,2,1,0,4,6,112,117,98,108,105,99,160,26,2,2,1,49,2,1,0,2,1,0,48,14,48,12,6,8,43,6,1,2,1,1,5,0,5,0>>,
case (catch dec_message(MsgWithOkVersion)) of
Msg when is_record(Msg, message) ->
@@ -123,7 +161,7 @@ otp7575(Config) when is_list(Config) ->
exit({unexpected_decode_result, 1, Unexpected1})
end,
- io:format("attempt to decode message with bad version~n", []),
+ ?IPRINT("attempt to decode message with bad version"),
MsgWithBadVersion = <<48,48,2,10,1,1,1,1,1,1,1,1,1,1,4,6,112,117,98,108,105,99,160,26,2,2,1,49,2,1,0,2,1,0,48,14,48,12,6,8,43,6,1,2,1,1,5,0,5,0>>,
case (catch dec_message(MsgWithBadVersion)) of
{'EXIT', {bad_version, BadVersion}} when is_integer(BadVersion) ->
@@ -132,7 +170,7 @@ otp7575(Config) when is_list(Config) ->
exit({unexpected_decode_result, 2, Unexpected2})
end,
- io:format("attempt to decode message with very bad version~n", []),
+ ?IPRINT("attempt to decode message with very bad version"),
MsgWithVeryBadVersion = <<48,49,2,11,1,1,1,1,1,1,1,1,1,1,1,4,6,112,117,98,108,105,99,160,26,2,2,1,49,2,1,0,2,1,0,48,14,48,12,6,8,43,6,1,2,1,1,5,0,5,0>>,
case (catch dec_message(MsgWithVeryBadVersion)) of
{'EXIT', {bad_version, {VersionSize, MaxVersionSize}}} when (VersionSize > MaxVersionSize) ->
@@ -140,7 +178,7 @@ otp7575(Config) when is_list(Config) ->
Unexpected3 ->
exit({unexpected_decode_result, 3, Unexpected3})
end,
- io:format("done~n", []),
+ ?IPRINT("done"),
ok.
@@ -148,52 +186,52 @@ otp8563(suite) -> [];
otp8563(doc) -> ["OTP-8563 - Counter64"];
otp8563(Config) when is_list(Config) ->
Val1 = 16#7fffffffffffffff,
- io:format("try encode and decode value 1: ~w (0x~.16b)~n", [Val1, Val1]),
+ ?IPRINT("try encode and decode value 1: ~w (0x~.16b)", [Val1, Val1]),
Enc1 = snmp_pdus:enc_value('Counter64', Val1),
- io:format(" => ~w~n", [Enc1]),
+ ?IPRINT(" => ~w", [Enc1]),
{{'Counter64', Val1}, []} = snmp_pdus:dec_value(Enc1),
Val2 = Val1 + 1,
- io:format("try encode and decode value 2: ~w (0x~.16b)~n", [Val2, Val2]),
+ ?IPRINT("try encode and decode value 2: ~w (0x~.16b)", [Val2, Val2]),
Enc2 = snmp_pdus:enc_value('Counter64', Val2),
- io:format(" => ~w~n", [Enc2]),
+ ?IPRINT(" => ~w", [Enc2]),
{{'Counter64', Val2}, []} = snmp_pdus:dec_value(Enc2),
Val3 = Val2 + 1,
- io:format("try encode and decode value 3: ~w (0x~.16b)~n", [Val3, Val3]),
+ ?IPRINT("try encode and decode value 3: ~w (0x~.16b)", [Val3, Val3]),
Enc3 = snmp_pdus:enc_value('Counter64', Val3),
- io:format(" => ~w~n", [Enc3]),
+ ?IPRINT(" => ~w", [Enc3]),
{{'Counter64', Val3}, []} = snmp_pdus:dec_value(Enc3),
Val4 = 16#fffffffffffffffe,
- io:format("try encode and decode value 4: ~w (0x~.16b)~n", [Val4, Val4]),
+ ?IPRINT("try encode and decode value 4: ~w (0x~.16b)", [Val4, Val4]),
Enc4 = snmp_pdus:enc_value('Counter64', Val4),
- io:format(" => ~w~n", [Enc4]),
+ ?IPRINT(" => ~w", [Enc4]),
{{'Counter64', Val4}, []} = snmp_pdus:dec_value(Enc4),
Val5 = Val4 + 1,
- io:format("try encode and decode value 5: ~w (0x~.16b)~n", [Val5, Val5]),
+ ?IPRINT("try encode and decode value 5: ~w (0x~.16b)", [Val5, Val5]),
Enc5 = snmp_pdus:enc_value('Counter64', Val5),
- io:format(" => ~w~n", [Enc5]),
+ ?IPRINT(" => ~w", [Enc5]),
{{'Counter64', Val5}, []} = snmp_pdus:dec_value(Enc5),
Val6 = 16#ffffffffffffffff + 1,
- io:format("try and fail to encode value 6: ~w (0x~.16b)~n", [Val6, Val6]),
+ ?IPRINT("try and fail to encode value 6: ~w (0x~.16b)", [Val6, Val6]),
case (catch snmp_pdus:enc_value('Counter64', Val6)) of
{'EXIT', {error, {bad_counter64, Val6}}} ->
ok;
Unexpected6 ->
- io:format(" => ~w~n", [Unexpected6]),
+ ?IPRINT(" => ~w", [Unexpected6]),
exit({unexpected_encode_result, Unexpected6, Val6})
end,
Val7 = -1,
- io:format("try and fail to encode value 7: ~w~n", [Val7]),
+ ?IPRINT("try and fail to encode value 7: ~w", [Val7]),
case (catch snmp_pdus:enc_value('Counter64', Val7)) of
{'EXIT', {error, {bad_counter64, Val7}}} ->
ok;
Unexpected7 ->
- io:format(" => ~w~n", [Unexpected7]),
+ ?IPRINT(" => ~w", [Unexpected7]),
exit({unexpected_encode_result, Unexpected7, Val7})
end,
@@ -204,70 +242,70 @@ otp9022(suite) -> [];
otp9022(doc) -> ["OTP-9022 - Counter32"];
otp9022(Config) when is_list(Config) ->
Val0 = 2908389204,
- io:format("try encode and decode value 0: ~w (0x~.16b)~n", [Val0, Val0]),
+ ?IPRINT("try encode and decode value 0: ~w (0x~.16b)", [Val0, Val0]),
Enc0 = snmp_pdus:enc_value('Counter32', Val0),
- io:format(" => ~w~n", [Enc0]),
+ ?IPRINT(" => ~w", [Enc0]),
{{'Counter32', Val0}, []} = snmp_pdus:dec_value(Enc0),
Val1 = 0,
- io:format("try encode and decode value 1: ~w (0x~.16b)~n", [Val1, Val1]),
+ ?IPRINT("try encode and decode value 1: ~w (0x~.16b)", [Val1, Val1]),
Enc1 = snmp_pdus:enc_value('Counter32', Val1),
- io:format(" => ~w~n", [Enc1]),
+ ?IPRINT(" => ~w", [Enc1]),
{{'Counter32', Val1}, []} = snmp_pdus:dec_value(Enc1),
Val2 = Val1 + 1,
- io:format("try encode and decode value 2: ~w (0x~.16b)~n", [Val2, Val2]),
+ ?IPRINT("try encode and decode value 2: ~w (0x~.16b)", [Val2, Val2]),
Enc2 = snmp_pdus:enc_value('Counter32', Val2),
- io:format(" => ~w~n", [Enc2]),
+ ?IPRINT(" => ~w", [Enc2]),
{{'Counter32', Val2}, []} = snmp_pdus:dec_value(Enc2),
Val3 = 16#7ffffffe,
- io:format("try encode and decode value 3: ~w (0x~.16b)~n", [Val3, Val3]),
+ ?IPRINT("try encode and decode value 3: ~w (0x~.16b)", [Val3, Val3]),
Enc3 = snmp_pdus:enc_value('Counter32', Val3),
- io:format(" => ~w~n", [Enc3]),
+ ?IPRINT(" => ~w", [Enc3]),
{{'Counter32', Val3}, []} = snmp_pdus:dec_value(Enc3),
Val4 = Val3 + 1,
- io:format("try encode and decode value 4: ~w (0x~.16b)~n", [Val4, Val4]),
+ ?IPRINT("try encode and decode value 4: ~w (0x~.16b)", [Val4, Val4]),
Enc4 = snmp_pdus:enc_value('Counter32', Val4),
- io:format(" => ~w~n", [Enc4]),
+ ?IPRINT(" => ~w", [Enc4]),
{{'Counter32', Val4}, []} = snmp_pdus:dec_value(Enc4),
Val5 = Val4 + 1,
- io:format("try encode and decode value 5: ~w (0x~.16b)~n", [Val5, Val5]),
+ ?IPRINT("try encode and decode value 5: ~w (0x~.16b)", [Val5, Val5]),
Enc5 = snmp_pdus:enc_value('Counter32', Val5),
- io:format(" => ~w~n", [Enc5]),
+ ?IPRINT(" => ~w", [Enc5]),
{{'Counter32', Val5}, []} = snmp_pdus:dec_value(Enc5),
Val6 = 16#fffffffe,
- io:format("try encode and decode value 6: ~w (0x~.16b)~n", [Val6, Val6]),
+ ?IPRINT("try encode and decode value 6: ~w (0x~.16b)", [Val6, Val6]),
Enc6 = snmp_pdus:enc_value('Counter32', Val6),
- io:format(" => ~w~n", [Enc6]),
+ ?IPRINT(" => ~w", [Enc6]),
{{'Counter32', Val6}, []} = snmp_pdus:dec_value(Enc6),
Val7 = Val6 + 1,
- io:format("try encode and decode value 7: ~w (0x~.16b)~n", [Val7, Val7]),
+ ?IPRINT("try encode and decode value 7: ~w (0x~.16b)", [Val7, Val7]),
Enc7 = snmp_pdus:enc_value('Counter32', Val7),
- io:format(" => ~w~n", [Enc7]),
+ ?IPRINT(" => ~w", [Enc7]),
{{'Counter32', Val7}, []} = snmp_pdus:dec_value(Enc7),
Val8 = 16#ffffffff + 1,
- io:format("try and fail to encode value 8: ~w (0x~.16b)~n", [Val8, Val8]),
+ ?IPRINT("try and fail to encode value 8: ~w (0x~.16b)", [Val8, Val8]),
case (catch snmp_pdus:enc_value('Counter32', Val8)) of
{'EXIT', {error, {bad_counter32, Val8}}} ->
ok;
Unexpected8 ->
- io:format(" => ~w~n", [Unexpected8]),
+ ?IPRINT(" => ~w", [Unexpected8]),
exit({unexpected_encode_result, Unexpected8, Val8})
end,
Val9 = -1,
- io:format("try and fail to encode value 9: ~w~n", [Val9]),
+ ?IPRINT("try and fail to encode value 9: ~w", [Val9]),
case (catch snmp_pdus:enc_value('Counter32', Val9)) of
{'EXIT', {error, {bad_counter32, Val9}}} ->
ok;
Unexpected9 ->
- io:format(" => ~w~n", [Unexpected9]),
+ ?IPRINT(" => ~w", [Unexpected9]),
exit({unexpected_encode_result, Unexpected9, Val9})
end,
@@ -278,74 +316,74 @@ otp10132(suite) -> [];
otp10132(doc) -> ["OTP-10132 - TimeTicks"];
otp10132(Config) when is_list(Config) ->
Val0 = 2159001034,
- io:format("try encode and decode value 0: ~w (0x~.16b)~n", [Val0, Val0]),
+ ?IPRINT("try encode and decode value 0: ~w (0x~.16b)", [Val0, Val0]),
Enc0 = snmp_pdus:enc_value('TimeTicks', Val0),
- io:format(" => ~w~n", [Enc0]),
+ ?IPRINT(" => ~w", [Enc0]),
{{'TimeTicks', Val0}, []} = snmp_pdus:dec_value(Enc0),
Val1 = 0,
- io:format("try encode and decode value 1: ~w (0x~.16b)~n", [Val1, Val1]),
+ ?IPRINT("try encode and decode value 1: ~w (0x~.16b)", [Val1, Val1]),
Enc1 = snmp_pdus:enc_value('TimeTicks', Val1),
- io:format(" => ~w~n", [Enc1]),
+ ?IPRINT(" => ~w", [Enc1]),
{{'TimeTicks', Val1}, []} = snmp_pdus:dec_value(Enc1),
Val2 = Val1 + 1,
- io:format("try encode and decode value 2: ~w (0x~.16b)~n", [Val2, Val2]),
+ ?IPRINT("try encode and decode value 2: ~w (0x~.16b)", [Val2, Val2]),
Enc2 = snmp_pdus:enc_value('TimeTicks', Val2),
- io:format(" => ~w~n", [Enc2]),
+ ?IPRINT(" => ~w", [Enc2]),
{{'TimeTicks', Val2}, []} = snmp_pdus:dec_value(Enc2),
Val3 = 16#7ffffffe,
- io:format("try encode and decode value 3: ~w (0x~.16b)~n", [Val3, Val3]),
+ ?IPRINT("try encode and decode value 3: ~w (0x~.16b)", [Val3, Val3]),
Enc3 = snmp_pdus:enc_value('TimeTicks', Val3),
- io:format(" => ~w~n", [Enc3]),
+ ?IPRINT(" => ~w", [Enc3]),
{{'TimeTicks', Val3}, []} = snmp_pdus:dec_value(Enc3),
Val4 = Val3 + 1,
- io:format("try encode and decode value 4: ~w (0x~.16b)~n", [Val4, Val4]),
+ ?IPRINT("try encode and decode value 4: ~w (0x~.16b)", [Val4, Val4]),
Enc4 = snmp_pdus:enc_value('TimeTicks', Val4),
- io:format(" => ~w~n", [Enc4]),
+ ?IPRINT(" => ~w", [Enc4]),
{{'TimeTicks', Val4}, []} = snmp_pdus:dec_value(Enc4),
Val5 = Val4 + 1,
- io:format("try encode and decode value 5: ~w (0x~.16b)~n", [Val5, Val5]),
+ ?IPRINT("try encode and decode value 5: ~w (0x~.16b)", [Val5, Val5]),
Enc5 = snmp_pdus:enc_value('TimeTicks', Val5),
- io:format(" => ~w~n", [Enc5]),
+ ?IPRINT(" => ~w", [Enc5]),
{{'TimeTicks', Val5}, []} = snmp_pdus:dec_value(Enc5),
Val6 = 16#fffffffe,
- io:format("try encode and decode value 6: ~w (0x~.16b)~n", [Val6, Val6]),
+ ?IPRINT("try encode and decode value 6: ~w (0x~.16b)", [Val6, Val6]),
Enc6 = snmp_pdus:enc_value('TimeTicks', Val6),
- io:format(" => ~w~n", [Enc6]),
+ ?IPRINT(" => ~w", [Enc6]),
{{'TimeTicks', Val6}, []} = snmp_pdus:dec_value(Enc6),
Val7 = Val6 + 1,
- io:format("try encode and decode value 7: ~w (0x~.16b)~n", [Val7, Val7]),
+ ?IPRINT("try encode and decode value 7: ~w (0x~.16b)", [Val7, Val7]),
Enc7 = snmp_pdus:enc_value('TimeTicks', Val7),
- io:format(" => ~w~n", [Enc7]),
+ ?IPRINT(" => ~w", [Enc7]),
{{'TimeTicks', Val7}, []} = snmp_pdus:dec_value(Enc7),
Val8 = Val7 + 1,
- io:format("try and fail to encode value 8: ~w (0x~.16b)~n", [Val8, Val8]),
+ ?IPRINT("try and fail to encode value 8: ~w (0x~.16b)", [Val8, Val8]),
case (catch snmp_pdus:enc_value('TimeTicks', Val8)) of
{'EXIT', {error, {bad_timeticks, Val8}}} ->
ok;
Unexpected8 ->
- io:format(" => ~w~n", [Unexpected8]),
+ ?IPRINT(" => ~w", [Unexpected8]),
exit({unexpected_encode_result, Unexpected8, Val8})
end,
Val9 = -1,
- io:format("try and fail to encode value 9: ~w~n", [Val9]),
+ ?IPRINT("try and fail to encode value 9: ~w", [Val9]),
case (catch snmp_pdus:enc_value('TimeTicks', Val9)) of
{'EXIT', {error, {bad_timeticks, Val9}}} ->
ok;
Unexpected9 ->
- io:format(" => ~w~n", [Unexpected9]),
+ ?IPRINT(" => ~w", [Unexpected9]),
exit({unexpected_encode_result, Unexpected9, Val9})
end,
- io:format("done~n", []),
+ ?IPRINT("done"),
ok.
diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl
index e8bcfa8a0e..3e445174ba 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -42,12 +42,14 @@
-export([ping/1, local_nodes/0, nodes_on/1]).
-export([start_node/2, stop_node/1]).
-export([is_app_running/1,
- is_crypto_running/0, is_mnesia_running/0, is_snmp_running/0]).
+ is_crypto_running/0, is_mnesia_running/0, is_snmp_running/0,
+ ensure_not_running/3]).
-export([crypto_start/0, crypto_support/0]).
-export([watchdog/3, watchdog_start/1, watchdog_start/2, watchdog_stop/1]).
-export([del_dir/1]).
--export([cover/1]).
--export([f/2, p/2, print1/2, print2/2, print/5, formated_timestamp/0]).
+-export([f/2, formated_timestamp/0]).
+-export([p/2, print1/2, print2/2, print/5]).
+-export([eprint/2, wprint/2, nprint/2, iprint/2]).
-define(SKIP(R), skip(R, ?MODULE, ?LINE)).
@@ -97,20 +99,24 @@ tc_try(Case, TCCond, Pre, TC, Post)
tc_begin(Case),
try TCCond() of
ok ->
+ tc_print("starting: try pre"),
try Pre() of
State ->
+ tc_print("pre done: try test case"),
try
begin
TC(State),
sleep(seconds(1)),
+ tc_print("test case done: try post"),
(catch Post(State)),
tc_end("ok")
end
catch
C:{skip, _} = SKIP when (C =:= throw) orelse
(C =:= exit) ->
+ tc_print("test case (~w) skip: try post", [C]),
(catch Post(State)),
- tc_end( f("skipping(catched,~w,tc)", [C]) ),
+ tc_end( f("skipping(catched,~w,tc)", [C]) ),
SKIP;
C:E:S ->
%% We always check the system events
@@ -119,17 +125,18 @@ tc_try(Case, TCCond, Pre, TC, Post)
%% generate sys events itself...
case snmp_test_global_sys_monitor:events() of
[] ->
+ tc_print("test case failed: try post"),
(catch Post(State)),
tc_end( f("failed(catched,~w,tc)", [C]) ),
erlang:raise(C, E, S);
SysEvs ->
- tc_print("System Events received: "
+ tc_print("System Events received during tc: "
"~n ~p"
"~nwhen tc failed:"
"~n C: ~p"
"~n E: ~p"
"~n S: ~p",
- [SysEvs, C, E, S], "", ""),
+ [SysEvs, C, E, S]),
(catch Post(State)),
tc_end( f("skipping(catched-sysevs,~w,tc)",
[C]) ),
@@ -147,16 +154,22 @@ tc_try(Case, TCCond, Pre, TC, Post)
%% before we accept a failure
case snmp_test_global_sys_monitor:events() of
[] ->
- tc_end( f("failed(catched,~w,tc-pre)", [C]) ),
- erlang:raise(C, E, S);
- SysEvs ->
- tc_print("System Events received: "
- "~n ~p"
- "~nwhen tc-pre failed:"
+ tc_print("tc-pre failed: auto-skip"
"~n C: ~p"
"~n E: ~p"
"~n S: ~p",
- [SysEvs, C, E, S], "", ""),
+ [C, E, S]),
+ tc_end( f("auto-skip(catched,~w,tc-pre)", [C]) ),
+ SKIP = {skip, f("TC-Pre failure (~w)", [C])},
+ SKIP;
+ SysEvs ->
+ tc_print("System Events received: "
+ "~n ~p"
+ "~nwhen tc-pre failed:"
+ "~n C: ~p"
+ "~n E: ~p"
+ "~n S: ~p",
+ [SysEvs, C, E, S], "", ""),
tc_end( f("skipping(catched-sysevs,~w,tc-pre)", [C]) ),
SKIP = {skip, "TC-Pre failure with system events"},
SKIP
@@ -210,13 +223,19 @@ tc_end(Result) when is_list(Result) ->
"", "----------------------------------------------------~n~n"),
ok.
+tc_print(F) ->
+ tc_print(F, [], "", "").
+
+tc_print(F, A) ->
+ tc_print(F, A, "", "").
+
tc_print(F, Before, After) ->
tc_print(F, [], Before, After).
tc_print(F, A, Before, After) ->
Name = tc_which_name(),
FStr = f("*** [~s][~s][~p] " ++ F ++ "~n",
- [formated_timestamp(),Name,self()|A]),
+ [formated_timestamp(), Name, self() | A]),
io:format(user, Before ++ FStr ++ After, []),
io:format(standard_io, Before ++ FStr ++ After, []).
@@ -799,21 +818,24 @@ analyze_and_print_host_info() ->
{unix, freebsd} ->
analyze_and_print_freebsd_host_info(Version);
{unix, sunos} ->
- io:format("Solaris: ~s"
- "~n", [Version]),
- 2;
+ analyze_and_print_solaris_host_info(Version);
+ {win32, nt} ->
+ analyze_and_print_win_host_info(Version);
_ ->
io:format("OS Family: ~p"
- "~n OS Type: ~p"
- "~n Version: ~p"
- "~n", [OsFam, OsName, Version]),
+ "~n OS Type: ~p"
+ "~n Version: ~p"
+ "~n Num Schedulers: ~s"
+ "~n", [OsFam, OsName, Version, str_num_schedulers()]),
try erlang:system_info(schedulers) of
1 ->
10;
2 ->
5;
+ N when (N =< 6) ->
+ 2;
_ ->
- 2
+ 1
catch
_:_:_ ->
10
@@ -867,9 +889,11 @@ analyze_and_print_linux_host_info(Version) ->
%% Check if we need to adjust the factor because of the memory
try linux_which_meminfo() of
AddFactor ->
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
Factor + AddFactor
catch
_:_:_ ->
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
Factor
end.
@@ -993,6 +1017,7 @@ analyze_and_print_openbsd_host_info(Version) ->
"~nMemory:"
"~n ~w KB"
"~n", [CPU, CPUSpeed, NCPU, Memory]),
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
CPUFactor =
if
(CPUSpeed =:= -1) ->
@@ -1033,6 +1058,7 @@ analyze_and_print_openbsd_host_info(Version) ->
end
catch
_:_:_ ->
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
1
end.
@@ -1041,47 +1067,43 @@ analyze_and_print_freebsd_host_info(Version) ->
io:format("FreeBSD:"
"~n Version: ~p"
"~n", [Version]),
- Extract =
- fun(Key) ->
- string:tokens(string:trim(os:cmd("sysctl " ++ Key)), [$:])
- end,
+ %% This test require that the program 'sysctl' is in the path.
+ %% First test with 'which sysctl', if that does not work
+ %% try with 'which /sbin/sysctl'. If that does not work either,
+ %% we skip the test...
try
begin
- CPU =
- case Extract("hw.model") of
- ["hw.model", Model] ->
- string:trim(Model);
- _ ->
- "-"
- end,
- CPUSpeed =
- case Extract("hw.clockrate") of
- ["hw.clockrate", Speed] ->
- list_to_integer(string:trim(Speed));
- _ ->
- -1
- end,
- NCPU =
- case Extract("hw.ncpu") of
- ["hw.ncpu", N] ->
- list_to_integer(string:trim(N));
- _ ->
- -1
+ SysCtl =
+ case string:trim(os:cmd("which sysctl")) of
+ [] ->
+ case string:trim(os:cmd("which /sbin/sysctl")) of
+ [] ->
+ throw(sysctl);
+ SC2 ->
+ SC2
+ end;
+ SC1 ->
+ SC1
end,
- Memory =
- case Extract("hw.physmem") of
- ["hw.physmem", PhysMem] ->
- list_to_integer(string:trim(PhysMem)) div 1024;
- _ ->
- -1
+ Extract =
+ fun(Key) ->
+ string:tokens(string:trim(os:cmd(SysCtl ++ " " ++ Key)),
+ [$:])
end,
+ CPU = analyze_freebsd_cpu(Extract),
+ CPUSpeed = analyze_freebsd_cpu_speed(Extract),
+ NCPU = analyze_freebsd_ncpu(Extract),
+ Memory = analyze_freebsd_memory(Extract),
io:format("CPU:"
- "~n Model: ~s"
- "~n Speed: ~w"
- "~n N: ~w"
+ "~n Model: ~s"
+ "~n Speed: ~w"
+ "~n N: ~w"
+ "~n Num Schedulers: ~s"
"~nMemory:"
"~n ~w KB"
- "~n", [CPU, CPUSpeed, NCPU, Memory]),
+ "~n",
+ [CPU, CPUSpeed, NCPU, str_num_schedulers(), Memory]),
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
CPUFactor =
if
(CPUSpeed =:= -1) ->
@@ -1097,6 +1119,8 @@ analyze_and_print_freebsd_host_info(Version) ->
end;
true ->
if
+ (NCPU =:= -1) ->
+ 1;
(NCPU >= 4) ->
2;
(NCPU >= 2) ->
@@ -1122,9 +1146,336 @@ analyze_and_print_freebsd_host_info(Version) ->
end
catch
_:_:_ ->
+ io:format("CPU:"
+ "~n Num Schedulers: ~s"
+ "~n", [str_num_schedulers()]),
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
+ case erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ _ ->
+ 2
+ end
+ end.
+
+
+analyze_freebsd_cpu(Extract) ->
+ analyze_freebsd_item(Extract, "hw.model", fun(X) -> X end, "-").
+
+analyze_freebsd_cpu_speed(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.clockrate",
+ fun(X) -> list_to_integer(X) end,
+ -1).
+
+analyze_freebsd_ncpu(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.ncpu",
+ fun(X) -> list_to_integer(X) end,
+ -1).
+
+analyze_freebsd_memory(Extract) ->
+ analyze_freebsd_item(Extract,
+ "hw.physmem",
+ fun(X) -> list_to_integer(X) div 1024 end,
+ -1).
+
+analyze_freebsd_item(Extract, Key, Process, Default) ->
+ try
+ begin
+ case Extract(Key) of
+ [Key, Model] ->
+ Process(string:trim(Model));
+ _ ->
+ Default
+ end
+ end
+ catch
+ _:_:_ ->
+ Default
+ end.
+
+
+analyze_and_print_solaris_host_info(Version) ->
+ Release =
+ case file:read_file_info("/etc/release") of
+ {ok, _} ->
+ case [string:trim(S) || S <- string:tokens(os:cmd("cat /etc/release"), [$\n])] of
+ [Rel | _] ->
+ Rel;
+ _ ->
+ "-"
+ end;
+ _ ->
+ "-"
+ end,
+ %% Display the firmware device tree root properties (prtconf -b)
+ Props = [list_to_tuple([string:trim(PS) || PS <- Prop]) ||
+ Prop <- [string:tokens(S, [$:]) ||
+ S <- string:tokens(os:cmd("prtconf -b"), [$\n])]],
+ BannerName = case lists:keysearch("banner-name", 1, Props) of
+ {value, {_, BN}} ->
+ string:trim(BN);
+ _ ->
+ "-"
+ end,
+ InstructionSet =
+ case string:trim(os:cmd("isainfo -k")) of
+ "Pseudo-terminal will not" ++ _ ->
+ "-";
+ IS ->
+ IS
+ end,
+ PtrConf = [list_to_tuple([string:trim(S) || S <- Items]) || Items <- [string:tokens(S, [$:]) || S <- string:tokens(os:cmd("prtconf"), [$\n])], length(Items) > 1],
+ SysConf =
+ case lists:keysearch("System Configuration", 1, PtrConf) of
+ {value, {_, SC}} ->
+ SC;
+ _ ->
+ "-"
+ end,
+ %% Because we count the lines of the output (which may contain
+ %% any number of extra crap lines) we need to ensure we only
+ %% count the "proper" stdout. So send it to a tmp file first
+ %% and then count its number of lines...
+ NumPhysCPU =
+ try
+ begin
+ File1 = f("/tmp/psrinfo_p.~s.~w", [os:getpid(), os:system_time()]),
+ os:cmd("psrinfo -p > " ++ File1),
+ string:trim(os:cmd("cat " ++ File1))
+ end
+ catch
+ _:_:_ ->
+ "-"
+ end,
+ %% Because we count the lines of the output (which may contain
+ %% any number of extra crap lines) we need to ensure we only
+ %% count the "proper" stdout. So send it to a tmp file first
+ %% and then count its number of lines...
+ NumVCPU =
+ try
+ begin
+ File2 = f("/tmp/psrinfo.~s.~w", [os:getpid(), os:system_time()]),
+ os:cmd("psrinfo > " ++ File2),
+ [NumVCPUStr | _] = string:tokens(os:cmd("wc -l " ++ File2), [$\ ]),
+ NumVCPUStr
+ end
+ catch
+ _:_:_ ->
+ "-"
+ end,
+ MemSz =
+ case lists:keysearch("Memory size", 1, PtrConf) of
+ {value, {_, MS}} ->
+ MS;
+ _ ->
+ "-"
+ end,
+ io:format("Solaris: ~s"
+ "~n Release: ~s"
+ "~n Banner Name: ~s"
+ "~n Instruction Set: ~s"
+ "~n CPUs: ~s (~s)"
+ "~n System Config: ~s"
+ "~n Memory Size: ~s"
+ "~n Num Schedulers: ~s"
+ "~n~n", [Version, Release, BannerName, InstructionSet,
+ NumPhysCPU, NumVCPU,
+ SysConf, MemSz,
+ str_num_schedulers()]),
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
+ MemFactor =
+ try string:tokens(MemSz, [$ ]) of
+ [SzStr, "Mega" ++ _] ->
+ try list_to_integer(SzStr) of
+ Sz when Sz > 8192 ->
+ 0;
+ Sz when Sz > 4096 ->
+ 1;
+ Sz when Sz > 2048 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ [SzStr, "Giga" ++ _] ->
+ try list_to_integer(SzStr) of
+ Sz when Sz > 8 ->
+ 0;
+ Sz when Sz > 4 ->
+ 1;
+ Sz when Sz > 2 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ _ ->
+ 10
+ catch
+ _:_:_ ->
+ 10
+ end,
+ try erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ N when (N =< 6) ->
+ 2;
+ _ ->
1
+ catch
+ _:_:_ ->
+ 10
+ end + MemFactor.
+
+
+
+analyze_and_print_win_host_info(Version) ->
+ SysInfo = which_win_system_info(),
+ OsName = win_sys_info_lookup(os_name, SysInfo),
+ OsVersion = win_sys_info_lookup(os_version, SysInfo),
+ SysMan = win_sys_info_lookup(system_manufacturer, SysInfo),
+ SysMod = win_sys_info_lookup(system_model, SysInfo),
+ NumProcs = win_sys_info_lookup(num_processors, SysInfo),
+ TotPhysMem = win_sys_info_lookup(total_phys_memory, SysInfo),
+ io:format("Windows: ~s"
+ "~n OS Version: ~s (~p)"
+ "~n System Manufacturer: ~s"
+ "~n System Model: ~s"
+ "~n Number of Processor(s): ~s"
+ "~n Total Physical Memory: ~s"
+ "~n Num Schedulers: ~s"
+ "~n~n", [OsName, OsVersion, Version,
+ SysMan, SysMod, NumProcs, TotPhysMem,
+ str_num_schedulers()]),
+ io:format("TS Scale Factor: ~w~n", [timetrap_scale_factor()]),
+ MemFactor =
+ try
+ begin
+ [MStr, MUnit|_] =
+ string:tokens(lists:delete($,, TotPhysMem), [$\ ]),
+ case string:to_lower(MUnit) of
+ "gb" ->
+ try list_to_integer(MStr) of
+ M when M > 8 ->
+ 0;
+ M when M > 4 ->
+ 1;
+ M when M > 2 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ "mb" ->
+ try list_to_integer(MStr) of
+ M when M > 8192 ->
+ 0;
+ M when M > 4096 ->
+ 1;
+ M when M > 2048 ->
+ 2;
+ _ ->
+ 5
+ catch
+ _:_:_ ->
+ 10
+ end;
+ _ ->
+ 10
+ end
+ end
+ catch
+ _:_:_ ->
+ 10
+ end,
+ CPUFactor =
+ case erlang:system_info(schedulers) of
+ 1 ->
+ 10;
+ 2 ->
+ 5;
+ _ ->
+ 2
+ end,
+ CPUFactor + MemFactor.
+
+win_sys_info_lookup(Key, SysInfo) ->
+ win_sys_info_lookup(Key, SysInfo, "-").
+
+win_sys_info_lookup(Key, SysInfo, Def) ->
+ case lists:keysearch(Key, 1, SysInfo) of
+ {value, {Key, Value}} ->
+ Value;
+ false ->
+ Def
end.
+%% This function only extracts the prop we actually care about!
+which_win_system_info() ->
+ SysInfo = os:cmd("systeminfo"),
+ try process_win_system_info(string:tokens(SysInfo, [$\r, $\n]), [])
+ catch
+ _:_:_ ->
+ io:format("Failed process System info: "
+ "~s~n", [SysInfo]),
+ []
+ end.
+
+process_win_system_info([], Acc) ->
+ Acc;
+process_win_system_info([H|T], Acc) ->
+ case string:tokens(H, [$:]) of
+ [Key, Value] ->
+ case string:to_lower(Key) of
+ "os name" ->
+ process_win_system_info(T,
+ [{os_name, string:trim(Value)}|Acc]);
+ "os version" ->
+ process_win_system_info(T,
+ [{os_version, string:trim(Value)}|Acc]);
+ "system manufacturer" ->
+ process_win_system_info(T,
+ [{system_manufacturer, string:trim(Value)}|Acc]);
+ "system model" ->
+ process_win_system_info(T,
+ [{system_model, string:trim(Value)}|Acc]);
+ "processor(s)" ->
+ [NumProcStr|_] = string:tokens(Value, [$\ ]),
+ T2 = lists:nthtail(list_to_integer(NumProcStr), T),
+ process_win_system_info(T2,
+ [{num_processors, NumProcStr}|Acc]);
+ "total physical memory" ->
+ process_win_system_info(T,
+ [{total_phys_memory, string:trim(Value)}|Acc]);
+ _ ->
+ process_win_system_info(T, Acc)
+ end;
+ _ ->
+ process_win_system_info(T, Acc)
+ end.
+
+
+
+str_num_schedulers() ->
+ try erlang:system_info(schedulers) of
+ N -> f("~w", [N])
+ catch
+ _:_:_ -> "-"
+ end.
+
+
%% ----------------------------------------------------------------
%% Time related function
@@ -1218,15 +1569,16 @@ is_snmp_running() ->
is_app_running(snmp).
crypto_start() ->
- case (catch crypto:start()) of
+ try crypto:start() of
ok ->
ok;
{error, {already_started,crypto}} ->
- ok;
- {'EXIT', Reason} ->
- {error, {exit, Reason}};
- Else ->
- Else
+ ok
+ catch
+ exit:{undef, [{crypto, start, [], []} | _]}:_ ->
+ {error, no_crypto};
+ C:E:S ->
+ {error, {C, E, S}}
end.
crypto_support() ->
@@ -1246,8 +1598,74 @@ crypto_support([Func|Funcs], Acc) ->
is_crypto_supported(Func) ->
snmp_misc:is_crypto_supported(Func).
-
-
+
+
+%% This function ensures that a *named* process on the local node is not running.
+%% It does so by:
+%% 1) Wait for 'Timeout' msec
+%% 2) If 1 did not work, issue 'stop' and then wait 'Timeout' msec
+%% 3) And finally, if 2 did not work, issue exit(kill).
+ensure_not_running(Name, Stopper, Timeout)
+ when is_atom(Name) andalso
+ is_function(Stopper, 0) andalso
+ is_integer(Timeout) ->
+ ensure_not_running(whereis(Name), Name, Stopper, Timeout).
+
+ensure_not_running(Pid, Name, Stopper, Timeout) when is_pid(Pid) ->
+ MRef = erlang:monitor(process, Pid),
+ try
+ begin
+ ensure_not_running_wait(Pid, MRef, Timeout),
+ ensure_not_running_stop(Pid, MRef, Stopper, Timeout),
+ ensure_not_running_kill(Pid, MRef, Timeout),
+ exit({failed_ensure_not_running, Name})
+ end
+ catch
+ throw:ok ->
+ sleep(1000),
+ ok
+ end;
+ensure_not_running(_, _, _, _) ->
+ iprint("ensure_not_running -> not running", []),
+ sleep(1000), % This should not actually be necessary!
+ ok.
+
+
+ensure_not_running_wait(Pid, MRef, Timeout) ->
+ receive
+ {'DOWN', MRef, process, Pid, _Info} ->
+ iprint("ensure_not_running_wait -> died peacefully", []),
+ throw(ok)
+ after Timeout ->
+ wprint("ensure_not_running_wait -> giving up", []),
+ ok
+ end.
+
+ensure_not_running_stop(Pid, MRef, Stopper, Timeout) ->
+ %% Spawn a stop'er process
+ StopPid = spawn(Stopper),
+ receive
+ {'DOWN', MRef, process, Pid, _Info} ->
+ nprint("ensure_not_running_stop -> dead (stopped)", []),
+ throw(ok)
+ after Timeout ->
+ wprint("ensure_not_running_stop -> giving up", []),
+ exit(StopPid, kill),
+ ok
+ end.
+
+ensure_not_running_kill(Pid, MRef, Timeout) ->
+ exit(Pid, kill),
+ receive
+ {'DOWN', MRef, process, Pid, _Info} ->
+ nprint("ensure_not_running_kill -> dead (killed)", []),
+ throw(ok)
+ after Timeout ->
+ wprint("ensure_not_running_kill -> giving up", []),
+ ok
+ end.
+
+
%% ----------------------------------------------------------------
%% Watchdog functions
%%
@@ -1376,19 +1794,6 @@ del_file_or_dir(FileOrDir) ->
%% ----------------------------------------------------------------------
-%% cover functions
-%%
-
-cover([Suite, Case] = Args) when is_atom(Suite) andalso is_atom(Case) ->
- Mods0 = cover:compile_directory("../src"),
- Mods1 = [Mod || {ok, Mod} <- Mods0],
- snmp_test_server:t(Args),
- Files0 = [cover:analyse_to_file(Mod) || Mod <- Mods1],
- [io:format("Cover output: ~s~n", [File]) || {ok, File} <- Files0],
- ok.
-
-
-%% ----------------------------------------------------------------------
%% (debug) Print functions
%%
@@ -1434,3 +1839,49 @@ print(Prefix, Module, Line, Format, Args) ->
formated_timestamp() ->
snmp_misc:formated_timestamp().
+
+%% ----------------------------------------------------------------------
+%%
+%% General purpose print functions
+%% ERROR, WARNING and NOTICE are written both to 'user' and 'standard_io'.
+%% INFO only to 'standard_io'.
+%%
+%% Should we also allow for (optional) a "short name" (sname)?
+%%
+
+%% ERROR print (both to user and standard_io)
+eprint(F, A) ->
+ Str = format_print("ERROR", F, A),
+ io:format(user, "~s~n", [Str]),
+ io:format(standard_io, "~s~n", [Str]).
+
+%% WARNING print (both to user and standard_io)
+wprint(F, A) ->
+ Str = format_print("WARNING", F, A),
+ io:format(user, "~s~n", [Str]),
+ io:format(standard_io, "~s~n", [Str]).
+
+%% NOTICE print (both to user and standard_io)
+nprint(F, A) ->
+ Str = format_print("NOTICE", F, A),
+ io:format(user, "~s~n", [Str]),
+ io:format(standard_io, "~s~n", [Str]).
+
+%% INFO print (only to user)
+iprint(F, A) ->
+ Str = format_print("INFO", F, A),
+ io:format(standard_io, "~s~n", [Str]).
+
+format_print(Prefix, F, A) ->
+ format_print(get(tname), Prefix, F, A).
+
+format_print(undefined, Prefix, F, A) ->
+ f("*** [~s] ~s ~p ~p *** ~n" ++ F ++ "~n",
+ [formated_timestamp(), Prefix, node(), self() | A]);
+format_print(TName, Prefix, F, A) when is_atom(TName) ->
+ format_print(atom_to_list(TName), Prefix, F, A);
+format_print(TName, Prefix, F, A) when is_list(TName) ->
+ f("*** [~s] ~s ~s ~p ~p *** ~n" ++ F ++ "~n",
+ [formated_timestamp(), Prefix, TName, node(), self() | A]).
+
+
diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl
index 1e6e513d9d..f4863c9a1e 100644
--- a/lib/snmp/test/snmp_test_lib.hrl
+++ b/lib/snmp/test/snmp_test_lib.hrl
@@ -84,6 +84,10 @@
-define(FLUSH(), ?LIB:flush_mqueue()).
-define(ETRAP_GET(), ?LIB:trap_exit()).
-define(ETRAP_SET(O), ?LIB:trap_exit(O)).
+-define(PINFO(__P__), try process_info(__P__)
+ catch _:_:_ ->
+ {not_running, __P__}
+ end).
%% - Node utility macros -
@@ -105,6 +109,9 @@
-define(CRYPTO_SUPPORT(), ?LIB:crypto_support()).
+-define(ENSURE_NOT_RUNNING(N, S, T), ?LIB:ensure_not_running(N, S, T)).
+
+
%% - Dir macros -
-define(DEL_DIR(D), ?LIB:del_dir(D)).
@@ -112,55 +119,33 @@
%% - Print macros
+%% Used for indicating the start of a test case
-define(P(C), ?LIB:p(?MODULE, C)).
--define(P1(F), ?LIB:p(F, [])).
--define(P2(F, A), ?LIB:p(F, A)).
--define(F(F, A), ?LIB:f(F, A)).
--ifdef(snmp_debug).
--ifndef(snmp_log).
--define(snmp_log,true).
--endif.
--ifndef(snmp_error).
--define(snmp_error,true).
--endif.
--else.
--ifdef(snmp_log).
--ifndef(snmp_error).
--define(snmp_error,true).
--endif.
--endif.
--endif.
+%% Takes a format call (such as io:format) and produces a printable string
+-define(F(F, A), ?LIB:f(F, A)).
-ifdef(snmp_debug).
--define(DBG(F,A), ?PRINT("DBG", F, A)).
+-define(DBG(F,A), ?IPRINT(F, A)).
-else.
-define(DBG(F,A), ok).
-endif.
--ifdef(snmp_log).
--define(LOG(F,A), ?PRINT("LOG", F, A)).
--else.
--define(LOG(F,A), ok).
--endif.
-
--ifdef(snmp_error).
--define(ERR(F,A), ?PRINT("ERR", F, A)).
--else.
--define(ERR(F,A), ok).
--endif.
-
--define(INF(F,A), ?PRINT("INF", F, A)).
+%% ERROR print
+-define(EPRINT(F), ?LIB:eprint(F, [])).
+-define(EPRINT(F, A), ?LIB:eprint(F, A)).
--define(PRINT(P,F,A), ?LIB:print(P, ?MODULE, ?LINE, F, A)).
+%% WARNING print
+-define(WPRINT(F), ?LIB:wprint(F, [])).
+-define(WPRINT(F, A), ?LIB:wprint(F, A)).
--define(PRINT1(F, A), ?LIB:print1(F, A)).
--define(PRINT1(F), ?PRINT1(F, [])).
--define(EPRINT1(F, A), ?PRINT1("<ERROR> " ++ F, A)).
+%% NOTICE print
+-define(NPRINT(F), ?LIB:nprint(F, [])).
+-define(NPRINT(F, A), ?LIB:nprint(F, A)).
--define(PRINT2(F, A), ?LIB:print2(F, A)).
--define(PRINT2(F), ?PRINT2(F, [])).
--define(EPRINT2(F, A), ?PRINT2("<ERROR> " ++ F, A)).
+%% INFO print
+-define(IPRINT(F), ?LIB:iprint(F, [])).
+-define(IPRINT(F, A), ?LIB:iprint(F, A)).
-define(FTS(), snmp_misc:formated_timestamp()).
-define(FTS(TS), snmp_misc:format_timestamp(TS)).
diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl
index f50147a852..0a80860ed1 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2019. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2020. 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.
@@ -191,40 +191,41 @@ receive_trap(Timeout) ->
%% {mibs, List of Filenames}, {trap_udp, UDPPort (default 5000)},
%%----------------------------------------------------------------------
init({Options, CallerPid}) ->
+ %% This causes "verbosity printouts" to print (from level debug)
+ %% in the modules we "borrow" from the agent code (burr,,,)
+ %% With "our" name (mgr).
put(sname, mgr),
- put(verbosity, debug),
+ put(verbosity, debug),
+ %% Make use of the "test name" print "feature"
+ put(tname, "MGR"),
?SNMP_RAND_SEED(),
- %% rand:seed(exrop,
- %% {erlang:phash2([node()]),
- %% erlang:monotonic_time(),
- %% erlang:unique_integer()}),
case (catch is_options_ok(Options)) of
true ->
put(debug, get_value(debug, Options, false)),
- d("init -> (~p) extract options",[self()]),
+ d("init -> extract options"),
PacksDbg = get_value(packet_server_debug, Options, false),
- print("[~w] ~p -> PacksDbg: ~p~n", [?MODULE, self(), PacksDbg]),
+ ?IPRINT("init -> PacksDbg: ~p", [PacksDbg]),
RecBufSz = get_value(recbuf, Options, 1024),
- print("[~w] ~p -> RecBufSz: ~p~n", [?MODULE, self(), RecBufSz]),
+ ?IPRINT("init -> RecBufSz: ~p", [RecBufSz]),
Mibs = get_value(mibs, Options, []),
- print("[~w] ~p -> Mibs: ~p~n", [?MODULE, self(), Mibs]),
+ ?IPRINT("init -> Mibs: ~p", [Mibs]),
Udp = get_value(agent_udp, Options, 4000),
- print("[~w] ~p -> Udp: ~p~n", [?MODULE, self(), Udp]),
+ ?IPRINT("init -> Udp: ~p", [Udp]),
User = get_value(user, Options, "initial"),
- print("[~w] ~p -> User: ~p~n", [?MODULE, self(), User]),
+ ?IPRINT("init -> User: ~p", [User]),
EngineId = get_value(engine_id, Options, "agentEngine"),
- print("[~w] ~p -> EngineId: ~p~n", [?MODULE, self(), EngineId]),
+ ?IPRINT("init -> EngineId: ~p", [EngineId]),
CtxEngineId = get_value(context_engine_id, Options, EngineId),
- print("[~w] ~p -> CtxEngineId: ~p~n", [?MODULE, self(), CtxEngineId]),
+ ?IPRINT("init -> CtxEngineId: ~p", [CtxEngineId]),
TrapUdp = get_value(trap_udp, Options, 5000),
- print("[~w] ~p -> TrapUdp: ~p~n", [?MODULE, self(), TrapUdp]),
+ ?IPRINT("init -> TrapUdp: ~p", [TrapUdp]),
Dir = get_value(dir, Options, "."),
- print("[~w] ~p -> Dir: ~p~n", [?MODULE, self(), Dir]),
+ ?IPRINT("init -> Dir: ~p", [Dir]),
SecLevel = get_value(sec_level, Options, noAuthNoPriv),
- print("[~w] ~p -> SecLevel: ~p~n", [?MODULE, self(), SecLevel]),
+ ?IPRINT("init -> SecLevel: ~p", [SecLevel]),
MiniMIB = snmp_mini_mib:create(Mibs),
- d("[~w] ~p -> MiniMIB: "
- "~n ~p", [?MODULE, self(), MiniMIB]),
+ d("init -> MiniMIB: "
+ "~n ~p", [MiniMIB]),
Version = case lists:member(v2, Options) of
true -> 'version-2';
false ->
@@ -233,41 +234,38 @@ init({Options, CallerPid}) ->
false -> 'version-1'
end
end,
- print("[~w] ~p -> Version: ~p~n", [?MODULE, self(), Version]),
+ ?IPRINT("init -> Version: ~p", [Version]),
Com = case Version of
'version-3' ->
get_value(context, Options, "");
_ ->
get_value(community, Options, "public")
end,
- print("[~w] ~p -> Com: ~p~n", [?MODULE, self(), Com]),
+ ?IPRINT("init -> Com: ~p", [Com]),
VsnHdrD =
{Com, User, EngineId, CtxEngineId, mk_seclevel(SecLevel)},
- print("[~w] ~p -> VsnHdrD: ~p~n", [?MODULE, self(), VsnHdrD]),
+ ?IPRINT("init -> VsnHdrD: ~p", [VsnHdrD]),
IpFamily = get_value(ipfamily, Options, inet),
- print("[~w] ~p -> IpFamily: ~p~n", [?MODULE, self(), IpFamily]),
+ ?IPRINT("init -> IpFamily: ~p", [IpFamily]),
AgIp = case snmp_misc:assq(agent, Options) of
{value, Addr} when is_tuple(Addr) andalso
(size(Addr) =:= 4) andalso
(IpFamily =:= inet) ->
- print("[~w] ~p -> Addr: ~p~n",
- [?MODULE, self(), Addr]),
+ ?IPRINT("init -> Addr: ~p", [Addr]),
Addr;
{value, Addr} when is_tuple(Addr) andalso
(size(Addr) =:= 8) andalso
(IpFamily =:= inet6) ->
- print("[~w] ~p -> Addr: ~p~n",
- [?MODULE, self(), Addr]),
+ ?IPRINT("init -> Addr: ~p", [Addr]),
Addr;
{value, Host} when is_list(Host) ->
- print("[~w] ~p -> Host: ~p~n",
- [?MODULE, self(), Host]),
+ ?IPRINT("init -> Host: ~p", [Host]),
{ok, Ip} = snmp_misc:ip(Host, IpFamily),
Ip
end,
- print("[~w] ~p -> AgIp: ~p~n", [?MODULE, self(), AgIp]),
+ ?IPRINT("init -> AgIp: ~p", [AgIp]),
Quiet = lists:member(quiet, Options),
- print("[~w] ~p -> Quiet: ~p~n", [?MODULE, self(), Quiet]),
+ ?IPRINT("init -> Quiet: ~p", [Quiet]),
PackServ =
start_packet_server(
Quiet, Options, CallerPid, AgIp, Udp, TrapUdp,
@@ -692,16 +690,16 @@ echo_pdu(PDU, MiniMIB) ->
%% Test Sequence
%%----------------------------------------------------------------------
echo_errors({error, Id, {ExpectedFormat, ExpectedData}, {Format, Data}})->
- io:format("* Unexpected Behaviour * Id: ~w.~n"
- " Expected: " ++ ExpectedFormat ++ "~n"
- " Got: " ++ Format ++ "~n",
- [Id] ++ ExpectedData ++ Data),
+ ?IPRINT("*** Unexpected Behaviour *** Id: ~w.~n"
+ " Expected: " ++ ExpectedFormat ++ "~n"
+ " Got: " ++ Format ++ "~n",
+ [Id] ++ ExpectedData ++ Data),
{error, Id, {ExpectedFormat, ExpectedData}, {Format, Data}};
echo_errors(ok) -> ok;
echo_errors({ok, Val}) -> {ok, Val}.
get_response_impl(Id, ExpVars) ->
- ?PRINT2("await response ~w with"
+ ?IPRINT("await response ~w with"
"~n Expected Varbinds: ~p",
[Id, ExpVars]),
PureVars = find_pure_oids2(ExpVars),
@@ -710,7 +708,7 @@ get_response_impl(Id, ExpVars) ->
error_status = noError,
error_index = 0,
varbinds = VBs} ->
- ?PRINT2("received expected response pdu (~w) - match vars"
+ ?IPRINT("received expected response pdu (~w) - match vars"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, PureVars, VBs]),
@@ -720,10 +718,10 @@ get_response_impl(Id, ExpVars) ->
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT2("received unexpected response pdu: ~w, ~w, ~w"
- "~n Received Error: ~p"
- "~n Received Index: ~p",
- [Type2, Id, ReqId, Err2, Index2]),
+ ?EPRINT("received unexpected response pdu: ~w, ~w, ~w"
+ "~n Received Error: ~p"
+ "~n Received Index: ~p",
+ [Type2, Id, ReqId, Err2, Index2]),
{error,
Id,
{"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
@@ -732,8 +730,8 @@ get_response_impl(Id, ExpVars) ->
[Type2, Err2, Index2]}};
{error, Reason} ->
- ?EPRINT2("unexpected receive pdu error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive pdu error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end.
@@ -743,81 +741,81 @@ get_response_impl(Id, ExpVars) ->
%% Returns: ok | {error, Id, {ExpectedFormat, ExpectedData}, {Format, Data}}
%%----------------------------------------------------------------------
expect_impl(Id, any) ->
- ?PRINT2("await ~w pdu (any)", [Id]),
+ ?IPRINT("await ~w pdu (any)", [Id]),
case receive_response() of
PDU when is_record(PDU, pdu) ->
- ?PRINT2("received expected pdu (~w)", [Id]),
+ ?IPRINT("received expected pdu (~w)", [Id]),
ok;
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, return) ->
- ?PRINT2("await ~w pdu", [Id]),
+ ?IPRINT("await ~w pdu", [Id]),
case receive_response() of
PDU when is_record(PDU, pdu) ->
- ?PRINT2("received expected pdu (~w)", [Id]),
+ ?IPRINT("received expected pdu (~w)", [Id]),
{ok, PDU};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, trap) ->
- ?PRINT2("await ~w trap", [Id]),
+ ?IPRINT("await ~w trap", [Id]),
case receive_trap(3500) of
PDU when is_record(PDU, trappdu) ->
- ?PRINT2("received expected trap (~w)", [Id]),
+ ?IPRINT("received expected trap (~w)", [Id]),
ok;
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, timeout) ->
- ?PRINT2("await ~w nothing", [Id]),
+ ?IPRINT("await ~w nothing", [Id]),
receive
X ->
- ?EPRINT1("received unexpected message: ~w"
- "~n ~p",
- [Id, X]),
+ ?EPRINT("received unexpected message: ~w"
+ "~n ~p",
+ [Id, X]),
{error, Id, {"Timeout", []}, {"Message ~w", [X]}}
after 3500 ->
ok
end;
expect_impl(Id, Err) when is_atom(Err) ->
- ?PRINT2("await ~w with"
+ ?IPRINT("await ~w with"
"~n Err: ~p",
[Id, Err]),
case receive_response() of
#pdu{error_status = Err} ->
- ?PRINT2("received pdu with expected error status (~w, ~w)",
+ ?IPRINT("received pdu with expected error status (~w, ~w)",
[Id, Err]),
ok;
#pdu{type = Type2,
request_id = ReqId,
error_status = Err2} ->
- ?EPRINT1("received pdu with unexpected error status: ~w, ~w, ~w"
- "~n Expected Error: ~p"
- "~n Received Error: ~p",
- [Type2, Id, ReqId, Err, Err2]),
+ ?EPRINT("received pdu with unexpected error status: ~w, ~w, ~w"
+ "~n Expected Error: ~p"
+ "~n Received Error: ~p",
+ [Type2, Id, ReqId, Err, Err2]),
{error, Id, {"ErrorStatus: ~w, RequestId: ~w", [Err,ReqId]},
{"ErrorStatus: ~w", [Err2]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
- ?PRINT2("await ~w with"
+ ?IPRINT("await ~w with"
"~n ExpectedVarbinds: ~p",
[Id, ExpectedVarbinds]),
PureVars = find_pure_oids(ExpectedVarbinds),
@@ -826,7 +824,7 @@ expect_impl(Id, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
error_status = noError,
error_index = 0,
varbinds = VBs} ->
- ?PRINT2("received expected response pdu (~w) - check varbinds"
+ ?IPRINT("received expected response pdu (~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, PureVars, VBs]),
@@ -836,22 +834,22 @@ expect_impl(Id, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT1("received unexpected pdu: ~w, ~w, ~w"
- "~n Received Error: ~p"
- "~n Received Index: ~p",
+ ?EPRINT("received unexpected pdu: ~w, ~w, ~w"
+ "~n Received Error: ~p"
+ "~n Received Index: ~p",
[Type2, Id, ReqId, Err2, Index2]),
{error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
['get-response', noError, 0, ReqId]},
{"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end.
expect_impl(Id, v2trap, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
- ?PRINT2("await v2 trap ~w with"
+ ?IPRINT("await v2 trap ~w with"
"~n ExpectedVarbinds: ~p",
[Id, ExpectedVarbinds]),
PureVars = find_pure_oids(ExpectedVarbinds),
@@ -860,7 +858,7 @@ expect_impl(Id, v2trap, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
error_status = noError,
error_index = 0,
varbinds = VBs} ->
- ?PRINT2("received expected v2 trap (~w) - check varbinds"
+ ?IPRINT("received expected v2 trap (~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, PureVars, VBs]),
@@ -870,22 +868,22 @@ expect_impl(Id, v2trap, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT1("received unexpected pdu: ~w, ~w, ~w"
- "~n Received Error: ~p"
- "~n Received Index: ~p",
- [Type2, Id, ReqId, Err2, Index2]),
+ ?EPRINT("received unexpected pdu: ~w, ~w, ~w"
+ "~n Received Error: ~p"
+ "~n Received Index: ~p",
+ [Type2, Id, ReqId, Err2, Index2]),
{error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
['snmpv2-trap', noError, 0, ReqId]},
{"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, report, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
- ?PRINT2("await report ~w with"
+ ?IPRINT("await report ~w with"
"~n ExpectedVarbinds: ~p",
[Id, ExpectedVarbinds]),
PureVBs = find_pure_oids(ExpectedVarbinds),
@@ -894,7 +892,7 @@ expect_impl(Id, report, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
error_status = noError,
error_index = 0,
varbinds = VBs} ->
- ?PRINT2("received expected report (~w) - check varbinds"
+ ?IPRINT("received expected report (~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, PureVBs, VBs]),
@@ -904,23 +902,23 @@ expect_impl(Id, report, ExpectedVarbinds) when is_list(ExpectedVarbinds) ->
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT1("received unexpected pdu: ~w, ~w, ~w"
- "~n Received Error: ~p"
- "~n Received Index: ~p",
- [Type2, Id, ReqId, Err2, Index2]),
+ ?EPRINT("received unexpected pdu: ~w, ~w, ~w"
+ "~n Received Error: ~p"
+ "~n Received Index: ~p",
+ [Type2, Id, ReqId, Err2, Index2]),
{error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
[report, noError, 0, ReqId]},
{"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, {inform, Reply}, ExpectedVarbinds)
when is_list(ExpectedVarbinds) ->
- ?PRINT2("await inform ~w with"
+ ?IPRINT("await inform ~w with"
"~n Reply: ~p"
"~n ExpectedVarbinds: ~p",
[Id, Reply, ExpectedVarbinds]),
@@ -931,20 +929,20 @@ expect_impl(Id, {inform, Reply}, ExpectedVarbinds)
error_status = noError,
error_index = 0,
varbinds = VBs} ->
- ?PRINT2("received inform (~w) - check varbinds"
+ ?IPRINT("received inform (~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, PureVBs, VBs]),
case check_vars(Id, PureVBs, VBs) of
ok when (Reply == true) ->
- ?PRINT2("varbinds ok (~w) - send ok inform response", [Id]),
+ ?IPRINT("varbinds ok (~w) - send ok inform response", [Id]),
RespPDU = Resp#pdu{type = 'get-response',
error_status = noError,
error_index = 0},
?MODULE:rpl(RespPDU),
ok;
ok when (element(1, Reply) == error) ->
- ?PRINT2("varbinds ok (~w) - send error inform response", [Id]),
+ ?IPRINT("varbinds ok (~w) - send error inform response", [Id]),
{error, Status, Index} = Reply,
RespPDU = Resp#pdu{type = 'get-response',
error_status = Status,
@@ -952,13 +950,12 @@ expect_impl(Id, {inform, Reply}, ExpectedVarbinds)
?MODULE:rpl(RespPDU),
ok;
ok when (Reply == false) ->
- ?PRINT2("varbinds ok (~w) - don't send inform response", [Id]),
+ ?IPRINT("varbinds ok (~w) - don't send inform response", [Id]),
ok;
Else ->
- ?EPRINT1("unexpected varbinds (~w)", [Id]),
- io:format("expect_impl(~w, inform) -> "
- "~n Else: ~p"
- "~n", [Id, Else]),
+ ?EPRINT("unexpected (inform) varbinds (~w):"
+ "~n VBs: ~p"
+ "~n ~p", [Id, VBs, Else]),
Else
end;
@@ -966,22 +963,22 @@ expect_impl(Id, {inform, Reply}, ExpectedVarbinds)
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT1("received unexpected pdu: ~w, ~w, ~w"
- "~n Received Error: ~p"
- "~n Received Index: ~p",
- [Type2, Id, ReqId, Err2, Index2]),
+ ?EPRINT("received unexpected pdu: ~w, ~w, ~w"
+ "~n Received Error: ~p"
+ "~n Received Index: ~p",
+ [Type2, Id, ReqId, Err2, Index2]),
{error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
['inform-request', noError, 0, ReqId]},
{"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end.
expect_impl(Id, Err, Index, any = _ExpectedVarbinds) ->
- ?PRINT2("await response ~w with"
+ ?IPRINT("await response ~w with"
"~n Err: ~p"
"~n Index: ~p"
"~n ExpectedVarbinds: ~p",
@@ -990,13 +987,13 @@ expect_impl(Id, Err, Index, any = _ExpectedVarbinds) ->
#pdu{type = 'get-response',
error_status = Err,
error_index = Index} ->
- ?PRINT2("received expected response pdu (~w, ~w, ~w)",
+ ?IPRINT("received expected response pdu (~w, ~w, ~w)",
[Id, Err, Index]),
ok;
#pdu{type = 'get-response',
error_status = Err} when (Index == any) ->
- ?PRINT2("received expected response pdu (~w, ~w)",
+ ?IPRINT("received expected response pdu (~w, ~w)",
[Id, Err]),
ok;
@@ -1006,14 +1003,14 @@ expect_impl(Id, Err, Index, any = _ExpectedVarbinds) ->
error_index = Idx} when is_list(Index) ->
case lists:member(Idx, Index) of
true ->
- ?PRINT2("received expected response pdu (~w, ~w, ~w)",
+ ?IPRINT("received expected response pdu (~w, ~w, ~w)",
[Id, Err, Idx]),
ok;
false ->
- ?EPRINT1("received response pdu with unexpected index (~w, ~w):"
- "~n Expected Index: ~p"
- "~n Received Index: ~p",
- [Id, Err, Index, Idx]),
+ ?EPRINT("received response pdu with unexpected index (~w, ~w):"
+ "~n Expected Index: ~p"
+ "~n Received Index: ~p",
+ [Id, Err, Index, Idx]),
{error, Id, {"ErrStat: ~w, Idx: ~w, RequestId: ~w",
[Err, Index, ReqId]},
{"ErrStat: ~w, Idx: ~w", [Err, Idx]}}
@@ -1023,22 +1020,24 @@ expect_impl(Id, Err, Index, any = _ExpectedVarbinds) ->
request_id = ReqId,
error_status = Err2,
error_index = Index2} ->
- ?EPRINT1("received unexpected response pdu: ~w, ~w, ~w"
- "~n Expected Error: ~p"
- "~n Received Error: ~p"
- "~n Expected Index: ~p"
- "~n Received Index: ~p",
- [Type2, Id, ReqId, Err, Err2, Index, Index2]),
+ ?EPRINT("received unexpected response pdu: ~w, ~w, ~w"
+ "~n Expected Error: ~p"
+ "~n Received Error: ~p"
+ "~n Expected Index: ~p"
+ "~n Received Index: ~p",
+ [Type2, Id, ReqId, Err, Err2, Index, Index2]),
{error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w",
['get-response', Err, Index, ReqId]},
{"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}};
{error, Reason} ->
+ ?EPRINT("unexpected (receive) response: "
+ "~n ~p", [Reason]),
format_reason(Id, Reason)
end;
expect_impl(Id, Err, Index, ExpectedVarbinds) ->
- ?PRINT2("await response ~w with"
+ ?IPRINT("await response ~w with"
"~n Err: ~p"
"~n Index: ~p"
"~n ExpectedVarbinds: ~p",
@@ -1049,7 +1048,7 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) ->
error_status = Err,
error_index = Index,
varbinds = VBs} ->
- ?PRINT2("received expected response pdu (~w, ~w, ~w) - check varbinds"
+ ?IPRINT("received expected response pdu (~w, ~w, ~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, Err, Index, PureVBs, VBs]),
@@ -1058,7 +1057,7 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) ->
#pdu{type = 'get-response',
error_status = Err,
varbinds = VBs} when (Index == any) ->
- ?PRINT2("received expected response pdu (~w, ~w) - check varbinds"
+ ?IPRINT("received expected response pdu (~w, ~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, Err, PureVBs, VBs]),
@@ -1071,18 +1070,18 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) ->
varbinds = VBs} when is_list(Index) ->
case lists:member(Idx, Index) of
true ->
- ?PRINT2("received expected pdu (~w, ~w, ~w) - check varbinds"
+ ?IPRINT("received expected pdu (~w, ~w, ~w) - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[Id, Err, Idx, PureVBs, VBs]),
check_vars(Id, PureVBs, VBs);
false ->
- ?EPRINT1("received response pdu with unexpected index (~w, ~w):"
- "~n Expected Index: ~p"
- "~n Received Index: ~p"
- "~n Expected VBs: ~p"
- "~n Received VBs: ~p",
- [Id, Err, Index, Idx, PureVBs, VBs]),
+ ?EPRINT("received response pdu with unexpected index (~w, ~w):"
+ "~n Expected Index: ~p"
+ "~n Received Index: ~p"
+ "~n Expected VBs: ~p"
+ "~n Received VBs: ~p",
+ [Id, Err, Index, Idx, PureVBs, VBs]),
{error,Id,
{"ErrStat: ~w, Idx: ~w, Varbinds: ~w, RequestId: ~w",
[Err,Index,PureVBs,ReqId]},
@@ -1095,15 +1094,15 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) ->
error_status = Err2,
error_index = Index2,
varbinds = VBs} ->
- ?EPRINT1("received unexpected response pdu: ~w, ~w, ~w"
- "~n Expected Error: ~p"
- "~n Received Error: ~p"
- "~n Expected Index: ~p"
- "~n Received Index: ~p"
- "~n Expected VBs: ~p"
- "~n Received VBs: ~p",
- [Type2, Id, ReqId,
- Err, Err2, Index, Index2, PureVBs, VBs]),
+ ?EPRINT("received unexpected response pdu: ~w, ~w, ~w"
+ "~n Expected Error: ~p"
+ "~n Received Error: ~p"
+ "~n Expected Index: ~p"
+ "~n Received Index: ~p"
+ "~n Expected VBs: ~p"
+ "~n Received VBs: ~p",
+ [Type2, Id, ReqId,
+ Err, Err2, Index, Index2, PureVBs, VBs]),
{error,Id,
{"Type: ~w, ErrStat: ~w, Idx: ~w, Varbinds: ~w, RequestId: ~w",
['get-response',Err,Index,PureVBs,ReqId]},
@@ -1111,13 +1110,13 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) ->
[Type2,Err2,Index2,VBs]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive pdu error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive pdu error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end.
expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) ->
- ?PRINT2("await trap pdu ~w with"
+ ?IPRINT("await trap pdu ~w with"
"~n Enterprise: ~p"
"~n Generic: ~p"
"~n Specific: ~p"
@@ -1130,7 +1129,7 @@ expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) ->
generic_trap = Generic,
specific_trap = Specific,
varbinds = VBs} ->
- ?PRINT2("received expected trap pdu - check varbinds"
+ ?IPRINT("received expected trap pdu - check varbinds"
"~n Expected VBs: ~p"
"~n Received VBs: ~p",
[PureVBs, VBs]),
@@ -1140,20 +1139,20 @@ expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) ->
generic_trap = G2,
specific_trap = Spec2,
varbinds = VBs} ->
- ?EPRINT1("received unexpected trap pdu: ~w"
- "~n Expected Enterprise: ~p"
- "~n Received Enterprise: ~p"
- "~n Expected Generic: ~p"
- "~n Received Generic: ~p"
- "~n Expected Specific: ~p"
- "~n Received Specific: ~p"
- "~n Expected VBs: ~p"
- "~n Received VBs: ~p",
- [Id,
- PureE, Ent2,
- Generic, G2,
- Specific, Spec2,
- PureVBs, VBs]),
+ ?EPRINT("received unexpected trap pdu: ~w"
+ "~n Expected Enterprise: ~p"
+ "~n Received Enterprise: ~p"
+ "~n Expected Generic: ~p"
+ "~n Received Generic: ~p"
+ "~n Expected Specific: ~p"
+ "~n Received Specific: ~p"
+ "~n Expected VBs: ~p"
+ "~n Received VBs: ~p",
+ [Id,
+ PureE, Ent2,
+ Generic, G2,
+ Specific, Spec2,
+ PureVBs, VBs]),
{error, Id,
{"Enterprise: ~w, Generic: ~w, Specific: ~w, Varbinds: ~w",
[PureE, Generic, Specific, ExpectedVarbinds]},
@@ -1161,8 +1160,8 @@ expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) ->
[Ent2, G2, Spec2, VBs]}};
{error, Reason} ->
- ?EPRINT1("unexpected receive trap pdu error: ~w"
- "~n ~p", [Id, Reason]),
+ ?EPRINT("unexpected receive trap pdu error: ~w"
+ "~n ~p", [Id, Reason]),
format_reason(Id, Reason)
end.
@@ -1252,15 +1251,11 @@ sizeOf(L) when is_list(L) ->
sizeOf(B) when is_binary(B) ->
size(B).
+d(F) -> d(F, []).
d(F, A) -> d(get(debug), F, A).
d(true, F, A) ->
- print(F, A);
+ ?IPRINT(F, A);
d(_,_F,_A) ->
ok.
-print(F, A) ->
- ?PRINT2("MGR " ++ F, A).
-
-%% formated_timestamp() ->
-%% snmp_test_lib:formated_timestamp().
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index 6608a88c00..738f45a1b0 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2019. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2020. 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.
@@ -102,13 +102,21 @@ init_packet(
Parent,
SnmpMgr, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
DbgOptions, IpFamily) ->
+ %% This causes "verbosity printouts" to print (from the
+ %% specified level) in the modules we "borrow" from the
+ %% agent code (burr,,,).
+ %% With "our" name (mgr_misc).
put(sname, mgr_misc),
init_debug(DbgOptions),
+ %% Make use of the "test name" print "feature"
+ put(tname, "MGR-MISC"),
+ ?IPRINT("starting"),
UdpOpts = [{recbuf,BufSz}, {reuseaddr, true}, IpFamily],
{ok, UdpId} = gen_udp:open(TrapUdp, UdpOpts),
put(msg_id, 1),
init_usm(Version, Dir),
proc_lib:init_ack(Parent, self()),
+ ?IPRINT("started"),
packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, []).
init_debug(Dbg) when is_atom(Dbg) ->
@@ -601,43 +609,51 @@ set_pdu(Msg, RePdu) ->
Msg#message{data = RePdu}.
+%% Disgustingly, we borrow stuff from the agent, including the
+%% local-db. Also, disgustingly, the local-db may actually not
+%% have died yet. But since we actually *need* a clean local-db,
+%% we must make sure its dead before we try to start the new
+%% instance...
init_usm('version-3', Dir) ->
- ?vlog("init_usm -> create (and init) fake \"agent\" table", []),
+ ?IPRINT("init_usm -> create (and init) fake \"agent\" table", []),
ets:new(snmp_agent_table, [set, public, named_table]),
ets:insert(snmp_agent_table, {agent_mib_storage, persistent}),
%% The local-db process may *still* be running (from a previous
%% test case), on the way down, but not yet dead.
- %% Either way, before we start it, make sure its dead and *gone*!
+ %% Either way, before we try to start it, make sure its old instance
+ %% dead and *gone*!
%% How do we do that without getting hung up? Calling the stop
%% function, will not do since it uses Timeout=infinity.
- ?vlog("init_usm -> ensure (old) fake local-db is dead", []),
+ ?IPRINT("init_usm -> ensure (old) fake local-db is dead", []),
ensure_local_db_dead(),
- ?vlog("init_usm -> try start fake local-db", []),
+ ?IPRINT("init_usm -> try start fake local-db", []),
case snmpa_local_db:start_link(normal, Dir,
[{sname, "MGR-LOCAL-DB"},
{verbosity, trace}]) of
{ok, Pid} ->
- ?vlog("started: ~p"
- "~n ~p", [Pid, process_info(Pid)]);
+ ?IPRINT("init_usm -> local-db started: ~p"
+ "~n ~p", [Pid, process_info(Pid)]);
{error, {already_started, Pid}} ->
LDBInfo = process_info(Pid),
- ?vlog("already started: ~p"
- "~n ~p", [Pid, LDBInfo]),
+ ?EPRINT("init_usm -> local-db already started: ~p"
+ "~n ~p", [Pid, LDBInfo]),
?FAIL({still_running, snmpa_local_db, LDBInfo});
{error, Reason} ->
+ ?EPRINT("init_usm -> failed start local-db: "
+ "~n ~p", [Reason]),
?FAIL({failed_starting, snmpa_local_db, Reason})
end,
NameDb = snmpa_agent:db(snmpEngineID),
- ?vlog("init_usm -> try set manager engine-id", []),
+ ?IPRINT("init_usm -> try set manager engine-id"),
R = snmp_generic:variable_set(NameDb, "mgrEngine"),
snmp_verbosity:print(info, info, "init_usm -> engine-id set result: ~p", [R]),
- ?vlog("init_usm -> try set engine boots (framework-mib)", []),
+ ?IPRINT("init_usm -> try set engine boots (framework-mib)"),
snmp_framework_mib:set_engine_boots(1),
- ?vlog("init_usm -> try set engine time (framework-mib)", []),
+ ?IPRINT("init_usm -> try set engine time (framework-mib)"),
snmp_framework_mib:set_engine_time(1),
- ?vlog("init_usm -> try usm (mib) reconfigure", []),
+ ?IPRINT("init_usm -> try usm (mib) reconfigure"),
snmp_user_based_sm_mib:reconfigure(Dir),
- ?vlog("init_usm -> done", []),
+ ?IPRINT("init_usm -> done"),
ok;
init_usm(_Vsn, _Dir) ->
ok.
@@ -659,27 +675,28 @@ ensure_dead(Pid, Timeout) when is_pid(Pid) ->
ok
end;
ensure_dead(_, _) ->
- ?vlog("ensure_dead -> already dead", []),
+ ?IPRINT("ensure_dead -> already dead", []),
ok.
ensure_dead_wait(Pid, MRef, Timeout) ->
receive
{'DOWN', MRef, process, Pid, _Info} ->
- ?vlog("ensure_dead_wait -> died peacefully", []),
+ ?IPRINT("ensure_dead_wait -> died peacefully"),
throw(ok)
after Timeout ->
- ?vlog("ensure_dead_wait -> giving up", []),
+ ?WPRINT("ensure_dead_wait -> giving up"),
ok
end.
ensure_dead_stop(Pid, MRef, Timeout) ->
+ %% Spawn a stop'er process
StopPid = spawn(fun() -> snmpa_local_db:stop() end),
receive
{'DOWN', MRef, process, Pid, _Info} ->
- ?vlog("ensure_dead -> dead (stopped)", []),
+ ?NPRINT("ensure_dead -> dead (stopped)"),
throw(ok)
after Timeout ->
- ?vlog("ensure_dead_stop -> giving up", []),
+ ?WPRINT("ensure_dead_stop -> giving up"),
exit(StopPid, kill),
ok
end.
@@ -688,10 +705,10 @@ ensure_dead_kill(Pid, MRef, Timeout) ->
exit(Pid, kill),
receive
{'DOWN', MRef, process, Pid, _Info} ->
- ?vlog("ensure_dead -> dead (killed)", []),
+ ?NPRINT("ensure_dead -> dead (killed)"),
throw(ok)
after Timeout ->
- ?vlog("ensure_dead_kill -> giving up", []),
+ ?WPRINT("ensure_dead_kill -> giving up"),
ok
end.
@@ -891,10 +908,7 @@ d(F) -> d(F, []).
d(F,A) -> d(get(debug), F, A).
d(true, F, A) ->
- print(F, A);
+ ?IPRINT(F, A);
d(_,_F,_A) ->
ok.
-print(F, A) ->
- ?PRINT2("MGR_PS " ++ F, A).
-
diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
index 0863cf0000..76a1967513 100644
--- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
+++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2014-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2014-2020. 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.
@@ -130,8 +130,11 @@ snmpd_cases() ->
%% -----
%%
-init_per_suite(Config) ->
- case netsnmp_init(Config) of
+init_per_suite(Config0) ->
+ ?IPRINT("init_per_suite -> entry with"
+ "~n Config: ~p", [Config0]),
+
+ case netsnmp_init(Config0) of
{skip, _} = SKIP ->
SKIP;
@@ -142,6 +145,10 @@ init_per_suite(Config) ->
Config2 when is_list(Config2) ->
snmp_test_sys_monitor:start(),
+
+ ?IPRINT("init_per_suite -> end when"
+ "~n Config: ~p", [Config2]),
+
Config2
end
end.
@@ -176,9 +183,15 @@ netsnmp_check(RE) ->
end_per_suite(Config) ->
+ ?IPRINT("end_per_suite -> entry with"
+ "~n Config: ~p", [Config]),
+
snmp_test_sys_monitor:stop(),
- ?LIB:end_per_suite(Config).
+ ?LIB:end_per_suite(Config),
+ ?IPRINT("end_per_suite -> end"),
+
+ Config.
%%
%% -----
@@ -260,17 +273,27 @@ end_per_group(_GroupName, Config) ->
%%
init_per_testcase(_Case, Config) ->
+ ?IPRINT("init_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
snmp_test_global_sys_monitor:reset_events(),
- Dog = ct:timetrap(20000),
+ Dog = ct:timetrap(?SECS(20)),
application:stop(snmp),
application:unload(snmp),
- [{watchdog, Dog} | Config].
+ Config1 = [{watchdog, Dog} | Config],
+
+ ?IPRINT("init_per_testcase -> done when"
+ "~n Config: ~p", [Config1]),
+
+ Config1.
end_per_testcase(_, Config) ->
- ?PRINT2("system events during test: "
+ ?IPRINT("end_per_testcase -> entry with"
+ "~n Config: ~p", [Config]),
+
+ ?IPRINT("system events during test: "
"~n ~p", [snmp_test_global_sys_monitor:events()]),
case application:stop(snmp) of
@@ -285,6 +308,10 @@ end_per_testcase(_, Config) ->
E2 ->
ct:pal("application:unload(snmp) -> ~p", [E2])
end,
+
+ ?IPRINT("end_per_testcase -> done with"
+ "~n Config: ~p", [Config]),
+
Config.
find_executable(Exec, Config) ->
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 1cbd48eafc..e79cbaa336 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -668,6 +668,21 @@
</section>
</section>
+<section><title>Ssh 4.6.9.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed possible hanging in <c>ssh_sftp:stop_channel/1</c>.</p>
+ <p>
+ Own Id: OTP-16507 Aux Id: ERIERL-470 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.6.9.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index aa0fbe376c..862f79ac56 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -1196,6 +1196,41 @@
</desc>
</func>
+<!-- SET_SOCK_OPTS/2 -->
+ <func>
+ <name name="set_sock_opts" arity="2" since=""/>
+ <fsummary>Set tcp socket options on connections</fsummary>
+ <desc>
+ <p>Sets tcp socket options on the tcp-socket below an ssh connection.</p>
+ <p>This function calls the
+ <seealso marker="kernel:inet#setopts/2">inet:setopts/2</seealso>, read that documentation and
+ for <seealso marker="kernel:gen_tcp#type-option">gen_tcp:option()</seealso>.
+ All gen_tcp socket options except <c>active</c>, <c>deliver</c>, <c>mode</c> and <c>packet</c>
+ are allowed. The excluded options are reserved by the SSH application.
+ </p>
+ <warning>
+ <p>This is an extremly dangerous function. You use it on your own risk.</p>
+ <p>Some options are OS and OS version dependent.
+ Do not use it unless you know what effect your option values will have
+ on an TCP stream.</p>
+ <p>Some values may destroy the functionality of the SSH protocol.
+ </p>
+ </warning>
+ </desc>
+ </func>
+
+<!-- GET_SOCK_OPTS/2 -->
+ <func>
+ <name name="get_sock_opts" arity="2" since=""/>
+ <fsummary>Get tcp socket options on connections</fsummary>
+ <desc>
+ <p>Get tcp socket option values of the tcp-socket below an ssh connection.</p>
+ <p>This function calls the
+ <seealso marker="kernel:inet#getopts/2">inet:getopts/2</seealso>, read that documentation.
+ </p>
+ </desc>
+ </func>
+
<!-- DEAMON/1,2,3 -->
<func>
<name since="">daemon(Port | TcpSocket) -> Result</name>
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index c93b796078..355b40eea8 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -35,6 +35,7 @@
channel_info/3,
daemon/1, daemon/2, daemon/3,
daemon_info/1, daemon_info/2,
+ set_sock_opts/2, get_sock_opts/2,
default_algorithms/0,
chk_algos_opts/1,
stop_listener/1, stop_listener/2, stop_listener/3,
@@ -560,6 +561,25 @@ chk_algos_opts(Opts) ->
{error, {non_algo_opts_found,OtherOps}}
end.
+
+%%--------------------------------------------------------------------
+-spec set_sock_opts(ConnectionRef, SocketOptions) ->
+ ok | {error, inet:posix()} when
+ ConnectionRef :: connection_ref(),
+ SocketOptions :: [gen_tcp:option()] .
+%%--------------------------------------------------------------------
+set_sock_opts(ConnectionRef, SocketOptions) ->
+ ssh_connection_handler:set_sock_opts(ConnectionRef, SocketOptions).
+
+%%--------------------------------------------------------------------
+-spec get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ ok | {error, inet:posix()} when
+ ConnectionRef :: connection_ref(),
+ SocketGetOptions :: [gen_tcp:option_name()] .
+%%--------------------------------------------------------------------
+get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ ssh_connection_handler:get_sock_opts(ConnectionRef, SocketGetOptions).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index d200dac33c..e8c0d88e59 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -57,7 +57,8 @@
channel_info/3,
adjust_window/3, close/2,
disconnect/4,
- get_print_info/1
+ get_print_info/1,
+ set_sock_opts/2, get_sock_opts/2
]).
-type connection_ref() :: ssh:connection_ref().
@@ -321,6 +322,31 @@ close(ConnectionHandler, ChannelId) ->
ok
end.
+
+%%--------------------------------------------------------------------
+%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+set_sock_opts(ConnectionRef, SocketOptions) ->
+ try lists:foldr(fun({Name,_Val}, Acc) ->
+ case lists:member(Name, [active, deliver, mode, packet]) of
+ true -> [Name|Acc];
+ false -> Acc
+ end
+ end, [], SocketOptions)
+ of
+ [] ->
+ call(ConnectionRef, {set_sock_opts,SocketOptions});
+ Bad ->
+ {error, {not_allowed,Bad}}
+ catch
+ _:_ ->
+ {error, badarg}
+ end.
+
+%%--------------------------------------------------------------------
+%% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+get_sock_opts(ConnectionRef, SocketGetOptions) ->
+ call(ConnectionRef, {get_sock_opts,SocketGetOptions}).
+
%%====================================================================
%% Test support
%%====================================================================
@@ -1205,6 +1231,20 @@ handle_event({call,From}, {info, ChannelPid}, _, D) ->
end, [], cache(D)),
{keep_state_and_data, [{reply, From, {ok,Result}}]};
+handle_event({call,From}, {set_sock_opts,SocketOptions}, _StateName, D) ->
+ Result = try inet:setopts(D#data.socket, SocketOptions)
+ catch
+ _:_ -> {error, badarg}
+ end,
+ {keep_state_and_data, [{reply,From,Result}]};
+
+handle_event({call,From}, {get_sock_opts,SocketGetOptions}, _StateName, D) ->
+ Result = try inet:getopts(D#data.socket, SocketGetOptions)
+ catch
+ _:_ -> {error, badarg}
+ end,
+ {keep_state_and_data, [{reply,From,Result}]};
+
handle_event({call,From}, stop, _StateName, D0) ->
{Repls,D} = send_replies(ssh_connection:handle_stop(D0#data.connection_state), D0),
{stop_and_reply, normal, [{reply,From,ok}|Repls], D};
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index f8b883c643..386730af17 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -79,7 +79,8 @@ groups() ->
packet_size,
ssh_info_print,
{group, login_bad_pwd_no_retry},
- shell_exit_status
+ shell_exit_status,
+ setopts_getopts
]},
{ssh_renegotiate_SUITE, [?PARALLEL], [rekey0,
@@ -1440,6 +1441,42 @@ shell_exit_status(Config) when is_list(Config) ->
%%----------------------------------------------------------------------------
+setopts_getopts(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = proplists:get_value(data_dir, Config),
+ UserDir = proplists:get_value(priv_dir, Config),
+
+ ShellFun = fun (_User) -> spawn(fun() -> ok end) end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {shell, ShellFun},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ %% Test get_sock_opts
+ {ok,[{active,once},{deliver,term},{mode,binary},{packet,0}]} =
+ ssh:get_sock_opts(ConnectionRef, [active, deliver, mode, packet]),
+
+ %% Test to set forbidden opts
+ {error,{not_allowed,[active,deliver,mode,packet]}} =
+ ssh:set_sock_opts(ConnectionRef, [{active,once},{deliver,term},{mode,binary},{packet,0}]),
+
+ %% Test to set some other opt
+ {ok,[{delay_send,DS0}]} =
+ ssh:get_sock_opts(ConnectionRef, [delay_send]),
+ DS1 = not DS0,
+ ok = ssh:set_sock_opts(ConnectionRef, [{delay_send,DS1}]),
+ {ok,[{delay_send,DS1}]} =
+ ssh:get_sock_opts(ConnectionRef, [delay_send]),
+
+ ssh:stop_daemon(Pid).
+
+%%----------------------------------------------------------------------------
%%% Idle timeout test
rekey0() -> [{timetrap,{seconds,90}}].
rekey1() -> [{timetrap,{seconds,90}}].
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index c45e6bcf9a..63ccaabd74 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -74,5 +74,5 @@
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-3.5","public_key-1.5","kernel-6.0",
+ {runtime_dependencies, ["stdlib-3.5","public_key-@OTP-16528@","kernel-6.0",
"erts-10.0","crypto-4.2", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index e24ea9ac22..b62a1c4546 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -53,7 +53,8 @@
%% Alert and close handling
-export([handle_own_alert/4, handle_alert/3,
handle_normal_shutdown/3,
- handle_trusted_certs_db/1]).
+ handle_trusted_certs_db/1,
+ maybe_invalidate_session/6]).
%% Data handling
-export([read_application_data/2, internal_renegotiation/2]).
@@ -325,6 +326,7 @@ dist_handshake_complete(ConnectionPid, DHandle) ->
prf(ConnectionPid, Secret, Label, Seed, WantedLength) ->
call(ConnectionPid, {prf, Secret, Label, Seed, WantedLength}).
+
%%====================================================================
%% Alert and close handling
%%====================================================================
@@ -442,6 +444,13 @@ handle_alert(#alert{level = ?WARNING} = Alert, StateName,
Alert#alert{role = opposite_role(Role)}),
Connection:next_event(StateName, no_record, State).
+maybe_invalidate_session(undefined,_, _, _, _, _) ->
+ ok;
+maybe_invalidate_session({3, 4},_, _, _, _, _) ->
+ ok;
+maybe_invalidate_session({3, N}, Type, Role, Host, Port, Session) when N < 4 ->
+ maybe_invalidate_session(Type, Role, Host, Port, Session).
+
%%====================================================================
%% Data handling
%%====================================================================
@@ -1496,16 +1505,23 @@ handle_call(_,_,_,_,_) ->
handle_info({ErrorTag, Socket, econnaborted}, StateName,
#state{static_env = #static_env{role = Role,
+ host = Host,
+ port = Port,
socket = Socket,
transport_cb = Transport,
error_tag = ErrorTag,
trackers = Trackers,
protocol_cb = Connection},
- start_or_recv_from = StartFrom
- } = State) when StateName =/= connection ->
+ handshake_env = #handshake_env{renegotiation = Type},
+ connection_env = #connection_env{negotiated_version = Version},
+ session = Session,
+ start_or_recv_from = StartFrom
+ } = State) when StateName =/= connection ->
+
+ maybe_invalidate_session(Version, Type, Role, Host, Port, Session),
Pids = Connection:pids(State),
alert_user(Pids, Transport, Trackers,Socket,
- StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role, StateName, Connection),
+ StartFrom, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role, StateName, Connection),
{stop, {shutdown, normal}, State};
handle_info({ErrorTag, Socket, Reason}, StateName, #state{static_env = #static_env{
@@ -3013,6 +3029,11 @@ log_alert(Level, Role, ProtocolName, StateName, Alert) ->
alert => Alert,
alerter => peer}, Alert#alert.where).
+maybe_invalidate_session({false, first}, server = Role, Host, Port, Session) ->
+ invalidate_session(Role, Host, Port, Session);
+maybe_invalidate_session(_, _, _, _, _) ->
+ ok.
+
invalidate_session(client, Host, Port, Session) ->
ssl_manager:invalidate_session(Host, Port, Session);
invalidate_session(server, _, Port, Session) ->
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 8e53be72ed..3b33af95d0 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -402,6 +402,12 @@ certificate_verify(Signature, PublicKeyInfo, Version,
%%--------------------------------------------------------------------
verify_signature(_Version, _Hash, {_HashAlgo, anon}, _Signature, _) ->
true;
+verify_signature({3, Minor}, Hash, {HashAlgo, rsa_pss_rsae}, Signature, {?rsaEncryption, PubKey, _PubKeyParams})
+ when Minor >= 3 ->
+ public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey,
+ [{rsa_padding, rsa_pkcs1_pss_padding},
+ {rsa_pss_saltlen, -1},
+ {rsa_mgf1_md, HashAlgo}]);
verify_signature({3, Minor}, Hash, {HashAlgo, rsa}, Signature, {?rsaEncryption, PubKey, _PubKeyParams})
when Minor >= 3 ->
public_key:verify({digest, Hash}, HashAlgo, Signature, PubKey);
@@ -2356,6 +2362,20 @@ dec_server_key_params(Len, Keys, Version) ->
<<Params:Len/bytes, Signature/binary>> = Keys,
dec_server_key_signature(Params, Signature, Version).
+dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo),
+ ?UINT16(0)>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>,
+ Scheme = ssl_cipher:signature_scheme(Scheme0),
+ {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme),
+ {Params, {Hash, Sign}, <<>>};
+dec_server_key_signature(Params, <<?BYTE(8), ?BYTE(SignAlgo),
+ ?UINT16(Len), Signature:Len/binary>>, {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ <<?UINT16(Scheme0)>> = <<?BYTE(8), ?BYTE(SignAlgo)>>,
+ Scheme = ssl_cipher:signature_scheme(Scheme0),
+ {Hash, Sign, _} = ssl_cipher:scheme_to_components(Scheme),
+ {Params, {Hash, Sign}, Signature};
dec_server_key_signature(Params, <<?BYTE(HashAlgo), ?BYTE(SignAlgo),
?UINT16(0)>>, {Major, Minor})
when Major == 3, Minor >= 3 ->
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 6c8553d6e0..7257e1dea5 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -734,7 +734,7 @@ hello(internal, #server_hello{} = Hello,
[{next_event, internal, Hello}]}
end;
hello(info, Event, State) ->
- gen_info(Event, ?FUNCTION_NAME, State);
+ handle_info(Event, ?FUNCTION_NAME, State);
hello(Type, Event, State) ->
gen_handshake(?FUNCTION_NAME, Type, Event, State).
@@ -1200,9 +1200,22 @@ handle_info({PassiveTag, Socket}, StateName,
handle_info({CloseTag, Socket}, StateName,
#state{static_env = #static_env{
role = Role,
+ host = Host,
+ port = Port,
socket = Socket,
close_tag = CloseTag},
+ handshake_env = #handshake_env{renegotiation = Type},
connection_env = #connection_env{negotiated_version = Version},
+ session = Session} = State) when StateName =/= connection ->
+ ssl_connection:maybe_invalidate_session(Version, Type, Role, Host, Port, Session),
+ Alert = ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY, transport_closed),
+ ssl_connection:handle_normal_shutdown(Alert#alert{role = Role}, StateName, State),
+ {stop, {shutdown, transport_closed}, State};
+handle_info({CloseTag, Socket}, StateName,
+ #state{static_env = #static_env{
+ role = Role,
+ socket = Socket,
+ close_tag = CloseTag},
socket_options = #socket_options{active = Active},
protocol_buffers = #protocol_buffers{tls_cipher_texts = CTs},
user_data_buffer = {_,BufferSize,_},
@@ -1215,16 +1228,16 @@ handle_info({CloseTag, Socket}, StateName,
case (Active == false) andalso ((CTs =/= []) or (BufferSize =/= 0)) of
false ->
- case Version of
- {1, N} when N >= 1 ->
- ok;
- _ ->
- %% As invalidate_sessions here causes performance issues,
- %% we will conform to the widespread implementation
- %% practice and go aginst the spec
- %%invalidate_session(Role, Host, Port, Session)
- ok
- end,
+ %% As invalidate_sessions here causes performance issues,
+ %% we will conform to the widespread implementation
+ %% practice and go aginst the spec
+ %% case Version of
+ %% {3, N} when N >= 1 ->
+ %% ok;
+ %% _ ->
+ %% invalidate_session(Role, Host, Port, Session)
+ %% ok
+ %% end,
Alert = ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY, transport_closed),
ssl_connection:handle_normal_shutdown(Alert#alert{role = Role}, StateName, State),
{stop, {shutdown, transport_closed}, State};
diff --git a/lib/ssl/src/tls_sender.erl b/lib/ssl/src/tls_sender.erl
index 951d4302e9..790746658e 100644
--- a/lib/ssl/src/tls_sender.erl
+++ b/lib/ssl/src/tls_sender.erl
@@ -540,7 +540,9 @@ key_update_at(Version, #{security_parameters :=
?AES_GCM ->
KeyUpdateAt;
?CHACHA20_POLY1305 ->
- seq_num_wrap
+ seq_num_wrap;
+ ?AES_CCM ->
+ KeyUpdateAt
end;
key_update_at(_, _, KeyUpdateAt) ->
KeyUpdateAt.
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 381793c65d..38594151d9 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -884,7 +884,9 @@ oid_to_enum(?secp384r1) -> 24;
oid_to_enum(?secp521r1) -> 25;
oid_to_enum(?brainpoolP256r1) -> 26;
oid_to_enum(?brainpoolP384r1) -> 27;
-oid_to_enum(?brainpoolP512r1) -> 28.
+oid_to_enum(?brainpoolP512r1) -> 28;
+oid_to_enum(?'id-X25519') -> 29;
+oid_to_enum(?'id-X448') -> 30.
enum_to_oid(1) -> ?sect163k1;
enum_to_oid(2) -> ?sect163r1;
@@ -914,5 +916,7 @@ enum_to_oid(25) -> ?secp521r1;
enum_to_oid(26) -> ?brainpoolP256r1;
enum_to_oid(27) -> ?brainpoolP384r1;
enum_to_oid(28) -> ?brainpoolP512r1;
+enum_to_oid(29) -> ?'id-X25519';
+enum_to_oid(30) -> ?'id-X448';
enum_to_oid(_) ->
undefined.
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 1bd4c2c910..e53f54130f 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -67,6 +67,7 @@ MODULES = \
ssl_engine_SUITE\
ssl_handshake_SUITE \
ssl_key_update_SUITE \
+ openssl_key_update_SUITE \
ssl_npn_hello_SUITE \
ssl_packet_SUITE \
ssl_payload_SUITE \
@@ -74,6 +75,7 @@ MODULES = \
ssl_session_SUITE \
ssl_session_cache_SUITE \
ssl_session_ticket_SUITE \
+ openssl_session_ticket_SUITE \
openssl_session_SUITE \
ssl_ECC_SUITE \
ssl_ECC_openssl_SUITE \
diff --git a/lib/ssl/test/openssl_key_update_SUITE.erl b/lib/ssl/test/openssl_key_update_SUITE.erl
new file mode 100644
index 0000000000..4963f0bb30
--- /dev/null
+++ b/lib/ssl/test/openssl_key_update_SUITE.erl
@@ -0,0 +1,134 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2020-2020. 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%
+%%
+-module(openssl_key_update_SUITE).
+
+%% Callback functions
+-export([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([openssl_client_explicit_key_update/0,
+ openssl_client_explicit_key_update/1,
+ openssl_server_explicit_key_update/0,
+ openssl_server_explicit_key_update/1]).
+
+-include_lib("common_test/include/ct.hrl").
+
+all() ->
+ [{group, 'tlsv1.3'}].
+
+groups() ->
+ [{'tlsv1.3', [], tls_1_3_tests()}].
+
+tls_1_3_tests() ->
+ [openssl_client_explicit_key_update,
+ openssl_server_explicit_key_update].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ case proplists:get_bool(ecdh, proplists:get_value(public_keys, crypto:supports())) of
+ true ->
+ ssl_test_lib:make_ecdsa_cert(Config0);
+ false ->
+ {skip, "Missing EC crypto support"}
+ end
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:init_per_group_openssl(GroupName, Config).
+
+end_per_group(GroupName, Config) ->
+ ssl_test_lib:end_per_group(GroupName, Config).
+
+init_per_testcase(_TestCase, Config) ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 10}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+openssl_client_explicit_key_update() ->
+ [{doc,"Test ssl:update_key/2 between openssl s_client and erlang server."}].
+
+openssl_client_explicit_key_update(Config) ->
+ Data = "123456789012345", %% 15 bytes
+
+ Server = ssl_test_lib:start_server(erlang, [{log_level, debug}], Config),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client(openssl, [{port, Port}], Config),
+ ssl_test_lib:send_recv_result_active(Client, Server, Data),
+
+ %% TODO s_client can hang after sending special commands e.g "k", "K"
+ %% ssl_test_lib:update_keys(Client, write),
+ %% ssl_test_lib:update_keys(Client, read_write),
+ ssl_test_lib:update_keys(Server, write),
+ ssl_test_lib:update_keys(Server, read_write),
+
+ ssl_test_lib:send_recv_result_active(Client, Server, Data),
+
+ ssl_test_lib:close(Client),
+ ssl_test_lib:close(Server).
+
+openssl_server_explicit_key_update() ->
+ [{doc,"Test ssl:update_key/2 between ssl client and s_server."}].
+
+openssl_server_explicit_key_update(Config) ->
+ Data = "123456789012345", %% 15 bytes
+
+ Server = ssl_test_lib:start_server(openssl, [], Config),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client(erlang, [{port, Port},
+ {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']}],Config),
+ ssl_test_lib:send_recv_result_active(Server, Client, Data),
+
+ ssl_test_lib:update_keys(Client, write),
+ ssl_test_lib:update_keys(Client, read_write),
+ ssl_test_lib:update_keys(Server, write),
+ ssl_test_lib:update_keys(Server, read_write),
+
+ ssl_test_lib:send_recv_result_active(Client, Server, Data),
+
+ ssl_test_lib:close(Client),
+ ssl_test_lib:close(Server).
diff --git a/lib/ssl/test/openssl_session_ticket_SUITE.erl b/lib/ssl/test/openssl_session_ticket_SUITE.erl
new file mode 100644
index 0000000000..775048e355
--- /dev/null
+++ b/lib/ssl/test/openssl_session_ticket_SUITE.erl
@@ -0,0 +1,409 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2020. 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%
+%%
+
+-module(openssl_session_ticket_SUITE).
+
+%% Callback functions
+-export([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([openssl_server_basic/0,
+ openssl_server_basic/1,
+ openssl_server_hrr/0,
+ openssl_server_hrr/1,
+ openssl_server_hrr_multiple_tickets/0,
+ openssl_server_hrr_multiple_tickets/1,
+ openssl_client_basic/0,
+ openssl_client_basic/1,
+ openssl_client_hrr/0,
+ openssl_client_hrr/1]).
+
+-include("tls_handshake.hrl").
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 500).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, 'tlsv1.3'}
+ ].
+
+groups() ->
+ [{'tlsv1.3', [], [{group, stateful},
+ {group, stateless},
+ {group, openssl_server}]},
+ {openssl_server, [], [openssl_server_basic,
+ openssl_server_hrr,
+ openssl_server_hrr_multiple_tickets
+ ]},
+ {stateful, [], session_tests()},
+ {stateless, [], session_tests()}].
+
+session_tests() ->
+ [openssl_client_basic,
+ openssl_client_hrr].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+init_per_group(stateful, Config) ->
+ [{server_ticket_mode, stateful} | proplists:delete(server_ticket_mode, Config)];
+init_per_group(stateless, Config) ->
+ [{server_ticket_mode, stateless} | proplists:delete(server_ticket_mode, Config)];
+init_per_group(GroupName, Config) ->
+ ssl_test_lib:init_per_group_openssl(GroupName, Config).
+
+end_per_group(GroupName, Config) ->
+ ssl_test_lib:end_per_group(GroupName, Config).
+
+init_per_testcase(_TestCase, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ ssl:start(),
+ ct:timetrap({seconds, 15}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+openssl_server_basic() ->
+ [{doc,"Test session resumption with session tickets (erlang client - openssl server)"}].
+openssl_server_basic(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Version = 'tlsv1.3',
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CACertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ %% Configure session tickets
+ ClientOpts = [{session_tickets, auto}, {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,"-key", KeyFile, "-CAfile", CACertFile, "-msg", "-debug"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ %% Store ticket from first connection
+ Client0 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [false, no_reply]}},
+ {from, self()}, {options, ClientOpts}]),
+ %% Wait for session ticket
+ ct:sleep(100),
+
+ %% Close previous connection as s_server can only handle one at a time
+ ssl_test_lib:close(Client0),
+
+ %% Use ticket
+ Client1 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [true, no_reply]}},
+ {from, self()},
+ {options, ClientOpts}]),
+ process_flag(trap_exit, false),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client1).
+
+openssl_client_basic() ->
+ [{doc,"Test session resumption with session tickets (openssl client - erlang server)"}].
+openssl_client_basic(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
+ TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
+
+ Data = "Hello world",
+
+ %% Configure session tickets
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
+
+ Server0 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [false]}},
+ {options, ServerOpts}]),
+
+ Version = 'tlsv1.3',
+ Port0 = ssl_test_lib:inet_port(Server0),
+
+ Exe = "openssl",
+ Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
+ ++ ":" ++ integer_to_list(Port0),
+ ssl_test_lib:version_flag(Version),
+ "-sess_out", TicketFile0],
+
+ OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0),
+
+ true = port_command(OpenSslPort0, Data),
+
+ ssl_test_lib:check_result(Server0, ok),
+
+ Server0 ! {listen, {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [true]}}},
+
+ %% Wait for session ticket
+ ct:sleep(100),
+
+ Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
+ ++ ":" ++ integer_to_list(Port0),
+ ssl_test_lib:version_flag(Version),
+ "-sess_in", TicketFile0,
+ "-sess_out", TicketFile1],
+
+ OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1),
+
+ true = port_command(OpenSslPort1, Data),
+
+ ssl_test_lib:check_result(Server0, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server0),
+ ssl_test_lib:close_port(OpenSslPort0),
+ ssl_test_lib:close_port(OpenSslPort1).
+
+openssl_server_hrr() ->
+ [{doc,"Test session resumption with session tickets and hello_retry_request (erlang client - openssl server)"}].
+openssl_server_hrr(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Version = 'tlsv1.3',
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CACertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ %% Configure session tickets
+ ClientOpts = [{session_tickets, auto}, {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups,[secp256r1, x25519]}|ClientOpts0],
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,
+ "-key", KeyFile,
+ "-CAfile", CACertFile,
+ "-groups", "X448:X25519",
+ "-msg", "-debug"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ %% Store ticket from first connection
+ Client0 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [false, no_reply]}},
+ {from, self()}, {options, ClientOpts}]),
+ %% Wait for session ticket
+ ct:sleep(100),
+
+ %% Close previous connection as s_server can only handle one at a time
+ ssl_test_lib:close(Client0),
+
+ %% Use ticket
+ Client1 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [true, no_reply]}},
+ {from, self()},
+ {options, ClientOpts}]),
+ process_flag(trap_exit, false),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client1).
+
+openssl_client_hrr() ->
+ [{doc,"Test session resumption with session tickets and hello_retry_request (openssl client - erlang server)"}].
+openssl_client_hrr(Config) when is_list(Config) ->
+ ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
+ TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
+ ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
+
+ Data = "Hello world",
+
+ %% Configure session tickets
+ ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups,[x448, x25519]}|ServerOpts0],
+
+ Server0 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [false]}},
+ {options, ServerOpts}]),
+
+ Version = 'tlsv1.3',
+ Port0 = ssl_test_lib:inet_port(Server0),
+
+ Exe = "openssl",
+ Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
+ ++ ":" ++ integer_to_list(Port0),
+ ssl_test_lib:version_flag(Version),
+ "-groups", "P-256:X25519",
+ "-sess_out", TicketFile0],
+
+ OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0),
+
+ true = port_command(OpenSslPort0, Data),
+
+ ssl_test_lib:check_result(Server0, ok),
+
+ Server0 ! {listen, {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [true]}}},
+
+ %% Wait for session ticket
+ ct:sleep(100),
+
+ Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
+ ++ ":" ++ integer_to_list(Port0),
+ ssl_test_lib:version_flag(Version),
+ "-groups", "P-256:X25519",
+ "-sess_in", TicketFile0,
+ "-sess_out", TicketFile1],
+
+ OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1),
+
+ true = port_command(OpenSslPort1, Data),
+
+ ssl_test_lib:check_result(Server0, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close(Server0),
+ ssl_test_lib:close_port(OpenSslPort0),
+ ssl_test_lib:close_port(OpenSslPort1).
+
+openssl_server_hrr_multiple_tickets() ->
+ [{doc,"Test session resumption with multiple session tickets and hello_retry_request (erlang client - openssl server)"}].
+openssl_server_hrr_multiple_tickets(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Version = 'tlsv1.3',
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ CACertFile = proplists:get_value(cacertfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ %% Configure session tickets
+ ClientOpts = [{session_tickets, manual}, {log_level, debug},
+ {versions, ['tlsv1.2','tlsv1.3']},
+ {supported_groups,[secp256r1, x25519]}|ClientOpts0],
+
+ Exe = "openssl",
+ Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
+ "-cert", CertFile,
+ "-key", KeyFile,
+ "-CAfile", CACertFile,
+ "-groups", "X448:X25519",
+ "-msg", "-debug"],
+
+ OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
+
+ ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
+
+ %% Store ticket from first connection
+ Client0 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [false, no_reply, {tickets, 2}]}},
+ {from, self()}, {options, ClientOpts}]),
+
+ Tickets0 = ssl_test_lib:check_tickets(Client0),
+
+ ct:pal("Received tickets: ~p~n", [Tickets0]),
+
+ %% Close previous connection as s_server can only handle one at a time
+ ssl_test_lib:close(Client0),
+
+ %% Use tickets
+ Client1 = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib,
+ verify_active_session_resumption,
+ [true, no_reply, no_tickets]}},
+ {from, self()},
+ {options, [{use_ticket, Tickets0}|ClientOpts]}]),
+
+ process_flag(trap_exit, false),
+
+ %% Clean close down! Server needs to be closed first !!
+ ssl_test_lib:close_port(OpensslPort),
+ ssl_test_lib:close(Client1).
diff --git a/lib/ssl/test/ssl_cipher_suite_SUITE.erl b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
index e598d662e9..855533cc3d 100644
--- a/lib/ssl/test/ssl_cipher_suite_SUITE.erl
+++ b/lib/ssl/test/ssl_cipher_suite_SUITE.erl
@@ -32,6 +32,7 @@
%%--------------------------------------------------------------------
all() ->
[
+ {group, 'tlsv1.3'},
{group, 'tlsv1.2'},
{group, 'tlsv1.1'},
{group, 'tlsv1'},
@@ -42,6 +43,7 @@ all() ->
groups() ->
[
+ {'tlsv1.3', [], tls_1_3_kex()},
{'tlsv1.2', [], kex()},
{'tlsv1.1', [], kex()},
{'tlsv1', [], kex()},
@@ -60,6 +62,7 @@ groups() ->
ecdhe_rsa_aes_256_gcm,
ecdhe_rsa_chacha20_poly1305
]},
+ {ecdhe_1_3_rsa_cert, [], tls_1_3_cipher_suites()},
{ecdhe_ecdsa, [],[ecdhe_ecdsa_rc4_128,
ecdhe_ecdsa_3des_ede_cbc,
ecdhe_ecdsa_aes_128_cbc,
@@ -127,6 +130,17 @@ groups() ->
]}
].
+
+tls_1_3_kex() ->
+ [{group, ecdhe_1_3_rsa_cert}].
+
+tls_1_3_cipher_suites() ->
+ [aes_256_gcm_sha384,
+ aes_128_gcm_sha256,
+ chacha20_poly1305_sha256,
+ aes_128_ccm_sha256
+ ].
+
kex() ->
rsa() ++ ecdsa() ++ dss() ++ anonymous().
@@ -186,7 +200,13 @@ end_per_suite(_Config) ->
ssl:stop(),
application:stop(crypto).
-
+init_per_group(GroupName, Config) when GroupName == ecdhe_1_3_rsa_cert ->
+ case proplists:get_bool(ecdh, proplists:get_value(public_keys, crypto:supports())) of
+ true ->
+ init_certs(GroupName, Config);
+ false ->
+ {skip, "Missing EC crypto support"}
+ end;
init_per_group(GroupName, Config) when GroupName == ecdh_anon;
GroupName == ecdhe_rsa;
GroupName == ecdhe_psk ->
@@ -318,6 +338,53 @@ init_per_testcase(TestCase, Config) when TestCase == psk_aes_256_ccm_8;
_ ->
{skip, "Missing AES_256_CCM crypto support"}
end;
+init_per_testcase(aes_256_gcm_sha384, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_256_gcm, SupCiphers)) andalso
+ (lists:member(sha384, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_256_GCM_SHA384 crypto support"}
+ end;
+init_per_testcase(aes_128_gcm_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_256_gcm, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_128_GCM_SHA256 crypto support"}
+ end;
+init_per_testcase(chacha20_poly1305_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(chacha20_poly1305, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs))
+ of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing chacha20_poly1305_sha256 crypto support"}
+ end;
+init_per_testcase(aes_128_ccm_sha256, Config) ->
+ SupCiphers = proplists:get_value(ciphers, crypto:supports()),
+ SupHashs = proplists:get_value(hashs, crypto:supports()),
+ case (lists:member(aes_128_ccm, SupCiphers)) andalso
+ (lists:member(sha256, SupHashs)) of
+ true ->
+ ct:timetrap({seconds, 5}),
+ Config;
+ _ ->
+ {skip, "Missing AES_128_CCM_SHA256 crypto support"}
+ end;
init_per_testcase(TestCase, Config) ->
Cipher = ssl_test_lib:test_cipher(TestCase, Config),
SupCiphers = proplists:get_value(ciphers, crypto:supports()),
@@ -335,7 +402,6 @@ end_per_testcase(_TestCase, Config) ->
%%--------------------------------------------------------------------
%% Initializtion ------------------------------------------
%%--------------------------------------------------------------------
-
init_certs(srp_rsa, Config) ->
DefConf = ssl_test_lib:default_cert_chain_conf(),
CertChainConf = ssl_test_lib:gen_conf(rsa, rsa, DefConf, DefConf),
@@ -367,6 +433,14 @@ init_certs(rsa, Config) ->
[{tls_config, #{server_config => ServerOpts,
client_config => ClientOpts}} |
proplists:delete(tls_config, Config)];
+init_certs(ecdhe_1_3_rsa_cert, Config) ->
+ ClientExt = x509_test:extensions([{key_usage, [digitalSignature]}]),
+ {ClientOpts, ServerOpts} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],[],[{extensions, ClientExt}]]}],
+ Config, "_peer_rsa_digitalsign"),
+ [{tls_config, #{server_config => ServerOpts,
+ client_config => ClientOpts}} |
+ proplists:delete(tls_config, Config)];
init_certs(dhe_dss, Config) ->
DefConf = ssl_test_lib:default_cert_chain_conf(),
CertChainConf = ssl_test_lib:gen_conf(dsa, dsa, DefConf, DefConf),
@@ -427,6 +501,22 @@ init_certs(_GroupName, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
+aes_256_gcm_sha384(Config) when is_list(Config)->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_256_GCM_SHA384"), Version, Config).
+
+aes_128_gcm_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_128_GCM_SHA256"), Version, Config).
+
+chacha20_poly1305_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_CHACHA20_POLY1305_SHA256"), Version, Config).
+
+aes_128_ccm_sha256(Config) when is_list(Config) ->
+ Version = ssl_test_lib:protocol_version(Config),
+ cipher_suite_test(ssl:str_to_suite("TLS_AES_128_CCM_SHA256"), Version, Config).
+
%%--------------------------------------------------------------------
%% SRP --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -775,3 +865,4 @@ test_ciphers(Kex, Cipher, Version) ->
(_) -> false
end}]).
+
diff --git a/lib/ssl/test/ssl_key_update_SUITE.erl b/lib/ssl/test/ssl_key_update_SUITE.erl
index 32cbe0a5a1..2816f1a39e 100644
--- a/lib/ssl/test/ssl_key_update_SUITE.erl
+++ b/lib/ssl/test/ssl_key_update_SUITE.erl
@@ -19,7 +19,21 @@
%%
-module(ssl_key_update_SUITE).
--compile(export_all).
+%% Callback functions
+-export([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([key_update_at/0,
+ key_update_at/1,
+ explicit_key_update/0,
+ explicit_key_update/1]).
-include_lib("common_test/include/ct.hrl").
@@ -30,10 +44,8 @@ groups() ->
[{'tlsv1.3', [], tls_1_3_tests()}].
tls_1_3_tests() ->
- [ssl_client_ssl_server_key_update_at,
- ssl_client_ssl_server_explicit_key_update,
- openssl_client_ssl_server_explicit_key_update,
- ssl_client_openssl_server_explicit_key_update].
+ [key_update_at,
+ explicit_key_update].
init_per_suite(Config0) ->
catch crypto:stop(),
@@ -56,28 +68,10 @@ end_per_suite(_Config) ->
application:stop(crypto).
init_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- case ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- [{client_type, erlang},
- {server_type, erlang}, {version, GroupName}
- | ssl_test_lib:init_tls_version(GroupName, Config)];
- false ->
- {skip, "Missing crypto support"}
- end;
- _ ->
- ssl:start(),
- Config
- end.
+ ssl_test_lib:init_per_group(GroupName, Config).
end_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- ssl_test_lib:clean_tls_version(Config);
- false ->
- Config
- end.
+ ssl_test_lib:end_per_group(GroupName, Config).
init_per_testcase(_TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
@@ -92,10 +86,10 @@ end_per_testcase(_TestCase, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-ssl_client_ssl_server_key_update_at() ->
+key_update_at() ->
[{doc,"Test option 'key_update_at' between erlang client and erlang server."}].
-ssl_client_ssl_server_key_update_at(Config) ->
+key_update_at(Config) ->
%% {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
Data = "123456789012345", %% 15 bytes
@@ -117,10 +111,10 @@ ssl_client_ssl_server_key_update_at(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-ssl_client_ssl_server_explicit_key_update() ->
+explicit_key_update() ->
[{doc,"Test ssl:update_key/2 between erlang client and erlang server."}].
-ssl_client_ssl_server_explicit_key_update(Config) ->
+explicit_key_update(Config) ->
Data = "123456789012345", %% 15 bytes
Server = ssl_test_lib:start_server(erlang, [{log_level, debug}], Config),
@@ -140,50 +134,3 @@ ssl_client_ssl_server_explicit_key_update(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-
-openssl_client_ssl_server_explicit_key_update() ->
- [{doc,"Test ssl:update_key/2 between openssl s_client and erlang server."}].
-
-openssl_client_ssl_server_explicit_key_update(Config) ->
- Data = "123456789012345", %% 15 bytes
-
- Server = ssl_test_lib:start_server(erlang, [{log_level, debug}], Config),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client(openssl, [{port, Port}], Config),
- ssl_test_lib:send_recv_result_active(Client, Server, Data),
-
- %% TODO s_client can hang after sending special commands e.g "k", "K"
- %% ssl_test_lib:update_keys(Client, write),
- %% ssl_test_lib:update_keys(Client, read_write),
- ssl_test_lib:update_keys(Server, write),
- ssl_test_lib:update_keys(Server, read_write),
-
- ssl_test_lib:send_recv_result_active(Client, Server, Data),
-
- ssl_test_lib:close(Client),
- ssl_test_lib:close(Server).
-
-ssl_client_openssl_server_explicit_key_update() ->
- [{doc,"Test ssl:update_key/2 between ssl client and s_server."}].
-
-ssl_client_openssl_server_explicit_key_update(Config) ->
- Data = "123456789012345", %% 15 bytes
-
- Server = ssl_test_lib:start_server(openssl, [], Config),
- Port = ssl_test_lib:inet_port(Server),
-
- Client = ssl_test_lib:start_client(erlang, [{port, Port},
- {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']}],Config),
- ssl_test_lib:send_recv_result_active(Server, Client, Data),
-
- ssl_test_lib:update_keys(Client, write),
- ssl_test_lib:update_keys(Client, read_write),
- ssl_test_lib:update_keys(Server, write),
- ssl_test_lib:update_keys(Server, read_write),
-
- ssl_test_lib:send_recv_result_active(Client, Server, Data),
-
- ssl_test_lib:close(Client),
- ssl_test_lib:close(Server).
diff --git a/lib/ssl/test/ssl_session_SUITE.erl b/lib/ssl/test/ssl_session_SUITE.erl
index aa79698a72..f8dd633ed4 100644
--- a/lib/ssl/test/ssl_session_SUITE.erl
+++ b/lib/ssl/test/ssl_session_SUITE.erl
@@ -25,6 +25,7 @@
-compile(export_all).
-include("tls_handshake.hrl").
+-include("ssl_record.hrl").
-include_lib("common_test/include/ct.hrl").
-include_lib("public_key/include/public_key.hrl").
@@ -48,11 +49,11 @@ all() ->
groups() ->
[{'dtlsv1.2', [], session_tests()},
{'dtlsv1', [], session_tests()},
- {'tlsv1.3', [], session_tests()},
- {'tlsv1.2', [], session_tests()},
- {'tlsv1.1', [], session_tests()},
- {'tlsv1', [], session_tests()},
- {'sslv3', [], session_tests()}
+ {'tlsv1.3', [], session_tests() ++ tls_session_tests()},
+ {'tlsv1.2', [], session_tests() ++ tls_session_tests()},
+ {'tlsv1.1', [], session_tests() ++ tls_session_tests()},
+ {'tlsv1', [], session_tests() ++ tls_session_tests()},
+ {'sslv3', [], session_tests() ++ tls_session_tests()}
].
session_tests() ->
@@ -62,6 +63,8 @@ session_tests() ->
no_reuses_session_server_restart_new_cert,
no_reuses_session_server_restart_new_cert_file].
+tls_session_tests() ->
+ [session_table_stable_size_on_tcp_close].
init_per_suite(Config0) ->
catch crypto:stop(),
@@ -372,6 +375,177 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
ssl_test_lib:close(Server1),
ssl_test_lib:close(Client1).
+session_table_stable_size_on_tcp_close() ->
+ [{doc, "Check that new sessions are cleanup when connection is closed abruptly during first handshake"}].
+
+session_table_stable_size_on_tcp_close(Config) when is_list(Config)->
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = ssl_test_lib:state(Prop),
+ ServerCache = element(3, State),
+
+ N = ets:info(ServerCache, size),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{reuseaddr, true} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ faulty_client(Hostname, Port),
+ check_table_did_not_grow(ServerCache, N).
+
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
+check_table_did_not_grow(ServerCache, N) ->
+ ct:sleep(500),
+ check_table_did_not_grow(ServerCache, N, 10).
+
+check_table_did_not_grow(_, _, 0) ->
+ ct:fail(table_grew);
+check_table_did_not_grow(ServerCache, N, Tries) ->
+ case ets:info(ServerCache, size) of
+ N ->
+ ok;
+ _ ->
+ ct:sleep(500),
+ check_table_did_not_grow(ServerCache, N, Tries -1)
+ end.
+
+faulty_client(Host, Port) ->
+ {ok, Sock} = gen_tcp:connect(Host, Port, [], 10000),
+ Random = crypto:strong_rand_bytes(32),
+ CH = client_hello(Random),
+ CHBin = encode_client_hello(CH, Random),
+ gen_tcp:send(Sock, CHBin),
+ ct:sleep(100),
+ gen_tcp:close(Sock).
+
+
+server(LOpts, Port) ->
+ {ok, LSock} = ssl:listen(Port, LOpts),
+ Pid = spawn_link(?MODULE, accept_loop, [LSock]),
+ ssl:controlling_process(LSock, Pid),
+ Pid.
+
+accept_loop(Sock) ->
+ {ok, CSock} = ssl:transport_accept(Sock),
+ _ = ssl:handshake(CSock),
+ accept_loop(Sock).
+
+
+encode_client_hello(CH, Random) ->
+ HSBin = tls_handshake:encode_handshake(CH, {3,3}),
+ CS = connection_states(Random),
+ {Encoded, _} = tls_record:encode_handshake(HSBin, {3,3}, CS),
+ Encoded.
+
+client_hello(Random) ->
+ CipherSuites = [<<0,255>>, <<"À,">>, <<"À0">>, <<"À$">>, <<"À(">>,
+ <<"À.">>, <<"À2">>, <<"À&">>, <<"À*">>, <<0,159>>,
+ <<0,163>>, <<0,107>>, <<0,106>>, <<"À+">>, <<"À/">>,
+ <<"À#">>, <<"À'">>, <<"À-">>, <<"À1">>, <<"À%">>,
+ <<"À)">>, <<0,158>>, <<0,162>>, <<0,103>>, <<0,64>>,
+ <<"À\n">>, <<192,20>>, <<0,57>>, <<0,56>>, <<192,5>>,
+ <<192,15>>, <<"À\t">>, <<192,19>>, <<0,51>>, <<0,50>>,
+ <<192,4>>, <<192,14>>],
+ Extensions = #{alpn => undefined,
+ ec_point_formats =>
+ {ec_point_formats,
+ [0]},
+ elliptic_curves =>
+ {elliptic_curves,
+ [{1,3,132,0,39},
+ {1,3,132,0,38},
+ {1,3,132,0,35},
+ {1,3,36,3,3,2,
+ 8,1,1,13},
+ {1,3,132,0,36},
+ {1,3,132,0,37},
+ {1,3,36,3,3,2,
+ 8,1,1,11},
+ {1,3,132,0,34},
+ {1,3,132,0,16},
+ {1,3,132,0,17},
+ {1,3,36,3,3,2,
+ 8,1,1,7},
+ {1,3,132,0,10},
+ {1,2,840,
+ 10045,3,1,7},
+ {1,3,132,0,3},
+ {1,3,132,0,26},
+ {1,3,132,0,27},
+ {1,3,132,0,32},
+ {1,3,132,0,33},
+ {1,3,132,0,24},
+ {1,3,132,0,25},
+ {1,3,132,0,31},
+ {1,2,840,
+ 10045,3,1,1},
+ {1,3,132,0,1},
+ {1,3,132,0,2},
+ {1,3,132,0,15},
+ {1,3,132,0,9},
+ {1,3,132,0,8},
+ {1,3,132,0,
+ 30}]},
+ next_protocol_negotiation =>
+ undefined,
+ renegotiation_info =>
+ {renegotiation_info,
+ undefined},
+ signature_algs =>
+ {hash_sign_algos,
+ [{sha512,ecdsa},
+ {sha512,rsa},
+ {sha384,ecdsa},
+ {sha384,rsa},
+ {sha256,ecdsa},
+ {sha256,rsa},
+ {sha224,ecdsa},
+ {sha224,rsa},
+ {sha,ecdsa},
+ {sha,rsa},
+ {sha,dsa}]},
+ sni =>
+ {sni,
+ "localhost"},
+ srp =>
+ undefined},
+
+ #client_hello{client_version = {3,3},
+ random = Random,
+ session_id = crypto:strong_rand_bytes(32),
+ cipher_suites = CipherSuites,
+ compression_methods = [0],
+ extensions = Extensions
+ }.
+
+connection_states(Random) ->
+ #{current_write =>
+ #{beast_mitigation => one_n_minus_one,cipher_state => undefined,
+ client_verify_data => undefined,compression_state => undefined,
+ mac_secret => undefined,secure_renegotiation => undefined,
+ security_parameters =>
+ #security_parameters{
+ cipher_suite = <<0,0>>,
+ connection_end = 1,
+ bulk_cipher_algorithm = 0,
+ cipher_type = 0,
+ iv_size = 0,
+ key_size = 0,
+ key_material_length = 0,
+ expanded_key_material_length = 0,
+ mac_algorithm = 0,
+ prf_algorithm = 0,
+ hash_size = 0,
+ compression_algorithm = 0,
+ master_secret = undefined,
+ resumption_master_secret = undefined,
+ client_random = Random,
+ server_random = undefined,
+ exportable = undefined},
+ sequence_number => 0,server_verify_data => undefined}}.
diff --git a/lib/ssl/test/ssl_session_ticket_SUITE.erl b/lib/ssl/test/ssl_session_ticket_SUITE.erl
index 96b0fb5c2a..3d41b59223 100644
--- a/lib/ssl/test/ssl_session_ticket_SUITE.erl
+++ b/lib/ssl/test/ssl_session_ticket_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2020. 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.
@@ -18,11 +18,27 @@
%% %CopyrightEnd%
%%
-%%
-module(ssl_session_ticket_SUITE).
-%% Note: This directive should only be used in test suites.
--compile(export_all).
+%% Callback functions
+-export([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([basic/0,
+ basic/1,
+ hello_retry_request/0,
+ hello_retry_request/1,
+ multiple_tickets/0,
+ multiple_tickets/1,
+ multiple_tickets_2hash/0,
+ multiple_tickets_2hash/1]).
-include("tls_handshake.hrl").
@@ -40,21 +56,15 @@ all() ->
].
groups() ->
- [{'tlsv1.3', [], [{group, stateful}, {group, stateless}, {group, openssl_server}]},
- {openssl_server, [], [erlang_client_openssl_server_basic,
- erlang_client_openssl_server_hrr,
- erlang_client_openssl_server_hrr_multiple_tickets
- ]},
+ [{'tlsv1.3', [], [{group, stateful}, {group, stateless}]},
{stateful, [], session_tests()},
{stateless, [], session_tests()}].
session_tests() ->
- [erlang_client_erlang_server_basic,
- openssl_client_erlang_server_basic,
- erlang_client_erlang_server_hrr,
- openssl_client_erlang_server_hrr,
- erlang_client_erlang_server_multiple_tickets,
- erlang_client_erlang_server_multiple_tickets_2hash].
+ [basic,
+ hello_retry_request,
+ multiple_tickets,
+ multiple_tickets_2hash].
init_per_suite(Config0) ->
catch crypto:stop(),
@@ -75,27 +85,10 @@ init_per_group(stateful, Config) ->
init_per_group(stateless, Config) ->
[{server_ticket_mode, stateless} | proplists:delete(server_ticket_mode, Config)];
init_per_group(GroupName, Config) ->
- ssl_test_lib:clean_tls_version(Config),
- case ssl_test_lib:is_tls_version(GroupName) andalso ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- ssl_test_lib:init_tls_version(GroupName, Config);
- _ ->
- case ssl_test_lib:sufficient_crypto_support(GroupName) of
- true ->
- ssl:start(),
- Config;
- false ->
- {skip, "Missing crypto support"}
- end
- end.
+ ssl_test_lib:init_per_group(GroupName, Config).
end_per_group(GroupName, Config) ->
- case ssl_test_lib:is_tls_version(GroupName) of
- true ->
- ssl_test_lib:clean_tls_version(Config);
- false ->
- Config
- end.
+ ssl_test_lib:end_per_group(GroupName, Config).
init_per_testcase(_, Config) ->
ssl:stop(),
@@ -111,10 +104,9 @@ end_per_testcase(_TestCase, Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-
-erlang_client_erlang_server_basic() ->
+basic() ->
[{doc,"Test session resumption with session tickets (erlang client - erlang server)"}].
-erlang_client_erlang_server_basic(Config) when is_list(Config) ->
+basic(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -166,127 +158,9 @@ erlang_client_erlang_server_basic(Config) when is_list(Config) ->
ssl_test_lib:close(Server0),
ssl_test_lib:close(Client1).
-
-erlang_client_openssl_server_basic() ->
- [{doc,"Test session resumption with session tickets (erlang client - openssl server)"}].
-erlang_client_openssl_server_basic(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Version = 'tlsv1.3',
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CACertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
-
- %% Configure session tickets
- ClientOpts = [{session_tickets, auto}, {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile,"-key", KeyFile, "-CAfile", CACertFile, "-msg", "-debug"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- %% Store ticket from first connection
- Client0 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [false, no_reply]}},
- {from, self()}, {options, ClientOpts}]),
- %% Wait for session ticket
- ct:sleep(100),
-
- %% Close previous connection as s_server can only handle one at a time
- ssl_test_lib:close(Client0),
-
- %% Use ticket
- Client1 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [true, no_reply]}},
- {from, self()},
- {options, ClientOpts}]),
- process_flag(trap_exit, false),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client1).
-
-
-openssl_client_erlang_server_basic() ->
- [{doc,"Test session resumption with session tickets (openssl client - erlang server)"}].
-openssl_client_erlang_server_basic(Config) when is_list(Config) ->
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
- TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
- ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
-
- Data = "Hello world",
-
- %% Configure session tickets
- ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0],
-
- Server0 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [false]}},
- {options, ServerOpts}]),
-
- Version = 'tlsv1.3',
- Port0 = ssl_test_lib:inet_port(Server0),
-
- Exe = "openssl",
- Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
- ++ ":" ++ integer_to_list(Port0),
- ssl_test_lib:version_flag(Version),
- "-sess_out", TicketFile0],
-
- OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0),
-
- true = port_command(OpenSslPort0, Data),
-
- ssl_test_lib:check_result(Server0, ok),
-
- Server0 ! {listen, {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [true]}}},
-
- %% Wait for session ticket
- ct:sleep(100),
-
- Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
- ++ ":" ++ integer_to_list(Port0),
- ssl_test_lib:version_flag(Version),
- "-sess_in", TicketFile0,
- "-sess_out", TicketFile1],
-
- OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1),
-
- true = port_command(OpenSslPort1, Data),
-
- ssl_test_lib:check_result(Server0, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server0),
- ssl_test_lib:close_port(OpenSslPort0),
- ssl_test_lib:close_port(OpenSslPort1).
-
-
-erlang_client_erlang_server_hrr() ->
+hello_retry_request() ->
[{doc,"Test session resumption with session tickets and hello_retry_request (erlang client - erlang server)"}].
-erlang_client_erlang_server_hrr(Config) when is_list(Config) ->
+hello_retry_request(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -340,135 +214,9 @@ erlang_client_erlang_server_hrr(Config) when is_list(Config) ->
ssl_test_lib:close(Server0),
ssl_test_lib:close(Client1).
-
-erlang_client_openssl_server_hrr() ->
- [{doc,"Test session resumption with session tickets and hello_retry_request (erlang client - openssl server)"}].
-erlang_client_openssl_server_hrr(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Version = 'tlsv1.3',
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CACertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
-
- %% Configure session tickets
- ClientOpts = [{session_tickets, auto}, {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups,[secp256r1, x25519]}|ClientOpts0],
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile,
- "-key", KeyFile,
- "-CAfile", CACertFile,
- "-groups", "X448:X25519",
- "-msg", "-debug"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- %% Store ticket from first connection
- Client0 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [false, no_reply]}},
- {from, self()}, {options, ClientOpts}]),
- %% Wait for session ticket
- ct:sleep(100),
-
- %% Close previous connection as s_server can only handle one at a time
- ssl_test_lib:close(Client0),
-
- %% Use ticket
- Client1 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [true, no_reply]}},
- {from, self()},
- {options, ClientOpts}]),
- process_flag(trap_exit, false),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client1).
-
-
-openssl_client_erlang_server_hrr() ->
- [{doc,"Test session resumption with session tickets and hello_retry_request (openssl client - erlang server)"}].
-openssl_client_erlang_server_hrr(Config) when is_list(Config) ->
- ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]),
- TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]),
- ServerTicketMode = proplists:get_value(server_ticket_mode, Config),
-
- Data = "Hello world",
-
- %% Configure session tickets
- ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups,[x448, x25519]}|ServerOpts0],
-
- Server0 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [false]}},
- {options, ServerOpts}]),
-
- Version = 'tlsv1.3',
- Port0 = ssl_test_lib:inet_port(Server0),
-
- Exe = "openssl",
- Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
- ++ ":" ++ integer_to_list(Port0),
- ssl_test_lib:version_flag(Version),
- "-groups", "P-256:X25519",
- "-sess_out", TicketFile0],
-
- OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0),
-
- true = port_command(OpenSslPort0, Data),
-
- ssl_test_lib:check_result(Server0, ok),
-
- Server0 ! {listen, {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [true]}}},
-
- %% Wait for session ticket
- ct:sleep(100),
-
- Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname)
- ++ ":" ++ integer_to_list(Port0),
- ssl_test_lib:version_flag(Version),
- "-groups", "P-256:X25519",
- "-sess_in", TicketFile0,
- "-sess_out", TicketFile1],
-
- OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1),
-
- true = port_command(OpenSslPort1, Data),
-
- ssl_test_lib:check_result(Server0, ok),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close(Server0),
- ssl_test_lib:close_port(OpenSslPort0),
- ssl_test_lib:close_port(OpenSslPort1).
-
-
-erlang_client_erlang_server_multiple_tickets() ->
+multiple_tickets() ->
[{doc,"Test session resumption with multiple session tickets (erlang client - erlang server)"}].
-erlang_client_erlang_server_multiple_tickets(Config) when is_list(Config) ->
+multiple_tickets(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -524,72 +272,9 @@ erlang_client_erlang_server_multiple_tickets(Config) when is_list(Config) ->
ssl_test_lib:close(Server0),
ssl_test_lib:close(Client1).
-
-erlang_client_openssl_server_hrr_multiple_tickets() ->
- [{doc,"Test session resumption with multiple session tickets and hello_retry_request (erlang client - openssl server)"}].
-erlang_client_openssl_server_hrr_multiple_tickets(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
- ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
- {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
-
- Version = 'tlsv1.3',
- Port = ssl_test_lib:inet_port(node()),
- CertFile = proplists:get_value(certfile, ServerOpts),
- CACertFile = proplists:get_value(cacertfile, ServerOpts),
- KeyFile = proplists:get_value(keyfile, ServerOpts),
-
- %% Configure session tickets
- ClientOpts = [{session_tickets, manual}, {log_level, debug},
- {versions, ['tlsv1.2','tlsv1.3']},
- {supported_groups,[secp256r1, x25519]}|ClientOpts0],
-
- Exe = "openssl",
- Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version),
- "-cert", CertFile,
- "-key", KeyFile,
- "-CAfile", CACertFile,
- "-groups", "X448:X25519",
- "-msg", "-debug"],
-
- OpensslPort = ssl_test_lib:portable_open_port(Exe, Args),
-
- ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)),
-
- %% Store ticket from first connection
- Client0 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [false, no_reply, {tickets, 2}]}},
- {from, self()}, {options, ClientOpts}]),
-
- Tickets0 = ssl_test_lib:check_tickets(Client0),
-
- ct:pal("Received tickets: ~p~n", [Tickets0]),
-
- %% Close previous connection as s_server can only handle one at a time
- ssl_test_lib:close(Client0),
-
- %% Use tickets
- Client1 = ssl_test_lib:start_client([{node, ClientNode},
- {port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib,
- verify_active_session_resumption,
- [true, no_reply, no_tickets]}},
- {from, self()},
- {options, [{use_ticket, Tickets0}|ClientOpts]}]),
-
- process_flag(trap_exit, false),
-
- %% Clean close down! Server needs to be closed first !!
- ssl_test_lib:close_port(OpensslPort),
- ssl_test_lib:close(Client1).
-
-
-erlang_client_erlang_server_multiple_tickets_2hash() ->
+multiple_tickets_2hash() ->
[{doc,"Test session resumption with multiple session tickets with 2 different hash algorithms (erlang client - erlang server)"}].
-erlang_client_erlang_server_multiple_tickets_2hash(Config) when is_list(Config) ->
+multiple_tickets_2hash(Config) when is_list(Config) ->
ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config),
ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index e7f5a59235..206c4c8b32 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -76,6 +76,43 @@ get_client_opts(Config) ->
COpts = proplists:get_value(client_ecdsa_opts, Config),
ssl_test_lib:ssl_options(COpts, Config).
+%% Default callback functions
+init_per_group(GroupName, Config) ->
+ clean_tls_version(Config),
+ case is_tls_version(GroupName) andalso sufficient_crypto_support(GroupName) of
+ true ->
+ init_tls_version(GroupName, Config);
+ _ ->
+ case sufficient_crypto_support(GroupName) of
+ true ->
+ ssl:start(),
+ Config;
+ false ->
+ {skip, "Missing crypto support"}
+ end
+ end.
+
+init_per_group_openssl(GroupName, Config) ->
+ case is_tls_version(GroupName) of
+ true ->
+ case check_sane_openssl_version(GroupName) of
+ true ->
+ [{version, GroupName}|init_tls_version(GroupName, Config)];
+ false ->
+ {skip, "Missing openssl support"}
+ end;
+ _ ->
+ ssl:start(),
+ Config
+ end.
+
+end_per_group(GroupName, Config) ->
+ case is_tls_version(GroupName) of
+ true ->
+ clean_tls_version(Config);
+ false ->
+ Config
+ end.
%%====================================================================
%% Internal functions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index 39fc565ff8..c12ad2deef 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -101,10 +101,10 @@
</item>
<item>
In OTP 22.3 the possibility to change the callback module
- with action
- <seealso marker="#type-action">
- <c>change_callback_module</c>
- </seealso>
+ with actions
+ <seealso marker="#type-action"><c>change_callback_module</c></seealso>,
+ <seealso marker="#type-action"><c>push_callback_module</c></seealso> and
+ <seealso marker="#type-action"><c>pop_callback_module</c></seealso>,
was added.
</item>
</list>
@@ -750,8 +750,10 @@ handle_event(_, _, State, Data) ->
<seealso marker="#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
is called when starting the <c>gen_statem</c>,
after code change
- and after changing the callback module with action
- <seealso marker="#type-action"><c>change_callback_module</c></seealso>.
+ and after changing the callback module with any of the actions
+ <seealso marker="#type-action"><c>change_callback_module</c></seealso>,
+ <seealso marker="#type-action"><c>push_callback_module</c></seealso> or
+ <seealso marker="#type-action"><c>pop_callback_module</c></seealso>.
The result is cached for subsequent calls to
<seealso marker="#state callback">state callbacks</seealso>.
</p>
@@ -1191,7 +1193,9 @@ handle_event(_, _, State, Data) ->
an event inserted this way from any external event.
</p>
</item>
- <tag><c>change_callback_module</c></tag>
+ <tag>
+ <c>change_callback_module</c>
+ </tag>
<item>
<p>
Changes the callback module to
@@ -1231,6 +1235,32 @@ handle_event(_, _, State, Data) ->
from the old module.
</p>
</item>
+ <tag>
+ <c>push_callback_module</c><br />
+ </tag>
+ <item>
+ <p>
+ Pushes the current callback module
+ to the top of an internal stack of callback modules
+ and changes the callback module to
+ <c><anno>NewModule</anno></c>.
+ Otherwise like
+ <c>{change_callback_module, NewModule}</c>
+ above.
+ </p>
+ </item>
+ <tag>
+ <c>pop_callback_module</c>
+ </tag>
+ <item>
+ Pops the top module from the internal stack of
+ callback modules and changes the callback module
+ to be the popped module.
+ If the stack is empty the server fails.
+ Otherwise like
+ <c>{change_callback_module, NewModule}</c>
+ above.
+ </item>
</taglist>
</desc>
</datatype>
@@ -2017,8 +2047,10 @@ handle_event(_, _, State, Data) ->
returns.
A change of the callback module happens when a
<seealso marker="#state callback"><em>state callback</em></seealso>
- returns the action
- <seealso marker="#type-action"><c>change_callback_module</c></seealso>.
+ returns any of the actions
+ <seealso marker="#type-action"><c>change_callback_module</c></seealso>,
+ <seealso marker="#type-action"><c>push_callback_module</c></seealso> or
+ <seealso marker="#type-action"><c>pop_callback_module</c></seealso>.
</p>
<p>
The <c>CallbackMode</c> is either just
@@ -2125,6 +2157,37 @@ handle_event(_, _, State, Data) ->
will not be honoured,
most probably causing a server crash.
</p>
+ <p>
+ If the server changes callback module using any of the actions
+ <seealso marker="#type-action"><c>change_callback_module</c></seealso>,
+ <seealso marker="#type-action"><c>push_callback_module</c></seealso> or
+ <seealso marker="#type-action"><c>pop_callback_module</c></seealso>,
+ be aware that it is always the current callback module that
+ will get this callback call. That the current callback module
+ handles the current state and data update should be no surprise,
+ but it must be able to handle even parts of
+ the state and data that it is not familiar with,
+ somehow.
+ </p>
+ <p>
+ In the supervisor
+ <seealso marker="doc/design_principles:sup_princ#child-specification">child specification</seealso>
+ there is a list of modules which is recommended to contain
+ only the callback module.
+ For a <c>gen_statem</c> with multiple callback modules
+ there is no real need to list all of them,
+ it may not even be possible since the list could change
+ after code upgrade.
+ If this list would contain only the start callback module,
+ as recommended, what is important is to upgrade <em>that</em> module
+ whenever a <em>synchronized code replacement</em> is done.
+ Then the release handler concludes that an upgrade
+ that upgrades <em>that</em> module needs to suspend,
+ code change, and resume any server whose child specification
+ declares that it is using <em>that</em> module.
+ And again; the <em>current</em> callback module will get the
+ <c>Module:code_change/4</c> call.
+ </p>
</desc>
</func>
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index 3a8fe2211b..ef6d1882e6 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2019. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2020. 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.
@@ -369,7 +369,7 @@ rfc3339_to_system_time(DateTimeString, Options) ->
IsFractionChar = fun(C) -> C >= $0 andalso C =< $9 orelse C =:= $. end,
{FractionStr, UtcOffset} = lists:splitwith(IsFractionChar, TimeStr),
Time = datetime_to_system_time(DateTime),
- Secs = Time - offset_adjustment(Time, second, UtcOffset),
+ Secs = Time - offset_string_adjustment(Time, second, UtcOffset),
check(DateTimeString, Options, Secs),
ScaledEpoch = erlang:convert_time_unit(Secs, second, Unit),
ScaledEpoch + copy_sign(fraction(Unit, FractionStr), ScaledEpoch).
@@ -689,13 +689,13 @@ offset(OffsetOption, Secs0) when OffsetOption =:= "";
offset(OffsetOption, _Secs) ->
OffsetOption.
+offset_adjustment(Time, Unit, "") ->
+ local_offset(Time, Unit);
offset_adjustment(Time, Unit, OffsetString) when is_list(OffsetString) ->
offset_string_adjustment(Time, Unit, OffsetString);
offset_adjustment(_Time, Unit, Offset) when is_integer(Offset) ->
erlang:convert_time_unit(Offset, Unit, second).
-offset_string_adjustment(Time, Unit, "") ->
- local_offset(Time, Unit);
offset_string_adjustment(_Time, _Unit, "Z") ->
0;
offset_string_adjustment(_Time, _Unit, "z") ->
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 885c6ef031..2cf30e10ec 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -150,6 +150,8 @@
EventType :: event_type(),
EventContent :: term()} |
{'change_callback_module', NewModule :: module()} |
+ {'push_callback_module', NewModule :: module()} |
+ 'pop_callback_module' |
enter_action().
-type enter_action() ::
'hibernate' | % Set the hibernate option
@@ -423,7 +425,7 @@ timeout_event_type(Type) ->
{callback_mode = undefined :: callback_mode() | undefined,
state_enter = false :: boolean(),
parent :: pid(),
- module :: atom(),
+ modules :: [module()],
name :: atom() | pid(),
hibernate_after = infinity :: timeout()
}).
@@ -691,7 +693,7 @@ enter(
P =
#params{
parent = Parent,
- module = Module,
+ modules = [Module],
name = Name,
hibernate_after = HibernateAfterTimeout},
S = #state{state_data = {State,Data}},
@@ -728,7 +730,7 @@ init_it(Starter, Parent, ServerRef, Module, Args, Opts) ->
proc_lib:init_ack(Starter, {error,Reason}),
error_info(
Class, Reason, Stacktrace, Debug,
- #params{parent = Parent, name = Name, module = Module},
+ #params{parent = Parent, name = Name, modules = [Module]},
#state{}, []),
erlang:raise(Class, Reason, Stacktrace)
end.
@@ -764,7 +766,7 @@ init_result(
proc_lib:init_ack(Starter, {error,Error}),
error_info(
error, Error, ?STACKTRACE(), Debug,
- #params{parent = Parent, name = Name, module = Module},
+ #params{parent = Parent, name = Name, modules = [Module]},
#state{}, []),
exit(Error)
end.
@@ -785,7 +787,7 @@ system_terminate(Reason, Parent, Debug, {P,S}) ->
update_parent(P, Parent), Debug, S, []).
system_code_change(
- {#params{module = Module} = P,
+ {#params{modules = [Module | _]} = P,
#state{state_data = {State,Data}} = S},
_Mod, OldVsn, Extra) ->
case
@@ -816,7 +818,7 @@ system_replace_state(
format_status(
Opt,
[PDict,SysState,Parent,Debug,
- {#params{name = Name} = P,
+ {#params{name = Name, modules = Modules} = P,
#state{postponed = Postponed, timers = Timers} = S}]) ->
Header = gen:format_status_header("Status for state machine", Name),
Log = sys:get_log(Debug),
@@ -824,6 +826,7 @@ format_status(
{data,
[{"Status",SysState},
{"Parent",Parent},
+ {"Modules",Modules},
{"Time-outs",list_timeouts(Timers)},
{"Logged Events",Log},
{"Postponed",Postponed}]} |
@@ -1079,7 +1082,7 @@ loop_state_callback(P, Debug, S, Q, State_Data, CallbackEvent) ->
StateCall, CallbackEvent).
%%
loop_state_callback(
- #params{callback_mode = undefined, module = Module} = P,
+ #params{callback_mode = undefined, modules = [Module | _]} = P,
Debug, S, Q, State_Data,
NextEventsR, Hibernate, TimeoutsR, Postpone,
StateCall, CallbackEvent) ->
@@ -1105,7 +1108,7 @@ loop_state_callback(
Class, Reason, Stacktrace, P, Debug, S, Q)
end;
loop_state_callback(
- #params{callback_mode = CallbackMode, module = Module} = P,
+ #params{callback_mode = CallbackMode, modules = [Module | _]} = P,
Debug, S, Q, {State,Data} = State_Data,
NextEventsR, Hibernate, TimeoutsR, Postpone,
StateCall, {Type,Content}) ->
@@ -1446,13 +1449,21 @@ loop_actions_list(
NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions, Type, Content);
%%
- {change_callback_module, NewModule}
- when is_atom(NewModule) ->
+ {Tag, NewModule}
+ when Tag =:= change_callback_module, is_atom(NewModule);
+ Tag =:= push_callback_module, is_atom(NewModule) ->
if
StateCall ->
+ NewModules =
+ case Tag of
+ change_callback_module ->
+ [NewModule | tl(P#params.modules)];
+ push_callback_module ->
+ [NewModule | P#params.modules]
+ end,
P_1 =
P#params{
- callback_mode = undefined, module = NewModule},
+ callback_mode = undefined, modules = NewModules},
loop_actions_list(
P_1, Debug, S, Q, NextState_NewData,
NextEventsR, Hibernate, TimeoutsR, Postpone,
@@ -1467,91 +1478,40 @@ loop_actions_list(
hibernate = Hibernate},
Q)
end;
- %%
- Timeout ->
- loop_actions_timeout(
- P, Debug, S, Q, NextState_NewData,
- NextEventsR, Hibernate, TimeoutsR, Postpone,
- CallEnter, StateCall, Actions, Timeout)
- end.
-
-%% Process a reply action
-%%
-loop_actions_reply(
- P, Debug, S, Q, NextState_NewData,
- NextEventsR, Hibernate, TimeoutsR, Postpone,
- CallEnter, StateCall, Actions,
- From, Reply) ->
- %%
- case from(From) of
- true ->
- %% No need for a separate ?not_sys_debug clause here
- %% since the external call to erlang:'!'/2 in reply/2
- %% will cause swap out of all live registers anyway
- reply(From, Reply),
- Debug_1 = ?sys_debug(Debug, P#params.name, {out,Reply,From}),
- loop_actions_list(
- P, Debug_1, S, Q, NextState_NewData,
- NextEventsR, Hibernate, TimeoutsR, Postpone,
- CallEnter, StateCall, Actions);
- false ->
- terminate(
- error,
- {bad_action_from_state_function,{reply,From,Reply}},
- ?STACKTRACE(), P, Debug,
- S#state{
- state_data = NextState_NewData,
- hibernate = Hibernate},
- Q)
- end.
-
-%% Process a next_event action
-%%
-loop_actions_next_event(
- P, Debug, S, Q, NextState_NewData,
- NextEventsR, Hibernate, TimeoutsR, Postpone,
- CallEnter, StateCall, Actions, Type, Content) ->
- case event_type(Type) of
- true when StateCall ->
- NextEvent = {Type,Content},
- case Debug of
- ?not_sys_debug ->
+ pop_callback_module when tl(P#params.modules) =/= [] ->
+ if
+ StateCall ->
+ NewModules = tl(P#params.modules),
+ P_1 =
+ P#params{
+ callback_mode = undefined,
+ modules = NewModules},
loop_actions_list(
- P, Debug, S, Q, NextState_NewData,
- [NextEvent|NextEventsR],
- Hibernate, TimeoutsR, Postpone,
+ P_1, Debug, S, Q, NextState_NewData,
+ NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions);
- _ ->
- Name = P#params.name,
- {State,_Data} = S#state.state_data,
- Debug_1 =
- sys_debug(Debug, Name, {in,{Type,Content},State}),
- loop_actions_list(
- P, Debug_1, S, Q, NextState_NewData,
- [NextEvent|NextEventsR],
- Hibernate, TimeoutsR, Postpone,
- CallEnter, StateCall, Actions)
- end;
+ true ->
+ terminate(
+ error,
+ {bad_state_enter_action_from_state_function,Action},
+ ?STACKTRACE(), P, Debug,
+ S#state{
+ state_data = NextState_NewData,
+ hibernate = Hibernate},
+ Q)
+ end;
+ %%
_ ->
- terminate(
- error,
- {if
- StateCall ->
- bad_action_from_state_function;
- true ->
- bad_state_enter_action_from_state_function
- end,
- {next_event,Type,Content}},
- ?STACKTRACE(), P, Debug,
- S#state{
- state_data = NextState_NewData,
- hibernate = Hibernate},
- Q)
+ loop_actions_list(
+ P, Debug, S, Q, NextState_NewData,
+ NextEventsR, Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions, Action)
end.
-%% Process a timeout action, or also any unrecognized action
+%% Process all other actions, i.e timeout actions,
+%% all others are unrecognized
%%
-loop_actions_timeout(
+loop_actions_list(
P, Debug, S, Q, NextState_NewData,
NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions,
@@ -1618,7 +1578,7 @@ loop_actions_timeout(
hibernate = Hibernate},
Q)
end;
-loop_actions_timeout(
+loop_actions_list(
P, Debug, S, Q, NextState_NewData,
NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions,
@@ -1643,7 +1603,7 @@ loop_actions_timeout(
hibernate = Hibernate},
Q)
end;
-loop_actions_timeout(
+loop_actions_list(
P, Debug, S, Q, NextState_NewData,
NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions,
@@ -1667,7 +1627,7 @@ loop_actions_timeout(
hibernate = Hibernate},
Q)
end;
-loop_actions_timeout(
+loop_actions_list(
P, Debug, S, Q, NextState_NewData,
NextEventsR, Hibernate, TimeoutsR, Postpone,
CallEnter, StateCall, Actions,
@@ -1692,6 +1652,80 @@ loop_actions_timeout(
Q)
end.
+%% Process a reply action
+%%
+loop_actions_reply(
+ P, Debug, S, Q, NextState_NewData,
+ NextEventsR, Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions,
+ From, Reply) ->
+ %%
+ case from(From) of
+ true ->
+ %% No need for a separate ?not_sys_debug clause here
+ %% since the external call to erlang:'!'/2 in reply/2
+ %% will cause swap out of all live registers anyway
+ reply(From, Reply),
+ Debug_1 = ?sys_debug(Debug, P#params.name, {out,Reply,From}),
+ loop_actions_list(
+ P, Debug_1, S, Q, NextState_NewData,
+ NextEventsR, Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions);
+ false ->
+ terminate(
+ error,
+ {bad_action_from_state_function,{reply,From,Reply}},
+ ?STACKTRACE(), P, Debug,
+ S#state{
+ state_data = NextState_NewData,
+ hibernate = Hibernate},
+ Q)
+ end.
+
+%% Process a next_event action
+%%
+loop_actions_next_event(
+ P, Debug, S, Q, NextState_NewData,
+ NextEventsR, Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions, Type, Content) ->
+ case event_type(Type) of
+ true when StateCall ->
+ NextEvent = {Type,Content},
+ case Debug of
+ ?not_sys_debug ->
+ loop_actions_list(
+ P, Debug, S, Q, NextState_NewData,
+ [NextEvent|NextEventsR],
+ Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions);
+ _ ->
+ Name = P#params.name,
+ {State,_Data} = S#state.state_data,
+ Debug_1 =
+ sys_debug(Debug, Name, {in,{Type,Content},State}),
+ loop_actions_list(
+ P, Debug_1, S, Q, NextState_NewData,
+ [NextEvent|NextEventsR],
+ Hibernate, TimeoutsR, Postpone,
+ CallEnter, StateCall, Actions)
+ end;
+ _ ->
+ terminate(
+ error,
+ {if
+ StateCall ->
+ bad_action_from_state_function;
+ true ->
+ bad_state_enter_action_from_state_function
+ end,
+ {next_event,Type,Content}},
+ ?STACKTRACE(), P, Debug,
+ S#state{
+ state_data = NextState_NewData,
+ hibernate = Hibernate},
+ Q)
+ end.
+
%% Do the state transition
%%
loop_state_transition(
@@ -2269,7 +2303,7 @@ do_reply_then_terminate(
terminate(
Class, Reason, Stacktrace,
- #params{module = Module} = P, Debug,
+ #params{modules = [Module | _]} = P, Debug,
#state{state_data = {State,Data}} = S, Q) ->
case erlang:function_exported(Module, terminate, 3) of
true ->
@@ -2310,6 +2344,7 @@ error_info(
Class, Reason, Stacktrace, Debug,
#params{
name = Name,
+ modules = Modules,
callback_mode = CallbackMode,
state_enter = StateEnter} = P,
#state{
@@ -2321,6 +2356,7 @@ error_info(
name=>Name,
queue=>Q,
postponed=>Postponed,
+ modules=>Modules,
callback_mode=>CallbackMode,
state_enter=>StateEnter,
state=>format_status(terminate, get(), P, S),
@@ -2360,6 +2396,7 @@ format_log(#{label:={gen_statem,terminate},
name:=Name,
queue:=Q,
postponed:=Postponed,
+ modules:=Modules,
callback_mode:=CallbackMode,
state_enter:=StateEnter,
state:=FmtData,
@@ -2406,6 +2443,7 @@ format_log(#{label:={gen_statem,terminate},
end ++
"** When server state = ~tp~n" ++
"** Reason for termination = ~w:~tp~n" ++
+ "** Callback modules = ~p~n" ++
"** Callback mode = ~p~n" ++
case Q of
[_,_|_] -> "** Queued = ~tp~n";
@@ -2434,6 +2472,7 @@ format_log(#{label:={gen_statem,terminate},
end] ++
[error_logger:limit_term(FmtData),
Class,error_logger:limit_term(FixedReason),
+ error_logger:limit_term(Modules),
CBMode] ++
case Q of
[_|[_|_] = Events] -> [error_logger:limit_term(Events)];
@@ -2471,7 +2510,7 @@ format_client_log({_Pid,{Name,Stacktrace}}) ->
%% Call Module:format_status/2 or return a default value
format_status(
Opt, PDict,
- #params{module = Module},
+ #params{modules = [Module | _]},
#state{state_data = {State,Data} = State_Data}) ->
case erlang:function_exported(Module, format_status, 2) of
true ->
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index 74efe5c513..2114b17a79 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -356,11 +356,6 @@ clause({clause,Line,H0,G0,B0},Bound) ->
copy({call,Line,{remote,_Line2,{atom,_Line3,ets},{atom,_Line4,fun2ms}},
As0},Bound) ->
{transform_call(ets,Line,As0,Bound),Bound};
-copy({call,Line,{remote,_Line2,{record_field,_Line3,
- {atom,_Line4,''},{atom,_Line5,ets}},
- {atom,_Line6,fun2ms}}, As0},Bound) ->
- %% Packages...
- {transform_call(ets,Line,As0,Bound),Bound};
copy({call,Line,{remote,_Line2,{atom,_Line3,dbg},{atom,_Line4,fun2ms}},
As0},Bound) ->
{transform_call(dbg,Line,As0,Bound),Bound};
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index 224c0d5625..bea5a217db 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2019. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2020. 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.
@@ -223,6 +223,7 @@ rfc3339(Config) when is_list(Config) ->
{'EXIT', _} = (catch do_format_z(253402300799+1, [])),
{'EXIT', _} = (catch do_parse("9999-12-31T23:59:60Z", [])),
{'EXIT', _} = (catch do_format_z(253402300799*1000000000+999999999+1, Ns)),
+ {'EXIT', _} = (catch do_parse("2010-04-11T22:35:41", [])), % OTP-16514
253402300799 = do_parse("9999-12-31T23:59:59Z", []),
"0000-01-01T00:00:00Z" = test_parse("0000-01-01T00:00:00.0+00:00"),
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index 0586575736..296973370c 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -69,7 +69,7 @@ tcs(sys) ->
get_state, replace_state];
tcs(undef_callbacks) ->
[undef_code_change, undef_terminate1, undef_terminate2,
- function_clause_after_change_callback_module].
+ pop_too_many].
init_per_suite(Config) ->
Config.
@@ -1778,7 +1778,7 @@ verify_down(Statem, MRef, Reason) ->
end.
-function_clause_after_change_callback_module(_Config) ->
+pop_too_many(_Config) ->
_ = process_flag(trap_exit, true),
Machine =
@@ -1790,8 +1790,17 @@ function_clause_after_change_callback_module(_Config) ->
fun ({call, From}, {change_callback_module, _Module} = Action,
undefined = _Data) ->
{keep_state_and_data,
- [{reply,From,ok},
- Action]}
+ [Action,
+ {reply,From,ok}]};
+ ({call, From}, {verify, ?MODULE},
+ undefined = _Data) ->
+ {keep_state_and_data,
+ [{reply,From,ok}]};
+ ({call, From}, pop_callback_module = Action,
+ undefined = _Data) ->
+ {keep_state_and_data,
+ [Action,
+ {reply,From,ok}]}
end},
{ok, STM} =
gen_statem:start_link(
@@ -1800,16 +1809,16 @@ function_clause_after_change_callback_module(_Config) ->
[{debug, [trace]}]),
ok = gen_statem:call(STM, {change_callback_module, oc_statem}),
+ ok = gen_statem:call(STM, {push_callback_module, ?MODULE}),
+ ok = gen_statem:call(STM, {verify, ?MODULE}),
+ ok = gen_statem:call(STM, pop_callback_module),
+ BadAction = {bad_action_from_state_function, pop_callback_module},
+ {{BadAction, _},
+ {gen_statem,call,[STM,pop_callback_module,infinity]}} =
+ ?EXPECT_FAILURE(gen_statem:call(STM, pop_callback_module), Reason),
- Call = unhandled_call,
- {{function_clause,
- [{oc_statem, handle_event,
- [{call, _From}, Call, start, _Data], _Line}
- | _RestStacktrace]} = Undef,
- {gen_statem, call, [STM,Call,_Timeout]}} =
- ?EXPECT_FAILURE(gen_statem:call(STM, Call), Reason),
receive
- {'EXIT', STM, Undef} ->
+ {'EXIT', STM, {BadAction, _}} ->
ok;
Other ->
ct:fail({surprise, Other})
diff --git a/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl b/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl
index 1493cfb192..1bcd08867f 100644
--- a/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl
+++ b/lib/stdlib/test/gen_statem_SUITE_data/oc_statem.erl
@@ -37,4 +37,16 @@ callback_mode() ->
[handle_event_function, state_enter].
handle_event(enter, start, start, _Data) ->
- keep_state_and_data.
+ keep_state_and_data;
+handle_event(
+ {call,From}, {push_callback_module,NewModule} = Action,
+ start, _Data) ->
+ {keep_state_and_data,
+ [Action,
+ {reply,From,ok}]};
+handle_event(
+ {call,From}, pop_callback_module = Action,
+ start, _Data) ->
+ {keep_state_and_data,
+ [Action,
+ {reply,From,ok}]}.
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index 2b3af417b6..80af13a4c3 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1722,7 +1722,10 @@ bool_switch(E, T, F, AllVars, AuxVarN) ->
{'case',Line,E,
[{clause,Line,[{atom,Line,true}],[],[T]},
{clause,Line,[{atom,Line,false}],[],[F]},
- {clause,Line,[AuxVar],[],
+ %% Mark the next clause as compiler-generated to suppress
+ %% a warning if the case expression is an obvious boolean
+ %% value.
+ {clause,erl_anno:set_generated(true, Line),[AuxVar],[],
[{call,Line,
{remote,Line,{atom,Line,erlang},{atom,Line,error}},
[{tuple,Line,[{atom,Line,badarg},AuxVar]}]}]}]}.
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 36d4828861..369fbb2d42 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -2782,6 +2782,8 @@ parsify({A, B, C}) ->
{parsify(A), parsify(B), parsify(C)};
parsify(Tuple) when is_tuple(Tuple) ->
list_to_tuple(parsify(tuple_to_list(Tuple)));
+parsify(Map) when is_map(Map) ->
+ maps:from_list(parsify(maps:to_list(Map)));
parsify(Pid) when is_pid(Pid) ->
erlang:pid_to_list(Pid);
parsify(Port) when is_port(Port) ->
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
index 462767f430..0de73bc3d7 100644
--- a/lib/tools/test/cover_SUITE.erl
+++ b/lib/tools/test/cover_SUITE.erl
@@ -37,7 +37,7 @@ all() ->
dont_reconnect_after_stop, stop_node_after_disconnect,
export_import, otp_5031, otp_6115,
otp_8270, otp_10979_hanging_node, otp_14817,
- local_only, startup_race],
+ local_only, startup_race, otp_16476],
case whereis(cover_server) of
undefined ->
[coverage,StartStop ++ NoStartStop];
@@ -1803,6 +1803,17 @@ startup_race_1([]) ->
cover:stop(),
ok.
+otp_16476(Config) when is_list(Config) ->
+ Mod = obvious_booleans,
+ Dir = filename:join(proplists:get_value(data_dir, Config),
+ ?FUNCTION_NAME),
+ ok = file:set_cwd(Dir),
+ {ok, Mod} = compile:file(Mod, [debug_info]),
+ {ok, Mod} = cover:compile(Mod),
+ ok = Mod:Mod(),
+ ok = cover:stop(),
+ ok.
+
%%--Auxiliary------------------------------------------------------------
analyse_expr(Expr, Config) ->
diff --git a/lib/tools/test/cover_SUITE_data/otp_16476/obvious_booleans.erl b/lib/tools/test/cover_SUITE_data/otp_16476/obvious_booleans.erl
new file mode 100644
index 0000000000..1f383be0a5
--- /dev/null
+++ b/lib/tools/test/cover_SUITE_data/otp_16476/obvious_booleans.erl
@@ -0,0 +1,17 @@
+-module(obvious_booleans).
+-export([?MODULE/0]).
+-compile([warnings_as_errors]).
+
+?MODULE() ->
+ true = both_ok(ok, ok),
+ false = both_ok(ok, nok),
+ true = one_ok(ok, nok),
+ true = one_ok(nok, ok),
+ false = one_ok(nok, nok),
+ ok.
+
+both_ok(A, B) ->
+ A =:= ok andalso B =:= ok.
+
+one_ok(A, B) ->
+ A =:= ok orelse B =:= ok.
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
index ae0e7253ad..cdb207c1e2 100644
--- a/lib/tools/test/fprof_SUITE.erl
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -27,7 +27,7 @@
%% Test suites
-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
imm_tail_seq/1, imm_create_file_slow/1, imm_compile/1,
- cpu_create_file_slow/1, unicode/1]).
+ cpu_create_file_slow/1, unicode/1, parsify_maps/1]).
%% Other exports
-export([create_file_slow/2]).
@@ -59,7 +59,7 @@ all() ->
false ->
[stack_seq, tail_seq, create_file_slow, spawn_simple,
imm_tail_seq, imm_create_file_slow, imm_compile,
- cpu_create_file_slow, unicode]
+ cpu_create_file_slow, unicode, parsify_maps]
end.
@@ -544,6 +544,35 @@ unicode(Config) when is_list(Config) ->
ok = fprof:profile(dump, AnalysisFile),
ok = fprof:analyse(dest, AnalysisFile).
+parsify_maps(Config) when is_list(Config) ->
+ Pid = self(),
+ Ref = make_ref(),
+ Port = hd(erlang:ports()),
+ Fun = fun () -> ok end,
+ M = #{pid => Pid, Pid => pid,
+ ref => Ref, Ref => ref,
+ port => Port, Port => port,
+ a_fun => Fun, Fun => a_fun},
+ io:format("M = ~p~n", [M]),
+ L = [{tuple, M}, M, #{my_map => M, M => my_map}],
+ PL = fprof:parsify(L),
+ [{tuple, PM}, PM, PMap] = PL,
+ #{my_map := PM, PM := my_map} = PMap,
+ io:format("PM = ~p~n", [PM]),
+ LPid = pid_to_list(Pid),
+ LRef = ref_to_list(Ref),
+ LPort = port_to_list(Port),
+ LFun = erlang:fun_to_list(Fun),
+ LPid = maps:get(pid, PM),
+ pid = maps:get(LPid, PM),
+ LRef = maps:get(ref, PM),
+ ref = maps:get(LRef, PM),
+ LPort = maps:get(port, PM),
+ port = maps:get(LPort, PM),
+ LFun = maps:get(a_fun, PM),
+ a_fun = maps:get(LFun, PM),
+ ok.
+
%%%---------------------------------------------------------------------
%%% Functions to test
%%%---------------------------------------------------------------------
diff --git a/make/otp_version_tickets_in_merge b/make/otp_version_tickets_in_merge
index e2401e5757..e69de29bb2 100644
--- a/make/otp_version_tickets_in_merge
+++ b/make/otp_version_tickets_in_merge
@@ -1,4 +0,0 @@
-OTP-16452
-OTP-16456
-OTP-16466
-OTP-16467
diff --git a/otp_versions.table b/otp_versions.table
index 30acd06214..e9547c7ead 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,3 +1,4 @@
+OTP-22.2.8 : diameter-2.2.2 # asn1-5.0.9 common_test-1.18.1 compiler-7.5.2 crypto-4.6.4 debugger-4.2.8 dialyzer-4.1.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.11 erl_interface-3.13.1 erts-10.6.4 et-1.6.4 eunit-2.4 ftp-1.0.4 hipe-3.19.2 inets-7.1.2 jinterface-1.10.1 kernel-6.5.1 megaco-3.18.7 mnesia-4.16.2 observer-2.9.3 odbc-2.12.4 os_mon-2.5.1 parsetools-2.1.8 public_key-1.7.1 reltool-0.8 runtime_tools-1.14 sasl-3.4.1 snmp-5.4.5 ssh-4.8.2 ssl-9.5.3 stdlib-3.11.2 syntax_tools-2.2.1 tftp-1.0.2 tools-3.3 wx-1.9 xmerl-1.3.23 :
OTP-22.2.7 : compiler-7.5.2 # asn1-5.0.9 common_test-1.18.1 crypto-4.6.4 debugger-4.2.8 dialyzer-4.1.1 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.11 erl_interface-3.13.1 erts-10.6.4 et-1.6.4 eunit-2.4 ftp-1.0.4 hipe-3.19.2 inets-7.1.2 jinterface-1.10.1 kernel-6.5.1 megaco-3.18.7 mnesia-4.16.2 observer-2.9.3 odbc-2.12.4 os_mon-2.5.1 parsetools-2.1.8 public_key-1.7.1 reltool-0.8 runtime_tools-1.14 sasl-3.4.1 snmp-5.4.5 ssh-4.8.2 ssl-9.5.3 stdlib-3.11.2 syntax_tools-2.2.1 tftp-1.0.2 tools-3.3 wx-1.9 xmerl-1.3.23 :
OTP-22.2.6 : erts-10.6.4 # asn1-5.0.9 common_test-1.18.1 compiler-7.5.1 crypto-4.6.4 debugger-4.2.8 dialyzer-4.1.1 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.11 erl_interface-3.13.1 et-1.6.4 eunit-2.4 ftp-1.0.4 hipe-3.19.2 inets-7.1.2 jinterface-1.10.1 kernel-6.5.1 megaco-3.18.7 mnesia-4.16.2 observer-2.9.3 odbc-2.12.4 os_mon-2.5.1 parsetools-2.1.8 public_key-1.7.1 reltool-0.8 runtime_tools-1.14 sasl-3.4.1 snmp-5.4.5 ssh-4.8.2 ssl-9.5.3 stdlib-3.11.2 syntax_tools-2.2.1 tftp-1.0.2 tools-3.3 wx-1.9 xmerl-1.3.23 :
OTP-22.2.5 : erts-10.6.3 stdlib-3.11.2 # asn1-5.0.9 common_test-1.18.1 compiler-7.5.1 crypto-4.6.4 debugger-4.2.8 dialyzer-4.1.1 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.11 erl_interface-3.13.1 et-1.6.4 eunit-2.4 ftp-1.0.4 hipe-3.19.2 inets-7.1.2 jinterface-1.10.1 kernel-6.5.1 megaco-3.18.7 mnesia-4.16.2 observer-2.9.3 odbc-2.12.4 os_mon-2.5.1 parsetools-2.1.8 public_key-1.7.1 reltool-0.8 runtime_tools-1.14 sasl-3.4.1 snmp-5.4.5 ssh-4.8.2 ssl-9.5.3 syntax_tools-2.2.1 tftp-1.0.2 tools-3.3 wx-1.9 xmerl-1.3.23 :
@@ -24,6 +25,7 @@ OTP-22.0.3 : compiler-7.4.2 dialyzer-4.0.1 erts-10.4.2 ssl-9.3.2 stdlib-3.9.2 #
OTP-22.0.2 : compiler-7.4.1 crypto-4.5.1 erts-10.4.1 stdlib-3.9.1 # asn1-5.0.9 common_test-1.17.3 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3.1 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0.1 : ssl-9.3.1 # asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 :
OTP-22.0 : asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3 stdlib-3.9 syntax_tools-2.2 tools-3.2 wx-1.8.8 xmerl-1.3.21 # diameter-2.2.1 et-1.6.4 eunit-2.3.7 ftp-1.0.2 parsetools-2.1.8 tftp-1.0.1 :
+OTP-21.3.8.14 : erts-10.3.5.10 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2.2 hipe-3.18.3 inets-7.0.7.2 jinterface-1.9.1 kernel-6.3.1.3 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6.3 ssl-9.2.3.5 stdlib-3.8.2.3 syntax_tools-2.1.7.1 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.13 : erts-10.3.5.9 stdlib-3.8.2.3 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2.2 hipe-3.18.3 inets-7.0.7.2 jinterface-1.9.1 kernel-6.3.1.3 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6.3 ssl-9.2.3.5 syntax_tools-2.1.7.1 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.12 : crypto-4.4.2.2 erts-10.3.5.8 ssh-4.7.6.3 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2.2 hipe-3.18.3 inets-7.0.7.2 jinterface-1.9.1 kernel-6.3.1.3 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssl-9.2.3.5 stdlib-3.8.2.2 syntax_tools-2.1.7.1 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
OTP-21.3.8.11 : erts-10.3.5.7 ftp-1.0.2.2 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2.1 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 hipe-3.18.3 inets-7.0.7.2 jinterface-1.9.1 kernel-6.3.1.3 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6.2 ssl-9.2.3.5 stdlib-3.8.2.2 syntax_tools-2.1.7.1 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 :
@@ -70,6 +72,7 @@ OTP-21.0.3 : erts-10.0.3 # asn1-5.0.6 common_test-1.16 compiler-7.2.2 crypto-4.3
OTP-21.0.2 : compiler-7.2.2 erts-10.0.2 public_key-1.6.1 stdlib-3.5.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 :
OTP-21.0.1 : compiler-7.2.1 erts-10.0.1 # asn1-5.0.6 common_test-1.16 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 megaco-3.18.3 mnesia-4.15.4 observer-2.8 odbc-2.12.1 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 snmp-5.2.11 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 :
OTP-21.0 : asn1-5.0.6 common_test-1.16 compiler-7.2 crypto-4.3 debugger-4.2.5 dialyzer-3.3 diameter-2.1.5 edoc-0.9.3 eldap-1.2.4 erl_docgen-0.8 erl_interface-3.10.3 erts-10.0 et-1.6.2 eunit-2.3.6 ftp-1.0 hipe-3.18 inets-7.0 jinterface-1.9 kernel-6.0 mnesia-4.15.4 observer-2.8 os_mon-2.4.5 otp_mibs-1.2 parsetools-2.1.7 public_key-1.6 reltool-0.7.6 runtime_tools-1.13 sasl-3.2 ssh-4.7 ssl-9.0 stdlib-3.5 syntax_tools-2.1.5 tftp-1.0 tools-3.0 wx-1.8.4 xmerl-1.3.17 # megaco-3.18.3 odbc-2.12.1 snmp-5.2.11 :
+OTP-20.3.8.26 : erts-9.3.3.15 ssh-4.6.9.7 # asn1-5.0.5.2 common_test-1.15.4.4 compiler-7.1.5.2 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2.4 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4.1 edoc-0.9.2 eldap-1.2.3.1 erl_docgen-0.7.3 erl_interface-3.10.2.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4.2 inets-6.5.2.4 jinterface-1.8.1 kernel-5.4.3.2 megaco-3.18.3 mnesia-4.15.3.2 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11.2 ssl-8.2.6.4 stdlib-3.4.5.1 syntax_tools-2.1.4.2 tools-2.11.2.2 wx-1.8.3 xmerl-1.3.16.1 :
OTP-20.3.8.25 : crypto-4.2.2.4 erts-9.3.3.14 ssh-4.6.9.6 # asn1-5.0.5.2 common_test-1.15.4.4 compiler-7.1.5.2 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4.1 edoc-0.9.2 eldap-1.2.3.1 erl_docgen-0.7.3 erl_interface-3.10.2.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4.2 inets-6.5.2.4 jinterface-1.8.1 kernel-5.4.3.2 megaco-3.18.3 mnesia-4.15.3.2 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11.2 ssl-8.2.6.4 stdlib-3.4.5.1 syntax_tools-2.1.4.2 tools-2.11.2.2 wx-1.8.3 xmerl-1.3.16.1 :
OTP-20.3.8.24 : common_test-1.15.4.4 erts-9.3.3.13 ssh-4.6.9.5 # asn1-5.0.5.2 compiler-7.1.5.2 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2.3 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4.1 edoc-0.9.2 eldap-1.2.3.1 erl_docgen-0.7.3 erl_interface-3.10.2.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4.2 inets-6.5.2.4 jinterface-1.8.1 kernel-5.4.3.2 megaco-3.18.3 mnesia-4.15.3.2 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11.2 ssl-8.2.6.4 stdlib-3.4.5.1 syntax_tools-2.1.4.2 tools-2.11.2.2 wx-1.8.3 xmerl-1.3.16.1 :
OTP-20.3.8.23 : crypto-4.2.2.3 erts-9.3.3.12 snmp-5.2.11.2 syntax_tools-2.1.4.2 # asn1-5.0.5.2 common_test-1.15.4.3 compiler-7.1.5.2 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4.1 edoc-0.9.2 eldap-1.2.3.1 erl_docgen-0.7.3 erl_interface-3.10.2.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4.2 inets-6.5.2.4 jinterface-1.8.1 kernel-5.4.3.2 megaco-3.18.3 mnesia-4.15.3.2 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 ssh-4.6.9.4 ssl-8.2.6.4 stdlib-3.4.5.1 tools-2.11.2.2 wx-1.8.3 xmerl-1.3.16.1 :
diff --git a/scripts/bundle-otp b/scripts/bundle-otp
index aa1f166732..df82ff4fc5 100755
--- a/scripts/bundle-otp
+++ b/scripts/bundle-otp
@@ -6,8 +6,8 @@ if [ "$TRAVIS_PULL_REQUEST" = "false" -a "$TRAVIS_REPO_SLUG" != "erlang/otp" ];
exit 0
fi
-OTP_META_FILE=$ERL_TOP/${TRAVIS_TAG}-bundle.txt
-OTP_FILE=$ERL_TOP/${TRAVIS_TAG}-bundle.tar.gz
+OTP_META_FILE=$ERL_TOP/${TRAVIS_TAG}.0-bundle.txt
+OTP_FILE=$ERL_TOP/${TRAVIS_TAG}.0-bundle.tar.gz
REPOSITORIES="otp,$TRAVIS_TAG corba,.*"
diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml
index 027a71c59f..0bcd7dc1b2 100644
--- a/system/doc/design_principles/release_handling.xml
+++ b/system/doc/design_principles/release_handling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2016</year>
+ <year>2003</year><year>2020</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -59,7 +59,7 @@
<p><em>Step 2</em>) The release is transferred to and installed at
target environment. For information of how to install the first
target system, see
- <seealso marker="system_principles:create_target">System Principles</seealso>.</p>
+ <seealso marker="doc/system_principles:create_target">System Principles</seealso>.</p>
<p><em>Step 3</em>) Modifications, for example, error corrections,
are made to the code in the development environment.</p>
<p><em>Step 4</em>) At some point, it is time to make a new version
diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml
index f657e8cb00..d6d907de45 100644
--- a/system/doc/design_principles/statem.xml
+++ b/system/doc/design_principles/statem.xml
@@ -185,15 +185,17 @@ State(S) x Event(E) -> Actions(A), State(S')</pre>
</p>
<p>
The <em>callback module</em> can be changed for a running server
- using the
- <seealso marker="#Transition Actions">transition action</seealso>
- <seealso marker="stdlib:gen_statem#type-action"><c>{change_callback_module, NewModule}</c></seealso>.
+ using any of the
+ <seealso marker="#Transition Actions">transition actions</seealso>
+ <seealso marker="stdlib:gen_statem#type-action"><c>{change_callback_module, NewModule}</c></seealso>,
+ <seealso marker="stdlib:gen_statem#type-action"><c>{push_callback_module, NewModule}</c></seealso> or
+ <seealso marker="stdlib:gen_statem#type-action"><c>pop_callback_module</c></seealso>.
Note that this is a pretty esotheric thing to do...
The origin for this feature is a protocol that after
version negotiation branches off into quite different
state machines depending on the protocol version.
There <i>might</i> be other use cases.
- <i>Beware</i> that the <c>NewModule</c>
+ <i>Beware</i> that the new callback module
completely replaces the previous behaviour module,
so all relevant callback functions has to handle
the state and data from the previous callback module.
@@ -664,6 +666,41 @@ State(S) x Event(E) -> Actions(A), State(S')</pre>
but it can <i>not</i> be done from a
<seealso marker="#State Enter Calls"><em>state enter call</em></seealso>.
</item>
+ <tag>
+ <seealso marker="stdlib:gen_statem#type-action">
+ <c>{push_callback_module, NewModule}</c>
+ </seealso>
+ </tag>
+ <item>
+ Push the current <em>callback module</em>
+ to the top of an internal stack of callback modules
+ and set the new
+ <seealso marker="#Callback Module">
+ <em>callback module</em>
+ </seealso>
+ for the running server.
+ Otherwise like
+ <c>{change_callback_module, NewModule}</c>
+ above.
+ </item>
+ <tag>
+ <seealso marker="stdlib:gen_statem#type-action">
+ <c>pop_callback_module</c>
+ </seealso>
+ </tag>
+ <item>
+ Pop the top module from
+ the internal stack of callback modules
+ and set it to be the new
+ <seealso marker="#Callback Module">
+ <em>callback module</em>
+ </seealso>
+ for the running server.
+ If the stack is empty the server fails.
+ Otherwise like
+ <c>{change_callback_module, NewModule}</c>
+ above.
+ </item>
</taglist>
<p>
For details, see the <c>gen_statem(3)</c>