def ModifySemiStaleExpectations(stale_expectation_map, expectation_file): """Modifies lines from |stale_expectation_map| in |expectation_file|. Prompts the user for each modification and provides debug information since semi-stale expectations cannot be blindly removed like fully stale ones. Args: stale_expectation_map: A data_types.TestExpectationMap containing stale expectations. expectation_file: A filepath pointing to an expectation file to remove lines from. file_handle: An optional open file-like object to output to. If not specified, stdout will be used. Returns: A set of strings containing URLs of bugs associated with the modified (manually modified by the user or removed by the script) expectations. """ with open(expectation_file) as infile: file_contents = infile.read() expectations_to_remove = [] expectations_to_modify = [] for _, e, builder_map in stale_expectation_map.IterBuilderStepMaps(): line, line_number = _GetExpectationLine(e, file_contents) expectation_str = None if not line: logging.error( 'Could not find line corresponding to semi-stale expectation for %s ' 'with tags %s and expected results %s' % e.test, e.tags, e.expected_results) expectation_str = '[ %s ] %s [ %s ]' % (' '.join( e.tags), e.test, ' '.join(e.expected_results)) else: expectation_str = '%s (approx. line %d)' % (line, line_number) str_dict = _ConvertBuilderMapToPassOrderedStringDict(builder_map) print '\nSemi-stale expectation:\n%s' % expectation_str result_output._RecursivePrintToFile(str_dict, 1, sys.stdout) response = _WaitForUserInputOnModification() if response == 'r': expectations_to_remove.append(e) elif response == 'm': expectations_to_modify.append(e) modified_urls = RemoveExpectationsFromFile(expectations_to_remove, expectation_file) for e in expectations_to_modify: modified_urls.add(e.bug) return modified_urls
def testRecursivePrintToFileUnmatchedResults(self): """Tests _RecursivePrintToFile() with unmatched results as input.""" unmatched_results = { 'foo': { 'builder': { None: [ 'Expected "" on http://ci.chromium.org/b/build_id, got ' '"Failure" with tags []', ], 'step_name': [ 'Expected "Failure RetryOnFailure" on ' 'http://ci.chromium.org/b/build_id, got ' '"Failure" with tags [win intel]', ] }, }, } result_output._RecursivePrintToFile(unmatched_results, 0, self._file_handle) self._file_handle.close() # pylint: disable=line-too-long # Order is not guaranteed, so create permutations. expected_template = """\ foo builder%s """ values = [ """ None Expected "" on http://ci.chromium.org/b/build_id, got "Failure" with tags []\ """, """ step_name Expected "Failure RetryOnFailure" on http://ci.chromium.org/b/build_id, got "Failure" with tags [win intel]\ """, ] expected_output = CreateTextOutputPermutations(expected_template, values) # pylint: enable=line-too-long with open(self._filepath) as f: self.assertIn(f.read(), expected_output)
def testRecursivePrintToFileExpectationMap(self): """Tests _RecursivePrintToFile() with an expectation map as input.""" expectation_map = { 'foo': { '"RetryOnFailure" expectation on "win intel"': { 'builder': { 'Fully passed in the following': [ 'all_pass (2/2)', ], 'Never passed in the following': [ 'all_fail (0/2)', ], 'Partially passed in the following': { 'some_pass (1/2)': [ data_types.BuildLinkFromBuildId('build_id0'), ], }, }, }, }, } result_output._RecursivePrintToFile(expectation_map, 0, self._file_handle) self._file_handle.close() expected_output = """\ foo "RetryOnFailure" expectation on "win intel" builder Never passed in the following all_fail (0/2) Fully passed in the following all_pass (2/2) Partially passed in the following some_pass (1/2) http://ci.chromium.org/b/build_id0 """ with open(self._filepath) as f: self.assertEqual(f.read(), expected_output)