Пример #1
0
    def _init_test(self, test: Test) -> Optional[RunningTask]:
        """Initialize a test.

        Record outcome if the initialization fails.
        Record skip if the test is skipped.
        Save the initialized test if it successfully initializes.
        """

        if test.skip:
            hilight_start = ANSI.COLOR_TEST if want_color_output() else ''
            hilight_end = ANSI.COLOR_DEFAULT if want_color_output() else ''
            # Want this to stand out a little bit
            self.log.info("{}Skipping test {}/{}:{} {}".format(
                hilight_start, self.count, self.ntests, hilight_end,
                test.__qualname__))
            self._record_result(test, None, 0, 0)
            return None

        test_init_outcome = cocotb.outcomes.capture(test, self._dut)

        if isinstance(test_init_outcome, cocotb.outcomes.Error):
            self.log.error("Failed to initialize test %s" % test.__qualname__,
                           exc_info=test_init_outcome.error)
            self._record_result(test, test_init_outcome, 0, 0)
            return None

        test = test_init_outcome.get()
        return test
Пример #2
0
 def _log_test_failed(self,
                      test: Test,
                      result: Optional[Exception] = None,
                      msg: Optional[str] = None) -> None:
     start_hilight = ANSI.COLOR_FAILED if want_color_output() else ""
     stop_hilight = ANSI.COLOR_DEFAULT if want_color_output() else ""
     if msg is None:
         rest = ""
     else:
         rest = f": {msg}"
     self.log.info(f"{test} {start_hilight}failed{stop_hilight}{rest}",
                   exc_info=result)
Пример #3
0
    def _log_test_summary(self):
        TEST_FIELD = 'TEST'
        RESULT_FIELD = 'PASS/FAIL'
        SIM_FIELD = 'SIM TIME(NS)'
        REAL_FIELD = 'REAL TIME(S)'
        RATIO_FIELD = 'RATIO(NS/S)'

        TEST_FIELD_LEN = max(
            len(TEST_FIELD),
            len(max([x['test'] for x in self.test_results], key=len)))
        RESULT_FIELD_LEN = len(RESULT_FIELD)
        SIM_FIELD_LEN = len(SIM_FIELD)
        REAL_FIELD_LEN = len(REAL_FIELD)
        RATIO_FIELD_LEN = len(RATIO_FIELD)

        LINE_LEN = 3 + TEST_FIELD_LEN + 2 + RESULT_FIELD_LEN + 2 + SIM_FIELD_LEN + 2 + REAL_FIELD_LEN + 2 + RATIO_FIELD_LEN + 3

        LINE_SEP = "*" * LINE_LEN + "\n"

        summary = ""
        summary += LINE_SEP
        summary += "** {a:<{a_len}}  {b:^{b_len}}  {c:>{c_len}}  {d:>{d_len}}  {e:>{e_len}} **\n".format(
            a=TEST_FIELD,
            a_len=TEST_FIELD_LEN,
            b=RESULT_FIELD,
            b_len=RESULT_FIELD_LEN,
            c=SIM_FIELD,
            c_len=SIM_FIELD_LEN,
            d=REAL_FIELD,
            d_len=REAL_FIELD_LEN,
            e=RATIO_FIELD,
            e_len=RATIO_FIELD_LEN)
        summary += LINE_SEP
        for result in self.test_results:
            hilite = ''

            if result['pass'] is None:
                pass_fail_str = "N/A"
            elif result['pass']:
                pass_fail_str = "PASS"
            else:
                pass_fail_str = "FAIL"
                if want_color_output():
                    hilite = ANSI.COLOR_HILITE_SUMMARY

            summary += "{start}** {a:<{a_len}}  {b:^{b_len}}  {c:>{c_len}.2f}   {d:>{d_len}.2f}   {e:>{e_len}.2f}  **\n".format(
                a=result['test'],
                a_len=TEST_FIELD_LEN,
                b=pass_fail_str,
                b_len=RESULT_FIELD_LEN,
                c=result['sim'],
                c_len=SIM_FIELD_LEN - 1,
                d=result['real'],
                d_len=REAL_FIELD_LEN - 1,
                e=result['ratio'],
                e_len=RATIO_FIELD_LEN - 1,
                start=hilite)
        summary += LINE_SEP

        self.log.info(summary)
