#!/usr/bin/env python3
# vim: set syntax=python ts=4 :
"""Zephyr Sanity Tests

This script scans for the set of unit test applications in the git
repository and attempts to execute them. By default, it tries to
build each test case on one platform per architecture, using a precedence
list defined in an architecture configuration file, and if possible
run the tests in the QEMU emulator.

Test cases are detected by the presence of a 'testcase.yaml' or a sample.yaml
files in the application's project directory. This file may contain one or more
blocks, each identifying a test scenario. The title of the block is a name for
the test case, which only needs to be unique for the test cases specified in
that testcase meta-data. The full canonical name for each test case is <path to
test case>/<block>.

Each test block in the testcase meta data can define the following key/value
pairs:

  tags: <list of tags> (required)
    A set of string tags for the testcase. Usually pertains to
    functional domains but can be anything. Command line invocations
    of this script can filter the set of tests to run based on tag.

  skip: <True|False> (default False)
    skip testcase unconditionally. This can be used for broken tests.

  slow: <True|False> (default False)
    Don't build or run this test case unless --enable-slow was passed
    in on the command line. Intended for time-consuming test cases
    that are only run under certain circumstances, like daily
    builds.

  extra_args: <list of extra arguments>
    Extra cache entries to pass to CMake when building or running the
    test case.

  extra_configs: <list of extra configurations>
    Extra configuration options to be merged with a master prj.conf
    when building or running the test case.

  build_only: <True|False> (default False)
    If true, don't try to run the test under QEMU even if the
    selected platform supports it.

  build_on_all: <True|False> (default False)
    If true, attempt to build test on all available platforms.

  depends_on: <list of features>
    A board or platform can announce what features it supports, this option
    will enable the test only those platforms that provide this feature.

  min_ram: <integer>
    minimum amount of RAM needed for this test to build and run. This is
    compared with information provided by the board metadata.

  min_flash: <integer>
    minimum amount of ROM needed for this test to build and run. This is
    compared with information provided by the board metadata.

  timeout: <number of seconds>
    Length of time to run test in QEMU before automatically killing it.
    Default to 60 seconds.

  arch_whitelist: <list of arches, such as x86, arm, arc>
    Set of architectures that this test case should only be run for.

  arch_exclude: <list of arches, such as x86, arm, arc>
    Set of architectures that this test case should not run on.

  platform_whitelist: <list of platforms>
    Set of platforms that this test case should only be run for.

  platform_exclude: <list of platforms>
    Set of platforms that this test case should not run on.

  extra_sections: <list of extra binary sections>
    When computing sizes, sanitycheck will report errors if it finds
    extra, unexpected sections in the Zephyr binary unless they are named
    here. They will not be included in the size calculation.

  filter: <expression>
    Filter whether the testcase should be run by evaluating an expression
    against an environment containing the following values:

    { ARCH : <architecture>,
      PLATFORM : <platform>,
      <all CONFIG_* key/value pairs in the test's generated defconfig>,
      <all DT_* key/value pairs in the test's generated device tree file>,
      <all CMake key/value pairs in the test's generated CMakeCache.txt file>,
      *<env>: any environment variable available
    }

    The grammar for the expression language is as follows:

    expression ::= expression "and" expression
                 | expression "or" expression
                 | "not" expression
                 | "(" expression ")"
                 | symbol "==" constant
                 | symbol "!=" constant
                 | symbol "<" number
                 | symbol ">" number
                 | symbol ">=" number
                 | symbol "<=" number
                 | symbol "in" list
                 | symbol ":" string
                 | symbol

    list ::= "[" list_contents "]"

    list_contents ::= constant
                    | list_contents "," constant

    constant ::= number
               | string


    For the case where expression ::= symbol, it evaluates to true
    if the symbol is defined to a non-empty string.

    Operator precedence, starting from lowest to highest:

        or (left associative)
        and (left associative)
        not (right associative)
        all comparison operators (non-associative)

    arch_whitelist, arch_exclude, platform_whitelist, platform_exclude
    are all syntactic sugar for these expressions. For instance

        arch_exclude = x86 arc

    Is the same as:

        filter = not ARCH in ["x86", "arc"]

    The ':' operator compiles the string argument as a regular expression,
    and then returns a true value only if the symbol's value in the environment
    matches. For example, if CONFIG_SOC="quark_se" then

        filter = CONFIG_SOC : "quark.*"

    Would match it.

The set of test cases that actually run depends on directives in the testcase
filed and options passed in on the command line. If there is any confusion,
running with -v or --discard-report can help show why particular test cases
were skipped.

Metrics (such as pass/fail state and binary size) for the last code
release are stored in scripts/sanity_chk/sanity_last_release.csv.
To update this, pass the --all --release options.

To load arguments from a file, write '+' before the file name, e.g.,
+file_name. File content must be one or more valid arguments separated by
line break instead of white spaces.

Most everyday users will run with no arguments.

"""

import os

if os.name == 'nt':
    print("Running sanitycheck on Windows is not supported yet.")
    print("https://github.com/zephyrproject-rtos/zephyr/issues/2664")
    exit(1)

import contextlib
import string
import mmap
import argparse
import sys
import re
import subprocess
import multiprocessing
import select
import shutil
import signal
import threading
import time
import csv
import glob
import serial
import concurrent
import concurrent.futures
import xml.etree.ElementTree as ET
from xml.sax.saxutils import escape
from collections import OrderedDict
from itertools import islice
from functools import cmp_to_key
from pathlib import Path
from distutils.spawn import find_executable

import logging
from sanity_chk import scl
from sanity_chk import expr_parser

log_format = "%(levelname)s %(name)s::%(module)s.%(funcName)s():%(lineno)d: %(message)s"
logging.basicConfig(format=log_format, level=30)

ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE")
if not ZEPHYR_BASE:
    sys.stderr.write("$ZEPHYR_BASE environment variable undefined.\n")
    exit(1)

sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/"))


VERBOSE = 0
LAST_SANITY = os.path.join(ZEPHYR_BASE, "scripts", "sanity_chk",
                           "last_sanity.csv")
LAST_SANITY_XUNIT = os.path.join(ZEPHYR_BASE, "scripts", "sanity_chk",
                                 "last_sanity.xml")
RELEASE_DATA = os.path.join(ZEPHYR_BASE, "scripts", "sanity_chk",
                            "sanity_last_release.csv")
JOBS = multiprocessing.cpu_count() * 2

if os.isatty(sys.stdout.fileno()):
    TERMINAL = True
    COLOR_NORMAL = '\033[0m'
    COLOR_RED = '\033[91m'
    COLOR_GREEN = '\033[92m'
    COLOR_YELLOW = '\033[93m'
else:
    TERMINAL = False
    COLOR_NORMAL = ""
    COLOR_RED = ""
    COLOR_GREEN = ""
    COLOR_YELLOW = ""

class CMakeCacheEntry:
    '''Represents a CMake cache entry.

    This class understands the type system in a CMakeCache.txt, and
    converts the following cache types to Python types:

    Cache Type    Python type
    ----------    -------------------------------------------
    FILEPATH      str
    PATH          str
    STRING        str OR list of str (if ';' is in the value)
    BOOL          bool
    INTERNAL      str OR list of str (if ';' is in the value)
    ----------    -------------------------------------------
    '''

    # Regular expression for a cache entry.
    #
    # CMake variable names can include escape characters, allowing a
    # wider set of names than is easy to match with a regular
    # expression. To be permissive here, use a non-greedy match up to
    # the first colon (':'). This breaks if the variable name has a
    # colon inside, but it's good enough.
    CACHE_ENTRY = re.compile(
        r'''(?P<name>.*?)                               # name
         :(?P<type>FILEPATH|PATH|STRING|BOOL|INTERNAL)  # type
         =(?P<value>.*)                                 # value
        ''', re.X)

    @classmethod
    def _to_bool(cls, val):
        # Convert a CMake BOOL string into a Python bool.
        #
        #   "True if the constant is 1, ON, YES, TRUE, Y, or a
        #   non-zero number. False if the constant is 0, OFF, NO,
        #   FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in
        #   the suffix -NOTFOUND. Named boolean constants are
        #   case-insensitive. If the argument is not one of these
        #   constants, it is treated as a variable."
        #
        # https://cmake.org/cmake/help/v3.0/command/if.html
        val = val.upper()
        if val in ('ON', 'YES', 'TRUE', 'Y'):
            return 1
        elif val in ('OFF', 'NO', 'FALSE', 'N', 'IGNORE', 'NOTFOUND', ''):
            return 0
        elif val.endswith('-NOTFOUND'):
            return 0
        else:
            try:
                v = int(val)
                return v != 0
            except ValueError as exc:
                raise ValueError('invalid bool {}'.format(val)) from exc

    @classmethod
    def from_line(cls, line, line_no):
        # Comments can only occur at the beginning of a line.
        # (The value of an entry could contain a comment character).
        if line.startswith('//') or line.startswith('#'):
            return None

        # Whitespace-only lines do not contain cache entries.
        if not line.strip():
            return None

        m = cls.CACHE_ENTRY.match(line)
        if not m:
            return None

        name, type_, value = (m.group(g) for g in ('name', 'type', 'value'))
        if type_ == 'BOOL':
            try:
                value = cls._to_bool(value)
            except ValueError as exc:
                args = exc.args + ('on line {}: {}'.format(line_no, line),)
                raise ValueError(args) from exc
        elif type_ == 'STRING' or type_ == 'INTERNAL':
            # If the value is a CMake list (i.e. is a string which
            # contains a ';'), convert to a Python list.
            if ';' in value:
                value = value.split(';')

        return CMakeCacheEntry(name, value)

    def __init__(self, name, value):
        self.name = name
        self.value = value

    def __str__(self):
        fmt = 'CMakeCacheEntry(name={}, value={})'
        return fmt.format(self.name, self.value)


class CMakeCache:
    '''Parses and represents a CMake cache file.'''

    @staticmethod
    def from_file(cache_file):
        return CMakeCache(cache_file)

    def __init__(self, cache_file):
        self.cache_file = cache_file
        self.load(cache_file)

    def load(self, cache_file):
        entries = []
        with open(cache_file, 'r') as cache:
            for line_no, line in enumerate(cache):
                entry = CMakeCacheEntry.from_line(line, line_no)
                if entry:
                    entries.append(entry)
        self._entries = OrderedDict((e.name, e) for e in entries)

    def get(self, name, default=None):
        entry = self._entries.get(name)
        if entry is not None:
            return entry.value
        else:
            return default

    def get_list(self, name, default=None):
        if default is None:
            default = []
        entry = self._entries.get(name)
        if entry is not None:
            value = entry.value
            if isinstance(value, list):
                return value
            elif isinstance(value, str):
                return [value] if value else []
            else:
                msg = 'invalid value {} type {}'
                raise RuntimeError(msg.format(value, type(value)))
        else:
            return default

    def __contains__(self, name):
        return name in self._entries

    def __getitem__(self, name):
        return self._entries[name].value

    def __setitem__(self, name, entry):
        if not isinstance(entry, CMakeCacheEntry):
            msg = 'improper type {} for value {}, expecting CMakeCacheEntry'
            raise TypeError(msg.format(type(entry), entry))
        self._entries[name] = entry

    def __delitem__(self, name):
        del self._entries[name]

    def __iter__(self):
        return iter(self._entries.values())

class SanityCheckException(Exception):
    pass


class SanityRuntimeError(SanityCheckException):
    pass


class ConfigurationError(SanityCheckException):
    def __init__(self, cfile, message):
        self.cfile = cfile
        self.message = message

    def __str__(self):
        return repr(self.cfile + ": " + self.message)


class MakeError(SanityCheckException):
    pass


class BuildError(MakeError):
    pass


class ExecutionError(MakeError):
    pass


log_file = None


# Debug Functions
def info(what):
    sys.stdout.write(what + "\n")
    sys.stdout.flush()
    if log_file:
        log_file.write(what + "\n")
        log_file.flush()


def error(what):
    sys.stderr.write(COLOR_RED + what + COLOR_NORMAL + "\n")
    if log_file:
        log_file(what + "\n")
        log_file.flush()


def debug(what):
    if VERBOSE >= 1:
        info(what)


def verbose(what):
    if VERBOSE >= 2:
        info(what)

class HarnessImporter:

    def __init__(self, name):
        sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/sanity_chk"))
        module = __import__("harness")
        if name:
            my_class = getattr(module, name)
        else:
            my_class = getattr(module, "Test")

        self.instance = my_class()

class Handler:
    def __init__(self, instance):
        """Constructor

        @param name Arbitrary name of the created thread
        @param outdir Working directory, should be where handler pid file (qemu.pid for example)
            gets created by the build system
        @param log_fn Absolute path to write out handler's log data
        @param timeout Kill the handler process if it doesn't finish up within
            the given number of seconds
        """
        self.lock = threading.Lock()
        self.state = "waiting"
        self.run = False
        self.metrics = {}
        self.metrics["handler_time"] = 0
        self.metrics["ram_size"] = 0
        self.metrics["rom_size"] = 0

        self.binary = None
        self.pid_fn = None
        self.call_make_run = False

        self.name = instance.name
        self.instance = instance
        self.timeout = instance.test.timeout
        self.sourcedir = instance.test.test_path
        self.outdir = instance.outdir
        self.log = os.path.join(self.outdir, "handler.log")
        self.returncode = 0
        self.set_state("running", {})

    def set_state(self, state, metrics):
        self.lock.acquire()
        self.state = state
        self.metrics.update(metrics)
        self.lock.release()

    def get_state(self):
        self.lock.acquire()
        ret = (self.state, self.metrics)
        self.lock.release()
        return ret

