def runSpecial(testNames, categoryName): """Run the tests named in testNamed assuming they are special tests. Each name should be a directory under firemarshal/test/ and should have a test.py script that will be run and indicates pass/fail via return code. The tests will be called as such: ./test.py pathToMarshalBin""" log = logging.getLogger() # Tuples of (testName, exception) for each failed test failures = [] for tName in testNames: log.log(logging.INFO, "[{}] {}:".format(categoryName, tName)) tPath = testDir / tName try: wlutil.run(["python3", tPath / "test.py", marshalBin], check=True) except sp.CalledProcessError as e: log.log(logging.INFO, "FAIL") failures.append(("[{}]: {}".format(categoryName, tName), e)) continue log.log(logging.INFO, "PASS") return failures
def runTests(testNames, categoryName, marshalArgs=[], cmdArgs=[]): """Run the tests named in testNames. Logging will use categoryName to identify this set of tests. marshalArgs and cmdArgs are the arguments to pass to 'marshal' and 'marshal test', respectively.""" log = logging.getLogger() # Tuples of (testName, exception) for each failed test failures = [] for tName in testNames: log.log(logging.INFO, "[{}] {}:".format(categoryName, tName)) tPath = testDir / (tName + ".yaml") try: # These log at level DEBUG (go to log file but not stdout) wlutil.run([marshalBin] + marshalArgs + ['clean', tPath], check=True) wlutil.run([marshalBin] + marshalArgs + ['test'] + cmdArgs + [tPath], check=True) except sp.CalledProcessError as e: log.log(logging.INFO, "FAIL") failures.append(("[{}]: {}".format(categoryName, tName), e)) continue log.log(logging.INFO, "PASS") return failures
def buildBaseImage(self): """Ensures that the image file specified by baseConfig() exists and is up to date. This is called as a doit task. """ try: wlutil.checkSubmodule(br_dir / 'buildroot') # Buildroot complains about some common PERL configurations env = os.environ.copy() env.pop('PERL_MM_OPT', None) env = {**env, **self.opts['environment']} self.configure(env) # This is unfortunate but buildroot can't remove things from the # image without rebuilding everything from scratch. It adds 20min # to the unit tests and anyone who builds a custom buildroot. wlutil.run(['make', 'clean'], cwd=br_dir / "buildroot", env=env) wlutil.run(['make'], cwd=br_dir / "buildroot", env=env) shutil.move(img_dir / 'rootfs.ext2', self.outputImg) except wlutil.SubmoduleError as e: return doit.exceptions.TaskFailed(e)
def configure(self, env): """Construct the final buildroot configuration for this environment. After calling this, it is safe to call 'make' in the buildroot directory.""" toolVer = wlutil.getToolVersions() # Contains options specific to the build environment (br is touchy about this stuff) toolKfrag = wlutil.getOpt('gen-dir') / 'brToolKfrag' with open(toolKfrag, 'w') as f: f.write("BR2_TOOLCHAIN_EXTERNAL_HEADERS_" + toolVer['linuxMaj'] + "_" + toolVer['linuxMin'] + "=y\n") f.write("BR2_TOOLCHAIN_HEADERS_AT_LEAST_" + toolVer['linuxMaj'] + "_" + toolVer['linuxMin'] + "=y\n") f.write('BR2_TOOLCHAIN_HEADERS_AT_LEAST="' + toolVer['linuxMaj'] + "." + toolVer['linuxMin'] + '"\n') f.write('BR2_TOOLCHAIN_GCC_AT_LEAST_' + toolVer['gcc'] + '=y\n') f.write('BR2_TOOLCHAIN_GCC_AT_LEAST="' + toolVer['gcc'] + '"\n') f.write('BR2_TOOLCHAIN_EXTERNAL_GCC_' + toolVer['gcc'] + '=y\n') f.write('BR2_JLEVEL=' + str(os.cpu_count()) + '\n') # Default Configuration (allows us to bump BR independently of our configs) defconfig = wlutil.getOpt('gen-dir') / 'brDefConfig' wlutil.run(['make', 'defconfig'], cwd=(br_dir / 'buildroot'), env=env) shutil.copy(br_dir / 'buildroot' / '.config', defconfig) kFrags = [defconfig, toolKfrag] + self.opts['configs'] mergeScript = br_dir / 'merge_config.sh' wlutil.run([mergeScript] + kFrags, cwd=(br_dir / 'buildroot'), env=env)
def buildBaseImage(self): log = logging.getLogger() rootfs_target = "rootfs.img" shutil.copy(os.path.join(br_dir, 'buildroot-config'), os.path.join(br_dir, "buildroot/.config")) # log.debug(sp.check_output(['make'], cwd=os.path.join(br_dir, "buildroot"))) # Buildroot complains about some common PERL configurations env = os.environ.copy() env.pop('PERL_MM_OPT', None) wlutil.run(['make'], cwd=os.path.join(br_dir, "buildroot"), env=env)
def generateBootScriptOverlay(self, script, args): # How this works: # The fedora repo has a pre-built overlay with all the systemd paths # filled in and a custom boot target (firesim.target) that loads a # custom service (firesim.service) that runs a script (/init.sh). We # can change the default boot behavior by changing this script. scriptDst = os.path.join(overlay, 'etc/firesim/firesim.sh') if script != None: print("applying script: " + scriptDst) shutil.copy(script, scriptDst) # wlutil.run(['cp', script, scriptDst]) else: wlutil.run(['rm', scriptDst]) # Create a blank init script because overlays won't let us delete stuff # Alternatively: we could consider replacing the default.target # symlink to disable the firesim target entirely wlutil.run(['touch', scriptDst]) wlutil.run(['chmod', '+x', scriptDst]) # Create the service script if args is None: serviceScript = serviceTemplate.format(scriptName='firesim.sh', scriptArgs='') else: serviceScript = serviceTemplate.format(scriptName='firesim.sh', scriptArgs=args) with open(os.path.join(overlay, 'etc/systemd/system/firesim.service'), 'w') as f: f.write(serviceScript) return overlay
def install(targetCfg, opts): log = logging.getLogger() if targetCfg['nodisk'] == False: raise NotImplementedError( "nodisk builds are the only workload type supported by the install command" ) nodiskPath = str(targetCfg['bin']) + '-nodisk' outputPath = nodiskPath + '-flat' if targetCfg['firmware']['use-bbl'] == False: wlutil.run([ 'riscv64-unknown-elf-objcopy', '-S', '-O', 'binary', '--change-addresses', '-0x80000000', nodiskPath, outputPath ]) else: print("Copy BBL's flattened binary to " + outputPath) shutil.copy( str(targetCfg['firmware']['bbl-src']) + '/build/bbl.bin', outputPath) log.info("Workload flattened and \"installed\" to " + outputPath)
def generateBootScriptOverlay(script, args): # How this works: # The buildroot repo has a pre-built overlay with a custom S99run # script that init will run last. This script will run the /firesim.sh # script at boot. We just overwrite this script. scriptDst = os.path.join(overlay, 'firesim.sh') if script != None: wlutil.run(['cp', script, scriptDst]) else: wlutil.run(['rm', scriptDst]) # Create a blank init script because overlays won't let us delete stuff # Alternatively: we could consider replacing the default.target # symlink to disable the firesim target entirely wlutil.run(['touch', scriptDst]) wlutil.run(['chmod', '+x', scriptDst]) with open(os.path.join(overlay, 'etc/init.d/S99run'), 'w') as f: if args == None: f.write(initTemplate.substitute(args='')) else: f.write(initTemplate.substitute(args=args)) return overlay
def buildBaseImage(self): wlutil.run(['make', "rootfs.img"], cwd=fed_dir)