Пример #4
0
 def _log_test_passed(self,
                      test: Test,
                      result: Optional[Exception] = None,
                      msg: Optional[str] = None) -> None:
     start_hilight = ANSI.COLOR_PASSED if want_color_output() else ""
     stop_hilight = ANSI.COLOR_DEFAULT if want_color_output() else ""
     if msg is None:
         rest = ""
     else:
         rest = f": {msg}"
     if result is None:
         result_was = ""
     else:
         result_was = f" (result was {type(result).__qualname__})"
     self.log.info(
         f"{test} {start_hilight}passed{stop_hilight}{rest}{result_was}")
Пример #5
0
 def colour(self):
     warnings.warn(
         "the .colour attribute may be removed in future, use the "
         "equivalent `cocotb.utils.want_color_output()` instead",
         DeprecationWarning,
         stacklevel=2)
     return want_color_output()
Пример #6
0
def default_config():
    """Apply the default cocotb log formatting to the root logger.

    This hooks up the logger to write to stdout, using either
    :class:`SimColourLogFormatter` or :class:`SimLogFormatter` depending
    on whether colored output is requested. It also adds a
    :class:`SimTimeContextFilter` filter so that
    :attr:`~logging.LogRecord.created_sim_time` is available to the formatter.

    The logging level for cocotb logs is set based on the
    :envvar:`COCOTB_LOG_LEVEL` environment variable, which defaults to ``INFO``.

    If desired, this logging configuration can be overwritten by calling
    ``logging.basicConfig(..., force=True)`` (in Python 3.8 onwards), or by
    manually resetting the root logger instance.
    An example of this can be found in the section on :ref:`rotating-logger`.

    .. versionadded:: 1.4
    """
    # construct an appropriate handler
    hdlr = logging.StreamHandler(sys.stdout)
    hdlr.addFilter(SimTimeContextFilter())
    if want_color_output():
        hdlr.setFormatter(SimColourLogFormatter())
    else:
        hdlr.setFormatter(SimLogFormatter())

    logging.setLoggerClass(SimBaseLog)  # For backwards compatibility
    logging.basicConfig()
    logging.getLogger().handlers = [hdlr]  # overwrite default handlers

    # apply level settings for cocotb
    log = logging.getLogger("cocotb")

    try:
        # All log levels are upper case, convert the user input for convenience.
        level = os.environ["COCOTB_LOG_LEVEL"].upper()
    except KeyError:
        level = _COCOTB_LOG_LEVEL_DEFAULT

    try:
        log.setLevel(level)
    except ValueError:
        valid_levels = ("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE")
        raise ValueError(
            "Invalid log level %r passed through the "
            "COCOTB_LOG_LEVEL environment variable. Valid log "
            "levels: %s" % (level, ", ".join(valid_levels))
        )

    # Notify GPI of log level, which it uses as an optimization to avoid
    # calling into Python.
    from cocotb import simulator

    simulator.log_level(log.getEffectiveLevel())
Пример #7
0
    def _init_test(self, test: Test) -> Optional[RunningTask]:
        """Initialize a test.

        Record outcome if the initialization fails.
        Record skip if the test is skipped.
        Save the initialized test if it successfully initializes.
        """

        if test.skip:
            hilight_start = ANSI.COLOR_SKIPPED if want_color_output() else ""
            hilight_end = ANSI.COLOR_DEFAULT if want_color_output() else ""
            # Want this to stand out a little bit
            self.log.info("{start}skipping{end} {name} ({i}/{total})".format(
                start=hilight_start,
                i=self.count,
                total=self.ntests,
                end=hilight_end,
                name=test.__qualname__,
            ))
            self._record_result(test, None, 0, 0)
            return None

        test_init_outcome = cocotb.outcomes.capture(test, self._dut)

        if isinstance(test_init_outcome, cocotb.outcomes.Error):
            self.log.error(
                "Failed to initialize test %s" % test.__qualname__,
                exc_info=test_init_outcome.error,
            )
            self._record_result(test, test_init_outcome, 0, 0)
            return None

        running_test = test_init_outcome.get()

        # seed random number generator based on test module, name, and RANDOM_SEED
        hasher = hashlib.sha1()
        hasher.update(test.__qualname__.encode())
        hasher.update(test.__module__.encode())
        seed = cocotb.RANDOM_SEED + int(hasher.hexdigest(), 16)
        random.seed(seed)

        return running_test