class BinaryHandler(Handler):
    def __init__(self, instance):
        """Constructor

        @param instance Test Instance
        """
        super().__init__(instance)

        self.valgrind = False
        self.terminated = False

    def try_kill_process_by_pid(self):
        if self.pid_fn != None:
            pid = int(open(self.pid_fn).read())
            os.unlink(self.pid_fn)
            self.pid_fn = None  # clear so we don't try to kill the binary twice
            try:
                os.kill(pid, signal.SIGTERM)
            except ProcessLookupError:
                pass

    def _output_reader(self, proc, harness):
        log_out_fp = open(self.log, "wt")
        for line in iter(proc.stdout.readline, b''):
            verbose("OUTPUT: {0}".format(line.decode('utf-8').rstrip()))
            log_out_fp.write(line.decode('utf-8'))
            log_out_fp.flush()
            harness.handle(line.decode('utf-8').rstrip())
            if harness.state:
                try:
                    #POSIX arch based ztests end on their own,
                    #so let's give it up to 100ms to do so
                    proc.wait(0.1)
                except subprocess.TimeoutExpired:
                    proc.terminate()
                    self.terminated = True
                break

        log_out_fp.close()

    def handle(self):

        harness_name = self.instance.test.harness.capitalize()
        harness_import = HarnessImporter(harness_name)
        harness = harness_import.instance
        harness.configure(self.instance)

        if self.call_make_run:
            if options.ninja:
                generator_cmd = "ninja"
            else:
                generator_cmd = "make"
            command = [generator_cmd, "-C", self.outdir, "run"]
        else:
            command = [self.binary]

        if shutil.which("valgrind") and self.valgrind:
            command = ["valgrind", "--error-exitcode=2",
                       "--leak-check=full",
                       "--suppressions="+ZEPHYR_BASE+"/scripts/valgrind.supp",
                       "--log-file="+self.outdir+"/valgrind.log"
                       ] + command

        with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
            t = threading.Thread(target=self._output_reader, args=(proc, harness, ))
            t.start()
            t.join(self.timeout)
            if t.is_alive():
                self.try_kill_process_by_pid()
                proc.terminate()
                self.terminated = True
                t.join()
            proc.wait()
            self.returncode = proc.returncode

        if options.enable_coverage:
            returncode = subprocess.call(["GCOV_PREFIX=" + self.outdir,
                "gcov", self.sourcedir, "-b", "-s", self.outdir], shell=True)

        self.try_kill_process_by_pid()

        # FIME: This is needed when killing the simulator, the console is
        # garbled and needs to be reset. Did not find a better way to do that.

        subprocess.call(["stty", "sane"])
        self.instance.results = harness.tests
        if self.terminated==False and self.returncode != 0:
            #When a process is killed, the default handler returns 128 + SIGTERM
            #so in that case the return code itself is not meaningful
            self.set_state("error", {})
        elif harness.state:
            self.set_state(harness.state, {})
        else:
            self.set_state("timeout", {})

class DeviceHandler(Handler):

    def __init__(self, instance):
        """Constructor

        @param instance Test Instance
        """
        super().__init__(instance)

    def monitor_serial(self, ser, halt_fileno, harness):
        log_out_fp = open(self.log, "wt")

        ser_fileno = ser.fileno()
        readlist = [halt_fileno, ser_fileno]

        while ser.isOpen():
            readable, _, _ = select.select(readlist, [], [], self.timeout)

            if halt_fileno in readable:
                verbose('halted')
                ser.close()
                break
            if ser_fileno not in readable:
                continue        # Timeout.

            serial_line = None
            try:
                serial_line = ser.readline()
            except TypeError:
                pass
            except serial.serialutil.SerialException:
                ser.close()
                break

            # Just because ser_fileno has data doesn't mean an entire line
            # is available yet.
            if serial_line:
                sl = serial_line.decode('utf-8', 'ignore')
                verbose("DEVICE: {0}".format(sl.rstrip()))

                log_out_fp.write(sl)
                log_out_fp.flush()
                harness.handle(sl.rstrip())

            if harness.state:
                ser.close()
                break

        log_out_fp.close()

    def handle(self):
        out_state = "failed"

        if options.ninja:
            generator_cmd = "ninja"
        else:
            generator_cmd = "make"

        command = [generator_cmd, "-C", self.outdir, "flash"]

        device = options.device_serial
        ser = serial.Serial(
                device,
                baudrate=115200,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                bytesize=serial.EIGHTBITS,
                timeout=self.timeout
                )

        ser.flush()

        harness_name = self.instance.test.harness.capitalize()
        harness_import = HarnessImporter(harness_name)
        harness = harness_import.instance
        harness.configure(self.instance)
        rpipe, wpipe = os.pipe()

        t = threading.Thread(target=self.monitor_serial, daemon=True,
                             args=(ser, rpipe, harness))
        t.start()

        try:
            if VERBOSE:
                subprocess.check_call(command)
            else:
                subprocess.check_output(command, stderr=subprocess.PIPE)
        except subprocess.CalledProcessError:
            os.write(wpipe, b'x')    # halt the thread

        t.join(self.timeout)
        if t.is_alive():
            out_state = "timeout"

        if ser.isOpen():
            ser.close()

        if out_state == "timeout":
            for c in self.instance.test.cases:
                if c not in harness.tests:
                    harness.tests[c] = "BLOCK"

        self.instance.results = harness.tests
        if harness.state:
            self.set_state(harness.state, {})
        else:
            self.set_state(out_state, {})


class QEMUHandler(Handler):
    """Spawns a thread to monitor QEMU output from pipes

    We pass QEMU_PIPE to 'make run' and monitor the pipes for output.
    We need to do this as once qemu starts, it runs forever until killed.
    Test cases emit special messages to the console as they run, we check
    for these to collect whether the test passed or failed.
    """

    @staticmethod
    def _thread(handler, timeout, outdir, logfile, fifo_fn, pid_fn, results, harness):
        fifo_in = fifo_fn + ".in"
        fifo_out = fifo_fn + ".out"

        # These in/out nodes are named from QEMU's perspective, not ours
        if os.path.exists(fifo_in):
            os.unlink(fifo_in)
        os.mkfifo(fifo_in)
        if os.path.exists(fifo_out):
            os.unlink(fifo_out)
        os.mkfifo(fifo_out)

        # We don't do anything with out_fp but we need to open it for
        # writing so that QEMU doesn't block, due to the way pipes work
        out_fp = open(fifo_in, "wb")
        # Disable internal buffering, we don't
        # want read() or poll() to ever block if there is data in there
        in_fp = open(fifo_out, "rb", buffering=0)
        log_out_fp = open(logfile, "wt")

        start_time = time.time()
        timeout_time = start_time + timeout
        p = select.poll()
        p.register(in_fp, select.POLLIN)
        out_state = None

        metrics = {}
        line = ""
        timeout_extended = False
        while True:
            this_timeout = int((timeout_time - time.time()) * 1000)
            if this_timeout < 0 or not p.poll(this_timeout):
                if not out_state:
                    out_state = "timeout"
                break

            try:
                c = in_fp.read(1).decode("utf-8")
            except UnicodeDecodeError:
                # Test is writing something weird, fail
                out_state = "unexpected byte"
                break

            if c == "":
                # EOF, this shouldn't happen unless QEMU crashes
                out_state = "unexpected eof"
                break
            line = line + c
            if c != "\n":
                continue

            # line contains a full line of data output from QEMU
            log_out_fp.write(line)
            log_out_fp.flush()
            line = line.strip()
            verbose("QEMU: %s" % line)

            harness.handle(line)
            if harness.state:
                # if we have registered a fail make sure the state is not
                # overridden by a false success message coming from the
                # testsuite
                if out_state != 'failed':
                    out_state = harness.state

                # if we get some state, that means test is doing well, we reset
                # the timeout and wait for 2 more seconds just in case we have
                # crashed after test has completed
                if not timeout_extended or harness.capture_coverage:
                    timeout_extended= True
                    if harness.capture_coverage:
                        timeout_time = time.time() + 10
                    else:
                        timeout_time = time.time() + 2

            # TODO: Add support for getting numerical performance data
            # from test cases. Will involve extending test case reporting
            # APIs. Add whatever gets reported to the metrics dictionary
            line = ""

        metrics["handler_time"] = time.time() - start_time
        verbose("QEMU complete (%s) after %f seconds" %
                (out_state, metrics["handler_time"]))
        handler.set_state(out_state, metrics)

        log_out_fp.close()
        out_fp.close()
        in_fp.close()

        pid = int(open(pid_fn).read())
        os.unlink(pid_fn)
        try:
            os.kill(pid, signal.SIGTERM)
        except ProcessLookupError:
            # Oh well, as long as it's dead! User probably sent Ctrl-C
            pass

        os.unlink(fifo_in)
        os.unlink(fifo_out)

    def __init__(self, instance):
        """Constructor

        @param instance Test instance
        """

        super().__init__(instance)

        self.results = {}
        self.run = True

        # We pass this to QEMU which looks for fifos with .in and .out
        # suffixes.
        self.fifo_fn = os.path.join(instance.outdir, "qemu-fifo")

        self.pid_fn = os.path.join(instance.outdir, "qemu.pid")
        if os.path.exists(self.pid_fn):
            os.unlink(self.pid_fn)

        self.log_fn = self.log

        harness_import = HarnessImporter(instance.test.harness.capitalize())
        harness = harness_import.instance
        harness.configure(self.instance)
        self.thread = threading.Thread(name=self.name, target=QEMUHandler._thread,
                                       args=(self, self.timeout, self.outdir,
                                             self.log_fn, self.fifo_fn,
                                             self.pid_fn, self.results, harness))

        self.instance.results = harness.tests
        self.thread.daemon = True
        verbose("Spawning QEMU process for %s" % self.name)
        self.thread.start()

    def get_fifo(self):
        return self.fifo_fn


class SizeCalculator:

    alloc_sections = ["bss", "noinit", "app_bss", "app_noinit", "ccm_bss",
                      "ccm_noinit"]
    rw_sections = ["datas", "initlevel", "exceptions", "initshell",
                   "_static_thread_area", "_k_timer_area",
                   "_k_mem_slab_area", "_k_mem_pool_area", "sw_isr_table",
                   "_k_sem_area", "_k_mutex_area", "app_shmem_regions",
                   "_k_fifo_area", "_k_lifo_area", "_k_stack_area",
                   "_k_msgq_area", "_k_mbox_area", "_k_pipe_area",
                   "net_if", "net_if_dev", "net_stack", "net_l2_data",
                   "_k_queue_area", "_net_buf_pool_area", "app_datas",
                   "kobject_data", "mmu_tables", "app_pad", "priv_stacks",
                   "ccm_data", "usb_descriptor", "usb_data", "usb_bos_desc",
                   'log_backends_sections', 'log_dynamic_sections',
                   'log_const_sections',"app_smem", 'shell_root_cmds_sections',
                   'log_const_sections',"app_smem", "font_entry_sections",
                   "priv_stacks_noinit", "_TEXT_SECTION_NAME_2",
                   '_GCOV_BSS_SECTION_NAME', 'gcov', 'nocache']

    # These get copied into RAM only on non-XIP
    ro_sections = ["text", "ctors", "init_array", "reset", "object_access",
                   "rodata", "devconfig", "net_l2", "vector", "sw_isr_table",
                   "_bt_settings_area", "vectors"]

    def __init__(self, filename, extra_sections):
        """Constructor

        @param filename Path to the output binary
            The <filename> is parsed by objdump to determine section sizes
        """
        # Make sure this is an ELF binary
        with open(filename, "rb") as f:
            magic = f.read(4)

        try:
            if (magic != b'\x7fELF'):
                raise SanityRuntimeError("%s is not an ELF binary" % filename)
        except Exception as e:
            print(str(e))
            sys.exit(2)

        # Search for CONFIG_XIP in the ELF's list of symbols using NM and AWK.
        # GREP can not be used as it returns an error if the symbol is not
        # found.
        is_xip_command = "nm " + filename + \
            " | awk '/CONFIG_XIP/ { print $3 }'"
        is_xip_output = subprocess.check_output(
            is_xip_command, shell=True, stderr=subprocess.STDOUT).decode(
            "utf-8").strip()
        try:
            if is_xip_output.endswith("no symbols"):
                raise SanityRuntimeError("%s has no symbol information" % filename)
        except Exception as e:
            print(str(e))
            sys.exit(2)

        self.is_xip = (len(is_xip_output) != 0)

        self.filename = filename
        self.sections = []
        self.rom_size = 0
        self.ram_size = 0
        self.extra_sections = extra_sections

        self._calculate_sizes()

    def get_ram_size(self):
        """Get the amount of RAM the application will use up on the device

        @return amount of RAM, in bytes
        """
        return self.ram_size

    def get_rom_size(self):
        """Get the size of the data that this application uses on device's flash

        @return amount of ROM, in bytes
        """
        return self.rom_size

    def unrecognized_sections(self):
        """Get a list of sections inside the binary that weren't recognized

        @return list of unrecognized section names
        """
        slist = []
        for v in self.sections:
            if not v["recognized"]:
                slist.append(v["name"])
        return slist

    def _calculate_sizes(self):
        """ Calculate RAM and ROM usage by section """
        objdump_command = "objdump -h " + self.filename
        objdump_output = subprocess.check_output(
            objdump_command, shell=True).decode("utf-8").splitlines()

        for line in objdump_output:
            words = line.split()

            if (len(words) == 0):               # Skip lines that are too short
                continue

            index = words[0]
            if (not index[0].isdigit()):        # Skip lines that do not start
                continue                        # with a digit

            name = words[1]                     # Skip lines with section names
            if (name[0] == '.'):                # starting with '.'
                continue

            # TODO this doesn't actually reflect the size in flash or RAM as
            # it doesn't include linker-imposed padding between sections.
            # It is close though.
            size = int(words[2], 16)
            if size == 0:
                continue

            load_addr = int(words[4], 16)
            virt_addr = int(words[3], 16)

            # Add section to memory use totals (for both non-XIP and XIP scenarios)
            # Unrecognized section names are not included in the calculations.
            recognized = True
            if name in SizeCalculator.alloc_sections:
                self.ram_size += size
                stype = "alloc"
            elif name in SizeCalculator.rw_sections:
                self.ram_size += size
                self.rom_size += size
                stype = "rw"
            elif name in SizeCalculator.ro_sections:
                self.rom_size += size
                if not self.is_xip:
                    self.ram_size += size
                stype = "ro"
            else:
                stype = "unknown"
                if name not in self.extra_sections:
                    recognized = False

            self.sections.append({"name": name, "load_addr": load_addr,
                                  "size": size, "virt_addr": virt_addr,
                                  "type": stype, "recognized": recognized})


