def __init__(self, device, config): self.device = device self.config = config self.reboot_policy = config.reboot_policy self.output_directory = None self.current_job = None self.resolver = None self.last_error = None self.run_info = None self.run_result = None self.run_output_directory = settings.output_directory self.host_working_directory = settings.meta_directory self.iteration_artifacts = None self.run_artifacts = copy(self.default_run_artifacts) self.job_iteration_counts = defaultdict(int) self.aborted = False self.runner = None if settings.agenda: self.run_artifacts.append( Artifact('agenda', os.path.join(self.host_working_directory, os.path.basename(settings.agenda)), 'meta', mandatory=True, description='Agenda for this run.')) for i, filepath in enumerate(settings.loaded_files, 1): name = 'config_{}'.format(i) path = os.path.join(self.host_working_directory, name + os.path.splitext(filepath)[1]) self.run_artifacts.append( Artifact(name, path, kind='meta', mandatory=True, description='Config file used for the run.'))
class ExecutionContext(object): """ Provides a context for instrumentation. Keeps track of things like current workload and iteration. This class also provides two status members that can be used by workloads and instrumentation to keep track of arbitrary state. ``result`` is reset on each new iteration of a workload; run_status is maintained throughout a Workload Automation run. """ # These are the artifacts generated by the core framework. default_run_artifacts = [ Artifact('runlog', 'run.log', 'log', mandatory=True, description='The log for the entire run.'), ] @property def current_iteration(self): if self.current_job: spec_id = self.current_job.spec.id return self.job_iteration_counts[spec_id] else: return None @property def job_status(self): if not self.current_job: return None return self.current_job.result.status @property def workload(self): return getattr(self.spec, 'workload', None) @property def spec(self): return getattr(self.current_job, 'spec', None) @property def result(self): return getattr(self.current_job, 'result', self.run_result) def __init__(self, device, config): self.device = device self.config = config self.reboot_policy = config.reboot_policy self.output_directory = None self.current_job = None self.resolver = None self.last_error = None self.run_info = None self.run_result = None self.run_output_directory = settings.output_directory self.host_working_directory = settings.meta_directory self.iteration_artifacts = None self.run_artifacts = copy(self.default_run_artifacts) self.job_iteration_counts = defaultdict(int) self.aborted = False self.runner = None if settings.agenda: self.run_artifacts.append( Artifact('agenda', os.path.join(self.host_working_directory, os.path.basename(settings.agenda)), 'meta', mandatory=True, description='Agenda for this run.')) for i, filepath in enumerate(settings.loaded_files, 1): name = 'config_{}'.format(i) path = os.path.join(self.host_working_directory, name + os.path.splitext(filepath)[1]) self.run_artifacts.append( Artifact(name, path, kind='meta', mandatory=True, description='Config file used for the run.')) def initialize(self): if not os.path.isdir(self.run_output_directory): os.makedirs(self.run_output_directory) self.output_directory = self.run_output_directory self.resolver = ResourceResolver(self.config) self.run_info = RunInfo(self.config) self.run_result = RunResult(self.run_info, self.run_output_directory) def next_job(self, job): """Invoked by the runner when starting a new iteration of workload execution.""" self.current_job = job self.job_iteration_counts[self.spec.id] += 1 if not self.aborted: outdir_name = '_'.join( map(str, [self.spec.label, self.spec.id, self.current_iteration])) self.output_directory = _d( os.path.join(self.run_output_directory, outdir_name)) self.iteration_artifacts = [wa for wa in self.workload.artifacts] self.current_job.result.iteration = self.current_iteration self.current_job.result.output_directory = self.output_directory def end_job(self): if self.current_job.result.status == IterationResult.ABORTED: self.aborted = True self.current_job = None self.output_directory = self.run_output_directory def add_metric(self, *args, **kwargs): self.result.add_metric(*args, **kwargs) def add_artifact(self, name, path, kind, *args, **kwargs): if self.current_job is None: self.add_run_artifact(name, path, kind, *args, **kwargs) else: self.add_iteration_artifact(name, path, kind, *args, **kwargs) def add_run_artifact(self, name, path, kind, *args, **kwargs): path = _check_artifact_path(path, self.run_output_directory) self.run_artifacts.append( Artifact(name, path, kind, Artifact.ITERATION, *args, **kwargs)) def add_iteration_artifact(self, name, path, kind, *args, **kwargs): path = _check_artifact_path(path, self.output_directory) self.iteration_artifacts.append( Artifact(name, path, kind, Artifact.RUN, *args, **kwargs)) def get_artifact(self, name): if self.iteration_artifacts: for art in self.iteration_artifacts: if art.name == name: return art for art in self.run_artifacts: if art.name == name: return art return None
def add_iteration_artifact(self, name, path, kind, *args, **kwargs): path = _check_artifact_path(path, self.output_directory) self.iteration_artifacts.append( Artifact(name, path, kind, Artifact.RUN, *args, **kwargs))
def add_run_artifact(self, name, path, kind, *args, **kwargs): path = _check_artifact_path(path, self.run_output_directory) self.run_artifacts.append( Artifact(name, path, kind, Artifact.ITERATION, *args, **kwargs))