Пример #8
0
    def __init__(self, name):
        super(SimBaseLog, self).__init__(name)

        # customizations of the defaults
        hdlr = logging.StreamHandler(sys.stdout)

        if want_color_output():
            hdlr.setFormatter(SimColourLogFormatter())
        else:
            hdlr.setFormatter(SimLogFormatter())

        self.propagate = False
        self.addHandler(hdlr)
Пример #9
0
    def _start_test(self) -> None:
        start = ''
        end = ''
        if want_color_output():
            start = ANSI.COLOR_TEST
            end = ANSI.COLOR_DEFAULT
        # Want this to stand out a little bit
        self.log.info(
            "%sRunning test %d/%d:%s %s" %
            (start, self.count, self.ntests, end, self._test.__qualname__))

        self._test_start_time = time.time()
        self._test_start_sim_time = get_sim_time('ns')
        cocotb.scheduler._add_test(self._test_task)
Пример #10
0
    def execute(self):
        self._running_test = cocotb.regression_manager.next_test()
        if self._running_test:
            start = ''
            end = ''
            if want_color_output():
                start = ANSI.COLOR_TEST
                end = ANSI.COLOR_DEFAULT
            # Want this to stand out a little bit
            self.log.info("%sRunning test %d/%d:%s %s" %
                          (start, self.count, self.ntests, end,
                           self._running_test.funcname))

            cocotb.scheduler.add_test(self._running_test)
            self.count += 1
        else:
            self.tear_down()
Пример #11
0
def default_config():
    """ Apply the default cocotb log formatting to the root logger.

    This hooks up the logger to write to stdout, using either
    :class:`SimColourLogFormatter` or :class:`SimLogFormatter` depending
    on whether colored output is requested. It also adds a
    :class:`SimTimeContextFilter` filter so that
    :attr:`~logging.LogRecord.created_sim_time` is available to the formatter.

    The logging level for cocotb logs is set based on the
    :envvar:`COCOTB_LOG_LEVEL` environment variable, which defaults to ``INFO``.

    If desired, this logging configuration can be overwritten by calling
    ``logging.basicConfig(..., force=True)`` (in Python 3.8 onwards), or by
    manually resetting the root logger instance.
    An example of this can be found in the section on :ref:`rotating-logger`.

    .. versionadded:: 1.4
    """
    # construct an appropriate handler
    hdlr = logging.StreamHandler(sys.stdout)
    hdlr.addFilter(SimTimeContextFilter())
    if want_color_output():
        hdlr.setFormatter(SimColourLogFormatter())
    else:
        hdlr.setFormatter(SimLogFormatter())

    logging.setLoggerClass(SimBaseLog)  # For backwards compatibility
    logging.basicConfig()
    logging.getLogger().handlers = [hdlr]  # overwrite default handlers

    # apply level settings for cocotb
    log = logging.getLogger('cocotb')
    level = os.getenv("COCOTB_LOG_LEVEL", "INFO")
    try:
        _default_log = getattr(logging, level)
    except AttributeError:
        log.error("Unable to set logging level to %r" % level)
        _default_log = logging.INFO
    log.setLevel(_default_log)

    # Notify GPI of log level, which it uses as an optimization to avoid
    # calling into Python.
    from cocotb import simulator
    simulator.log_level(_default_log)
Пример #12
0
    def _start_test(self) -> None:
        start = ''
        end = ''
        if want_color_output():
            start = ANSI.COLOR_TEST
            end = ANSI.COLOR_DEFAULT
        # Want this to stand out a little bit
        self.log.info("{start}running{end} {name} ({i}/{total})".format(
            start=start,
            i=self.count,
            total=self.ntests,
            end=end,
            name=self._test.__qualname__,
        ))

        self._test_start_time = time.time()
        self._test_start_sim_time = get_sim_time('ns')
        cocotb.scheduler._add_test(self._test_task)
Пример #13
0
    def _start_test(self) -> None:
        # Want this to stand out a little bit
        start = ""
        end = ""
        if want_color_output():
            start = ANSI.COLOR_TEST
            end = ANSI.COLOR_DEFAULT
        self.log.info(
            "{start}running{end} {name} ({i}/{total}){description}".format(
                start=start,
                i=self.count,
                total=self.ntests,
                end=end,
                name=self._test.__qualname__,
                description=_trim(self._test.__doc__),
            ))

        self._test_start_time = time.time()
        self._test_start_sim_time = get_sim_time("ns")
        cocotb.scheduler._add_test(self._test_task)