class MakeGoal:
    """Metadata class representing one of the sub-makes called by MakeGenerator

    MakeGenerator returns a dictionary of these which can then be associated
    with TestInstances to get a complete picture of what happened during a test.
    MakeGenerator is used for tasks outside of building tests (such as
    defconfigs) which is why MakeGoal is a separate class from TestInstance.
    """

    def __init__(self, name, text, handler, make_log, build_log, run_log, handler_log):
        self.name = name
        self.text = text
        self.handler = handler
        self.make_log = make_log
        self.build_log = build_log
        self.run_log = run_log
        self.handler_log = handler_log
        self.make_state = "waiting"
        self.failed = False
        self.finished = False
        self.reason = None
        self.metrics = {}

    def get_error_log(self):
        if self.make_state == "waiting":
            # Shouldn't ever see this; breakage in the main Makefile itself.
            return self.make_log
        elif self.make_state == "building":
            # Failure when calling the sub-make to build the code
            return self.build_log
        elif self.make_state == "running":
            # Failure in sub-make for "make run", qemu probably failed to start
            return self.run_log
        elif self.make_state == "finished":
            # Execution handler finished, but timed out or otherwise wasn't successful
            return self.handler_log

    def fail(self, reason):
        self.failed = True
        self.finished = True
        self.reason = reason

    def success(self):
        self.finished = True

    def __str__(self):
        if self.finished:
            if self.failed:
                return "[%s] failed (%s: see %s)" % (self.name, self.reason,
                                                     self.get_error_log())
            else:
                return "[%s] passed" % self.name
        else:
            return "[%s] in progress (%s)" % (self.name, self.make_state)


class MakeGenerator:
    """Generates a Makefile which just calls a bunch of sub-make sessions

    In any given test suite we may need to build dozens if not hundreds of
    test cases. The cleanest way to parallelize this is to just let Make
    do the parallelization, sharing the jobserver among all the different
    sub-make targets.
    """

    GOAL_HEADER_TMPL = """.PHONY: {goal}
{goal}:
"""

    MAKE_RULE_TMPL = """\t@echo sanity_test_{phase} {goal} >&2
\tcmake  \\
\t\t-G"{generator}"\\
\t\t-H{directory}\\
\t\t-B{outdir}\\
\t\t-DEXTRA_CFLAGS="-Werror {cflags}"\\
\t\t-DEXTRA_AFLAGS=-Wa,--fatal-warnings\\
\t\t-DEXTRA_LDFLAGS="{ldflags}"\\
\t\t{args}\\
\t\t>{logfile} 2>&1
\t{generator_cmd} -C {outdir}\\
\t\t{verb} {make_args}\\
\t\t>>{logfile} 2>&1
"""
    MAKE_RULE_TMPL_RUN = """\t@echo sanity_test_{phase} {goal} >&2
\t{generator_cmd} -C {outdir}\\
\t\t{verb} {make_args}\\
\t\t>>{logfile} 2>&1
"""

    GOAL_FOOTER_TMPL = "\t@echo sanity_test_finished {goal} >&2\n\n"

    re_make = re.compile(
        "sanity_test_([A-Za-z0-9]+) (.+)|$|make[:] \*\*\* \[(.+:.+: )?(.+)\] Error.+$")

    def __init__(self, base_outdir):
        """MakeGenerator constructor

        @param base_outdir Intended to be the base out directory. A make.log
            file will be created here which contains the output of the
            top-level Make session, as well as the dynamic control Makefile
        @param verbose If true, pass V=1 to all the sub-makes which greatly
            increases their verbosity
        """
        self.goals = {}
        if not os.path.exists(base_outdir):
            os.makedirs(base_outdir)
        self.logfile = os.path.join(base_outdir, "make.log")
        self.makefile = os.path.join(base_outdir, "Makefile")
        self.deprecations = options.error_on_deprecations

    def _get_rule_header(self, name):
        return MakeGenerator.GOAL_HEADER_TMPL.format(goal=name)

    def _get_sub_make(self, name, phase, workdir, outdir,
                      logfile, args, make_args=""):
        """
        @param      args Arguments given to CMake
        @param make_args Arguments given to the Makefile generated by CMake
        """
        args = " ".join(["-D{}".format(a) for a in args])
        ldflags = ""
        cflags = ""

        if self.deprecations:
            cflags = cflags + "  -Wno-deprecated-declarations"

        ldflags="-Wl,--fatal-warnings"

        if options.ninja:
            generator = "Ninja"
            generator_cmd = "ninja -j1"
            verb = "-v" if VERBOSE else ""
        else:
            generator = "Unix Makefiles"
            generator_cmd = "$(MAKE)"
            verb = "VERBOSE=1" if VERBOSE else ""

        if phase == 'running':
            return MakeGenerator.MAKE_RULE_TMPL_RUN.format(
                generator_cmd=generator_cmd,
                phase=phase,
                goal=name,
                outdir=outdir,
                verb=verb,
                logfile=logfile,
                make_args=make_args
            )
        else:
            return MakeGenerator.MAKE_RULE_TMPL.format(
                generator=generator,
                generator_cmd=generator_cmd,
                phase=phase,
                goal=name,
                outdir=outdir,
                cflags=cflags,
                ldflags=ldflags,
                directory=workdir,
                verb=verb,
                args=args,
                logfile=logfile,
                make_args=make_args
            )

    def _get_rule_footer(self, name):
        return MakeGenerator.GOAL_FOOTER_TMPL.format(goal=name)

    def add_build_goal(self, name, directory, outdir,
                       args, buildlog, make_args=""):
        """Add a goal to invoke a build session

        @param name A unique string name for this build goal. The results
            dictionary returned by execute() will be keyed by this name.
        @param directory Absolute path to working directory, will be passed
            to make -C
        @param outdir Absolute path to output directory, will be passed to
            cmake via -B=<path>
        @param args Extra command line arguments to pass to 'cmake', typically
            environment variables or specific Make goals
        """

        if not os.path.exists(outdir):
            os.makedirs(outdir)

        build_logfile = os.path.join(outdir, buildlog)
        text = self._get_rule_header(name)
        text +=  self._get_sub_make(name, "building", directory, outdir, build_logfile,
                args, make_args=make_args)
        text += self._get_rule_footer(name)

        self.goals[name] = MakeGoal( name, text, None, self.logfile, build_logfile, None, None)

    def add_goal(self, instance, type, args, make_args=""):

        """Add a goal to build a Zephyr project and then run it using a handler

        The generated make goal invokes Make twice, the first time it will
        build the default goal, and the second will invoke the 'qemu' goal.
        The output of the handler session will be monitored, and terminated
        either upon pass/fail result of the test program, or the timeout
        is reached.

        @param args Extra cache entries to define in CMake.
        """

        name = instance.name
        directory = instance.test.test_path
        outdir = instance.outdir

        build_logfile = os.path.join(outdir, "build.log")
        run_logfile = os.path.join(outdir, "run.log")

        if not os.path.exists(outdir):
            os.makedirs(outdir)

        handler = None
        if type == "qemu":
            handler = QEMUHandler(instance)
        elif type == "native":
            handler = BinaryHandler(instance)
            handler.binary = os.path.join(outdir, "zephyr", "zephyr.exe")
            if options.enable_coverage:
                args += ["EXTRA_LDFLAGS=--coverage"]
        elif type == "nsim":
            handler = BinaryHandler(instance)
            handler.call_make_run = True
        elif type == "unit":
            handler = BinaryHandler(instance)
            handler.binary = os.path.join(outdir, "testbinary")
            if options.enable_coverage:
                args += ["EXTRA_LDFLAGS=--coverage"]
        elif type == "device":
            handler = DeviceHandler(instance)
        elif type == "renode":
            handler = BinaryHandler(instance)
            handler.pid_fn = os.path.join(instance.outdir, "renode.pid")
            handler.call_make_run = True


        if type == 'qemu':
            args.append("QEMU_PIPE=%s" % handler.get_fifo())

        text = (self._get_rule_header(name) +
                self._get_sub_make(name, "building", directory,
                                   outdir, build_logfile, args, make_args=make_args))
        if handler and handler.run:
            text += self._get_sub_make(name, "running", directory,
                                   outdir, run_logfile,
                                   args, make_args="run")

        text += self._get_rule_footer(name)

        self.goals[name] = MakeGoal(name, text, handler, self.logfile, build_logfile,
                                    run_logfile, handler.log if handler else None)


    def add_test_instance(self, ti, extra_args=[]):
        """Add a goal to build/test a TestInstance object

        @param ti TestInstance object to build. The status dictionary returned
            by execute() will be keyed by its .name field.
        """
        args = ti.test.extra_args[:]

        # merge overlay files into one variable
        overlays = ""
        idx = 0
        for a in args:
            m = re.search('OVERLAY_CONFIG="(.*)"', a)
            if m:
                overlays += m.group(1)
                del args[idx]
                idx += 1

        if len(ti.test.extra_configs) > 0 or options.coverage:
            args.append("OVERLAY_CONFIG=\"%s %s\"" %(overlays,
                        os.path.join(ti.outdir, "overlay.conf")))

        if ti.test.type == "unit" and options.enable_coverage:
            args.append("COVERAGE=1")

        args.append("BOARD={}".format(ti.platform.name))
        args.extend(extra_args)

        do_build_only = ti.build_only or options.build_only
        do_run = not do_build_only
        skip_slow = ti.test.slow and not options.enable_slow

        # FIXME: Need refactoring and cleanup
        type = None
        if ti.platform.qemu_support and do_run:
            type = "qemu"
        elif ti.test.type == "unit":
            type = "unit"
        elif ti.platform.type == "native" and do_run:
            type = "native"
        elif ti.platform.simulation == "nsim" and do_run:
            if find_executable("nsimdrv"):
                type = "nsim"
        elif ti.platform.simulation == "renode" and do_run:
            if find_executable("renode"):
                type = "renode"
        elif options.device_testing and (not ti.build_only) and (not options.build_only):
            type = "device"

        if not skip_slow:
            self.add_goal(ti, type, args)
        else:
            verbose("Skipping slow test: " + ti.name)

    def execute(self, callback_fn=None, context=None):
        """Execute all the registered build goals

        @param callback_fn If not None, a callback function will be called
            as individual goals transition between states. This function
            should accept two parameters: a string state and an arbitrary
            context object, supplied here
        @param context Context object to pass to the callback function.
            Type and semantics are specific to that callback function.
        @return A dictionary mapping goal names to final status.
        """

        with open(self.makefile, "wt") as tf, \
                open(os.devnull, "wb") as devnull, \
                open(self.logfile, "wt") as make_log:
            # Create our dynamic Makefile and execute it.
            # Watch stderr output which is where we will keep
            # track of build state
            tf.write('\n# Generated by %s which is expected\n' % __file__)
            tf.write('# to spawn qemu or testbinary, renode, etc. \n\n')
            for name, goal in sorted(self.goals.items()):
                tf.write(goal.text)
            tf.write("all: %s\n" % (" ".join(sorted(self.goals.keys()))))
            tf.flush()

            cmd = ["make", "-k", "-j", str(JOBS), "-f", tf.name, "all"]

            # assure language neutral environemnt
            make_env = os.environ.copy()
            make_env['LC_MESSAGES'] = 'C.UTF-8'
            p = subprocess.Popen(cmd, stderr=subprocess.PIPE,
                                 stdout=devnull, env=make_env)

            for line in iter(p.stderr.readline, b''):
                line = line.decode("utf-8")
                make_log.write(line)
                verbose("MAKE: " + repr(line.strip()))
                m = MakeGenerator.re_make.match(line)
                if not m:
                    continue

                state, name, _, error = m.groups()
                if error:
                    goal = self.goals[error]
                    # Sometimes QEMU will run an image and then crash out, which
                    # will cause the 'make run' invocation to exit with
                    # nonzero status.
                    # Need to distinguish this case from a compilation failure.
                    if goal.handler:
                        goal.fail("handler_crash")
                    else:
                        goal.fail("build_error")
                else:
                    goal = self.goals[name]
                    goal.make_state = state

                    if state == "finished":
                        if goal.handler:
                            if hasattr(goal.handler, "handle"):
                                goal.handler.handle()
                                goal.handler_log = goal.handler.log

                            thread_status, metrics = goal.handler.get_state()
                            goal.metrics.update(metrics)
                            if thread_status == "passed":
                                goal.success()
                            else:
                                goal.fail(thread_status)
                        else:
                            goal.success()

                if callback_fn:
                    callback_fn(context, self.goals, goal)

            p.wait()
        return self.goals


