#!/usr/bin/env python3
# vim: set syntax=python ts=4 :
# SPDX-License-Identifier: Apache-2.0
"""Zephyr Sanity Tests

Also check the "User and Developer Guides" at https://docs.zephyrproject.org/

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 any available emulators or simulators on the system.

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 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 emulator 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="stm32f107xc" then

        filter = CONFIG_SOC : "stm.*"

    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 examining the discard report (sanitycheck_discard.csv)
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
import contextlib
import string
import mmap
import argparse
import sys
import re
import subprocess
import multiprocessing
import select
import shutil
import shlex
import signal
import threading
import concurrent.futures
from threading import BoundedSemaphore
import queue
import time
import datetime
import csv
import yaml
import glob
import serial
import concurrent
import xml.etree.ElementTree as ET
from collections import OrderedDict
from itertools import islice
from pathlib import Path
from distutils.spawn import find_executable

ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
if not ZEPHYR_BASE:
    sys.exit("$ZEPHYR_BASE environment variable undefined")

sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "dts"))
import edtlib

import logging


hw_map_local = threading.Lock()
report_lock = threading.Lock()


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

# Use this for internal comparisons; that's what canonicalization is
# for. Don't use it when invoking other components of the build system
# to avoid confusing and hard to trace inconsistencies in error messages
# and logs, generated Makefiles, etc. compared to when users invoke these
# components directly.
# Note "normalization" is different from canonicalization, see os.path.
canonical_zephyr_base = os.path.realpath(ZEPHYR_BASE)

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

from sanity_chk import scl
from sanity_chk import expr_parser


VERBOSE = 0

RELEASE_DATA = os.path.join(ZEPHYR_BASE, "scripts", "sanity_chk",
                            "sanity_last_release.csv")

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_ in ['STRING','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):
        SanityCheckException.__init__(self, cfile + ": " + message)

class BuildError(SanityCheckException):
    pass


class ExecutionError(SanityCheckException):
    pass


log_file = None

# Debug Functions
def info(what, show_time=True):
    if options.timestamps and show_time:
        date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        what = "{}: {}".format(date, what)
    sys.stdout.write(what + "\n")
    sys.stdout.flush()
    if log_file:
        log_file.write(what + "\n")
        log_file.flush()


def error(what):
    if options.timestamps:
        date = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
        what = "{}: {}".format(date, 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, type_str="build"):
        """Constructor

        """
        self.lock = threading.Lock()

        self.state = "waiting"
        self.run = False
        self.duration = 0
        self.type_str = type_str

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

        self.name = instance.name
        self.instance = instance
        self.timeout = instance.testcase.timeout
        self.sourcedir = instance.testcase.source_dir
        self.build_dir = instance.build_dir
        self.log = os.path.join(self.build_dir, "handler.log")
        self.returncode = 0
        self.set_state("running", self.duration)

        self.args = []

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

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

    def record(self, harness):
        if harness.recording:
            filename = os.path.join(options.outdir,
                    self.instance.platform.name,
                    self.instance.testcase.name, "recording.csv")
            with open(filename, "at") as csvfile:
                cw = csv.writer(csvfile, harness.fieldnames, lineterminator=os.linesep)
                cw.writerow(harness.fieldnames)
                for instance in harness.recording:
                    cw.writerow(instance)

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

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

        self.terminated = False

    def try_kill_process_by_pid(self):
        if self.pid_fn:
            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.testcase.harness.capitalize()
        harness_import = HarnessImporter(harness_name)
        harness = harness_import.instance
        harness.configure(self.instance)

        if self.call_make_run:
            command = [get_generator()[0], "run"]
        else:
            command = [self.binary]

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

        verbose("Spawning process: " +
                " ".join(shlex.quote(word) for word in command) + os.linesep +
                "Spawning process in directory: " + self.build_dir)

        start_time = time.time()

        env = os.environ.copy()
        if options.enable_asan:
            env["ASAN_OPTIONS"] = "log_path=stdout:" + \
                    env.get("ASAN_OPTIONS", "")
            if not options.enable_lsan:
                env["ASAN_OPTIONS"] += "detect_leaks=0"
        with subprocess.Popen(command, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE, cwd=self.build_dir, env=env) as proc:
            verbose("Spawning BinaryHandler Thread for %s" % self.name)
            t = threading.Thread(target=self._output_reader, args=(proc, harness, ), daemon=True)
            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

        handler_time = time.time() - start_time

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

        self.try_kill_process_by_pid()

        # FIXME: 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 not self.terminated 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("failed", handler_time)
            self.instance.reason = "Handler Error"
        elif run_valgrind and self.returncode == 2:
            self.set_state("failed", handler_time)
            self.instance.reason = "Valgrind error"
        elif harness.state:
            self.set_state(harness.state, handler_time)
        else:
            self.set_state("timeout", handler_time)
            self.instance.reason = "Handler timeout"

        self.record(harness)

class DeviceHandler(Handler):

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

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

        self.suite = None

    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.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 device_is_available(self, device):
        for i in self.suite.connected_hardware:
            if i['platform'] == device and i['available'] and i['connected']:
                return True

        return False

    def get_available_device(self, device):
        for i in self.suite.connected_hardware:
            if i['platform'] == device and i['available']:
                i['available'] = False
                i['counter'] += 1
                return i

        return None

    def make_device_available(self, serial):
        with hw_map_local:
            for i in self.suite.connected_hardware:
                if i['serial'] == serial:
                    i['available'] = True

    def handle(self):
        out_state = "failed"

        if options.west_flash:
            command = ["west", "flash", "--skip-rebuild", "-d", self.build_dir]
            if options.west_runner:
                command.append("--runner")
                command.append(options.west_runner)
            # There are three ways this option is used.
            # 1) bare: --west-flash
            #    This results in options.west_flash == []
            # 2) with a value: --west-flash="--board-id=42"
            #    This results in options.west_flash == "--board-id=42"
            # 3) Multiple values: --west-flash="--board-id=42,--erase"
            #    This results in options.west_flash == "--board-id=42 --erase"
            if options.west_flash != []:
                command.append('--')
                command.extend(options.west_flash.split(','))
        else:
            command = [get_generator()[0], "-C", self.build_dir, "flash"]


        while not self.device_is_available(self.instance.platform.name):
            time.sleep(1)

        hardware = self.get_available_device(self.instance.platform.name)

        runner = hardware.get('runner', None)
        if runner:
            board_id = hardware.get("probe_id", hardware.get("id", None))
            product = hardware.get("product", None)
            command = ["west", "flash", "--skip-rebuild", "-d", self.build_dir]
            command.append("--runner")
            command.append(hardware.get('runner', None))
            if runner == "pyocd":
                command.append("--board-id")
                command.append(board_id)
            elif runner == "nrfjprog":
                command.append('--')
                command.append("--snr")
                command.append(board_id)
            elif runner == "openocd" and product == "STM32 STLink":
                command.append('--')
                command.append("--cmd-pre-init")
                command.append("hla_serial %s" %(board_id))
            elif runner == "openocd" and product == "EDBG CMSIS-DAP":
                command.append('--')
                command.append("--cmd-pre-init")
                command.append("cmsis_dap_serial %s" %(board_id))
            elif runner == "jlink":
                command.append("--tool-opt=-SelectEmuBySN  %s" %(board_id))

        serial_device = hardware['serial']

        try:
            ser = serial.Serial(
                    serial_device,
                    baudrate=115200,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS,
                    timeout=self.timeout
                    )
        except serial.SerialException as e:
            self.set_state("failed", 0)
            error("Serial device err: %s" %(str(e)))
            self.make_device_available(serial_device)
            return

        ser.flush()

        harness_name = self.instance.testcase.harness.capitalize()
        harness_import = HarnessImporter(harness_name)
        harness = harness_import.instance
        harness.configure(self.instance)
        read_pipe, write_pipe = os.pipe()
        start_time = time.time()

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

        logging.debug('Flash command: %s', command)
        try:
            if VERBOSE and not runner:
                subprocess.check_call(command)
            else:
                subprocess.check_output(command, stderr=subprocess.PIPE)

        except subprocess.CalledProcessError:
            os.write(write_pipe, 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.testcase.cases:
                if c not in harness.tests:
                    harness.tests[c] = "BLOCK"

        handler_time = time.time() - start_time

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

        self.make_device_available(serial_device)

        self.record(harness)

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.
    """


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

        @param instance Test instance
        """

        super().__init__(instance, type_str)
        self.fifo_fn = os.path.join(instance.build_dir, "qemu-fifo")

        self.pid_fn = os.path.join(instance.build_dir, "qemu.pid")


    @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

        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 to catch anything
                # printed late. We wait much longer if code
                # coverage is enabled since dumping this information can
                # take some time.
                if not timeout_extended or harness.capture_coverage:
                    timeout_extended= True
                    if harness.capture_coverage:
                        timeout_time = time.time() + 30
                    else:
                        timeout_time = time.time() + 2
            line = ""

        handler.record(harness)

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

        log_out_fp.close()
        out_fp.close()
        in_fp.close()
        if os.path.exists(pid_fn):
            pid = int(open(pid_fn).read())
            os.unlink(pid_fn)

            try:
                if pid:
                    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 handle(self):
        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(self.instance.build_dir, "qemu-fifo")

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

        self.log_fn = self.log

        harness_import = HarnessImporter(self.instance.testcase.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.build_dir,
                                             self.log_fn, self.fifo_fn,
                                             self.pid_fn, self.results, harness))

        self.instance.results = harness.tests
        self.thread.daemon = True
        verbose("Spawning QEMUHandler Thread for %s" % self.name)
        self.thread.start()
        subprocess.call(["stty", "sane"])

        verbose("Running %s (%s)" %(self.name, self.type_str))
        command = [get_generator()[0]]
        command += ["-C", self.build_dir, "run"]

        with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.build_dir) as proc:
            verbose("Spawning QEMUHandler Thread for %s" % self.name)
            proc.wait()
            self.returncode = proc.returncode

        if self.returncode != 0:
            self.set_state("failed", 0)
            self.instance.reason = "Exited with {}".format(self.returncode)

    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',
        "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",
        "_settings_handlers_area",
        "_bt_channels_area",
        "_bt_br_channels_area",
        "_bt_services_area",
        "vectors",
        "net_socket_register",
        "net_ppp_proto"
        ]

    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 not words:               # 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})


# "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 = {
                       "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 = {}
        self.schema = schema
        self.filename = filename
        self.tests = {}
        self.common = {}

    def load(self):
        self.data = scl.yaml_load_verify(self.filename, self.schema)

        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 {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):
                    # By default, we just concatenate string values of keys
                    # which appear both in "common" and per-test sections,
                    # but some keys are handled in adhoc way based on their
                    # semantics.
                    if k == "filter":
                        d[k] = "(%s) and (%s)" % (d[k], v)
                    else:
                        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:
                    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"""

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

    def __init__(self):
        """Constructor.

        """

        self.name = ""
        self.sanitycheck = True
        # if no RAM size is specified by the board, take a default of 128K
        self.ram = 128

        self.ignore_tags = []
        self.default = False
        # if no flash size is specified by the board, take a default of 512K
        self.flash = 512
        self.supported = set()

        self.arch = ""
        self.type = "na"
        self.simulation = "na"
        self.supported_toolchains = []
        self.env = []
        self.env_satisfied = True
        self.filter_data = dict()

    def load(self, platform_file):
        scp = SanityConfigParser(platform_file, self.platform_schema)
        scp.load()
        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.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 not os.environ.get(env, None):
                self.env_satisfied = False


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

