Repository: RedHatInsights/insights-core

Issue:
Parser for /proc/sys/net/ipv4/tcp_rmem & /proc/sys/net/ipv4/tcp_wmem
The files `/proc/sys/net/ipv4/tcp_rmem` & `/proc/sys/net/ipv4/tcp_wmem` contain the minimum, default and maximum socket buffer values which can be used by a specific socket connection.




Discussion:
@yadneshk Please go ahead and raise the PR.

Resolving patch:
diff --git a/insights/parsers/sendq_recvq_socket_buffer.py b/insights/parsers/sendq_recvq_socket_buffer.py
new file mode 100644
--- /dev/null
+++ b/insights/parsers/sendq_recvq_socket_buffer.py
@@ -0,0 +1,96 @@
+"""
+SendQSocketBuffer - file ``/proc/sys/net/ipv4/tcp_wmem``
+--------------------------------------------------------
+RecvQSocketBuffer - file ``/proc/sys/net/ipv4/tcp_rmem``
+--------------------------------------------------------
+"""
+from insights.parsers import ParseException
+from insights import parser, Parser
+from insights.specs import Specs
+
+
+class SocketBuffer(Parser):
+    """ Base class for SendQSocketBuffer & RecvQSocketBuffer
+    """
+    def parse_content(self, content):
+        if not content:
+            raise ParseException("Empty content")
+        buffer_values = content[-1].split()
+        self.raw = " ".join(buffer_values)
+        self.minimum, self.default, self.maximum = [int(value) for value in buffer_values]
+
+    def __repr__(self):
+        return "<raw: {r}, minimum: {min}, default: {dft}, maximum: {max}>".format(
+            r=self.raw,
+            min=self.minimum,
+            dft=self.default,
+            max=self.maximum
+        )
+
+
+@parser(Specs.sendq_socket_buffer)
+class SendQSocketBuffer(SocketBuffer):
+    """Parse the file ``/proc/sys/net/ipv4/tcp_wmem``
+
+    Parameter ipv4/tcp_wmem is the amount of memory in bytes write (transmit) buffer per open socket.
+    This is a vector of 3 integers: [min, default, max].
+    These parameters are used by TCP to regulate send buffer sizes.
+    TCP dynamically adjusts the size of the send buffer from the default values listed below,
+    in the range of these values, depending on memory available.
+
+    Read more on http://man7.org/linux/man-pages/man7/tcp.7.html
+
+    Sample input::
+        4096	16384	4194304
+
+    Examples:
+        >>> sendq_buffer_values.raw
+        '4096 16384 4194304'
+        >>> sendq_buffer_values.minimum
+        4096
+        >>> sendq_buffer_values.default
+        16384
+        >>> sendq_buffer_values.maximum
+        4194304
+
+    Attributes:
+        raw: The raw content of send buffer sizes from tcp_wmem
+        minimum: Minimum size of the send buffer used by each TCP socket
+        default: The default size of the send buffer for a TCP socket
+        maximum: The maximum size of the send buffer used by each TCP socket
+    """
+    pass
+
+
+@parser(Specs.recvq_socket_buffer)
+class RecvQSocketBuffer(SocketBuffer):
+    """Parse the file ``/proc/sys/net/ipv4/tcp_rmem``
+
+    Parameter ipv4/tcp_rmem is the amount of memory in bytes for read (receive) buffer per open socket.
+    This is a vector of 3 integers: [min, default, max].
+    These parameters are used by TCP to regulate receive buffer sizes.
+    TCP dynamically adjusts the size of the receive buffer from the defaults listed below,
+    in the range of these values, depending on memory available in the system.
+
+    Read more on http://man7.org/linux/man-pages/man7/tcp.7.html
+
+    Sample input::
+        4096	87380	6291456
+
+    Examples:
+        >>> recvq_buffer_values.raw
+        '4096 87380 6291456'
+        >>> recvq_buffer_values.minimum
+        4096
+        >>> recvq_buffer_values.default
+        87380
+        >>> recvq_buffer_values.maximum
+        6291456
+
+    Attributes:
+        raw: The raw content of receive buffer sizes from tcp_rmem
+        minimum: Minimum size of the receive buffer used by each TCP socket
+        default: The default size of the receive buffer for a TCP socket
+        maximum: The maximum size of the receive buffer used by each TCP socket
+    """
+    pass
diff --git a/insights/specs/__init__.py b/insights/specs/__init__.py
--- a/insights/specs/__init__.py
+++ b/insights/specs/__init__.py
@@ -669,3 +669,5 @@ class Specs(SpecSet):
     yum_repos_d = RegistryPoint(multi_output=True)
     zdump_v = RegistryPoint()
     zipl_conf = RegistryPoint()