# "list" - List of strings
# "list:<type>" - List of <type>
# "set" - Set of unordered, unique strings
# "set:<type>" - Set of <type>
# "float" - Floating point
# "int" - Integer
# "bool" - Boolean
# "str" - String

# XXX Be sure to update __doc__ if you change any of this!!

platform_valid_keys = {"qemu_support": {"type": "bool", "default": False},
                       "supported_toolchains": {"type": "list", "default": []},
                       "env": {"type": "list", "default": []}
                       }

testcase_valid_keys = {"tags": {"type": "set", "required": False},
                       "type": {"type": "str", "default": "integration"},
                       "extra_args": {"type": "list"},
                       "extra_configs": {"type": "list"},
                       "build_only": {"type": "bool", "default": False},
                       "build_on_all": {"type": "bool", "default": False},
                       "skip": {"type": "bool", "default": False},
                       "slow": {"type": "bool", "default": False},
                       "timeout": {"type": "int", "default": 60},
                       "min_ram": {"type": "int", "default": 8},
                       "depends_on": {"type": "set"},
                       "min_flash": {"type": "int", "default": 32},
                       "arch_whitelist": {"type": "set"},
                       "arch_exclude": {"type": "set"},
                       "extra_sections": {"type": "list", "default": []},
                       "platform_exclude": {"type": "set"},
                       "platform_whitelist": {"type": "set"},
                       "toolchain_exclude": {"type": "set"},
                       "toolchain_whitelist": {"type": "set"},
                       "filter": {"type": "str"},
                       "harness": {"type": "str"},
                       "harness_config": {"type": "map", "default": {}}
                       }


class SanityConfigParser:
    """Class to read test case files with semantic checking
    """

    def __init__(self, filename, schema):
        """Instantiate a new SanityConfigParser object

        @param filename Source .yaml file to read
        """
        self.data = scl.yaml_load_verify(filename, schema)
        self.filename = filename
        self.tests = {}
        self.common = {}
        if 'tests' in self.data:
            self.tests = self.data['tests']
        if 'common' in self.data:
            self.common = self.data['common']

    def _cast_value(self, value, typestr):
        if isinstance(value, str):
            v = value.strip()
        if typestr == "str":
            return v

        elif typestr == "float":
            return float(value)

        elif typestr == "int":
            return int(value)

        elif typestr == "bool":
            return value

        elif typestr.startswith("list") and isinstance(value, list):
            return value
        elif typestr.startswith("list") and isinstance(value, str):
            vs = v.split()
            if len(typestr) > 4 and typestr[4] == ":":
                return [self._cast_value(vsi, typestr[5:]) for vsi in vs]
            else:
                return vs

        elif typestr.startswith("set"):
            vs = v.split()
            if len(typestr) > 3 and typestr[3] == ":":
                return set([self._cast_value(vsi, typestr[4:]) for vsi in vs])
            else:
                return set(vs)

        elif typestr.startswith("map"):
            return value
        else:
            raise ConfigurationError(
                self.filename, "unknown type '%s'" % value)

    def get_test(self, name, valid_keys):
        """Get a dictionary representing the keys/values within a test

        @param name The test in the .yaml file to retrieve data from
        @param valid_keys A dictionary representing the intended semantics
            for this test. Each key in this dictionary is a key that could
            be specified, if a key is given in the .yaml file which isn't in
            here, it will generate an error. Each value in this dictionary
            is another dictionary containing metadata:

                "default" - Default value if not given
                "type" - Data type to convert the text value to. Simple types
                    supported are "str", "float", "int", "bool" which will get
                    converted to respective Python data types. "set" and "list"
                    may also be specified which will split the value by
                    whitespace (but keep the elements as strings). finally,
                    "list:<type>" and "set:<type>" may be given which will
                    perform a type conversion after splitting the value up.
                "required" - If true, raise an error if not defined. If false
                    and "default" isn't specified, a type conversion will be
                    done on an empty string
        @return A dictionary containing the test key-value pairs with
            type conversion and default values filled in per valid_keys
        """

        d = {}
        for k, v in self.common.items():
            d[k] = v

        for k, v in self.tests[name].items():
            if k not in valid_keys:
                raise ConfigurationError(
                    self.filename,
                    "Unknown config key '%s' in definition for '%s'" %
                    (k, name))

            if k in d:
                if isinstance(d[k], str):
                    d[k] += " " + v
            else:
                d[k] = v

        for k, kinfo in valid_keys.items():
            if k not in d:
                if "required" in kinfo:
                    required = kinfo["required"]
                else:
                    required = False

                if required:
                    raise ConfigurationError(
                        self.filename,
                        "missing required value for '%s' in test '%s'" %
                        (k, name))
                else:
                    if "default" in kinfo:
                        default = kinfo["default"]
                    else:
                        default = self._cast_value("", kinfo["type"])
                    d[k] = default
            else:
                try:
                    d[k] = self._cast_value(d[k], kinfo["type"])
                except ValueError as ve:
                    raise ConfigurationError(
                        self.filename, "bad %s value '%s' for key '%s' in name '%s'" %
                        (kinfo["type"], d[k], k, name))

        return d


class Platform:
    """Class representing metadata for a particular platform

    Maps directly to BOARD when building"""

    yaml_platform_schema = scl.yaml_load(
        os.path.join(
            ZEPHYR_BASE,
            "scripts",
            "sanity_chk",
            "sanitycheck-platform-schema.yaml"))

    def __init__(self, cfile):
        """Constructor.

        @param cfile Path to platform configuration file, which gives
            info about the platform to be added.
        """
        scp = SanityConfigParser(cfile, self.yaml_platform_schema)
        data = scp.data

        self.name = data['identifier']
        self.sanitycheck = data.get("sanitycheck", True)
        # if no RAM size is specified by the board, take a default of 128K
        self.ram = data.get("ram", 128)
        testing = data.get("testing", {})
        self.ignore_tags = testing.get("ignore_tags", [])
        self.default = testing.get("default", False)
        # if no flash size is specified by the board, take a default of 512K
        self.flash = data.get("flash", 512)
        self.supported = set()
        for supp_feature in data.get("supported", []):
            for item in supp_feature.split(":"):
                self.supported.add(item)

        self.qemu_support = True if data.get('simulation', "na") == 'qemu' else False
        self.arch = data['arch']
        self.type = data.get('type', "na")
        self.simulation = data.get('simulation', "na")
        self.supported_toolchains = data.get("toolchain", [])
        self.env = data.get("env", [])
        self.env_satisfied = True
        for env in self.env:
            if os.environ.get(env, None) == None:
                self.env_satisfied = False
        self.defconfig = None
        pass

    def __repr__(self):
        return "<%s on %s>" % (self.name, self.arch)


class Architecture:
    """Class representing metadata for a particular architecture
    """

    def __init__(self, name, platforms):
        """Architecture constructor

        @param name String name for this architecture
        @param platforms list of platforms belonging to this architecture
        """
        self.platforms = platforms

        self.name = name

    def __repr__(self):
        return "<arch %s>" % self.name


class TestCase:
    """Class representing a test application
    """

    def __init__(self, testcase_root, workdir, name, tc_dict, yamlfile):
        """TestCase constructor.

        This gets called by TestSuite as it finds and reads test yaml files.
        Multiple TestCase instances may be generated from a single testcase.yaml,
        each one corresponds to an entry within that file.

        We need to have a unique name for every single test case. Since
        a testcase.yaml can define multiple tests, the canonical name for
        the test case is <workdir>/<name>.

        @param testcase_root Absolute path to the root directory where
            all the test cases live
        @param workdir Relative path to the project directory for this
            test application from the test_case root.
        @param name Name of this test case, corresponding to the entry name
            in the test case configuration file. For many test cases that just
            define one test, can be anything and is usually "test". This is
            really only used to distinguish between different cases when
            the testcase.yaml defines multiple tests
        @param tc_dict Dictionary with test values for this test case
            from the testcase.yaml file
        """
        self.test_path = os.path.join(testcase_root, workdir)

        self.id = name
        self.cases = []
        self.type = tc_dict["type"]
        self.tags = tc_dict["tags"]
        self.extra_args = tc_dict["extra_args"]
        self.extra_configs = tc_dict["extra_configs"]
        self.arch_whitelist = tc_dict["arch_whitelist"]
        self.arch_exclude = tc_dict["arch_exclude"]
        self.skip = tc_dict["skip"]
        self.platform_exclude = tc_dict["platform_exclude"]
        self.platform_whitelist = tc_dict["platform_whitelist"]
        self.toolchain_exclude = tc_dict["toolchain_exclude"]
        self.toolchain_whitelist = tc_dict["toolchain_whitelist"]
        self.tc_filter = tc_dict["filter"]
        self.timeout = tc_dict["timeout"]
        self.harness = tc_dict["harness"]
        self.harness_config = tc_dict["harness_config"]
        self.build_only = tc_dict["build_only"]
        self.build_on_all = tc_dict["build_on_all"]
        self.slow = tc_dict["slow"]
        self.min_ram = tc_dict["min_ram"]
        self.depends_on = tc_dict["depends_on"]
        self.min_flash = tc_dict["min_flash"]
        self.extra_sections = tc_dict["extra_sections"]

        self.name = self.get_unique(testcase_root, workdir, name)

        self.defconfig = {}
        self.dt_config = {}
        self.cmake_cache = {}
        self.yamlfile = yamlfile


    def get_unique(self, testcase_root, workdir, name):

        if ZEPHYR_BASE in testcase_root:
            # This is a Zephyr Test, so include path in name for uniqueness
            # FIXME: We should not depend on path of test for unique names.

            zephyr_base = os.path.join(os.path.realpath(ZEPHYR_BASE))
            short_path = os.path.normpath(testcase_root.replace(zephyr_base + "/", ""))
        else:
            short_path = ""

        unique = os.path.normpath(os.path.join(short_path, workdir, name))
        return unique

    def scan_file(self, inf_name):
        suite_regex = re.compile(
            # do not match until end-of-line, otherwise we won't allow
            # stc_regex below to catch the ones that are declared in the same
            # line--as we only search starting the end of this match
            br"^\s*ztest_test_suite\(\s*(?P<suite_name>[a-zA-Z0-9_]+)\s*,",
            re.MULTILINE)
        stc_regex = re.compile(
            br"^\s*"		# empy space at the beginning is ok
            # catch the case where it is declared in the same sentence, e.g:
            #
            # ztest_test_suite(mutex_complex, ztest_user_unit_test(TESTNAME));
            br"(?:ztest_test_suite\([a-zA-Z0-9_]+,\s*)?"
            # Catch ztest[_user]_unit_test-[_setup_teardown](TESTNAME)
            br"ztest_(?:user_)?unit_test(?:_setup_teardown)?"
            # Consume the argument that becomes the extra testcse
            br"\(\s*"
            br"(?P<stc_name>[a-zA-Z0-9_]+)"
            # _setup_teardown() variant has two extra arguments that we ignore
            br"(?:\s*,\s*[a-zA-Z0-9_]+\s*,\s*[a-zA-Z0-9_]+)?"
            br"\s*\)",
            # We don't check how it finishes; we don't care
            re.MULTILINE)
        suite_run_regex = re.compile(
            br"^\s*ztest_run_test_suite\((?P<suite_name>[a-zA-Z0-9_]+)\)",
            re.MULTILINE)
        achtung_regex = re.compile(
            br"(#ifdef|#endif)",
            re.MULTILINE)
        warnings = None

        with open(inf_name) as inf:
            with contextlib.closing(mmap.mmap(inf.fileno(), 0, mmap.MAP_PRIVATE,
                                              mmap.PROT_READ, 0)) as main_c:
                suite_regex_match = suite_regex.search(main_c)
                if not suite_regex_match:
                    # can't find ztest_test_suite, maybe a client, because
                    # it includes ztest.h
                    return None, None

                suite_run_match = suite_run_regex.search(main_c)
                if not suite_run_match:
                    raise ValueError("can't find ztest_run_test_suite")

                achtung_matches = re.findall(
                    achtung_regex,
                    main_c[suite_regex_match.end():suite_run_match.start()])
                if achtung_matches:
                    warnings = "found invalid %s in ztest_test_suite()" \
                               % ", ".join(set([
                                   match.decode() for match in achtung_matches
                               ]))
                _matches = re.findall(
                    stc_regex,
                    main_c[suite_regex_match.end():suite_run_match.start()])
                matches = [ match.decode().replace("test_", "") for match in _matches ]
                return matches, warnings

    def scan_path(self, path):
        subcases = []
        for filename in glob.glob(os.path.join(path, "src", "*.c")):
            try:
                _subcases, warnings = self.scan_file(filename)
                if warnings:
                    error("%s: %s" % (filename, warnings))
                if _subcases:
                    subcases += _subcases
            except ValueError as e:
                error("%s: can't find: %s", filename, e)
        return subcases


    def parse_subcases(self):
        results = self.scan_path(self.test_path)
        for sub in results:
            name = "{}.{}".format(self.id, sub)
            self.cases.append(name)


    def __str__(self):
        return self.name


