コード例 #1
0
ファイル: kernel_test.py プロジェクト: knsathya/kint
    def __init__(self, src=None, old_cfg=None, logger=None):
        self.logger = logger or logging.getLogger(__name__)
        self.src = src
        self.results = {}
        self.kernel_params = {}
        self.static_results = []
        self.checkpatch_results = {}
        self.bisect_results = {}
        self.aiaiai_results = {}

        res_obj = {}

        self.kernel_params["head"] = ""
        self.kernel_params["base"] = ""
        self.kernel_params["branch"] = ""
        self.kernel_params["version"] = "Linux"

        for arch in supported_archs:
            static_obj = {}
            static_obj["arch_name"] = arch
            for config in supported_configs:
                static_obj[config] = {}
                static_obj[config]["compile-test"] = {}
                static_obj[config]["compile-test"]["status"] = "N/A"
                static_obj[config]["compile-test"]["warning_count"] = 0
                static_obj[config]["compile-test"]["error_count"] = 0
                static_obj[config]["sparse-test"] = {}
                static_obj[config]["sparse-test"]["status"] = "N/A"
                static_obj[config]["sparse-test"]["warning_count"] = 0
                static_obj[config]["sparse-test"]["error_count"] = 0
                static_obj[config]["smatch-test"] = {}
                static_obj[config]["smatch-test"]["status"] = "N/A"
                static_obj[config]["smatch-test"]["warning_count"] = 0
                static_obj[config]["smatch-test"]["error_count"] = 0

            self.static_results.append(static_obj)

        self.checkpatch_results["status"] = "N/A"
        self.checkpatch_results["warning_count"] = 0
        self.checkpatch_results["error_count"] = 0

        self.bisect_results["status"] = "N/A"
        self.bisect_results["patch-list"] = []

        self.aiaiai_results["status"] = "N/A"
        self.aiaiai_results["warning_count"] = 0
        self.aiaiai_results["error_count"] = 0

        res_obj["kernel-params"] = self.kernel_params
        res_obj["static-test"] = self.static_results
        res_obj["checkpatch"] = self.checkpatch_results
        res_obj["bisect"] = self.bisect_results
        res_obj["aiaiai"] = self.aiaiai_results

        self.cfgobj = JSONParser(RESULT_SCHEMA, res_obj, extend_defaults=True)
        self.results = self.cfgobj.get_cfg()

        if old_cfg is not None:
            self.update_results(old_cfg)
コード例 #2
0
ファイル: kernel_test.py プロジェクト: knsathya/kint
    def run_test(self, cfg):
        self.logger.info(format_h1("Running kernel tests from json", tab=2))

        status = True

        self.cfg = JSONParser(
            TEST_SCHEMA, cfg,
            extend_defaults=True).get_cfg() if cfg is not None else None

        if self.cfg is None:
            self.logger.warning("Invalid JSON config file")
            return False

        self.logger.info(self.cfg.keys())

        compile_config = self.cfg.get("compile-config", None)

        self.logger.info(compile_config)

        if compile_config is not None and compile_config["enable"] is True:

            for obj in compile_config["test-list"]:

                def config_enabled(config):
                    return obj[config]

                for config in filter(config_enabled, supported_configs):
                    current_status = self.compile(
                        obj["arch_name"], config,
                        obj["compiler_options"]["CC"],
                        obj["compiler_options"]["cflags"])
                    if current_status is False:
                        self.logger.error(
                            "Compilation of arch:%s config:%s failed\n" %
                            (obj["arch_name"], config))

                    status &= current_status

        checkpatch_config = self.cfg.get("checkpatch-config", None)

        self.logger.info(checkpatch_config)

        if checkpatch_config is not None and checkpatch_config[
                "enable"] is True:
            if len(checkpatch_config["source"]) > 0:
                self.checkpatch_source = checkpatch_config["source"]
            status &= self.run_checkpatch()[0]

        aiaiai_config = self.cfg.get("aiaiai-config", None)

        self.logger.info(aiaiai_config)

        if aiaiai_config is not None and aiaiai_config["enable"] is True:
            if len(aiaiai_config["source"]) > 0:
                self.aiaiai_source = aiaiai_config["source"]
            status &= self.run_aiaiai()

        return status