Пример #14
0
    def _log_test_summary(self) -> None:

        real_time = time.time() - self.start_time
        sim_time_ns = get_sim_time("ns")
        ratio_time = self._safe_divide(sim_time_ns, real_time)

        if len(self.test_results) == 0:
            return

        TEST_FIELD = "TEST"
        RESULT_FIELD = "STATUS"
        SIM_FIELD = "SIM TIME (ns)"
        REAL_FIELD = "REAL TIME (s)"
        RATIO_FIELD = "RATIO (ns/s)"
        TOTAL_NAME = f"TESTS={self.ntests} PASS={self.passed} FAIL={self.failures} SKIP={self.skipped}"

        TEST_FIELD_LEN = max(
            len(TEST_FIELD),
            len(TOTAL_NAME),
            len(max([x["test"] for x in self.test_results], key=len)),
        )
        RESULT_FIELD_LEN = len(RESULT_FIELD)
        SIM_FIELD_LEN = len(SIM_FIELD)
        REAL_FIELD_LEN = len(REAL_FIELD)
        RATIO_FIELD_LEN = len(RATIO_FIELD)

        header_dict = dict(
            a=TEST_FIELD,
            b=RESULT_FIELD,
            c=SIM_FIELD,
            d=REAL_FIELD,
            e=RATIO_FIELD,
            a_len=TEST_FIELD_LEN,
            b_len=RESULT_FIELD_LEN,
            c_len=SIM_FIELD_LEN,
            d_len=REAL_FIELD_LEN,
            e_len=RATIO_FIELD_LEN,
        )

        LINE_LEN = (3 + TEST_FIELD_LEN + 2 + RESULT_FIELD_LEN + 2 +
                    SIM_FIELD_LEN + 2 + REAL_FIELD_LEN + 2 + RATIO_FIELD_LEN +
                    3)

        LINE_SEP = "*" * LINE_LEN + "\n"

        summary = ""
        summary += LINE_SEP
        summary += "** {a:<{a_len}}  {b:^{b_len}}  {c:>{c_len}}  {d:>{d_len}}  {e:>{e_len}} **\n".format(
            **header_dict)
        summary += LINE_SEP

        test_line = "** {a:<{a_len}}  {start}{b:^{b_len}}{end}  {c:>{c_len}.2f}   {d:>{d_len}.2f}   {e:>{e_len}}  **\n"
        for result in self.test_results:
            hilite = ""
            lolite = ""

            if result["pass"] is None:
                ratio = "-.--"
                pass_fail_str = "SKIP"
                if want_color_output():
                    hilite = ANSI.COLOR_SKIPPED
                    lolite = ANSI.COLOR_DEFAULT
            elif result["pass"]:
                ratio = format(result["ratio"], "0.2f")
                pass_fail_str = "PASS"
                if want_color_output():
                    hilite = ANSI.COLOR_PASSED
                    lolite = ANSI.COLOR_DEFAULT
            else:
                ratio = format(result["ratio"], "0.2f")
                pass_fail_str = "FAIL"
                if want_color_output():
                    hilite = ANSI.COLOR_FAILED
                    lolite = ANSI.COLOR_DEFAULT

            test_dict = dict(
                a=result["test"],
                b=pass_fail_str,
                c=result["sim"],
                d=result["real"],
                e=ratio,
                a_len=TEST_FIELD_LEN,
                b_len=RESULT_FIELD_LEN,
                c_len=SIM_FIELD_LEN - 1,
                d_len=REAL_FIELD_LEN - 1,
                e_len=RATIO_FIELD_LEN - 1,
                start=hilite,
                end=lolite,
            )

            summary += test_line.format(**test_dict)

        summary += LINE_SEP

        summary += test_line.format(
            a=TOTAL_NAME,
            b="",
            c=sim_time_ns,
            d=real_time,
            e=format(ratio_time, "0.2f"),
            a_len=TEST_FIELD_LEN,
            b_len=RESULT_FIELD_LEN,
            c_len=SIM_FIELD_LEN - 1,
            d_len=REAL_FIELD_LEN - 1,
            e_len=RATIO_FIELD_LEN - 1,
            start="",
            end="",
        )

        summary += LINE_SEP

        self.log.info(summary)