class TestInstance:
    """Class representing the execution of a particular TestCase on a platform

    @param test The TestCase object we want to build/execute
    @param platform Platform object that we want to build and run against
    @param base_outdir Base directory for all test results. The actual
        out directory used is <outdir>/<platform>/<test case name>
    """

    def __init__(self, test, platform, base_outdir):
        self.test = test
        self.platform = platform
        self.name = os.path.join(platform.name, test.name)
        self.outdir = os.path.join(base_outdir, platform.name, test.name)

        self.build_only = options.build_only or test.build_only \
                or self.check_dependency()
        self.results = {}

    def check_dependency(self):
        build_only = False
        if self.test.harness == 'console':
            if "fixture" in self.test.harness_config:
                fixture = self.test.harness_config['fixture']
                if fixture not in options.fixture:
                    build_only = True
        elif self.test.harness:
            build_only = True

        return build_only

    def create_overlay(self, platform):
        file = os.path.join(self.outdir, "overlay.conf")
        os.makedirs(self.outdir, exist_ok=True)
        with open(file, "w") as f:
            content = ""

            if len(self.test.extra_configs) > 0:
                content = "\n".join(self.test.extra_configs)

            if options.enable_coverage:
                if platform in options.coverage_platform:
                    content = content + "\nCONFIG_COVERAGE=y"

            f.write(content)

    def calculate_sizes(self):
        """Get the RAM/ROM sizes of a test case.

        This can only be run after the instance has been executed by
        MakeGenerator, otherwise there won't be any binaries to measure.

        @return A SizeCalculator object
        """
        fns = glob.glob(os.path.join(self.outdir, "zephyr", "*.elf"))
        fns.extend(glob.glob(os.path.join(self.outdir, "zephyr", "*.exe")))
        fns = [x for x in fns if not x.endswith('_prebuilt.elf')]
        if (len(fns) != 1):
            raise BuildError("Missing/multiple output ELF binary")
        return SizeCalculator(fns[0], self.test.extra_sections)

    def __repr__(self):
        return "<TestCase %s on %s>" % (self.test.name, self.platform.name)


def defconfig_cb(context, goals, goal):
    if not goal.failed:
        return

    info("%sCould not build defconfig for %s%s" %
         (COLOR_RED, goal.name, COLOR_NORMAL))
    if INLINE_LOGS:
        with open(goal.get_error_log()) as fp:
            data = fp.read()
            sys.stdout.write(data)
            if log_file:
                log_file.write(data)
    else:
        info("\tsee: " + COLOR_YELLOW + goal.get_error_log() + COLOR_NORMAL)