コード例 #3
0
ファイル: kernel_test.py プロジェクト: knsathya/kint
 def update_results(self, new_cfg):
     try:
         new_results = JSONParser(RESULT_SCHEMA,
                                  new_cfg,
                                  extend_defaults=True).get_cfg()
     except Exception:
         self.logger.warning("Invalid results config file\n")
     else:
         self.results = self.merge_results(self.results, new_results)
コード例 #4
0
ファイル: kernel_release.py プロジェクト: knsathya/kint
    def generate_output(self, schema, cfg):

        if not os.path.exists(os.path.abspath(cfg)):
            self.logger.error("Invalid config file %s", os.path.abspath(cfg))
            return False

        if not os.path.exists(os.path.abspath(schema)):
            self.logger.error("Invalid schema file %s",
                              os.path.abspath(schema))
            return False

        parser = JSONParser(schema,
                            cfg,
                            extend_defaults=True,
                            logger=self.logger)

        self.cfg = parser.get_cfg()

        return True
コード例 #5
0
ファイル: kernel_test.py プロジェクト: knsathya/kint
class KernelResults(object):
    def __init__(self, src=None, old_cfg=None, logger=None):
        self.logger = logger or logging.getLogger(__name__)
        self.src = src
        self.results = {}
        self.kernel_params = {}
        self.static_results = []
        self.checkpatch_results = {}
        self.bisect_results = {}
        self.aiaiai_results = {}

        res_obj = {}

        self.kernel_params["head"] = ""
        self.kernel_params["base"] = ""
        self.kernel_params["branch"] = ""
        self.kernel_params["version"] = "Linux"

        for arch in supported_archs:
            static_obj = {}
            static_obj["arch_name"] = arch
            for config in supported_configs:
                static_obj[config] = {}
                static_obj[config]["compile-test"] = {}
                static_obj[config]["compile-test"]["status"] = "N/A"
                static_obj[config]["compile-test"]["warning_count"] = 0
                static_obj[config]["compile-test"]["error_count"] = 0
                static_obj[config]["sparse-test"] = {}
                static_obj[config]["sparse-test"]["status"] = "N/A"
                static_obj[config]["sparse-test"]["warning_count"] = 0
                static_obj[config]["sparse-test"]["error_count"] = 0
                static_obj[config]["smatch-test"] = {}
                static_obj[config]["smatch-test"]["status"] = "N/A"
                static_obj[config]["smatch-test"]["warning_count"] = 0
                static_obj[config]["smatch-test"]["error_count"] = 0

            self.static_results.append(static_obj)

        self.checkpatch_results["status"] = "N/A"
        self.checkpatch_results["warning_count"] = 0
        self.checkpatch_results["error_count"] = 0

        self.bisect_results["status"] = "N/A"
        self.bisect_results["patch-list"] = []

        self.aiaiai_results["status"] = "N/A"
        self.aiaiai_results["warning_count"] = 0
        self.aiaiai_results["error_count"] = 0

        res_obj["kernel-params"] = self.kernel_params
        res_obj["static-test"] = self.static_results
        res_obj["checkpatch"] = self.checkpatch_results
        res_obj["bisect"] = self.bisect_results
        res_obj["aiaiai"] = self.aiaiai_results

        self.cfgobj = JSONParser(RESULT_SCHEMA, res_obj, extend_defaults=True)
        self.results = self.cfgobj.get_cfg()

        if old_cfg is not None:
            self.update_results(old_cfg)

    def update_results(self, new_cfg):
        try:
            new_results = JSONParser(RESULT_SCHEMA,
                                     new_cfg,
                                     extend_defaults=True).get_cfg()
        except Exception:
            self.logger.warning("Invalid results config file\n")
        else:
            self.results = self.merge_results(self.results, new_results)

    def _update_static_test_results(self,
                                    type,
                                    arch,
                                    config,
                                    status,
                                    warning_count=0,
                                    error_count=0):
        for obj in self.results["static-test"]:
            if obj['arch_name'] == arch:
                obj[config][type]["status"] = "Passed" if status else "Failed"
                obj[config][type]["warning_count"] = warning_count
                obj[config][type]["error_count"] = error_count

    def update_compile_test_results(self,
                                    arch,
                                    config,
                                    status,
                                    warning_count=0,
                                    error_count=0):
        self._update_static_test_results("compile-test", arch, config, status,
                                         warning_count, error_count)

    def update_sparse_test_results(self,
                                   arch,
                                   config,
                                   status,
                                   warning_count=0,
                                   error_count=0):
        self._update_static_test_results("sparse-test", arch, config, status,
                                         warning_count, error_count)

    def update_smatch_test_results(self,
                                   arch,
                                   config,
                                   status,
                                   warning_count=0,
                                   error_count=0):
        self._update_static_test_results("smatch-test", arch, config, status,
                                         warning_count, error_count)

    def update_aiaiai_results(self,
                              status,
                              warning_count=None,
                              error_count=None):
        self.results["aiaiai"]["status"] = "Passed" if status else "Failed"
        if warning_count is not None:
            self.results["aiaiai"]["warning_count"] = warning_count
        if error_count is not None:
            self.results["aiaiai"]["error_count"] = warning_count

    def update_checkpatch_results(self,
                                  status,
                                  warning_count=None,
                                  error_count=None):
        self.results["checkpatch"]["status"] = "Passed" if status else "Failed"
        if warning_count is not None:
            self.results["checkpatch"]["warning_count"] = warning_count
        if error_count is not None:
            self.results["checkpatch"]["error_count"] = warning_count

    def update_kernel_params(self,
                             version=None,
                             branch=None,
                             base=None,
                             head=None):
        if version is not None:
            self.results["kernel-params"]["version"] = version
        if branch is not None:
            self.results["kernel-params"]["branch"] = branch
        if base is not None:
            self.results["kernel-params"]["base"] = base
        if head is not None:
            self.results["kernel-params"]["head"] = head

    def kernel_info(self):
        out = ''
        if self.src is not None:
            out += 'Kernel Info:\n'
            out += "\tVersion: %s\n" % self.results["kernel-params"]["version"]
            out += "\tBranch: %s\n" % self.results["kernel-params"]["branch"]
            out += "\tHead: %s\n" % self.results["kernel-params"]["head"]
            out += "\tBase: %s\n" % self.results["kernel-params"]["base"]

        return out + '\n'

    def static_test_results(self):
        width = len(max(supported_configs, key=len)) * 2
        out = 'Static Test Results:\n'
        for obj in self.results["static-test"]:
            out += '\t%s results:\n' % obj['arch_name']
            for config in supported_configs:
                out += '\t\t%s results:\n' % config
                for type in ["compile-test", "sparse-test", "smatch-test"]:
                    out += '\t\t\t%s results:\n' % type
                    out += ('\t\t\t\t%-' + str(width) + 's: %s\n') % (
                        "status", obj[config][type]["status"])
                    out += ('\t\t\t\t%-' + str(width) + 's: %s\n') % (
                        "warning", obj[config][type]["warning_count"])
                    out += ('\t\t\t\t%-' + str(width) + 's: %s\n') % (
                        "error", obj[config][type]["error_count"])

        return out + '\n'

    def checkpatch_test_results(self):
        out = 'Checkpatch Test Results:\n'
        out += '\tstatus       : %s\n' % self.checkpatch_results["status"]
        out += '\twarning_count: %s\n' % self.checkpatch_results[
            "warning_count"]
        out += '\terror_count  : %s\n' % self.checkpatch_results["error_count"]

        return out + '\n'

    def bisect_test_results(self):
        out = 'Bisect Test Results:\n'
        out += '\tstatus       : %s\n' % self.bisect_results["status"]

        return out + '\n'

    def aiaiai_test_results(self):
        out = 'AiAiAi Test Results:\n'
        out += '\tstatus       : %s\n' % self.aiaiai_results["status"]
        out += '\twarning_count: %s\n' % self.aiaiai_results["warning_count"]
        out += '\terror_count  : %s\n' % self.aiaiai_results["error_count"]

        return out + '\n'

    def get_test_results(self, test_type="compile"):
        out = ''
        out += self.kernel_info()
        if test_type == "static":
            out += self.static_test_results()
        elif test_type == "checkpatch":
            out += self.checkpatch_test_results()
        elif test_type == "aiaiai":
            out += self.aiaiai_test_results()
        elif test_type == "all":
            out += self.static_test_results()
            out += self.checkpatch_test_results()
            out += self.aiaiai_test_results()

        return out

    def print_test_results(self, test_type="compile"):
        self.logger.info(self.get_test_results(test_type))

    def merge_results(self, dest, src):

        if isinstance(src, collections.Mapping):
            for key, value in src.iteritems():
                dest[key] = self.merge_results(dest[key], src[key])
        elif isinstance(src, (list, tuple)):
            for index, value in enumerate(src):
                dest[index] = self.merge_results(dest[index], src[index])
        else:
            dest = src

        return dest

    def dump_results(self, outfile):
        fobj = open(outfile, 'w+')
        fobj.truncate()
        fobj.close()
        raw_input("Continue to write to file")
        self.cfgobj.dump_cfg(outfile)
