| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #!/usr/bin/env python3
- import os
- import sys
- import time
- import copy
- import glob
- import tempfile
- import json
- import argparse
- from nsdk_builder import *
- from nsdk_utils import *
- from nsdk_report import *
- class nsdk_bench(nsdk_runner):
- def __init__(self):
- super().__init__()
- pass
- def build_apps(self, config:dict, show_output=True, logdir=None, stoponfail=False):
- if isinstance(config, dict) == False:
- return False, None
- global_build_config = config.get("build_config", dict())
- global_build_configs = config.get("build_configs", dict())
- global_target = config.get("build_target", "all")
- global_parallel = config.get("parallel", "")
- global_cpobjs = config.get("copy_objects", False)
- rootdirs = config.get("appdirs", [])
- ignored_rootdirs = config.get("appdirs_ignore", [])
- if (isinstance(rootdirs, list) and isinstance(ignored_rootdirs, list)) == False:
- print("appdirs type in config should be list, please check!")
- return False, None
- if len(rootdirs) == 0:
- print("No appdirs specified in config, please check!")
- return False, None
- root_appdirs = dict()
- appnum = 0
- # Find all the apps in rootdirs
- for rootdir in rootdirs:
- root_appdirs[rootdir] = self.find_apps(rootdir)
- appnum += len(root_appdirs[rootdir])
- # Find all the ignored apps in ignored_rootdirs
- ignored_apps = []
- for ig_rootdir in ignored_rootdirs:
- ignored_apps.extend(self.find_apps(ig_rootdir))
- if appnum == 0:
- print("No application found in appdirs specified in config")
- return False, None
- createlog = False
- if isinstance(logdir, str):
- createlog = True
- if os.path.isdir(logdir) == False:
- os.makedirs(logdir)
- appconfigs = config.get("appconfig", dict())
- # Construct all the applications' configuration
- apps_config = dict()
- for rootdir in root_appdirs:
- for appdir in root_appdirs[rootdir]:
- if appdir in ignored_apps:
- print("%s is ignored by appdirs_ignore section" % (appdir))
- continue
- appdir = appdir.replace("\\", "/") # Change windows \\ path to /
- app_buildcfg = copy.deepcopy(global_build_config)
- app_buildcfgs = copy.deepcopy(global_build_configs)
- app_buildtarget = copy.deepcopy(global_target)
- app_parallel = copy.deepcopy(global_parallel)
- app_cpobjs = copy.deepcopy(global_cpobjs)
- found_cfg = find_local_appconfig(appdir, appconfigs)
- if found_cfg:
- appcfg = appconfigs[found_cfg]
- # merge_global is True if not present
- merge_global = appcfg.get("merge_global", True)
- # Merge global config when merge_global is True
- if merge_global:
- app_buildcfg.update(appcfg.get("build_config", dict()))
- app_buildcfgs.update(appcfg.get("build_configs", dict()))
- if "build_target" in appcfg:
- app_buildtarget = appcfg["build_target"]
- if "parallel" in appcfg:
- app_parallel = appcfg["parallel"]
- if "copy_objects" in appcfg:
- app_cpobjs = appcfg["copy_objects"]
- else: # if merge_global is false, then use app config only
- app_buildcfg = appcfg.get("build_config", dict())
- app_buildcfgs = appcfg.get("build_configs", dict())
- app_buildtarget = appcfg.get("build_target", "all")
- app_parallel = appcfg.get("parallel", "")
- app_cpobjs = appcfg.get("copy_objects", False)
- app_allconfigs = {"configs": {}}
- if len(app_buildcfgs) == 0:
- app_buildcfgs = { "default": {} }
- for cfgname in app_buildcfgs:
- if createlog:
- buildlog_name = os.path.join(cfgname, "build.log")
- applogfile = get_logfile(appdir, rootdir, logdir, buildlog_name)
- else:
- applogfile = None
- percfg_appbuildcfg = copy.deepcopy(app_buildcfg)
- percfg_appbuildcfg.update(app_buildcfgs[cfgname])
- app_allconfigs["configs"][cfgname] = {"build_config": percfg_appbuildcfg, "build_target": app_buildtarget, \
- "copy_objects": app_cpobjs, "parallel": app_parallel, "logs": {"build": applogfile}}
- apps_config[appdir] = copy.deepcopy(app_allconfigs)
- if len(apps_config) == 0:
- print("No applications need to be run according to the configuration")
- return False, None
- # Build all the applications
- print("Build %d applications defined by configuration" % (len(apps_config)))
- cmdsts, build_status = self.build_apps_with_configs(apps_config, show_output, stoponfail)
- return cmdsts, build_status
- def run_apps(self, config:dict, show_output=True, logdir=None, stoponfail=False):
- if isinstance(config, dict) == False:
- return False, None
- global_build_config = config.get("build_config", dict())
- global_build_configs = config.get("build_configs", dict())
- global_target = config.get("build_target", "clean all")
- global_parallel = config.get("parallel", "")
- global_cpobjs = config.get("copy_objects", False)
- global_run_config = config.get("run_config", dict())
- global_checks = config.get("checks", dict())
- rootdirs = config.get("appdirs", [])
- ignored_rootdirs = config.get("appdirs_ignore", [])
- if (isinstance(rootdirs, list) and isinstance(ignored_rootdirs, list)) == False:
- print("appdirs type in config should be list, please check!")
- return False, None
- if len(rootdirs) == 0:
- print("No appdirs specified in config, please check!")
- return False, None
- root_appdirs = dict()
- appnum = 0
- # Find all the apps in rootdirs
- for rootdir in rootdirs:
- root_appdirs[rootdir] = self.find_apps(rootdir)
- appnum += len(root_appdirs[rootdir])
- # Find all the ignored apps in ignored_rootdirs
- ignored_apps = []
- for ig_rootdir in ignored_rootdirs:
- ignored_apps.extend(self.find_apps(ig_rootdir))
- if appnum == 0:
- print("No application found in appdirs specified in config")
- return False, None
- createlog = False
- if isinstance(logdir, str):
- createlog = True
- if os.path.isdir(logdir) == False:
- os.makedirs(logdir)
- appconfigs = config.get("appconfig", dict())
- # Construct all the applications' configuration
- apps_config = dict()
- for rootdir in root_appdirs:
- for appdir in root_appdirs[rootdir]:
- if appdir in ignored_apps:
- print("%s is ignored according to appdirs_ignore settings in configuration" % (appdir))
- continue
- appdir = appdir.replace("\\", "/") # Change windows \\ path to /
- app_buildcfg = copy.deepcopy(global_build_config)
- app_buildcfgs = copy.deepcopy(global_build_configs)
- app_buildtarget = copy.deepcopy(global_target)
- app_parallel = copy.deepcopy(global_parallel)
- app_cpobjs = copy.deepcopy(global_cpobjs)
- app_runcfg = copy.deepcopy(global_run_config)
- app_checks = copy.deepcopy(global_checks)
- found_cfg = find_local_appconfig(appdir, appconfigs)
- if found_cfg:
- appcfg = appconfigs[found_cfg]
- # merge_global is True if not present
- merge_global = appcfg.get("merge_global", True)
- # Merge global config when merge_global is True
- if merge_global:
- app_buildcfg.update(appcfg.get("build_config", dict()))
- app_buildcfgs.update(appcfg.get("build_configs", dict()))
- app_runcfg.update(appcfg.get("run_config", dict()))
- app_checks.update(appcfg.get("checks", dict()))
- if "build_target" in appcfg:
- app_buildtarget = appcfg["build_target"]
- if "parallel" in appcfg:
- app_parallel = appcfg["parallel"]
- if "copy_objects" in appcfg:
- app_cpobjs = appcfg["copy_objects"]
- else: # if merge_global is false, then use app config only
- app_buildcfg = appcfg.get("build_config", dict())
- app_buildcfgs = appcfg.get("build_configs", dict())
- app_buildtarget = appcfg.get("build_target", "clean all")
- app_parallel = appcfg.get("parallel", "")
- app_runcfg = appcfg.get("run_config", dict())
- app_checks = appcfg.get("checks", dict())
- app_cpobjs = appcfg.get("copy_objects", False)
- app_allconfigs = {"configs": {}}
- if len(app_buildcfgs) == 0:
- app_buildcfgs = { "default": {} }
- for cfgname in app_buildcfgs:
- if createlog:
- buildlog_name = os.path.join(cfgname, "build.log")
- runlog_name = os.path.join(cfgname, "run.log")
- app_buildlogfile = get_logfile(appdir, rootdir, logdir, buildlog_name)
- app_runlogfile = get_logfile(appdir, rootdir, logdir, runlog_name)
- else:
- app_buildlogfile = None
- app_runlogfile = None
- percfg_appbuildcfg = copy.deepcopy(app_buildcfg)
- percfg_appbuildcfg.update(app_buildcfgs[cfgname])
- app_allconfigs["configs"][cfgname] = {"build_config": percfg_appbuildcfg, "build_target": app_buildtarget, \
- "copy_objects": app_cpobjs, "parallel": app_parallel, "run_config": app_runcfg, "checks": app_checks, \
- "logs": {"build": app_buildlogfile, "run": app_runlogfile}}
- apps_config[appdir] = copy.deepcopy(app_allconfigs)
- if len(apps_config) == 0:
- print("No applications need to be run according to the configuration")
- return False, None
- print("Run %d applications defined by configuration" % (len(apps_config)))
- # Run all the applications
- cmdsts, build_status = self.run_apps_with_configs(apps_config, show_output, stoponfail)
- return cmdsts, build_status
- def merge_config(appcfg, hwcfg):
- return merge_two_config(appcfg, hwcfg)
- def merge_cmd_config(config, args_dict):
- return merge_config_with_args(config, args_dict)
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description="Nuclei SDK Benchmark and Report Tool")
- parser.add_argument('--appcfg', required=True, help="Application JSON Configuration File")
- parser.add_argument('--hwcfg', help="Hardware Target JSON Configuration File, if specified, will overwrite configuration defined in appcfg")
- parser.add_argument('--logdir', default='logs', help="logs directory, default logs")
- parser.add_argument('--serport', help="Serial port for monitor, if not specified, it will use the specified by appcfg and hwcfg")
- parser.add_argument('--baudrate', help="Serial port baudrate for monitor, it will use the specified by appcfg and hwcfg")
- parser.add_argument('--make_options', help="Extra make options passed to overwrite default build configuration passed via appcfg and hwcfg")
- parser.add_argument('--build_target', help="Build target passed to make, to overwrite default build_target defined in configuration file")
- parser.add_argument('--run_target', help="Run target which program will run, such as hardware, qemu or xlspike")
- parser.add_argument('--parallel', help="parallel value, such as -j4 or -j or -j8, default None")
- parser.add_argument('--run', action='store_true', help="If specified, will do run not build process")
- parser.add_argument('--ncycm', help="If specified, will use cycle model specified here")
- parser.add_argument("--timeout", help="If specified, will use timeout value specified here")
- parser.add_argument('--verbose', action='store_true', help="If specified, will show detailed build/run messsage")
- parser.add_argument('--uniqueid', default="", help="Pass pipeline$CI_PIPELINE_ID, such as pipeline123456")
- args = parser.parse_args()
- # Load appcfg and hwcfg
- ret, appcfg = load_json(args.appcfg)
- if ret != JSON_OK:
- print("Please provide valid json config file")
- sys.exit(1)
- # record start time
- start_time = time.time()
- ret, hwcfg = load_json(args.hwcfg)
- # Merge appcfg and hwcfg, hwcfg has higher priority
- config = merge_config(appcfg, hwcfg)
- if args.ncycm and os.path.isfile(args.ncycm) == False:
- print("ERROR: cycle model %s doesn't exist, please check!" % (args.ncycm))
- sys.exit(0)
- # Merge options passed by serport, baudrate, make_options
- config = merge_cmd_config(config, vars(args))
- set_global_variables(config)
- nsdk_ext = nsdk_bench()
- if args.run:
- cmdsts, result = nsdk_ext.run_apps(config, args.verbose, args.logdir, False)
- else:
- cmdsts, result = nsdk_ext.build_apps(config, args.verbose, args.logdir, False)
- runtime = round(time.time() - start_time, 2)
- print("Applications specified in %s build or run status: %s, time cost %s seconds" % (args.appcfg, cmdsts, runtime))
- ret = check_expected(result, config, args.run)
- print("Application build as expected: %s" % (ret))
- save_results(appcfg, hwcfg, config, result, args.logdir)
- if result:
- # Generate build or run report
- save_report_files(args.logdir, config, result, args.run)
- print("This bench cost about %s seconds" % (runtime))
- # Exit with ret value
- if ret:
- sys.exit(0)
- else:
- sys.exit(1)
|