class TestSuite:
    config_re = re.compile('(CONFIG_[A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$')
    dt_re = re.compile('([A-Za-z0-9_]+)[=]\"?([^\"]*)\"?$')

    yaml_tc_schema = scl.yaml_load(
        os.path.join(ZEPHYR_BASE,
                     "scripts", "sanity_chk", "sanitycheck-tc-schema.yaml"))

    def __init__(self, board_root_list, testcase_roots, outdir):
        # Keep track of which test cases we've filtered out and why
        self.arches = {}
        self.testcases = {}
        self.platforms = []
        self.outdir = os.path.abspath(outdir)
        self.instances = {}
        self.goals = None
        self.discards = None
        self.load_errors = 0

        for testcase_root in testcase_roots:
            testcase_root = os.path.abspath(testcase_root)

            debug("Reading test case configuration files under %s..." %
                  testcase_root)
            for dirpath, dirnames, filenames in os.walk(testcase_root,
                                                        topdown=True):
                verbose("scanning %s" % dirpath)
                if 'sample.yaml' in filenames:
                    filename = 'sample.yaml'
                elif 'testcase.yaml' in filenames:
                    filename = 'testcase.yaml'
                else:
                    continue

                verbose("Found possible test case in " + dirpath)
                dirnames[:] = []
                yaml_path = os.path.join(dirpath, filename)
                try:
                    parsed_data = SanityConfigParser(
                        yaml_path, self.yaml_tc_schema)

                    workdir = os.path.relpath(dirpath, testcase_root)

                    for name in parsed_data.tests.keys():
                        tc_dict = parsed_data.get_test(name, testcase_valid_keys)
                        tc = TestCase(testcase_root, workdir, name, tc_dict,
                                      yaml_path)
                        tc.parse_subcases()
                        self.testcases[tc.name] = tc

                except Exception as e:
                    error("E: %s: can't load (skipping): %s" % (yaml_path, e))
                    self.load_errors += 1


        for board_root in board_root_list:
            board_root = os.path.abspath(board_root)

            debug(
                "Reading platform configuration files under %s..." %
                board_root)
            for fn in glob.glob(os.path.join(board_root, "*", "*", "*.yaml")):
                verbose("Found plaform configuration " + fn)
                try:
                    platform = Platform(fn)
                    if platform.sanitycheck:
                        self.platforms.append(platform)
                except RuntimeError as e:
                    error("E: %s: can't load: %s" % (fn, e))
                    self.load_errors += 1

        arches = []
        for p in self.platforms:
            arches.append(p.arch)
        for a in list(set(arches)):
            aplatforms = [p for p in self.platforms if p.arch == a]
            arch = Architecture(a, aplatforms)
            self.arches[a] = arch

        self.instances = {}

    def get_platform(self, name):
        selected_platform = None
        for platform in self.platforms:
            if platform.name == name:
                selected_platform = platform
                break
        return selected_platform

    def get_last_failed(self):
        try:
            if not os.path.exists(LAST_SANITY):
                raise SanityRuntimeError("Couldn't find last sanity run.")
        except Exception as e:
            print(str(e))
            sys.exit(2)

        result = []
        with open(LAST_SANITY, "r") as fp:
            cr = csv.DictReader(fp)
            instance_list = []
            for row in cr:
                if row["passed"] == "True":
                    continue
                test = row["test"]
                platform = self.get_platform(row["platform"])
                instance = TestInstance(self.testcases[test], platform, self.outdir)
                instance.create_overlay(platform.name)
                instance_list.append(instance)
            self.add_instances(instance_list)

    def load_from_file(self, file):
        try:
            if not os.path.exists(file):
                raise SanityRuntimeError(
                    "Couldn't find input file with list of tests.")
        except Exception as e:
            print(str(e))
            sys.exit(2)

        with open(file, "r") as fp:
            cr = csv.reader(fp)
            instance_list = []
            for row in cr:
                name = os.path.join(row[0], row[1])
                platform = self.get_platform(row[2])
                instance = TestInstance(self.testcases[name], platform, self.outdir)
                instance.create_overlay(platform.name)
                instance_list.append(instance)
            self.add_instances(instance_list)

    def apply_filters(self):

        toolchain = os.environ.get("ZEPHYR_TOOLCHAIN_VARIANT", None) or \
                    os.environ.get("ZEPHYR_GCC_VARIANT", None)

        if toolchain == "gccarmemb":
            # Remove this translation when gccarmemb is no longer supported.
            toolchain = "gnuarmemb"

        try:
            if not toolchain:
                raise SanityRuntimeError("E: Variable ZEPHYR_TOOLCHAIN_VARIANT is not defined")
        except Exception as e:
            print(str(e))
            sys.exit(2)


        instances = []
        discards = {}
        platform_filter = options.platform
        testcase_filter = run_individual_tests
        arch_filter = options.arch
        tag_filter = options.tag
        exclude_tag = options.exclude_tag
        config_filter = options.config
        extra_args = options.extra_args
        all_plats = options.all

        verbose("platform filter: " + str(platform_filter))
        verbose("    arch_filter: " + str(arch_filter))
        verbose("     tag_filter: " + str(tag_filter))
        verbose("    exclude_tag: " + str(exclude_tag))
        verbose("  config_filter: " + str(config_filter))

        default_platforms = False

        if all_plats:
            info("Selecting all possible platforms per test case")
            # When --all used, any --platform arguments ignored
            platform_filter = []
        elif not platform_filter:
            info("Selecting default platforms per test case")
            default_platforms = True

        mg = MakeGenerator(self.outdir)
        defconfig_list = {}
        dt_list = {}
        cmake_list = {}
        for tc_name, tc in self.testcases.items():
            for arch_name, arch in self.arches.items():
                for plat in arch.platforms:
                    instance = TestInstance(tc, plat, self.outdir)

                    if (arch_name == "unit") != (tc.type == "unit"):
                        continue

                    if tc.build_on_all and not platform_filter:
                        platform_filter = []

                    if tc.skip:
                        continue

                    if tag_filter and not tc.tags.intersection(tag_filter):
                        continue

                    if exclude_tag and tc.tags.intersection(exclude_tag):
                        continue

                    if testcase_filter and tc_name not in testcase_filter:
                        continue

                    if arch_filter and arch_name not in arch_filter:
                        continue

                    if tc.arch_whitelist and arch.name not in tc.arch_whitelist:
                        continue

                    if tc.arch_exclude and arch.name in tc.arch_exclude:
                        continue

                    if tc.platform_exclude and plat.name in tc.platform_exclude:
                        continue

                    if tc.toolchain_exclude and toolchain in tc.toolchain_exclude:
                        continue

                    if platform_filter and plat.name not in platform_filter:
                        continue

                    if plat.ram < tc.min_ram:
                        continue

                    if set(plat.ignore_tags) & tc.tags:
                        continue

                    if tc.depends_on:
                        dep_intersection = tc.depends_on.intersection(
                            set(plat.supported))
                        if dep_intersection != set(tc.depends_on):
                            continue

                    if plat.flash < tc.min_flash:
                        continue

                    if tc.platform_whitelist and plat.name not in tc.platform_whitelist:
                        continue

                    if tc.toolchain_whitelist and toolchain not in tc.toolchain_whitelist:
                        continue

                    if (plat.env_satisfied and tc.tc_filter
                            and (plat.default or all_plats or platform_filter)
                            and (toolchain in plat.supported_toolchains or options.force_toolchain)):
                        args = tc.extra_args[:]
                        args.append("BOARD={}".format(plat.name))
                        args.extend(extra_args)
                        # FIXME would be nice to use a common outdir for this so that
                        # conf, gen_idt, etc aren't rebuilt for every  combination,
                        # need a way to avoid different Make processes from clobbering
                        # each other since they all try to build them
                        # simultaneously

                        o = os.path.join(self.outdir, plat.name, tc.name)
                        cmake_cache_path = os.path.join(o, "CMakeCache.txt")
                        generated_dt_confg = "include/generated/generated_dts_board.conf"
                        dt_config_path = os.path.join(o, "zephyr", generated_dt_confg)
                        dt_list[tc, plat, tc.name.split("/")[-1]] = dt_config_path
                        cmake_list[tc, plat, tc.name.split("/")[-1]] = cmake_cache_path
                        defconfig_list[tc, plat, tc.name.split("/")[-1]] = os.path.join(o, "zephyr", ".config")
                        goal = "_".join([plat.name, "_".join(tc.name.split("/")), "config-sanitycheck"])
                        mg.add_build_goal(goal, os.path.join(ZEPHYR_BASE, tc.test_path),
                                o, args, "config-sanitycheck.log", make_args="config-sanitycheck")

        info("Building testcase defconfigs...")
        results = mg.execute(defconfig_cb)

        for name, goal in results.items():
            try:
                if goal.failed:
                    raise SanityRuntimeError("Couldn't build some defconfigs")
            except Exception as e:
                error(str(e))
                sys.exit(2)


        for k, out_config in defconfig_list.items():
            test, plat, name = k
            defconfig = {}
            with open(out_config, "r") as fp:
                for line in fp.readlines():
                    m = TestSuite.config_re.match(line)
                    if not m:
                        if line.strip() and not line.startswith("#"):
                            sys.stderr.write("Unrecognized line %s\n" % line)
                        continue
                    defconfig[m.group(1)] = m.group(2).strip()
            test.defconfig[plat] = defconfig

        for k, cache_file in cmake_list.items():
            if not os.path.exists(out_config):
                continue

            test, plat, name = k
            cmake_conf = {}
            try:
                cache = CMakeCache.from_file(cache_file)
            except FileNotFoundError:
                cache = {}

            for k in iter(cache):
                cmake_conf[k.name] = k.value

            test.cmake_cache[plat] = cmake_conf

        for k, out_config in dt_list.items():
            if not os.path.exists(out_config):
                continue

            test, plat, name = k
            dt_conf = {}
            with open(out_config, "r") as fp:
                for line in fp.readlines():
                    m = TestSuite.dt_re.match(line)
                    if not m:
                        if line.strip() and not line.startswith("#"):
                            sys.stderr.write("Unrecognized line %s\n" % line)
                        continue
                    dt_conf[m.group(1)] = m.group(2).strip()
            test.dt_config[plat] = dt_conf

        for tc_name, tc in self.testcases.items():
            for arch_name, arch in self.arches.items():
                instance_list = []
                for plat in arch.platforms:
                    instance = TestInstance(tc, plat, self.outdir)

                    if (arch_name == "unit") != (tc.type == "unit"):
                        # Discard silently
                        continue

                    if tc.skip:
                        discards[instance] = "Skip filter"
                        continue

                    if tc.build_on_all and not platform_filter:
                        platform_filter = []

                    if tag_filter and not tc.tags.intersection(tag_filter):
                        discards[instance] = "Command line testcase tag filter"
                        continue

                    if exclude_tag and tc.tags.intersection(exclude_tag):
                        discards[instance] = "Command line testcase exclude filter"
                        continue

                    if testcase_filter and tc_name not in testcase_filter:
                        discards[instance] = "Testcase name filter"
                        continue

                    if arch_filter and arch_name not in arch_filter:
                        discards[instance] = "Command line testcase arch filter"
                        continue

                    if tc.arch_whitelist and arch.name not in tc.arch_whitelist:
                        discards[instance] = "Not in test case arch whitelist"
                        continue

                    if tc.arch_exclude and arch.name in tc.arch_exclude:
                        discards[instance] = "In test case arch exclude"
                        continue

                    if tc.platform_exclude and plat.name in tc.platform_exclude:
                        discards[instance] = "In test case platform exclude"
                        continue

                    if tc.toolchain_exclude and toolchain in tc.toolchain_exclude:
                        discards[instance] = "In test case toolchain exclude"
                        continue

                    if platform_filter and plat.name not in platform_filter:
                        discards[instance] = "Command line platform filter"
                        continue

                    if tc.platform_whitelist and plat.name not in tc.platform_whitelist:
                        discards[instance] = "Not in testcase platform whitelist"
                        continue

                    if tc.toolchain_whitelist and toolchain not in tc.toolchain_whitelist:
                        discards[instance] = "Not in testcase toolchain whitelist"
                        continue

                    if not plat.env_satisfied:
                        discards[instance] = "Environment ({}) not satisfied".format(", ".join(plat.env))
                        continue

                    if not options.force_toolchain \
                        and toolchain and (toolchain not in plat.supported_toolchains) \
                        and tc.type != 'unit':
                        discards[instance] = "Not supported by the toolchain"
                        continue

                    if plat.ram < tc.min_ram:
                        discards[instance] = "Not enough RAM"
                        continue

                    if tc.depends_on:
                        dep_intersection = tc.depends_on.intersection(set(plat.supported))
                        if dep_intersection != set(tc.depends_on):
                            discards[instance] = "No hardware support"
                            continue

                    if plat.flash < tc.min_flash:
                        discards[instance] = "Not enough FLASH"
                        continue

                    if set(plat.ignore_tags) & tc.tags:
                        discards[instance] = "Excluded tags per platform"
                        continue

                    defconfig = {
                            "ARCH": arch.name,
                            "PLATFORM": plat.name
                            }
                    defconfig.update(os.environ)
                    for p, tdefconfig in tc.defconfig.items():
                        if p == plat:
                            defconfig.update(tdefconfig)
                            break

                    for p, tdefconfig in tc.dt_config.items():
                        if p == plat:
                            defconfig.update(tdefconfig)
                            break

                    for p, tdefconfig in tc.cmake_cache.items():
                        if p == plat:
                            defconfig.update(tdefconfig)
                            break

                    if tc.tc_filter:
                        try:
                            res = expr_parser.parse(tc.tc_filter, defconfig)
                        except (ValueError, SyntaxError) as se:
                            sys.stderr.write(
                                "Failed processing %s\n" % tc.yamlfile)
                            raise se
                        if not res:
                            discards[instance] = (
                                "defconfig doesn't satisfy expression '%s'" %
                                tc.tc_filter)
                            continue

                    instance_list.append(instance)

                if not instance_list:
                    # Every platform in this arch was rejected already
                    continue

                if default_platforms and not tc.build_on_all:
                    if not tc.platform_whitelist:
                        instances = list(
                            filter(
                                lambda tc: tc.platform.default,
                                instance_list))
                        self.add_instances(instances)
                    else:
                        self.add_instances(instance_list[:1])

                    for instance in list(
                            filter(lambda tc: not tc.platform.default, instance_list)):
                        discards[instance] = "Not a default test platform"
                else:
                    self.add_instances(instance_list)

                for name, case in self.instances.items():
                    case.create_overlay(case.platform.name)

        self.discards = discards
        return discards

    def add_instances(self, ti_list):
        for ti in ti_list:
            self.instances[ti.name] = ti

    def execute(self, cb, cb_context):

        def calc_one_elf_size(name, goal):
            if not goal.failed:
                if self.instances[name].platform.type != "native":
                    i = self.instances[name]
                    sc = i.calculate_sizes()
                    goal.metrics["ram_size"] = sc.get_ram_size()
                    goal.metrics["rom_size"] = sc.get_rom_size()
                    goal.metrics["unrecognized"] = sc.unrecognized_sections()
                else:
                    goal.metrics["ram_size"] = 0
                    goal.metrics["rom_size"] = 0
                    goal.metrics["unrecognized"] = []

        mg = MakeGenerator(self.outdir)
        for i in self.instances.values():
            mg.add_test_instance(i, options.extra_args)
        self.goals = mg.execute(cb, cb_context)

        if not options.disable_size_report:
            # Parallelize size calculation
            executor = concurrent.futures.ThreadPoolExecutor(JOBS)
            futures = [executor.submit(calc_one_elf_size, name, goal)
                       for name, goal in self.goals.items()]
            concurrent.futures.wait(futures)
        else:
            for goal in self.goals.values():
                goal.metrics["ram_size"] = 0
                goal.metrics["rom_size"] = 0
                goal.metrics["unrecognized"] = []

        return self.goals

    def save_tests(self, filename):
        with open(filename, "at") as csvfile:
            fieldnames = ['path', 'test', 'platform', 'arch']
            cw = csv.DictWriter(csvfile, fieldnames, lineterminator=os.linesep)
            for instance in self.instances.values():
                rowdict = {
                    "path": os.path.dirname(instance.test.name),
                    "test": os.path.basename(instance.test.name),
                    "platform": instance.platform.name,
                    "arch": instance.platform.arch
                }
                cw.writerow(rowdict)

    def discard_report(self, filename):

        try:
            if self.discards is None:
                raise SanityRuntimeError("apply_filters() hasn't been run!")
        except Exception as e:
            error(str(e))
            sys.exit(2)

        with open(filename, "wt") as csvfile:
            fieldnames = ["test", "arch", "platform", "reason"]
            cw = csv.DictWriter(csvfile, fieldnames, lineterminator=os.linesep)
            cw.writeheader()
            for instance, reason in self.discards.items():
                rowdict = {"test": instance.test.name,
                           "arch": instance.platform.arch,
                           "platform": instance.platform.name,
                           "reason": reason}
                cw.writerow(rowdict)

    def compare_metrics(self, filename):
        # name, datatype, lower results better
        interesting_metrics = [("ram_size", int, True),
                               ("rom_size", int, True)]

        try:
            if self.goals is None:
                raise SanityRuntimeError("execute() hasn't been run!")
        except Exception as e:
            print(str(e))
            sys.exit(2)

        if not os.path.exists(filename):
            info("Cannot compare metrics, %s not found" % filename)
            return []

        results = []
        saved_metrics = {}
        with open(filename) as fp:
            cr = csv.DictReader(fp)
            for row in cr:
                d = {}
                for m, _, _ in interesting_metrics:
                    d[m] = row[m]
                saved_metrics[(row["test"], row["platform"])] = d

        for name, goal in self.goals.items():
            i = self.instances[name]
            mkey = (i.test.name, i.platform.name)
            if mkey not in saved_metrics:
                continue
            sm = saved_metrics[mkey]
            for metric, mtype, lower_better in interesting_metrics:
                if metric not in goal.metrics:
                    continue
                if sm[metric] == "":
                    continue
                delta = goal.metrics[metric] - mtype(sm[metric])
                if delta == 0:
                    continue
                results.append((i, metric, goal.metrics[metric], delta,
                                lower_better))
        return results



    def encode_for_xml(self, unicode_data, encoding='ascii'):
        unicode_data = unicode_data.replace('\x00', '')
        return unicode_data

    def testcase_target_report(self, report_file):

        run = "Sanitycheck"
        eleTestsuite = None
        append = options.only_failed

        errors = 0
        passes = 0
        fails = 0
        duration = 0
        skips = 0

        for identifier, ti in self.instances.items():
            for k in ti.results.keys():
                if ti.results[k] == 'PASS':
                    passes += 1
                elif ti.results[k] == 'BLOCK':
                    errors += 1
                elif ti.results[k] == 'SKIP':
                    skips += 1
                else:
                    fails += 1

        eleTestsuites = ET.Element('testsuites')
        eleTestsuite = ET.SubElement(eleTestsuites, 'testsuite',
                                     name=run, time="%d" % duration,
                                     tests="%d" % (errors + passes + fails),
                                     failures="%d" % fails,
                                     errors="%d" % errors, skipped="%d" %skips)

        handler_time = "0"

        # print out test results
        for identifier, ti in self.instances.items():
            for k in ti.results.keys():

                eleTestcase = ET.SubElement(
                        eleTestsuite, 'testcase', classname="%s:%s" %(ti.platform.name, os.path.basename(ti.test.name)),
                        name="%s" % (k), time=handler_time)
                if ti.results[k] in ['FAIL', 'BLOCK']:
                    el = None

                    if ti.results[k] == 'FAIL':
                        el = ET.SubElement(
                            eleTestcase,
                            'failure',
                            type="failure",
                            message="failed")
                    elif ti.results[k] == 'BLOCK':
                        el = ET.SubElement(
                            eleTestcase,
                            'error',
                            type="failure",
                            message="failed")
                    p = os.path.join(options.outdir, ti.platform.name, ti.test.name)
                    bl = os.path.join(p, "handler.log")

                    if os.path.exists(bl):
                        with open(bl, "rb") as f:
                            log = f.read().decode("utf-8")
                            el.text = self.encode_for_xml(log)

                elif ti.results[k] == 'SKIP':
                    el = ET.SubElement(
                        eleTestcase,
                        'skipped',
                        type="skipped",
                        message="Skipped")

        result = ET.tostring(eleTestsuites)
        f = open(report_file, 'wb')
        f.write(result)
        f.close()


    def testcase_xunit_report(self, filename, duration):
        try:
            if self.goals is None:
                raise SanityRuntimeError("execute() hasn't been run!")
        except Exception as e:
            print(str(e))
            sys.exit(2)

        fails = 0
        passes = 0
        errors = 0

        for name, goal in self.goals.items():
            if goal.failed:
                if goal.reason in ['build_error', 'handler_crash']:
                    errors += 1
                else:
                    fails += 1
            else:
                passes += 1

        run = "Sanitycheck"
        eleTestsuite = None
        append = options.only_failed

        if os.path.exists(filename) and append:
            tree = ET.parse(filename)
            eleTestsuites = tree.getroot()
            eleTestsuite = tree.findall('testsuite')[0]
        else:
            eleTestsuites = ET.Element('testsuites')
            eleTestsuite = ET.SubElement(eleTestsuites, 'testsuite',
                                         name=run, time="%d" % duration,
                                         tests="%d" % (errors + passes + fails),
                                         failures="%d" % fails,
                                         errors="%d" % errors, skip="0")

        handler_time = "0"
        for name, goal in self.goals.items():

            i = self.instances[name]
            if append:
                for tc in eleTestsuite.findall('testcase'):
                    if tc.get('classname') == "%s:%s" % (
                            i.platform.name, i.test.name):
                        eleTestsuite.remove(tc)

            if not goal.failed and goal.handler:
                handler_time = "%s" %(goal.metrics["handler_time"])

            eleTestcase = ET.SubElement(
                eleTestsuite, 'testcase', classname="%s:%s" %
                (i.platform.name, i.test.name), name="%s" %
                (name), time=handler_time)
            if goal.failed:
                failure = ET.SubElement(
                    eleTestcase,
                    'failure',
                    type="failure",
                    message=goal.reason)
                p = ("%s/%s/%s" % (options.outdir, i.platform.name, i.test.name))
                bl = os.path.join(p, "build.log")
                hl = os.path.join(p, "handler.log")
                log_file = bl
                if goal.reason != 'build_error':
                    if os.path.exists(hl):
                        log_file = hl
                    else:
                        log_file = bl

                if os.path.exists(log_file):
                    with open(log_file, "rb") as f:
                        log = f.read().decode("utf-8")
                        filtered_string = ''.join(filter(lambda x: x in string.printable, log))
                        failure.text = filtered_string
                        f.close()

        result = ET.tostring(eleTestsuites)
        f = open(filename, 'wb')
        f.write(result)
        f.close()

    def testcase_report(self, filename):
        try:
            if self.goals is None:
                raise SanityRuntimeError("execute() hasn't been run!")
        except Exception as e:
            print(str(e))
            sys.exit(2)

        with open(filename, "wt") as csvfile:
            fieldnames = ["test", "arch", "platform", "passed", "status",
                          "extra_args", "qemu", "handler_time", "ram_size",
                          "rom_size"]
            cw = csv.DictWriter(csvfile, fieldnames, lineterminator=os.linesep)
            cw.writeheader()
            for name, goal in self.goals.items():
                i = self.instances[name]
                rowdict = {"test": i.test.name,
                           "arch": i.platform.arch,
                           "platform": i.platform.name,
                           "extra_args": " ".join(i.test.extra_args),
                           "qemu": i.platform.qemu_support}
                if goal.failed:
                    rowdict["passed"] = False
                    rowdict["status"] = goal.reason
                else:
                    rowdict["passed"] = True
                    if goal.handler:
                        rowdict["handler_time"] = goal.metrics["handler_time"]
                    rowdict["ram_size"] = goal.metrics["ram_size"]
                    rowdict["rom_size"] = goal.metrics["rom_size"]
                cw.writerow(rowdict)