コード例 #6
0
ファイル: kernel_test.py プロジェクト: knsathya/kint
class KernelTest(object):
    def __init__(self,
                 src,
                 out=None,
                 branch=None,
                 head=None,
                 base=None,
                 res_cfg=None,
                 logger=None):
        self.logger = logger or logging.getLogger(__name__)
        self.src = src
        self.out = os.path.join(self.src,
                                'out') if out is None else os.path.absapth(out)
        self.branch = branch
        self.head = head
        self.base = base
        self.valid_git = False
        self.cfg = None
        self.resobj = KernelResults(self.src,
                                    old_cfg=res_cfg,
                                    logger=self.logger)
        self.git = GitShell(wd=self.src, logger=logger)
        self.sh = PyShell(wd=self.src, logger=logger)
        self.checkpatch_source = CHECK_PATCH_SCRIPT
        self.aiaiai_source = ""

        if not is_valid_kernel(src, logger):
            return

        self.version = BuildKernel(self.src).uname

        if len(self.version) > 0:
            self.resobj.update_kernel_params(version=self.version)

        self.valid_git = True if self.git.valid() else False

        if self.valid_git:
            if self.branch is not None:
                if self.git.cmd('checkout', branch)[0] != 0:
                    self.logger.error("Git checkout command failed in %s",
                                      self.src)
                    return
            else:
                self.branch = self.git.current_branch()

            #update base & head if its not given
            if self.head is None:
                self.head = self.git.head_sha()
            if self.base is None:
                self.base = self.git.base_sha()

            self.resobj.update_kernel_params(base=self.base,
                                             head=self.head,
                                             branch=self.branch)

    def run_test(self, cfg):
        self.logger.info(format_h1("Running kernel tests from json", tab=2))

        status = True

        self.cfg = JSONParser(
            TEST_SCHEMA, cfg,
            extend_defaults=True).get_cfg() if cfg is not None else None

        if self.cfg is None:
            self.logger.warning("Invalid JSON config file")
            return False

        self.logger.info(self.cfg.keys())

        compile_config = self.cfg.get("compile-config", None)

        self.logger.info(compile_config)

        if compile_config is not None and compile_config["enable"] is True:

            for obj in compile_config["test-list"]:

                def config_enabled(config):
                    return obj[config]

                for config in filter(config_enabled, supported_configs):
                    current_status = self.compile(
                        obj["arch_name"], config,
                        obj["compiler_options"]["CC"],
                        obj["compiler_options"]["cflags"])
                    if current_status is False:
                        self.logger.error(
                            "Compilation of arch:%s config:%s failed\n" %
                            (obj["arch_name"], config))

                    status &= current_status

        checkpatch_config = self.cfg.get("checkpatch-config", None)

        self.logger.info(checkpatch_config)

        if checkpatch_config is not None and checkpatch_config[
                "enable"] is True:
            if len(checkpatch_config["source"]) > 0:
                self.checkpatch_source = checkpatch_config["source"]
            status &= self.run_checkpatch()[0]

        aiaiai_config = self.cfg.get("aiaiai-config", None)

        self.logger.info(aiaiai_config)

        if aiaiai_config is not None and aiaiai_config["enable"] is True:
            if len(aiaiai_config["source"]) > 0:
                self.aiaiai_source = aiaiai_config["source"]
            status &= self.run_aiaiai()

        return status

    def compile(self, arch='', config='', cc='', cflags=[]):
        if arch not in supported_archs or config not in supported_configs:
            self.logger.error("Invalid arch/config %s/%s" % (arch, config))
            return False

        kobj = BuildKernel(src_dir=self.src,
                           out_dir=os.path.join(self.out, arch, config),
                           arch=arch,
                           cc=cc,
                           cflags=cflags,
                           logger=self.logger)
        getattr(kobj, 'make_' + config)()

        ret, out, err = kobj.make_kernel()

        warning_count = len(
            filter(lambda x: True
                   if "warning:" in x else False, out.split('\n')))
        error_count = len(
            filter(lambda x: True
                   if "error:" in x else False, out.split('\n')))

        status = True if ret == 0 else False

        self.resobj.update_compile_test_results(arch, config, status,
                                                warning_count, error_count)

        return status

    def sparse(self, arch='', config='', cc='', cflags=[]):

        if arch not in supported_archs or config not in supported_configs:
            self.logger.error("Invalid arch/config %s/%s" % (arch, config))
            return False

        sparse_flags = ["C=1", 'CHECK="/usr/bin/sparse"']

        kobj = BuildKernel(src_dir=self.src,
                           out_dir=os.path.join(self.out, arch, config),
                           arch=arch,
                           cc=cc,
                           cflags=sparse_flags + cflags,
                           logger=self.logger)
        getattr(kobj, 'make_' + config)()

        ret, out, err = kobj.make_kernel()

        warning_count = len(
            filter(lambda x: True
                   if "warning:" in x else False, out.split('\n')))
        error_count = len(
            filter(lambda x: True
                   if "error:" in x else False, out.split('\n')))

        status = True if ret == 0 else False

        self.resobj.update_sparse_test_results(arch, config, status,
                                               warning_count, error_count)

        return status

    def smatch(self, arch='', config='', cc='', cflags=[]):

        if arch not in supported_archs or config not in supported_configs:
            self.logger.error("Invalid arch/config %s/%s" % (arch, config))
            return False

        sparse_flags = ["C=1", 'CHECK="smatch -p=kernel"']

        kobj = BuildKernel(src_dir=self.src,
                           out_dir=os.path.join(self.out, arch, config),
                           arch=arch,
                           cc=cc,
                           cflags=sparse_flags + cflags,
                           logger=self.logger)
        getattr(kobj, 'make_' + config)()

        ret, out, err = kobj.make_kernel()

        warning_count = len(
            filter(lambda x: True
                   if "warning:" in x else False, out.split('\n')))
        error_count = len(
            filter(lambda x: True
                   if "error:" in x else False, out.split('\n')))

        status = True if ret == 0 else False

        self.resobj.update_smatch_test_results(arch, config, status,
                                               warning_count, error_count)

        return status

    def compile_list(self, arch='', config_list=[], cc='', cflags=[]):
        self.logger.info(format_h1("Running compile tests", tab=2))
        result = []

        for config in config_list:
            result.append(self.compile(arch, config, cc, cflags))

        return result

    def sparse_list(self, arch='', config_list=[], cc='', cflags=[]):
        self.logger.info(format_h1("Running sparse tests", tab=2))
        result = []

        for config in config_list:
            result.append(self.sparse(arch, config, cc, cflags))

        return result

    def smatch_list(self, arch='', config_list=[], cc='', cflags=[]):
        self.logger.info(format_h1("Running smatch tests", tab=2))
        result = []

        for config in config_list:
            result.append(self.smatch(arch, config, cc, cflags))

        return result

    def run_aiaiai(self):
        self.logger.info(format_h1("Run AiAiAi Script", tab=2))

        return True

    def run_sparse(self):
        self.logger.info(format_h1("Run sparse Script", tab=2))

        return True

    def run_checkpatch(self):

        self.logger.info(format_h1("Runing checkpatch script", tab=2))

        self.enable_checkpatch = True

        get_val = lambda x, y: getattr(self, y) if x is None else x

        err_count = 0
        warning_count = 0

        try:
            if self.valid_git is False:
                raise Exception("Invalid git repo")

            if not os.path.exists(os.path.join(self.src, CHECK_PATCH_SCRIPT)):
                raise Exception("Invalid checkpatch script")

            ret, count, err = self.git.cmd(
                'rev-list', '--count',
                str(self.base) + '..' + str(self.head))
            if ret != 0:
                raise Exception("git rev-list command failed")

            self.logger.debug("Number of patches between %s..%s is %d",
                              self.base, self.head, int(count))

            def parse_results(data):
                regex = r"total: ([0-9]*) errors, ([0-9]*) warnings,"
                match = re.search(regex, data)
                if match:
                    return int(match.group(1)), int(match.group(2))

                return 0, 0

            prev_index = 0
            for index in range(1, int(count) + 1):
                commit_range = str(self.head) + '~' + str(index) + '..' + str(
                    self.head) + '~' + str(prev_index)
                ret, out, err = self.sh.cmd(
                    os.path.join(self.src, CHECK_PATCH_SCRIPT), '-g',
                    commit_range)
                error, warning = parse_results(out)
                if error != 0 or warning != 0:
                    self.logger.debug(out)
                    self.logger.debug(err)
                err_count += error
                warning_count += warning
                prev_index = index
        except Exception as e:
            self.logger.error(e)
            return False, err_count, warning_count
        else:
            self.resobj.update_checkpatch_results(True, err_count,
                                                  warning_count)
            return True, err_count, warning_count

    def print_results(self, test_type='all'):
        self.resobj.print_test_results(test_type=test_type)

    def get_results(self, test_type='all'):
        return self.resobj.get_test_results(test_type=test_type)

    def dump_results(self, outfile):
        self.resobj.dump_results(outfile)
