From 586bc7513250594de9d1aa36348a121239a7be57 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran Date: Thu, 10 Dec 2020 14:15:22 +0530 Subject: [PATCH] - Add '-d/--device' option for displaying AER stats of specified device - Include UT cases for device, no-zero options --- pcieutil/main.py | 211 +++++++++++------------ tests/mock_tables/state_db.json | 53 +++++- tests/pcieutil_test.py | 285 +++++++++++++++++++------------- 3 files changed, 328 insertions(+), 221 deletions(-) diff --git a/pcieutil/main.py b/pcieutil/main.py index 1f004a64fe..882487adac 100644 --- a/pcieutil/main.py +++ b/pcieutil/main.py @@ -7,6 +7,7 @@ try: import os + import re import sys from collections import OrderedDict @@ -108,162 +109,162 @@ def pcie_show(): Id = item["id"] click.echo("bus:dev.fn %s:%s.%s - dev_id=0x%s, %s" % (Bus, Dev, Fn, Id, Name)) -# Show PCIe AER status +# PCIe AER stats helpers -@cli.group(cls=clicommon.AliasedGroup) -def pcie_aer(): - '''Display PCIe AER status''' - pass +aer_fields = { + "correctable": ['RxErr', 'BadTLP', 'BadDLLP', 'Rollover', 'Timeout', 'NonFatalErr', 'CorrIntErr', 'HeaderOF', 'TOTAL_ERR_COR'], + "fatal": ['Undefined', 'DLP', 'SDES', 'TLP', 'FCP', 'CmpltTO', 'CmpltAbrt', 'UnxCmplt', 'RxOF', 'MalfTLP', 'ECRC', 'UnsupReq', + 'ACSViol', 'UncorrIntErr', 'BlockedTLP', 'AtomicOpBlocked', 'TLPBlockedErr', 'TOTAL_ERR_FATAL'], + "non_fatal": ['Undefined', 'DLP', 'SDES', 'TLP', 'FCP', 'CmpltTO', 'CmpltAbrt', 'UnxCmplt', 'RxOF', 'MalfTLP', 'ECRC', 'UnsupReq', + 'ACSViol', 'UncorrIntErr', 'BlockedTLP', 'AtomicOpBlocked', 'TLPBlockedErr', 'TOTAL_ERR_NONFATAL'] +} -@pcie_aer.command() -@click.option('-nz', '--no-zero', is_flag=True) -def correctable(no_zero): - '''Show PCIe AER correctable attributes''' +class PcieDevice(click.ParamType): + name = ":." - statedb = SonicV2Connector() - statedb.connect(statedb.STATE_DB) - header = ['AER - CORRECTABLE'] + def convert(self, value, param, ctx): + match = re.match(r'([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2})\.([0-9A-Fa-f])', value) - # AER - Correctable fields (9) - fields = ['RxErr', 'BadTLP', 'BadDLLP', 'Rollover', 'Timeout', 'NonFatalErr', 'CorrIntErr', 'HeaderOF', 'TOTAL_ERR_COR'] - table = OrderedDict() - for field in fields: - table[field] = [field] + if not match: + self.fail('{} is not in :. format'.format(value), param, ctx) - resultInfo = platform_pcieutil.get_pcie_check() - for item in resultInfo: - if item["result"] == "Failed": - continue + Bus, Dev, Fn = [int(val, 16) for val in match.groups()] + if Bus > 255: + self.fail('Invalid Bus number', param, ctx) - Bus = item["bus"] - Dev = item["dev"] - Fn = item["fn"] - Id = item["id"] + if Dev > 31: + self.fail('Invalid Dev number', param, ctx) - pcie_dev_key = "PCIE_DEVICE|0x%s|%s:%s.%s" % (Id, Bus, Dev, Fn) - aer_attribute = statedb.get_all(statedb.STATE_DB, pcie_dev_key) - if not aer_attribute: - continue + if Fn > 7: + self.fail('Invalid Fn number', param, ctx) - if no_zero and all(val=='0' for key, val in aer_attribute.items() if key.startswith('correctable')): - continue + return "%02x:%02x.%d" % (Bus, Dev, Fn) - # Tabulate Header - device_name = "%s:%s.%s\n0x%s" % (Bus, Dev, Fn, Id) - header.append(device_name) - # Tabulate Row - for field in fields: - key = "correctable|" + field - table[field].append(aer_attribute.get(key, 'NA')) +_pcie_aer_click_options = [ + click.option('-d', '--device', 'device_key', + type=PcieDevice(), + help="Display stats only for the specified device"), + click.option('-nz', '--no-zero', + is_flag=True, + help="Display non-zero AER stats") +] - click.echo(tabulate(list(table.values()), header, tablefmt="grid")) +def pcie_aer_click_options(func): + for option in reversed(_pcie_aer_click_options): + func = option(func) + return func + + +def pcie_aer_display(ctx, severity): + device_key = ctx.params['device_key'] + no_zero = ctx.params['no_zero'] + header = ["AER - " + severity.upper().replace("_", "")] + fields = aer_fields[severity] + pcie_dev_list = list() + dev_found = False -@pcie_aer.command() -@click.option('-nz', '--no-zero', is_flag=True) -def fatal(no_zero): - '''Show PCIe AER fatal attributes''' statedb = SonicV2Connector() statedb.connect(statedb.STATE_DB) - header = ['AER - FATAL'] - # AER - Fatal fields (18) - fields = ['Undefined', 'DLP', 'SDES', 'TLP', 'FCP', 'CmpltTO', 'CmpltAbrt', 'UnxCmplt', 'RxOF', 'MalfTLP', 'ECRC', 'UnsupReq', 'ACSViol', 'UncorrIntErr', 'BlockedTLP', 'AtomicOpBlocked', 'TLPBlockedErr', 'TOTAL_ERR_FATAL'] table = OrderedDict() for field in fields: table[field] = [field] - resultInfo = platform_pcieutil.get_pcie_check() - for item in resultInfo: - if item["result"] == "Failed": - continue - - Bus = item["bus"] - Dev = item["dev"] - Fn = item["fn"] - Id = item["id"] + if device_key: + pcie_dev_list = ["PCIE_DEVICE|%s" % device_key] + else: + keys = statedb.keys(statedb.STATE_DB, "PCIE_DEVICE|*") + if keys: + pcie_dev_list = sorted(keys) - pcie_dev_key = "PCIE_DEVICE|0x%s|%s:%s.%s" % (Id, Bus, Dev, Fn) + for pcie_dev_key in pcie_dev_list: aer_attribute = statedb.get_all(statedb.STATE_DB, pcie_dev_key) if not aer_attribute: continue - if no_zero and all(val=='0' for key, val in aer_attribute.items() if key.startswith('fatal')): + if device_key: + dev_found = True + + if no_zero and all(val == '0' for key, val in aer_attribute.items() if key.startswith(severity)): continue + pcie_dev = pcie_dev_key.split("|")[1] + Id = aer_attribute['id'] + # Tabulate Header - device_name = "%s:%s.%s\n0x%s" % (Bus, Dev, Fn, Id) + device_name = "%s\n%s" % (pcie_dev, Id) header.append(device_name) # Tabulate Row for field in fields: - key = "fatal|" + field + key = severity + "|" + field table[field].append(aer_attribute.get(key, 'NA')) - click.echo(tabulate(list(table.values()), header, tablefmt="grid")) + if device_key and not dev_found: + ctx.exit("Device not found in DB") + # Strip fields with no non-zero value + if no_zero: + for field in fields: + if all(val == '0' for val in table[field][1:]): + del table[field] -@pcie_aer.command() -@click.option('-nz', '--no-zero', is_flag=True) -def non_fatal(no_zero): - '''Show PCIe AER non-fatal attributes ''' - statedb = SonicV2Connector() - statedb.connect(statedb.STATE_DB) - aer_attribute = {} - header = ['AER - NONFATAL'] + if not (no_zero and (len(header) == 1)): + if ctx.obj: + click.echo("") - # AER - Non-Fatal fields (18) - fields = ['Undefined', 'DLP', 'SDES', 'TLP', 'FCP', 'CmpltTO', 'CmpltAbrt', 'UnxCmplt', 'RxOF', 'MalfTLP', 'ECRC', 'UnsupReq', 'ACSViol', 'UncorrIntErr', 'BlockedTLP', 'AtomicOpBlocked', 'TLPBlockedErr', 'TOTAL_ERR_NONFATAL'] - table = OrderedDict() - for field in fields: - table[field] = [field] + click.echo(tabulate(list(table.values()), header, tablefmt="grid")) + ctx.obj = True + else: + ctx.obj = False - resultInfo = platform_pcieutil.get_pcie_check() - for item in resultInfo: - if item["result"] == "Failed": - continue - Bus = item["bus"] - Dev = item["dev"] - Fn = item["fn"] - Id = item["id"] +# Show PCIe AER status +@cli.group(cls=clicommon.AliasedGroup) +@click.pass_context +def pcie_aer(ctx): + '''Display PCIe AER status''' + # Set True to insert a line between severities in 'all' context + ctx.obj = False + pass - pcie_dev_key = "PCIE_DEVICE|0x%s|%s:%s.%s" % (Id, Bus, Dev, Fn) - aer_attribute = statedb.get_all(statedb.STATE_DB, pcie_dev_key) - if not aer_attribute: - continue - if no_zero and all(val=='0' for key, val in aer_attribute.items() if key.startswith('non_fatal')): - continue +@pcie_aer.command() +@pcie_aer_click_options +@click.pass_context +def correctable(ctx, no_zero, device_key): + '''Show PCIe AER correctable attributes''' + pcie_aer_display(ctx, "correctable") - # Tabulate Header - device_name = "%s:%s.%s\n0x%s" % (Bus, Dev, Fn, Id) - header.append(device_name) - # Tabulate Row - for field in fields: - key = "non_fatal|" + field - table[field].append(aer_attribute.get(key, 'NA')) +@pcie_aer.command() +@pcie_aer_click_options +@click.pass_context +def fatal(ctx, no_zero, device_key): + '''Show PCIe AER fatal attributes''' + pcie_aer_display(ctx, "fatal") + - click.echo(tabulate(list(table.values()), header, tablefmt="grid")) +@pcie_aer.command() +@pcie_aer_click_options +@click.pass_context +def non_fatal(ctx, no_zero, device_key): + '''Show PCIe AER non-fatal attributes ''' + pcie_aer_display(ctx, "non_fatal") @pcie_aer.command(name='all') -@click.option('-nz', '--no-zero', is_flag=True) +@pcie_aer_click_options @click.pass_context -def all_errors(ctx, no_zero): +def all_errors(ctx, no_zero, device_key): '''Show all PCIe AER attributes ''' - ctx.forward(correctable) - click.echo("") - - ctx.forward(fatal) - click.echo("") - - ctx.forward(non_fatal) - click.echo("") + pcie_aer_display(ctx, "correctable") + pcie_aer_display(ctx, "fatal") + pcie_aer_display(ctx, "non_fatal") # Show PCIE Vender ID and Device ID diff --git a/tests/mock_tables/state_db.json b/tests/mock_tables/state_db.json index 4c302621ee..6729f7c93b 100644 --- a/tests/mock_tables/state_db.json +++ b/tests/mock_tables/state_db.json @@ -328,15 +328,17 @@ "MUX_CABLE_TABLE|Ethernet12": { "state": "unknown" }, - "PCIE_DEVICE|0x0001|00:01.0": { + "PCIE_DEVICE|00:01.0": { "correctable|BadDLLP": "0", "correctable|BadTLP": "0", + "correctable|BadTLP": "1", "correctable|CorrIntErr": "0", "correctable|HeaderOF": "0", "correctable|NonFatalErr": "0", "correctable|Rollover": "0", "correctable|RxErr": "0", "correctable|TOTAL_ERR_COR": "0", + "correctable|TOTAL_ERR_COR": "1", "correctable|Timeout": "0", "fatal|ACSViol": "0", "fatal|AtomicOpBlocked": "0", @@ -356,6 +358,55 @@ "fatal|Undefined": "0", "fatal|UnsupReq": "0", "fatal|UnxCmplt": "0", + "id": "0x0001", + "non_fatal|ACSViol": "0", + "non_fatal|AtomicOpBlocked": "0", + "non_fatal|BlockedTLP": "0", + "non_fatal|CmpltAbrt": "0", + "non_fatal|CmpltTO": "0", + "non_fatal|DLP": "0", + "non_fatal|ECRC": "0", + "non_fatal|FCP": "0", + "non_fatal|MalfTLP": "1", + "non_fatal|RxOF": "0", + "non_fatal|SDES": "0", + "non_fatal|TLP": "0", + "non_fatal|TLPBlockedErr": "0", + "non_fatal|TOTAL_ERR_NONFATAL": "1", + "non_fatal|UncorrIntErr": "0", + "non_fatal|Undefined": "0", + "non_fatal|UnsupReq": "0", + "non_fatal|UnxCmplt": "0" + }, + "PCIE_DEVICE|01:00.0": { + "correctable|BadDLLP": "0", + "correctable|BadTLP": "0", + "correctable|CorrIntErr": "0", + "correctable|HeaderOF": "0", + "correctable|NonFatalErr": "0", + "correctable|Rollover": "0", + "correctable|RxErr": "1", + "correctable|TOTAL_ERR_COR": "1", + "correctable|Timeout": "0", + "fatal|ACSViol": "0", + "fatal|AtomicOpBlocked": "0", + "fatal|BlockedTLP": "0", + "fatal|CmpltAbrt": "0", + "fatal|CmpltTO": "0", + "fatal|DLP": "0", + "fatal|ECRC": "0", + "fatal|FCP": "0", + "fatal|MalfTLP": "0", + "fatal|RxOF": "0", + "fatal|SDES": "0", + "fatal|TLP": "0", + "fatal|TLPBlockedErr": "0", + "fatal|TOTAL_ERR_FATAL": "0", + "fatal|UncorrIntErr": "0", + "fatal|Undefined": "0", + "fatal|UnsupReq": "0", + "fatal|UnxCmplt": "0", + "id": "0x0002", "non_fatal|ACSViol": "0", "non_fatal|AtomicOpBlocked": "0", "non_fatal|BlockedTLP": "0", diff --git a/tests/pcieutil_test.py b/tests/pcieutil_test.py index 63401a0473..6b777fdd5e 100644 --- a/tests/pcieutil_test.py +++ b/tests/pcieutil_test.py @@ -11,13 +11,148 @@ import pcieutil.main as pcieutil pcieutil_pcie_aer_correctable_output = """\ ++---------------------+-----------+-----------+ +| AER - CORRECTABLE | 00:01.0 | 01:00.0 | +| | 0x0001 | 0x0002 | ++=====================+===========+===========+ +| RxErr | 0 | 1 | ++---------------------+-----------+-----------+ +| BadTLP | 1 | 0 | ++---------------------+-----------+-----------+ +| BadDLLP | 0 | 0 | ++---------------------+-----------+-----------+ +| Rollover | 0 | 0 | ++---------------------+-----------+-----------+ +| Timeout | 0 | 0 | ++---------------------+-----------+-----------+ +| NonFatalErr | 0 | 0 | ++---------------------+-----------+-----------+ +| CorrIntErr | 0 | 0 | ++---------------------+-----------+-----------+ +| HeaderOF | 0 | 0 | ++---------------------+-----------+-----------+ +| TOTAL_ERR_COR | 1 | 1 | ++---------------------+-----------+-----------+ +""" + +pcieutil_pcie_aer_fatal_output = """\ ++-----------------+-----------+-----------+ +| AER - FATAL | 00:01.0 | 01:00.0 | +| | 0x0001 | 0x0002 | ++=================+===========+===========+ +| Undefined | 0 | 0 | ++-----------------+-----------+-----------+ +| DLP | 0 | 0 | ++-----------------+-----------+-----------+ +| SDES | 0 | 0 | ++-----------------+-----------+-----------+ +| TLP | 0 | 0 | ++-----------------+-----------+-----------+ +| FCP | 0 | 0 | ++-----------------+-----------+-----------+ +| CmpltTO | 0 | 0 | ++-----------------+-----------+-----------+ +| CmpltAbrt | 0 | 0 | ++-----------------+-----------+-----------+ +| UnxCmplt | 0 | 0 | ++-----------------+-----------+-----------+ +| RxOF | 0 | 0 | ++-----------------+-----------+-----------+ +| MalfTLP | 0 | 0 | ++-----------------+-----------+-----------+ +| ECRC | 0 | 0 | ++-----------------+-----------+-----------+ +| UnsupReq | 0 | 0 | ++-----------------+-----------+-----------+ +| ACSViol | 0 | 0 | ++-----------------+-----------+-----------+ +| UncorrIntErr | 0 | 0 | ++-----------------+-----------+-----------+ +| BlockedTLP | 0 | 0 | ++-----------------+-----------+-----------+ +| AtomicOpBlocked | 0 | 0 | ++-----------------+-----------+-----------+ +| TLPBlockedErr | 0 | 0 | ++-----------------+-----------+-----------+ +| TOTAL_ERR_FATAL | 0 | 0 | ++-----------------+-----------+-----------+ +""" + +pcieutil_pcie_aer_nonfatal_output = """\ ++--------------------+-----------+-----------+ +| AER - NONFATAL | 00:01.0 | 01:00.0 | +| | 0x0001 | 0x0002 | ++====================+===========+===========+ +| Undefined | 0 | 0 | ++--------------------+-----------+-----------+ +| DLP | 0 | 0 | ++--------------------+-----------+-----------+ +| SDES | 0 | 0 | ++--------------------+-----------+-----------+ +| TLP | 0 | 0 | ++--------------------+-----------+-----------+ +| FCP | 0 | 0 | ++--------------------+-----------+-----------+ +| CmpltTO | 0 | 0 | ++--------------------+-----------+-----------+ +| CmpltAbrt | 0 | 0 | ++--------------------+-----------+-----------+ +| UnxCmplt | 0 | 0 | ++--------------------+-----------+-----------+ +| RxOF | 0 | 0 | ++--------------------+-----------+-----------+ +| MalfTLP | 1 | 0 | ++--------------------+-----------+-----------+ +| ECRC | 0 | 0 | ++--------------------+-----------+-----------+ +| UnsupReq | 0 | 0 | ++--------------------+-----------+-----------+ +| ACSViol | 0 | 0 | ++--------------------+-----------+-----------+ +| UncorrIntErr | 0 | 0 | ++--------------------+-----------+-----------+ +| BlockedTLP | 0 | 0 | ++--------------------+-----------+-----------+ +| AtomicOpBlocked | 0 | 0 | ++--------------------+-----------+-----------+ +| TLPBlockedErr | 0 | 0 | ++--------------------+-----------+-----------+ +| TOTAL_ERR_NONFATAL | 1 | 0 | ++--------------------+-----------+-----------+ +""" + +pcieutil_pcie_aer_correctable_nozero_output = """\ ++---------------------+-----------+-----------+ +| AER - CORRECTABLE | 00:01.0 | 01:00.0 | +| | 0x0001 | 0x0002 | ++=====================+===========+===========+ +| RxErr | 0 | 1 | ++---------------------+-----------+-----------+ +| BadTLP | 1 | 0 | ++---------------------+-----------+-----------+ +| TOTAL_ERR_COR | 1 | 1 | ++---------------------+-----------+-----------+ +""" + +pcieutil_pcie_aer_nonfatal_nozero_output = """\ ++--------------------+-----------+ +| AER - NONFATAL | 00:01.0 | +| | 0x0001 | ++====================+===========+ +| MalfTLP | 1 | ++--------------------+-----------+ +| TOTAL_ERR_NONFATAL | 1 | ++--------------------+-----------+ +""" + +pcieutil_pcie_aer_correctable_dev_output = """\ +---------------------+-----------+ | AER - CORRECTABLE | 00:01.0 | | | 0x0001 | +=====================+===========+ | RxErr | 0 | +---------------------+-----------+ -| BadTLP | 0 | +| BadTLP | 1 | +---------------------+-----------+ | BadDLLP | 0 | +---------------------+-----------+ @@ -31,133 +166,53 @@ +---------------------+-----------+ | HeaderOF | 0 | +---------------------+-----------+ -| TOTAL_ERR_COR | 0 | +| TOTAL_ERR_COR | 1 | +---------------------+-----------+ """ -pcieutil_pcie_aer_non_fatal_output = """\ -+--------------------+-----------+ -| AER - NONFATAL | 00:01.0 | -| | 0x0001 | -+====================+===========+ -| Undefined | 0 | -+--------------------+-----------+ -| DLP | 0 | -+--------------------+-----------+ -| SDES | 0 | -+--------------------+-----------+ -| TLP | 0 | -+--------------------+-----------+ -| FCP | 0 | -+--------------------+-----------+ -| CmpltTO | 0 | -+--------------------+-----------+ -| CmpltAbrt | 0 | -+--------------------+-----------+ -| UnxCmplt | 0 | -+--------------------+-----------+ -| RxOF | 0 | -+--------------------+-----------+ -| MalfTLP | 0 | -+--------------------+-----------+ -| ECRC | 0 | -+--------------------+-----------+ -| UnsupReq | 0 | -+--------------------+-----------+ -| ACSViol | 0 | -+--------------------+-----------+ -| UncorrIntErr | 0 | -+--------------------+-----------+ -| BlockedTLP | 0 | -+--------------------+-----------+ -| AtomicOpBlocked | 0 | -+--------------------+-----------+ -| TLPBlockedErr | 0 | -+--------------------+-----------+ -| TOTAL_ERR_NONFATAL | 0 | -+--------------------+-----------+ -""" - -pcieutil_pcie_aer_fatal_output = """\ -+-----------------+-----------+ -| AER - FATAL | 00:01.0 | -| | 0x0001 | -+=================+===========+ -| Undefined | 0 | -+-----------------+-----------+ -| DLP | 0 | -+-----------------+-----------+ -| SDES | 0 | -+-----------------+-----------+ -| TLP | 0 | -+-----------------+-----------+ -| FCP | 0 | -+-----------------+-----------+ -| CmpltTO | 0 | -+-----------------+-----------+ -| CmpltAbrt | 0 | -+-----------------+-----------+ -| UnxCmplt | 0 | -+-----------------+-----------+ -| RxOF | 0 | -+-----------------+-----------+ -| MalfTLP | 0 | -+-----------------+-----------+ -| ECRC | 0 | -+-----------------+-----------+ -| UnsupReq | 0 | -+-----------------+-----------+ -| ACSViol | 0 | -+-----------------+-----------+ -| UncorrIntErr | 0 | -+-----------------+-----------+ -| BlockedTLP | 0 | -+-----------------+-----------+ -| AtomicOpBlocked | 0 | -+-----------------+-----------+ -| TLPBlockedErr | 0 | -+-----------------+-----------+ -| TOTAL_ERR_FATAL | 0 | -+-----------------+-----------+ -""" - - -class MockPcieUtil(object): - def __init__(self): - self.confInfo = [ - {'bus': '00', 'dev': '01', 'name': 'PCIe Device 1', 'fn': '0', 'id': '0001'} - ] - - def get_pcie_check(self): - for item in self.confInfo: - item['result'] = "Passed" - - return self.confInfo - - class TestPcieUtil(object): @classmethod def setup_class(cls): print("SETUP") os.environ["UTILITIES_UNIT_TESTING"] = "1" + def test_aer_non_all(self): + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["all"], []) + assert result.output == (pcieutil_pcie_aer_correctable_output + "\n"\ + + pcieutil_pcie_aer_fatal_output + "\n"\ + + pcieutil_pcie_aer_nonfatal_output) + def test_aer_correctable(self): - with mock.patch("pcieutil.main.platform_pcieutil", new_callable=MockPcieUtil): - runner = CliRunner() - result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["correctable"], []) - assert pcieutil_pcie_aer_correctable_output == result.output + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["correctable"], []) + assert result.output == pcieutil_pcie_aer_correctable_output + + def test_aer_fatal(self): + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["fatal"], []) + assert result.output == pcieutil_pcie_aer_fatal_output def test_aer_non_fatal(self): - with mock.patch("pcieutil.main.platform_pcieutil", new_callable=MockPcieUtil): - runner = CliRunner() - result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["non-fatal"], []) - assert pcieutil_pcie_aer_non_fatal_output == result.output + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["non-fatal"], []) + assert result.output == pcieutil_pcie_aer_nonfatal_output - def test_aer_fatal(self): - with mock.patch("pcieutil.main.platform_pcieutil", new_callable=MockPcieUtil): - runner = CliRunner() - result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["fatal"], []) - assert pcieutil_pcie_aer_fatal_output == result.output + def test_aer_option_non_zero(self): + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["correctable"], ["-nz"]) + assert result.output == pcieutil_pcie_aer_correctable_nozero_output + + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["fatal"], ["-nz"]) + assert result.output == "" + + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["non-fatal"], ["-nz"]) + assert result.output == pcieutil_pcie_aer_nonfatal_nozero_output + + def test_aer_option_device(self): + runner = CliRunner() + result = runner.invoke(pcieutil.cli.commands["pcie-aer"].commands["correctable"], ["-d", "0:1.0"]) + assert result.output == pcieutil_pcie_aer_correctable_dev_output @classmethod def teardown_class(cls):