def parse_arguments():

    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.fromfile_prefix_chars = "+"

    case_select = parser.add_argument_group("Test case selection",
                                            """
Artificially long but functional example:
    $ ./scripts/sanitycheck -v     \\
      --testcase-root tests/     \\
      --testcase-root mytests/   \\
      --test      tests/ztest/base/testing.ztest.verbose_0  \\
      --test      tests/kernel/fifo/fifo_api/kernel.fifo.poll

   "kernel.fifo.poll" is one of the test section names in
                                 __/fifo_api/testcase.yaml
    """)

    parser.add_argument("--force-toolchain", action="store_true",
            help="Do not filter based on toolchain, use the set "
            " toolchain unconditionally")
    parser.add_argument(
        "-p", "--platform", action="append",
        help="Platform filter for testing. This option may be used multiple "
        "times. Testcases will only be built/run on the platforms "
        "specified. If this option is not used, then platforms marked "
        "as default in the platform metadata file will be chosen "
        "to build and test. ")
    parser.add_argument(
        "-a", "--arch", action="append",
        help="Arch filter for testing. Takes precedence over --platform. "
        "If unspecified, test all arches. Multiple invocations "
        "are treated as a logical 'or' relationship")
    parser.add_argument(
        "-t", "--tag", action="append",
        help="Specify tags to restrict which tests to run by tag value. "
        "Default is to not do any tag filtering. Multiple invocations "
        "are treated as a logical 'or' relationship")
    parser.add_argument("-e", "--exclude-tag", action="append",
                        help="Specify tags of tests that should not run. "
                        "Default is to run all tests with all tags.")
    case_select.add_argument(
        "-f",
        "--only-failed",
        action="store_true",
        help="Run only those tests that failed the previous sanity check "
        "invocation.")
    parser.add_argument(
        "-c", "--config", action="append",
        help="Specify platform configuration values filtering. This can be "
        "specified two ways: <config>=<value> or just <config>. The "
        "defconfig for all platforms will be "
        "checked. For the <config>=<value> case, only match defconfig "
        "that have that value defined. For the <config> case, match "
        "defconfig that have that value assigned to any value. "
        "Prepend a '!' to invert the match.")

    test_xor_subtest = case_select.add_mutually_exclusive_group()

    test_xor_subtest.add_argument(
        "-s", "--test", action="append",
        help="Run only the specified test cases. These are named by "
        "path/relative/to/Zephyr/base/section.name.in.testcase.yaml>")

    test_xor_subtest.add_argument(
        "--sub-test", action="append",
        help="""Recursively find sub-test functions and run the entire
        test section where they were found, including all sibling test
        functions. Sub-tests are named by:
        section.name.in.testcase.yaml.function_name_without_test_prefix
        Example: kernel.fifo.poll.fifo_loop
        """)

    parser.add_argument(
        "-l", "--all", action="store_true",
        help="Build/test on all platforms. Any --platform arguments "
        "ignored.")

    parser.add_argument(
        "-o", "--testcase-report",
        help="Output a CSV spreadsheet containing results of the test run")
    parser.add_argument(
        "-d", "--discard-report",
        help="Output a CSV spreadsheet showing tests that were skipped "
        "and why")
    parser.add_argument("--compare-report",
                        help="Use this report file for size comparison")

    parser.add_argument(
        "-B", "--subset",
        help="Only run a subset of the tests, 1/4 for running the first 25%%, "
        "3/5 means run the 3rd fifth of the total. "
        "This option is useful when running a large number of tests on "
        "different hosts to speed up execution time.")

    parser.add_argument(
        "-N", "--ninja", action="store_true",
        help="Use the Ninja generator with CMake")

    parser.add_argument(
        "-y", "--dry-run", action="store_true",
        help="Create the filtered list of test cases, but don't actually "
        "run them. Useful if you're just interested in "
        "--discard-report")

    parser.add_argument("--list-tags", action="store_true",
            help="list all tags in selected tests")

    case_select.add_argument("--list-tests", action="store_true",
        help="""List of all sub-test functions recursively found in
        all --testcase-root arguments. Note different sub-tests can share
        the same section name and come from different directories.
        The output is flattened and reports --sub-test names only,
        not their directories. For instance net.socket.getaddrinfo_ok
        and net.socket.fd_set belong to different directories.
        """)

    parser.add_argument("--export-tests", action="store",
            metavar="FILENAME",
            help="Export tests case meta-data to a file in CSV format.")

    parser.add_argument("--detailed-report",
            action="store",
            metavar="FILENAME",
            help="Generate a junit report with detailed testcase results.")

    parser.add_argument(
        "-r", "--release", action="store_true",
        help="Update the benchmark database with the results of this test "
        "run. Intended to be run by CI when tagging an official "
        "release. This database is used as a basis for comparison "
        "when looking for deltas in metrics such as footprint")
    parser.add_argument("-w", "--warnings-as-errors", action="store_true",
                        help="Treat warning conditions as errors")
    parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        default=0,
        help="Emit debugging information, call multiple times to increase "
        "verbosity")
    parser.add_argument(
        "-i", "--inline-logs", action="store_true",
        help="Upon test failure, print relevant log data to stdout "
        "instead of just a path to it")
    parser.add_argument("--log-file", metavar="FILENAME", action="store",
                        help="log also to file")
    parser.add_argument(
        "-m", "--last-metrics", action="store_true",
        help="Instead of comparing metrics from the last --release, "
        "compare with the results of the previous sanity check "
        "invocation")
    parser.add_argument(
        "-u",
        "--no-update",
        action="store_true",
        help="do not update the results of the last run of the sanity "
        "checks")
    case_select.add_argument(
        "-F",
        "--load-tests",
        metavar="FILENAME",
        action="store",
        help="Load list of tests and platforms to be run from file.")

    case_select.add_argument(
        "-E",
        "--save-tests",
        metavar="FILENAME",
        action="store",
        help="Append list of tests and platforms to be run to file.")

    parser.add_argument(
        "-b", "--build-only", action="store_true",
        help="Only build the code, do not execute any of it in QEMU")
    parser.add_argument(
        "-j", "--jobs", type=int,
        help="Number of jobs for building, defaults to number of CPU threads "
        "overcommited by factor 2")

    parser.add_argument(
        "--device-testing", action="store_true",
        help="Test on device directly. Specify the serial device to "
             "use with the --device-serial option.")

    parser.add_argument(
        "-X", "--fixture", action="append", default=[],
        help="Specify a fixture that a board might support")
    parser.add_argument(
        "--device-serial",
		help="Serial device for accessing the board (e.g., /dev/ttyACM0)")
    parser.add_argument(
            "--show-footprint", action="store_true",
            help="Show footprint statistics and deltas since last release."
            )
    parser.add_argument(
        "-H", "--footprint-threshold", type=float, default=5,
        help="When checking test case footprint sizes, warn the user if "
        "the new app size is greater then the specified percentage "
        "from the last release. Default is 5. 0 to warn on any "
        "increase on app size")
    parser.add_argument(
        "-D", "--all-deltas", action="store_true",
        help="Show all footprint deltas, positive or negative. Implies "
        "--footprint-threshold=0")
    parser.add_argument(
        "-O", "--outdir",
        default="%s/sanity-out" % os.getcwd(),
        help="Output directory for logs and binaries. "
        "Default is 'sanity-out' in the current directory. "
        "This directory will be deleted unless '--no-clean' is set.")
    parser.add_argument(
        "-n", "--no-clean", action="store_true",
        help="Do not delete the outdir before building. Will result in "
        "faster compilation since builds will be incremental")
    case_select.add_argument(
        "-T", "--testcase-root", action="append", default=[],
        help="Base directory to recursively search for test cases. All "
        "testcase.yaml files under here will be processed. May be "
        "called multiple times. Defaults to the 'samples/' and "
        "'tests/' directories at the base of the Zephyr tree.")

    board_root_list = ["%s/boards" % ZEPHYR_BASE,
                       "%s/scripts/sanity_chk/boards" % ZEPHYR_BASE]

    parser.add_argument(
        "-A", "--board-root", action="append", default=board_root_list,
        help="Directory to search for board configuration files. All .yaml "
        "files in the directory will be processed.")
    parser.add_argument(
        "-z", "--size", action="append",
        help="Don't run sanity  checks. Instead, produce a report to "
        "stdout detailing RAM/ROM sizes on the specified filenames. "
        "All other command line arguments ignored.")
    parser.add_argument(
        "-S", "--enable-slow", action="store_true",
        help="Execute time-consuming test cases that have been marked "
        "as 'slow' in testcase.yaml. Normally these are only built.")
    parser.add_argument(
        "--disable-unrecognized-section-test", action="store_true",
        default=False,
        help="Skip the 'unrecognized section' test.")
    parser.add_argument("-R", "--enable-asserts", action="store_true",
                        default=True,
                        help="deprecated, left for compatibility")
    parser.add_argument("--disable-asserts", action="store_false",
                        dest="enable_asserts",
                        help="deprecated, left for compatibility")
    parser.add_argument("-Q", "--error-on-deprecations", action="store_false",
                        help="Error on deprecation warnings.")
    parser.add_argument("--disable-size-report", action="store_true",
                        help="Skip expensive computation of ram/rom segment sizes.")

    parser.add_argument(
        "-x", "--extra-args", action="append", default=[],
        help="""Extra CMake cache entries to define when building test cases.
        May be called multiple times. The key-value entries will be
        prefixed with -D before being passed to CMake.

        E.g
        "sanitycheck -x=USE_CCACHE=0"
        will translate to
        "cmake -DUSE_CCACHE=0"

        which will ultimately disable ccache.
        """
    )
    parser.add_argument("--gcov-tool", default="gcov",
                        help="Path to the gcov tool. Default is gcov in the path.")

    parser.add_argument("--enable-coverage", action="store_true",
                        help="Enable code coverage using gcov.")

    parser.add_argument("-C", "--coverage", action="store_true",
                        help="Generate coverage reports. Implies --enable_coverage")

    coverage_platforms = ["native_posix", "nrf52_bsim"]
    parser.add_argument("--coverage-platform", action="append", default=coverage_platforms,
                        help="Plarforms to run coverage reports on. "
                        "This option may be used multiple times.")

    return parser.parse_args()


def log_info(filename):
    filename = os.path.relpath(os.path.realpath(filename))
    if INLINE_LOGS:
        info("{:-^100}".format(filename))

        try:
            with open(filename) as fp:
                data = fp.read()
        except Exception as e:
            data = "Unable to read log data (%s)\n" % (str(e))

        sys.stdout.write(data)
        if log_file:
            log_file.write(data)
        info("{:-^100}".format(filename))
    else:
        info("\tsee: " + COLOR_YELLOW + filename + COLOR_NORMAL)


def terse_test_cb(instances, goals, goal):
    total_tests = len(goals)
    total_done = 0
    total_failed = 0

    for k, g in goals.items():
        if g.finished:
            total_done += 1
        if g.failed:
            total_failed += 1

    if goal.failed:
        i = instances[goal.name]
        info(
            "\n\n{:<25} {:<50} {}FAILED{}: {}".format(
                i.platform.name,
                i.test.name,
                COLOR_RED,
                COLOR_NORMAL,
                goal.reason))
        log_info(goal.get_error_log())
        info("")

    sys.stdout.write(
        "\rtotal complete: %s%4d/%4d%s  %2d%%  failed: %s%4d%s" %
        (COLOR_GREEN, total_done, total_tests, COLOR_NORMAL,
         int((float(total_done) / total_tests) * 100),
         COLOR_RED if total_failed > 0 else COLOR_NORMAL, total_failed,
         COLOR_NORMAL))
    sys.stdout.flush()


