diff --git a/docs/parsers/proc_net_netstat.md b/docs/parsers/proc_net_netstat.md new file mode 100644 index 00000000..e9f2f982 --- /dev/null +++ b/docs/parsers/proc_net_netstat.md @@ -0,0 +1,324 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + + +# jc.parsers.proc\_net\_netstat + +jc - JSON Convert `/proc/net/netstat` file parser + +Usage (cli): + + $ cat /proc/net/netstat | jc --proc + +or + + $ jc /proc/net/netstat + +or + + $ cat /proc/net/netstat | jc --proc-net-netstat + +Usage (module): + + import jc + result = jc.parse('proc', proc_net_netstat_file) + +or + + import jc + result = jc.parse('proc_net_netstat', proc_net_netstat_file) + +Schema: + +All values except "type" are integers + + [ + { + "type": string, + "": integer + } + ] + +Examples: + + $ cat /proc/net/netstat | jc --proc -p + [ + { + "SyncookiesSent": 0, + "SyncookiesRecv": 0, + "SyncookiesFailed": 0, + "EmbryonicRsts": 0, + "PruneCalled": 0, + "RcvPruned": 0, + "OfoPruned": 0, + "OutOfWindowIcmps": 0, + "LockDroppedIcmps": 0, + "ArpFilter": 0, + "TW": 3, + "TWRecycled": 0, + "TWKilled": 0, + "PAWSActive": 0, + "PAWSEstab": 0, + "DelayedACKs": 10, + "DelayedACKLocked": 53, + "DelayedACKLost": 0, + "ListenOverflows": 0, + "ListenDrops": 0, + "TCPHPHits": 2387, + "TCPPureAcks": 12711, + "TCPHPAcks": 53535, + "TCPRenoRecovery": 0, + "TCPSackRecovery": 0, + "TCPSACKReneging": 0, + "TCPSACKReorder": 0, + "TCPRenoReorder": 0, + "TCPTSReorder": 0, + "TCPFullUndo": 0, + "TCPPartialUndo": 0, + "TCPDSACKUndo": 0, + "TCPLossUndo": 0, + "TCPLostRetransmit": 0, + "TCPRenoFailures": 0, + "TCPSackFailures": 0, + "TCPLossFailures": 0, + "TCPFastRetrans": 0, + "TCPSlowStartRetrans": 0, + "TCPTimeouts": 0, + "TCPLossProbes": 0, + "TCPLossProbeRecovery": 0, + "TCPRenoRecoveryFail": 0, + "TCPSackRecoveryFail": 0, + "TCPRcvCollapsed": 0, + "TCPBacklogCoalesce": 2883, + "TCPDSACKOldSent": 0, + "TCPDSACKOfoSent": 0, + "TCPDSACKRecv": 0, + "TCPDSACKOfoRecv": 0, + "TCPAbortOnData": 0, + "TCPAbortOnClose": 1, + "TCPAbortOnMemory": 0, + "TCPAbortOnTimeout": 0, + "TCPAbortOnLinger": 0, + "TCPAbortFailed": 0, + "TCPMemoryPressures": 0, + "TCPMemoryPressuresChrono": 0, + "TCPSACKDiscard": 0, + "TCPDSACKIgnoredOld": 0, + "TCPDSACKIgnoredNoUndo": 0, + "TCPSpuriousRTOs": 0, + "TCPMD5NotFound": 0, + "TCPMD5Unexpected": 0, + "TCPMD5Failure": 0, + "TCPSackShifted": 0, + "TCPSackMerged": 0, + "TCPSackShiftFallback": 0, + "TCPBacklogDrop": 0, + "PFMemallocDrop": 0, + "TCPMinTTLDrop": 0, + "TCPDeferAcceptDrop": 0, + "IPReversePathFilter": 0, + "TCPTimeWaitOverflow": 0, + "TCPReqQFullDoCookies": 0, + "TCPReqQFullDrop": 0, + "TCPRetransFail": 0, + "TCPRcvCoalesce": 151, + "TCPOFOQueue": 0, + "TCPOFODrop": 0, + "TCPOFOMerge": 0, + "TCPChallengeACK": 0, + "TCPSYNChallenge": 0, + "TCPFastOpenActive": 0, + "TCPFastOpenActiveFail": 0, + "TCPFastOpenPassive": 0, + "TCPFastOpenPassiveFail": 0, + "TCPFastOpenListenOverflow": 0, + "TCPFastOpenCookieReqd": 0, + "TCPFastOpenBlackhole": 0, + "TCPSpuriousRtxHostQueues": 0, + "BusyPollRxPackets": 0, + "TCPAutoCorking": 28376, + "TCPFromZeroWindowAdv": 0, + "TCPToZeroWindowAdv": 0, + "TCPWantZeroWindowAdv": 0, + "TCPSynRetrans": 0, + "TCPOrigDataSent": 119438, + "TCPHystartTrainDetect": 3, + "TCPHystartTrainCwnd": 60, + "TCPHystartDelayDetect": 0, + "TCPHystartDelayCwnd": 0, + "TCPACKSkippedSynRecv": 0, + "TCPACKSkippedPAWS": 0, + "TCPACKSkippedSeq": 0, + "TCPACKSkippedFinWait2": 0, + "TCPACKSkippedTimeWait": 0, + "TCPACKSkippedChallenge": 0, + "TCPWinProbe": 0, + "TCPKeepAlive": 6, + "TCPMTUPFail": 0, + "TCPMTUPSuccess": 0, + "TCPDelivered": 119453, + "TCPDeliveredCE": 0, + "TCPAckCompressed": 0, + "TCPZeroWindowDrop": 0, + "TCPRcvQDrop": 0, + "TCPWqueueTooBig": 0, + "TCPFastOpenPassiveAltKey": 0, + "TcpTimeoutRehash": 0, + "TcpDuplicateDataRehash": 0, + "type": "TcpExt" + }, + ... + ] + + $ cat /proc/net/netstat | jc --proc -p -r + [ + { + "SyncookiesSent": "0", + "SyncookiesRecv": "0", + "SyncookiesFailed": "0", + "EmbryonicRsts": "0", + "PruneCalled": "0", + "RcvPruned": "0", + "OfoPruned": "0", + "OutOfWindowIcmps": "0", + "LockDroppedIcmps": "0", + "ArpFilter": "0", + "TW": "3", + "TWRecycled": "0", + "TWKilled": "0", + "PAWSActive": "0", + "PAWSEstab": "0", + "DelayedACKs": "10", + "DelayedACKLocked": "53", + "DelayedACKLost": "0", + "ListenOverflows": "0", + "ListenDrops": "0", + "TCPHPHits": "2387", + "TCPPureAcks": "12711", + "TCPHPAcks": "53535", + "TCPRenoRecovery": "0", + "TCPSackRecovery": "0", + "TCPSACKReneging": "0", + "TCPSACKReorder": "0", + "TCPRenoReorder": "0", + "TCPTSReorder": "0", + "TCPFullUndo": "0", + "TCPPartialUndo": "0", + "TCPDSACKUndo": "0", + "TCPLossUndo": "0", + "TCPLostRetransmit": "0", + "TCPRenoFailures": "0", + "TCPSackFailures": "0", + "TCPLossFailures": "0", + "TCPFastRetrans": "0", + "TCPSlowStartRetrans": "0", + "TCPTimeouts": "0", + "TCPLossProbes": "0", + "TCPLossProbeRecovery": "0", + "TCPRenoRecoveryFail": "0", + "TCPSackRecoveryFail": "0", + "TCPRcvCollapsed": "0", + "TCPBacklogCoalesce": "2883", + "TCPDSACKOldSent": "0", + "TCPDSACKOfoSent": "0", + "TCPDSACKRecv": "0", + "TCPDSACKOfoRecv": "0", + "TCPAbortOnData": "0", + "TCPAbortOnClose": "1", + "TCPAbortOnMemory": "0", + "TCPAbortOnTimeout": "0", + "TCPAbortOnLinger": "0", + "TCPAbortFailed": "0", + "TCPMemoryPressures": "0", + "TCPMemoryPressuresChrono": "0", + "TCPSACKDiscard": "0", + "TCPDSACKIgnoredOld": "0", + "TCPDSACKIgnoredNoUndo": "0", + "TCPSpuriousRTOs": "0", + "TCPMD5NotFound": "0", + "TCPMD5Unexpected": "0", + "TCPMD5Failure": "0", + "TCPSackShifted": "0", + "TCPSackMerged": "0", + "TCPSackShiftFallback": "0", + "TCPBacklogDrop": "0", + "PFMemallocDrop": "0", + "TCPMinTTLDrop": "0", + "TCPDeferAcceptDrop": "0", + "IPReversePathFilter": "0", + "TCPTimeWaitOverflow": "0", + "TCPReqQFullDoCookies": "0", + "TCPReqQFullDrop": "0", + "TCPRetransFail": "0", + "TCPRcvCoalesce": "151", + "TCPOFOQueue": "0", + "TCPOFODrop": "0", + "TCPOFOMerge": "0", + "TCPChallengeACK": "0", + "TCPSYNChallenge": "0", + "TCPFastOpenActive": "0", + "TCPFastOpenActiveFail": "0", + "TCPFastOpenPassive": "0", + "TCPFastOpenPassiveFail": "0", + "TCPFastOpenListenOverflow": "0", + "TCPFastOpenCookieReqd": "0", + "TCPFastOpenBlackhole": "0", + "TCPSpuriousRtxHostQueues": "0", + "BusyPollRxPackets": "0", + "TCPAutoCorking": "28376", + "TCPFromZeroWindowAdv": "0", + "TCPToZeroWindowAdv": "0", + "TCPWantZeroWindowAdv": "0", + "TCPSynRetrans": "0", + "TCPOrigDataSent": "119438", + "TCPHystartTrainDetect": "3", + "TCPHystartTrainCwnd": "60", + "TCPHystartDelayDetect": "0", + "TCPHystartDelayCwnd": "0", + "TCPACKSkippedSynRecv": "0", + "TCPACKSkippedPAWS": "0", + "TCPACKSkippedSeq": "0", + "TCPACKSkippedFinWait2": "0", + "TCPACKSkippedTimeWait": "0", + "TCPACKSkippedChallenge": "0", + "TCPWinProbe": "0", + "TCPKeepAlive": "6", + "TCPMTUPFail": "0", + "TCPMTUPSuccess": "0", + "TCPDelivered": "119453", + "TCPDeliveredCE": "0", + "TCPAckCompressed": "0", + "TCPZeroWindowDrop": "0", + "TCPRcvQDrop": "0", + "TCPWqueueTooBig": "0", + "TCPFastOpenPassiveAltKey": "0", + "TcpTimeoutRehash": "0", + "TcpDuplicateDataRehash": "0", + "type": "TcpExt" + }, + ... + ] + + + +### parse + +```python +def parse(data: str, raw: bool = False, quiet: bool = False) -> List[Dict] +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + +Returns: + + List of Dictionaries. Raw or processed structured data. + +### Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/lib.py b/jc/lib.py index ec172cd8..0b1a7180 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -129,6 +129,7 @@ parsers = [ 'proc-net-igmp6', 'proc-net-ipv6-route', 'proc-net-netlink', + 'proc-net-netstat', 'ps', 'route', 'rpm-qi', diff --git a/jc/parsers/proc_net_netstat.py b/jc/parsers/proc_net_netstat.py new file mode 100644 index 00000000..55e447b2 --- /dev/null +++ b/jc/parsers/proc_net_netstat.py @@ -0,0 +1,381 @@ +"""jc - JSON Convert `/proc/net/netstat` file parser + +Usage (cli): + + $ cat /proc/net/netstat | jc --proc + +or + + $ jc /proc/net/netstat + +or + + $ cat /proc/net/netstat | jc --proc-net-netstat + +Usage (module): + + import jc + result = jc.parse('proc', proc_net_netstat_file) + +or + + import jc + result = jc.parse('proc_net_netstat', proc_net_netstat_file) + +Schema: + +All values except "type" are integers + + [ + { + "type": string, + "": integer + } + ] + +Examples: + + $ cat /proc/net/netstat | jc --proc -p + [ + { + "SyncookiesSent": 0, + "SyncookiesRecv": 0, + "SyncookiesFailed": 0, + "EmbryonicRsts": 0, + "PruneCalled": 0, + "RcvPruned": 0, + "OfoPruned": 0, + "OutOfWindowIcmps": 0, + "LockDroppedIcmps": 0, + "ArpFilter": 0, + "TW": 3, + "TWRecycled": 0, + "TWKilled": 0, + "PAWSActive": 0, + "PAWSEstab": 0, + "DelayedACKs": 10, + "DelayedACKLocked": 53, + "DelayedACKLost": 0, + "ListenOverflows": 0, + "ListenDrops": 0, + "TCPHPHits": 2387, + "TCPPureAcks": 12711, + "TCPHPAcks": 53535, + "TCPRenoRecovery": 0, + "TCPSackRecovery": 0, + "TCPSACKReneging": 0, + "TCPSACKReorder": 0, + "TCPRenoReorder": 0, + "TCPTSReorder": 0, + "TCPFullUndo": 0, + "TCPPartialUndo": 0, + "TCPDSACKUndo": 0, + "TCPLossUndo": 0, + "TCPLostRetransmit": 0, + "TCPRenoFailures": 0, + "TCPSackFailures": 0, + "TCPLossFailures": 0, + "TCPFastRetrans": 0, + "TCPSlowStartRetrans": 0, + "TCPTimeouts": 0, + "TCPLossProbes": 0, + "TCPLossProbeRecovery": 0, + "TCPRenoRecoveryFail": 0, + "TCPSackRecoveryFail": 0, + "TCPRcvCollapsed": 0, + "TCPBacklogCoalesce": 2883, + "TCPDSACKOldSent": 0, + "TCPDSACKOfoSent": 0, + "TCPDSACKRecv": 0, + "TCPDSACKOfoRecv": 0, + "TCPAbortOnData": 0, + "TCPAbortOnClose": 1, + "TCPAbortOnMemory": 0, + "TCPAbortOnTimeout": 0, + "TCPAbortOnLinger": 0, + "TCPAbortFailed": 0, + "TCPMemoryPressures": 0, + "TCPMemoryPressuresChrono": 0, + "TCPSACKDiscard": 0, + "TCPDSACKIgnoredOld": 0, + "TCPDSACKIgnoredNoUndo": 0, + "TCPSpuriousRTOs": 0, + "TCPMD5NotFound": 0, + "TCPMD5Unexpected": 0, + "TCPMD5Failure": 0, + "TCPSackShifted": 0, + "TCPSackMerged": 0, + "TCPSackShiftFallback": 0, + "TCPBacklogDrop": 0, + "PFMemallocDrop": 0, + "TCPMinTTLDrop": 0, + "TCPDeferAcceptDrop": 0, + "IPReversePathFilter": 0, + "TCPTimeWaitOverflow": 0, + "TCPReqQFullDoCookies": 0, + "TCPReqQFullDrop": 0, + "TCPRetransFail": 0, + "TCPRcvCoalesce": 151, + "TCPOFOQueue": 0, + "TCPOFODrop": 0, + "TCPOFOMerge": 0, + "TCPChallengeACK": 0, + "TCPSYNChallenge": 0, + "TCPFastOpenActive": 0, + "TCPFastOpenActiveFail": 0, + "TCPFastOpenPassive": 0, + "TCPFastOpenPassiveFail": 0, + "TCPFastOpenListenOverflow": 0, + "TCPFastOpenCookieReqd": 0, + "TCPFastOpenBlackhole": 0, + "TCPSpuriousRtxHostQueues": 0, + "BusyPollRxPackets": 0, + "TCPAutoCorking": 28376, + "TCPFromZeroWindowAdv": 0, + "TCPToZeroWindowAdv": 0, + "TCPWantZeroWindowAdv": 0, + "TCPSynRetrans": 0, + "TCPOrigDataSent": 119438, + "TCPHystartTrainDetect": 3, + "TCPHystartTrainCwnd": 60, + "TCPHystartDelayDetect": 0, + "TCPHystartDelayCwnd": 0, + "TCPACKSkippedSynRecv": 0, + "TCPACKSkippedPAWS": 0, + "TCPACKSkippedSeq": 0, + "TCPACKSkippedFinWait2": 0, + "TCPACKSkippedTimeWait": 0, + "TCPACKSkippedChallenge": 0, + "TCPWinProbe": 0, + "TCPKeepAlive": 6, + "TCPMTUPFail": 0, + "TCPMTUPSuccess": 0, + "TCPDelivered": 119453, + "TCPDeliveredCE": 0, + "TCPAckCompressed": 0, + "TCPZeroWindowDrop": 0, + "TCPRcvQDrop": 0, + "TCPWqueueTooBig": 0, + "TCPFastOpenPassiveAltKey": 0, + "TcpTimeoutRehash": 0, + "TcpDuplicateDataRehash": 0, + "type": "TcpExt" + }, + ... + ] + + $ cat /proc/net/netstat | jc --proc -p -r + [ + { + "SyncookiesSent": "0", + "SyncookiesRecv": "0", + "SyncookiesFailed": "0", + "EmbryonicRsts": "0", + "PruneCalled": "0", + "RcvPruned": "0", + "OfoPruned": "0", + "OutOfWindowIcmps": "0", + "LockDroppedIcmps": "0", + "ArpFilter": "0", + "TW": "3", + "TWRecycled": "0", + "TWKilled": "0", + "PAWSActive": "0", + "PAWSEstab": "0", + "DelayedACKs": "10", + "DelayedACKLocked": "53", + "DelayedACKLost": "0", + "ListenOverflows": "0", + "ListenDrops": "0", + "TCPHPHits": "2387", + "TCPPureAcks": "12711", + "TCPHPAcks": "53535", + "TCPRenoRecovery": "0", + "TCPSackRecovery": "0", + "TCPSACKReneging": "0", + "TCPSACKReorder": "0", + "TCPRenoReorder": "0", + "TCPTSReorder": "0", + "TCPFullUndo": "0", + "TCPPartialUndo": "0", + "TCPDSACKUndo": "0", + "TCPLossUndo": "0", + "TCPLostRetransmit": "0", + "TCPRenoFailures": "0", + "TCPSackFailures": "0", + "TCPLossFailures": "0", + "TCPFastRetrans": "0", + "TCPSlowStartRetrans": "0", + "TCPTimeouts": "0", + "TCPLossProbes": "0", + "TCPLossProbeRecovery": "0", + "TCPRenoRecoveryFail": "0", + "TCPSackRecoveryFail": "0", + "TCPRcvCollapsed": "0", + "TCPBacklogCoalesce": "2883", + "TCPDSACKOldSent": "0", + "TCPDSACKOfoSent": "0", + "TCPDSACKRecv": "0", + "TCPDSACKOfoRecv": "0", + "TCPAbortOnData": "0", + "TCPAbortOnClose": "1", + "TCPAbortOnMemory": "0", + "TCPAbortOnTimeout": "0", + "TCPAbortOnLinger": "0", + "TCPAbortFailed": "0", + "TCPMemoryPressures": "0", + "TCPMemoryPressuresChrono": "0", + "TCPSACKDiscard": "0", + "TCPDSACKIgnoredOld": "0", + "TCPDSACKIgnoredNoUndo": "0", + "TCPSpuriousRTOs": "0", + "TCPMD5NotFound": "0", + "TCPMD5Unexpected": "0", + "TCPMD5Failure": "0", + "TCPSackShifted": "0", + "TCPSackMerged": "0", + "TCPSackShiftFallback": "0", + "TCPBacklogDrop": "0", + "PFMemallocDrop": "0", + "TCPMinTTLDrop": "0", + "TCPDeferAcceptDrop": "0", + "IPReversePathFilter": "0", + "TCPTimeWaitOverflow": "0", + "TCPReqQFullDoCookies": "0", + "TCPReqQFullDrop": "0", + "TCPRetransFail": "0", + "TCPRcvCoalesce": "151", + "TCPOFOQueue": "0", + "TCPOFODrop": "0", + "TCPOFOMerge": "0", + "TCPChallengeACK": "0", + "TCPSYNChallenge": "0", + "TCPFastOpenActive": "0", + "TCPFastOpenActiveFail": "0", + "TCPFastOpenPassive": "0", + "TCPFastOpenPassiveFail": "0", + "TCPFastOpenListenOverflow": "0", + "TCPFastOpenCookieReqd": "0", + "TCPFastOpenBlackhole": "0", + "TCPSpuriousRtxHostQueues": "0", + "BusyPollRxPackets": "0", + "TCPAutoCorking": "28376", + "TCPFromZeroWindowAdv": "0", + "TCPToZeroWindowAdv": "0", + "TCPWantZeroWindowAdv": "0", + "TCPSynRetrans": "0", + "TCPOrigDataSent": "119438", + "TCPHystartTrainDetect": "3", + "TCPHystartTrainCwnd": "60", + "TCPHystartDelayDetect": "0", + "TCPHystartDelayCwnd": "0", + "TCPACKSkippedSynRecv": "0", + "TCPACKSkippedPAWS": "0", + "TCPACKSkippedSeq": "0", + "TCPACKSkippedFinWait2": "0", + "TCPACKSkippedTimeWait": "0", + "TCPACKSkippedChallenge": "0", + "TCPWinProbe": "0", + "TCPKeepAlive": "6", + "TCPMTUPFail": "0", + "TCPMTUPSuccess": "0", + "TCPDelivered": "119453", + "TCPDeliveredCE": "0", + "TCPAckCompressed": "0", + "TCPZeroWindowDrop": "0", + "TCPRcvQDrop": "0", + "TCPWqueueTooBig": "0", + "TCPFastOpenPassiveAltKey": "0", + "TcpTimeoutRehash": "0", + "TcpDuplicateDataRehash": "0", + "type": "TcpExt" + }, + ... + ] +""" +from typing import List, Dict +import jc.utils +from jc.parsers.universal import simple_table_parse + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`/proc/net/netstat` file parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] + hidden = True + + +__version__ = info.version + + +def _process(proc_data: List[Dict]) -> List[Dict]: + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (List of Dictionaries) raw structured data to process + + Returns: + + List of Dictionaries. Structured to conform to the schema. + """ + for item in proc_data: + for key, val in item.items(): + if key != 'type': + item[key] = int(val) + + return proc_data + + +def parse( + data: str, + raw: bool = False, + quiet: bool = False +) -> List[Dict]: + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + + Returns: + + List of Dictionaries. Raw or processed structured data. + """ + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) + + raw_output: List = [] + rows: List = [] + this_row: str = '' + headers: str = '' + + if jc.utils.has_data(data): + + for line in filter(None, data.splitlines()): + row_name, header_data = line.split(':', maxsplit=1) + + if row_name in rows: + # this is data + _, row_data = line.split(':', maxsplit=1) + data_table = headers + row_data + output_line = simple_table_parse(data_table.splitlines()) + output_line[0]['type'] = this_row + raw_output.extend(output_line) + continue + + else: + # this is a header row + rows.append(row_name) + this_row = row_name + headers = header_data + '\n' + continue + + return raw_output if raw else _process(raw_output) diff --git a/man/jc.1 b/man/jc.1 index 28ce203d..52fd0d40 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -630,6 +630,11 @@ PLIST file parser \fB--proc-net-netlink\fP `/proc/net/netlink` file parser +.TP +.B +\fB--proc-net-netstat\fP +`/proc/net/netstat` file parser + .TP .B \fB--ps\fP diff --git a/tests/fixtures/linux-proc/net_netstat.json b/tests/fixtures/linux-proc/net_netstat.json new file mode 100644 index 00000000..922a442a --- /dev/null +++ b/tests/fixtures/linux-proc/net_netstat.json @@ -0,0 +1 @@ +[{"SyncookiesSent":0,"SyncookiesRecv":0,"SyncookiesFailed":0,"EmbryonicRsts":0,"PruneCalled":0,"RcvPruned":0,"OfoPruned":0,"OutOfWindowIcmps":0,"LockDroppedIcmps":0,"ArpFilter":0,"TW":3,"TWRecycled":0,"TWKilled":0,"PAWSActive":0,"PAWSEstab":0,"DelayedACKs":10,"DelayedACKLocked":53,"DelayedACKLost":0,"ListenOverflows":0,"ListenDrops":0,"TCPHPHits":2387,"TCPPureAcks":12711,"TCPHPAcks":53535,"TCPRenoRecovery":0,"TCPSackRecovery":0,"TCPSACKReneging":0,"TCPSACKReorder":0,"TCPRenoReorder":0,"TCPTSReorder":0,"TCPFullUndo":0,"TCPPartialUndo":0,"TCPDSACKUndo":0,"TCPLossUndo":0,"TCPLostRetransmit":0,"TCPRenoFailures":0,"TCPSackFailures":0,"TCPLossFailures":0,"TCPFastRetrans":0,"TCPSlowStartRetrans":0,"TCPTimeouts":0,"TCPLossProbes":0,"TCPLossProbeRecovery":0,"TCPRenoRecoveryFail":0,"TCPSackRecoveryFail":0,"TCPRcvCollapsed":0,"TCPBacklogCoalesce":2883,"TCPDSACKOldSent":0,"TCPDSACKOfoSent":0,"TCPDSACKRecv":0,"TCPDSACKOfoRecv":0,"TCPAbortOnData":0,"TCPAbortOnClose":1,"TCPAbortOnMemory":0,"TCPAbortOnTimeout":0,"TCPAbortOnLinger":0,"TCPAbortFailed":0,"TCPMemoryPressures":0,"TCPMemoryPressuresChrono":0,"TCPSACKDiscard":0,"TCPDSACKIgnoredOld":0,"TCPDSACKIgnoredNoUndo":0,"TCPSpuriousRTOs":0,"TCPMD5NotFound":0,"TCPMD5Unexpected":0,"TCPMD5Failure":0,"TCPSackShifted":0,"TCPSackMerged":0,"TCPSackShiftFallback":0,"TCPBacklogDrop":0,"PFMemallocDrop":0,"TCPMinTTLDrop":0,"TCPDeferAcceptDrop":0,"IPReversePathFilter":0,"TCPTimeWaitOverflow":0,"TCPReqQFullDoCookies":0,"TCPReqQFullDrop":0,"TCPRetransFail":0,"TCPRcvCoalesce":151,"TCPOFOQueue":0,"TCPOFODrop":0,"TCPOFOMerge":0,"TCPChallengeACK":0,"TCPSYNChallenge":0,"TCPFastOpenActive":0,"TCPFastOpenActiveFail":0,"TCPFastOpenPassive":0,"TCPFastOpenPassiveFail":0,"TCPFastOpenListenOverflow":0,"TCPFastOpenCookieReqd":0,"TCPFastOpenBlackhole":0,"TCPSpuriousRtxHostQueues":0,"BusyPollRxPackets":0,"TCPAutoCorking":28376,"TCPFromZeroWindowAdv":0,"TCPToZeroWindowAdv":0,"TCPWantZeroWindowAdv":0,"TCPSynRetrans":0,"TCPOrigDataSent":119438,"TCPHystartTrainDetect":3,"TCPHystartTrainCwnd":60,"TCPHystartDelayDetect":0,"TCPHystartDelayCwnd":0,"TCPACKSkippedSynRecv":0,"TCPACKSkippedPAWS":0,"TCPACKSkippedSeq":0,"TCPACKSkippedFinWait2":0,"TCPACKSkippedTimeWait":0,"TCPACKSkippedChallenge":0,"TCPWinProbe":0,"TCPKeepAlive":6,"TCPMTUPFail":0,"TCPMTUPSuccess":0,"TCPDelivered":119453,"TCPDeliveredCE":0,"TCPAckCompressed":0,"TCPZeroWindowDrop":0,"TCPRcvQDrop":0,"TCPWqueueTooBig":0,"TCPFastOpenPassiveAltKey":0,"TcpTimeoutRehash":0,"TcpDuplicateDataRehash":0,"type":"TcpExt"},{"InNoRoutes":0,"InTruncatedPkts":0,"InMcastPkts":0,"OutMcastPkts":0,"InBcastPkts":366,"OutBcastPkts":0,"InOctets":57734503,"OutOctets":42330709,"InMcastOctets":0,"OutMcastOctets":0,"InBcastOctets":31466,"OutBcastOctets":0,"InCsumErrors":0,"InNoECTPkts":106821,"InECT1Pkts":0,"InECT0Pkts":3273,"InCEPkts":0,"ReasmOverlaps":0,"type":"IpExt"},{"MPCapableSYNRX":0,"MPCapableACKRX":0,"MPCapableFallbackACK":0,"MPCapableFallbackSYNACK":0,"MPTCPRetrans":0,"MPJoinNoTokenFound":0,"MPJoinSynRx":0,"MPJoinSynAckRx":0,"MPJoinSynAckHMacFailure":0,"MPJoinAckRx":0,"MPJoinAckHMacFailure":0,"DSSNotMatching":0,"InfiniteMapRx":0,"type":"MPTcpExt"}] diff --git a/tests/test_proc_net_netstat.py b/tests/test_proc_net_netstat.py new file mode 100644 index 00000000..10e5e9fa --- /dev/null +++ b/tests/test_proc_net_netstat.py @@ -0,0 +1,44 @@ +import os +import unittest +import json +from typing import Dict +import jc.parsers.proc_net_netstat + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class MyTests(unittest.TestCase): + f_in: Dict = {} + f_json: Dict = {} + + @classmethod + def setUpClass(cls): + fixtures = { + 'proc_net_netstat': ( + 'fixtures/linux-proc/net_netstat', + 'fixtures/linux-proc/net_netstat.json') + } + + for file, filepaths in fixtures.items(): + with open(os.path.join(THIS_DIR, filepaths[0]), 'r', encoding='utf-8') as a, \ + open(os.path.join(THIS_DIR, filepaths[1]), 'r', encoding='utf-8') as b: + cls.f_in[file] = a.read() + cls.f_json[file] = json.loads(b.read()) + + + def test_proc_net_netstat_nodata(self): + """ + Test 'proc_net_netstat' with no data + """ + self.assertEqual(jc.parsers.proc_net_netstat.parse('', quiet=True), []) + + def test_proc_net_netstat(self): + """ + Test '/proc/net/netstat' + """ + self.assertEqual(jc.parsers.proc_net_netstat.parse(self.f_in['proc_net_netstat'], quiet=True), + self.f_json['proc_net_netstat']) + + +if __name__ == '__main__': + unittest.main()