def update_bug(self, bug, use_db=True): """ Update a bug """ # Skip when it's already processed in instance bug_id = bug['id'] if bug_id in self.bugs: logger.warn('Bug {} already processed.'.format(bug_id)) return self.bugs[bug_id] # Compute the hash of the new bug bug_hash = compute_dict_hash(bug) if use_db: # Fetch or create existing bug result try: br = BugResult.query.filter_by(bugzilla_id=bug_id).one() logger.info('Update existing {}'.format(br)) # Check the bug has changed since last update if br.payload_hash == bug_hash: logger.info('Same bug hash, skip bug analysis {}'.format( br)) # noqa return br except NoResultFound: br = BugResult(bug_id) logger.info('Create new {}'.format(br)) else: # Create a new instance br = BugResult(bug_id) logger.info('Create new {}'.format(br)) # Do patch analysis try: analysis = bug_analysis(bug_id) except Exception as e: logger.error('Patch analysis failed on {} : {}'.format(bug_id, e)) return # Build html version of uplift comment if analysis['uplift_comment']: analysis['uplift_comment']['html'] = parse_uplift_comment( analysis['uplift_comment']['text'], bug_id) payload = { 'url': '{}/{}'.format(self.bugzilla_url, bug['id']), 'bug': bug, 'analysis': analysis, 'users': self.load_users(analysis), } br.payload = use_db and pickle.dumps(payload, 2) or payload br.payload_hash = bug_hash logger.info('Updated payload of {}'.format(br)) # Save in local cache self.bugs[bug_id] = br return br
def update(self): """ Update bug used in this sync """ # Skip when it's already processed in instance if self.analysis is not None: logger.warn('Bug {} already processed.'.format(self.bugzilla_id)) return True # Do patch analysis try: self.analysis = bug_analysis(self.bugzilla_id, 'release') except Exception as e: logger.error('Patch analysis failed on {} : {}'.format( self.bugzilla_id, e)) # noqa # TODO: Add to report return False # Build html version of uplift comment if self.analysis.get('uplift_comment'): self.analysis['uplift_comment']['html'] = parse_uplift_comment( self.analysis['uplift_comment']['text'], self.bugzilla_id) return True
def update_bug(self, bug, use_db=True): """ Update a bug """ # Skip when it's already processed in instance bug_id = bug['id'] if bug_id in self.bugs: logger.warn('Bug {} already processed.'.format(bug_id)) return self.bugs[bug_id] # Compute the hash of the new bug bug_hash = compute_dict_hash(bug) if use_db: # Fetch or create existing bug result try: br = BugResult.query.filter_by(bugzilla_id=bug_id).one() logger.info('Update existing {}'.format(br)) # Check the bug has changed since last update if br.payload_hash == bug_hash: logger.info('Same bug hash, skip bug analysis {}'.format(br)) # noqa return br except NoResultFound: br = BugResult(bug_id) logger.info('Create new {}'.format(br)) else: # Create a new instance br = BugResult(bug_id) logger.info('Create new {}'.format(br)) # Do patch analysis try: analysis = bug_analysis(bug_id) except Exception as e: logger.error('Patch analysis failed on {} : {}'.format(bug_id, e)) return # Build html version of uplift comment if analysis['uplift_comment']: analysis['uplift_comment']['html'] = parse_uplift_comment( analysis['uplift_comment']['text'], bug_id) payload = { 'url': '{}/{}'.format(self.bugzilla_url, bug['id']), 'bug': bug, 'analysis': analysis, 'users': self.load_users(analysis), } br.payload = use_db and pickle.dumps(payload, 2) or payload br.payload_hash = bug_hash logger.info('Updated payload of {}'.format(br)) # Save in local cache self.bugs[bug_id] = br return br
def analyze_bug(bug): sys.stdout = sys.stderr = open('analyze_bugs_' + str(os.getpid()) + ".out", "a", buffering=0) uplift_channels = utils.uplift_channels(bug) try: info = patchanalysis.bug_analysis(bug, author_cache=author_cache, reviewer_cache=reviewer_cache) # Translate sets into lists, as sets are not JSON-serializable. info['users']['authors'] = list(info['users']['authors']) info['users']['reviewers'] = list(info['users']['reviewers']) info['component'] = bug['component'] info['channels'] = uplift_channels info['types'] = utils.get_bug_types(bug) for channel in uplift_channels: uplift_info = patchanalysis.uplift_info(bug, channel) del uplift_info['landings'] info[channel + '_uplift_info'] = uplift_info # Transform timedelta objects to number of seconds (to make them JSON-serializable). info[channel + '_uplift_info']['landing_delta'] = int( uplift_info['landing_delta'].total_seconds()) info[channel + '_uplift_info']['response_delta'] = int( uplift_info['response_delta'].total_seconds()) info[channel + '_uplift_info']['release_delta'] = int( uplift_info['release_delta'].total_seconds()) if uplift_info['uplift_accepted']: info[channel + '_uplift_info']['uplift_date'] = utils.get_uplift_date( bug, channel).strftime('%Y-%m-%d') uplift_reject_date = utils.get_uplift_reject_date(bug, channel) if uplift_reject_date is not None: info[channel + '_uplift_info'][ 'uplift_reject_date'] = uplift_reject_date.strftime( '%Y-%m-%d') analyzed_bugs_shared[str(bug['id'])] = info except Exception as e: print('Error with bug ' + str(bug['id']) + ': ' + str(e)) traceback.print_exc()
def update(self): ''' Update bug used in this sync ''' # Skip when it's already processed in instance if self.analysis is not None: logger.warn('Bug {} already processed.'.format(self.bugzilla_id)) return True # Do patch analysis try: self.analysis = bug_analysis(self.bugzilla_id, 'release') except Exception as e: logger.error('Patch analysis failed on {} : {}'.format(self.bugzilla_id, e)) # noqa # TODO: Add to report return False # Build html version of uplift comment if self.analysis.get('uplift_comment'): self.analysis['uplift_comment']['html'] = parse_uplift_comment( self.analysis['uplift_comment']['text'], self.bugzilla_id) return True
def test_bug_analysis(self): # remove previous versions to avoid conflicts from responses versions.__dict__['__versions'] = None # Weird situation: the mozilla-central commit referenced in the comments is from some other # bug and the actual patch from the bug never landed on mozilla-central but directly on # other channels. with self.assertRaises(Exception) as exc: info = patchanalysis.bug_analysis(846986) self.assertIn(str(exc.exception), ['Too many matching authors ([email protected], [email protected]) found for [email protected]', 'Too many matching authors ([email protected], [email protected]) found for [email protected]']) info = patchanalysis.bug_analysis(846986, author_cache={ '*****@*****.**': ['*****@*****.**'], }) info = patchanalysis.bug_analysis(547914, uplift_channel='release') self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 11) self.assertEqual(info['patches']['1584ba8c1b86']['changes_size'], 640) self.assertEqual(info['patches']['1584ba8c1b86']['test_changes_size'], 0) self.assertEqual(info['patches']['1584ba8c1b86']['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['patches']['1584ba8c1b86']['code_churn_overall'], 205) self.assertEqual(info['patches']['1584ba8c1b86']['code_churn_last_3_releases'], 36) self.assertEqual(info['patches']['1584ba8c1b86']['developer_familiarity_overall'], 13) self.assertEqual(info['patches']['1584ba8c1b86']['developer_familiarity_last_3_releases'], 1) self.assertEqual(info['patches']['1584ba8c1b86']['reviewer_familiarity_overall'], 0) self.assertEqual(info['patches']['1584ba8c1b86']['reviewer_familiarity_last_3_releases'], 0) self.assertEqual(info['patches']['1584ba8c1b86']['languages'], ['License', 'Makefile']) self.assertIn('*****@*****.**', info['users']['reviewers']) self.assertIn('*****@*****.**', info['users']['reviewers']) self.assertEqual(info['users']['assignee']['email'], '*****@*****.**') self.assertEqual(len(info['patches']), 1) self.assertEqual(info['patches']['1584ba8c1b86']['source'], 'mercurial') self.assertEqual(info['patches']['1584ba8c1b86']['url'], 'https://hg.mozilla.org/mozilla-central/rev/1584ba8c1b86') self.assertEqual(info['landings']['nightly'], datetime(2010, 4, 5, 23, 12, 52, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) bug = {} def bughandler(found_bug): bug.update(found_bug) def commenthandler(found_bug, bugid): bug['comments'] = found_bug['comments'] def historyhandler(found_bug): bug['history'] = found_bug['history'] def attachmenthandler(attachments, bugid): bug['attachments'] = attachments Bugzilla('id=547914', bughandler=bughandler, commenthandler=commenthandler, attachmenthandler=attachmenthandler, historyhandler=historyhandler).get_data().wait() info2 = patchanalysis.bug_analysis(bug) self.assertEqual(info2, info) info = patchanalysis.bug_analysis(647570, uplift_channel='release') self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 40) self.assertEqual(info['patches']['8641afbd20e6']['changes_size'], 486) self.assertEqual(info['patches']['8641afbd20e6']['test_changes_size'], 0) self.assertEqual(info['patches']['8641afbd20e6']['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 3) self.assertEqual(info['patches']['8641afbd20e6']['code_churn_overall'], 184) self.assertEqual(info['patches']['8641afbd20e6']['code_churn_last_3_releases'], 31) self.assertEqual(info['patches']['8641afbd20e6']['developer_familiarity_overall'], 4) self.assertEqual(info['patches']['8641afbd20e6']['developer_familiarity_last_3_releases'], 4) self.assertEqual(info['patches']['8641afbd20e6']['reviewer_familiarity_overall'], 16) self.assertEqual(info['patches']['8641afbd20e6']['reviewer_familiarity_last_3_releases'], 0) self.assertEqual(len(info['patches']), 1) self.assertEqual(info['patches']['8641afbd20e6']['source'], 'mercurial') self.assertEqual(info['patches']['8641afbd20e6']['url'], 'https://hg.mozilla.org/mozilla-central/rev/8641afbd20e6') self.assertEqual(info['patches']['8641afbd20e6']['languages'], ['C', 'C++', 'Makefile']) self.assertEqual(info['landings']['nightly'], datetime(2011, 5, 26, 6, 40, 11, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) # Backed out once (when it was on inbound) with changesets from anther bug. # Author of the patch uses a different email in Bugzilla and Mercurial. # Reviewer's email doesn't start with his nick, but he's in CC list. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1271794, uplift_channel='release') self.assertWarnings(w, ['Revision d0ab0d508a24 was not found.', 'Revision 9f4983dfd881 was not found.', 'Bug 1271794 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 2) self.assertEqual(info['comments'], 24) self.assertEqual(info['patches']['154b951082e3']['changes_size'], 76) self.assertEqual(info['patches']['154b951082e3']['test_changes_size'], 0) self.assertEqual(info['patches']['154b951082e3']['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['patches']['154b951082e3']['code_churn_overall'], 249) self.assertEqual(info['patches']['154b951082e3']['code_churn_last_3_releases'], 245) self.assertEqual(info['patches']['154b951082e3']['developer_familiarity_overall'], 2) self.assertEqual(info['patches']['154b951082e3']['developer_familiarity_last_3_releases'], 2) self.assertEqual(info['patches']['154b951082e3']['reviewer_familiarity_overall'], 158) self.assertEqual(info['patches']['154b951082e3']['reviewer_familiarity_last_3_releases'], 157) self.assertEqual(info['patches']['154b951082e3']['languages'], ['Makefile']) self.assertEqual(len(info['patches']), 1) self.assertEqual(info['patches']['154b951082e3']['source'], 'mercurial') self.assertEqual(info['patches']['154b951082e3']['url'], 'https://hg.mozilla.org/mozilla-central/rev/154b951082e3') self.assertEqual(info['landings']['nightly'], datetime(2016, 5, 19, 16, 54, 30, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) # Backed out from central and relanded on central. # One of the reviewers email doesn't start with his nick and he isn't in CC list. # The author of the patch changed his email on Bugzilla. info = patchanalysis.bug_analysis(679352, uplift_channel='release') self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 4) self.assertEqual(info['depends_on'], 4) self.assertEqual(info['comments'], 19) self.assertEqual(info['patches']['b9d0984bdd95']['changes_size'], 312) self.assertEqual(info['patches']['f5578fdc50ef']['changes_size'], 8524) self.assertEqual(info['patches']['b9d0984bdd95']['test_changes_size'], 0) self.assertEqual(info['patches']['f5578fdc50ef']['test_changes_size'], 410) self.assertEqual(info['patches']['b9d0984bdd95']['modules_num'], 2) self.assertEqual(info['patches']['f5578fdc50ef']['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['patches']['b9d0984bdd95']['code_churn_overall'], 406) self.assertEqual(info['patches']['f5578fdc50ef']['code_churn_overall'], 670) self.assertEqual(info['patches']['b9d0984bdd95']['code_churn_last_3_releases'], 62) self.assertEqual(info['patches']['f5578fdc50ef']['code_churn_last_3_releases'], 121) self.assertEqual(info['patches']['b9d0984bdd95']['developer_familiarity_overall'], 5) self.assertEqual(info['patches']['f5578fdc50ef']['developer_familiarity_overall'], 5) self.assertEqual(info['patches']['b9d0984bdd95']['developer_familiarity_last_3_releases'], 5) self.assertEqual(info['patches']['f5578fdc50ef']['developer_familiarity_last_3_releases'], 5) self.assertEqual(info['patches']['b9d0984bdd95']['reviewer_familiarity_overall'], 48) self.assertEqual(info['patches']['f5578fdc50ef']['reviewer_familiarity_overall'], 9) self.assertEqual(info['patches']['b9d0984bdd95']['reviewer_familiarity_last_3_releases'], 1) self.assertEqual(info['patches']['f5578fdc50ef']['reviewer_familiarity_last_3_releases'], 2) self.assertEqual(info['patches']['b9d0984bdd95']['languages'], ['C', 'C++', 'Windows IDL']) self.assertEqual(info['patches']['f5578fdc50ef']['languages'], ['C', 'Makefile', 'Shell']) self.assertEqual(len(info['patches']), 2) self.assertEqual(info['patches']['b9d0984bdd95']['source'], 'mercurial') self.assertIn(info['patches']['b9d0984bdd95']['url'], 'https://hg.mozilla.org/mozilla-central/rev/b9d0984bdd95') self.assertEqual(info['patches']['f5578fdc50ef']['source'], 'mercurial') self.assertIn(info['patches']['f5578fdc50ef']['url'], 'https://hg.mozilla.org/mozilla-central/rev/f5578fdc50ef') self.assertEqual(info['landings']['nightly'], datetime(2011, 12, 11, 4, 15, 3, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) # Changeset with multiple unrelated backouts (on fx-team). # Landing comment with long revision (Entire hash instead of first 12 characters). info = patchanalysis.bug_analysis(384458, uplift_channel='release') self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 6) self.assertEqual(info['depends_on'], 64) self.assertEqual(info['comments'], 110) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 384458) self.assertEqual(info['landings']['nightly'], datetime(2016, 6, 10, 13, 42, 45, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) # Custom backout (no reference to revision). # Author has a different name on Bugzilla and Mercurial and they don't use the email on Mercurial. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1220307, uplift_channel='release') if sys.version_info >= (3, 0): self.assertWarnings(w, ['da10eecd0e76 looks like a backout, but we couldn\'t find which revision was backed out.', 'Revision da10eecd0e76 is related to another bug (1276850).', 'Bug 1220307 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 2) self.assertEqual(info['blocks'], 4) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 43) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 1220307) with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1276850, uplift_channel='release') if sys.version_info >= (3, 0): self.assertWarnings(w, ['da10eecd0e76 looks like a backout, but we couldn\'t find which revision was backed out.', 'Author [email protected] is not in the list of authors on Bugzilla ().', 'Bug 1276850 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 24) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 1276850) self.assertEqual(info['landings']['nightly'], datetime(2016, 6, 6, 15, 4, 18, tzinfo=pytz.UTC)) self.assertIsNone(info['landings']['release']) self.assertIsNone(info['landings']['beta']) self.assertIsNone(info['landings']['aurora']) self.assertIsNone(info['landings']['esr']) # No landed patches. # The author of the patch changed his email on Bugzilla, so past contributions # are hard to find. info = patchanalysis.bug_analysis(1007402) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 41) self.assertEqual(info['r-ed_patches'], 1) self.assertEqualPatches(info['patches'], 1007402) # No link between Bugzilla account and Mercurial author. # Reviewer uses different email on Bugzilla and Mercurial. info = patchanalysis.bug_analysis(901821) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 11) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 901821) # Reviewer has different emails on Bugzilla and Mercurial, and his short name is hard to find. info = patchanalysis.bug_analysis(859425) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 8) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 859425) # r=bustage info = patchanalysis.bug_analysis(701875) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 69) self.assertEqual(info['r-ed_patches'], 1) self.assertEqualPatches(info['patches'], 701875) # Reviewer doesn't have his short name in his Bugzilla name. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(853033) self.assertWarnings(w, ['Revision 8de609c5d378 is related to another bug (743252).', 'Reviewer jlebar could not be found.']) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 2) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 13) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 853033) # There are users in the CC list with empty real names. info = patchanalysis.bug_analysis(699633) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 41) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 699633) # Reviewer with several IRC names. info = patchanalysis.bug_analysis(914034) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 2) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 26) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 914034) # IRC handle in the domain of the email ([email protected]). info = patchanalysis.bug_analysis(903475) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 71) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 903475) # Backout without the 'changeset' word. info = patchanalysis.bug_analysis(829421) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 22) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 829421) # IRC handle first character is lower case in Mercurial, upper case in Bugzilla. info = patchanalysis.bug_analysis(799266) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 28) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 799266) # r=IRC_HANDLE_OF_THE_AUTHOR info = patchanalysis.bug_analysis(721760) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 72) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 721760) # IRC handle is ':IRC_HANDLE.SURNAME' and reviewer is not a reviewer of the patch on Bugzilla. info = patchanalysis.bug_analysis(1021265) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 111) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 1021265) # IRC handle is the beginning of the real name with a space after. info = patchanalysis.bug_analysis(1029098) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 15) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 1029098) # Typo in the reviewer name. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(843733) self.assertWarnings(w, ['Reviewer mjronseb could not be found.']) # r=oops info = patchanalysis.bug_analysis(843821) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 21) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 843821) # r=backout info = patchanalysis.bug_analysis(679509) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 97) self.assertEqual(info['r-ed_patches'], 0) self.assertEqualPatches(info['patches'], 679509) # Bugzilla user is impossible to find from IRC handle. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(700583, uplift_channel='release') self.assertWarnings(w, ['Reviewer [email protected] is not in the list of reviewers on Bugzilla (' + ', '.join(sorted(['*****@*****.**', '*****@*****.**'])) + ').', 'Bug 700583 doesn\'t have a uplift request date.']) # IRC handle is name+surname info = patchanalysis.bug_analysis(701262) # r=none info = patchanalysis.bug_analysis(733614) # Reviewer on Bugzilla is a different person than the reviewer in the Mercurial commit. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(963621) self.assertWarnings(w, ['Reviewer doublec could not be found.']) # IRC handle is part of the name. info = patchanalysis.bug_analysis(829646) # Multiple backouts with a commit message of one line. info = patchanalysis.bug_analysis(683280) # IRC handle on Bugzilla is different than the one used in Mercurial. info = patchanalysis.bug_analysis(680802) # A comment contains a non-existing revision. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1156913) self.assertWarnings(w, ['Revision fa8854bd0029 doesn\'t exist.']) # Author in mercurial doesn't use the same format as usual ("Full Name email" instead of "Full Name <email>"). info = patchanalysis.bug_analysis(1277522) # Author in mercurial doesn't have email # ESR landing too info = patchanalysis.bug_analysis(1254980, uplift_channel='release') self.assertEqual(info['landings']['nightly'], datetime(2016, 3, 26, 2, 12, 27, tzinfo=pytz.UTC)) self.assertEqual(info['landings']['aurora'], datetime(2016, 3, 28, 23, 24, 6, tzinfo=pytz.UTC)) self.assertEqual(info['landings']['beta'], datetime(2016, 3, 31, 19, 48, 30, tzinfo=pytz.UTC)) self.assertEqual(info['landings']['release'], datetime(2016, 4, 6, 19, 35, 18, tzinfo=pytz.UTC)) self.assertEqual(info['landings']['esr'], datetime(2016, 4, 7, 18, 41, 3, tzinfo=pytz.UTC)) # Check uplift request info = patchanalysis.bug_analysis(1230065, uplift_channel='release') self.assertIsNotNone(info['uplift_comment']) self.assertEqual(len(info['uplift_comment']['text'].split('\n')), 11) self.assertEqual(info['uplift_comment']['id'], 11222288) self.assertIsNotNone(info['uplift_author']) self.assertEqual(info['uplift_author']['email'], '*****@*****.**') self.assertIsNone(info['uplift_reviewer']) # in-testsuite? info = patchanalysis.bug_analysis(1190) self.assertEqual(info['in-testsuite'], '?') # in-testsuite- info = patchanalysis.bug_analysis(91) self.assertEqual(info['in-testsuite'], '-') # in-testsuite+ info = patchanalysis.bug_analysis(105) self.assertEqual(info['in-testsuite'], '+') # in-testsuite not set info = patchanalysis.bug_analysis(1234567) self.assertEqual(info['in-testsuite'], '') info = patchanalysis.bug_analysis(712363) self.assertEqual(info['backout_num'], 0) self.assertIn('e610972755d9', info['patches']) self.assertIn('0bcaac9fadf1', info['patches']) self.assertIn('efae575a79e4', info['patches']) self.assertIn('9576aeb57bd4', info['patches']) self.assertIn('d9eab22ce37a', info['patches']) # Author email has different upper- and lower-case letters on Mercurial and Bugzilla. info = patchanalysis.bug_analysis(772679) for h in ['8364cb62506e', '970496fa31dd', '7566f863512b', '1ee6a1ae6cfc', 'b2127fc9bd2b', '6424adfb7ac2', 'e63fd4fc05a0', 'b15fb3603bfe', '14d17919e235', '6efd09dda9e1', '313b5b97e7e3', 'f89ae41eed63']: self.assertIn(h, info['patches']) # Bugs with patches with no changes. info = patchanalysis.bug_analysis(829557, author_cache={ '*****@*****.**': ['*****@*****.**'], }) info = patchanalysis.bug_analysis(1019595) info = patchanalysis.bug_analysis(1264786) info = patchanalysis.bug_analysis(1114040) info = patchanalysis.bug_analysis(1211871) # Reviewer can't be found. info = patchanalysis.bug_analysis(1161913, reviewer_cache={ 'mt': '*****@*****.**', }) # Reviewer has a point in the short name. info = patchanalysis.bug_analysis(1232113) # Reviewer has an underscore in the short name. info = patchanalysis.bug_analysis(1281387)
def test_bug_analysis(self): info = patchanalysis.bug_analysis(547914) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 11) self.assertEqual(info['changes_size'], 640) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 205) self.assertEqual(info['code_churn_last_3_releases'], 36) self.assertEqual(info['developer_familiarity_overall'], 13) self.assertEqual(info['developer_familiarity_last_3_releases'], 1) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertIn('*****@*****.**', info['users']['reviewers']) self.assertIn('*****@*****.**', info['users']['reviewers']) self.assertEqual(info['users']['assignee']['email'], '*****@*****.**') self.assertGreater(info['crashes'], 0) bug = {} def bughandler(found_bug, data): bug.update(found_bug) def commenthandler(found_bug, bugid, data): bug['comments'] = found_bug['comments'] def historyhandler(found_bug, data): bug['history'] = found_bug['history'] def attachmenthandler(attachments, bugid, data): bug['attachments'] = attachments Bugzilla('id=547914', bughandler=bughandler, commenthandler=commenthandler, attachmenthandler=attachmenthandler, historyhandler=historyhandler).get_data().wait() info2 = patchanalysis.bug_analysis(bug) self.assertEqual(info2, info) info = patchanalysis.bug_analysis(647570) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 40) self.assertEqual(info['changes_size'], 488) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 3) self.assertEqual(info['code_churn_overall'], 184) self.assertEqual(info['code_churn_last_3_releases'], 31) self.assertEqual(info['developer_familiarity_overall'], 4) self.assertEqual(info['developer_familiarity_last_3_releases'], 4) self.assertEqual(info['reviewer_familiarity_overall'], 16) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreater(info['crashes'], 0) # Backed out once (when it was on inbound) with changesets from anther bug. # Author of the patch uses a different email in Bugzilla and Mercurial. # Reviewer's email doesn't start with his nick, but he's in CC list. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1271794) self.assertWarnings(w, ['Revision d0ab0d508a24 was not found.', 'Revision 9f4983dfd881 was not found.', 'Bug 1271794 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 2) self.assertEqual(info['comments'], 24) self.assertEqual(info['changes_size'], 76) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 249) self.assertEqual(info['code_churn_last_3_releases'], 245) self.assertEqual(info['developer_familiarity_overall'], 2) self.assertEqual(info['developer_familiarity_last_3_releases'], 2) self.assertEqual(info['reviewer_familiarity_overall'], 158) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 157) self.assertGreaterEqual(info['crashes'], 0) # Backed out from central and relanded on central. # One of the reviewers email doesn't start with his nick and he isn't in CC list. # The author of the patch changed his email on Bugzilla. info = patchanalysis.bug_analysis(679352) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 4) self.assertEqual(info['depends_on'], 4) self.assertEqual(info['comments'], 19) self.assertEqual(info['changes_size'], 8836) self.assertEqual(info['test_changes_size'], 410) self.assertEqual(info['modules_num'], 5) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 1076) self.assertEqual(info['code_churn_last_3_releases'], 183) self.assertEqual(info['developer_familiarity_overall'], 10) self.assertEqual(info['developer_familiarity_last_3_releases'], 10) self.assertEqual(info['reviewer_familiarity_overall'], 57) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 3) self.assertGreater(info['crashes'], 0) # Changeset with multiple unrelated backouts (on fx-team). # Landing comment with long revision (Entire hash instead of first 12 characters). info = patchanalysis.bug_analysis(384458) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 6) self.assertEqual(info['depends_on'], 47) self.assertEqual(info['comments'], 106) self.assertEqual(info['changes_size'], 2752) self.assertEqual(info['test_changes_size'], 462) self.assertEqual(info['modules_num'], 11) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 8191) self.assertEqual(info['code_churn_last_3_releases'], 801) self.assertEqual(info['developer_familiarity_overall'], 162) self.assertEqual(info['developer_familiarity_last_3_releases'], 51) self.assertEqual(info['reviewer_familiarity_overall'], 2) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreater(info['crashes'], 0) # Custom backout (no reference to revision). # Author has a different name on Bugzilla and Mercurial and they don't use the email on Mercurial. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1220307) self.assertWarnings(w, ['da10eecd0e76 looks like a backout, but we couldn\'t find which revision was backed out.', 'Revision da10eecd0e76 is related to another bug (1276850).', 'Bug 1220307 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 2) self.assertEqual(info['blocks'], 4) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 42) self.assertEqual(info['changes_size'], 67) self.assertEqual(info['test_changes_size'], 50) self.assertEqual(info['modules_num'], 3) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 79) self.assertEqual(info['code_churn_last_3_releases'], 33) self.assertEqual(info['developer_familiarity_overall'], 5) self.assertEqual(info['developer_familiarity_last_3_releases'], 5) self.assertEqual(info['reviewer_familiarity_overall'], 2) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 1) self.assertGreater(info['crashes'], 0) with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1276850) self.assertWarnings(w, ['da10eecd0e76 looks like a backout, but we couldn\'t find which revision was backed out.', 'Author [email protected] is not in the list of authors on Bugzilla.', 'Bug 1276850 doesn\'t have a uplift request date.']) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 24) self.assertEqual(info['changes_size'], 40) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 26) self.assertEqual(info['code_churn_last_3_releases'], 21) self.assertEqual(info['developer_familiarity_overall'], 0) self.assertEqual(info['developer_familiarity_last_3_releases'], 0) self.assertEqual(info['reviewer_familiarity_overall'], 26) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 21) self.assertGreater(info['crashes'], 0) # No landed patches. # The author of the patch changed his email on Bugzilla, so past contributions # are hard to find. info = patchanalysis.bug_analysis(1007402) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 41) self.assertEqual(info['changes_size'], 1035) self.assertEqual(info['test_changes_size'], 445) self.assertEqual(info['modules_num'], 6) self.assertEqual(info['r-ed_patches'], 1) self.assertEqual(info['code_churn_overall'], 2465) self.assertEqual(info['code_churn_last_3_releases'], 316) self.assertEqual(info['developer_familiarity_overall'], 4) self.assertEqual(info['developer_familiarity_last_3_releases'], 4) self.assertEqual(info['reviewer_familiarity_overall'], 266) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 15) self.assertGreaterEqual(info['crashes'], 0) # No link between Bugzilla account and Mercurial author. # Reviewer uses different email on Bugzilla and Mercurial. info = patchanalysis.bug_analysis(901821) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 11) self.assertEqual(info['changes_size'], 18) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 1088) self.assertEqual(info['code_churn_last_3_releases'], 152) self.assertEqual(info['developer_familiarity_overall'], 115) self.assertEqual(info['developer_familiarity_last_3_releases'], 23) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # Reviewer has different emails on Bugzilla and Mercurial, and his short name is hard to find. info = patchanalysis.bug_analysis(859425) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 8) self.assertEqual(info['changes_size'], 31) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 79) self.assertEqual(info['code_churn_last_3_releases'], 30) self.assertEqual(info['developer_familiarity_overall'], 1) self.assertEqual(info['developer_familiarity_last_3_releases'], 1) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # r=bustage info = patchanalysis.bug_analysis(701875) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 69) self.assertEqual(info['changes_size'], 194) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 5) self.assertEqual(info['r-ed_patches'], 1) self.assertEqual(info['code_churn_overall'], 3770) self.assertEqual(info['code_churn_last_3_releases'], 526) self.assertEqual(info['developer_familiarity_overall'], 86) self.assertEqual(info['developer_familiarity_last_3_releases'], 12) self.assertEqual(info['reviewer_familiarity_overall'], 25) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 5) self.assertGreaterEqual(info['crashes'], 0) # Reviewer doesn't have his short name in his Bugzilla name. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(853033) self.assertWarnings(w, ['Revision 8de609c5d378 is related to another bug (743252).', 'Reviewer jlebar could not be found.']) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 2) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 13) self.assertEqual(info['changes_size'], 18) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 4) self.assertEqual(info['code_churn_last_3_releases'], 1) self.assertEqual(info['developer_familiarity_overall'], 1) self.assertEqual(info['developer_familiarity_last_3_releases'], 1) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # There are users in the CC list with empty real names. info = patchanalysis.bug_analysis(699633) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 41) self.assertEqual(info['changes_size'], 179) self.assertEqual(info['test_changes_size'], 35) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 66) self.assertEqual(info['code_churn_last_3_releases'], 66) self.assertEqual(info['developer_familiarity_overall'], 28) self.assertEqual(info['developer_familiarity_last_3_releases'], 28) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # Reviewer with several IRC names. info = patchanalysis.bug_analysis(914034) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 2) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 26) self.assertEqual(info['changes_size'], 287) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 240) self.assertEqual(info['code_churn_last_3_releases'], 27) self.assertEqual(info['developer_familiarity_overall'], 7) self.assertEqual(info['developer_familiarity_last_3_releases'], 7) self.assertEqual(info['reviewer_familiarity_overall'], 3) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 2) self.assertGreaterEqual(info['crashes'], 0) # IRC handle in the domain of the email ([email protected]). info = patchanalysis.bug_analysis(903475) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 71) self.assertEqual(info['changes_size'], 18) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 13) self.assertEqual(info['code_churn_last_3_releases'], 3) self.assertEqual(info['developer_familiarity_overall'], 0) self.assertEqual(info['developer_familiarity_last_3_releases'], 0) self.assertEqual(info['reviewer_familiarity_overall'], 0) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # Backout without the 'changeset' word. info = patchanalysis.bug_analysis(829421) self.assertEqual(info['backout_num'], 1) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 22) self.assertEqual(info['changes_size'], 21) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 110) self.assertEqual(info['code_churn_last_3_releases'], 21) self.assertEqual(info['developer_familiarity_overall'], 0) self.assertEqual(info['developer_familiarity_last_3_releases'], 0) self.assertEqual(info['reviewer_familiarity_overall'], 11) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 4) self.assertGreaterEqual(info['crashes'], 0) # IRC handle first character is lower case in Mercurial, upper case in Bugzilla. info = patchanalysis.bug_analysis(799266) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 28) self.assertEqual(info['changes_size'], 104) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 355) self.assertEqual(info['code_churn_last_3_releases'], 37) self.assertEqual(info['developer_familiarity_overall'], 36) self.assertEqual(info['developer_familiarity_last_3_releases'], 5) self.assertEqual(info['reviewer_familiarity_overall'], 1) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # r=IRC_HANDLE_OF_THE_AUTHOR info = patchanalysis.bug_analysis(721760) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 72) self.assertEqual(info['changes_size'], 216) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 2) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 38) self.assertEqual(info['code_churn_last_3_releases'], 25) self.assertEqual(info['developer_familiarity_overall'], 28) self.assertEqual(info['developer_familiarity_last_3_releases'], 17) self.assertEqual(info['reviewer_familiarity_overall'], 13) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 6) self.assertGreaterEqual(info['crashes'], 0) # IRC handle is ':IRC_HANDLE.SURNAME' and reviewer is not a reviewer of the patch on Bugzilla. info = patchanalysis.bug_analysis(1021265) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 3) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 111) self.assertEqual(info['changes_size'], 173) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 5) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 1763) self.assertEqual(info['code_churn_last_3_releases'], 150) self.assertEqual(info['developer_familiarity_overall'], 66) self.assertEqual(info['developer_familiarity_last_3_releases'], 17) self.assertEqual(info['reviewer_familiarity_overall'], 325) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 36) self.assertGreaterEqual(info['crashes'], 0) # IRC handle is the beginning of the real name with a space after. info = patchanalysis.bug_analysis(1029098) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 15) self.assertEqual(info['changes_size'], 94) self.assertEqual(info['test_changes_size'], 97) self.assertEqual(info['modules_num'], 1) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 277) self.assertEqual(info['code_churn_last_3_releases'], 15) self.assertEqual(info['developer_familiarity_overall'], 81) self.assertEqual(info['developer_familiarity_last_3_releases'], 8) self.assertEqual(info['reviewer_familiarity_overall'], 9) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 0) self.assertGreaterEqual(info['crashes'], 0) # Typo in the reviewer name. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(843733) self.assertWarnings(w, ['Reviewer mjronseb could not be found.']) # r=oops info = patchanalysis.bug_analysis(843821) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 1) self.assertEqual(info['depends_on'], 1) self.assertEqual(info['comments'], 21) self.assertEqual(info['changes_size'], 148) self.assertEqual(info['test_changes_size'], 0) self.assertEqual(info['modules_num'], 2) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 887) self.assertEqual(info['code_churn_last_3_releases'], 149) self.assertEqual(info['developer_familiarity_overall'], 131) self.assertEqual(info['developer_familiarity_last_3_releases'], 19) self.assertEqual(info['reviewer_familiarity_overall'], 7) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 7) self.assertGreaterEqual(info['crashes'], 0) # r=backout info = patchanalysis.bug_analysis(679509) self.assertEqual(info['backout_num'], 0) self.assertEqual(info['blocks'], 0) self.assertEqual(info['depends_on'], 0) self.assertEqual(info['comments'], 97) self.assertEqual(info['changes_size'], 347) self.assertEqual(info['test_changes_size'], 108) self.assertEqual(info['modules_num'], 5) self.assertEqual(info['r-ed_patches'], 0) self.assertEqual(info['code_churn_overall'], 1874) self.assertEqual(info['code_churn_last_3_releases'], 334) self.assertEqual(info['developer_familiarity_overall'], 116) self.assertEqual(info['developer_familiarity_last_3_releases'], 43) self.assertEqual(info['reviewer_familiarity_overall'], 53) self.assertEqual(info['reviewer_familiarity_last_3_releases'], 44) self.assertGreaterEqual(info['crashes'], 0) # Bugzilla user is impossible to find from IRC handle. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(700583) self.assertWarnings(w, ['Reviewer [email protected] is not in the list of reviewers on Bugzilla.', 'Bug 700583 doesn\'t have a uplift request date.']) # IRC handle is name+surname info = patchanalysis.bug_analysis(701262) # r=none info = patchanalysis.bug_analysis(733614) # Reviewer on Bugzilla is a different person than the reviewer in the Mercurial commit. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(963621) self.assertWarnings(w, ['Reviewer doublec could not be found.']) # IRC handle is part of the name. info = patchanalysis.bug_analysis(829646) # Multiple backouts with a commit message of one line. info = patchanalysis.bug_analysis(683280) # IRC handle on Bugzilla is different than the one used in Mercurial. info = patchanalysis.bug_analysis(680802) # Weird situation: the mozilla-central commit referenced in the comments is from some other # bug and the actual patch from the bug never landed on mozilla-central but directly on # other channels. try: info = patchanalysis.bug_analysis(846986) except Exception as e: self.assertTrue(str(e) in ['Too many matching authors ([email protected], [email protected]) found for [email protected]', 'Too many matching authors ([email protected], [email protected]) found for [email protected]']) # A comment contains a non-existing revision. with warnings.catch_warnings(record=True) as w: info = patchanalysis.bug_analysis(1156913) self.assertWarnings(w, ['Revision fa8854bd0029 doesn\'t exist.']) # Author in mercurial doesn't use the same format as usual ("Full Name email" instead of "Full Name <email>"). info = patchanalysis.bug_analysis(1277522) # Check uplift request info = patchanalysis.bug_analysis(1230065) self.assertIsNotNone(info['uplift_comment']) self.assertEqual(len(info['uplift_comment']['text'].split('\n')), 11) self.assertEqual(info['uplift_comment']['id'], 11222288) self.assertIsNotNone(info['uplift_author']) self.assertEqual(info['uplift_author']['email'], '*****@*****.**')