def chatty_test_cb(instances, goals, goal):
    i = instances[goal.name]

    if VERBOSE < 2 and not goal.finished:
        return

    total_tests = len(goals)
    total_tests_width = len(str(total_tests))
    total_done = 0

    for k, g in goals.items():
        if g.finished:
            total_done += 1

    if goal.failed:
        status = COLOR_RED + "FAILED" + COLOR_NORMAL + ": " + goal.reason
    elif goal.finished:
        status = COLOR_GREEN + "PASSED" + COLOR_NORMAL
    else:
        status = goal.make_state

    info("{:>{}}/{} {:<25} {:<50} {}".format(
        total_done, total_tests_width, total_tests, i.platform.name,
        i.test.name, status))
    if goal.failed:
        log_info(goal.get_error_log())


def size_report(sc):
    info(sc.filename)
    info("SECTION NAME             VMA        LMA     SIZE  HEX SZ TYPE")
    for i in range(len(sc.sections)):
        v = sc.sections[i]

        info("%-17s 0x%08x 0x%08x %8d 0x%05x %-7s" %
             (v["name"], v["virt_addr"], v["load_addr"], v["size"], v["size"],
              v["type"]))

    info("Totals: %d bytes (ROM), %d bytes (RAM)" %
         (sc.rom_size, sc.ram_size))
    info("")

def retrieve_gcov_data(intput_file):
    if VERBOSE:
        print("Working on %s" %intput_file)
    extracted_coverage_info = {}
    capture_data = False
    capture_complete = False
    with open(intput_file, 'r') as fp:
        for line in fp.readlines():
            if re.search("GCOV_COVERAGE_DUMP_START", line):
                capture_data = True
                continue
            if re.search("GCOV_COVERAGE_DUMP_END", line):
                capture_complete = True
                break
            # Loop until the coverage data is found.
            if not capture_data:
                continue
            if line.startswith("*"):
                sp = line.split("<")
                if len(sp) > 1:
                    # Remove the leading delimiter "*"
                    file_name = sp[0][1:]
                    # Remove the trailing new line char
                    hex_dump = sp[1][:-1]
                else:
                    continue
            else:
                continue
            extracted_coverage_info.update({file_name:hex_dump})
    if not capture_data:
        capture_complete = True
    return {'complete': capture_complete, 'data': extracted_coverage_info}

def create_gcda_files(extracted_coverage_info):
    if VERBOSE:
        print("Generating gcda files")
    for filename, hexdump_val in extracted_coverage_info.items():
        # if kobject_hash is given for coverage gcovr fails
        # hence skipping it problem only in gcovr v4.1
        if "kobject_hash" in filename:
            filename = (filename[:-4]) +"gcno"
            try:
                os.remove(filename)
            except:
                pass
            continue

        with open(filename, 'wb') as fp:
            fp.write(bytes.fromhex(hexdump_val))

def generate_coverage(outdir, ignores):

    for filename in glob.glob("%s/**/handler.log" %outdir, recursive=True):
        gcov_data = retrieve_gcov_data(filename)
        capture_complete = gcov_data['complete']
        extracted_coverage_info = gcov_data['data']
        if capture_complete:
            create_gcda_files(extracted_coverage_info)
            verbose("Gcov data captured: {}".format(filename))
        else:
            error("Gcov data capture incomplete: {}".format(filename))

    gcov_tool = options.gcov_tool

    with open(os.path.join(outdir, "coverage.log"), "a") as coveragelog:
        coveragefile = os.path.join(outdir, "coverage.info")
        ztestfile = os.path.join(outdir, "ztest.info")
        subprocess.call(["lcov", "--gcov-tool", gcov_tool,
                            "--capture", "--directory", outdir,
                            "--rc", "lcov_branch_coverage=1",
                            "--output-file", coveragefile], stdout=coveragelog)
        # We want to remove tests/* and tests/ztest/test/* but save tests/ztest
        subprocess.call(["lcov", "--gcov-tool", gcov_tool, "--extract", coveragefile,
                         os.path.join(ZEPHYR_BASE, "tests", "ztest", "*"),
                         "--output-file", ztestfile,
                         "--rc", "lcov_branch_coverage=1"], stdout=coveragelog)

        if os.path.exists(ztestfile) and os.path.getsize(ztestfile) > 0:
            subprocess.call(["lcov", "--gcov-tool", gcov_tool, "--remove", ztestfile,
                             os.path.join(ZEPHYR_BASE, "tests/ztest/test/*"),
                             "--output-file", ztestfile,
                             "--rc", "lcov_branch_coverage=1"],
                             stdout=coveragelog)
            files = [coveragefile, ztestfile];
        else:
            files = [coveragefile];

        for i in ignores:
            subprocess.call(
                ["lcov", "--gcov-tool", gcov_tool, "--remove",
                    coveragefile, i, "--output-file",
                    coveragefile, "--rc", "lcov_branch_coverage=1"],
                stdout=coveragelog)

        #The --ignore-errors source option is added to avoid it exiting due to
        #samples/application_development/external_lib/
        ret = subprocess.call(["genhtml", "--legend", "--branch-coverage",
                               "--ignore-errors", "source",
                               "-output-directory",
                               os.path.join(outdir, "coverage")] + files,
                               stdout=coveragelog)
        if ret==0:
            info("HTML report generated: %s"%
                 os.path.join(outdir, "coverage","index.html"));


def main():
    start_time = time.time()
    global VERBOSE, INLINE_LOGS, JOBS, log_file
    global options
    global run_individual_tests
    options = parse_arguments()

    if options.coverage:
        options.enable_coverage = True

    if options.size:
        for fn in options.size:
            size_report(SizeCalculator(fn, []))
        sys.exit(0)


    if options.device_testing:
        if options.device_serial is None or len(options.platform) != 1:
            sys.exit(1)

    VERBOSE += options.verbose
    INLINE_LOGS = options.inline_logs
    if options.log_file:
        log_file = open(options.log_file, "w")

    if options.jobs:
        JOBS = options.jobs

    # Decrease JOBS for Ninja, if jobs weren't explicitly set
    if options.ninja and not options.jobs:
        JOBS = int(JOBS * 0.75)

    info("JOBS: %d" % JOBS);

    if options.subset:
        subset, sets = options.subset.split("/")
        if int(subset) > 0 and int(sets) >= int(subset):
            info("Running only a subset: %s/%s" % (subset, sets))
        else:
            error("You have provided a wrong subset value: %s." % options.subset)
            return

    if os.path.exists(options.outdir) and not options.no_clean:
        info("Cleaning output directory " + options.outdir)
        shutil.rmtree(options.outdir)

    if not options.testcase_root:
        options.testcase_root = [os.path.join(ZEPHYR_BASE, "tests"),
                              os.path.join(ZEPHYR_BASE, "samples")]

    ts = TestSuite(options.board_root, options.testcase_root, options.outdir)

    if ts.load_errors:
        sys.exit(1)

    if options.list_tags:
        tags = set()
        for n,tc in ts.testcases.items():
            tags = tags.union(tc.tags)

        for t in tags:
            print("- {}".format(t))

        return


    def export_tests(filename, tests):
        with open(filename, "wt") as csvfile:
            fieldnames = ['section', 'subsection', 'title', 'reference']
            cw = csv.DictWriter(csvfile, fieldnames, lineterminator=os.linesep)
            for test in tests:
                data = test.split(".")
                subsec = " ".join(data[1].split("_")).title()
                rowdict = {
                        "section": data[0].capitalize(),
                        "subsection": subsec,
                        "title": test,
                        "reference": test
                        }
                cw.writerow(rowdict)

    if options.export_tests:
        cnt = 0
        unq = []
        for n,tc in ts.testcases.items():
            for c in tc.cases:
                unq.append(c)

        tests = sorted(set(unq))
        export_tests(options.export_tests, tests)
        return

    run_individual_tests = []

    if options.test:
        run_individual_tests = options.test

    if options.list_tests or options.sub_test:
        cnt = 0
        unq = []
        run_individual_tests = []
        for n,tc in ts.testcases.items():
            for c in tc.cases:
                if options.sub_test and c in options.sub_test:
                    if tc.name not in run_individual_tests:
                        run_individual_tests.append(tc.name)
                unq.append(c)

        if options.sub_test:
            if run_individual_tests:
                info("Running the following tests:")
                for t in run_individual_tests:
                    print(" - {}".format(t))
            else:
                info("Tests not found")
                return

        elif options.list_tests:
            for u in sorted(set(unq)):
                cnt = cnt + 1
                print(" - {}".format(u))
            print("{} total.".format(cnt))
            return

    discards = []
    if options.load_tests:
        ts.load_from_file(options.load_tests)
    elif options.only_failed:
        ts.get_last_failed()
    else:
        discards = ts.apply_filters()

    if options.discard_report:
        ts.discard_report(options.discard_report)

    if VERBOSE > 1 and discards:
        # if we are using command line platform filter, no need to list every
        # other platform as excluded, we know that already.
        # Show only the discards that apply to the selected platforms on the
        # command line

        for i, reason in discards.items():
            if options.platform and i.platform.name not in options.platform:
                continue
            debug(
                "{:<25} {:<50} {}SKIPPED{}: {}".format(
                    i.platform.name,
                    i.test.name,
                    COLOR_YELLOW,
                    COLOR_NORMAL,
                    reason))


    def native_and_unit_first(a, b):
        if a[0].startswith('unit_testing'):
            return -1
        if b[0].startswith('unit_testing'):
            return 1
        if a[0].startswith('native_posix'):
            return -1
        if b[0].startswith('native_posix'):
            return 1
        if a[0].split("/",1)[0].endswith("_bsim"):
            return -1
        if b[0].split("/",1)[0].endswith("_bsim"):
            return 1

        return (a > b) - (a < b)

    ts.instances = OrderedDict(sorted(ts.instances.items(),
                               key=cmp_to_key(native_and_unit_first)))

    if options.save_tests:
        ts.save_tests(options.save_tests)
        return

    if options.subset:

        subset, sets = options.subset.split("/")
        total = len(ts.instances)
        per_set = round(total / int(sets))
        start = (int(subset) - 1) * per_set
        if subset == sets:
            end = total
        else:
            end = start + per_set

        sliced_instances = islice(ts.instances.items(), start, end)
        ts.instances = OrderedDict(sliced_instances)

    info("%d tests selected, %d tests discarded due to filters" %
         (len(ts.instances), len(discards)))

    if options.dry_run:
        return

    if VERBOSE or not TERMINAL:
        goals = ts.execute(
            chatty_test_cb,
            ts.instances)
    else:
        goals = ts.execute(
            terse_test_cb,
            ts.instances)
        info("")

    if options.detailed_report:
        ts.testcase_target_report(options.detailed_report)

    # figure out which report to use for size comparison
    if options.compare_report:
        report_to_use = options.compare_report
    elif options.last_metrics:
        report_to_use = LAST_SANITY
    else:
        report_to_use = RELEASE_DATA

    deltas = ts.compare_metrics(report_to_use)
    warnings = 0
    if deltas and options.show_footprint:
        for i, metric, value, delta, lower_better in deltas:
            if not options.all_deltas and ((delta < 0 and lower_better) or
                                        (delta > 0 and not lower_better)):
                continue

            percentage = (float(delta) / float(value - delta))
            if not options.all_deltas and (percentage <
                                        (options.footprint_threshold / 100.0)):
                continue

            info("{:<25} {:<60} {}{}{}: {} {:<+4}, is now {:6} {:+.2%}".format(
                 i.platform.name, i.test.name, COLOR_YELLOW,
                 "INFO" if options.all_deltas else "WARNING", COLOR_NORMAL,
                 metric, delta, value, percentage))
            warnings += 1

    if warnings:
        info("Deltas based on metrics from last %s" %
             ("release" if not options.last_metrics else "run"))

    failed = 0
    for name, goal in goals.items():
        if goal.failed:
            failed += 1
        elif goal.metrics.get("unrecognized") and not options.disable_unrecognized_section_test:
            info("%sFAILED%s: %s has unrecognized binary sections: %s" %
                 (COLOR_RED, COLOR_NORMAL, goal.name,
                  str(goal.metrics["unrecognized"])))
            failed += 1

    if options.coverage:
        info("Generating coverage files...")
        generate_coverage(options.outdir, ["*generated*", "tests/*", "samples/*"])

    duration = time.time() - start_time
    info("%s%d of %d%s tests passed with %s%d%s warnings in %d seconds" %
         (COLOR_RED if failed else COLOR_GREEN, len(goals) - failed,
          len(goals), COLOR_NORMAL, COLOR_YELLOW if warnings else COLOR_NORMAL,
          warnings, COLOR_NORMAL, duration))

    if options.testcase_report:
        ts.testcase_report(options.testcase_report)
    if not options.no_update:
        ts.testcase_xunit_report(LAST_SANITY_XUNIT, duration)
        ts.testcase_report(LAST_SANITY)
    if options.release:
        ts.testcase_report(RELEASE_DATA)
    if log_file:
        log_file.close()
    if failed or (warnings and options.warnings_as_errors):
        sys.exit(1)


if __name__ == "__main__":
    main()