class TestCase(object):
    """Class representing a test application
    """


    def __init__(self):
        """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 os.path.abspath() of one of the --testcase-root
        @param workdir Sub-directory of testcase_root where the
            .yaml test configuration file was found
        @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.id = ""
        self.source_dir = ""
        self.yamlfile = ""
        self.cases = []
        self.name = ""

        self.type = None
        self.tags = None
        self.extra_args = None
        self.extra_configs = None
        self.arch_whitelist = None
        self.arch_exclude = None
        self.skip = None
        self.platform_exclude = None
        self.platform_whitelist = None
        self.toolchain_exclude = None
        self.toolchain_whitelist = None
        self.tc_filter = None
        self.timeout = 60
        self.harness = ""
        self.harness_config = {}
        self.build_only = True
        self.build_on_all = False
        self.slow = False
        self.min_ram = None
        self.depends_on = None
        self.min_flash = None
        self.extra_sections = None


    @staticmethod
    def get_unique(testcase_root, workdir, name):

        canonical_testcase_root = os.path.realpath(testcase_root)
        if Path(canonical_zephyr_base) in Path(canonical_testcase_root).parents:
            # This is in ZEPHYR_BASE, so include path in name for uniqueness
            # FIXME: We should not depend on path of test for unique names.
            relative_tc_root = os.path.relpath(canonical_testcase_root,
                                         start=canonical_zephyr_base)
        else:
            relative_tc_root = ""

        # workdir can be "."
        unique = os.path.normpath(os.path.join(relative_tc_root, workdir, name))
        return unique

    @staticmethod
    def scan_file(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_(?:1cpu_)?(?: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:
            if os.name == 'nt':
                mmap_args = {'fileno':inf.fileno(), 'length':0, 'access':mmap.ACCESS_READ}
            else:
                mmap_args = {'fileno':inf.fileno(), 'length':0, 'flags':mmap.MAP_PRIVATE, 'prot':mmap.PROT_READ, 'offset':0}

            with contextlib.closing(mmap.mmap(**mmap_args)) as main_c:
                # contextlib makes pylint think main_c isn't subscriptable
                # pylint: disable=unsubscriptable-object

                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({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, test_path):
        results = self.scan_path(test_path)
        for sub in results:
            name = "{}.{}".format(self.id, sub)
            self.cases.append(name)

        if not results:
            self.cases.append(self.id)


    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, testcase, platform, base_outdir):

        self.testcase = testcase
        self.platform = platform

        self.status = None
        self.reason = "N/A"
        self.metrics = dict()
        self.handler = None


        self.name = os.path.join(platform.name, testcase.name)
        self.build_dir = os.path.join(base_outdir, platform.name, testcase.name)

        self.build_only = self.check_build_or_run()
        self.run = not self.build_only

        self.results = {}

    def __lt__(self, other):
        return self.name < other.name

    def check_build_or_run(self):
        # right now we only support building on windows. running is still work
        # in progress.

        if os.name == 'nt':
            return True

        build_only = True

        # we asked for build-only on the command line
        if options.build_only:
            return True

        # The testcase is designed to be build only.
        if self.testcase.build_only:
            return True

        # Do not run slow tests:
        skip_slow = self.testcase.slow and not options.enable_slow
        if skip_slow:
            return True

        runnable =bool(self.testcase.type == "unit" or \
            self.platform.type == "native" or \
            self.platform.simulation in ["nsim", "renode", "qemu"] or \
            options.device_testing)

        if self.platform.simulation == "nsim":
            if not find_executable("nsimdrv"):
                runnable = False

        if self.platform.simulation == "renode":
            if not find_executable("renode"):
                runnable = False

        # console harness allows us to run the test and capture data.
        if self.testcase.harness == 'console':

            # if we have a fixture that is also being supplied on the
            # command-line, then we need to run the test, not just build it.
            if "fixture" in self.testcase.harness_config:
                fixture = self.testcase.harness_config['fixture']
                if fixture in options.fixture:
                    build_only = False
                else:
                    build_only = True
            else:
                build_only = False
        elif self.testcase.harness:
            build_only = True
        else:
            build_only = False

        return not (not build_only and runnable)

    def create_overlay(self, platform):
        # Create this in a "sanitycheck/" subdirectory otherwise this
        # will pass this overlay to kconfig.py *twice* and kconfig.cmake
        # will silently give that second time precedence over any
        # --extra-args=CONFIG_*
        subdir = os.path.join(self.build_dir, "sanitycheck")
        os.makedirs(subdir, exist_ok=True)
        file = os.path.join(subdir, "testcase_extra.conf")
        with open(file, "w") as f:
            content = ""

            if self.testcase.extra_configs:
                content = "\n".join(self.testcase.extra_configs)

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

            if options.enable_asan:
                if platform.type == "native":
                    content = content + "\nCONFIG_ASAN=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.build_dir, "zephyr", "*.elf"))
        fns.extend(glob.glob(os.path.join(self.build_dir, "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.testcase.extra_sections)

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


class CMake():

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

    def __init__(self, testcase, platform, source_dir, build_dir):

        self.cwd = None
        self.capture_output = True

        self.defconfig = {}
        self.cmake_cache = {}

        self.instance = None
        self.testcase = testcase
        self.platform = platform
        self.source_dir = source_dir
        self.build_dir = build_dir
        self.log = "build.log"

    def parse_generated(self):
        self.defconfig = {}
        return {}

    def run_build(self, args=[]):

        verbose("Building %s for %s" % (self.source_dir, self.platform.name))

        cmake_args = []
        cmake_args.extend(args)
        cmake = shutil.which('cmake')
        cmd = [cmake] + cmake_args
        kwargs = dict()

        if self.capture_output:
            kwargs['stdout'] = subprocess.PIPE
            # CMake sends the output of message() to stderr unless it's STATUS
            kwargs['stderr'] = subprocess.STDOUT

        if self.cwd:
            kwargs['cwd'] = self.cwd

        p = subprocess.Popen(cmd, **kwargs)
        out, _ = p.communicate()

        results = {}
        if p.returncode == 0:
            msg = "Finished building %s for %s" %(self.source_dir, self.platform.name)

            self.instance.status = "passed"
            results = {'msg': msg, "returncode": p.returncode, "instance": self.instance}

            if out:
                log_msg = out.decode(sys.getdefaultencoding())
                with open(os.path.join(self.build_dir, self.log), "a") as log:
                    log.write(log_msg)

            else:
                return None
        else:
            # A real error occurred, raise an exception
            if out:
                log_msg = out.decode(sys.getdefaultencoding())
                with open(os.path.join(self.build_dir, self.log), "a") as log:
                    log.write(log_msg)

            overflow_flash = "region `FLASH' overflowed by"
            overflow_ram = "region `RAM' overflowed by"

            if log_msg:
                if log_msg.find(overflow_flash) > 0 or log_msg.find(overflow_ram) > 0:
                    verbose("RAM/ROM Overflow")
                    self.instance.status = "skipped"
                    self.instance.reason = "overflow"
                else:
                    self.instance.status = "failed"
                    self.instance.reason = "Build failure"

            results = {
                    "returncode": p.returncode,
                    "instance": self.instance,
                    }

        return results

    def run_cmake(self, args=[]):

        verbose("Running cmake on %s for %s" %(self.source_dir, self.platform.name))

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

        #fixme: add additional cflags based on options
        cmake_args = [
                '-B{}'.format(self.build_dir),
                '-S{}'.format(self.source_dir),
                '-DEXTRA_CFLAGS="-Werror ',
                '-DEXTRA_AFLAGS=-Wa,--fatal-warnings',
                '-DEXTRA_LDFLAGS="{}'.format(ldflags),
                '-G{}'.format(get_generator()[1])
                ]

        args = ["-D{}".format(a.replace('"', '')) for a in args]
        cmake_args.extend(args)

        cmake_opts = ['-DBOARD={}'.format(self.platform.name)]
        cmake_args.extend(cmake_opts)

        cmake = shutil.which('cmake')
        cmd = [cmake] + cmake_args
        kwargs = dict()

        if self.capture_output:
            kwargs['stdout'] = subprocess.PIPE
            # CMake sends the output of message() to stderr unless it's STATUS
            kwargs['stderr'] = subprocess.STDOUT

        if self.cwd:
            kwargs['cwd'] = self.cwd

        p = subprocess.Popen(cmd, **kwargs)
        out, _ = p.communicate()

        if p.returncode == 0:
            filter_results = self.parse_generated()
            msg = "Finished building %s for %s" %(self.source_dir, self.platform.name)

            results = {'msg': msg, 'filter': filter_results}

        else:
            self.instance.status = "failed"
            self.instance.reason = "Cmake build failure"
            results = {"returncode": p.returncode}


        if out:
            with open(os.path.join(self.build_dir, self.log), "a") as log:
                log_msg = out.decode(sys.getdefaultencoding())
                log.write(log_msg)

        return results


class FilterBuilder(CMake):

    def __init__(self, testcase, platform, source_dir, build_dir):
        super().__init__(testcase, platform, source_dir, build_dir)

        self.log = "config-sanitycheck.log"

    def parse_generated(self):

        if self.platform.name == "unit_testing":
            return {}

        cmake_cache_path = os.path.join(self.build_dir, "CMakeCache.txt")
        defconfig_path = os.path.join(self.build_dir, "zephyr", ".config")

        with open(defconfig_path, "r") as fp:
            defconfig = {}
            for line in fp.readlines():
                m = self.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()

        self.defconfig = defconfig

        cmake_conf = {}
        try:
            cache = CMakeCache.from_file(cmake_cache_path)
        except FileNotFoundError:
            cache = {}

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

        self.cmake_cache = cmake_conf

        filter_data = {
            "ARCH": self.platform.arch,
            "PLATFORM": self.platform.name
        }
        filter_data.update(os.environ)
        filter_data.update(self.defconfig)
        filter_data.update(self.cmake_cache)

        dts_path = os.path.join(self.build_dir, "zephyr", self.platform.name + ".dts.pre.tmp")
        if self.testcase and self.testcase.tc_filter:
            try:
                if os.path.exists(dts_path):
                    edt = edtlib.EDT(dts_path, [os.path.join(ZEPHYR_BASE, "dts", "bindings")])
                else:
                    edt = None
                res = expr_parser.parse(self.testcase.tc_filter, filter_data, edt)

            except (ValueError, SyntaxError) as se:
                sys.stderr.write(
                    "Failed processing %s\n" % self.testcase.yamlfile)
                raise se

            if not res:
                return {os.path.join(self.platform.name, self.testcase.name): True}
            else:
                return {os.path.join(self.platform.name, self.testcase.name): False}
        else:
            self.platform.filter_data = filter_data
            return filter_data


class ProjectBuilder(FilterBuilder):

    def __init__(self, suite, instance):
        super().__init__(instance.testcase, instance.platform, instance.testcase.source_dir, instance.build_dir)

        self.log = "build.log"
        self.instance = instance
        self.suite = suite

    def setup_handler(self):

        instance = self.instance
        args = []

        # FIXME: Needs simplification
        if instance.platform.simulation == "qemu":
            instance.handler = QEMUHandler(instance, "qemu")
            args.append("QEMU_PIPE=%s" % instance.handler.get_fifo())
            instance.handler.call_make_run = True
        elif instance.testcase.type == "unit":
            instance.handler = BinaryHandler(instance, "unit")
            instance.handler.binary = os.path.join(instance.build_dir, "testbinary")
        elif instance.platform.type == "native":
            instance.handler = BinaryHandler(instance, "native")
            instance.handler.binary = os.path.join(instance.build_dir, "zephyr", "zephyr.exe")
        elif instance.platform.simulation == "nsim":
            if find_executable("nsimdrv"):
                instance.handler = BinaryHandler(instance, "nsim")
                instance.handler.call_make_run = True
        elif instance.platform.simulation == "renode":
            if find_executable("renode"):
                instance.handler = BinaryHandler(instance, "renode")
                instance.handler.pid_fn = os.path.join(instance.build_dir, "renode.pid")
                instance.handler.call_make_run = True
        elif options.device_testing:
            instance.handler = DeviceHandler(instance, "device")

        if instance.handler:
            instance.handler.args = args

    def process(self, message):
        op = message.get('op')

        if not self.instance.handler:
            self.setup_handler()

        # The build process, call cmake and build with configured generator
        if op == "cmake":
            results = self.cmake()
            if self.instance.status == "failed":
                pipeline.put({"op": "report", "test": self.instance})
            elif options.cmake_only:
                pipeline.put({"op": "report", "test": self.instance})
            else:
                if self.instance.name in results['filter'] and results['filter'][self.instance.name]:
                    verbose("filtering %s" % self.instance.name)
                    self.instance.status = "skipped"
                    self.instance.reason = "filter"
                    pipeline.put({"op": "report", "test": self.instance})
                else:
                    pipeline.put({"op": "build", "test": self.instance})


        elif op == "build":
            verbose("build test: %s" %self.instance.name)
            results = self.build()

            if results.get('returncode', 1) > 0:
                pipeline.put({"op": "report", "test": self.instance})
            else:
                if self.instance.run:
                    pipeline.put({"op": "run", "test": self.instance})
                else:
                    pipeline.put({"op": "report", "test": self.instance})
        # Run the generated binary using one of the supported handlers
        elif op == "run":
            verbose("run test: %s" %self.instance.name)
            self.run()
            self.instance.status, _ = self.instance.handler.get_state()
            pipeline.put({
                "op": "report",
                "test": self.instance,
                "state": "executed",
                "status": self.instance.status,
                "reason": self.instance.reason}
                )

        # Report results and output progress to screen
        elif op == "report":
            with report_lock:
                self.report_out()

    def report_out(self):
        total_tests_width = len(str(self.suite.total_tests))
        self.suite.total_done += 1
        instance = self.instance

        if instance.status in ["failed", "timeout"]:
            self.suite.total_failed += 1
            if VERBOSE or not TERMINAL:
                status = COLOR_RED + "FAILED " + COLOR_NORMAL + instance.reason
            else:
                info(
                    "\n{:<25} {:<50} {}FAILED{}: {}".format(
                        instance.platform.name,
                        instance.testcase.name,
                        COLOR_RED,
                        COLOR_NORMAL,
                        instance.reason), False)
            if not VERBOSE:
                log_info_file(instance)
        elif instance.status == "skipped":
            self.suite.total_skipped += 1
            status = COLOR_YELLOW + "SKIPPED" + COLOR_NORMAL
        else:
            status = COLOR_GREEN + "PASSED" + COLOR_NORMAL

        if VERBOSE or not TERMINAL:
            if options.cmake_only:
                more_info = "cmake"
            elif instance.status == "skipped":
                more_info = instance.reason
            else:
                if instance.handler and instance.run:
                    more_info = instance.handler.type_str
                    htime = instance.handler.duration
                    if htime:
                        more_info += " {:.3f}s".format(htime)
                else:
                    more_info = "build"

            info("{:>{}}/{} {:<25} {:<50} {} ({})".format(
                self.suite.total_done, total_tests_width, self.suite.total_tests, instance.platform.name,
                instance.testcase.name, status, more_info))

            if instance.status in ["failed", "timeout"]:
                log_info_file(instance)
        else:
            sys.stdout.write("\rtotal complete: %s%4d/%4d%s  %2d%%  skipped: %s%4d%s, failed: %s%4d%s" % (
                        COLOR_GREEN,
                        self.suite.total_done,
                        self.suite.total_tests,
                        COLOR_NORMAL,
                        int((float(self.suite.total_done) / self.suite.total_tests) * 100),
                        COLOR_YELLOW if self.suite.total_skipped > 0 else COLOR_NORMAL,
                        self.suite.total_skipped,
                        COLOR_NORMAL,
                        COLOR_RED if self.suite.total_failed > 0 else COLOR_NORMAL,
                        self.suite.total_failed,
                        COLOR_NORMAL
                        )
                    )
        sys.stdout.flush()

    def cmake(self):

        instance = self.instance
        args = self.testcase.extra_args[:]

        if options.extra_args:
            args += options.extra_args

        if instance.handler:
            args += instance.handler.args

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

        if (self.testcase.extra_configs or options.coverage or
                options.enable_asan):
            args.append("OVERLAY_CONFIG=\"%s %s\"" %(overlays,
                        os.path.join(instance.build_dir,
                                     "sanitycheck", "testcase_extra.conf")))

        results = self.run_cmake(args)
        return results

    def build(self):
        results = self.run_build(['--build', self.build_dir])
        return results

    def run(self):

        instance = self.instance

        if instance.handler.type_str == "device":
            instance.handler.suite = self.suite

        instance.handler.handle()

        sys.stdout.flush()


pipeline = queue.LifoQueue()

class BoundedExecutor(concurrent.futures.ThreadPoolExecutor):
    """BoundedExecutor behaves as a ThreadPoolExecutor which will block on
    calls to submit() once the limit given as "bound" work items are queued for
    execution.
    :param bound: Integer - the maximum number of items in the work queue
    :param max_workers: Integer - the size of the thread pool
    """
    def __init__(self, bound, max_workers, **kwargs):
        super().__init__(max_workers)
        #self.executor = ThreadPoolExecutor(max_workers=max_workers)
        self.semaphore = BoundedSemaphore(bound + max_workers)

    def submit(self, fn, *args, **kwargs):
        self.semaphore.acquire()
        try:
            future = super().submit(fn, *args, **kwargs)
        except:
            self.semaphore.release()
            raise
        else:
            future.add_done_callback(lambda x: self.semaphore.release())
            return future


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

    tc_schema = scl.yaml_load(
        os.path.join(ZEPHYR_BASE,
                     "scripts", "sanity_chk", "testcase-schema.yaml"))

    def __init__(self, board_root_list, testcase_roots, outdir):

        self.roots = testcase_roots
        if not isinstance(board_root_list, list):
            self.board_roots= [board_root_list]
        else:
            self.board_roots = board_root_list

        # Keep track of which test cases we've filtered out and why
        self.testcases = {}
        self.platforms = []
        self.default_platforms = []
        self.outdir = os.path.abspath(outdir)
        self.discards = None
        self.load_errors = 0
        self.instances = dict()

        self.total_tests = 0 # number of test instances
        self.total_cases = 0 # number of test cases
        self.total_done = 0 # tests completed
        self.total_failed = 0
        self.total_skipped = 0

        self.total_platforms = 0
        self.start_time = 0
        self.duration = 0
        self.warnings = 0
        self.cv = threading.Condition()

        # hardcoded for now
        self.connected_hardware = []


        if options.jobs:
            self.jobs = options.jobs
        elif options.build_only:
            self.jobs = multiprocessing.cpu_count() * 2
        else:
            self.jobs = multiprocessing.cpu_count()

        info("JOBS: %d" % self.jobs)

    def update(self):
        self.total_tests = len(self.instances)
        self.total_cases = len(self.testcases)


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


        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 instance in self.instances.values():
            mkey = (instance.testcase.name, instance.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 instance.metrics:
                    continue
                if sm[metric] == "":
                    continue
                delta = instance.metrics.get(metric, 0) - mtype(sm[metric])
                if delta == 0:
                    continue
                results.append((instance, metric, instance.metrics.get(metric, 0 ), delta,
                                lower_better))
        return results

    def misc_reports(self, report, show_footprint, all_deltas,
                     footprint_threshold, last_metrics):

        if not report:
            return

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

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

                info("{:<25} {:<60} {}{}{}: {} {:<+4}, is now {:6} {:+.2%}".format(
                     i.platform.name, i.testcase.name, COLOR_YELLOW,
                     "INFO" if 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 last_metrics else "run"))

    def summary(self, unrecognized_sections):
        failed = 0
        for instance in self.instances.values():
            if instance.status == "failed":
                failed += 1
            elif instance.metrics.get("unrecognized") and not unrecognized_sections:
                info("%sFAILED%s: %s has unrecognized binary sections: %s" %
                     (COLOR_RED, COLOR_NORMAL, instance.name,
                      str(instance.metrics.get("unrecognized", []))))
                failed += 1

        if self.total_tests and self.total_tests != self.total_skipped:
            pass_rate = (float(self.total_tests - self.total_failed - self.total_skipped)/ float(self.total_tests - self.total_skipped))
        else:
            pass_rate = 0

        info("{}{} of {}{} tests passed ({:.2%}), {}{}{} failed, {} skipped with {}{}{} warnings in {:.2f} seconds".format(
            COLOR_RED if failed else COLOR_GREEN,
            self.total_tests - self.total_failed - self.total_skipped,
            self.total_tests,
            COLOR_NORMAL,
            pass_rate,
            COLOR_RED if self.total_failed else COLOR_NORMAL,
            self.total_failed,
            COLOR_NORMAL,
            self.total_skipped,
            COLOR_YELLOW if self.warnings else COLOR_NORMAL,
            self.warnings,
            COLOR_NORMAL,
            self.duration))

        platforms = set(p.platform for p in self.instances.values())
        self.total_platforms = len(self.platforms)
        if self.platforms:
            info("In total {} test cases were executed on {} out of total {} platforms ({:02.2f}%)".format(
                self.total_cases,
                len(platforms),
                self.total_platforms,
                (100 * len(platforms) / len(self.platforms))
            ))

    def save_reports(self):
        if not self.instances:
            return

        report_name = "sanitycheck"
        if options.report_name:
            report_name = options.report_name

        if options.report_dir:
            os.makedirs(options.report_dir, exist_ok=True)
            filename = os.path.join(options.report_dir, report_name)
            outdir = options.report_dir
        else:
            filename = os.path.join(options.outdir, report_name)
            outdir = options.outdir

        if not options.no_update:
            self.xunit_report(filename + ".xml")
            self.csv_report(filename + ".csv")
            self.target_report(outdir)
            if self.discards:
                self.discard_report(filename + "_discard.csv")

        if options.release:
            self.csv_report(RELEASE_DATA)

        if log_file:
            log_file.close()

    def load_hardware_map_from_cmdline(self, serial, platform):
        device = {
            "serial": serial,
            "platform": platform,
            "counter": 0,
            "available": True,
            "connected": True
        }
        self.connected_hardware = [device]

    def load_hardware_map(self, map_file):
        with open(map_file, 'r') as stream:
            try:
                self.connected_hardware = yaml.safe_load(stream)
            except yaml.YAMLError as exc:
                print(exc)
        for i in self.connected_hardware:
            i['counter'] = 0

    def add_configurations(self):

        for board_root in self.board_roots:
            board_root = os.path.abspath(board_root)

            debug("Reading platform configuration files under %s..." %
                board_root)

            for file in glob.glob(os.path.join(board_root, "*", "*", "*.yaml")):
                verbose("Found plaform configuration " + file)
                try:
                    platform = Platform()
                    platform.load(file)
                    if platform.sanitycheck:
                        self.platforms.append(platform)
                        if platform.default:
                            self.default_platforms.append(platform.name)

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


    def get_all_tests(self):
        tests = []
        for _, tc in self.testcases.items():
            for case in tc.cases:
                tests.append(case)

        return tests

    @staticmethod
    def get_toolchain():
        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)

        return toolchain


    def add_testcases(self):
        for root in self.roots:
            root = os.path.abspath(root)

            debug("Reading test case configuration files under %s..." %root)

            for dirpath, dirnames, filenames in os.walk(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[:] = []
                tc_path = os.path.join(dirpath, filename)
                self.add_testcase(tc_path, root)

    def add_testcase(self, tc_data_file, root):
        try:
            parsed_data = SanityConfigParser(tc_data_file, self.tc_schema)
            parsed_data.load()

            tc_path = os.path.dirname(tc_data_file)
            workdir = os.path.relpath(tc_path, root)

            for name in parsed_data.tests.keys():
                tc = TestCase()
                tc.name = tc.get_unique(root, workdir, name)

                tc_dict = parsed_data.get_test(name, testcase_valid_keys)

                tc.source_dir = tc_path
                tc.yamlfile = tc_data_file

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

                tc.parse_subcases(tc_path)

                if tc.name:
                    self.testcases[tc.name] = tc

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

        return True


    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):
        last_run = os.path.join(options.outdir, "sanitycheck.csv")
        try:
            if not os.path.exists(last_run):
                raise SanityRuntimeError("Couldn't find last sanitycheck run.: %s" %last_run)
        except Exception as e:
            print(str(e))
            sys.exit(2)

        total_tests = 0
        with open(last_run, "r") as fp:
            cr = csv.DictReader(fp)
            instance_list = []
            for row in cr:
                total_tests += 1
                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)
                instance_list.append(instance)
            self.add_instances(instance_list)

        tests_to_run = len(self.instances)
        info("%d tests passed already, retyring %d tests" %(total_tests - tests_to_run, tests_to_run))

    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.DictReader(fp)
            instance_list = []
            for row in cr:
                if row["arch"] == "arch":
                    continue
                test = row["test"]
                platform = self.get_platform(row["platform"])
                instance = TestInstance(self.testcases[test], platform, self.outdir)
                instance.create_overlay(platform)
                instance_list.append(instance)
            self.add_instances(instance_list)


    def apply_filters(self):

        toolchain = self.get_toolchain()

        discards = {}
        platform_filter = options.platform
        testcase_filter = run_individual_tests
        arch_filter = options.arch
        tag_filter = options.tag
        exclude_tag = options.exclude_tag

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

        default_platforms = False

        if platform_filter:
            platforms = list(filter(lambda p: p.name in platform_filter, self.platforms))
        else:
            platforms = self.platforms

        if options.all:
            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

        info("Building initial testcase list...")

        for tc_name, tc in self.testcases.items():
            # list of instances per testcase, aka configurations.
            instance_list = []
            for plat in platforms:
                instance = TestInstance(tc, plat, self.outdir)

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

                if options.device_testing and instance.build_only:
                    discards[instance] = "Not runnable on device"
                    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 plat.arch not in arch_filter:
                    discards[instance] = "Command line testcase arch filter"
                    continue

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

                if tc.arch_exclude and plat.arch 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

                # if nothing stopped us until now, it means this configuration
                # needs to be added.
                instance_list.append(instance)

            # no configurations, so jump to next testcase
            if not instance_list:
                continue

            # if sanitycheck was launched with no platform options at all, we
            # take all default platforms
            if default_platforms and not tc.build_on_all:
                if tc.platform_whitelist:
                    a = set(self.default_platforms)
                    b = set(tc.platform_whitelist)
                    c = a.intersection(b)
                    if c:
                        aa = list( filter( lambda tc: tc.platform.name in c, instance_list))
                        self.add_instances(aa)
                    else:
                        self.add_instances(instance_list[:1])
                else:
                    instances = list( filter( lambda tc: tc.platform.default, instance_list))
                    self.add_instances(instances)

                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 _, case in self.instances.items():
            case.create_overlay(case.platform)

        self.discards = discards

        return discards

    def add_instances(self, instance_list):
        for instance in instance_list:
            self.instances[instance.name] = instance

    def add_tasks_to_queue(self):
        for instance in self.instances.values():
            if options.test_only:
                if instance.run:
                    pipeline.put({"op": "run", "test": instance, "status": "built"})
            else:
                if instance.status not in ['passed', 'skipped']:
                    instance.status = None
                    pipeline.put({"op": "cmake", "test": instance})

        return "DONE FEEDING"

    def execute(self):
        def calc_one_elf_size(instance):
            if instance.status not in ["failed", "skipped"]:
                if instance.platform.type != "native":
                    size_calc = instance.calculate_sizes()
                    instance.metrics["ram_size"] = size_calc.get_ram_size()
                    instance.metrics["rom_size"] = size_calc.get_rom_size()
                    instance.metrics["unrecognized"] = size_calc.unrecognized_sections()
                else:
                    instance.metrics["ram_size"] = 0
                    instance.metrics["rom_size"] = 0
                    instance.metrics["unrecognized"] = []

                instance.metrics["handler_time"] = instance.handler.duration if instance.handler else 0

        info("Adding tasks to the queue...")
        # We can use a with statement to ensure threads are cleaned up promptly
        with BoundedExecutor(bound=self.jobs, max_workers=self.jobs) as executor:

            # start a future for a thread which sends work in through the queue
            future_to_test = {
                    executor.submit(self.add_tasks_to_queue): 'FEEDER DONE'}

            while future_to_test:
                # check for status of the futures which are currently working
                done, _ = concurrent.futures.wait(
                        future_to_test, timeout=0.25,
                        return_when=concurrent.futures.FIRST_COMPLETED)

                # if there is incoming work, start a new future
                while not pipeline.empty():
                    # fetch a url from the queue
                    message = pipeline.get()
                    test = message['test']

                    # Start the load operation and mark the future with its URL
                    pb = ProjectBuilder(self, test)
                    future_to_test[executor.submit(pb.process, message)] = test.name

                # process any completed futures
                for future in done:
                    test = future_to_test[future]
                    try:
                        data = future.result()
                    except Exception as exc:
                        sys.exit('%r generated an exception: %s' % (test, exc))

                    else:
                        if data:
                            verbose(data)

                    # remove the now completed future
                    del future_to_test[future]

        if options.enable_size_report and not options.cmake_only:
            # Parallelize size calculation
            executor = concurrent.futures.ThreadPoolExecutor(self.jobs)
            futures = [executor.submit(calc_one_elf_size, instance)
                       for instance in self.instances.values()]
            concurrent.futures.wait(futures)
        else:
            for instance in self.instances.values():
                instance.metrics["ram_size"] = 0
                instance.metrics["rom_size"] = 0
                instance.metrics["handler_time"] = instance.handler.duration if instance.handler else 0
                instance.metrics["unrecognized"] = []


    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 sorted(self.discards.items()):
                rowdict = {"test": instance.testcase.name,
                           "arch": instance.platform.arch,
                           "platform": instance.platform.name,
                           "reason": reason}
                cw.writerow(rowdict)


    def target_report(self, outdir):
        run = "Sanitycheck"
        eleTestsuite = None

        platforms = {inst.platform.name for _,inst in self.instances.items()}
        for platform in platforms:
            errors = 0
            passes = 0
            fails = 0
            duration = 0
            skips = 0
            for _, instance in self.instances.items():
                if instance.platform.name != platform:
                    continue

                handler_time = instance.metrics.get('handler_time', 0)
                duration += handler_time
                for k in instance.results.keys():
                    if instance.results[k] == 'PASS':
                        passes += 1
                    elif instance.results[k] == 'BLOCK':
                        errors += 1
                    elif instance.results[k] == 'SKIP':
                        skips += 1
                    else:
                        fails += 1

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

            handler_time = 0

            # print out test results
            for _, instance in self.instances.items():
                if instance.platform.name != platform:
                    continue
                handler_time = instance.metrics.get('handler_time', 0)
                for k in instance.results.keys():
                    eleTestcase = ET.SubElement(
                            eleTestsuite, 'testcase', classname="%s:%s" %(instance.platform.name, os.path.basename(instance.testcase.name)),
                            name="%s" % (k), time="%f" %handler_time)
                    if instance.results[k] in ['FAIL', 'BLOCK']:
                        el = None

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

                        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))
                                el.text = filtered_string

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


            result = ET.tostring(eleTestsuites)
            with open(os.path.join(outdir, platform + ".xml"), 'wb') as f:
                f.write(result)


    def xunit_report(self, filename):
        fails = 0
        passes = 0
        errors = 0
        skips = 0
        duration = 0

        for instance in self.instances.values():
            handler_time = instance.metrics.get('handler_time', 0)
            duration += handler_time
            if instance.status == "failed":
                if instance.reason in ['build_error', 'handler_crash']:
                    errors += 1
                else:
                    fails += 1
            elif instance.status == 'skipped':
                skips += 1
            else:
                passes += 1

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

        # When we re-run the tests, we re-use the results and update only with
        # the newly run tests.
        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="%f" % duration,
                                         tests="%d" % (errors + passes + fails + skips),
                                         failures="%d" % fails,
                                         errors="%d" %(errors), skip="%s" %(skips))

        for instance in self.instances.values():

            # remove testcases that are a re-run
            if append:
                for tc in eleTestsuite.findall('testcase'):
                    if tc.get('classname') == "%s:%s" % (
                            instance.platform.name, instance.testcase.name):
                        eleTestsuite.remove(tc)

            handler_time = 0
            if instance.status != "failed" and instance.handler:
                handler_time = instance.metrics.get("handler_time", 0)

            eleTestcase = ET.SubElement(
                eleTestsuite, 'testcase', classname="%s:%s" %
                (instance.platform.name, instance.testcase.name), name="%s" %
                (instance.testcase.name), time="%f" %handler_time)

            if instance.status == "failed":
                failure = ET.SubElement(
                    eleTestcase,
                    'failure',
                    type="failure",
                    message=instance.reason)
                p = ("%s/%s/%s" % (options.outdir, instance.platform.name, instance.testcase.name))
                bl = os.path.join(p, "build.log")
                hl = os.path.join(p, "handler.log")
                log_file = bl
                if instance.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()
            elif instance.status == "skipped":
                ET.SubElement( eleTestcase, 'skipped', type="skipped", message="Skipped")

        result = ET.tostring(eleTestsuites)
        with open(filename, 'wb') as report:
            report.write(result)


    def csv_report(self, filename):
        with open(filename, "wt") as csvfile:
            fieldnames = ["test", "arch", "platform", "passed", "status",
                          "extra_args", "handler", "handler_time", "ram_size",
                          "rom_size"]
            cw = csv.DictWriter(csvfile, fieldnames, lineterminator=os.linesep)
            cw.writeheader()
            for instance in sorted(self.instances.values()):
                rowdict = {"test": instance.testcase.name,
                           "arch": instance.platform.arch,
                           "platform": instance.platform.name,
                           "extra_args": " ".join(instance.testcase.extra_args),
                           "handler": instance.platform.simulation}

                if instance.status in ["failed", "timeout"]:
                    rowdict["passed"] = False
                    rowdict["status"] = instance.reason
                else:
                    rowdict["passed"] = True
                    if instance.handler:
                        rowdict["handler_time"] = instance.metrics.get("handler_time", 0)
                    ram_size = instance.metrics.get("ram_size", 0)
                    rom_size = instance.metrics.get("rom_size", 0)
                    rowdict["ram_size"] = ram_size
                    rowdict["rom_size"] = rom_size
                cw.writerow(rowdict)


    def get_testcase(self, identifier):
        results = []
        for _, tc in self.testcases.items():
            for case in tc.cases:
                if case == identifier:
                    results.append(tc)
        return results


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/ztest/base    \\
      --testcase-root tests/kernel   \\
      --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(
        "--retry-failed", type=int, default=0,
        help="Retry failing tests again, up to the number of times specified.")

    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", "--report-dir",
        help="""Output reports containing results of the test run into the
        specified directory.
        The output will be both in CSV and JUNIT format
        (sanitycheck.csv and sanitycheck.xml).
        """)

    parser.add_argument(
        "--report-name",
        help="""Create a report with a custom name.
        """)

    parser.add_argument("--detailed-report",
        action="store",
        metavar="FILENAME",
        help="""Generate a junit report with detailed testcase results.
        Unlike the CSV file produced by --testcase-report, this XML
        report includes only tests which have run and none which were
        merely built. If an image with multiple tests crashes early then
        later tests are not accounted for either.""")

    parser.add_argument("--report-excluded",
            action="store_true",
            help="""List all tests that are never run based on current scope and
            coverage. If you are looking for accurate results, run this with
            --all, but this will take a while...""")

    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 the discard report
        generated for every run and saved in the specified output
        directory (sanitycheck_discard.csv).
        """)

    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.
        """)

    case_select.add_argument("--list-test-duplicates", action="store_true",
        help="""List tests with duplicate identifiers.
        """)

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


    parser.add_argument("--timestamps",
            action="store_true",
            help="Print all messages with time stamps")

    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.")

    test_or_build = parser.add_mutually_exclusive_group()
    test_or_build.add_argument(
        "-b", "--build-only", action="store_true",
        help="Only build the code, do not execute any of it in QEMU")

    test_or_build.add_argument(
        "--test-only", action="store_true",
        help="""Only run device tests with current artifacts, do not build
             the code""")
    parser.add_argument(
        "--cmake-only", action="store_true",
        help="Only run cmake, do not build or run.")

    parser.add_argument(
        "-j", "--jobs", type=int,
        help="Number of jobs for building, defaults to number of CPU threads, "
        "overcommited by factor 2 when --build-only")

    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=os.path.join(os.getcwd(),"sanity-out"),
        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. The directory should have the same
structure in the main Zephyr tree: boards/<arch>/<board_name>/""")

    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("--enable-size-report", action="store_true",
                        help="Enable 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(
        "--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("--generate-hardware-map",
                        help="""Probe serial devices connected to this platform
                        and create a hardware map file to be used with
                        --device-testing
                        """)

    parser.add_argument("--hardware-map",
                        help="""Load hardware map from a file. This will be used
                        for testing on hardware that is listed in the file.
                        """)

    parser.add_argument(
        "--west-flash", nargs='?', const=[],
        help="""Uses west instead of ninja or make to flash when running with
             --device-testing. Supports comma-separated argument list.

        E.g "sanitycheck --device-testing --device-serial /dev/ttyACM0
                         --west-flash="--board-id=foobar,--erase"
        will translate to "west flash -- --board-id=foobar --erase"

        NOTE: device-testing must be enabled to use this option.
        """
    )
    parser.add_argument(
        "--west-runner",
        help="""Uses the specified west runner instead of default when running
             with --west-flash.

        E.g "sanitycheck --device-testing --device-serial /dev/ttyACM0
                         --west-flash --west-runner=pyocd"
        will translate to "west flash --runner pyocd"

        NOTE: west-flash must be enabled to use this option.
        """
    )

    valgrind_asan_group = parser.add_mutually_exclusive_group()

    valgrind_asan_group.add_argument(
        "--enable-valgrind", action="store_true",
        help="""Run binary through valgrind and check for several memory access
        errors. Valgrind needs to be installed on the host. This option only
        works with host binaries such as those generated for the native_posix
        configuration and is mutual exclusive with --enable-asan.
        """)

    valgrind_asan_group.add_argument(
        "--enable-asan", action="store_true",
        help="""Enable address sanitizer to check for several memory access
        errors. Libasan needs to be installed on the host. This option only
        works with host binaries such as those generated for the native_posix
        configuration and is mutual exclusive with --enable-valgrind.
        """)

    parser.add_argument(
        "--enable-lsan", action="store_true",
        help="""Enable leak sanitizer to check for heap memory leaks.
        Libasan needs to be installed on the host. This option only
        works with host binaries such as those generated for the native_posix
        configuration and when --enable-asan is given.
        """)

    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.")

    parser.add_argument("--coverage-platform", action="append", default=[],
                        help="Plarforms to run coverage reports on. "
                        "This option may be used multiple times. "
                        "Default to what was selected with --platform.")

    parser.add_argument("--gcov-tool", default=None,
                        help="Path to the gcov tool to use for code coverage "
                        "reports")

    return parser.parse_args()


