From 394c808142d58884a76cf087debcd62297b857f3 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 28 Jul 2020 17:23:02 -0700 Subject: [PATCH] add code for skipping test cases --- src/soc/fu/spr/test/test_pipe_caller.py | 15 ++--- src/soc/fu/test/common.py | 79 +++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/src/soc/fu/spr/test/test_pipe_caller.py b/src/soc/fu/spr/test/test_pipe_caller.py index 47a9e6c1..b3452ca8 100644 --- a/src/soc/fu/spr/test/test_pipe_caller.py +++ b/src/soc/fu/spr/test/test_pipe_caller.py @@ -13,7 +13,8 @@ from soc.config.endian import bigendian from soc.consts import MSR -from soc.fu.test.common import (TestAccumulatorBase, TestCase, ALUHelpers) +from soc.fu.test.common import ( + TestAccumulatorBase, skip_case, TestCase, ALUHelpers) from soc.fu.spr.pipeline import SPRBasePipe from soc.fu.spr.pipe_data import SPRPipeSpec import random @@ -83,7 +84,7 @@ class SPRTestCase(TestAccumulatorBase): initial_sprs = {'SRR0': 0x12345678, 'SRR1': 0x5678, 'LR': 0x1234, 'XER': 0xe00c0000} self.add_case(Program(lst, bigendian), - initial_regs, initial_sprs) + initial_regs, initial_sprs) def case_1_mtspr(self): lst = ["mtspr 26, 1", # SRR0 @@ -98,7 +99,7 @@ class SPRTestCase(TestAccumulatorBase): initial_sprs = {'SRR0': 0x12345678, 'SRR1': 0x5678, 'LR': 0x1234, 'XER': 0x0} self.add_case(Program(lst, bigendian), - initial_regs, initial_sprs) + initial_regs, initial_sprs) def case_2_mtspr_mfspr(self): lst = ["mtspr 26, 1", # SRR0 @@ -117,11 +118,11 @@ class SPRTestCase(TestAccumulatorBase): initial_sprs = {'SRR0': 0x12345678, 'SRR1': 0x5678, 'LR': 0x1234, 'XER': 0x0} self.add_case(Program(lst, bigendian), - initial_regs, initial_sprs) + initial_regs, initial_sprs) # TODO XXX whoops... - #@unittest.skip("spr does not have TRAP in it. has to be done another way") - def _skip_case_3_mtspr_priv(self): + @skip_case("spr does not have TRAP in it. has to be done another way") + def case_3_mtspr_priv(self): lst = ["mtspr 26, 1", # SRR0 "mtspr 27, 2", # SRR1 "mtspr 1, 3", # XER @@ -135,7 +136,7 @@ class SPRTestCase(TestAccumulatorBase): 'XER': 0x0} msr = 1 << MSR.PR self.add_case(Program(lst, bigendian), - initial_regs, initial_sprs, initial_msr=msr) + initial_regs, initial_sprs, initial_msr=msr) def case_ilang(self): pspec = SPRPipeSpec(id_wid=2) diff --git a/src/soc/fu/test/common.py b/src/soc/fu/test/common.py index 6d6181d7..d1473b05 100644 --- a/src/soc/fu/test/common.py +++ b/src/soc/fu/test/common.py @@ -4,10 +4,73 @@ Bugreports: """ import inspect +import functools +import types from soc.decoder.power_enums import XER_bits, CryIn, spr_dict from soc.regfile.util import fast_reg_to_spr # HACK! from soc.regfile.regfiles import FastRegs + +class SkipCase(Exception): + """Raise this exception to skip a test case. + + Usually you'd use one of the skip_case* decorators. + + For use with TestAccumulatorBase + """ + + +def _id(obj): + """identity function""" + return obj + + +def skip_case(reason): + """ + Unconditionally skip a test case. + + Use like: + @skip_case("my reason for skipping") + def case_abc(self): + ... + or: + @skip_case + def case_def(self): + ... + + For use with TestAccumulatorBase + """ + def decorator(item): + assert not isinstance(item, type), \ + "can't use skip_case to decorate types" + + @functools.wraps(item) + def wrapper(*args, **kwargs): + raise SkipCase(reason) + return wrapper + if isinstance(reason, types.FunctionType): + item = reason + reason = "" + return decorator(item) + return decorator + + +def skip_case_if(condition, reason): + """ + Conditionally skip a test case. + + Use like: + @skip_case_if(should_i_skip(), "my reason for skipping") + def case_abc(self): + ... + + For use with TestAccumulatorBase + """ + if condition: + return skip_case(reason) + return _id + + class TestAccumulatorBase: def __init__(self): @@ -17,14 +80,20 @@ class TestAccumulatorBase: # we need a different system for n, v in self.__class__.__dict__.items(): if n.startswith("case_") and callable(v): - v(self) + try: + v(self) + except SkipCase as e: + # TODO(programmerjake): translate to final test sending + # skip signal to unittest. for now, just print the skipped + # reason and ignore + print(f"SKIPPED({n}):", str(e)) def add_case(self, prog, initial_regs=None, initial_sprs=None, - initial_cr=0, initial_msr=0, - initial_mem=None): + initial_cr=0, initial_msr=0, + initial_mem=None): - test_name = inspect.stack()[1][3] # name of caller of this function - tc = TestCase(prog, test_name, + test_name = inspect.stack()[1][3] # name of caller of this function + tc = TestCase(prog, test_name, regs=initial_regs, sprs=initial_sprs, cr=initial_cr, msr=initial_msr, mem=initial_mem) -- 2.30.2