コード例 #7
0
    def __init__(self,
                 cfg,
                 schema,
                 repo_head='',
                 repo_dir=os.getcwd(),
                 subject_prefix='',
                 skip_rr_cache=False,
                 logger=None):
        # type: (json, jsonschema, str, str, str, boolean, boolean) -> object
        """
        Constructor of KernelInteg class.
        :rtype: object
        :param cfg: Kernel Integration Json config file.
        :param schema: Kernel Integration Json schema file.
        :param repo_head: SHA-ID or Tag of given branch.
        :param repo_dir: Repo directory.
        :param subject_prefix: Prefix for email subject.
        :param skip_rr_cache: Skip rr cache if set True.
        :param logger: Logger object
        """
        self.logger = logger or logging.getLogger(__name__)
        self.cfg = JSONParser(cfg, schema, logger=self.logger).get_cfg()
        self.remote_list = self.cfg['remote-list']
        self.repos = self.cfg['repos']
        self.kint_repos = self.cfg['kint-list']
        self.email_options = self.cfg['email-options']
        self.test_profiles = self.cfg['test-profiles']
        self.repo_dir = repo_dir
        self.skip_rr_cache = skip_rr_cache
        self.subject_prefix = subject_prefix
        # All git commands will be executed in repo directory.
        self.git = GitShell(wd=self.repo_dir, logger=self.logger)

        # git init
        self.logger.info(format_h1("Initalizing repo", tab=2))
        if not os.path.exists(os.path.join(self.repo_dir, ".git")):
            self._git("init", ".")

        # Create out dir if its not exists.
        out_dir = os.path.join(self.repo_dir, 'out')
        if not os.path.exists(out_dir):
            self.logger.info(format_h1("Create out dir", tab=2))
            os.makedirs(out_dir)

        # Add git remote
        self.logger.info(format_h1("Add remote", tab=2))
        for remote in self.remote_list:
            self._git("remote",
                      "add",
                      remote['name'],
                      remote['url'],
                      silent=True)

        # Get the latest updates
        self._git("remote", "update")

        valid_repo_head = False

        # Check if the repo head is valid.
        if len(repo_head) > 0:
            if self._is_valid_head(repo_head) is False:
                raise Exception("Invalid repo head %s" % repo_head)
            else:
                valid_repo_head = True

        #if repo head is given in config file, check whether its valid, make exception if not valid.
        for repo in self.repos:
            if valid_repo_head is True:
                repo['repo-head'] = repo_head
            else:
                if len(repo['repo-head']) == 0:
                    raise Exception("No valid repo head found for %s" %
                                    repo['repo-name'])
                else:
                    if self._is_valid_head(repo['repo-head']) is False:
                        raise Exception("Invalid repo head %s" %
                                        repo['repo-head'])

        # Checkout some random HEAD
        self._git("checkout", 'HEAD~1', silent=True)