def log_info(filename):
    filename = os.path.relpath(os.path.realpath(filename))
    if options.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("\n\tsee: " + COLOR_YELLOW + filename + COLOR_NORMAL)


def log_info_file(instance):
    build_dir = instance.build_dir
    h_log = "{}/handler.log".format(build_dir)
    b_log = "{}/build.log".format(build_dir)
    v_log = "{}/valgrind.log".format(build_dir)

    if os.path.exists(v_log) and "Valgrind" in instance.reason:
        log_info("{}".format(v_log))
    elif os.path.exists(h_log):
        log_info("{}".format(h_log))
    else:
        log_info("{}".format(b_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 Exception:
                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 get_generator():
    if options.ninja:
        generator_cmd = "ninja"
        generator = "Ninja"
    else:
        generator_cmd = "make"
        generator = "Unix Makefiles"
    return generator_cmd, generator


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(".")
            if len(data) > 1:
                subsec = " ".join(data[1].split("_")).title()
                rowdict = {
                        "section": data[0].capitalize(),
                        "subsection": subsec,
                        "title": test,
                        "reference": test
                        }
                cw.writerow(rowdict)
            else:
                info("{} can't be exported".format(test))


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)


run_individual_tests = None
options = None

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

    options = parse_arguments()


    if options.generate_hardware_map:
        from serial.tools import list_ports
        serial_devices = list_ports.comports()
        filtered = []
        for d in serial_devices:
            if d.manufacturer in ['ARM', 'SEGGER', 'MBED', 'STMicroelectronics',
                                  'Atmel Corp.', 'Texas Instruments',
                                  'Silicon Labs', 'NXP Semiconductors']:
                # TI XDS110 can have multiple serial devices for a single board
                # assume endpoint 0 is the serial, skip all others
                if d.manufacturer == 'Texas Instruments' and not d.location.endswith('0'):
                    continue
                s_dev = {}
                s_dev['platform'] = "unknown"
                s_dev['id'] = d.serial_number
                s_dev['serial'] = d.device
                s_dev['product'] = d.product
                if s_dev['product'] in ['DAPLink CMSIS-DAP', 'MBED CMSIS-DAP']:
                    s_dev['runner'] = "pyocd"
                elif s_dev['product'] in ['J-Link', 'J-Link OB']:
                    s_dev['runner'] = "jlink"
                elif s_dev['product'] in ['STM32 STLink']:
                    s_dev['runner'] = "openocd"
                elif s_dev['product'].startswith('XDS110'):
                    s_dev['runner'] = "openocd"
                else:
                    s_dev['runner'] = "unknown"
                s_dev['available'] = True
                s_dev['connected'] = True
                filtered.append(s_dev)
            else:
                print("Unsupported device (%s): %s" %(d.manufacturer, d))

        if os.path.exists(options.generate_hardware_map):
            # use existing map

            with open(options.generate_hardware_map, 'r') as yaml_file:
                hwm = yaml.load(yaml_file, Loader=yaml.FullLoader)
                # disconnect everything
                for h in hwm:
                    h['connected'] = False
                    h['serial'] = None

                for d in filtered:
                    for h in hwm:
                        if d['id'] == h['id'] and d['product'] == h['product']:
                            print("Already in map: %s (%s)" %(d['product'], d['id']))
                            h['connected'] = True
                            h['serial'] = d['serial']
                            d['match'] = True

                new = list(filter(lambda n:  not n.get('match', False), filtered))
                hwm = hwm + new

                #import pprint
                #pprint.pprint(hwm)
            with open(options.generate_hardware_map, 'w') as yaml_file:
                yaml.dump(hwm, yaml_file, default_flow_style=False)


        else:
            # create new file
            with open(options.generate_hardware_map, 'w') as yaml_file:
                yaml.dump(filtered, yaml_file, default_flow_style=False)

        return


    if options.west_runner and not options.west_flash:
        error("west-runner requires west-flash to be enabled")
        sys.exit(1)

    if options.west_flash and not options.device_testing:
        error("west-flash requires device-testing to be enabled")
        sys.exit(1)

    if options.coverage:
        options.enable_coverage = True

    if not options.coverage_platform:
        options.coverage_platform = options.platform

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

    VERBOSE += options.verbose

    if options.log_file:
        log_file = open(options.log_file, "w")

    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

    # Cleanup

    if options.no_clean or options.only_failed or options.test_only:
        if os.path.exists(options.outdir):
            info("Keeping artifacts untouched")
    elif os.path.exists(options.outdir):
        for i in range(1,100):
            new_out = options.outdir + ".{}".format(i)
            if not os.path.exists(new_out):
                info("Renaming output directory to {}".format(new_out))
                shutil.move(options.outdir, new_out)
                break
                #shutil.rmtree("%s.old" %options.outdir)

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

    suite = TestSuite(options.board_root, options.testcase_root, options.outdir)
    suite.add_testcases()
    suite.add_configurations()

    if options.device_testing:
        if options.hardware_map:
            suite.load_hardware_map(options.hardware_map)
            if not options.platform:
                options.platform = []
                for platform in suite.connected_hardware:
                    if platform['connected']:
                        options.platform.append(platform['platform'])

        elif options.device_serial: #back-ward compatibility
            if options.platform and len(options.platform) == 1:
                suite.load_hardware_map_from_cmdline(options.device_serial,
                                                    options.platform[0])
            else:
                error("""When --device-testing is used with --device-serial, only one
                      platform is allowed""")


    if suite.load_errors:
        sys.exit(1)

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

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

        return

    if options.export_tests:
        cnt = 0
        tests = suite.get_all_tests()
        export_tests(options.export_tests, tests)
        return

    run_individual_tests = []

    if options.test:
        run_individual_tests = options.test

    if options.list_tests or options.list_test_duplicates or options.sub_test:
        cnt = 0
        all_tests = suite.get_all_tests()

        if options.list_test_duplicates:
            import collections
            dupes = [item for item, count in collections.Counter(all_tests).items() if count > 1]
            if dupes:
                print("Tests with duplicate identifiers:")
                for dupe in dupes:
                    print("- {}".format(dupe))
                    for dc in suite.get_testcase(dupe):
                        print("  - {}".format(dc))
            else:
                print("No duplicates found.")
            return

        if options.sub_test:
            for st in options.sub_test:
                subtests = suite.get_testcase(st)
                for sti in subtests:
                    run_individual_tests.append(sti.name)

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

        elif options.list_tests:
            for test in all_tests:
                cnt = cnt + 1
                print(" - {}".format(test))
            print("{} total.".format(cnt))
            return

    discards = []

    if options.only_failed:
        suite.get_last_failed()
    elif options.load_tests:
        suite.load_from_file(options.load_tests)
    elif options.test_only:
        last_run = os.path.join(options.outdir, "sanitycheck.csv")
        suite.load_from_file(last_run)
    else:
        discards = suite.apply_filters()

    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.testcase.name,
                    COLOR_YELLOW,
                    COLOR_NORMAL,
                    reason))

    if options.report_excluded:
        all_tests = suite.get_all_tests()
        to_be_run = set()
        for i,p in suite.instances.items():
            to_be_run.update(p.testcase.cases)

        if all_tests - to_be_run:
            print("Tests that never build or run:")
            for not_run in all_tests - to_be_run:
                print("- {}".format(not_run))

        return

    if options.subset:
        #suite.instances = OrderedDict(sorted(suite.instances.items(),
        #                    key=cmp_to_key(native_and_unit_first)))
        subset, sets = options.subset.split("/")
        total = len(suite.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(suite.instances.items(), start, end)
        suite.instances = OrderedDict(sliced_instances)


    if options.save_tests:
        suite.csv_report(options.save_tests)
        return

    info("%d test configurations selected, %d configurations discarded due to filters." %
        (len(suite.instances), len(discards)))

    if options.device_testing:
        print("\nDevice testing on:")
        for p in suite.connected_hardware:
            if p['connected']:
                print("%s (%s) on %s" %(p['platform'], p.get('id', None), p['serial']))

    if options.dry_run:
        duration = time.time() - start_time
        info("Completed in %d seconds" % (duration))
        return

    retries = options.retry_failed + 1
    completed = 0

    suite.update()
    suite.start_time = start_time

    while True:
        completed += 1

        if completed > 1:
            info("%d Iteration:" %(completed ))
            time.sleep(60) # waiting for the system to settle down
            suite.total_done = suite.total_tests - suite.total_failed
            suite.total_failed = 0

        suite.execute()
        info("", False)

        retries = retries - 1
        if retries == 0 or suite.total_failed == 0:
            break

    suite.misc_reports(options.compare_report, options.show_footprint,
                options.all_deltas, options.footprint_threshold, options.last_metrics)

    suite.duration = time.time() - start_time
    suite.summary(options.disable_unrecognized_section_test)

    if options.coverage:
        if options.gcov_tool is None:
            use_system_gcov = False

            for plat in options.coverage_platform:
                ts_plat = suite.get_platform(plat)
                if ts_plat and (ts_plat.type in {"native", "unit"}):
                    use_system_gcov = True

            if use_system_gcov or "ZEPHYR_SDK_INSTALL_DIR" not in os.environ:
                options.gcov_tool = "gcov"
            else:
                options.gcov_tool = os.path.join(os.environ["ZEPHYR_SDK_INSTALL_DIR"],
                    "i586-zephyr-elf/bin/i586-zephyr-elf-gcov")

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

    if options.device_testing:
        print("\nHardware distribution summary:\n")
        for p in suite.connected_hardware:
            if p['connected']:
                print("%s (%s): %d" %(p['platform'], p.get('id', None), p['counter']))

    suite.save_reports()
    if suite.total_failed or (suite.warnings and options.warnings_as_errors):
        sys.exit(1)

if __name__ == "__main__":
    main()