+    sendq_socket_buffer = RegistryPoint()
+    recvq_socket_buffer = RegistryPoint()
diff --git a/insights/specs/sos_archive.py b/insights/specs/sos_archive.py
--- a/insights/specs/sos_archive.py
+++ b/insights/specs/sos_archive.py
@@ -160,3 +160,5 @@ class SosSpecs(Specs):
     vgs = first_file(["sos_commands/lvm2/vgs_-v_-o_vg_mda_count_vg_mda_free_vg_mda_size_vg_mda_used_count_vg_tags_--config_global_locking_type_0", "sos_commands/lvm2/vgs_-v", "sos_commands/devicemapper/vgs_-v"])
     xfs_info = glob_file("sos_commands/xfs/xfs_info*")
     yum_repolist = simple_file("sos_commands/yum/yum_-C_repolist")
+    sendq_socket_buffer = simple_file("proc/sys/net/ipv4/tcp_wmem")
+    recvq_socket_buffer = simple_file("proc/sys/net/ipv4/tcp_rmem")


Test patch:
diff --git a/insights/parsers/tests/test_sendq_recvq_socket_buffer.py b/insights/parsers/tests/test_sendq_recvq_socket_buffer.py
new file mode 100644
--- /dev/null
+++ b/insights/parsers/tests/test_sendq_recvq_socket_buffer.py
@@ -0,0 +1,58 @@
+import doctest
+import pytest
+from insights.parsers import ParseException
+
+from insights.tests import context_wrap
+from insights.parsers import sendq_recvq_socket_buffer
+from insights.parsers.sendq_recvq_socket_buffer import SendQSocketBuffer, RecvQSocketBuffer
+
+SENDQ_SOCKET_BUFFER = """
+4096	16384	4194304
+""".strip()
+
+EMPTY_SENDQ_SOCKET_BUFFER = """
+""".strip()
+
+RECVQ_SOCKET_BUFFER = """
+4096	87380	6291456
+""".strip()
+
+EMPTY_RECVQ_SOCKET_BUFFER = """
+""".strip()
+
+
+def test_empty_sendq_socket_buffer():
+    with pytest.raises(ParseException) as exc:
+        SendQSocketBuffer(context_wrap(EMPTY_SENDQ_SOCKET_BUFFER))
+    assert str(exc.value) == "Empty content"
+
+
+def test_sendq_socket_buffer():
+    sendq_buffer = SendQSocketBuffer(context_wrap(SENDQ_SOCKET_BUFFER))
+    assert sendq_buffer.minimum == 4096
+    assert sendq_buffer.default == 16384
+    assert sendq_buffer.maximum == 4194304
+    assert sendq_buffer.raw == '4096 16384 4194304'
+
+
+def test_empty_recvq_socket_buffer():
+    with pytest.raises(ParseException) as exc:
+        RecvQSocketBuffer(context_wrap(EMPTY_RECVQ_SOCKET_BUFFER))
+    assert str(exc.value) == "Empty content"
+
+
+def test_recvq_socket_buffer():
+    recvq_buffer = RecvQSocketBuffer(context_wrap(RECVQ_SOCKET_BUFFER))
+    assert recvq_buffer.minimum == 4096
+    assert recvq_buffer.default == 87380
+    assert recvq_buffer.maximum == 6291456
+    assert recvq_buffer.raw == '4096 87380 6291456'
+
+
+def test_doc():
+    env = {
+            'sendq_buffer_values': SendQSocketBuffer(context_wrap(SENDQ_SOCKET_BUFFER)),
+            'recvq_buffer_values': RecvQSocketBuffer(context_wrap(RECVQ_SOCKET_BUFFER)),
+          }
+    failures, tests = doctest.testmod(sendq_recvq_socket_buffer, globs=env)
+    assert failures == 0