def test_collect_assessment_issues(self): """Tests collection issues associated with Assessments.""" assessment1_mock = mock.MagicMock(id=1, status='In Review') issue1_mock = mock.MagicMock(issue_tracked_obj=assessment1_mock, issue_id='t1', issue_type='bug1', issue_priority='P1', issue_severity='S1') issue2_mock = mock.MagicMock(issue_tracked_obj=None, issue_id='t2', issue_type='bug2', issue_priority='P3', issue_severity='S3') filter_mock = mock.MagicMock() filter_mock.return_value.order_by.return_value.all.return_value = [ issue1_mock, issue2_mock, ] with mock.patch.multiple(sync_utils.models.IssuetrackerIssue, query=mock.MagicMock(filter=filter_mock)): actual = sync_utils.collect_issue_tracker_info("Assessment") self.assertEquals( actual, { 't1': { 'object_id': 1, 'state': { 'status': 'In Review', 'type': 'bug1', 'priority': 'P1', 'severity': 'S1', }, } })
def sync_assessment_statuses(): """Synchronizes issue tracker ticket statuses with the Assessment statuses. Checks for Assessments which are in sync with Issue Tracker issues and updates their statuses in accordance to the corresponding Assessments if differ. """ assessment_issues = sync_utils.collect_issue_tracker_info("Assessment", include_ccs=True) if not assessment_issues: return logger.debug('Syncing state of %d issues.', len(assessment_issues)) cli = issues.Client() processed_ids = set() for batch in sync_utils.iter_issue_batches(assessment_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id = str(issue_id) issue_info = assessment_issues.get(issue_id) if not issue_info: logger.warning( 'Got an unexpected issue from Issue Tracker: %s', issue_id) continue processed_ids.add(issue_id) assessment_state = issue_info['state'] status_value = ASSESSMENT_STATUSES_MAPPING.get( assessment_state["status"]) if not status_value: logger.error( 'Inexistent Issue Tracker status for assessment ID=%d ' 'with status: %s.', issue_info['object_id'], status_value) continue assessment_state["status"] = status_value if all( assessment_state.get(field) == issuetracker_state.get( field) for field in FIELDS_TO_CHECK) and _compare_ccs( assessment_state.get("ccs", []), issuetracker_state.get("ccs", [])): continue try: sync_utils.update_issue(cli, issue_id, assessment_state) except integrations_errors.Error as error: logger.error( 'Unable to update status of Issue Tracker issue ID=%s for ' 'assessment ID=%d: %r', issue_id, issue_info['object_id'], error) logger.debug('Sync is done, %d issue(s) were processed.', len(processed_ids)) missing_ids = set(assessment_issues) - processed_ids if missing_ids: logger.warning( 'Some issues are linked to Assessments ' 'but were not found in Issue Tracker: %s', ', '.join(str(i) for i in missing_ids))
def sync_assessment_statuses(): """Synchronizes issue tracker ticket statuses with the Assessment statuses. Checks for Assessments which are in sync with Issue Tracker issues and updates their statuses in accordance to the corresponding Assessments if differ. """ assessment_issues = sync_utils.collect_issue_tracker_info("Assessment") if not assessment_issues: return logger.debug('Syncing state of %d issues.', len(assessment_issues)) cli = issues.Client() processed_ids = set() for batch in sync_utils.iter_issue_batches(assessment_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id = str(issue_id) issue_info = assessment_issues.get(issue_id) if not issue_info: logger.warning( 'Got an unexpected issue from Issue Tracker: %s', issue_id) continue processed_ids.add(issue_id) assessment_state = issue_info['state'] status_value = ASSESSMENT_STATUSES_MAPPING.get( assessment_state["status"] ) if not status_value: logger.error( 'Inexistent Issue Tracker status for assessment ID=%d ' 'with status: %s.', issue_info['object_id'], status_value ) continue assessment_state["status"] = status_value if all( assessment_state.get(field) == issuetracker_state.get(field) for field in FIELDS_TO_CHECK ): continue try: sync_utils.update_issue(cli, issue_id, assessment_state) except integrations_errors.Error as error: logger.error( 'Unable to update status of Issue Tracker issue ID=%s for ' 'assessment ID=%d: %r', issue_id, issue_info['object_id'], error) logger.debug('Sync is done, %d issue(s) were processed.', len(processed_ids)) missing_ids = set(assessment_issues) - processed_ids if missing_ids: logger.warning( 'Some issues are linked to Assessments ' 'but were not found in Issue Tracker: %s', ', '.join(str(i) for i in missing_ids))
def sync_issue_attributes(): """Synchronizes issue tracker ticket attrs with the Issue object attrs. Synchronize issue status and email list (Primary contacts and Admins). """ issuetracker_issues = sync_utils.collect_issue_tracker_info( "Issue", include_object=True ) if not issuetracker_issues: return assignees_role = all_models.AccessControlRole.query.filter_by( object_type=all_models.Issue.__name__, name="Primary Contacts" ).first() admin_role = all_models.AccessControlRole.query.filter_by( object_type=all_models.Issue.__name__, name="Admin" ).first() processed_ids = set() for batch in sync_utils.iter_issue_batches(issuetracker_issues.keys(), include_emails=True): for issue_id, issuetracker_state in batch.iteritems(): issue_id = str(issue_id) issue_info = issuetracker_issues.get(issue_id) if not issue_info: logger.warning( "Got an unexpected issue from Issue Tracker: %s", issue_id) continue processed_ids.add(issue_id) sync_object = issue_info["object"] # Sync attributes. sync_statuses(issuetracker_state, sync_object) sync_assignee_email(issuetracker_state, sync_object, assignees_role) sync_verifier_email(issuetracker_state, sync_object, admin_role) custom_fields = { constants.CUSTOM_FIELDS_DUE_DATE: sync_utils.parse_due_date( issuetracker_state.get("custom_fields", []) ) } sync_due_date(custom_fields, sync_object) db.session.commit() logger.debug("Sync is done, %d issue(s) were processed.", len(processed_ids)) missing_ids = set(issuetracker_issues) - processed_ids if missing_ids: logger.warning( "Some issues are linked to Issue " "but were not found in Issue Tracker: %s", ", ".join(str(i) for i in missing_ids) )
def sync_issue_attributes(): """Synchronizes issue tracker ticket attrs with the Issue object attrs. Synchronize issue status and email list (Primary contacts and Admins). """ issuetracker_issues = sync_utils.collect_issue_tracker_info( "Issue" ) if not issuetracker_issues: return assignees_role = all_models.AccessControlRole.query.filter_by( object_type=all_models.Issue.__name__, name="Primary Contacts" ).first() admin_role = all_models.AccessControlRole.query.filter_by( object_type=all_models.Issue.__name__, name="Admin" ).first() processed_ids = set() for batch in sync_utils.iter_issue_batches(issuetracker_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id = str(issue_id) issue_info = issuetracker_issues.get(issue_id) if not issue_info: logger.warning( "Got an unexpected issue from Issue Tracker: %s", issue_id) continue processed_ids.add(issue_id) sync_object = issue_info["object"] # Sync attributes. sync_statuses(issuetracker_state, sync_object) sync_assignee_email(issuetracker_state, sync_object, assignees_role) sync_verifier_email(issuetracker_state, sync_object, admin_role) custom_fields = { constants.CustomFields.DUE_DATE: sync_utils.parse_due_date( issuetracker_state.get("custom_fields", []) ) } sync_due_date(custom_fields, sync_object) db.session.commit() logger.debug("Sync is done, %d issue(s) were processed.", len(processed_ids)) missing_ids = set(issuetracker_issues) - processed_ids if missing_ids: logger.warning( "Some issues are linked to Issue " "but were not found in Issue Tracker: %s", ", ".join(str(i) for i in missing_ids) )
def sync_assessment_attributes(): # noqa """Synchronizes issue tracker ticket statuses with the Assessment statuses. Checks for Assessments which are in sync with Issue Tracker issues and updates their statuses in accordance to the corresponding Assessments if differ. """ logger.info( "Assessment synchronization start: %s", datetime.datetime.utcnow() ) assessment_issues = sync_utils.collect_issue_tracker_info( "Assessment" ) if not assessment_issues: return logger.info("Syncing state of %d issues.", len(assessment_issues)) processed_ids = set() tracker_handler = assessment_integration.AssessmentTrackerHandler() for batch in sync_utils.iter_issue_batches(assessment_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id, issue_info = _get_issue_info_by_issue_id( issue_id, assessment_issues ) if not issue_info: logger.warning( "Got an unexpected issue from Issue Tracker: %s", issue_id ) continue processed_ids.add(issue_id) try: tracker_handler.handle_assessment_sync( issue_info, issue_id, issuetracker_state ) except Exception as ex: # pylint: disable=broad-except logger.error( "Unhandled synchronization error: %s %s %s", issue_id, issue_info, ex ) continue logger.info("Sync is done, %d issue(s) were processed.", len(processed_ids)) _check_missing_ids(assessment_issues, processed_ids)
def test_collect_assessment_issues(self): """Tests collection issues associated with Assessments.""" assessment1_mock = mock.MagicMock(id=1, status='In Review') issue1_mock = mock.MagicMock( issue_tracked_obj=assessment1_mock, component_id='1', issue_id='t1', issue_type='bug1', issue_priority='P1', issue_severity='S1', due_date=None, reporter='*****@*****.**', assignee='*****@*****.**' ) issue2_mock = mock.MagicMock( issue_tracked_obj=None, component_id=None, issue_id='t2', issue_type='bug2', issue_priority='P3', issue_severity='S3', due_date=None ) filter_mock = mock.MagicMock() filter_mock.return_value.order_by.return_value.all.return_value = [ issue1_mock, issue2_mock, ] with mock.patch.multiple( sync_utils.models.IssuetrackerIssue, query=mock.MagicMock(filter=filter_mock) ): actual = sync_utils.collect_issue_tracker_info("Assessment") self.assertEquals(actual, { 't1': { 'object_id': 1, 'object': assessment1_mock, 'state': { 'component_id': '1', 'status': 'In Review', 'type': 'bug1', 'priority': 'P1', 'severity': 'S1', 'due_date': None, 'reporter': '*****@*****.**', 'assignee': '*****@*****.**' }, } })
def sync_assessment_attributes(): # noqa """Synchronizes issue tracker ticket statuses with the Assessment statuses. Checks for Assessments which are in sync with Issue Tracker issues and updates their statuses in accordance to the corresponding Assessments if differ. """ assessment_issues = sync_utils.collect_issue_tracker_info("Assessment", include_ccs=True) if not assessment_issues: return logger.debug("Syncing state of %d issues.", len(assessment_issues)) cli = issues.Client() processed_ids = set() for batch in sync_utils.iter_issue_batches(assessment_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id, issue_info = _get_issue_info_by_issue_id( issue_id, assessment_issues) if not issue_info: logger.warning( "Got an unexpected issue from Issue Tracker: %s", issue_id) continue object_id = issue_info["object_id"] processed_ids.add(issue_id) issue_payload = _prepare_issue_payload(issue_info) if not _is_need_synchronize_issue(object_id, issue_payload, issuetracker_state): continue _update_issue(cli, issue_id, object_id, issue_payload) logger.debug("Sync is done, %d issue(s) were processed.", len(processed_ids)) _check_missing_ids(assessment_issues, processed_ids)