Пример #15
0
    def _log_test_summary(self) -> None:

        if self.failures:
            self.log.error("Failed %d out of %d tests (%d skipped)" %
                           (self.failures, self.count, self.skipped))
        else:
            self.log.info("Passed %d tests (%d skipped)" %
                          (self.count, self.skipped))

        if len(self.test_results) == 0:
            return

        TEST_FIELD = 'TEST'
        RESULT_FIELD = 'PASS/FAIL'
        SIM_FIELD = 'SIM TIME(NS)'
        REAL_FIELD = 'REAL TIME(S)'
        RATIO_FIELD = 'RATIO(NS/S)'

        TEST_FIELD_LEN = max(
            len(TEST_FIELD),
            len(max([x['test'] for x in self.test_results], key=len)))
        RESULT_FIELD_LEN = len(RESULT_FIELD)
        SIM_FIELD_LEN = len(SIM_FIELD)
        REAL_FIELD_LEN = len(REAL_FIELD)
        RATIO_FIELD_LEN = len(RATIO_FIELD)

        header_dict = dict(a=TEST_FIELD,
                           b=RESULT_FIELD,
                           c=SIM_FIELD,
                           d=REAL_FIELD,
                           e=RATIO_FIELD,
                           a_len=TEST_FIELD_LEN,
                           b_len=RESULT_FIELD_LEN,
                           c_len=SIM_FIELD_LEN,
                           d_len=REAL_FIELD_LEN,
                           e_len=RATIO_FIELD_LEN)

        LINE_LEN = 3 + TEST_FIELD_LEN + 2 + RESULT_FIELD_LEN + 2 + SIM_FIELD_LEN + 2 + \
            REAL_FIELD_LEN + 2 + RATIO_FIELD_LEN + 3

        LINE_SEP = "*" * LINE_LEN + "\n"

        summary = ""
        summary += LINE_SEP
        summary += "** {a:<{a_len}}  {b:^{b_len}}  {c:>{c_len}}  {d:>{d_len}}  {e:>{e_len}} **\n".format(
            **header_dict)
        summary += LINE_SEP

        test_line = "{start}** {a:<{a_len}}  {b:^{b_len}}  {c:>{c_len}.2f}   {d:>{d_len}.2f}   {e:>{e_len}.2f}  **\n"
        for result in self.test_results:
            hilite = ''

            if result['pass'] is None:
                pass_fail_str = "N/A"
            elif result['pass']:
                pass_fail_str = "PASS"
            else:
                pass_fail_str = "FAIL"
                if want_color_output():
                    hilite = ANSI.COLOR_HILITE_SUMMARY

            test_dict = dict(a=result['test'],
                             b=pass_fail_str,
                             c=result['sim'],
                             d=result['real'],
                             e=result['ratio'],
                             a_len=TEST_FIELD_LEN,
                             b_len=RESULT_FIELD_LEN,
                             c_len=SIM_FIELD_LEN - 1,
                             d_len=REAL_FIELD_LEN - 1,
                             e_len=RATIO_FIELD_LEN - 1,
                             start=hilite)

            summary += test_line.format(**test_dict)

        summary += LINE_SEP

        self.log.info(summary)
Пример #16
0
import logging
import sys
import re
from explainusb.descriptors import descriptor_data

# Use cocotb logging if available. Use the built in logging module otherwise.
# The color routines check if stdout is a tty.
SAME_COLOR = ''
DIFF_COLOR = ''
try:
    from cocotb.log import SimLog
    from cocotb.utils import want_color_output
    import cocotb.ANSI as ANSI
    logger = SimLog("cocotb.usb.explain")
    #logger.setLevel(logging.DEBUG)
    if want_color_output():
        SAME_COLOR = ANSI.COLOR_INFO
        DIFF_COLOR = ANSI.COLOR_ERROR
except ImportError:
    logger = logging

# Create a pretty printer object to display descriptors as structures.
# Leave list unsorted if the option is available.
if sys.version_info >= (3, 8):
    pp = pprint.PrettyPrinter(sort_dicts=False)
else:
    pp = pprint.PrettyPrinter()

# Use UTF empty set symbol for non-existant field in packet comparisons as long
# as environment is not limited to 8-bit characters.
import locale