def result(self, presentation, test): raw_data = self.raw.result(presentation, test) valid = False invalid_error = '' ret = None try: ret = loads(raw_data, object_pairs_hook=collections.OrderedDict) valid = True # TypeError is raised when raw_data is None, which can happen if the json # file was not created. We then correctly handle this as invalid result. except (ValueError, TypeError) as ex: # pragma: no cover invalid_error = str(ex) if self.add_json_log is True or (self.add_json_log == 'on_failure' and presentation.status != 'SUCCESS'): if valid: with contextlib.closing(recipe_util.StringListIO()) as listio: json.dump(ret, listio, indent=2, sort_keys=True) presentation.logs[self.label] = listio.lines else: presentation.logs[self.label + ' (invalid)'] = raw_data.splitlines() presentation.logs[self.label + ' (exception)'] = ( invalid_error.splitlines()) return ret
def trigger_test_suite(self, suite, test_type, test_type_args, amp_args, step_name=None, verbose=True): step_name = step_name or suite args = ([test_type] + test_type_args + amp_args + ['--trigger', self.m.json.output()]) if verbose: args += ['--verbose'] if self.m.chromium.c.BUILD_CONFIG == 'Release': args += ['--release'] step_test_data = lambda: self.m.json.test_api.output({ 'env': { 'device': { 'brand': 'Foo', 'name': 'Fone', 'os_version': '1.2.3', }, }, 'test_run': { 'test_run_id': 'T35TRUN1D', }, }) self._ensure_keys_downloaded() step_result = self.m.chromium_android.test_runner( '[trigger] %s' % step_name, args=args, step_test_data=step_test_data) trigger_data = step_result.json.output try: device_data = trigger_data['env']['device'] step_result.presentation.step_text = 'on %s %s %s' % ( device_data['brand'], device_data['name'], device_data['os_version']) except KeyError: step_result.presentation.status = self.m.step.WARNING step_result.presentation.step_text = 'unable to find device info' try: test_run_id = trigger_data['test_run']['test_run_id'] except KeyError as e: # Log trigger_data json for debugging. with contextlib.closing(recipe_util.StringListIO()) as listio: json.dump(trigger_data, listio, indent=2, sort_keys=True) step_result = self.m.step.active_result step_result.presentation.logs['trigger_data'] = listio.lines raise self.m.step.StepFailure( 'test_run_id not found in trigger_data json') self.m.file.write('[trigger] save %s' % step_name, self._get_trigger_file_for_suite(test_run_id), self.m.json.dumps(trigger_data)) return test_run_id
def analyze(self, affected_files, test_targets, additional_compile_targets, config_file_name, mb_mastername=None, mb_buildername=None, additional_names=None): """Runs "analyze" step to determine targets affected by the patch. Returns a tuple of: - list of targets that are needed to run tests (see filter recipe module) - list of targets that need to be compiled (see filter recipe module)""" if additional_names is None: additional_names = ['chromium'] use_mb = (self.m.chromium.c.project_generator.tool == 'mb') build_output_dir = '//out/%s' % self.m.chromium.c.build_config_fs self.does_patch_require_compile( affected_files, test_targets=test_targets, additional_compile_targets=additional_compile_targets, additional_names=additional_names, config_file_name=config_file_name, use_mb=use_mb, mb_mastername=mb_mastername, mb_buildername=mb_buildername, build_output_dir=build_output_dir, cros_board=self.m.chromium.c.TARGET_CROS_BOARD) compile_targets = self.compile_targets[:] # Emit more detailed output useful for debugging. analyze_details = { 'test_targets': test_targets, 'additional_compile_targets': additional_compile_targets, 'self.m.filter.compile_targets': self.compile_targets, 'self.m.filter.test_targets': self.test_targets, 'compile_targets': compile_targets, } with contextlib.closing(recipe_util.StringListIO()) as listio: json.dump(analyze_details, listio, indent=2, sort_keys=True) step_result = self.m.step.active_result step_result.presentation.logs['analyze_details'] = listio.lines return self.test_targets, compile_targets
def result(self, presentation, test): raw_data = self.raw.result(presentation, test) valid = False ret = None try: ret = json.loads(raw_data, object_pairs_hook=collections.OrderedDict) valid = True # TypeError is raised when raw_data is None, which can happen if the json # file was not created. We then correctly handle this as invalid result. except (ValueError, TypeError): # pragma: no cover pass if self.add_json_log: key = self.name + ('' if valid else ' (invalid)') with contextlib.closing(recipe_util.StringListIO()) as listio: json.dump(ret, listio, indent=2, sort_keys=True) presentation.logs[key] = listio.lines return ret
def analyze(self, affected_files, exes, compile_targets, config_file_name, additional_names=None): """Runs "analyze" step to determine targets affected by the patch. Returns a tuple of: - boolean, indicating whether patch requires compile - list of matching exes (see filter recipe module) - list of targets that need to be compiled (see filter recipe module)""" original_exes = exes[:] original_compile_targets = compile_targets[:] if additional_names is None: additional_names = ['chromium'] use_mb = (self.m.chromium.c.project_generator.tool == 'mb') build_output_dir = '//out/%s' % self.m.chromium.c.build_config_fs self.m.filter.does_patch_require_compile( affected_files, exes=exes, compile_targets=compile_targets, additional_names=additional_names, config_file_name=config_file_name, use_mb=use_mb, build_output_dir=build_output_dir, cros_board=self.m.chromium.c.TARGET_CROS_BOARD) if self.m.filter.matches_exclusion: requires_compile = bool(exes or compile_targets) return requires_compile, exes, compile_targets if not self.m.filter.result: # Patch does not require compile. return False, [], [] compile_targets = self.m.filter.compile_targets # Add crash_service to compile_targets. This is done after filtering compile # targets out because crash_service should always be there on windows. # TODO(akuegel): Need to solve this in a better way. crbug.com/478053 if (self.m.platform.is_win and compile_targets and 'crash_service' not in compile_targets): compile_targets.extend(['crash_service']) # Emit more detailed output useful for debugging. analyze_details = { 'original_exes': original_exes, 'original_compile_targets': original_compile_targets, 'compile_targets': compile_targets, 'self.m.filter.compile_targets': self.m.filter.compile_targets, 'self.m.filter.matching_exes': self.m.filter.matching_exes, } with contextlib.closing(recipe_util.StringListIO()) as listio: json.dump(analyze_details, listio, indent=2, sort_keys=True) step_result = self.m.step.active_result step_result.presentation.logs['analyze_details'] = listio.lines # Note: due to our custom logic above it's possible we end up with empty # results. In this case we should not compile, because doing so would # use default compile targets (i.e. compile too much). requires_compile = bool(self.m.filter.matching_exes or compile_targets) return requires_compile, self.m.filter.matching_exes, compile_targets