From caaeaf0d67cf44f8d2651cc53a7528d3ef0c74d3 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 29 Nov 2021 16:29:23 -0800 Subject: [PATCH 01/33] add 'str' type check on input --- jc/parsers/acpi.py | 6 +++--- jc/parsers/airport.py | 6 +++--- jc/parsers/airport_s.py | 6 +++--- jc/parsers/arp.py | 6 +++--- jc/parsers/blkid.py | 6 +++--- jc/parsers/cksum.py | 6 +++--- jc/parsers/crontab.py | 6 +++--- jc/parsers/crontab_u.py | 6 +++--- jc/parsers/csv.py | 6 +++--- jc/parsers/date.py | 6 +++--- jc/parsers/df.py | 6 +++--- jc/parsers/dig.py | 6 +++--- jc/parsers/dir.py | 6 +++--- jc/parsers/dmidecode.py | 6 +++--- jc/parsers/dpkg_l.py | 6 +++--- jc/parsers/du.py | 6 +++--- jc/parsers/env.py | 6 +++--- jc/parsers/file.py | 6 +++--- jc/parsers/finger.py | 6 +++--- jc/parsers/foo.py | 4 ++-- jc/parsers/free.py | 6 +++--- jc/parsers/fstab.py | 6 +++--- jc/parsers/group.py | 6 +++--- jc/parsers/gshadow.py | 6 +++--- jc/parsers/hash.py | 6 +++--- jc/parsers/hashsum.py | 6 +++--- jc/parsers/hciconfig.py | 6 +++--- jc/parsers/history.py | 6 +++--- jc/parsers/hosts.py | 6 +++--- jc/parsers/id.py | 6 +++--- jc/parsers/ifconfig.py | 6 +++--- jc/parsers/ini.py | 6 +++--- jc/parsers/iptables.py | 6 +++--- jc/parsers/iw_scan.py | 6 +++--- jc/parsers/jobs.py | 6 +++--- jc/parsers/last.py | 6 +++--- jc/parsers/ls.py | 6 +++--- jc/parsers/lsblk.py | 6 +++--- jc/parsers/lsmod.py | 6 +++--- jc/parsers/lsof.py | 6 +++--- jc/parsers/lsusb.py | 6 +++--- jc/parsers/mount.py | 6 +++--- jc/parsers/netstat.py | 6 +++--- jc/parsers/ntpq.py | 6 +++--- jc/parsers/passwd.py | 6 +++--- jc/parsers/ping.py | 6 +++--- jc/parsers/pip_list.py | 6 +++--- jc/parsers/pip_show.py | 6 +++--- jc/parsers/ps.py | 6 +++--- jc/parsers/route.py | 6 +++--- jc/parsers/rpm_qi.py | 6 +++--- jc/parsers/sfdisk.py | 6 +++--- jc/parsers/shadow.py | 6 +++--- jc/parsers/ss.py | 6 +++--- jc/parsers/stat.py | 6 +++--- jc/parsers/sysctl.py | 6 +++--- jc/parsers/systemctl.py | 6 +++--- jc/parsers/systemctl_lj.py | 6 +++--- jc/parsers/systemctl_ls.py | 6 +++--- jc/parsers/systemctl_luf.py | 6 +++--- jc/parsers/systeminfo.py | 6 +++--- jc/parsers/time.py | 6 +++--- jc/parsers/timedatectl.py | 6 +++--- jc/parsers/tracepath.py | 6 +++--- jc/parsers/traceroute.py | 6 +++--- jc/parsers/ufw.py | 6 +++--- jc/parsers/ufw_appinfo.py | 6 +++--- jc/parsers/uname.py | 6 +++--- jc/parsers/upower.py | 6 +++--- jc/parsers/uptime.py | 6 +++--- jc/parsers/vmstat.py | 6 +++--- jc/parsers/w.py | 6 +++--- jc/parsers/wc.py | 6 +++--- jc/parsers/who.py | 6 +++--- jc/parsers/xml.py | 6 +++--- jc/parsers/yaml.py | 6 +++--- 76 files changed, 227 insertions(+), 227 deletions(-) diff --git a/jc/parsers/acpi.py b/jc/parsers/acpi.py index 2125c38e..76e1e620 100644 --- a/jc/parsers/acpi.py +++ b/jc/parsers/acpi.py @@ -227,7 +227,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`acpi` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -302,8 +302,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] output_line = {} diff --git a/jc/parsers/airport.py b/jc/parsers/airport.py index f541316d..c4830d07 100644 --- a/jc/parsers/airport.py +++ b/jc/parsers/airport.py @@ -80,7 +80,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`airport -I` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -130,8 +130,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/airport_s.py b/jc/parsers/airport_s.py index 28ccc380..5c9cb96b 100644 --- a/jc/parsers/airport_s.py +++ b/jc/parsers/airport_s.py @@ -109,7 +109,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`airport -s` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -166,8 +166,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/arp.py b/jc/parsers/arp.py index fe45ea2b..1327fdde 100644 --- a/jc/parsers/arp.py +++ b/jc/parsers/arp.py @@ -118,7 +118,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.7' + version = '1.8' description = '`arp` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -171,8 +171,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/blkid.py b/jc/parsers/blkid.py index 6c4d7ab1..ab148137 100644 --- a/jc/parsers/blkid.py +++ b/jc/parsers/blkid.py @@ -121,7 +121,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`blkid` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -176,8 +176,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/cksum.py b/jc/parsers/cksum.py index 541abb82..66bc65e4 100644 --- a/jc/parsers/cksum.py +++ b/jc/parsers/cksum.py @@ -54,7 +54,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`cksum` and `sum` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -103,8 +103,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/crontab.py b/jc/parsers/crontab.py index ea71ce08..f8276c9b 100644 --- a/jc/parsers/crontab.py +++ b/jc/parsers/crontab.py @@ -171,7 +171,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`crontab` command and file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -225,8 +225,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/crontab_u.py b/jc/parsers/crontab_u.py index d8697e05..097f2cb2 100644 --- a/jc/parsers/crontab_u.py +++ b/jc/parsers/crontab_u.py @@ -167,7 +167,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`crontab` file parser with user support' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -220,8 +220,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/csv.py b/jc/parsers/csv.py index 1f87ff9f..68ecdcbe 100644 --- a/jc/parsers/csv.py +++ b/jc/parsers/csv.py @@ -75,7 +75,7 @@ import csv class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = 'CSV file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -119,8 +119,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/date.py b/jc/parsers/date.py index 3dd2ae1c..0db77cdc 100644 --- a/jc/parsers/date.py +++ b/jc/parsers/date.py @@ -72,7 +72,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '2.1' + version = '2.2' description = '`date` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -115,8 +115,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/df.py b/jc/parsers/df.py index 19cca3d8..64972527 100644 --- a/jc/parsers/df.py +++ b/jc/parsers/df.py @@ -99,7 +99,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.8' + version = '1.9' description = '`df` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -204,8 +204,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() fix_data = [] diff --git a/jc/parsers/dig.py b/jc/parsers/dig.py index 5c485a7a..3d7120bc 100644 --- a/jc/parsers/dig.py +++ b/jc/parsers/dig.py @@ -316,7 +316,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '2.1' + version = '2.2' description = '`dig` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -529,8 +529,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/dir.py b/jc/parsers/dir.py index ae1d2639..a433ae84 100644 --- a/jc/parsers/dir.py +++ b/jc/parsers/dir.py @@ -119,7 +119,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`dir` command parser' author = 'Rasheed Elsaleh' author_email = 'rasheed@rebelliondefense.com' @@ -173,8 +173,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/dmidecode.py b/jc/parsers/dmidecode.py index b03dfff7..453a0edf 100644 --- a/jc/parsers/dmidecode.py +++ b/jc/parsers/dmidecode.py @@ -125,7 +125,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`dmidecode` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -177,8 +177,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") item_header = False item_values = False diff --git a/jc/parsers/dpkg_l.py b/jc/parsers/dpkg_l.py index f39e7cb5..37b2f6d6 100644 --- a/jc/parsers/dpkg_l.py +++ b/jc/parsers/dpkg_l.py @@ -131,7 +131,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.1' + version = '1.2' description = '`dpkg -l` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -217,8 +217,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") working_list = [] raw_output = [] diff --git a/jc/parsers/du.py b/jc/parsers/du.py index 5774f615..fac3b902 100644 --- a/jc/parsers/du.py +++ b/jc/parsers/du.py @@ -88,7 +88,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`du` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -137,8 +137,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/env.py b/jc/parsers/env.py index 072f91ae..bdf62e97 100644 --- a/jc/parsers/env.py +++ b/jc/parsers/env.py @@ -69,7 +69,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`env` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -121,8 +121,8 @@ def parse(data, raw=False, quiet=False): Dictionary of raw structured data or List of Dictionaries of processed structured data """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/file.py b/jc/parsers/file.py index 2af927c7..4a7f782e 100644 --- a/jc/parsers/file.py +++ b/jc/parsers/file.py @@ -63,7 +63,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`file` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -106,8 +106,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/finger.py b/jc/parsers/finger.py index 1bd2b270..66b5fccc 100644 --- a/jc/parsers/finger.py +++ b/jc/parsers/finger.py @@ -92,7 +92,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.1' + version = '1.2' description = '`finger` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -168,8 +168,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/foo.py b/jc/parsers/foo.py index ee5cf395..3520c74e 100644 --- a/jc/parsers/foo.py +++ b/jc/parsers/foo.py @@ -86,8 +86,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/free.py b/jc/parsers/free.py index b1d4db9d..6e1ab404 100644 --- a/jc/parsers/free.py +++ b/jc/parsers/free.py @@ -73,7 +73,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`free` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -122,8 +122,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/fstab.py b/jc/parsers/fstab.py index d7522c75..f1ce977b 100644 --- a/jc/parsers/fstab.py +++ b/jc/parsers/fstab.py @@ -85,7 +85,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`/etc/fstab` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -132,8 +132,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/group.py b/jc/parsers/group.py index fe554df9..b38360ea 100644 --- a/jc/parsers/group.py +++ b/jc/parsers/group.py @@ -109,7 +109,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`/etc/group` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -160,8 +160,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/gshadow.py b/jc/parsers/gshadow.py index 4f3c01eb..a4eeff68 100644 --- a/jc/parsers/gshadow.py +++ b/jc/parsers/gshadow.py @@ -77,7 +77,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`/etc/gshadow` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -126,8 +126,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/hash.py b/jc/parsers/hash.py index 2fd7d0d4..a753776a 100644 --- a/jc/parsers/hash.py +++ b/jc/parsers/hash.py @@ -38,7 +38,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`hash` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -85,8 +85,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/hashsum.py b/jc/parsers/hashsum.py index 87d6fb21..ac29d8da 100644 --- a/jc/parsers/hashsum.py +++ b/jc/parsers/hashsum.py @@ -68,7 +68,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.1' + version = '1.2' description = 'hashsum command parser (`md5sum`, `shasum`, etc.)' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -113,8 +113,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/hciconfig.py b/jc/parsers/hciconfig.py index 70d247fe..c48806fe 100644 --- a/jc/parsers/hciconfig.py +++ b/jc/parsers/hciconfig.py @@ -317,7 +317,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`hciconfig` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -372,8 +372,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] device_object = {} diff --git a/jc/parsers/history.py b/jc/parsers/history.py index 88016928..7401e188 100644 --- a/jc/parsers/history.py +++ b/jc/parsers/history.py @@ -59,7 +59,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`history` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -109,8 +109,8 @@ def parse(data, raw=False, quiet=False): Dictionary of raw structured data or List of Dictionaries of processed structured data """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/hosts.py b/jc/parsers/hosts.py index c1c397b2..f64ed7e8 100644 --- a/jc/parsers/hosts.py +++ b/jc/parsers/hosts.py @@ -74,7 +74,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`/etc/hosts` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -117,8 +117,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/id.py b/jc/parsers/id.py index c3f54e44..4a16ad41 100644 --- a/jc/parsers/id.py +++ b/jc/parsers/id.py @@ -105,7 +105,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`id` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -161,8 +161,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/ifconfig.py b/jc/parsers/ifconfig.py index bd73cfde..d3b37384 100644 --- a/jc/parsers/ifconfig.py +++ b/jc/parsers/ifconfig.py @@ -188,7 +188,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.10' + version = '1.11' description = '`ifconfig` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -474,8 +474,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/ini.py b/jc/parsers/ini.py index 2c4d12eb..0f9a4a0a 100644 --- a/jc/parsers/ini.py +++ b/jc/parsers/ini.py @@ -66,7 +66,7 @@ import configparser class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = 'INI file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -125,8 +125,8 @@ def parse(data, raw=False, quiet=False): Dictionary representing the ini file """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/iptables.py b/jc/parsers/iptables.py index e59e6fa7..9575ed41 100644 --- a/jc/parsers/iptables.py +++ b/jc/parsers/iptables.py @@ -163,7 +163,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`iptables` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -240,8 +240,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] chain = {} diff --git a/jc/parsers/iw_scan.py b/jc/parsers/iw_scan.py index a16513f0..a0d20f9a 100644 --- a/jc/parsers/iw_scan.py +++ b/jc/parsers/iw_scan.py @@ -121,7 +121,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '0.6' + version = '0.7' description = '`iw dev [device] scan` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -293,8 +293,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] section = {} diff --git a/jc/parsers/jobs.py b/jc/parsers/jobs.py index a920d7bb..1410a7c4 100644 --- a/jc/parsers/jobs.py +++ b/jc/parsers/jobs.py @@ -93,7 +93,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`jobs` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -141,8 +141,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/last.py b/jc/parsers/last.py index 84969db2..f54cbf18 100644 --- a/jc/parsers/last.py +++ b/jc/parsers/last.py @@ -104,7 +104,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.7' + version = '1.8' description = '`last` and `lastb` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -185,8 +185,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/ls.py b/jc/parsers/ls.py index d9f385d4..17b7a1bb 100644 --- a/jc/parsers/ls.py +++ b/jc/parsers/ls.py @@ -107,7 +107,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.9' + version = '1.10' description = '`ls` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -162,8 +162,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] warned = False diff --git a/jc/parsers/lsblk.py b/jc/parsers/lsblk.py index b835d1fd..39d12efe 100644 --- a/jc/parsers/lsblk.py +++ b/jc/parsers/lsblk.py @@ -269,7 +269,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.7' + version = '1.8' description = '`lsblk` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -321,8 +321,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/lsmod.py b/jc/parsers/lsmod.py index 07b07cdd..7d89cc5e 100644 --- a/jc/parsers/lsmod.py +++ b/jc/parsers/lsmod.py @@ -126,7 +126,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`lsmod` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -174,8 +174,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/lsof.py b/jc/parsers/lsof.py index 8115763d..02a3fdca 100644 --- a/jc/parsers/lsof.py +++ b/jc/parsers/lsof.py @@ -120,7 +120,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`lsof` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -168,8 +168,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/lsusb.py b/jc/parsers/lsusb.py index e2fb6a31..a71caab6 100644 --- a/jc/parsers/lsusb.py +++ b/jc/parsers/lsusb.py @@ -262,7 +262,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = '`lsusb` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -815,8 +815,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") lsusb = _LsUsb() diff --git a/jc/parsers/mount.py b/jc/parsers/mount.py index 1fa47038..7f26082a 100644 --- a/jc/parsers/mount.py +++ b/jc/parsers/mount.py @@ -75,7 +75,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`mount` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -163,8 +163,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/netstat.py b/jc/parsers/netstat.py index a5db5120..5267ddd8 100644 --- a/jc/parsers/netstat.py +++ b/jc/parsers/netstat.py @@ -354,7 +354,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.11' + version = '1.12' description = '`netstat` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -424,8 +424,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ import jc.utils - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = list(filter(None, data.splitlines())) raw_output = [] diff --git a/jc/parsers/ntpq.py b/jc/parsers/ntpq.py index 4d2a8aef..82ed9797 100644 --- a/jc/parsers/ntpq.py +++ b/jc/parsers/ntpq.py @@ -207,7 +207,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`ntpq -p` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -264,8 +264,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/passwd.py b/jc/parsers/passwd.py index acb5d616..fa04c456 100644 --- a/jc/parsers/passwd.py +++ b/jc/parsers/passwd.py @@ -94,7 +94,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`/etc/passwd` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -142,8 +142,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index c4600aec..06129d8a 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -158,7 +158,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`ping` and `ping6` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -616,8 +616,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/pip_list.py b/jc/parsers/pip_list.py index eafcf176..80d76f8a 100644 --- a/jc/parsers/pip_list.py +++ b/jc/parsers/pip_list.py @@ -48,7 +48,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`pip list` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -91,8 +91,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/pip_show.py b/jc/parsers/pip_show.py index 023730c5..14c5ec16 100644 --- a/jc/parsers/pip_show.py +++ b/jc/parsers/pip_show.py @@ -65,7 +65,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`pip show` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -108,8 +108,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] package = {} diff --git a/jc/parsers/ps.py b/jc/parsers/ps.py index bf8e4749..7fc067ad 100644 --- a/jc/parsers/ps.py +++ b/jc/parsers/ps.py @@ -207,7 +207,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`ps` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -276,8 +276,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/route.py b/jc/parsers/route.py index a3516e77..118e1fb0 100644 --- a/jc/parsers/route.py +++ b/jc/parsers/route.py @@ -109,7 +109,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`route` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -180,8 +180,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines()[1:] diff --git a/jc/parsers/rpm_qi.py b/jc/parsers/rpm_qi.py index e63f63a0..49729c8e 100644 --- a/jc/parsers/rpm_qi.py +++ b/jc/parsers/rpm_qi.py @@ -156,7 +156,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`rpm -qi` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -216,8 +216,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] entry_obj = {} diff --git a/jc/parsers/sfdisk.py b/jc/parsers/sfdisk.py index 91f7041a..28b9f512 100644 --- a/jc/parsers/sfdisk.py +++ b/jc/parsers/sfdisk.py @@ -201,7 +201,7 @@ import jc.parsers.universal class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.1' + version = '1.2' description = '`sfdisk` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -265,8 +265,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] item = {} diff --git a/jc/parsers/shadow.py b/jc/parsers/shadow.py index ebaae347..9bd4fdf4 100644 --- a/jc/parsers/shadow.py +++ b/jc/parsers/shadow.py @@ -101,7 +101,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`/etc/shadow` file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -149,8 +149,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/ss.py b/jc/parsers/ss.py index 62d3fc2c..730f3b30 100644 --- a/jc/parsers/ss.py +++ b/jc/parsers/ss.py @@ -279,7 +279,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`ss` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -337,8 +337,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") contains_colon = ['nl', 'p_raw', 'raw', 'udp', 'tcp', 'v_str', 'icmp6'] raw_output = [] diff --git a/jc/parsers/stat.py b/jc/parsers/stat.py index 6ed8e6cc..6837f79b 100644 --- a/jc/parsers/stat.py +++ b/jc/parsers/stat.py @@ -169,7 +169,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.9' + version = '1.10' description = '`stat` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -229,8 +229,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/sysctl.py b/jc/parsers/sysctl.py index e29e3322..73352d27 100644 --- a/jc/parsers/sysctl.py +++ b/jc/parsers/sysctl.py @@ -54,7 +54,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.1' + version = '1.2' description = '`sysctl` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -105,8 +105,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/systemctl.py b/jc/parsers/systemctl.py index 1a399296..613f2a43 100644 --- a/jc/parsers/systemctl.py +++ b/jc/parsers/systemctl.py @@ -58,7 +58,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`systemctl` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -101,8 +101,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_lj.py b/jc/parsers/systemctl_lj.py index ee0a701d..73bc0959 100644 --- a/jc/parsers/systemctl_lj.py +++ b/jc/parsers/systemctl_lj.py @@ -75,7 +75,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`systemctl list-jobs` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -123,8 +123,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_ls.py b/jc/parsers/systemctl_ls.py index de876419..18a52ee1 100644 --- a/jc/parsers/systemctl_ls.py +++ b/jc/parsers/systemctl_ls.py @@ -50,7 +50,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`systemctl list-sockets` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -93,8 +93,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_luf.py b/jc/parsers/systemctl_luf.py index 032df43d..6556a178 100644 --- a/jc/parsers/systemctl_luf.py +++ b/jc/parsers/systemctl_luf.py @@ -46,7 +46,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`systemctl list-unit-files` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -89,8 +89,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systeminfo.py b/jc/parsers/systeminfo.py index c8f6cc9e..ca95c0c2 100644 --- a/jc/parsers/systeminfo.py +++ b/jc/parsers/systeminfo.py @@ -205,7 +205,7 @@ import jc.utils class info: """Provides parser metadata (version, author, etc.)""" - version = "1.0" + version = "1.1" description = "`systeminfo` command parser" author = "Jon Smith" author_email = "jon@rebelliondefense.com" @@ -303,8 +303,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") delim = ":" # k/v delimiter raw_data = {} # intermediary output diff --git a/jc/parsers/time.py b/jc/parsers/time.py index 99511e33..05d1f835 100644 --- a/jc/parsers/time.py +++ b/jc/parsers/time.py @@ -123,7 +123,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`/usr/bin/time` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -198,8 +198,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/timedatectl.py b/jc/parsers/timedatectl.py index b1f99845..b585e855 100644 --- a/jc/parsers/timedatectl.py +++ b/jc/parsers/timedatectl.py @@ -63,7 +63,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`timedatectl status` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -116,8 +116,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/tracepath.py b/jc/parsers/tracepath.py index 24b226a3..748cf9ce 100644 --- a/jc/parsers/tracepath.py +++ b/jc/parsers/tracepath.py @@ -132,7 +132,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`tracepath` and `tracepath6` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -192,8 +192,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") RE_TTL_HOST = re.compile(r'^\s?(?P\d+)(?P\??):\s+(?P(?:no reply|\S+))') # groups: ttl, ttl_guess, host RE_PMTU = re.compile(r'\spmtu\s(?P[\d]+)') # group: pmtu diff --git a/jc/parsers/traceroute.py b/jc/parsers/traceroute.py index 740a06a6..3094dce9 100644 --- a/jc/parsers/traceroute.py +++ b/jc/parsers/traceroute.py @@ -119,7 +119,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.3' + version = '1.4' description = '`traceroute` and `traceroute6` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -368,8 +368,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index c4ae15c2..5965c433 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -199,7 +199,7 @@ import ipaddress class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = '`ufw status` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -394,8 +394,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} rules_list = [] diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index ecde58c1..4885dc14 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -130,7 +130,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = '`ufw app info [application]` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -265,8 +265,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] item_obj = {} diff --git a/jc/parsers/uname.py b/jc/parsers/uname.py index bd03582d..1c89c4a8 100644 --- a/jc/parsers/uname.py +++ b/jc/parsers/uname.py @@ -48,7 +48,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.6' + version = '1.7' description = '`uname -a` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -91,8 +91,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} diff --git a/jc/parsers/upower.py b/jc/parsers/upower.py index ebc92efc..aa55f12e 100644 --- a/jc/parsers/upower.py +++ b/jc/parsers/upower.py @@ -194,7 +194,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`upower` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -323,8 +323,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] device_obj = {} diff --git a/jc/parsers/uptime.py b/jc/parsers/uptime.py index cccf78d0..f7ae11de 100644 --- a/jc/parsers/uptime.py +++ b/jc/parsers/uptime.py @@ -65,7 +65,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = '`uptime` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -155,8 +155,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/vmstat.py b/jc/parsers/vmstat.py index 7978d4ba..6a261d4b 100644 --- a/jc/parsers/vmstat.py +++ b/jc/parsers/vmstat.py @@ -121,7 +121,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = '`vmstat` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -181,8 +181,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] output_line = {} diff --git a/jc/parsers/w.py b/jc/parsers/w.py index 65682166..4fcd93c3 100644 --- a/jc/parsers/w.py +++ b/jc/parsers/w.py @@ -104,7 +104,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`w` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -153,8 +153,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") cleandata = data.splitlines()[1:] raw_output = [] diff --git a/jc/parsers/wc.py b/jc/parsers/wc.py index 6a3c4f4d..7eddfc15 100644 --- a/jc/parsers/wc.py +++ b/jc/parsers/wc.py @@ -54,7 +54,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.2' + version = '1.3' description = '`wc` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -103,8 +103,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/who.py b/jc/parsers/who.py index bf55caf5..e0be6286 100644 --- a/jc/parsers/who.py +++ b/jc/parsers/who.py @@ -133,7 +133,7 @@ import jc.utils class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.4' + version = '1.5' description = '`who` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -186,8 +186,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/xml.py b/jc/parsers/xml.py index 6db0b590..1ac5971a 100644 --- a/jc/parsers/xml.py +++ b/jc/parsers/xml.py @@ -71,7 +71,7 @@ from jc.exceptions import LibraryNotInstalled class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = 'XML file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -121,8 +121,8 @@ def parse(data, raw=False, quiet=False): except Exception: raise LibraryNotInstalled('The xmltodict library is not installed.') - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] diff --git a/jc/parsers/yaml.py b/jc/parsers/yaml.py index bfcbe85a..89a1d374 100644 --- a/jc/parsers/yaml.py +++ b/jc/parsers/yaml.py @@ -85,7 +85,7 @@ from jc.exceptions import LibraryNotInstalled class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.5' + version = '1.6' description = 'YAML file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -135,8 +135,8 @@ def parse(data, raw=False, quiet=False): except Exception: raise LibraryNotInstalled('The ruamel.yaml library is not installed.') - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") raw_output = [] From e395142e599aa78b4a7ec80dcc3f8ccf279f97b1 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 29 Nov 2021 16:45:22 -0800 Subject: [PATCH 02/33] version bump --- CHANGELOG | 3 +++ jc/__init__.py | 2 +- setup.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4ec0e106..4c387050 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ jc changelog +20211129 v1.17.3 +- Update parsers to exit with error if non-string input is detected (raise TypeError) + 20211117 v1.17.2 - Fix ping parser to add Alpine linux support - Fix netstat parser for older versions of netstat on linux diff --git a/jc/__init__.py b/jc/__init__.py index e4c2b5bd..c7a39794 100644 --- a/jc/__init__.py +++ b/jc/__init__.py @@ -73,4 +73,4 @@ Module Example: """ name = 'jc' -__version__ = '1.17.2' +__version__ = '1.17.3' diff --git a/setup.py b/setup.py index 67bf22f4..c9ed7588 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r') as f: setuptools.setup( name='jc', - version='1.17.2', + version='1.17.3', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Converts the output of popular command-line tools and file-types to JSON.', From 8a46a259a36efc55bb0b2141acb9dd5ae52b7725 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 09:19:51 -0800 Subject: [PATCH 03/33] add input type checks --- jc/parsers/ping_s.py | 8 +++++--- tests/test_ping_s.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/jc/parsers/ping_s.py b/jc/parsers/ping_s.py index 1f335c4e..68677fe8 100644 --- a/jc/parsers/ping_s.py +++ b/jc/parsers/ping_s.py @@ -468,14 +468,16 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): """ s = _state() - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") for line in data: - output_line = {} try: + if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + # skip blank lines if line.strip() == '': continue diff --git a/tests/test_ping_s.py b/tests/test_ping_s.py index 579fef3f..c1eaa63b 100644 --- a/tests/test_ping_s.py +++ b/tests/test_ping_s.py @@ -397,7 +397,7 @@ class MyTests(unittest.TestCase): """ Test 'ping' with no data """ - self.assertEqual(list(jc.parsers.ping_s.parse('', quiet=True)), []) + self.assertEqual(list(jc.parsers.ping_s.parse([], quiet=True)), []) def test_ping_s_unparsable(self): data = 'unparsable data' From 975cf195cc02774f50460ca479d9ebb7b73c7870 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 09:40:49 -0800 Subject: [PATCH 04/33] formatting --- jc/parsers/ping_s.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jc/parsers/ping_s.py b/jc/parsers/ping_s.py index 68677fe8..ba242800 100644 --- a/jc/parsers/ping_s.py +++ b/jc/parsers/ping_s.py @@ -474,7 +474,6 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): for line in data: output_line = {} - try: if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") From cfb58b1cf3e3028f8e03fdd93f0165cf8d230e1e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 09:41:16 -0800 Subject: [PATCH 05/33] add input type checks --- jc/parsers/foo_s.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jc/parsers/foo_s.py b/jc/parsers/foo_s.py index 4b79dd3f..2143b23e 100644 --- a/jc/parsers/foo_s.py +++ b/jc/parsers/foo_s.py @@ -97,12 +97,14 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") for line in data: + output_line = {} try: - output_line = {} + if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") # # parse the input here From caf0a5c8713bf0d72951a2c6fd5a2c62c9eb59d3 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 09:51:27 -0800 Subject: [PATCH 06/33] add input type checking --- jc/parsers/vmstat_s.py | 9 ++++++--- tests/test_vmstat_s.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/jc/parsers/vmstat_s.py b/jc/parsers/vmstat_s.py index 6697f082..abe8f0d8 100644 --- a/jc/parsers/vmstat_s.py +++ b/jc/parsers/vmstat_s.py @@ -145,10 +145,10 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") - output_line = {} procs = None buff_cache = None disk = None @@ -156,7 +156,10 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): tz = None for line in data: + output_line = {} try: + if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + # skip blank lines if line.strip() == '': continue diff --git a/tests/test_vmstat_s.py b/tests/test_vmstat_s.py index f8ccd04e..ec64bd31 100644 --- a/tests/test_vmstat_s.py +++ b/tests/test_vmstat_s.py @@ -75,7 +75,7 @@ class MyTests(unittest.TestCase): """ Test 'vmstat' with no data """ - self.assertEqual(list(jc.parsers.vmstat_s.parse('', quiet=True)), []) + self.assertEqual(list(jc.parsers.vmstat_s.parse([], quiet=True)), []) def test_vmstat_s_unparsable(self): data = 'unparsable data' From 3a9f0934c41c85ea7fa87165b9559f08814645cd Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 09:56:33 -0800 Subject: [PATCH 07/33] add input type checks --- jc/parsers/ls_s.py | 6 ++++-- tests/test_ls_s.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/jc/parsers/ls_s.py b/jc/parsers/ls_s.py index 48e80d57..cb7b33f5 100644 --- a/jc/parsers/ls_s.py +++ b/jc/parsers/ls_s.py @@ -123,13 +123,15 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") parent = '' for line in data: try: + if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") # skip line if it starts with 'total 1234' if re.match(r'total [0-9]+', line): diff --git a/tests/test_ls_s.py b/tests/test_ls_s.py index 2922a487..a4fcac78 100644 --- a/tests/test_ls_s.py +++ b/tests/test_ls_s.py @@ -103,7 +103,7 @@ class MyTests(unittest.TestCase): """ Test plain 'ls' on an empty directory """ - self.assertEqual(list(jc.parsers.ls_s.parse('', quiet=True)), []) + self.assertEqual(list(jc.parsers.ls_s.parse([], quiet=True)), []) def test_ls_s_centos_7_7_raise_exception(self): """ From 14247adb0ae007924ca551a706eb0cfdbae97a41 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 10:03:59 -0800 Subject: [PATCH 08/33] add input type checks --- jc/parsers/csv_s.py | 7 ++++--- tests/test_csv_s.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jc/parsers/csv_s.py b/jc/parsers/csv_s.py index acde6825..eecb7de3 100644 --- a/jc/parsers/csv_s.py +++ b/jc/parsers/csv_s.py @@ -48,7 +48,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '1.0' + version = '1.1' description = 'CSV file streaming parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -95,8 +95,9 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: - jc.utils.compatibility(__name__, info.compatible) + if not quiet: jc.utils.compatibility(__name__, info.compatible) + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") # convert data to an iterable in case a sequence like a list is used as input. # this allows the exhaustion of the input so we don't double-process later. diff --git a/tests/test_csv_s.py b/tests/test_csv_s.py index 4de2aec6..5a9707ce 100644 --- a/tests/test_csv_s.py +++ b/tests/test_csv_s.py @@ -74,7 +74,7 @@ class MyTests(unittest.TestCase): """ Test CSV parser with no data """ - self.assertEqual(list(jc.parsers.csv_s.parse('', quiet=True)), []) + self.assertEqual(list(jc.parsers.csv_s.parse([], quiet=True)), []) def test_csv_unparsable(self): """ From 0e2fe401e1c49a9f947d7d17b72cfc4e90787f47 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 10:08:27 -0800 Subject: [PATCH 09/33] version bump --- jc/parsers/ls_s.py | 2 +- jc/parsers/ping_s.py | 2 +- jc/parsers/vmstat_s.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jc/parsers/ls_s.py b/jc/parsers/ls_s.py index cb7b33f5..2f7cac4a 100644 --- a/jc/parsers/ls_s.py +++ b/jc/parsers/ls_s.py @@ -64,7 +64,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '0.5' + version = '0.6' description = '`ls` command streaming parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' diff --git a/jc/parsers/ping_s.py b/jc/parsers/ping_s.py index ba242800..fbbb56d3 100644 --- a/jc/parsers/ping_s.py +++ b/jc/parsers/ping_s.py @@ -72,7 +72,7 @@ from jc.utils import stream_success, stream_error class info(): """Provides parser metadata (version, author, etc.)""" - version = '0.5' + version = '0.6' description = '`ping` and `ping6` command streaming parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' diff --git a/jc/parsers/vmstat_s.py b/jc/parsers/vmstat_s.py index abe8f0d8..9d18f4c6 100644 --- a/jc/parsers/vmstat_s.py +++ b/jc/parsers/vmstat_s.py @@ -83,7 +83,7 @@ from jc.exceptions import ParseError class info(): """Provides parser metadata (version, author, etc.)""" - version = '0.5' + version = '0.6' description = '`vmstat` command streaming parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' From 12d2de22821fd8f57f4d412e62f53db3d89d5e30 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 11:43:06 -0800 Subject: [PATCH 10/33] use jc.utils.input_type_check() and simplify compatibility check --- jc/parsers/acpi.py | 4 ++-- jc/parsers/airport.py | 4 ++-- jc/parsers/airport_s.py | 4 ++-- jc/parsers/arp.py | 4 ++-- jc/parsers/blkid.py | 4 ++-- jc/parsers/cksum.py | 4 ++-- jc/parsers/crontab.py | 4 ++-- jc/parsers/crontab_u.py | 4 ++-- jc/parsers/csv.py | 4 ++-- jc/parsers/date.py | 4 ++-- jc/parsers/df.py | 5 ++--- jc/parsers/dig.py | 5 ++--- jc/parsers/dir.py | 4 ++-- jc/parsers/dmidecode.py | 4 ++-- jc/parsers/dpkg_l.py | 4 ++-- jc/parsers/du.py | 4 ++-- jc/parsers/env.py | 4 ++-- jc/parsers/file.py | 4 ++-- jc/parsers/finger.py | 4 ++-- jc/parsers/foo.py | 4 ++-- jc/parsers/free.py | 4 ++-- jc/parsers/fstab.py | 4 ++-- jc/parsers/group.py | 4 ++-- jc/parsers/gshadow.py | 4 ++-- jc/parsers/hash.py | 4 ++-- jc/parsers/hashsum.py | 4 ++-- jc/parsers/hciconfig.py | 4 ++-- jc/parsers/history.py | 4 ++-- jc/parsers/hosts.py | 4 ++-- jc/parsers/id.py | 4 ++-- jc/parsers/ifconfig.py | 4 ++-- jc/parsers/ini.py | 4 ++-- jc/parsers/iptables.py | 4 ++-- jc/parsers/iw_scan.py | 4 ++-- jc/parsers/jobs.py | 4 ++-- jc/parsers/last.py | 4 ++-- jc/parsers/ls.py | 4 ++-- jc/parsers/lsblk.py | 4 ++-- jc/parsers/lsmod.py | 4 ++-- jc/parsers/lsof.py | 4 ++-- jc/parsers/lsusb.py | 4 ++-- jc/parsers/mount.py | 4 ++-- jc/parsers/netstat.py | 4 ++-- jc/parsers/ntpq.py | 4 ++-- jc/parsers/passwd.py | 4 ++-- jc/parsers/ping.py | 4 ++-- jc/parsers/pip_list.py | 4 ++-- jc/parsers/pip_show.py | 4 ++-- jc/parsers/ps.py | 4 ++-- jc/parsers/route.py | 4 ++-- jc/parsers/rpm_qi.py | 4 ++-- jc/parsers/sfdisk.py | 4 ++-- jc/parsers/shadow.py | 4 ++-- jc/parsers/ss.py | 4 ++-- jc/parsers/stat.py | 4 ++-- jc/parsers/sysctl.py | 4 ++-- jc/parsers/systemctl.py | 4 ++-- jc/parsers/systemctl_lj.py | 4 ++-- jc/parsers/systemctl_ls.py | 4 ++-- jc/parsers/systemctl_luf.py | 4 ++-- jc/parsers/systeminfo.py | 4 ++-- jc/parsers/time.py | 4 ++-- jc/parsers/timedatectl.py | 4 ++-- jc/parsers/tracepath.py | 4 ++-- jc/parsers/traceroute.py | 4 ++-- jc/parsers/ufw.py | 4 ++-- jc/parsers/ufw_appinfo.py | 4 ++-- jc/parsers/uname.py | 4 ++-- jc/parsers/upower.py | 4 ++-- jc/parsers/uptime.py | 4 ++-- jc/parsers/vmstat.py | 4 ++-- jc/parsers/w.py | 4 ++-- jc/parsers/wc.py | 4 ++-- jc/parsers/who.py | 4 ++-- jc/parsers/xml.py | 4 ++-- jc/parsers/yaml.py | 4 ++-- jc/utils.py | 40 +++++++++++++++++++++++++++---------- 77 files changed, 181 insertions(+), 165 deletions(-) diff --git a/jc/parsers/acpi.py b/jc/parsers/acpi.py index 76e1e620..24225a55 100644 --- a/jc/parsers/acpi.py +++ b/jc/parsers/acpi.py @@ -302,8 +302,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] output_line = {} diff --git a/jc/parsers/airport.py b/jc/parsers/airport.py index c4830d07..174ae851 100644 --- a/jc/parsers/airport.py +++ b/jc/parsers/airport.py @@ -130,8 +130,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/airport_s.py b/jc/parsers/airport_s.py index 5c9cb96b..cbf5203c 100644 --- a/jc/parsers/airport_s.py +++ b/jc/parsers/airport_s.py @@ -166,8 +166,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/arp.py b/jc/parsers/arp.py index 1327fdde..664ec6e0 100644 --- a/jc/parsers/arp.py +++ b/jc/parsers/arp.py @@ -171,8 +171,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/blkid.py b/jc/parsers/blkid.py index ab148137..0a4af511 100644 --- a/jc/parsers/blkid.py +++ b/jc/parsers/blkid.py @@ -176,8 +176,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/cksum.py b/jc/parsers/cksum.py index 66bc65e4..d1004fdc 100644 --- a/jc/parsers/cksum.py +++ b/jc/parsers/cksum.py @@ -103,8 +103,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/crontab.py b/jc/parsers/crontab.py index f8276c9b..0c0476eb 100644 --- a/jc/parsers/crontab.py +++ b/jc/parsers/crontab.py @@ -225,8 +225,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/crontab_u.py b/jc/parsers/crontab_u.py index 097f2cb2..a67b9b29 100644 --- a/jc/parsers/crontab_u.py +++ b/jc/parsers/crontab_u.py @@ -220,8 +220,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/csv.py b/jc/parsers/csv.py index 68ecdcbe..924d731c 100644 --- a/jc/parsers/csv.py +++ b/jc/parsers/csv.py @@ -119,8 +119,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/date.py b/jc/parsers/date.py index 0db77cdc..1e6671c2 100644 --- a/jc/parsers/date.py +++ b/jc/parsers/date.py @@ -115,8 +115,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/df.py b/jc/parsers/df.py index 64972527..edc2bfae 100644 --- a/jc/parsers/df.py +++ b/jc/parsers/df.py @@ -203,9 +203,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() fix_data = [] diff --git a/jc/parsers/dig.py b/jc/parsers/dig.py index 3d7120bc..b09dccca 100644 --- a/jc/parsers/dig.py +++ b/jc/parsers/dig.py @@ -528,9 +528,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/dir.py b/jc/parsers/dir.py index a433ae84..9d5045e5 100644 --- a/jc/parsers/dir.py +++ b/jc/parsers/dir.py @@ -173,8 +173,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/dmidecode.py b/jc/parsers/dmidecode.py index 453a0edf..e3e8ca39 100644 --- a/jc/parsers/dmidecode.py +++ b/jc/parsers/dmidecode.py @@ -177,8 +177,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) item_header = False item_values = False diff --git a/jc/parsers/dpkg_l.py b/jc/parsers/dpkg_l.py index 37b2f6d6..3fb26974 100644 --- a/jc/parsers/dpkg_l.py +++ b/jc/parsers/dpkg_l.py @@ -217,8 +217,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) working_list = [] raw_output = [] diff --git a/jc/parsers/du.py b/jc/parsers/du.py index fac3b902..37d4bb11 100644 --- a/jc/parsers/du.py +++ b/jc/parsers/du.py @@ -137,8 +137,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/env.py b/jc/parsers/env.py index bdf62e97..ff56cc5e 100644 --- a/jc/parsers/env.py +++ b/jc/parsers/env.py @@ -121,8 +121,8 @@ def parse(data, raw=False, quiet=False): Dictionary of raw structured data or List of Dictionaries of processed structured data """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/file.py b/jc/parsers/file.py index 4a7f782e..aeb844c7 100644 --- a/jc/parsers/file.py +++ b/jc/parsers/file.py @@ -106,8 +106,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/finger.py b/jc/parsers/finger.py index 66b5fccc..b7721677 100644 --- a/jc/parsers/finger.py +++ b/jc/parsers/finger.py @@ -168,8 +168,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/foo.py b/jc/parsers/foo.py index 3520c74e..c97ac772 100644 --- a/jc/parsers/foo.py +++ b/jc/parsers/foo.py @@ -86,8 +86,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/free.py b/jc/parsers/free.py index 6e1ab404..84474f67 100644 --- a/jc/parsers/free.py +++ b/jc/parsers/free.py @@ -122,8 +122,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/fstab.py b/jc/parsers/fstab.py index f1ce977b..91e5df34 100644 --- a/jc/parsers/fstab.py +++ b/jc/parsers/fstab.py @@ -132,8 +132,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/group.py b/jc/parsers/group.py index b38360ea..01cadbe1 100644 --- a/jc/parsers/group.py +++ b/jc/parsers/group.py @@ -160,8 +160,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/gshadow.py b/jc/parsers/gshadow.py index a4eeff68..b260fcb2 100644 --- a/jc/parsers/gshadow.py +++ b/jc/parsers/gshadow.py @@ -126,8 +126,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] cleandata = data.splitlines() diff --git a/jc/parsers/hash.py b/jc/parsers/hash.py index a753776a..275d8495 100644 --- a/jc/parsers/hash.py +++ b/jc/parsers/hash.py @@ -85,8 +85,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/hashsum.py b/jc/parsers/hashsum.py index ac29d8da..1582a794 100644 --- a/jc/parsers/hashsum.py +++ b/jc/parsers/hashsum.py @@ -113,8 +113,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/hciconfig.py b/jc/parsers/hciconfig.py index c48806fe..77e5cc3b 100644 --- a/jc/parsers/hciconfig.py +++ b/jc/parsers/hciconfig.py @@ -372,8 +372,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] device_object = {} diff --git a/jc/parsers/history.py b/jc/parsers/history.py index 7401e188..43431cfe 100644 --- a/jc/parsers/history.py +++ b/jc/parsers/history.py @@ -109,8 +109,8 @@ def parse(data, raw=False, quiet=False): Dictionary of raw structured data or List of Dictionaries of processed structured data """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/hosts.py b/jc/parsers/hosts.py index f64ed7e8..b0a0b10f 100644 --- a/jc/parsers/hosts.py +++ b/jc/parsers/hosts.py @@ -117,8 +117,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/id.py b/jc/parsers/id.py index 4a16ad41..d824053b 100644 --- a/jc/parsers/id.py +++ b/jc/parsers/id.py @@ -161,8 +161,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/ifconfig.py b/jc/parsers/ifconfig.py index d3b37384..15b8006d 100644 --- a/jc/parsers/ifconfig.py +++ b/jc/parsers/ifconfig.py @@ -474,8 +474,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/ini.py b/jc/parsers/ini.py index 0f9a4a0a..ac1c681d 100644 --- a/jc/parsers/ini.py +++ b/jc/parsers/ini.py @@ -125,8 +125,8 @@ def parse(data, raw=False, quiet=False): Dictionary representing the ini file """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/iptables.py b/jc/parsers/iptables.py index 9575ed41..ce217c10 100644 --- a/jc/parsers/iptables.py +++ b/jc/parsers/iptables.py @@ -240,8 +240,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] chain = {} diff --git a/jc/parsers/iw_scan.py b/jc/parsers/iw_scan.py index a0d20f9a..ede62aca 100644 --- a/jc/parsers/iw_scan.py +++ b/jc/parsers/iw_scan.py @@ -293,8 +293,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] section = {} diff --git a/jc/parsers/jobs.py b/jc/parsers/jobs.py index 1410a7c4..ad7bbd0a 100644 --- a/jc/parsers/jobs.py +++ b/jc/parsers/jobs.py @@ -141,8 +141,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/last.py b/jc/parsers/last.py index f54cbf18..fb497bc3 100644 --- a/jc/parsers/last.py +++ b/jc/parsers/last.py @@ -185,8 +185,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/ls.py b/jc/parsers/ls.py index 17b7a1bb..1ce7529b 100644 --- a/jc/parsers/ls.py +++ b/jc/parsers/ls.py @@ -162,8 +162,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] warned = False diff --git a/jc/parsers/lsblk.py b/jc/parsers/lsblk.py index 39d12efe..ca4f7184 100644 --- a/jc/parsers/lsblk.py +++ b/jc/parsers/lsblk.py @@ -321,8 +321,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/lsmod.py b/jc/parsers/lsmod.py index 7d89cc5e..cf20f683 100644 --- a/jc/parsers/lsmod.py +++ b/jc/parsers/lsmod.py @@ -174,8 +174,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/lsof.py b/jc/parsers/lsof.py index 02a3fdca..15bf2a5e 100644 --- a/jc/parsers/lsof.py +++ b/jc/parsers/lsof.py @@ -168,8 +168,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/lsusb.py b/jc/parsers/lsusb.py index a71caab6..966ab00d 100644 --- a/jc/parsers/lsusb.py +++ b/jc/parsers/lsusb.py @@ -815,8 +815,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) lsusb = _LsUsb() diff --git a/jc/parsers/mount.py b/jc/parsers/mount.py index 7f26082a..85f427c3 100644 --- a/jc/parsers/mount.py +++ b/jc/parsers/mount.py @@ -163,8 +163,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines cleandata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/netstat.py b/jc/parsers/netstat.py index 5267ddd8..7a2e81c8 100644 --- a/jc/parsers/netstat.py +++ b/jc/parsers/netstat.py @@ -424,8 +424,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ import jc.utils - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = list(filter(None, data.splitlines())) raw_output = [] diff --git a/jc/parsers/ntpq.py b/jc/parsers/ntpq.py index 82ed9797..06e7ddf9 100644 --- a/jc/parsers/ntpq.py +++ b/jc/parsers/ntpq.py @@ -264,8 +264,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/passwd.py b/jc/parsers/passwd.py index fa04c456..a6d42605 100644 --- a/jc/parsers/passwd.py +++ b/jc/parsers/passwd.py @@ -142,8 +142,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index 06129d8a..10fcb54e 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -616,8 +616,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/pip_list.py b/jc/parsers/pip_list.py index 80d76f8a..c50b08e3 100644 --- a/jc/parsers/pip_list.py +++ b/jc/parsers/pip_list.py @@ -91,8 +91,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/pip_show.py b/jc/parsers/pip_show.py index 14c5ec16..926a4b2c 100644 --- a/jc/parsers/pip_show.py +++ b/jc/parsers/pip_show.py @@ -108,8 +108,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] package = {} diff --git a/jc/parsers/ps.py b/jc/parsers/ps.py index 7fc067ad..655c7ed3 100644 --- a/jc/parsers/ps.py +++ b/jc/parsers/ps.py @@ -276,8 +276,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines() raw_output = [] diff --git a/jc/parsers/route.py b/jc/parsers/route.py index 118e1fb0..0ad83826 100644 --- a/jc/parsers/route.py +++ b/jc/parsers/route.py @@ -180,8 +180,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines()[1:] diff --git a/jc/parsers/rpm_qi.py b/jc/parsers/rpm_qi.py index 49729c8e..b5d526dd 100644 --- a/jc/parsers/rpm_qi.py +++ b/jc/parsers/rpm_qi.py @@ -216,8 +216,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] entry_obj = {} diff --git a/jc/parsers/sfdisk.py b/jc/parsers/sfdisk.py index 28b9f512..c368a9d4 100644 --- a/jc/parsers/sfdisk.py +++ b/jc/parsers/sfdisk.py @@ -265,8 +265,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] item = {} diff --git a/jc/parsers/shadow.py b/jc/parsers/shadow.py index 9bd4fdf4..db51455c 100644 --- a/jc/parsers/shadow.py +++ b/jc/parsers/shadow.py @@ -149,8 +149,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/ss.py b/jc/parsers/ss.py index 730f3b30..5a4e2c72 100644 --- a/jc/parsers/ss.py +++ b/jc/parsers/ss.py @@ -337,8 +337,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) contains_colon = ['nl', 'p_raw', 'raw', 'udp', 'tcp', 'v_str', 'icmp6'] raw_output = [] diff --git a/jc/parsers/stat.py b/jc/parsers/stat.py index 6837f79b..4fd69050 100644 --- a/jc/parsers/stat.py +++ b/jc/parsers/stat.py @@ -229,8 +229,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/sysctl.py b/jc/parsers/sysctl.py index 73352d27..0c3f63bd 100644 --- a/jc/parsers/sysctl.py +++ b/jc/parsers/sysctl.py @@ -105,8 +105,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/systemctl.py b/jc/parsers/systemctl.py index 613f2a43..8a9956ad 100644 --- a/jc/parsers/systemctl.py +++ b/jc/parsers/systemctl.py @@ -101,8 +101,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_lj.py b/jc/parsers/systemctl_lj.py index 73bc0959..98cbda5d 100644 --- a/jc/parsers/systemctl_lj.py +++ b/jc/parsers/systemctl_lj.py @@ -123,8 +123,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_ls.py b/jc/parsers/systemctl_ls.py index 18a52ee1..42fbc1aa 100644 --- a/jc/parsers/systemctl_ls.py +++ b/jc/parsers/systemctl_ls.py @@ -93,8 +93,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systemctl_luf.py b/jc/parsers/systemctl_luf.py index 6556a178..69d34e55 100644 --- a/jc/parsers/systemctl_luf.py +++ b/jc/parsers/systemctl_luf.py @@ -89,8 +89,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) # Clear any blank lines linedata = list(filter(None, data.splitlines())) diff --git a/jc/parsers/systeminfo.py b/jc/parsers/systeminfo.py index ca95c0c2..f6bc2b3c 100644 --- a/jc/parsers/systeminfo.py +++ b/jc/parsers/systeminfo.py @@ -303,8 +303,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) delim = ":" # k/v delimiter raw_data = {} # intermediary output diff --git a/jc/parsers/time.py b/jc/parsers/time.py index 05d1f835..f5e594e1 100644 --- a/jc/parsers/time.py +++ b/jc/parsers/time.py @@ -198,8 +198,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/timedatectl.py b/jc/parsers/timedatectl.py index b585e855..92f0d068 100644 --- a/jc/parsers/timedatectl.py +++ b/jc/parsers/timedatectl.py @@ -116,8 +116,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/tracepath.py b/jc/parsers/tracepath.py index 748cf9ce..c600e68a 100644 --- a/jc/parsers/tracepath.py +++ b/jc/parsers/tracepath.py @@ -192,8 +192,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) RE_TTL_HOST = re.compile(r'^\s?(?P\d+)(?P\??):\s+(?P(?:no reply|\S+))') # groups: ttl, ttl_guess, host RE_PMTU = re.compile(r'\spmtu\s(?P[\d]+)') # group: pmtu diff --git a/jc/parsers/traceroute.py b/jc/parsers/traceroute.py index 3094dce9..e78a066b 100644 --- a/jc/parsers/traceroute.py +++ b/jc/parsers/traceroute.py @@ -368,8 +368,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 5965c433..7e9b4f97 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -394,8 +394,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} rules_list = [] diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index 4885dc14..522a53ca 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -265,8 +265,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] item_obj = {} diff --git a/jc/parsers/uname.py b/jc/parsers/uname.py index 1c89c4a8..96ae4ba7 100644 --- a/jc/parsers/uname.py +++ b/jc/parsers/uname.py @@ -91,8 +91,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} diff --git a/jc/parsers/upower.py b/jc/parsers/upower.py index aa55f12e..400443ec 100644 --- a/jc/parsers/upower.py +++ b/jc/parsers/upower.py @@ -323,8 +323,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] device_obj = {} diff --git a/jc/parsers/uptime.py b/jc/parsers/uptime.py index f7ae11de..810815a2 100644 --- a/jc/parsers/uptime.py +++ b/jc/parsers/uptime.py @@ -155,8 +155,8 @@ def parse(data, raw=False, quiet=False): Dictionary. Raw or processed structured data """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = {} cleandata = data.splitlines() diff --git a/jc/parsers/vmstat.py b/jc/parsers/vmstat.py index 6a261d4b..c05caa27 100644 --- a/jc/parsers/vmstat.py +++ b/jc/parsers/vmstat.py @@ -181,8 +181,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] output_line = {} diff --git a/jc/parsers/w.py b/jc/parsers/w.py index 4fcd93c3..e0ff5ec5 100644 --- a/jc/parsers/w.py +++ b/jc/parsers/w.py @@ -153,8 +153,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) cleandata = data.splitlines()[1:] raw_output = [] diff --git a/jc/parsers/wc.py b/jc/parsers/wc.py index 7eddfc15..5f672ff7 100644 --- a/jc/parsers/wc.py +++ b/jc/parsers/wc.py @@ -103,8 +103,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/who.py b/jc/parsers/who.py index e0be6286..3df28d9f 100644 --- a/jc/parsers/who.py +++ b/jc/parsers/who.py @@ -186,8 +186,8 @@ def parse(data, raw=False, quiet=False): List of Dictionaries. Raw or processed structured data. """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/xml.py b/jc/parsers/xml.py index 1ac5971a..544d4d80 100644 --- a/jc/parsers/xml.py +++ b/jc/parsers/xml.py @@ -121,8 +121,8 @@ def parse(data, raw=False, quiet=False): except Exception: raise LibraryNotInstalled('The xmltodict library is not installed.') - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/parsers/yaml.py b/jc/parsers/yaml.py index 89a1d374..ba0b7a59 100644 --- a/jc/parsers/yaml.py +++ b/jc/parsers/yaml.py @@ -135,8 +135,8 @@ def parse(data, raw=False, quiet=False): except Exception: raise LibraryNotInstalled('The ruamel.yaml library is not installed.') - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) raw_output = [] diff --git a/jc/utils.py b/jc/utils.py index a1d7e81b..e8c4531c 100644 --- a/jc/utils.py +++ b/jc/utils.py @@ -75,7 +75,7 @@ def error_message(message_lines): print(message, file=sys.stderr) -def compatibility(mod_name, compatible): +def compatibility(mod_name, compatible, quiet=False): """Checks for the parser's compatibility with the running OS platform. Parameters: @@ -86,22 +86,25 @@ def compatibility(mod_name, compatible): compatible options: linux, darwin, cygwin, win32, aix, freebsd + quiet: (bool) supress compatibility message if True + Returns: None - just prints output to STDERR """ - platform_found = False + if not quiet: + platform_found = False - for platform in compatible: - if sys.platform.startswith(platform): - platform_found = True - break + for platform in compatible: + if sys.platform.startswith(platform): + platform_found = True + break - if not platform_found: - mod = mod_name.split('.')[-1] - compat_list = ', '.join(compatible) - warning_message([f'{mod} parser not compatible with your OS ({sys.platform}).', - f'Compatible platforms: {compat_list}']) + if not platform_found: + mod = mod_name.split('.')[-1] + compat_list = ', '.join(compatible) + warning_message([f'{mod} parser not compatible with your OS ({sys.platform}).', + f'Compatible platforms: {compat_list}']) def has_data(data): @@ -235,6 +238,21 @@ def stream_error(e, ignore_exceptions, line): } +def input_type_check(data): + if not isinstance(data, str): + raise TypeError("Input data must be a 'str' object.") + + +def streaming_input_type_check(data): + if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): + raise TypeError("Input data must be a non-string iterable object.") + + +def streaming_line_input_type_check(line): + if not isinstance(line, str): + raise TypeError("Input line must be a 'str' object.") + + class timestamp: """ Input a date-time text string of several formats and convert to a naive or timezone-aware epoch timestamp in UTC From e8e4b46021557fbf5776c32dff46de022817fb6b Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 11:49:40 -0800 Subject: [PATCH 11/33] use jc.utils type checks --- jc/parsers/csv_s.py | 5 ++--- jc/parsers/foo_s.py | 7 +++---- jc/parsers/ls_s.py | 7 +++---- jc/parsers/ping_s.py | 7 +++---- jc/parsers/vmstat_s.py | 7 +++---- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/jc/parsers/csv_s.py b/jc/parsers/csv_s.py index eecb7de3..b357227c 100644 --- a/jc/parsers/csv_s.py +++ b/jc/parsers/csv_s.py @@ -95,9 +95,8 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): - raise TypeError("Input data must be a non-string iterable object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) # convert data to an iterable in case a sequence like a list is used as input. # this allows the exhaustion of the input so we don't double-process later. diff --git a/jc/parsers/foo_s.py b/jc/parsers/foo_s.py index 2143b23e..03962509 100644 --- a/jc/parsers/foo_s.py +++ b/jc/parsers/foo_s.py @@ -97,14 +97,13 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): - raise TypeError("Input data must be a non-string iterable object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) for line in data: output_line = {} try: - if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + jc.utils.streaming_line_input_type_check(line) # # parse the input here diff --git a/jc/parsers/ls_s.py b/jc/parsers/ls_s.py index 2f7cac4a..465a0b69 100644 --- a/jc/parsers/ls_s.py +++ b/jc/parsers/ls_s.py @@ -123,15 +123,14 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): - raise TypeError("Input data must be a non-string iterable object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) parent = '' for line in data: try: - if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + jc.utils.streaming_line_input_type_check(line) # skip line if it starts with 'total 1234' if re.match(r'total [0-9]+', line): diff --git a/jc/parsers/ping_s.py b/jc/parsers/ping_s.py index fbbb56d3..6cfe9ec7 100644 --- a/jc/parsers/ping_s.py +++ b/jc/parsers/ping_s.py @@ -468,14 +468,13 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): """ s = _state() - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): - raise TypeError("Input data must be a non-string iterable object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) for line in data: output_line = {} try: - if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + jc.utils.streaming_line_input_type_check(line) # skip blank lines if line.strip() == '': diff --git a/jc/parsers/vmstat_s.py b/jc/parsers/vmstat_s.py index 9d18f4c6..188042e5 100644 --- a/jc/parsers/vmstat_s.py +++ b/jc/parsers/vmstat_s.py @@ -145,9 +145,8 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): Iterator object """ - if not quiet: jc.utils.compatibility(__name__, info.compatible) - if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): - raise TypeError("Input data must be a non-string iterable object.") + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) procs = None buff_cache = None @@ -158,7 +157,7 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): for line in data: output_line = {} try: - if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") + jc.utils.streaming_line_input_type_check(line) # skip blank lines if line.strip() == '': From 1168259bc23862f671326d41f5282a3575205214 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 11:57:04 -0800 Subject: [PATCH 12/33] add doc strings --- jc/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jc/utils.py b/jc/utils.py index e8c4531c..f4b8a85e 100644 --- a/jc/utils.py +++ b/jc/utils.py @@ -239,16 +239,19 @@ def stream_error(e, ignore_exceptions, line): def input_type_check(data): + """Ensure input data is a string""" if not isinstance(data, str): raise TypeError("Input data must be a 'str' object.") def streaming_input_type_check(data): + """Ensure input data is an iterable, but not a string or bytes""" if not hasattr(data, '__iter__') or isinstance(data, (str, bytes)): raise TypeError("Input data must be a non-string iterable object.") def streaming_line_input_type_check(line): + """Ensure each line is a string""" if not isinstance(line, str): raise TypeError("Input line must be a 'str' object.") From d2dc4a983c86c538e13e568b908072de4ca0daaf Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 11:59:26 -0800 Subject: [PATCH 13/33] changelog update --- CHANGELOG | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 4c387050..1b8d821a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,9 @@ jc changelog -20211129 v1.17.3 +20211130 v1.17.3 - Update parsers to exit with error if non-string input is detected (raise TypeError) +- Update streaming parsers to exit with error if non-iterable input is detected (raise TypeError) +- Simplify quiet-checking in parsers 20211117 v1.17.2 - Fix ping parser to add Alpine linux support From 7a6ebf3c9555dd82df7dc0b71981cdd32ce0061d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 30 Nov 2021 16:54:32 -0800 Subject: [PATCH 14/33] add iostat parser --- jc/cli.py | 1 + jc/parsers/iostat.py | 170 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 jc/parsers/iostat.py diff --git a/jc/cli.py b/jc/cli.py index b7577560..7727a0f8 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -76,6 +76,7 @@ parsers = [ 'id', 'ifconfig', 'ini', + 'iostat', 'iptables', 'iw-scan', 'jobs', diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py new file mode 100644 index 00000000..767c54b1 --- /dev/null +++ b/jc/parsers/iostat.py @@ -0,0 +1,170 @@ +"""jc - JSON CLI output utility `iostat` command output parser + +<> + +Usage (cli): + + $ iostat | jc --iostat + + or + + $ jc iostat + +Usage (module): + + import jc.parsers.iostat + result = jc.parsers.iostat.parse(iostat_command_output) + +Schema: + + [ + { + "iostat": string, + "bar": boolean, + "baz": integer + } + ] + +Examples: + + $ iostat | jc --iostat -p + [] + + $ iostat | jc --iostat -p -r + [] +""" +import jc.utils +import jc.parsers.universal + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`iostat` command parser' + author = 'John Doe' + author_email = 'johndoe@gmail.com' + # details = 'enter any other details here' + + # compatible options: linux, darwin, cygwin, win32, aix, freebsd + compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'] + magic_commands = ['iostat'] + + +__version__ = info.version + + +def _process(proc_data): + """ + 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. + """ + + # process the data here + # rebuild output for added semantic information + # use helper functions in jc.utils for int, float, bool conversions and timestamps + + return proc_data + +def _normalize_headers(line): + return line.replace('%', ' ').replace('/', '_').lower() + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON 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 = [] + + if jc.utils.has_data(data): + section = '' # either 'cpu' or 'device' + headers = '' + cpu_list = [] + device_list = [] + + for line in filter(None, data.splitlines()): + if line.startswith('avg-cpu:'): + if cpu_list: + output_list = jc.parsers.universal.simple_table_parse(cpu_list) + for item in output_list: + item['type'] = 'cpu' + raw_output.extend(output_list) + cpu_list = [] + + if device_list: + output_list = jc.parsers.universal.simple_table_parse(device_list) + for item in output_list: + item['type'] = 'device' + raw_output.extend(output_list) + device_list = [] + + section = 'cpu' + headers = _normalize_headers(line) + headers = headers.strip().split(':', maxsplit=1)[1:] + headers = ' '.join(headers) + cpu_list.append(headers) + continue + + if line.startswith('Device:'): + if cpu_list: + output_list = jc.parsers.universal.simple_table_parse(cpu_list) + for item in output_list: + item['type'] = 'cpu' + raw_output.extend(output_list) + cpu_list = [] + + if device_list: + output_list = jc.parsers.universal.simple_table_parse(device_list) + for item in output_list: + item['type'] = 'device' + raw_output.extend(output_list) + device_list = [] + + section = 'device' + headers = _normalize_headers(line) + headers = headers.replace(':', ' ') + device_list.append(headers) + continue + + if section == 'cpu': + cpu_list.append(line) + + if section == 'device': + device_list.append(line) + + if cpu_list: + output_list = jc.parsers.universal.simple_table_parse(cpu_list) + for item in output_list: + item['type'] = 'cpu' + raw_output.extend(output_list) + cpu_list = [] + + if device_list: + output_list = jc.parsers.universal.simple_table_parse(device_list) + for item in output_list: + item['type'] = 'device' + raw_output.extend(output_list) + device_list = [] + + return raw_output if raw else _process(raw_output) + +if __name__ == '__main__': + pass From dcf552ca0c69aa5f0309a83dc33dee7c5ed81292 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 10:34:55 -0800 Subject: [PATCH 15/33] add _process and cleanup --- jc/parsers/iostat.py | 185 ++++++++++++++++++++++++++++++++----------- 1 file changed, 138 insertions(+), 47 deletions(-) diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py index 767c54b1..5110514f 100644 --- a/jc/parsers/iostat.py +++ b/jc/parsers/iostat.py @@ -1,7 +1,5 @@ """jc - JSON CLI output utility `iostat` command output parser -<> - Usage (cli): $ iostat | jc --iostat @@ -19,19 +17,121 @@ Schema: [ { - "iostat": string, - "bar": boolean, - "baz": integer + "type": string, + "percent_user": float, + "percent_nice": float, + "percent_system": float, + "percent_iowait": float, + "percent_steal": float, + "percent_idle": float, + "device": string, + "tps": float, + "kb_read_s": float, + "mb_read_s": float, + "kb_wrtn_s": float, + "mb_wrtn_s": float, + "kb_read": integer, + "mb_read": integer, + "kb_wrtn": integer, + "mb_wrtn": integer, + "rrqm_s": float, + "wrqm_s": float, + "r_s": float, + "w_s": float, + "rmb_s": float, + "rkb_s": float, + "wmb_s": float, + "wkb_s": float, + "avgrq_sz": float, + "avgqu_sz": float, + "await": float, + "r_await": float, + "w_await": float, + "svctm": float, + "percent_util": float } - ] Examples: $ iostat | jc --iostat -p - [] + [ + { + "percent_user": 0.15, + "percent_nice": 0.0, + "percent_system": 0.18, + "percent_iowait": 0.0, + "percent_steal": 0.0, + "percent_idle": 99.67, + "type": "cpu" + }, + { + "device": "sda", + "tps": 0.29, + "kb_read_s": 7.22, + "kb_wrtn_s": 1.25, + "kb_read": 194341, + "kb_wrtn": 33590, + "type": "device" + }, + { + "device": "dm-0", + "tps": 0.29, + "kb_read_s": 5.99, + "kb_wrtn_s": 1.17, + "kb_read": 161361, + "kb_wrtn": 31522, + "type": "device" + }, + { + "device": "dm-1", + "tps": 0.0, + "kb_read_s": 0.08, + "kb_wrtn_s": 0.0, + "kb_read": 2204, + "kb_wrtn": 0, + "type": "device" + } + ] $ iostat | jc --iostat -p -r - [] + [ + { + "percent_user": "0.15", + "percent_nice": "0.00", + "percent_system": "0.18", + "percent_iowait": "0.00", + "percent_steal": "0.00", + "percent_idle": "99.67", + "type": "cpu" + }, + { + "device": "sda", + "tps": "0.29", + "kb_read_s": "7.22", + "kb_wrtn_s": "1.25", + "kb_read": "194341", + "kb_wrtn": "33590", + "type": "device" + }, + { + "device": "dm-0", + "tps": "0.29", + "kb_read_s": "5.99", + "kb_wrtn_s": "1.17", + "kb_read": "161361", + "kb_wrtn": "31522", + "type": "device" + }, + { + "device": "dm-1", + "tps": "0.00", + "kb_read_s": "0.08", + "kb_wrtn_s": "0.00", + "kb_read": "2204", + "kb_wrtn": "0", + "type": "device" + } + ] """ import jc.utils import jc.parsers.universal @@ -41,12 +141,9 @@ class info(): """Provides parser metadata (version, author, etc.)""" version = '1.0' description = '`iostat` command parser' - author = 'John Doe' - author_email = 'johndoe@gmail.com' - # details = 'enter any other details here' - - # compatible options: linux, darwin, cygwin, win32, aix, freebsd - compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'] + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] magic_commands = ['iostat'] @@ -66,14 +163,31 @@ def _process(proc_data): List of Dictionaries. Structured to conform to the schema. """ - # process the data here - # rebuild output for added semantic information - # use helper functions in jc.utils for int, float, bool conversions and timestamps + for entry in proc_data: + float_list = [ + 'percent_user', 'percent_nice', 'percent_system', 'percent_iowait', + 'percent_steal', 'percent_idle', 'tps', 'kb_read_s', 'mb_read_s', 'kb_wrtn_s', + 'mb_wrtn_s', 'rrqm_s', 'wrqm_s', 'r_s', 'w_s', 'rmb_s', 'rkb_s', 'wmb_s', + 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', 'percent_util' + ] + int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] + for key in entry: + if key in int_list: + entry[key] = jc.utils.convert_to_int(entry[key]) + + if key in float_list: + entry[key] = jc.utils.convert_to_float(entry[key]) return proc_data def _normalize_headers(line): - return line.replace('%', ' ').replace('/', '_').lower() + return line.replace('%', 'percent_').replace('/', '_').replace('-', '_').lower() + +def _create_obj_list(section_list, section_name): + output_list = jc.parsers.universal.simple_table_parse(section_list) + for item in output_list: + item['type'] = section_name + return output_list def parse(data, raw=False, quiet=False): """ @@ -103,17 +217,11 @@ def parse(data, raw=False, quiet=False): for line in filter(None, data.splitlines()): if line.startswith('avg-cpu:'): if cpu_list: - output_list = jc.parsers.universal.simple_table_parse(cpu_list) - for item in output_list: - item['type'] = 'cpu' - raw_output.extend(output_list) + raw_output.extend(_create_obj_list(cpu_list, 'cpu')) cpu_list = [] if device_list: - output_list = jc.parsers.universal.simple_table_parse(device_list) - for item in output_list: - item['type'] = 'device' - raw_output.extend(output_list) + raw_output.extend(_create_obj_list(device_list, 'device')) device_list = [] section = 'cpu' @@ -125,17 +233,11 @@ def parse(data, raw=False, quiet=False): if line.startswith('Device:'): if cpu_list: - output_list = jc.parsers.universal.simple_table_parse(cpu_list) - for item in output_list: - item['type'] = 'cpu' - raw_output.extend(output_list) + raw_output.extend(_create_obj_list(cpu_list, 'cpu')) cpu_list = [] if device_list: - output_list = jc.parsers.universal.simple_table_parse(device_list) - for item in output_list: - item['type'] = 'device' - raw_output.extend(output_list) + raw_output.extend(_create_obj_list(device_list, 'device')) device_list = [] section = 'device' @@ -151,20 +253,9 @@ def parse(data, raw=False, quiet=False): device_list.append(line) if cpu_list: - output_list = jc.parsers.universal.simple_table_parse(cpu_list) - for item in output_list: - item['type'] = 'cpu' - raw_output.extend(output_list) - cpu_list = [] + raw_output.extend(_create_obj_list(cpu_list, 'cpu')) if device_list: - output_list = jc.parsers.universal.simple_table_parse(device_list) - for item in output_list: - item['type'] = 'device' - raw_output.extend(output_list) - device_list = [] + raw_output.extend(_create_obj_list(device_list, 'device')) return raw_output if raw else _process(raw_output) - -if __name__ == '__main__': - pass From 6665ffaeb8107e9db3b917db0663beaf44024533 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 10:59:07 -0800 Subject: [PATCH 16/33] remove python 3.6 from tests --- .github/workflows/pythonapp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 8e9a96df..a4aa6014 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [macos-latest, ubuntu-latest, windows-latest] - python-version: [3.6, 3.7, 3.8, 3.9, 3.10.0] + python-version: [3.7, 3.8, 3.9, 3.10.0] steps: - uses: actions/checkout@v2 From 406336c7185b539b5e00532b58146d5b1b73f259 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 13:53:31 -0800 Subject: [PATCH 17/33] add iostat example --- EXAMPLES.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 5a6e28b3..2ebf448d 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -1516,6 +1516,50 @@ cat example.ini | jc --ini -p } } ``` +### iostat +```bash +$ iostat | jc --iostat -p # or: jc -p iostat +``` +```json +[ + { + "percent_user": 0.15, + "percent_nice": 0.0, + "percent_system": 0.18, + "percent_iowait": 0.0, + "percent_steal": 0.0, + "percent_idle": 99.67, + "type": "cpu" + }, + { + "device": "sda", + "tps": 0.29, + "kb_read_s": 7.22, + "kb_wrtn_s": 1.25, + "kb_read": 194341, + "kb_wrtn": 33590, + "type": "device" + }, + { + "device": "dm-0", + "tps": 0.29, + "kb_read_s": 5.99, + "kb_wrtn_s": 1.17, + "kb_read": 161361, + "kb_wrtn": 31522, + "type": "device" + }, + { + "device": "dm-1", + "tps": 0.0, + "kb_read_s": 0.08, + "kb_wrtn_s": 0.0, + "kb_read": 2204, + "kb_wrtn": 0, + "type": "device" + } +] +``` ### iptables ```bash iptables --line-numbers -v -L -t nat | jc --iptables -p # or: jc -p iptables --line-numbers -v -L -t nat From bf15575e90985cfec5c57dd11dfa2b86d53a41be Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:01:52 -0800 Subject: [PATCH 18/33] fixes for ubunut --- jc/parsers/iostat.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py index 5110514f..3c464876 100644 --- a/jc/parsers/iostat.py +++ b/jc/parsers/iostat.py @@ -48,8 +48,14 @@ Schema: "r_await": float, "w_await": float, "svctm": float, - "percent_util": float + "aqu_sz": float, + "rareq_sz": float, + "wareq_sz": float, + "percent_util": float, + "percent_rrqm": float, + "percent_wrqm": float } + ] Examples: @@ -168,7 +174,8 @@ def _process(proc_data): 'percent_user', 'percent_nice', 'percent_system', 'percent_iowait', 'percent_steal', 'percent_idle', 'tps', 'kb_read_s', 'mb_read_s', 'kb_wrtn_s', 'mb_wrtn_s', 'rrqm_s', 'wrqm_s', 'r_s', 'w_s', 'rmb_s', 'rkb_s', 'wmb_s', - 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', 'percent_util' + 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', + 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz' ] int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] for key in entry: @@ -231,7 +238,7 @@ def parse(data, raw=False, quiet=False): cpu_list.append(headers) continue - if line.startswith('Device:'): + if line.startswith('Device'): if cpu_list: raw_output.extend(_create_obj_list(cpu_list, 'cpu')) cpu_list = [] @@ -252,10 +259,10 @@ def parse(data, raw=False, quiet=False): if section == 'device': device_list.append(line) - if cpu_list: - raw_output.extend(_create_obj_list(cpu_list, 'cpu')) + if cpu_list: + raw_output.extend(_create_obj_list(cpu_list, 'cpu')) - if device_list: - raw_output.extend(_create_obj_list(device_list, 'device')) + if device_list: + raw_output.extend(_create_obj_list(device_list, 'device')) return raw_output if raw else _process(raw_output) From e2311cbb03f407414df953c8d1c07d0cf1a549ca Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:02:06 -0800 Subject: [PATCH 19/33] add iostat tests --- tests/fixtures/centos-7.7/iostat-1.json | 1 + tests/fixtures/centos-7.7/iostat-1.out | 26 ++++ tests/fixtures/centos-7.7/iostat-m.json | 1 + tests/fixtures/centos-7.7/iostat-m.out | 10 ++ tests/fixtures/centos-7.7/iostat-mx.json | 1 + tests/fixtures/centos-7.7/iostat-mx.out | 9 ++ tests/fixtures/centos-7.7/iostat-x.json | 1 + tests/fixtures/centos-7.7/iostat-x.out | 10 ++ tests/fixtures/centos-7.7/iostat.json | 1 + tests/fixtures/centos-7.7/iostat.out | 9 ++ tests/fixtures/ubuntu-18.04/iostat-1.json | 1 + tests/fixtures/ubuntu-18.04/iostat-1.out | 77 +++++++++++ tests/fixtures/ubuntu-18.04/iostat-m.json | 1 + tests/fixtures/ubuntu-18.04/iostat-m.out | 27 ++++ tests/fixtures/ubuntu-18.04/iostat-mx.json | 1 + tests/fixtures/ubuntu-18.04/iostat-mx.out | 26 ++++ tests/fixtures/ubuntu-18.04/iostat-x.json | 1 + tests/fixtures/ubuntu-18.04/iostat-x.out | 26 ++++ tests/fixtures/ubuntu-18.04/iostat.json | 1 + tests/fixtures/ubuntu-18.04/iostat.out | 27 ++++ tests/test_iostat.py | 143 +++++++++++++++++++++ 21 files changed, 400 insertions(+) create mode 100644 tests/fixtures/centos-7.7/iostat-1.json create mode 100644 tests/fixtures/centos-7.7/iostat-1.out create mode 100644 tests/fixtures/centos-7.7/iostat-m.json create mode 100644 tests/fixtures/centos-7.7/iostat-m.out create mode 100644 tests/fixtures/centos-7.7/iostat-mx.json create mode 100644 tests/fixtures/centos-7.7/iostat-mx.out create mode 100644 tests/fixtures/centos-7.7/iostat-x.json create mode 100644 tests/fixtures/centos-7.7/iostat-x.out create mode 100644 tests/fixtures/centos-7.7/iostat.json create mode 100644 tests/fixtures/centos-7.7/iostat.out create mode 100644 tests/fixtures/ubuntu-18.04/iostat-1.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-1.out create mode 100644 tests/fixtures/ubuntu-18.04/iostat-m.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-m.out create mode 100644 tests/fixtures/ubuntu-18.04/iostat-mx.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-mx.out create mode 100644 tests/fixtures/ubuntu-18.04/iostat-x.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-x.out create mode 100644 tests/fixtures/ubuntu-18.04/iostat.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat.out create mode 100644 tests/test_iostat.py diff --git a/tests/fixtures/centos-7.7/iostat-1.json b/tests/fixtures/centos-7.7/iostat-1.json new file mode 100644 index 00000000..38f2c4e8 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-1.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"kb_read_s":5.24,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42533,"type":"device"},{"device":"dm-0","tps":0.25,"kb_read_s":4.39,"kb_wrtn_s":1.04,"kb_read":170325,"kb_wrtn":40464,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.06,"kb_wrtn_s":0.0,"kb_read":2204,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":100.0,"type":"cpu"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":100.0,"type":"cpu"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-1.out b/tests/fixtures/centos-7.7/iostat-1.out new file mode 100644 index 00000000..57587124 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-1.out @@ -0,0 +1,26 @@ +Linux 3.10.0-1062.1.2.el7.x86_64 (localhost.localdomain) 11/30/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.14 0.00 0.16 0.00 0.00 99.70 + +Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn +sda 0.24 5.24 1.10 203305 42533 +dm-0 0.25 4.39 1.04 170325 40464 +dm-1 0.00 0.06 0.00 2204 0 + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.00 0.00 0.00 0.00 0.00 100.00 + +Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn +sda 0.00 0.00 0.00 0 0 +dm-0 0.00 0.00 0.00 0 0 +dm-1 0.00 0.00 0.00 0 0 + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.00 0.00 0.00 0.00 0.00 100.00 + +Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn +sda 0.00 0.00 0.00 0 0 +dm-0 0.00 0.00 0.00 0 0 +dm-1 0.00 0.00 0.00 0 0 + diff --git a/tests/fixtures/centos-7.7/iostat-m.json b/tests/fixtures/centos-7.7/iostat-m.json new file mode 100644 index 00000000..e757dc9e --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-m.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_read":198,"mb_wrtn":41,"type":"device"},{"device":"dm-0","tps":0.25,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":166,"mb_wrtn":39,"type":"device"},{"device":"dm-1","tps":0.0,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":2,"mb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-m.out b/tests/fixtures/centos-7.7/iostat-m.out new file mode 100644 index 00000000..4e71a536 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-m.out @@ -0,0 +1,10 @@ +Linux 3.10.0-1062.1.2.el7.x86_64 (localhost.localdomain) 11/30/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.14 0.00 0.16 0.00 0.00 99.70 + +Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn +sda 0.24 0.01 0.00 198 41 +dm-0 0.25 0.00 0.00 166 39 +dm-1 0.00 0.00 0.00 2 0 + diff --git a/tests/fixtures/centos-7.7/iostat-mx.json b/tests/fixtures/centos-7.7/iostat-mx.json new file mode 100644 index 00000000..421a2779 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-mx.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","rrqm_s":0.0,"wrqm_s":0.02,"r_s":0.13,"w_s":0.11,"rmb_s":0.01,"wmb_s":0.0,"avgrq_sz":52.51,"avgqu_sz":0.0,"await":0.88,"r_await":0.53,"w_await":1.29,"svctm":0.52,"percent_util":0.01,"type":"device"},{"device":"dm-0","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.12,"w_s":0.13,"rmb_s":0.0,"wmb_s":0.0,"avgrq_sz":44.28,"avgqu_sz":0.0,"await":0.92,"r_await":0.54,"w_await":1.27,"svctm":0.5,"percent_util":0.01,"type":"device"},{"device":"dm-1","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.0,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"avgrq_sz":50.09,"avgqu_sz":0.0,"await":0.08,"r_await":0.08,"w_await":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-mx.out b/tests/fixtures/centos-7.7/iostat-mx.out new file mode 100644 index 00000000..30f5bbd6 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-mx.out @@ -0,0 +1,9 @@ +Linux 3.10.0-1062.1.2.el7.x86_64 (localhost.localdomain) 11/30/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.14 0.00 0.16 0.00 0.00 99.70 + +Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util +sda 0.00 0.02 0.13 0.11 0.01 0.00 52.51 0.00 0.88 0.53 1.29 0.52 0.01 +dm-0 0.00 0.00 0.12 0.13 0.00 0.00 44.28 0.00 0.92 0.54 1.27 0.50 0.01 +dm-1 0.00 0.00 0.00 0.00 0.00 0.00 50.09 0.00 0.08 0.08 0.00 0.08 0.00 diff --git a/tests/fixtures/centos-7.7/iostat-x.json b/tests/fixtures/centos-7.7/iostat-x.json new file mode 100644 index 00000000..2d45b2c1 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-x.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","rrqm_s":0.0,"wrqm_s":0.02,"r_s":0.13,"w_s":0.11,"rkb_s":5.27,"wkb_s":1.1,"avgrq_sz":52.53,"avgqu_sz":0.0,"await":0.88,"r_await":0.53,"w_await":1.29,"svctm":0.52,"percent_util":0.01,"type":"device"},{"device":"dm-0","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.12,"w_s":0.13,"rkb_s":4.41,"wkb_s":1.05,"avgrq_sz":44.3,"avgqu_sz":0.0,"await":0.92,"r_await":0.54,"w_await":1.27,"svctm":0.5,"percent_util":0.01,"type":"device"},{"device":"dm-1","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.0,"w_s":0.0,"rkb_s":0.06,"wkb_s":0.0,"avgrq_sz":50.09,"avgqu_sz":0.0,"await":0.08,"r_await":0.08,"w_await":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-x.out b/tests/fixtures/centos-7.7/iostat-x.out new file mode 100644 index 00000000..76071788 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-x.out @@ -0,0 +1,10 @@ +Linux 3.10.0-1062.1.2.el7.x86_64 (localhost.localdomain) 11/30/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.14 0.00 0.16 0.00 0.00 99.70 + +Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util +sda 0.00 0.02 0.13 0.11 5.27 1.10 52.53 0.00 0.88 0.53 1.29 0.52 0.01 +dm-0 0.00 0.00 0.12 0.13 4.41 1.05 44.30 0.00 0.92 0.54 1.27 0.50 0.01 +dm-1 0.00 0.00 0.00 0.00 0.06 0.00 50.09 0.00 0.08 0.08 0.00 0.08 0.00 + diff --git a/tests/fixtures/centos-7.7/iostat.json b/tests/fixtures/centos-7.7/iostat.json new file mode 100644 index 00000000..6a971b6c --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"kb_read_s":5.28,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42368,"type":"device"},{"device":"dm-0","tps":0.25,"kb_read_s":4.42,"kb_wrtn_s":1.05,"kb_read":170325,"kb_wrtn":40299,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.06,"kb_wrtn_s":0.0,"kb_read":2204,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat.out b/tests/fixtures/centos-7.7/iostat.out new file mode 100644 index 00000000..afa8f1a5 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat.out @@ -0,0 +1,9 @@ +Linux 3.10.0-1062.1.2.el7.x86_64 (localhost.localdomain) 11/30/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.14 0.00 0.16 0.00 0.00 99.70 + +Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn +sda 0.24 5.28 1.10 203305 42368 +dm-0 0.25 4.42 1.05 170325 40299 +dm-1 0.00 0.06 0.00 2204 0 diff --git a/tests/fixtures/ubuntu-18.04/iostat-1.json b/tests/fixtures/ubuntu-18.04/iostat-1.json new file mode 100644 index 00000000..ab42c81a --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-1.json @@ -0,0 +1 @@ +[{"percent_user":11.66,"percent_nice":3.51,"percent_system":7.44,"percent_iowait":1.33,"percent_steal":0.0,"percent_idle":76.06,"type":"cpu"},{"device":"loop0","tps":0.05,"kb_read_s":0.16,"kb_wrtn_s":0.0,"kb_read":125,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":11.06,"kb_read_s":12.71,"kb_wrtn_s":0.0,"kb_read":10139,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.12,"kb_read_s":1.77,"kb_wrtn_s":0.0,"kb_read":1413,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.07,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":359,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.07,"kb_read_s":1.34,"kb_wrtn_s":0.0,"kb_read":1067,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.13,"kb_read_s":1.49,"kb_wrtn_s":0.0,"kb_read":1190,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.05,"kb_read_s":0.16,"kb_wrtn_s":0.0,"kb_read":125,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.08,"kb_read_s":1.34,"kb_wrtn_s":0.0,"kb_read":1070,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.26,"kb_read_s":1.01,"kb_wrtn_s":0.0,"kb_read":806,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":82.01,"kb_read_s":1901.45,"kb_wrtn_s":3368.25,"kb_read":1517318,"kb_wrtn":2687800,"type":"device"},{"device":"scd0","tps":2.89,"kb_read_s":64.94,"kb_wrtn_s":0.0,"kb_read":51818,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":2.89,"kb_read_s":64.44,"kb_wrtn_s":0.0,"kb_read":51418,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":15.88,"kb_read_s":17.15,"kb_wrtn_s":0.0,"kb_read":13683,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.08,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":362,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.12,"kb_read_s":0.6,"kb_wrtn_s":0.0,"kb_read":476,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.04,"kb_read_s":0.14,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.06,"kb_read_s":0.44,"kb_wrtn_s":0.0,"kb_read":353,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.05,"kb_read_s":0.44,"kb_wrtn_s":0.0,"kb_read":348,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.08,"kb_read_s":0.46,"kb_wrtn_s":0.0,"kb_read":366,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.08,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":361,"kb_wrtn":0,"type":"device"},{"percent_user":1.01,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":98.99,"type":"cpu"},{"device":"loop0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":1.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.0,"type":"cpu"},{"device":"loop0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-1.out b/tests/fixtures/ubuntu-18.04/iostat-1.out new file mode 100644 index 00000000..27633f26 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-1.out @@ -0,0 +1,77 @@ +Linux 4.15.0-158-generic (kbrazil-ubuntu) 12/01/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 11.66 3.51 7.44 1.33 0.00 76.06 + +Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn +loop0 0.05 0.16 0.00 125 0 +loop1 11.06 12.71 0.00 10139 0 +loop2 0.12 1.77 0.00 1413 0 +loop3 0.07 0.45 0.00 359 0 +loop4 0.07 1.34 0.00 1067 0 +loop5 0.13 1.49 0.00 1190 0 +loop6 0.05 0.16 0.00 125 0 +loop7 0.08 1.34 0.00 1070 0 +fd0 0.26 1.01 0.00 806 0 +sda 82.01 1901.45 3368.25 1517318 2687800 +scd0 2.89 64.94 0.00 51818 0 +scd1 2.89 64.44 0.00 51418 0 +loop8 15.88 17.15 0.00 13683 0 +loop9 0.08 0.45 0.00 362 0 +loop10 0.12 0.60 0.00 476 0 +loop11 0.04 0.14 0.00 108 0 +loop12 0.06 0.44 0.00 353 0 +loop13 0.05 0.44 0.00 348 0 +loop14 0.08 0.46 0.00 366 0 +loop15 0.08 0.45 0.00 361 0 + +avg-cpu: %user %nice %system %iowait %steal %idle + 1.01 0.00 0.00 0.00 0.00 98.99 + +Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn +loop0 0.00 0.00 0.00 0 0 +loop1 0.00 0.00 0.00 0 0 +loop2 0.00 0.00 0.00 0 0 +loop3 0.00 0.00 0.00 0 0 +loop4 0.00 0.00 0.00 0 0 +loop5 0.00 0.00 0.00 0 0 +loop6 0.00 0.00 0.00 0 0 +loop7 0.00 0.00 0.00 0 0 +fd0 0.00 0.00 0.00 0 0 +sda 0.00 0.00 0.00 0 0 +scd0 0.00 0.00 0.00 0 0 +scd1 0.00 0.00 0.00 0 0 +loop8 0.00 0.00 0.00 0 0 +loop9 0.00 0.00 0.00 0 0 +loop10 0.00 0.00 0.00 0 0 +loop11 0.00 0.00 0.00 0 0 +loop12 0.00 0.00 0.00 0 0 +loop13 0.00 0.00 0.00 0 0 +loop14 0.00 0.00 0.00 0 0 +loop15 0.00 0.00 0.00 0 0 + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.00 0.00 1.00 0.00 0.00 99.00 + +Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn +loop0 0.00 0.00 0.00 0 0 +loop1 0.00 0.00 0.00 0 0 +loop2 0.00 0.00 0.00 0 0 +loop3 0.00 0.00 0.00 0 0 +loop4 0.00 0.00 0.00 0 0 +loop5 0.00 0.00 0.00 0 0 +loop6 0.00 0.00 0.00 0 0 +loop7 0.00 0.00 0.00 0 0 +fd0 0.00 0.00 0.00 0 0 +sda 0.00 0.00 0.00 0 0 +scd0 0.00 0.00 0.00 0 0 +scd1 0.00 0.00 0.00 0 0 +loop8 0.00 0.00 0.00 0 0 +loop9 0.00 0.00 0.00 0 0 +loop10 0.00 0.00 0.00 0 0 +loop11 0.00 0.00 0.00 0 0 +loop12 0.00 0.00 0.00 0 0 +loop13 0.00 0.00 0.00 0 0 +loop14 0.00 0.00 0.00 0 0 +loop15 0.00 0.00 0.00 0 0 + diff --git a/tests/fixtures/ubuntu-18.04/iostat-m.json b/tests/fixtures/ubuntu-18.04/iostat-m.json new file mode 100644 index 00000000..f51e6da1 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-m.json @@ -0,0 +1 @@ +[{"percent_user":13.71,"percent_nice":4.14,"percent_system":8.73,"percent_iowait":1.56,"percent_steal":0.0,"percent_idle":71.86,"type":"cpu"},{"device":"loop0","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop1","tps":13.06,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_read":9,"mb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.14,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.08,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.16,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.3,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"sda","tps":96.73,"mb_read_s":2.19,"mb_wrtn_s":3.88,"mb_read":1481,"mb_wrtn":2624,"type":"device"},{"device":"scd0","tps":3.41,"mb_read_s":0.07,"mb_wrtn_s":0.0,"mb_read":50,"mb_wrtn":0,"type":"device"},{"device":"scd1","tps":3.41,"mb_read_s":0.07,"mb_wrtn_s":0.0,"mb_read":50,"mb_wrtn":0,"type":"device"},{"device":"loop8","tps":18.73,"mb_read_s":0.02,"mb_wrtn_s":0.0,"mb_read":13,"mb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.15,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.05,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.07,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-m.out b/tests/fixtures/ubuntu-18.04/iostat-m.out new file mode 100644 index 00000000..ef40fd95 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-m.out @@ -0,0 +1,27 @@ +Linux 4.15.0-158-generic (kbrazil-ubuntu) 12/01/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 13.71 4.14 8.73 1.56 0.00 71.86 + +Device tps MB_read/s MB_wrtn/s MB_read MB_wrtn +loop0 0.06 0.00 0.00 0 0 +loop1 13.06 0.01 0.00 9 0 +loop2 0.14 0.00 0.00 1 0 +loop3 0.08 0.00 0.00 0 0 +loop4 0.09 0.00 0.00 1 0 +loop5 0.16 0.00 0.00 1 0 +loop6 0.06 0.00 0.00 0 0 +loop7 0.09 0.00 0.00 1 0 +fd0 0.30 0.00 0.00 0 0 +sda 96.73 2.19 3.88 1481 2624 +scd0 3.41 0.07 0.00 50 0 +scd1 3.41 0.07 0.00 50 0 +loop8 18.73 0.02 0.00 13 0 +loop9 0.09 0.00 0.00 0 0 +loop10 0.15 0.00 0.00 0 0 +loop11 0.05 0.00 0.00 0 0 +loop12 0.07 0.00 0.00 0 0 +loop13 0.06 0.00 0.00 0 0 +loop14 0.09 0.00 0.00 0 0 +loop15 0.09 0.00 0.00 0 0 + diff --git a/tests/fixtures/ubuntu-18.04/iostat-mx.json b/tests/fixtures/ubuntu-18.04/iostat-mx.json new file mode 100644 index 00000000..25cbcb75 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-mx.json @@ -0,0 +1 @@ +[{"percent_user":12.13,"percent_nice":3.65,"percent_system":7.74,"percent_iowait":1.38,"percent_steal":0.0,"percent_idle":75.1,"type":"cpu"},{"device":"loop0","r_s":0.05,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":16.9,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.14,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":11.52,"w_s":0.0,"rmb_s":0.01,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":1.15,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.13,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.97,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":14.57,"wareq_sz":0.0,"svctm":0.12,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.07,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":11.04,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.65,"wareq_sz":0.0,"svctm":0.22,"percent_util":0.0,"type":"device"},{"device":"loop4","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":13.83,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":18.08,"wareq_sz":0.0,"svctm":2.24,"percent_util":0.02,"type":"device"},{"device":"loop5","r_s":0.14,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.14,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":11.12,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop6","r_s":0.05,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.14,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.61,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":17.54,"wareq_sz":0.0,"svctm":0.07,"percent_util":0.0,"type":"device"},{"device":"fd0","r_s":0.27,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.43,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.92,"wareq_sz":0.0,"svctm":4.43,"percent_util":0.12,"type":"device"},{"device":"sda","r_s":40.74,"w_s":44.66,"rmb_s":1.93,"wmb_s":3.43,"rrqm_s":3.5,"wrqm_s":96.04,"percent_rrqm":7.9,"percent_wrqm":68.26,"r_await":1.65,"w_await":3.0,"aqu_sz":0.2,"rareq_sz":48.6,"wareq_sz":78.55,"svctm":0.55,"percent_util":4.66,"type":"device"},{"device":"scd0","r_s":3.01,"w_s":0.0,"rmb_s":0.07,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.3,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.48,"wareq_sz":0.0,"svctm":0.29,"percent_util":0.09,"type":"device"},{"device":"scd1","r_s":3.01,"w_s":0.0,"rmb_s":0.07,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.27,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.31,"wareq_sz":0.0,"svctm":0.27,"percent_util":0.08,"type":"device"},{"device":"loop8","r_s":16.54,"w_s":0.0,"rmb_s":0.02,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.83,"w_await":0.0,"aqu_sz":0.01,"rareq_sz":1.08,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.06,"type":"device"},{"device":"loop9","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.03,"wareq_sz":0.0,"svctm":0.6,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.13,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.51,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.81,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.0,"type":"device"},{"device":"loop11","r_s":0.04,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop12","r_s":0.06,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.25,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":7.36,"wareq_sz":0.0,"svctm":0.42,"percent_util":0.0,"type":"device"},{"device":"loop13","r_s":0.06,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":5.02,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":8.1,"wareq_sz":0.0,"svctm":0.09,"percent_util":0.0,"type":"device"},{"device":"loop14","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.0,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop15","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.06,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":5.82,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-mx.out b/tests/fixtures/ubuntu-18.04/iostat-mx.out new file mode 100644 index 00000000..d95ed86f --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-mx.out @@ -0,0 +1,26 @@ +Linux 4.15.0-158-generic (kbrazil-ubuntu) 12/01/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 12.13 3.65 7.74 1.38 0.00 75.10 + +Device r/s w/s rMB/s wMB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util +loop0 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 16.90 0.00 0.00 3.14 0.00 0.00 0.00 +loop1 11.52 0.00 0.01 0.00 0.00 0.00 0.00 0.00 0.12 0.00 0.00 1.15 0.00 0.00 0.00 +loop2 0.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.97 0.00 0.00 14.57 0.00 0.12 0.00 +loop3 0.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 11.04 0.00 0.00 6.65 0.00 0.22 0.00 +loop4 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 13.83 0.00 0.00 18.08 0.00 2.24 0.02 +loop5 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.14 0.00 0.00 11.12 0.00 0.00 0.00 +loop6 0.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.00 0.00 0.00 3.14 0.00 0.00 0.00 +loop7 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.61 0.00 0.00 17.54 0.00 0.07 0.00 +fd0 0.27 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.43 0.00 0.00 3.92 0.00 4.43 0.12 +sda 40.74 44.66 1.93 3.43 3.50 96.04 7.90 68.26 1.65 3.00 0.20 48.60 78.55 0.55 4.66 +scd0 3.01 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.30 0.00 0.00 22.48 0.00 0.29 0.09 +scd1 3.01 0.00 0.07 0.00 0.00 0.00 0.00 0.00 0.27 0.00 0.00 22.31 0.00 0.27 0.08 +loop8 16.54 0.00 0.02 0.00 0.00 0.00 0.00 0.00 0.83 0.00 0.01 1.08 0.00 0.04 0.06 +loop9 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.67 0.00 0.00 6.03 0.00 0.60 0.00 +loop10 0.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.51 0.00 0.00 4.81 0.00 0.04 0.00 +loop11 0.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.67 0.00 0.00 3.27 0.00 0.00 0.00 +loop12 0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.25 0.00 0.00 7.36 0.00 0.42 0.00 +loop13 0.06 0.00 0.00 0.00 0.00 0.00 0.00 0.00 5.02 0.00 0.00 8.10 0.00 0.09 0.00 +loop14 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.00 0.00 0.00 0.00 +loop15 0.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 5.82 0.00 0.00 0.00 diff --git a/tests/fixtures/ubuntu-18.04/iostat-x.json b/tests/fixtures/ubuntu-18.04/iostat-x.json new file mode 100644 index 00000000..6af9685f --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-x.json @@ -0,0 +1 @@ +[{"percent_user":39.64,"percent_nice":12.36,"percent_system":28.21,"percent_iowait":2.28,"percent_steal":0.0,"percent_idle":17.51,"type":"cpu"},{"device":"loop0","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":20.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":63.02,"w_s":0.0,"rkb_s":72.52,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":1.15,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.01,"type":"device"},{"device":"loop2","r_s":0.66,"w_s":0.0,"rkb_s":10.2,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":7.42,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":15.51,"wareq_sz":0.0,"svctm":0.13,"percent_util":0.01,"type":"device"},{"device":"loop3","r_s":0.34,"w_s":0.0,"rkb_s":2.49,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":12.87,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":7.41,"wareq_sz":0.0,"svctm":0.26,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.43,"w_s":0.0,"rkb_s":7.8,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":13.83,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":18.08,"wareq_sz":0.0,"svctm":2.24,"percent_util":0.1,"type":"device"},{"device":"loop5","r_s":0.72,"w_s":0.0,"rkb_s":8.56,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.39,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":11.84,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop6","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.64,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.39,"w_s":0.0,"rkb_s":7.69,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.08,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":19.85,"wareq_sz":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"},{"device":"fd0","r_s":1.21,"w_s":0.0,"rkb_s":4.82,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.59,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.0,"wareq_sz":0.0,"svctm":2.59,"percent_util":0.31,"type":"device"},{"device":"sda","r_s":127.92,"w_s":67.15,"rkb_s":8595.16,"wkb_s":12457.33,"rrqm_s":15.79,"wrqm_s":142.95,"percent_rrqm":10.99,"percent_wrqm":68.04,"r_await":2.57,"w_await":6.93,"aqu_sz":0.79,"rareq_sz":67.19,"wareq_sz":185.52,"svctm":0.78,"percent_util":15.14,"type":"device"},{"device":"scd0","r_s":14.11,"w_s":0.0,"rkb_s":317.88,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.34,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.52,"wareq_sz":0.0,"svctm":0.34,"percent_util":0.47,"type":"device"},{"device":"scd1","r_s":14.11,"w_s":0.0,"rkb_s":315.43,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.31,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.35,"wareq_sz":0.0,"svctm":0.31,"percent_util":0.43,"type":"device"},{"device":"loop8","r_s":92.5,"w_s":0.0,"rkb_s":99.83,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.83,"w_await":0.0,"aqu_sz":0.07,"rareq_sz":1.08,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.36,"type":"device"},{"device":"loop9","r_s":0.38,"w_s":0.0,"rkb_s":2.51,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":7.54,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.62,"wareq_sz":0.0,"svctm":0.69,"percent_util":0.03,"type":"device"},{"device":"loop10","r_s":0.67,"w_s":0.0,"rkb_s":3.35,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.61,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.99,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.0,"type":"device"},{"device":"loop11","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop12","r_s":0.3,"w_s":0.0,"rkb_s":2.45,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.98,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":8.2,"wareq_sz":0.0,"svctm":0.49,"percent_util":0.01,"type":"device"},{"device":"loop13","r_s":0.26,"w_s":0.0,"rkb_s":2.42,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":5.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":9.19,"wareq_sz":0.0,"svctm":0.11,"percent_util":0.0,"type":"device"},{"device":"loop14","r_s":0.39,"w_s":0.0,"rkb_s":2.54,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.57,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop15","r_s":0.39,"w_s":0.0,"rkb_s":2.51,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.35,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-x.out b/tests/fixtures/ubuntu-18.04/iostat-x.out new file mode 100644 index 00000000..89b466d0 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-x.out @@ -0,0 +1,26 @@ +Linux 4.15.0-158-generic (kbrazil-ubuntu) 12/01/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 39.64 12.36 28.21 2.28 0.00 17.51 + +Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util +loop0 0.24 0.00 0.79 0.00 0.00 0.00 0.00 0.00 20.12 0.00 0.00 3.27 0.00 0.00 0.00 +loop1 63.02 0.00 72.52 0.00 0.00 0.00 0.00 0.00 0.12 0.00 0.00 1.15 0.00 0.00 0.01 +loop2 0.66 0.00 10.20 0.00 0.00 0.00 0.00 0.00 7.42 0.00 0.00 15.51 0.00 0.13 0.01 +loop3 0.34 0.00 2.49 0.00 0.00 0.00 0.00 0.00 12.87 0.00 0.00 7.41 0.00 0.26 0.01 +loop4 0.43 0.00 7.80 0.00 0.00 0.00 0.00 0.00 13.83 0.00 0.00 18.08 0.00 2.24 0.10 +loop5 0.72 0.00 8.56 0.00 0.00 0.00 0.00 0.00 3.39 0.00 0.00 11.84 0.00 0.00 0.00 +loop6 0.24 0.00 0.79 0.00 0.00 0.00 0.00 0.00 3.64 0.00 0.00 3.27 0.00 0.00 0.00 +loop7 0.39 0.00 7.69 0.00 0.00 0.00 0.00 0.00 4.08 0.00 0.00 19.85 0.00 0.08 0.00 +fd0 1.21 0.00 4.82 0.00 0.00 0.00 0.00 0.00 2.59 0.00 0.00 4.00 0.00 2.59 0.31 +sda 127.92 67.15 8595.16 12457.33 15.79 142.95 10.99 68.04 2.57 6.93 0.79 67.19 185.52 0.78 15.14 +scd0 14.11 0.00 317.88 0.00 0.00 0.00 0.00 0.00 0.34 0.00 0.00 22.52 0.00 0.34 0.47 +scd1 14.11 0.00 315.43 0.00 0.00 0.00 0.00 0.00 0.31 0.00 0.00 22.35 0.00 0.31 0.43 +loop8 92.50 0.00 99.83 0.00 0.00 0.00 0.00 0.00 0.83 0.00 0.07 1.08 0.00 0.04 0.36 +loop9 0.38 0.00 2.51 0.00 0.00 0.00 0.00 0.00 7.54 0.00 0.00 6.62 0.00 0.69 0.03 +loop10 0.67 0.00 3.35 0.00 0.00 0.00 0.00 0.00 2.61 0.00 0.00 4.99 0.00 0.04 0.00 +loop11 0.24 0.00 0.79 0.00 0.00 0.00 0.00 0.00 6.67 0.00 0.00 3.27 0.00 0.00 0.00 +loop12 0.30 0.00 2.45 0.00 0.00 0.00 0.00 0.00 4.98 0.00 0.00 8.20 0.00 0.49 0.01 +loop13 0.26 0.00 2.42 0.00 0.00 0.00 0.00 0.00 5.67 0.00 0.00 9.19 0.00 0.11 0.00 +loop14 0.39 0.00 2.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.57 0.00 0.00 0.00 +loop15 0.39 0.00 2.51 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.35 0.00 0.00 0.00 diff --git a/tests/fixtures/ubuntu-18.04/iostat.json b/tests/fixtures/ubuntu-18.04/iostat.json new file mode 100644 index 00000000..8ae487b8 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat.json @@ -0,0 +1 @@ +[{"percent_user":28.59,"percent_nice":11.11,"percent_system":33.13,"percent_iowait":1.52,"percent_steal":0.0,"percent_idle":25.66,"type":"cpu"},{"device":"loop0","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":94.34,"kb_read_s":108.57,"kb_wrtn_s":0.0,"kb_read":9923,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.98,"kb_read_s":15.27,"kb_wrtn_s":0.0,"kb_read":1396,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.5,"kb_read_s":3.73,"kb_wrtn_s":0.0,"kb_read":341,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.57,"kb_read_s":11.6,"kb_wrtn_s":0.0,"kb_read":1060,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.58,"kb_read_s":11.51,"kb_wrtn_s":0.0,"kb_read":1052,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.97,"kb_read_s":3.89,"kb_wrtn_s":0.0,"kb_read":356,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":179.87,"kb_read_s":7918.74,"kb_wrtn_s":9915.54,"kb_read":723773,"kb_wrtn":906280,"type":"device"},{"device":"scd0","tps":11.58,"kb_read_s":260.7,"kb_wrtn_s":0.0,"kb_read":23828,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":11.58,"kb_read_s":258.69,"kb_wrtn_s":0.0,"kb_read":23644,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":138.52,"kb_read_s":149.51,"kb_wrtn_s":0.0,"kb_read":13665,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.57,"kb_read_s":3.76,"kb_wrtn_s":0.0,"kb_read":344,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":1.01,"kb_read_s":5.02,"kb_wrtn_s":0.0,"kb_read":459,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.45,"kb_read_s":3.68,"kb_wrtn_s":0.0,"kb_read":336,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.39,"kb_read_s":3.62,"kb_wrtn_s":0.0,"kb_read":331,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.58,"kb_read_s":3.81,"kb_wrtn_s":0.0,"kb_read":348,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.59,"kb_read_s":3.75,"kb_wrtn_s":0.0,"kb_read":343,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat.out b/tests/fixtures/ubuntu-18.04/iostat.out new file mode 100644 index 00000000..cee226e6 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat.out @@ -0,0 +1,27 @@ +Linux 4.15.0-158-generic (kbrazil-ubuntu) 12/01/2021 _x86_64_ (1 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 28.59 11.11 33.13 1.52 0.00 25.66 + +Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn +loop0 0.36 1.18 0.00 108 0 +loop1 94.34 108.57 0.00 9923 0 +loop2 0.98 15.27 0.00 1396 0 +loop3 0.50 3.73 0.00 341 0 +loop4 0.57 11.60 0.00 1060 0 +loop5 0.36 1.18 0.00 108 0 +loop6 0.36 1.18 0.00 108 0 +loop7 0.58 11.51 0.00 1052 0 +fd0 0.97 3.89 0.00 356 0 +sda 179.87 7918.74 9915.54 723773 906280 +scd0 11.58 260.70 0.00 23828 0 +scd1 11.58 258.69 0.00 23644 0 +loop8 138.52 149.51 0.00 13665 0 +loop9 0.57 3.76 0.00 344 0 +loop10 1.01 5.02 0.00 459 0 +loop11 0.36 1.18 0.00 108 0 +loop12 0.45 3.68 0.00 336 0 +loop13 0.39 3.62 0.00 331 0 +loop14 0.58 3.81 0.00 348 0 +loop15 0.59 3.75 0.00 343 0 + diff --git a/tests/test_iostat.py b/tests/test_iostat.py new file mode 100644 index 00000000..9a269915 --- /dev/null +++ b/tests/test_iostat.py @@ -0,0 +1,143 @@ +import os +import unittest +import json +import jc.parsers.iostat + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class MyTests(unittest.TestCase): + + def setUp(self): + # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-m.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-x.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_mx = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-1.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_1 = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-m.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-x.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_mx = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_1 = f.read() + + + # output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-m.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_m_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-x.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_x_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-mx.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_mx_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-1.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_1_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-m.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_m_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-x.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_x_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-mx.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_mx_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_1_json = json.loads(f.read()) + + def test_iostat_nodata(self): + """ + Test 'iostat' with no data + """ + self.assertEqual(jc.parsers.iostat.parse('', quiet=True), []) + + def test_iostat_centos_7_7(self): + """ + Test 'iostat' on Centos 7.7 + """ + self.assertEqual(jc.parsers.iostat.parse(self.centos_7_7_iostat, quiet=True), self.centos_7_7_iostat_json) + + def test_iostat_m_centos_7_7(self): + """ + Test 'iostat -m' on Centos 7.7 + """ + self.assertEqual(jc.parsers.iostat.parse(self.centos_7_7_iostat_m, quiet=True), self.centos_7_7_iostat_m_json) + + def test_iostat_x_centos_7_7(self): + """ + Test 'iostat -x' on Centos 7.7 + """ + self.assertEqual(jc.parsers.iostat.parse(self.centos_7_7_iostat_x, quiet=True), self.centos_7_7_iostat_x_json) + + def test_iostat_mx_centos_7_7(self): + """ + Test 'iostat -mx' on Centos 7.7 + """ + self.assertEqual(jc.parsers.iostat.parse(self.centos_7_7_iostat_mx, quiet=True), self.centos_7_7_iostat_mx_json) + + def test_iostat_1_centos_7_7(self): + """ + Test 'iostat 1 3' on Centos 7.7 + """ + self.assertEqual(jc.parsers.iostat.parse(self.centos_7_7_iostat_1, quiet=True), self.centos_7_7_iostat_1_json) + + def test_iostat_ubuntu_18_4(self): + """ + Test 'iostat' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat, quiet=True), self.ubuntu_18_4_iostat_json) + + def test_iostat_m_ubuntu_18_4(self): + """ + Test 'iostat -m' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat_m, quiet=True), self.ubuntu_18_4_iostat_m_json) + + def test_iostat_x_ubuntu_18_4(self): + """ + Test 'iostat -x' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat_x, quiet=True), self.ubuntu_18_4_iostat_x_json) + + def test_iostat_mx_ubuntu_18_4(self): + """ + Test 'iostat -mx' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat_mx, quiet=True), self.ubuntu_18_4_iostat_mx_json) + + def test_iostat_1_ubuntu_18_4(self): + """ + Test 'iostat 1 3' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat_1, quiet=True), self.ubuntu_18_4_iostat_1_json) + + +if __name__ == '__main__': + unittest.main() From 43d34461e27e3e4ac5f985786831c170b348c7c5 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:12:51 -0800 Subject: [PATCH 20/33] update docs --- README.md | 1 + docs/parsers/acpi.md | 2 +- docs/parsers/airport.md | 2 +- docs/parsers/airport_s.md | 2 +- docs/parsers/arp.md | 2 +- docs/parsers/blkid.md | 2 +- docs/parsers/cksum.md | 2 +- docs/parsers/crontab.md | 2 +- docs/parsers/crontab_u.md | 2 +- docs/parsers/csv.md | 2 +- docs/parsers/csv_s.md | 2 +- docs/parsers/date.md | 2 +- docs/parsers/df.md | 2 +- docs/parsers/dig.md | 2 +- docs/parsers/dir.md | 2 +- docs/parsers/dmidecode.md | 2 +- docs/parsers/dpkg_l.md | 2 +- docs/parsers/du.md | 2 +- docs/parsers/env.md | 2 +- docs/parsers/file.md | 2 +- docs/parsers/finger.md | 2 +- docs/parsers/free.md | 2 +- docs/parsers/fstab.md | 2 +- docs/parsers/group.md | 2 +- docs/parsers/gshadow.md | 2 +- docs/parsers/hash.md | 2 +- docs/parsers/hashsum.md | 2 +- docs/parsers/hciconfig.md | 2 +- docs/parsers/history.md | 2 +- docs/parsers/hosts.md | 2 +- docs/parsers/id.md | 2 +- docs/parsers/ifconfig.md | 2 +- docs/parsers/ini.md | 2 +- docs/parsers/iostat.md | 172 ++++++++++++++++++++++++++++++++++ docs/parsers/iptables.md | 2 +- docs/parsers/iw_scan.md | 2 +- docs/parsers/jobs.md | 2 +- docs/parsers/last.md | 2 +- docs/parsers/ls.md | 2 +- docs/parsers/ls_s.md | 2 +- docs/parsers/lsblk.md | 2 +- docs/parsers/lsmod.md | 2 +- docs/parsers/lsof.md | 2 +- docs/parsers/lsusb.md | 2 +- docs/parsers/mount.md | 2 +- docs/parsers/netstat.md | 2 +- docs/parsers/ntpq.md | 2 +- docs/parsers/passwd.md | 2 +- docs/parsers/ping.md | 2 +- docs/parsers/ping_s.md | 2 +- docs/parsers/pip_list.md | 2 +- docs/parsers/pip_show.md | 2 +- docs/parsers/ps.md | 2 +- docs/parsers/route.md | 2 +- docs/parsers/rpm_qi.md | 2 +- docs/parsers/sfdisk.md | 2 +- docs/parsers/shadow.md | 2 +- docs/parsers/ss.md | 2 +- docs/parsers/stat.md | 2 +- docs/parsers/sysctl.md | 2 +- docs/parsers/systemctl.md | 2 +- docs/parsers/systemctl_lj.md | 2 +- docs/parsers/systemctl_ls.md | 2 +- docs/parsers/systemctl_luf.md | 2 +- docs/parsers/systeminfo.md | 2 +- docs/parsers/time.md | 2 +- docs/parsers/timedatectl.md | 2 +- docs/parsers/tracepath.md | 2 +- docs/parsers/traceroute.md | 2 +- docs/parsers/ufw.md | 2 +- docs/parsers/ufw_appinfo.md | 2 +- docs/parsers/uname.md | 2 +- docs/parsers/upower.md | 2 +- docs/parsers/uptime.md | 2 +- docs/parsers/vmstat.md | 2 +- docs/parsers/vmstat_s.md | 2 +- docs/parsers/w.md | 2 +- docs/parsers/wc.md | 2 +- docs/parsers/who.md | 2 +- docs/parsers/xml.md | 2 +- docs/parsers/yaml.md | 2 +- docs/utils.md | 22 ++++- man/jc.1 | 7 +- 83 files changed, 279 insertions(+), 81 deletions(-) create mode 100644 docs/parsers/iostat.md diff --git a/README.md b/README.md index 2547657a..0fa3f6fe 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--id` enables the `id` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/id)) - `--ifconfig` enables the `ifconfig` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ifconfig)) - `--ini` enables the INI file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ini)) +- `--iostat` enables the `iostat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat)) - `--iptables` enables the `iptables` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables)) - `--iw-scan` enables the `iw dev [device] scan` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan)) - `--jobs` enables the `jobs` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/jobs)) diff --git a/docs/parsers/acpi.md b/docs/parsers/acpi.md index cac7087c..ecf0122b 100644 --- a/docs/parsers/acpi.md +++ b/docs/parsers/acpi.md @@ -252,4 +252,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/airport.md b/docs/parsers/airport.md index 9966499c..b45bde86 100644 --- a/docs/parsers/airport.md +++ b/docs/parsers/airport.md @@ -105,4 +105,4 @@ Returns: ## Parser Information Compatibility: darwin -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/airport_s.md b/docs/parsers/airport_s.md index 08929c09..49fb032d 100644 --- a/docs/parsers/airport_s.md +++ b/docs/parsers/airport_s.md @@ -133,4 +133,4 @@ Returns: ## Parser Information Compatibility: darwin -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/arp.md b/docs/parsers/arp.md index a9a32ee1..223b5219 100644 --- a/docs/parsers/arp.md +++ b/docs/parsers/arp.md @@ -142,4 +142,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd, darwin -Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/blkid.md b/docs/parsers/blkid.md index f3246fb1..94ae4308 100644 --- a/docs/parsers/blkid.md +++ b/docs/parsers/blkid.md @@ -145,4 +145,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/cksum.md b/docs/parsers/cksum.md index 21c8c175..e278bac6 100644 --- a/docs/parsers/cksum.md +++ b/docs/parsers/cksum.md @@ -79,4 +79,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/crontab.md b/docs/parsers/crontab.md index 7c390176..4d920fa0 100644 --- a/docs/parsers/crontab.md +++ b/docs/parsers/crontab.md @@ -195,4 +195,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/crontab_u.md b/docs/parsers/crontab_u.md index b209a72c..088560ee 100644 --- a/docs/parsers/crontab_u.md +++ b/docs/parsers/crontab_u.md @@ -191,4 +191,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/csv.md b/docs/parsers/csv.md index 90d1571c..2c095082 100644 --- a/docs/parsers/csv.md +++ b/docs/parsers/csv.md @@ -99,4 +99,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/csv_s.md b/docs/parsers/csv_s.md index 983563b5..8967538a 100644 --- a/docs/parsers/csv_s.md +++ b/docs/parsers/csv_s.md @@ -74,4 +74,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/date.md b/docs/parsers/date.md index e489be92..4872bf4c 100644 --- a/docs/parsers/date.md +++ b/docs/parsers/date.md @@ -96,4 +96,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 2.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 2.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/df.md b/docs/parsers/df.md index a8b08ada..5db298d2 100644 --- a/docs/parsers/df.md +++ b/docs/parsers/df.md @@ -122,4 +122,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/dig.md b/docs/parsers/dig.md index 7b252b07..c4abdcd1 100644 --- a/docs/parsers/dig.md +++ b/docs/parsers/dig.md @@ -341,4 +341,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd, darwin, win32, cygwin -Version 2.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 2.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/dir.md b/docs/parsers/dir.md index ba3a19e8..a7a48e69 100644 --- a/docs/parsers/dir.md +++ b/docs/parsers/dir.md @@ -143,4 +143,4 @@ Returns: ## Parser Information Compatibility: win32 -Version 1.3 by Rasheed Elsaleh (rasheed@rebelliondefense.com) +Version 1.4 by Rasheed Elsaleh (rasheed@rebelliondefense.com) diff --git a/docs/parsers/dmidecode.md b/docs/parsers/dmidecode.md index 7f85b819..5be09999 100644 --- a/docs/parsers/dmidecode.md +++ b/docs/parsers/dmidecode.md @@ -150,4 +150,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/dpkg_l.md b/docs/parsers/dpkg_l.md index f367c0f6..706847f5 100644 --- a/docs/parsers/dpkg_l.md +++ b/docs/parsers/dpkg_l.md @@ -155,4 +155,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/du.md b/docs/parsers/du.md index 9d87abbb..5e795d39 100644 --- a/docs/parsers/du.md +++ b/docs/parsers/du.md @@ -112,4 +112,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/env.md b/docs/parsers/env.md index 493a121c..e141320e 100644 --- a/docs/parsers/env.md +++ b/docs/parsers/env.md @@ -95,4 +95,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/file.md b/docs/parsers/file.md index 42e1ea8e..a9c7bfeb 100644 --- a/docs/parsers/file.md +++ b/docs/parsers/file.md @@ -87,4 +87,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd, darwin -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/finger.md b/docs/parsers/finger.md index 118bbb02..111f4043 100644 --- a/docs/parsers/finger.md +++ b/docs/parsers/finger.md @@ -115,4 +115,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, freebsd -Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/free.md b/docs/parsers/free.md index 34736377..b30a22cc 100644 --- a/docs/parsers/free.md +++ b/docs/parsers/free.md @@ -97,4 +97,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/fstab.md b/docs/parsers/fstab.md index a6ab9d22..bf94c524 100644 --- a/docs/parsers/fstab.md +++ b/docs/parsers/fstab.md @@ -110,4 +110,4 @@ Returns: ## Parser Information Compatibility: linux, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/group.md b/docs/parsers/group.md index 034c80d6..a644c566 100644 --- a/docs/parsers/group.md +++ b/docs/parsers/group.md @@ -134,4 +134,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/gshadow.md b/docs/parsers/gshadow.md index d32dc91e..46709d9d 100644 --- a/docs/parsers/gshadow.md +++ b/docs/parsers/gshadow.md @@ -102,4 +102,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/hash.md b/docs/parsers/hash.md index 721e8b83..5042bf45 100644 --- a/docs/parsers/hash.md +++ b/docs/parsers/hash.md @@ -62,4 +62,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/hashsum.md b/docs/parsers/hashsum.md index 5bcb6b77..bbe3b318 100644 --- a/docs/parsers/hashsum.md +++ b/docs/parsers/hashsum.md @@ -93,4 +93,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/hciconfig.md b/docs/parsers/hciconfig.md index 93e34812..d86ce1d3 100644 --- a/docs/parsers/hciconfig.md +++ b/docs/parsers/hciconfig.md @@ -342,4 +342,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/history.md b/docs/parsers/history.md index 22eaaaec..aec2f0cd 100644 --- a/docs/parsers/history.md +++ b/docs/parsers/history.md @@ -85,4 +85,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/hosts.md b/docs/parsers/hosts.md index ed652c7b..f4646d4e 100644 --- a/docs/parsers/hosts.md +++ b/docs/parsers/hosts.md @@ -99,4 +99,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/id.md b/docs/parsers/id.md index 303858f1..2b7a4038 100644 --- a/docs/parsers/id.md +++ b/docs/parsers/id.md @@ -130,4 +130,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ifconfig.md b/docs/parsers/ifconfig.md index 985be4be..568b6f28 100644 --- a/docs/parsers/ifconfig.md +++ b/docs/parsers/ifconfig.md @@ -211,4 +211,4 @@ Returns: ## Parser Information Compatibility: linux, aix, freebsd, darwin -Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ini.md b/docs/parsers/ini.md index a0659329..775bdd39 100644 --- a/docs/parsers/ini.md +++ b/docs/parsers/ini.md @@ -90,4 +90,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/iostat.md b/docs/parsers/iostat.md new file mode 100644 index 00000000..2903f963 --- /dev/null +++ b/docs/parsers/iostat.md @@ -0,0 +1,172 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.iostat +jc - JSON CLI output utility `iostat` command output parser + +Usage (cli): + + $ iostat | jc --iostat + + or + + $ jc iostat + +Usage (module): + + import jc.parsers.iostat + result = jc.parsers.iostat.parse(iostat_command_output) + +Schema: + + [ + { + "type": string, + "percent_user": float, + "percent_nice": float, + "percent_system": float, + "percent_iowait": float, + "percent_steal": float, + "percent_idle": float, + "device": string, + "tps": float, + "kb_read_s": float, + "mb_read_s": float, + "kb_wrtn_s": float, + "mb_wrtn_s": float, + "kb_read": integer, + "mb_read": integer, + "kb_wrtn": integer, + "mb_wrtn": integer, + "rrqm_s": float, + "wrqm_s": float, + "r_s": float, + "w_s": float, + "rmb_s": float, + "rkb_s": float, + "wmb_s": float, + "wkb_s": float, + "avgrq_sz": float, + "avgqu_sz": float, + "await": float, + "r_await": float, + "w_await": float, + "svctm": float, + "aqu_sz": float, + "rareq_sz": float, + "wareq_sz": float, + "percent_util": float, + "percent_rrqm": float, + "percent_wrqm": float + } + ] + +Examples: + + $ iostat | jc --iostat -p + [ + { + "percent_user": 0.15, + "percent_nice": 0.0, + "percent_system": 0.18, + "percent_iowait": 0.0, + "percent_steal": 0.0, + "percent_idle": 99.67, + "type": "cpu" + }, + { + "device": "sda", + "tps": 0.29, + "kb_read_s": 7.22, + "kb_wrtn_s": 1.25, + "kb_read": 194341, + "kb_wrtn": 33590, + "type": "device" + }, + { + "device": "dm-0", + "tps": 0.29, + "kb_read_s": 5.99, + "kb_wrtn_s": 1.17, + "kb_read": 161361, + "kb_wrtn": 31522, + "type": "device" + }, + { + "device": "dm-1", + "tps": 0.0, + "kb_read_s": 0.08, + "kb_wrtn_s": 0.0, + "kb_read": 2204, + "kb_wrtn": 0, + "type": "device" + } + ] + + $ iostat | jc --iostat -p -r + [ + { + "percent_user": "0.15", + "percent_nice": "0.00", + "percent_system": "0.18", + "percent_iowait": "0.00", + "percent_steal": "0.00", + "percent_idle": "99.67", + "type": "cpu" + }, + { + "device": "sda", + "tps": "0.29", + "kb_read_s": "7.22", + "kb_wrtn_s": "1.25", + "kb_read": "194341", + "kb_wrtn": "33590", + "type": "device" + }, + { + "device": "dm-0", + "tps": "0.29", + "kb_read_s": "5.99", + "kb_wrtn_s": "1.17", + "kb_read": "161361", + "kb_wrtn": "31522", + "type": "device" + }, + { + "device": "dm-1", + "tps": "0.00", + "kb_read_s": "0.08", + "kb_wrtn_s": "0.00", + "kb_read": "2204", + "kb_wrtn": "0", + "type": "device" + } + ] + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON 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/docs/parsers/iptables.md b/docs/parsers/iptables.md index 6cbc0c60..5660af97 100644 --- a/docs/parsers/iptables.md +++ b/docs/parsers/iptables.md @@ -188,4 +188,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/iw_scan.md b/docs/parsers/iw_scan.md index e36d91fb..ab0533b1 100644 --- a/docs/parsers/iw_scan.md +++ b/docs/parsers/iw_scan.md @@ -145,4 +145,4 @@ Returns: ## Parser Information Compatibility: linux -Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 0.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/jobs.md b/docs/parsers/jobs.md index 81cb5641..56aebae2 100644 --- a/docs/parsers/jobs.md +++ b/docs/parsers/jobs.md @@ -117,4 +117,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/last.md b/docs/parsers/last.md index b5a1419c..47c8e1e8 100644 --- a/docs/parsers/last.md +++ b/docs/parsers/last.md @@ -128,4 +128,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ls.md b/docs/parsers/ls.md index 7c523c04..f09aa824 100644 --- a/docs/parsers/ls.md +++ b/docs/parsers/ls.md @@ -131,4 +131,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ls_s.md b/docs/parsers/ls_s.md index 85d923cc..237ff159 100644 --- a/docs/parsers/ls_s.md +++ b/docs/parsers/ls_s.md @@ -91,4 +91,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 0.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/lsblk.md b/docs/parsers/lsblk.md index 5958575f..685d9146 100644 --- a/docs/parsers/lsblk.md +++ b/docs/parsers/lsblk.md @@ -293,4 +293,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/lsmod.md b/docs/parsers/lsmod.md index f914e1c6..99cfcb2e 100644 --- a/docs/parsers/lsmod.md +++ b/docs/parsers/lsmod.md @@ -150,4 +150,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/lsof.md b/docs/parsers/lsof.md index 4de5fef6..165c4473 100644 --- a/docs/parsers/lsof.md +++ b/docs/parsers/lsof.md @@ -144,4 +144,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/lsusb.md b/docs/parsers/lsusb.md index 0f441dfa..707e66ec 100644 --- a/docs/parsers/lsusb.md +++ b/docs/parsers/lsusb.md @@ -285,4 +285,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/mount.md b/docs/parsers/mount.md index 77b6e4b9..b0015589 100644 --- a/docs/parsers/mount.md +++ b/docs/parsers/mount.md @@ -100,4 +100,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/netstat.md b/docs/parsers/netstat.md index daa15895..58758941 100644 --- a/docs/parsers/netstat.md +++ b/docs/parsers/netstat.md @@ -379,4 +379,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.11 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.12 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ntpq.md b/docs/parsers/ntpq.md index a5001b67..5e389e41 100644 --- a/docs/parsers/ntpq.md +++ b/docs/parsers/ntpq.md @@ -231,4 +231,4 @@ Returns: ## Parser Information Compatibility: linux, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/passwd.md b/docs/parsers/passwd.md index f808b80d..312a9ab5 100644 --- a/docs/parsers/passwd.md +++ b/docs/parsers/passwd.md @@ -119,4 +119,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ping.md b/docs/parsers/ping.md index ec0db5e2..1d25d05c 100644 --- a/docs/parsers/ping.md +++ b/docs/parsers/ping.md @@ -181,4 +181,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ping_s.md b/docs/parsers/ping_s.md index 352b3ae9..ae0e26ba 100644 --- a/docs/parsers/ping_s.md +++ b/docs/parsers/ping_s.md @@ -98,4 +98,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 0.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/pip_list.md b/docs/parsers/pip_list.md index 42a22b65..4b64e2d5 100644 --- a/docs/parsers/pip_list.md +++ b/docs/parsers/pip_list.md @@ -72,4 +72,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/pip_show.md b/docs/parsers/pip_show.md index 2fc00bda..33a58720 100644 --- a/docs/parsers/pip_show.md +++ b/docs/parsers/pip_show.md @@ -90,4 +90,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ps.md b/docs/parsers/ps.md index 7d525dec..47dce780 100644 --- a/docs/parsers/ps.md +++ b/docs/parsers/ps.md @@ -231,4 +231,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/route.md b/docs/parsers/route.md index 111abbb1..119c6711 100644 --- a/docs/parsers/route.md +++ b/docs/parsers/route.md @@ -133,4 +133,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/rpm_qi.md b/docs/parsers/rpm_qi.md index 0766c222..38a08c05 100644 --- a/docs/parsers/rpm_qi.md +++ b/docs/parsers/rpm_qi.md @@ -181,4 +181,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/sfdisk.md b/docs/parsers/sfdisk.md index a8fb0365..c5eededc 100644 --- a/docs/parsers/sfdisk.md +++ b/docs/parsers/sfdisk.md @@ -225,4 +225,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/shadow.md b/docs/parsers/shadow.md index ff22a0d1..e937ab14 100644 --- a/docs/parsers/shadow.md +++ b/docs/parsers/shadow.md @@ -126,4 +126,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, aix, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ss.md b/docs/parsers/ss.md index 8bc98d89..231055cf 100644 --- a/docs/parsers/ss.md +++ b/docs/parsers/ss.md @@ -303,4 +303,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/stat.md b/docs/parsers/stat.md index 3e62440b..05676277 100644 --- a/docs/parsers/stat.md +++ b/docs/parsers/stat.md @@ -193,4 +193,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.10 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/sysctl.md b/docs/parsers/sysctl.md index a24da65d..7e51fb18 100644 --- a/docs/parsers/sysctl.md +++ b/docs/parsers/sysctl.md @@ -79,4 +79,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/systemctl.md b/docs/parsers/systemctl.md index 050c492f..2c23c110 100644 --- a/docs/parsers/systemctl.md +++ b/docs/parsers/systemctl.md @@ -83,4 +83,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/systemctl_lj.md b/docs/parsers/systemctl_lj.md index 72a5a4af..cb38e495 100644 --- a/docs/parsers/systemctl_lj.md +++ b/docs/parsers/systemctl_lj.md @@ -100,4 +100,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/systemctl_ls.md b/docs/parsers/systemctl_ls.md index 9270e007..e4f02318 100644 --- a/docs/parsers/systemctl_ls.md +++ b/docs/parsers/systemctl_ls.md @@ -75,4 +75,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/systemctl_luf.md b/docs/parsers/systemctl_luf.md index 8e1bb21a..477b2f14 100644 --- a/docs/parsers/systemctl_luf.md +++ b/docs/parsers/systemctl_luf.md @@ -71,4 +71,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/systeminfo.md b/docs/parsers/systeminfo.md index 625a5176..a30216f5 100644 --- a/docs/parsers/systeminfo.md +++ b/docs/parsers/systeminfo.md @@ -229,4 +229,4 @@ Returns: ## Parser Information Compatibility: win32 -Version 1.0 by Jon Smith (jon@rebelliondefense.com) +Version 1.1 by Jon Smith (jon@rebelliondefense.com) diff --git a/docs/parsers/time.md b/docs/parsers/time.md index cc8468bd..909d74ac 100644 --- a/docs/parsers/time.md +++ b/docs/parsers/time.md @@ -148,4 +148,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/timedatectl.md b/docs/parsers/timedatectl.md index 9d740a5a..e896bef5 100644 --- a/docs/parsers/timedatectl.md +++ b/docs/parsers/timedatectl.md @@ -88,4 +88,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/tracepath.md b/docs/parsers/tracepath.md index b4ab6b43..3d621c8a 100644 --- a/docs/parsers/tracepath.md +++ b/docs/parsers/tracepath.md @@ -156,4 +156,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/traceroute.md b/docs/parsers/traceroute.md index e29dd8b8..5cedbc83 100644 --- a/docs/parsers/traceroute.md +++ b/docs/parsers/traceroute.md @@ -142,4 +142,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index a82a4034..1aee6e3d 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -222,4 +222,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/ufw_appinfo.md b/docs/parsers/ufw_appinfo.md index 35a5d75f..19250d97 100644 --- a/docs/parsers/ufw_appinfo.md +++ b/docs/parsers/ufw_appinfo.md @@ -155,4 +155,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/uname.md b/docs/parsers/uname.md index 6af337af..329711bc 100644 --- a/docs/parsers/uname.md +++ b/docs/parsers/uname.md @@ -72,4 +72,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, freebsd -Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.7 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/upower.md b/docs/parsers/upower.md index 6156d1e6..2e4fc65f 100644 --- a/docs/parsers/upower.md +++ b/docs/parsers/upower.md @@ -219,4 +219,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/uptime.md b/docs/parsers/uptime.md index 1fe63384..e7cc2ed8 100644 --- a/docs/parsers/uptime.md +++ b/docs/parsers/uptime.md @@ -90,4 +90,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/vmstat.md b/docs/parsers/vmstat.md index c220728c..fdf5792c 100644 --- a/docs/parsers/vmstat.md +++ b/docs/parsers/vmstat.md @@ -146,4 +146,4 @@ Returns: ## Parser Information Compatibility: linux -Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/vmstat_s.md b/docs/parsers/vmstat_s.md index 4cfdc858..214814d9 100644 --- a/docs/parsers/vmstat_s.md +++ b/docs/parsers/vmstat_s.md @@ -111,4 +111,4 @@ Returns: ## Parser Information Compatibility: linux -Version 0.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 0.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/w.md b/docs/parsers/w.md index 63340390..630e942b 100644 --- a/docs/parsers/w.md +++ b/docs/parsers/w.md @@ -128,4 +128,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/wc.md b/docs/parsers/wc.md index 130ef740..1b5b5d38 100644 --- a/docs/parsers/wc.md +++ b/docs/parsers/wc.md @@ -79,4 +79,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.2 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.3 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/who.md b/docs/parsers/who.md index f694220e..fa954387 100644 --- a/docs/parsers/who.md +++ b/docs/parsers/who.md @@ -157,4 +157,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, aix, freebsd -Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/xml.md b/docs/parsers/xml.md index 6be25da5..2dddebc9 100644 --- a/docs/parsers/xml.md +++ b/docs/parsers/xml.md @@ -95,4 +95,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/yaml.md b/docs/parsers/yaml.md index d389c3ec..a24deacb 100644 --- a/docs/parsers/yaml.md +++ b/docs/parsers/yaml.md @@ -109,4 +109,4 @@ Returns: ## Parser Information Compatibility: linux, darwin, cygwin, win32, aix, freebsd -Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com) +Version 1.6 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/utils.md b/docs/utils.md index 0a4482f0..08938dcc 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -40,7 +40,7 @@ Returns: ## compatibility ```python -compatibility(mod_name, compatible) +compatibility(mod_name, compatible, quiet=False) ``` Checks for the parser's compatibility with the running OS platform. @@ -52,6 +52,8 @@ Parameters: compatible options: linux, darwin, cygwin, win32, aix, freebsd + quiet: (bool) supress compatibility message if True + Returns: None - just prints output to STDERR @@ -135,6 +137,24 @@ Reraise the stream exception with annotation or print an error `_jc_meta` field if `ignore_exceptions=True` +## input_type_check +```python +input_type_check(data) +``` +Ensure input data is a string + +## streaming_input_type_check +```python +streaming_input_type_check(data) +``` +Ensure input data is an iterable, but not a string or bytes + +## streaming_line_input_type_check +```python +streaming_line_input_type_check(line) +``` +Ensure each line is a string + ## timestamp ```python timestamp(datetime_string) diff --git a/man/jc.1 b/man/jc.1 index 15b35aa7..8c94ca35 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -1,4 +1,4 @@ -.TH jc 1 2021-11-18 1.17.2 "JSON CLI output utility" +.TH jc 1 2021-12-01 1.17.3 "JSON CLI output utility" .SH NAME jc \- JSONifies the output of many CLI tools and file-types .SH SYNOPSIS @@ -177,6 +177,11 @@ hashsum command parser (`md5sum`, `shasum`, etc.) \fB--ini\fP INI file parser +.TP +.B +\fB--iostat\fP +`iostat` command parser + .TP .B \fB--iptables\fP From 6c11e912afe3c4d16da9199b5c2fc10461928ac3 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:14:22 -0800 Subject: [PATCH 21/33] update changelog --- CHANGELOG | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 1b8d821a..550bf190 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,10 @@ jc changelog -20211130 v1.17.3 +20211201 v1.17.3 - Update parsers to exit with error if non-string input is detected (raise TypeError) - Update streaming parsers to exit with error if non-iterable input is detected (raise TypeError) - Simplify quiet-checking in parsers +- Add iostat parser tested on linux 20211117 v1.17.2 - Fix ping parser to add Alpine linux support From 2752e0d66a9ba0b57ac86913fd302ada23c280c0 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:47:09 -0800 Subject: [PATCH 22/33] add iostat streaming parser --- jc/cli.py | 1 + jc/parsers/iostat_s.py | 165 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 jc/parsers/iostat_s.py diff --git a/jc/cli.py b/jc/cli.py index 7727a0f8..a81a1c32 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -77,6 +77,7 @@ parsers = [ 'ifconfig', 'ini', 'iostat', + 'iostat-s', 'iptables', 'iw-scan', 'jobs', diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py new file mode 100644 index 00000000..7780c894 --- /dev/null +++ b/jc/parsers/iostat_s.py @@ -0,0 +1,165 @@ +"""jc - JSON CLI output utility `iostat` command output streaming parser + +> This streaming parser outputs JSON Lines + +<> + +Usage (cli): + + $ iostat | jc --iostat-s + +Usage (module): + + import jc.parsers.iostat_s + result = jc.parsers.iostat_s.parse(iostat_command_output.splitlines()) # result is an iterable object + for item in result: + # do something + +Schema: + + { + "iostat": string, + "_jc_meta": # This object only exists if using -qq or ignore_exceptions=True + { + "success": booean, # true if successfully parsed, false if error + "error": string, # exists if "success" is false + "line": string # exists if "success" is false + } + } + +Examples: + + $ iostat | jc --iostat-s + {example output} + ... + + $ iostat | jc --iostat-s -r + {example output} + ... +""" +import jc.utils +from jc.utils import stream_success, stream_error +from jc.exceptions import ParseError +import jc.parsers.universal + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`iostat` command streaming parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] + streaming = True + + +__version__ = info.version + + +def _process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (Dictionary) raw structured data to process + + Returns: + + Dictionary. Structured data to conform to the schema. + """ + float_list = [ + 'percent_user', 'percent_nice', 'percent_system', 'percent_iowait', + 'percent_steal', 'percent_idle', 'tps', 'kb_read_s', 'mb_read_s', 'kb_wrtn_s', + 'mb_wrtn_s', 'rrqm_s', 'wrqm_s', 'r_s', 'w_s', 'rmb_s', 'rkb_s', 'wmb_s', + 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', + 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz' + ] + int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] + for key in proc_data: + if key in int_list: + proc_data[key] = jc.utils.convert_to_int(proc_data[key]) + + if key in float_list: + proc_data[key] = jc.utils.convert_to_float(proc_data[key]) + + return proc_data + +def _normalize_headers(line): + return line.replace('%', 'percent_').replace('/', '_').replace('-', '_').lower() + +def _create_obj_list(section_list, section_name): + output_list = jc.parsers.universal.simple_table_parse(section_list) + for item in output_list: + item['type'] = section_name + return output_list + +def parse(data, raw=False, quiet=False, ignore_exceptions=False): + """ + Main text parsing generator function. Returns an iterator object. + + Parameters: + + data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines()) + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + ignore_exceptions: (boolean) ignore parsing exceptions if True + + Yields: + + Dictionary. Raw or processed structured data. + + Returns: + + Iterator object + """ + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.streaming_input_type_check(data) + + section = '' # either 'cpu' or 'device' + headers = '' + cpu_list = [] + device_list = [] + + for line in data: + output_line = {} + try: + jc.utils.streaming_line_input_type_check(line) + + # ignore blank lines and header line + if line == '\n' or line.startswith('Linux'): + continue + + if line.startswith('avg-cpu:'): + section = 'cpu' + headers = _normalize_headers(line) + headers = headers.strip().split(':', maxsplit=1)[1:] + headers = ' '.join(headers) + continue + + if line.startswith('Device'): + section = 'device' + headers = _normalize_headers(line) + headers = headers.replace(':', ' ') + continue + + if section == 'cpu': + cpu_list.append(headers) + cpu_list.append(line) + output_line = _create_obj_list(cpu_list, 'cpu')[0] + cpu_list = [] + + + if section == 'device': + device_list.append(headers) + device_list.append(line) + output_line = _create_obj_list(device_list, 'device')[0] + device_list = [] + + if output_line: + yield stream_success(output_line, ignore_exceptions) if raw else stream_success(_process(output_line), ignore_exceptions) + else: + raise ParseError('Not iostat data') + + except Exception as e: + yield stream_error(e, ignore_exceptions, line) From 158a15157c7e5dde95dc21766d0696bd82486688 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 1 Dec 2021 16:47:17 -0800 Subject: [PATCH 23/33] changelog update --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 550bf190..613b0ec2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ jc changelog - Update streaming parsers to exit with error if non-iterable input is detected (raise TypeError) - Simplify quiet-checking in parsers - Add iostat parser tested on linux +- Add iostat streaming parser tested on linux 20211117 v1.17.2 - Fix ping parser to add Alpine linux support From 8f02021014b7b19acf1a8bbd777161aa82c65d66 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 05:54:38 -0800 Subject: [PATCH 24/33] formatting --- jc/parsers/iostat_s.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 7780c894..8d5ba872 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -149,7 +149,6 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): output_line = _create_obj_list(cpu_list, 'cpu')[0] cpu_list = [] - if section == 'device': device_list.append(headers) device_list.append(line) From 541aa1d09f20ff6979eabaa66790decb3895f18d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 08:41:36 -0800 Subject: [PATCH 25/33] Add new field float conversions for iostat v11 --- jc/parsers/iostat.py | 15 ++++++++++- jc/parsers/iostat_s.py | 61 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py index 3c464876..8362640d 100644 --- a/jc/parsers/iostat.py +++ b/jc/parsers/iostat.py @@ -1,5 +1,7 @@ """jc - JSON CLI output utility `iostat` command output parser +Note: `iostat` version 11 and higher include a JSON output option + Usage (cli): $ iostat | jc --iostat @@ -51,6 +53,15 @@ Schema: "aqu_sz": float, "rareq_sz": float, "wareq_sz": float, + "d_s": float, + "dkb_s": float, + "dmb_s": float, + "drqm_s": float, + "percent_drqm": float, + "d_await": float, + "dareq_sz": float, + "f_s": float, + "f_await": float, "percent_util": float, "percent_rrqm": float, "percent_wrqm": float @@ -175,7 +186,9 @@ def _process(proc_data): 'percent_steal', 'percent_idle', 'tps', 'kb_read_s', 'mb_read_s', 'kb_wrtn_s', 'mb_wrtn_s', 'rrqm_s', 'wrqm_s', 'r_s', 'w_s', 'rmb_s', 'rkb_s', 'wmb_s', 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', - 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz' + 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz', + 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', + 'f_s', 'f_await' ] int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] for key in entry: diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 8d5ba872..5e9b2946 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -2,7 +2,7 @@ > This streaming parser outputs JSON Lines -<> +Note: `iostat` version 11 and higher include a JSON output option Usage (cli): @@ -18,12 +18,57 @@ Usage (module): Schema: { - "iostat": string, - "_jc_meta": # This object only exists if using -qq or ignore_exceptions=True + "type": string, + "percent_user": float, + "percent_nice": float, + "percent_system": float, + "percent_iowait": float, + "percent_steal": float, + "percent_idle": float, + "device": string, + "tps": float, + "kb_read_s": float, + "mb_read_s": float, + "kb_wrtn_s": float, + "mb_wrtn_s": float, + "kb_read": integer, + "mb_read": integer, + "kb_wrtn": integer, + "mb_wrtn": integer, + "rrqm_s": float, + "wrqm_s": float, + "r_s": float, + "w_s": float, + "rmb_s": float, + "rkb_s": float, + "wmb_s": float, + "wkb_s": float, + "avgrq_sz": float, + "avgqu_sz": float, + "await": float, + "r_await": float, + "w_await": float, + "svctm": float, + "aqu_sz": float, + "rareq_sz": float, + "wareq_sz": float, + "d_s": float, + "dkb_s": float, + "dmb_s": float, + "drqm_s": float, + "percent_drqm": float, + "d_await": float, + "dareq_sz": float, + "f_s": float, + "f_await": float, + "percent_util": float, + "percent_rrqm": float, + "percent_wrqm": float, + "_jc_meta": # This object only exists if using -qq or ignore_exceptions=True { - "success": booean, # true if successfully parsed, false if error - "error": string, # exists if "success" is false - "line": string # exists if "success" is false + "success": booean, # true if successfully parsed, false if error + "error": string, # exists if "success" is false + "line": string # exists if "success" is false } } @@ -73,7 +118,9 @@ def _process(proc_data): 'percent_steal', 'percent_idle', 'tps', 'kb_read_s', 'mb_read_s', 'kb_wrtn_s', 'mb_wrtn_s', 'rrqm_s', 'wrqm_s', 'r_s', 'w_s', 'rmb_s', 'rkb_s', 'wmb_s', 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', - 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz' + 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz', + 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', + 'f_s', 'f_await' ] int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] for key in proc_data: From 4d823575e791999e200dedd491511c4fde64fc2e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 08:47:25 -0800 Subject: [PATCH 26/33] add more float fields --- jc/parsers/iostat.py | 4 +++- jc/parsers/iostat_s.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py index 8362640d..55175c3a 100644 --- a/jc/parsers/iostat.py +++ b/jc/parsers/iostat.py @@ -62,6 +62,8 @@ Schema: "dareq_sz": float, "f_s": float, "f_await": float, + "kb_dscd_s": float, + "mb_dscd_s": float, "percent_util": float, "percent_rrqm": float, "percent_wrqm": float @@ -188,7 +190,7 @@ def _process(proc_data): 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz', 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', - 'f_s', 'f_await' + 'f_s', 'f_await', 'kb_dscd_s', 'mb_dscd_s' ] int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] for key in entry: diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 5e9b2946..7df6a6cc 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -61,6 +61,8 @@ Schema: "dareq_sz": float, "f_s": float, "f_await": float, + "kb_dscd_s": float, + "mb_dscd_s": float, "percent_util": float, "percent_rrqm": float, "percent_wrqm": float, @@ -120,7 +122,7 @@ def _process(proc_data): 'wkb_s', 'avgrq_sz', 'avgqu_sz', 'await', 'r_await', 'w_await', 'svctm', 'percent_util', 'percent_rrqm', 'percent_wrqm', 'aqu_sz', 'rareq_sz', 'wareq_sz', 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', - 'f_s', 'f_await' + 'f_s', 'f_await', 'kb_dscd_s', 'mb_dscd_s' ] int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] for key in proc_data: From 537b8f263087894c02b5b7c121765cf96182a370 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 09:14:43 -0800 Subject: [PATCH 27/33] add more int conversions --- jc/parsers/iostat.py | 4 +++- jc/parsers/iostat_s.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jc/parsers/iostat.py b/jc/parsers/iostat.py index 55175c3a..d33d5e93 100644 --- a/jc/parsers/iostat.py +++ b/jc/parsers/iostat.py @@ -36,6 +36,8 @@ Schema: "mb_read": integer, "kb_wrtn": integer, "mb_wrtn": integer, + 'kb_dscd': integer, + 'mb_dscd': integer, "rrqm_s": float, "wrqm_s": float, "r_s": float, @@ -192,7 +194,7 @@ def _process(proc_data): 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', 'f_s', 'f_await', 'kb_dscd_s', 'mb_dscd_s' ] - int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] + int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn', 'kb_dscd', 'mb_dscd'] for key in entry: if key in int_list: entry[key] = jc.utils.convert_to_int(entry[key]) diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 7df6a6cc..9fff6a78 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -35,6 +35,8 @@ Schema: "mb_read": integer, "kb_wrtn": integer, "mb_wrtn": integer, + 'kb_dscd': integer, + 'mb_dscd': integer, "rrqm_s": float, "wrqm_s": float, "r_s": float, @@ -124,7 +126,7 @@ def _process(proc_data): 'd_s', 'dkb_s', 'dmb_s', 'drqm_s', 'percent_drqm', 'd_await', 'dareq_sz', 'f_s', 'f_await', 'kb_dscd_s', 'mb_dscd_s' ] - int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn'] + int_list = ['kb_read', 'mb_read', 'kb_wrtn', 'mb_wrtn', 'kb_dscd', 'mb_dscd'] for key in proc_data: if key in int_list: proc_data[key] = jc.utils.convert_to_int(proc_data[key]) From 7b467c466568ad4e7986d4d7cf3ec606681b6d46 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 09:30:16 -0800 Subject: [PATCH 28/33] add ubuntu 20.10 tests --- tests/fixtures/ubuntu-20.10/iostat-m.json | 1 + tests/fixtures/ubuntu-20.10/iostat-m.out | 21 ++++++++++ tests/fixtures/ubuntu-20.10/iostat-mx.json | 1 + tests/fixtures/ubuntu-20.10/iostat-mx.out | 22 ++++++++++ tests/fixtures/ubuntu-20.10/iostat-x.json | 1 + tests/fixtures/ubuntu-20.10/iostat-x.out | 21 ++++++++++ tests/fixtures/ubuntu-20.10/iostat.json | 1 + tests/fixtures/ubuntu-20.10/iostat.out | 22 ++++++++++ tests/test_iostat.py | 47 ++++++++++++++++++++++ 9 files changed, 137 insertions(+) create mode 100644 tests/fixtures/ubuntu-20.10/iostat-m.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-m.out create mode 100644 tests/fixtures/ubuntu-20.10/iostat-mx.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-mx.out create mode 100644 tests/fixtures/ubuntu-20.10/iostat-x.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-x.out create mode 100644 tests/fixtures/ubuntu-20.10/iostat.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat.out diff --git a/tests/fixtures/ubuntu-20.10/iostat-m.json b/tests/fixtures/ubuntu-20.10/iostat-m.json new file mode 100644 index 00000000..4a979a69 --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-m.json @@ -0,0 +1 @@ +[{"percent_user":0.39,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.1,"type":"cpu"},{"device":"dm-0","tps":9.5,"mb_read_s":0.1,"mb_wrtn_s":0.13,"mb_dscd_s":0.0,"mb_read":517,"mb_wrtn":678,"mb_dscd":0,"type":"device"},{"device":"loop0","tps":0.02,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop1","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop10","tps":0.0,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop2","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop3","tps":0.04,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":2,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop4","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop5","tps":0.1,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":17,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop6","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop7","tps":0.12,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":22,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop8","tps":0.02,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop9","tps":0.04,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":2,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"sda","tps":5.45,"mb_read_s":0.1,"mb_wrtn_s":0.13,"mb_dscd_s":0.0,"mb_read":528,"mb_wrtn":679,"mb_dscd":0,"type":"device"},{"device":"sr0","tps":0.19,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":36,"mb_wrtn":0,"mb_dscd":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-m.out b/tests/fixtures/ubuntu-20.10/iostat-m.out new file mode 100644 index 00000000..b927cb77 --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-m.out @@ -0,0 +1,21 @@ +Linux 5.8.0-53-generic (ubuntu) 12/02/2021 _x86_64_ (2 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.39 0.04 0.44 0.04 0.00 99.10 + +Device tps MB_read/s MB_wrtn/s MB_dscd/s MB_read MB_wrtn MB_dscd +dm-0 9.50 0.10 0.13 0.00 517 678 0 +loop0 0.02 0.00 0.00 0.00 1 0 0 +loop1 0.01 0.00 0.00 0.00 0 0 0 +loop10 0.00 0.00 0.00 0.00 0 0 0 +loop2 0.01 0.00 0.00 0.00 1 0 0 +loop3 0.04 0.00 0.00 0.00 2 0 0 +loop4 0.01 0.00 0.00 0.00 1 0 0 +loop5 0.10 0.00 0.00 0.00 17 0 0 +loop6 0.01 0.00 0.00 0.00 0 0 0 +loop7 0.12 0.00 0.00 0.00 22 0 0 +loop8 0.02 0.00 0.00 0.00 0 0 0 +loop9 0.04 0.00 0.00 0.00 2 0 0 +sda 5.45 0.10 0.13 0.00 528 679 0 +sr0 0.19 0.01 0.00 0.00 36 0 0 + diff --git a/tests/fixtures/ubuntu-20.10/iostat-mx.json b/tests/fixtures/ubuntu-20.10/iostat-mx.json new file mode 100644 index 00000000..05ccb2ab --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-mx.json @@ -0,0 +1 @@ +[{"percent_user":0.38,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.1,"type":"cpu"},{"device":"dm-0","r_s":2.35,"rmb_s":0.1,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.55,"rareq_sz":41.48,"w_s":7.13,"wmb_s":0.13,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.4,"wareq_sz":17.98,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.34,"type":"device"},{"device":"loop0","r_s":0.02,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.14,"rareq_sz":12.41,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.4,"rareq_sz":7.48,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.0,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":1.5,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.32,"rareq_sz":19.21,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.04,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.42,"rareq_sz":10.42,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.34,"rareq_sz":17.14,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop5","r_s":0.1,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.37,"rareq_sz":33.41,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop6","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.46,"rareq_sz":7.5,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.12,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.12,"rareq_sz":34.54,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop8","r_s":0.02,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":8.46,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop9","r_s":0.04,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.06,"rareq_sz":9.98,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"sda","r_s":2.65,"rmb_s":0.1,"rrqm_s":0.65,"percent_rrqm":19.71,"r_await":0.36,"rareq_sz":37.62,"w_s":2.8,"wmb_s":0.13,"wrqm_s":4.38,"percent_wrqm":61.04,"w_await":0.42,"wareq_sz":45.83,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.41,"type":"device"},{"device":"sr0","r_s":0.18,"rmb_s":0.01,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.24,"rareq_sz":37.55,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-mx.out b/tests/fixtures/ubuntu-20.10/iostat-mx.out new file mode 100644 index 00000000..68163f74 --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-mx.out @@ -0,0 +1,22 @@ +Linux 5.8.0-53-generic (ubuntu) 12/02/2021 _x86_64_ (2 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.38 0.04 0.44 0.04 0.00 99.10 + +Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util +dm-0 2.35 0.10 0.00 0.00 0.55 41.48 7.13 0.13 0.00 0.00 0.40 17.98 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.34 +loop0 0.02 0.00 0.00 0.00 0.14 12.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop1 0.01 0.00 0.00 0.00 0.40 7.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop10 0.00 0.00 0.00 0.00 0.00 1.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop2 0.01 0.00 0.00 0.00 0.32 19.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop3 0.04 0.00 0.00 0.00 0.42 10.42 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 +loop4 0.01 0.00 0.00 0.00 0.34 17.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop5 0.10 0.00 0.00 0.00 0.37 33.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 +loop6 0.01 0.00 0.00 0.00 0.46 7.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop7 0.12 0.00 0.00 0.00 0.12 34.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 +loop8 0.02 0.00 0.00 0.00 0.00 8.46 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop9 0.04 0.00 0.00 0.00 0.06 9.98 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +sda 2.65 0.10 0.65 19.71 0.36 37.62 2.80 0.13 4.38 61.04 0.42 45.83 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.41 +sr0 0.18 0.01 0.00 0.00 0.24 37.55 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 + + diff --git a/tests/fixtures/ubuntu-20.10/iostat-x.json b/tests/fixtures/ubuntu-20.10/iostat-x.json new file mode 100644 index 00000000..140c99ff --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-x.json @@ -0,0 +1 @@ +[{"percent_user":0.39,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.09,"type":"cpu"},{"device":"dm-0","r_s":2.38,"rkb_s":98.75,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.55,"rareq_sz":41.48,"w_s":7.18,"wkb_s":129.42,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.4,"wareq_sz":18.04,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.34,"type":"device"},{"device":"loop0","r_s":0.02,"rkb_s":0.27,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.14,"rareq_sz":12.41,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":0.01,"rkb_s":0.07,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.4,"rareq_sz":7.48,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.0,"rkb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":1.5,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.01,"rkb_s":0.2,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.32,"rareq_sz":19.21,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.04,"rkb_s":0.4,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.42,"rareq_sz":10.42,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.01,"rkb_s":0.21,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.34,"rareq_sz":17.14,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop5","r_s":0.1,"rkb_s":3.29,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.37,"rareq_sz":33.41,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop6","r_s":0.01,"rkb_s":0.07,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.46,"rareq_sz":7.5,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.12,"rkb_s":4.3,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.12,"rareq_sz":34.54,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop8","r_s":0.02,"rkb_s":0.13,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":8.46,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop9","r_s":0.04,"rkb_s":0.41,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.06,"rareq_sz":9.98,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"sda","r_s":2.67,"rkb_s":100.76,"rrqm_s":0.66,"percent_rrqm":19.76,"r_await":0.36,"rareq_sz":37.75,"w_s":2.81,"wkb_s":129.44,"wrqm_s":4.42,"percent_wrqm":61.15,"w_await":0.42,"wareq_sz":46.11,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.41,"type":"device"},{"device":"sr0","r_s":0.19,"rkb_s":7.01,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.24,"rareq_sz":37.55,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-x.out b/tests/fixtures/ubuntu-20.10/iostat-x.out new file mode 100644 index 00000000..8b5ea02b --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-x.out @@ -0,0 +1,21 @@ +Linux 5.8.0-53-generic (ubuntu) 12/02/2021 _x86_64_ (2 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.39 0.04 0.44 0.04 0.00 99.09 + +Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util +dm-0 2.38 98.75 0.00 0.00 0.55 41.48 7.18 129.42 0.00 0.00 0.40 18.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.34 +loop0 0.02 0.27 0.00 0.00 0.14 12.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop1 0.01 0.07 0.00 0.00 0.40 7.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop10 0.00 0.00 0.00 0.00 0.00 1.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop2 0.01 0.20 0.00 0.00 0.32 19.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop3 0.04 0.40 0.00 0.00 0.42 10.42 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 +loop4 0.01 0.21 0.00 0.00 0.34 17.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop5 0.10 3.29 0.00 0.00 0.37 33.41 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 +loop6 0.01 0.07 0.00 0.00 0.46 7.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop7 0.12 4.30 0.00 0.00 0.12 34.54 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03 +loop8 0.02 0.13 0.00 0.00 0.00 8.46 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +loop9 0.04 0.41 0.00 0.00 0.06 9.98 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +sda 2.67 100.76 0.66 19.76 0.36 37.75 2.81 129.44 4.42 61.15 0.42 46.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.41 +sr0 0.19 7.01 0.00 0.00 0.24 37.55 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 + diff --git a/tests/fixtures/ubuntu-20.10/iostat.json b/tests/fixtures/ubuntu-20.10/iostat.json new file mode 100644 index 00000000..3823a9ed --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat.json @@ -0,0 +1 @@ +[{"percent_user":0.4,"percent_nice":0.04,"percent_system":0.45,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.07,"type":"cpu"},{"device":"dm-0","tps":9.78,"kb_read_s":101.69,"kb_wrtn_s":133.03,"kb_dscd_s":0.0,"kb_read":530217,"kb_wrtn":693624,"kb_dscd":0,"type":"device"},{"device":"loop0","tps":0.02,"kb_read_s":0.28,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1464,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop1","tps":0.01,"kb_read_s":0.07,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":359,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":18,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop2","tps":0.01,"kb_read_s":0.21,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1095,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop3","tps":0.04,"kb_read_s":0.41,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":2137,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop4","tps":0.01,"kb_read_s":0.21,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1114,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop5","tps":0.1,"kb_read_s":3.39,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":17673,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop6","tps":0.01,"kb_read_s":0.07,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":360,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop7","tps":0.13,"kb_read_s":4.43,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":23074,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop8","tps":0.02,"kb_read_s":0.13,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":694,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop9","tps":0.04,"kb_read_s":0.42,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":2195,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"sda","tps":5.58,"kb_read_s":103.76,"kb_wrtn_s":133.05,"kb_dscd_s":0.0,"kb_read":541026,"kb_wrtn":693732,"kb_dscd":0,"type":"device"},{"device":"sr0","tps":0.19,"kb_read_s":7.22,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":37658,"kb_wrtn":0,"kb_dscd":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat.out b/tests/fixtures/ubuntu-20.10/iostat.out new file mode 100644 index 00000000..d5b56533 --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat.out @@ -0,0 +1,22 @@ +Linux 5.8.0-53-generic (ubuntu) 12/02/2021 _x86_64_ (2 CPU) + +avg-cpu: %user %nice %system %iowait %steal %idle + 0.40 0.04 0.45 0.04 0.00 99.07 + +Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd +dm-0 9.78 101.69 133.03 0.00 530217 693624 0 +loop0 0.02 0.28 0.00 0.00 1464 0 0 +loop1 0.01 0.07 0.00 0.00 359 0 0 +loop10 0.00 0.00 0.00 0.00 18 0 0 +loop2 0.01 0.21 0.00 0.00 1095 0 0 +loop3 0.04 0.41 0.00 0.00 2137 0 0 +loop4 0.01 0.21 0.00 0.00 1114 0 0 +loop5 0.10 3.39 0.00 0.00 17673 0 0 +loop6 0.01 0.07 0.00 0.00 360 0 0 +loop7 0.13 4.43 0.00 0.00 23074 0 0 +loop8 0.02 0.13 0.00 0.00 694 0 0 +loop9 0.04 0.42 0.00 0.00 2195 0 0 +sda 5.58 103.76 133.05 0.00 541026 693732 0 +sr0 0.19 7.22 0.00 0.00 37658 0 0 + + diff --git a/tests/test_iostat.py b/tests/test_iostat.py index 9a269915..1288f998 100644 --- a/tests/test_iostat.py +++ b/tests/test_iostat.py @@ -40,6 +40,17 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1.out'), 'r', encoding='utf-8') as f: self.ubuntu_18_4_iostat_1 = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-m.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-x.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_mx = f.read() # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat.json'), 'r', encoding='utf-8') as f: @@ -72,6 +83,18 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1.json'), 'r', encoding='utf-8') as f: self.ubuntu_18_4_iostat_1_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-m.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_m_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-x.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_x_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-mx.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_mx_json = json.loads(f.read()) + def test_iostat_nodata(self): """ Test 'iostat' with no data @@ -138,6 +161,30 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_18_4_iostat_1, quiet=True), self.ubuntu_18_4_iostat_1_json) + def test_iostat_ubuntu_20_10(self): + """ + Test 'iostat' on Ubuntu 20.10 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_20_10_iostat, quiet=True), self.ubuntu_20_10_iostat_json) + + def test_iostat_m_ubuntu_20_10(self): + """ + Test 'iostat -m' on Ubuntu 20.10 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_20_10_iostat_m, quiet=True), self.ubuntu_20_10_iostat_m_json) + + def test_iostat_x_ubuntu_20_10(self): + """ + Test 'iostat -x' on Ubuntu 20.10 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_20_10_iostat_x, quiet=True), self.ubuntu_20_10_iostat_x_json) + + def test_iostat_mx_ubuntu_20_10(self): + """ + Test 'iostat -mx' on Ubuntu 20.10 + """ + self.assertEqual(jc.parsers.iostat.parse(self.ubuntu_20_10_iostat_mx, quiet=True), self.ubuntu_20_10_iostat_mx_json) + if __name__ == '__main__': unittest.main() From 6f18e5344356684e845ec63158c570d82156254f Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 11:37:52 -0800 Subject: [PATCH 29/33] fix for null lines --- tests/test_iostat_s.py | 203 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 tests/test_iostat_s.py diff --git a/tests/test_iostat_s.py b/tests/test_iostat_s.py new file mode 100644 index 00000000..a29c78a5 --- /dev/null +++ b/tests/test_iostat_s.py @@ -0,0 +1,203 @@ +import os +import json +import unittest +from jc.exceptions import ParseError +import jc.parsers.iostat_s + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + +# To create streaming output use: +# $ cat iostat.out | jc --iostat-s | jello -c > iostat-streaming.json + + +class MyTests(unittest.TestCase): + + def setUp(self): + # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-m.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-x.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_mx = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-1.out'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_1 = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-m.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-x.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_mx = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_1 = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-m.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_m = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-x.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_x = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-mx.out'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_mx = f.read() + + # output + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-streaming.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-m-streaming.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_m_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-x-streaming.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_x_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-mx-streaming.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_mx_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/iostat-1-streaming.json'), 'r', encoding='utf-8') as f: + self.centos_7_7_iostat_1_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-m-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_m_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-x-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_x_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_mx_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/iostat-1-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_4_iostat_1_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-m-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_m_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-x-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_x_streaming_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json'), 'r', encoding='utf-8') as f: + self.ubuntu_20_10_iostat_mx_streaming_json = json.loads(f.read()) + + def test_iostat_empty_dir(self): + """ + Test plain 'ls' on an empty directory + """ + self.assertEqual(list(jc.parsers.iostat_s.parse([], quiet=True)), []) + + def test_iostat_raise_exception(self): + """ + Test non-iostat data (raises ParseError) + """ + g = jc.parsers.iostat_s.parse(['not iostat data','not iostat data'], quiet=True) + with self.assertRaises(ParseError): + list(g) + + def test_iostat_centos_7_7(self): + """ + Test 'iostat' on centos 7 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.centos_7_7_iostat.splitlines(), quiet=True)), self.centos_7_7_iostat_streaming_json) + + def test_iostat_m_centos_7_7(self): + """ + Test 'iostat -m' on centos 7 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.centos_7_7_iostat_m.splitlines(), quiet=True)), self.centos_7_7_iostat_m_streaming_json) + + def test_iostat_x_centos_7_7(self): + """ + Test 'iostat -x' on centos 7 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.centos_7_7_iostat_x.splitlines(), quiet=True)), self.centos_7_7_iostat_x_streaming_json) + + def test_iostat_mx_centos_7_7(self): + """ + Test 'iostat -mx' on centos 7 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.centos_7_7_iostat_mx.splitlines(), quiet=True)), self.centos_7_7_iostat_mx_streaming_json) + + def test_iostat_1_centos_7_7(self): + """ + Test 'iostat 1' on centos 7 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.centos_7_7_iostat_1.splitlines(), quiet=True)), self.centos_7_7_iostat_1_streaming_json) + + def test_iostat_ubuntu_18_4(self): + """ + Test 'iostat' on ubuntu 18.4 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_18_4_iostat.splitlines(), quiet=True)), self.ubuntu_18_4_iostat_streaming_json) + + def test_iostat_m_ubuntu_18_4(self): + """ + Test 'iostat -m' on ubuntu 18.4 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_18_4_iostat_m.splitlines(), quiet=True)), self.ubuntu_18_4_iostat_m_streaming_json) + + def test_iostat_x_ubuntu_18_4(self): + """ + Test 'iostat -x' on ubuntu 18.4 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_18_4_iostat_x.splitlines(), quiet=True)), self.ubuntu_18_4_iostat_x_streaming_json) + + def test_iostat_mx_ubuntu_18_4(self): + """ + Test 'iostat -mx' on ubuntu 18.4 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_18_4_iostat_mx.splitlines(), quiet=True)), self.ubuntu_18_4_iostat_mx_streaming_json) + + def test_iostat_1_ubuntu_18_4(self): + """ + Test 'iostat 1' on ubuntu 18.4 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_18_4_iostat_1.splitlines(), quiet=True)), self.ubuntu_18_4_iostat_1_streaming_json) + + def test_iostat_ubuntu_20_10(self): + """ + Test 'iostat' on ubuntu 20.10 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_20_10_iostat.splitlines(), quiet=True)), self.ubuntu_20_10_iostat_streaming_json) + + def test_iostat_m_ubuntu_20_10(self): + """ + Test 'iostat -m' on ubuntu 20.10 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_20_10_iostat_m.splitlines(), quiet=True)), self.ubuntu_20_10_iostat_m_streaming_json) + + def test_iostat_x_ubuntu_20_10(self): + """ + Test 'iostat -x' on ubuntu 20.10 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_20_10_iostat_x.splitlines(), quiet=True)), self.ubuntu_20_10_iostat_x_streaming_json) + + def test_iostat_mx_ubuntu_20_10(self): + """ + Test 'iostat -mx' on ubuntu 20.10 + """ + self.assertEqual(list(jc.parsers.iostat_s.parse(self.ubuntu_20_10_iostat_mx.splitlines(), quiet=True)), self.ubuntu_20_10_iostat_mx_streaming_json) + + +if __name__ == '__main__': + unittest.main() From 11aa01b0d9d6913059f98f9bd7591d7cad9037cf Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 11:38:00 -0800 Subject: [PATCH 30/33] iostat-s tests --- jc/parsers/iostat_s.py | 2 +- tests/fixtures/centos-7.7/iostat-1-streaming.json | 1 + tests/fixtures/centos-7.7/iostat-m-streaming.json | 1 + tests/fixtures/centos-7.7/iostat-mx-streaming.json | 1 + tests/fixtures/centos-7.7/iostat-streaming.json | 1 + tests/fixtures/centos-7.7/iostat-x-streaming.json | 1 + tests/fixtures/ubuntu-18.04/iostat-1-streaming.json | 1 + tests/fixtures/ubuntu-18.04/iostat-m-streaming.json | 1 + tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json | 1 + tests/fixtures/ubuntu-18.04/iostat-streaming.json | 1 + tests/fixtures/ubuntu-18.04/iostat-x-streaming.json | 1 + tests/fixtures/ubuntu-20.10/iostat-m-streaming.json | 1 + tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json | 1 + tests/fixtures/ubuntu-20.10/iostat-streaming.json | 1 + tests/fixtures/ubuntu-20.10/iostat-x-streaming.json | 1 + 15 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/centos-7.7/iostat-1-streaming.json create mode 100644 tests/fixtures/centos-7.7/iostat-m-streaming.json create mode 100644 tests/fixtures/centos-7.7/iostat-mx-streaming.json create mode 100644 tests/fixtures/centos-7.7/iostat-streaming.json create mode 100644 tests/fixtures/centos-7.7/iostat-x-streaming.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-1-streaming.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-m-streaming.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-streaming.json create mode 100644 tests/fixtures/ubuntu-18.04/iostat-x-streaming.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-m-streaming.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-streaming.json create mode 100644 tests/fixtures/ubuntu-20.10/iostat-x-streaming.json diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 9fff6a78..288a46e5 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -178,7 +178,7 @@ def parse(data, raw=False, quiet=False, ignore_exceptions=False): jc.utils.streaming_line_input_type_check(line) # ignore blank lines and header line - if line == '\n' or line.startswith('Linux'): + if line == '\n' or line == '' or line.startswith('Linux'): continue if line.startswith('avg-cpu:'): diff --git a/tests/fixtures/centos-7.7/iostat-1-streaming.json b/tests/fixtures/centos-7.7/iostat-1-streaming.json new file mode 100644 index 00000000..38f2c4e8 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-1-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"kb_read_s":5.24,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42533,"type":"device"},{"device":"dm-0","tps":0.25,"kb_read_s":4.39,"kb_wrtn_s":1.04,"kb_read":170325,"kb_wrtn":40464,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.06,"kb_wrtn_s":0.0,"kb_read":2204,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":100.0,"type":"cpu"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":100.0,"type":"cpu"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-m-streaming.json b/tests/fixtures/centos-7.7/iostat-m-streaming.json new file mode 100644 index 00000000..e757dc9e --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-m-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_read":198,"mb_wrtn":41,"type":"device"},{"device":"dm-0","tps":0.25,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":166,"mb_wrtn":39,"type":"device"},{"device":"dm-1","tps":0.0,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":2,"mb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-mx-streaming.json b/tests/fixtures/centos-7.7/iostat-mx-streaming.json new file mode 100644 index 00000000..421a2779 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-mx-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","rrqm_s":0.0,"wrqm_s":0.02,"r_s":0.13,"w_s":0.11,"rmb_s":0.01,"wmb_s":0.0,"avgrq_sz":52.51,"avgqu_sz":0.0,"await":0.88,"r_await":0.53,"w_await":1.29,"svctm":0.52,"percent_util":0.01,"type":"device"},{"device":"dm-0","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.12,"w_s":0.13,"rmb_s":0.0,"wmb_s":0.0,"avgrq_sz":44.28,"avgqu_sz":0.0,"await":0.92,"r_await":0.54,"w_await":1.27,"svctm":0.5,"percent_util":0.01,"type":"device"},{"device":"dm-1","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.0,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"avgrq_sz":50.09,"avgqu_sz":0.0,"await":0.08,"r_await":0.08,"w_await":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-streaming.json b/tests/fixtures/centos-7.7/iostat-streaming.json new file mode 100644 index 00000000..6a971b6c --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","tps":0.24,"kb_read_s":5.28,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42368,"type":"device"},{"device":"dm-0","tps":0.25,"kb_read_s":4.42,"kb_wrtn_s":1.05,"kb_read":170325,"kb_wrtn":40299,"type":"device"},{"device":"dm-1","tps":0.0,"kb_read_s":0.06,"kb_wrtn_s":0.0,"kb_read":2204,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/centos-7.7/iostat-x-streaming.json b/tests/fixtures/centos-7.7/iostat-x-streaming.json new file mode 100644 index 00000000..2d45b2c1 --- /dev/null +++ b/tests/fixtures/centos-7.7/iostat-x-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"},{"device":"sda","rrqm_s":0.0,"wrqm_s":0.02,"r_s":0.13,"w_s":0.11,"rkb_s":5.27,"wkb_s":1.1,"avgrq_sz":52.53,"avgqu_sz":0.0,"await":0.88,"r_await":0.53,"w_await":1.29,"svctm":0.52,"percent_util":0.01,"type":"device"},{"device":"dm-0","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.12,"w_s":0.13,"rkb_s":4.41,"wkb_s":1.05,"avgrq_sz":44.3,"avgqu_sz":0.0,"await":0.92,"r_await":0.54,"w_await":1.27,"svctm":0.5,"percent_util":0.01,"type":"device"},{"device":"dm-1","rrqm_s":0.0,"wrqm_s":0.0,"r_s":0.0,"w_s":0.0,"rkb_s":0.06,"wkb_s":0.0,"avgrq_sz":50.09,"avgqu_sz":0.0,"await":0.08,"r_await":0.08,"w_await":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-1-streaming.json b/tests/fixtures/ubuntu-18.04/iostat-1-streaming.json new file mode 100644 index 00000000..ab42c81a --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-1-streaming.json @@ -0,0 +1 @@ +[{"percent_user":11.66,"percent_nice":3.51,"percent_system":7.44,"percent_iowait":1.33,"percent_steal":0.0,"percent_idle":76.06,"type":"cpu"},{"device":"loop0","tps":0.05,"kb_read_s":0.16,"kb_wrtn_s":0.0,"kb_read":125,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":11.06,"kb_read_s":12.71,"kb_wrtn_s":0.0,"kb_read":10139,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.12,"kb_read_s":1.77,"kb_wrtn_s":0.0,"kb_read":1413,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.07,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":359,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.07,"kb_read_s":1.34,"kb_wrtn_s":0.0,"kb_read":1067,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.13,"kb_read_s":1.49,"kb_wrtn_s":0.0,"kb_read":1190,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.05,"kb_read_s":0.16,"kb_wrtn_s":0.0,"kb_read":125,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.08,"kb_read_s":1.34,"kb_wrtn_s":0.0,"kb_read":1070,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.26,"kb_read_s":1.01,"kb_wrtn_s":0.0,"kb_read":806,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":82.01,"kb_read_s":1901.45,"kb_wrtn_s":3368.25,"kb_read":1517318,"kb_wrtn":2687800,"type":"device"},{"device":"scd0","tps":2.89,"kb_read_s":64.94,"kb_wrtn_s":0.0,"kb_read":51818,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":2.89,"kb_read_s":64.44,"kb_wrtn_s":0.0,"kb_read":51418,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":15.88,"kb_read_s":17.15,"kb_wrtn_s":0.0,"kb_read":13683,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.08,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":362,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.12,"kb_read_s":0.6,"kb_wrtn_s":0.0,"kb_read":476,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.04,"kb_read_s":0.14,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.06,"kb_read_s":0.44,"kb_wrtn_s":0.0,"kb_read":353,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.05,"kb_read_s":0.44,"kb_wrtn_s":0.0,"kb_read":348,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.08,"kb_read_s":0.46,"kb_wrtn_s":0.0,"kb_read":366,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.08,"kb_read_s":0.45,"kb_wrtn_s":0.0,"kb_read":361,"kb_wrtn":0,"type":"device"},{"percent_user":1.01,"percent_nice":0.0,"percent_system":0.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":98.99,"type":"cpu"},{"device":"loop0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"percent_user":0.0,"percent_nice":0.0,"percent_system":1.0,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.0,"type":"cpu"},{"device":"loop0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd0","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_read":0,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-m-streaming.json b/tests/fixtures/ubuntu-18.04/iostat-m-streaming.json new file mode 100644 index 00000000..f51e6da1 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-m-streaming.json @@ -0,0 +1 @@ +[{"percent_user":13.71,"percent_nice":4.14,"percent_system":8.73,"percent_iowait":1.56,"percent_steal":0.0,"percent_idle":71.86,"type":"cpu"},{"device":"loop0","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop1","tps":13.06,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_read":9,"mb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.14,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.08,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.16,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":1,"mb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.3,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"sda","tps":96.73,"mb_read_s":2.19,"mb_wrtn_s":3.88,"mb_read":1481,"mb_wrtn":2624,"type":"device"},{"device":"scd0","tps":3.41,"mb_read_s":0.07,"mb_wrtn_s":0.0,"mb_read":50,"mb_wrtn":0,"type":"device"},{"device":"scd1","tps":3.41,"mb_read_s":0.07,"mb_wrtn_s":0.0,"mb_read":50,"mb_wrtn":0,"type":"device"},{"device":"loop8","tps":18.73,"mb_read_s":0.02,"mb_wrtn_s":0.0,"mb_read":13,"mb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop10","tps":0.15,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.05,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.07,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.06,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.09,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_read":0,"mb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json b/tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json new file mode 100644 index 00000000..25cbcb75 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-mx-streaming.json @@ -0,0 +1 @@ +[{"percent_user":12.13,"percent_nice":3.65,"percent_system":7.74,"percent_iowait":1.38,"percent_steal":0.0,"percent_idle":75.1,"type":"cpu"},{"device":"loop0","r_s":0.05,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":16.9,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.14,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":11.52,"w_s":0.0,"rmb_s":0.01,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":1.15,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.13,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.97,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":14.57,"wareq_sz":0.0,"svctm":0.12,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.07,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":11.04,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.65,"wareq_sz":0.0,"svctm":0.22,"percent_util":0.0,"type":"device"},{"device":"loop4","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":13.83,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":18.08,"wareq_sz":0.0,"svctm":2.24,"percent_util":0.02,"type":"device"},{"device":"loop5","r_s":0.14,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.14,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":11.12,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop6","r_s":0.05,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.14,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.61,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":17.54,"wareq_sz":0.0,"svctm":0.07,"percent_util":0.0,"type":"device"},{"device":"fd0","r_s":0.27,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.43,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.92,"wareq_sz":0.0,"svctm":4.43,"percent_util":0.12,"type":"device"},{"device":"sda","r_s":40.74,"w_s":44.66,"rmb_s":1.93,"wmb_s":3.43,"rrqm_s":3.5,"wrqm_s":96.04,"percent_rrqm":7.9,"percent_wrqm":68.26,"r_await":1.65,"w_await":3.0,"aqu_sz":0.2,"rareq_sz":48.6,"wareq_sz":78.55,"svctm":0.55,"percent_util":4.66,"type":"device"},{"device":"scd0","r_s":3.01,"w_s":0.0,"rmb_s":0.07,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.3,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.48,"wareq_sz":0.0,"svctm":0.29,"percent_util":0.09,"type":"device"},{"device":"scd1","r_s":3.01,"w_s":0.0,"rmb_s":0.07,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.27,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.31,"wareq_sz":0.0,"svctm":0.27,"percent_util":0.08,"type":"device"},{"device":"loop8","r_s":16.54,"w_s":0.0,"rmb_s":0.02,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.83,"w_await":0.0,"aqu_sz":0.01,"rareq_sz":1.08,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.06,"type":"device"},{"device":"loop9","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.03,"wareq_sz":0.0,"svctm":0.6,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.13,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.51,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.81,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.0,"type":"device"},{"device":"loop11","r_s":0.04,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop12","r_s":0.06,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.25,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":7.36,"wareq_sz":0.0,"svctm":0.42,"percent_util":0.0,"type":"device"},{"device":"loop13","r_s":0.06,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":5.02,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":8.1,"wareq_sz":0.0,"svctm":0.09,"percent_util":0.0,"type":"device"},{"device":"loop14","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.0,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop15","r_s":0.08,"w_s":0.0,"rmb_s":0.0,"wmb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.06,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":5.82,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-streaming.json b/tests/fixtures/ubuntu-18.04/iostat-streaming.json new file mode 100644 index 00000000..8ae487b8 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-streaming.json @@ -0,0 +1 @@ +[{"percent_user":28.59,"percent_nice":11.11,"percent_system":33.13,"percent_iowait":1.52,"percent_steal":0.0,"percent_idle":25.66,"type":"cpu"},{"device":"loop0","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop1","tps":94.34,"kb_read_s":108.57,"kb_wrtn_s":0.0,"kb_read":9923,"kb_wrtn":0,"type":"device"},{"device":"loop2","tps":0.98,"kb_read_s":15.27,"kb_wrtn_s":0.0,"kb_read":1396,"kb_wrtn":0,"type":"device"},{"device":"loop3","tps":0.5,"kb_read_s":3.73,"kb_wrtn_s":0.0,"kb_read":341,"kb_wrtn":0,"type":"device"},{"device":"loop4","tps":0.57,"kb_read_s":11.6,"kb_wrtn_s":0.0,"kb_read":1060,"kb_wrtn":0,"type":"device"},{"device":"loop5","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop6","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop7","tps":0.58,"kb_read_s":11.51,"kb_wrtn_s":0.0,"kb_read":1052,"kb_wrtn":0,"type":"device"},{"device":"fd0","tps":0.97,"kb_read_s":3.89,"kb_wrtn_s":0.0,"kb_read":356,"kb_wrtn":0,"type":"device"},{"device":"sda","tps":179.87,"kb_read_s":7918.74,"kb_wrtn_s":9915.54,"kb_read":723773,"kb_wrtn":906280,"type":"device"},{"device":"scd0","tps":11.58,"kb_read_s":260.7,"kb_wrtn_s":0.0,"kb_read":23828,"kb_wrtn":0,"type":"device"},{"device":"scd1","tps":11.58,"kb_read_s":258.69,"kb_wrtn_s":0.0,"kb_read":23644,"kb_wrtn":0,"type":"device"},{"device":"loop8","tps":138.52,"kb_read_s":149.51,"kb_wrtn_s":0.0,"kb_read":13665,"kb_wrtn":0,"type":"device"},{"device":"loop9","tps":0.57,"kb_read_s":3.76,"kb_wrtn_s":0.0,"kb_read":344,"kb_wrtn":0,"type":"device"},{"device":"loop10","tps":1.01,"kb_read_s":5.02,"kb_wrtn_s":0.0,"kb_read":459,"kb_wrtn":0,"type":"device"},{"device":"loop11","tps":0.36,"kb_read_s":1.18,"kb_wrtn_s":0.0,"kb_read":108,"kb_wrtn":0,"type":"device"},{"device":"loop12","tps":0.45,"kb_read_s":3.68,"kb_wrtn_s":0.0,"kb_read":336,"kb_wrtn":0,"type":"device"},{"device":"loop13","tps":0.39,"kb_read_s":3.62,"kb_wrtn_s":0.0,"kb_read":331,"kb_wrtn":0,"type":"device"},{"device":"loop14","tps":0.58,"kb_read_s":3.81,"kb_wrtn_s":0.0,"kb_read":348,"kb_wrtn":0,"type":"device"},{"device":"loop15","tps":0.59,"kb_read_s":3.75,"kb_wrtn_s":0.0,"kb_read":343,"kb_wrtn":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-18.04/iostat-x-streaming.json b/tests/fixtures/ubuntu-18.04/iostat-x-streaming.json new file mode 100644 index 00000000..6af9685f --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/iostat-x-streaming.json @@ -0,0 +1 @@ +[{"percent_user":39.64,"percent_nice":12.36,"percent_system":28.21,"percent_iowait":2.28,"percent_steal":0.0,"percent_idle":17.51,"type":"cpu"},{"device":"loop0","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":20.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":63.02,"w_s":0.0,"rkb_s":72.52,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.12,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":1.15,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.01,"type":"device"},{"device":"loop2","r_s":0.66,"w_s":0.0,"rkb_s":10.2,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":7.42,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":15.51,"wareq_sz":0.0,"svctm":0.13,"percent_util":0.01,"type":"device"},{"device":"loop3","r_s":0.34,"w_s":0.0,"rkb_s":2.49,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":12.87,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":7.41,"wareq_sz":0.0,"svctm":0.26,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.43,"w_s":0.0,"rkb_s":7.8,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":13.83,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":18.08,"wareq_sz":0.0,"svctm":2.24,"percent_util":0.1,"type":"device"},{"device":"loop5","r_s":0.72,"w_s":0.0,"rkb_s":8.56,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.39,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":11.84,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop6","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":3.64,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.39,"w_s":0.0,"rkb_s":7.69,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.08,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":19.85,"wareq_sz":0.0,"svctm":0.08,"percent_util":0.0,"type":"device"},{"device":"fd0","r_s":1.21,"w_s":0.0,"rkb_s":4.82,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.59,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.0,"wareq_sz":0.0,"svctm":2.59,"percent_util":0.31,"type":"device"},{"device":"sda","r_s":127.92,"w_s":67.15,"rkb_s":8595.16,"wkb_s":12457.33,"rrqm_s":15.79,"wrqm_s":142.95,"percent_rrqm":10.99,"percent_wrqm":68.04,"r_await":2.57,"w_await":6.93,"aqu_sz":0.79,"rareq_sz":67.19,"wareq_sz":185.52,"svctm":0.78,"percent_util":15.14,"type":"device"},{"device":"scd0","r_s":14.11,"w_s":0.0,"rkb_s":317.88,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.34,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.52,"wareq_sz":0.0,"svctm":0.34,"percent_util":0.47,"type":"device"},{"device":"scd1","r_s":14.11,"w_s":0.0,"rkb_s":315.43,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.31,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":22.35,"wareq_sz":0.0,"svctm":0.31,"percent_util":0.43,"type":"device"},{"device":"loop8","r_s":92.5,"w_s":0.0,"rkb_s":99.83,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.83,"w_await":0.0,"aqu_sz":0.07,"rareq_sz":1.08,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.36,"type":"device"},{"device":"loop9","r_s":0.38,"w_s":0.0,"rkb_s":2.51,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":7.54,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.62,"wareq_sz":0.0,"svctm":0.69,"percent_util":0.03,"type":"device"},{"device":"loop10","r_s":0.67,"w_s":0.0,"rkb_s":3.35,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":2.61,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":4.99,"wareq_sz":0.0,"svctm":0.04,"percent_util":0.0,"type":"device"},{"device":"loop11","r_s":0.24,"w_s":0.0,"rkb_s":0.79,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":6.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":3.27,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop12","r_s":0.3,"w_s":0.0,"rkb_s":2.45,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":4.98,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":8.2,"wareq_sz":0.0,"svctm":0.49,"percent_util":0.01,"type":"device"},{"device":"loop13","r_s":0.26,"w_s":0.0,"rkb_s":2.42,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":5.67,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":9.19,"wareq_sz":0.0,"svctm":0.11,"percent_util":0.0,"type":"device"},{"device":"loop14","r_s":0.39,"w_s":0.0,"rkb_s":2.54,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.57,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"},{"device":"loop15","r_s":0.39,"w_s":0.0,"rkb_s":2.51,"wkb_s":0.0,"rrqm_s":0.0,"wrqm_s":0.0,"percent_rrqm":0.0,"percent_wrqm":0.0,"r_await":0.0,"w_await":0.0,"aqu_sz":0.0,"rareq_sz":6.35,"wareq_sz":0.0,"svctm":0.0,"percent_util":0.0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-m-streaming.json b/tests/fixtures/ubuntu-20.10/iostat-m-streaming.json new file mode 100644 index 00000000..4a979a69 --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-m-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.39,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.1,"type":"cpu"},{"device":"dm-0","tps":9.5,"mb_read_s":0.1,"mb_wrtn_s":0.13,"mb_dscd_s":0.0,"mb_read":517,"mb_wrtn":678,"mb_dscd":0,"type":"device"},{"device":"loop0","tps":0.02,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop1","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop10","tps":0.0,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop2","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop3","tps":0.04,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":2,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop4","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":1,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop5","tps":0.1,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":17,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop6","tps":0.01,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop7","tps":0.12,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":22,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop8","tps":0.02,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":0,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"loop9","tps":0.04,"mb_read_s":0.0,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":2,"mb_wrtn":0,"mb_dscd":0,"type":"device"},{"device":"sda","tps":5.45,"mb_read_s":0.1,"mb_wrtn_s":0.13,"mb_dscd_s":0.0,"mb_read":528,"mb_wrtn":679,"mb_dscd":0,"type":"device"},{"device":"sr0","tps":0.19,"mb_read_s":0.01,"mb_wrtn_s":0.0,"mb_dscd_s":0.0,"mb_read":36,"mb_wrtn":0,"mb_dscd":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json b/tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json new file mode 100644 index 00000000..05ccb2ab --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-mx-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.38,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.1,"type":"cpu"},{"device":"dm-0","r_s":2.35,"rmb_s":0.1,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.55,"rareq_sz":41.48,"w_s":7.13,"wmb_s":0.13,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.4,"wareq_sz":17.98,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.34,"type":"device"},{"device":"loop0","r_s":0.02,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.14,"rareq_sz":12.41,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.4,"rareq_sz":7.48,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.0,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":1.5,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.32,"rareq_sz":19.21,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.04,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.42,"rareq_sz":10.42,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.34,"rareq_sz":17.14,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop5","r_s":0.1,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.37,"rareq_sz":33.41,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop6","r_s":0.01,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.46,"rareq_sz":7.5,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.12,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.12,"rareq_sz":34.54,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop8","r_s":0.02,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":8.46,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop9","r_s":0.04,"rmb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.06,"rareq_sz":9.98,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"sda","r_s":2.65,"rmb_s":0.1,"rrqm_s":0.65,"percent_rrqm":19.71,"r_await":0.36,"rareq_sz":37.62,"w_s":2.8,"wmb_s":0.13,"wrqm_s":4.38,"percent_wrqm":61.04,"w_await":0.42,"wareq_sz":45.83,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.41,"type":"device"},{"device":"sr0","r_s":0.18,"rmb_s":0.01,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.24,"rareq_sz":37.55,"w_s":0.0,"wmb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dmb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-streaming.json b/tests/fixtures/ubuntu-20.10/iostat-streaming.json new file mode 100644 index 00000000..3823a9ed --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.4,"percent_nice":0.04,"percent_system":0.45,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.07,"type":"cpu"},{"device":"dm-0","tps":9.78,"kb_read_s":101.69,"kb_wrtn_s":133.03,"kb_dscd_s":0.0,"kb_read":530217,"kb_wrtn":693624,"kb_dscd":0,"type":"device"},{"device":"loop0","tps":0.02,"kb_read_s":0.28,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1464,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop1","tps":0.01,"kb_read_s":0.07,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":359,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop10","tps":0.0,"kb_read_s":0.0,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":18,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop2","tps":0.01,"kb_read_s":0.21,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1095,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop3","tps":0.04,"kb_read_s":0.41,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":2137,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop4","tps":0.01,"kb_read_s":0.21,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":1114,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop5","tps":0.1,"kb_read_s":3.39,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":17673,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop6","tps":0.01,"kb_read_s":0.07,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":360,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop7","tps":0.13,"kb_read_s":4.43,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":23074,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop8","tps":0.02,"kb_read_s":0.13,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":694,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"loop9","tps":0.04,"kb_read_s":0.42,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":2195,"kb_wrtn":0,"kb_dscd":0,"type":"device"},{"device":"sda","tps":5.58,"kb_read_s":103.76,"kb_wrtn_s":133.05,"kb_dscd_s":0.0,"kb_read":541026,"kb_wrtn":693732,"kb_dscd":0,"type":"device"},{"device":"sr0","tps":0.19,"kb_read_s":7.22,"kb_wrtn_s":0.0,"kb_dscd_s":0.0,"kb_read":37658,"kb_wrtn":0,"kb_dscd":0,"type":"device"}] diff --git a/tests/fixtures/ubuntu-20.10/iostat-x-streaming.json b/tests/fixtures/ubuntu-20.10/iostat-x-streaming.json new file mode 100644 index 00000000..140c99ff --- /dev/null +++ b/tests/fixtures/ubuntu-20.10/iostat-x-streaming.json @@ -0,0 +1 @@ +[{"percent_user":0.39,"percent_nice":0.04,"percent_system":0.44,"percent_iowait":0.04,"percent_steal":0.0,"percent_idle":99.09,"type":"cpu"},{"device":"dm-0","r_s":2.38,"rkb_s":98.75,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.55,"rareq_sz":41.48,"w_s":7.18,"wkb_s":129.42,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.4,"wareq_sz":18.04,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.34,"type":"device"},{"device":"loop0","r_s":0.02,"rkb_s":0.27,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.14,"rareq_sz":12.41,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop1","r_s":0.01,"rkb_s":0.07,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.4,"rareq_sz":7.48,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop10","r_s":0.0,"rkb_s":0.0,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":1.5,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop2","r_s":0.01,"rkb_s":0.2,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.32,"rareq_sz":19.21,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop3","r_s":0.04,"rkb_s":0.4,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.42,"rareq_sz":10.42,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"},{"device":"loop4","r_s":0.01,"rkb_s":0.21,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.34,"rareq_sz":17.14,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop5","r_s":0.1,"rkb_s":3.29,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.37,"rareq_sz":33.41,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop6","r_s":0.01,"rkb_s":0.07,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.46,"rareq_sz":7.5,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop7","r_s":0.12,"rkb_s":4.3,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.12,"rareq_sz":34.54,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.03,"type":"device"},{"device":"loop8","r_s":0.02,"rkb_s":0.13,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.0,"rareq_sz":8.46,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"loop9","r_s":0.04,"rkb_s":0.41,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.06,"rareq_sz":9.98,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.0,"type":"device"},{"device":"sda","r_s":2.67,"rkb_s":100.76,"rrqm_s":0.66,"percent_rrqm":19.76,"r_await":0.36,"rareq_sz":37.75,"w_s":2.81,"wkb_s":129.44,"wrqm_s":4.42,"percent_wrqm":61.15,"w_await":0.42,"wareq_sz":46.11,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.41,"type":"device"},{"device":"sr0","r_s":0.19,"rkb_s":7.01,"rrqm_s":0.0,"percent_rrqm":0.0,"r_await":0.24,"rareq_sz":37.55,"w_s":0.0,"wkb_s":0.0,"wrqm_s":0.0,"percent_wrqm":0.0,"w_await":0.0,"wareq_sz":0.0,"d_s":0.0,"dkb_s":0.0,"drqm_s":0.0,"percent_drqm":0.0,"d_await":0.0,"dareq_sz":0.0,"f_s":0.0,"f_await":0.0,"aqu_sz":0.0,"percent_util":0.01,"type":"device"}] From dbd134d0dac2fc152183480958fd9e65919ac98d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 11:40:47 -0800 Subject: [PATCH 31/33] add examples to docs --- jc/parsers/iostat_s.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jc/parsers/iostat_s.py b/jc/parsers/iostat_s.py index 288a46e5..7a0e9203 100644 --- a/jc/parsers/iostat_s.py +++ b/jc/parsers/iostat_s.py @@ -79,11 +79,13 @@ Schema: Examples: $ iostat | jc --iostat-s - {example output} + {"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"} + {"device":"sda","tps":0.24,"kb_read_s":5.28,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42368,"type":"device"} ... $ iostat | jc --iostat-s -r - {example output} + {"percent_user":"0.14","percent_nice":"0.00","percent_system":"0.16","percent_iowait":"0.00","percent_steal":"0.00","percent_idle":"99.70","type":"cpu"} + {"device":"sda","tps":"0.24","kb_read_s":"5.28","kb_wrtn_s":"1.10","kb_read":"203305","kb_wrtn":"42368","type":"device"} ... """ import jc.utils From a26a298f1a3c141171e7d7ce459a27a297cec031 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 11:42:56 -0800 Subject: [PATCH 32/33] doc update --- README.md | 1 + docs/parsers/iostat.md | 15 +++++ docs/parsers/iostat_s.md | 126 +++++++++++++++++++++++++++++++++++++++ man/jc.1 | 7 ++- 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 docs/parsers/iostat_s.md diff --git a/README.md b/README.md index 0fa3f6fe..3dc2b22f 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--ifconfig` enables the `ifconfig` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ifconfig)) - `--ini` enables the INI file parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ini)) - `--iostat` enables the `iostat` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat)) +- `--iostat-s` enables the `iostat` command streaming parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iostat_s)) - `--iptables` enables the `iptables` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iptables)) - `--iw-scan` enables the `iw dev [device] scan` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/iw_scan)) - `--jobs` enables the `jobs` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/jobs)) diff --git a/docs/parsers/iostat.md b/docs/parsers/iostat.md index 2903f963..6d9417ed 100644 --- a/docs/parsers/iostat.md +++ b/docs/parsers/iostat.md @@ -3,6 +3,8 @@ # jc.parsers.iostat jc - JSON CLI output utility `iostat` command output parser +Note: `iostat` version 11 and higher include a JSON output option + Usage (cli): $ iostat | jc --iostat @@ -37,6 +39,8 @@ Schema: "mb_read": integer, "kb_wrtn": integer, "mb_wrtn": integer, + 'kb_dscd': integer, + 'mb_dscd': integer, "rrqm_s": float, "wrqm_s": float, "r_s": float, @@ -54,6 +58,17 @@ Schema: "aqu_sz": float, "rareq_sz": float, "wareq_sz": float, + "d_s": float, + "dkb_s": float, + "dmb_s": float, + "drqm_s": float, + "percent_drqm": float, + "d_await": float, + "dareq_sz": float, + "f_s": float, + "f_await": float, + "kb_dscd_s": float, + "mb_dscd_s": float, "percent_util": float, "percent_rrqm": float, "percent_wrqm": float diff --git a/docs/parsers/iostat_s.md b/docs/parsers/iostat_s.md new file mode 100644 index 00000000..6f3ad819 --- /dev/null +++ b/docs/parsers/iostat_s.md @@ -0,0 +1,126 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.iostat_s +jc - JSON CLI output utility `iostat` command output streaming parser + +> This streaming parser outputs JSON Lines + +Note: `iostat` version 11 and higher include a JSON output option + +Usage (cli): + + $ iostat | jc --iostat-s + +Usage (module): + + import jc.parsers.iostat_s + result = jc.parsers.iostat_s.parse(iostat_command_output.splitlines()) # result is an iterable object + for item in result: + # do something + +Schema: + + { + "type": string, + "percent_user": float, + "percent_nice": float, + "percent_system": float, + "percent_iowait": float, + "percent_steal": float, + "percent_idle": float, + "device": string, + "tps": float, + "kb_read_s": float, + "mb_read_s": float, + "kb_wrtn_s": float, + "mb_wrtn_s": float, + "kb_read": integer, + "mb_read": integer, + "kb_wrtn": integer, + "mb_wrtn": integer, + 'kb_dscd': integer, + 'mb_dscd': integer, + "rrqm_s": float, + "wrqm_s": float, + "r_s": float, + "w_s": float, + "rmb_s": float, + "rkb_s": float, + "wmb_s": float, + "wkb_s": float, + "avgrq_sz": float, + "avgqu_sz": float, + "await": float, + "r_await": float, + "w_await": float, + "svctm": float, + "aqu_sz": float, + "rareq_sz": float, + "wareq_sz": float, + "d_s": float, + "dkb_s": float, + "dmb_s": float, + "drqm_s": float, + "percent_drqm": float, + "d_await": float, + "dareq_sz": float, + "f_s": float, + "f_await": float, + "kb_dscd_s": float, + "mb_dscd_s": float, + "percent_util": float, + "percent_rrqm": float, + "percent_wrqm": float, + "_jc_meta": # This object only exists if using -qq or ignore_exceptions=True + { + "success": booean, # true if successfully parsed, false if error + "error": string, # exists if "success" is false + "line": string # exists if "success" is false + } + } + +Examples: + + $ iostat | jc --iostat-s + {"percent_user":0.14,"percent_nice":0.0,"percent_system":0.16,"percent_iowait":0.0,"percent_steal":0.0,"percent_idle":99.7,"type":"cpu"} + {"device":"sda","tps":0.24,"kb_read_s":5.28,"kb_wrtn_s":1.1,"kb_read":203305,"kb_wrtn":42368,"type":"device"} + ... + + $ iostat | jc --iostat-s -r + {"percent_user":"0.14","percent_nice":"0.00","percent_system":"0.16","percent_iowait":"0.00","percent_steal":"0.00","percent_idle":"99.70","type":"cpu"} + {"device":"sda","tps":"0.24","kb_read_s":"5.28","kb_wrtn_s":"1.10","kb_read":"203305","kb_wrtn":"42368","type":"device"} + ... + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False, ignore_exceptions=False) +``` + +Main text parsing generator function. Returns an iterator object. + +Parameters: + + data: (iterable) line-based text data to parse (e.g. sys.stdin or str.splitlines()) + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + ignore_exceptions: (boolean) ignore parsing exceptions if True + +Yields: + + Dictionary. Raw or processed structured data. + +Returns: + + Iterator object + +## Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/man/jc.1 b/man/jc.1 index 8c94ca35..4c990e69 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -1,4 +1,4 @@ -.TH jc 1 2021-12-01 1.17.3 "JSON CLI output utility" +.TH jc 1 2021-12-02 1.17.3 "JSON CLI output utility" .SH NAME jc \- JSONifies the output of many CLI tools and file-types .SH SYNOPSIS @@ -182,6 +182,11 @@ INI file parser \fB--iostat\fP `iostat` command parser +.TP +.B +\fB--iostat-s\fP +`iostat` command streaming parser + .TP .B \fB--iptables\fP From f7cb5f7d01ac01538bee4da816408072b585768e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 2 Dec 2021 16:30:47 -0800 Subject: [PATCH 33/33] update date --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 613b0ec2..384693cf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ jc changelog -20211201 v1.17.3 +20211202 v1.17.3 - Update parsers to exit with error if non-string input is detected (raise TypeError) - Update streaming parsers to exit with error if non-iterable input is detected (raise TypeError) - Simplify quiet-checking in parsers