def test_runs_delay_auto_approval(self, _delay_auto_approval_mock): self.scanner_rule.update(action=DELAY_AUTO_APPROVAL) run_action(self.version.id) assert _delay_auto_approval_mock.called _delay_auto_approval_mock.assert_called_with(self.version)
def test_runs_flag_for_human_review(self, flag_for_human_review_mock): self.scanner_rule.update(action=FLAG_FOR_HUMAN_REVIEW) run_action(self.version.id) assert flag_for_human_review_mock.called flag_for_human_review_mock.assert_called_with(self.version)
def test_runs_no_action(self, no_action_mock): self.scanner_rule.update(action=NO_ACTION) run_action(self.version.id) assert no_action_mock.called no_action_mock.assert_called_with(self.version)
def test_returns_when_no_action_found(self, log_mock): self.scanner_rule.delete() run_action(self.version.id) log_mock.assert_called_with('No action to execute for version %s.', self.version.id)
def test_runs_delay_auto_approval_indefinitely( self, _delay_auto_approval_indefinitely_mock): self.scanner_rule.update(action=DELAY_AUTO_APPROVAL_INDEFINITELY) run_action(self.version.id) assert _delay_auto_approval_indefinitely_mock.called _delay_auto_approval_indefinitely_mock.assert_called_with(self.version)
def test_selects_the_action_with_the_highest_severity( self, flag_for_human_review_mock, no_action_mock): # Create another rule and add it to the current scanner result. This # rule is more severe than `rule-1` created in `setUp()`. rule = ScannerRule.objects.create(name='rule-2', scanner=self.scanner, action=FLAG_FOR_HUMAN_REVIEW) self.scanner_result.matched_rules.add(rule) run_action(self.version.id) assert not no_action_mock.called assert flag_for_human_review_mock.called
def test_selects_active_actions_only(self, flag_for_human_review_mock, no_action_mock): # Create another rule and add it to the current scanner result. This # rule is more severe than `rule-1` created in `setUp()`. In this test # case, we disable this rule, though. rule = ScannerRule.objects.create( name='rule-2', scanner=self.scanner, action=FLAG_FOR_HUMAN_REVIEW, is_active=False, ) self.scanner_result.matched_rules.add(rule) run_action(self.version.id) assert no_action_mock.called assert not flag_for_human_review_mock.called
def process(self, version): """Process a single version, figuring out if it should be auto-approved and calling the approval code if necessary.""" already_locked = AutoApprovalSummary.check_is_locked(version) if not already_locked: # Lock the addon for ourselves if possible. Even though # AutoApprovalSummary.create_summary_for_version() will do # call check_is_locked() again later when calculating the verdict, # we have to do it now to prevent overwriting an existing lock with # our own. set_reviewing_cache(version.addon.pk, settings.TASK_USER_ID) try: with transaction.atomic(): log.info('Processing %s version %s...', str(version.addon.name), str(version.version)) if waffle.switch_is_active('run-action-in-auto-approve'): # We want to execute `run_action()` only once. summary_exists = AutoApprovalSummary.objects.filter( version=version).exists() if summary_exists: log.debug('Not running run_action() because it has ' 'already been executed') else: run_action(version.id) summary, info = AutoApprovalSummary.create_summary_for_version( version, dry_run=self.dry_run) self.stats.update({k: int(v) for k, v in info.items()}) if summary.verdict == self.successful_verdict: if summary.verdict == amo.AUTO_APPROVED: self.approve(version) self.stats['auto_approved'] += 1 verdict_string = summary.get_verdict_display() else: verdict_string = '%s (%s)' % ( summary.get_verdict_display(), ', '.join( summary.verdict_info_prettifier(info))) log.info('Auto Approval for %s version %s: %s', str(version.addon.name), str(version.version), verdict_string) # At this point, any exception should have rolled back the transaction, # so even if we did create/update an AutoApprovalSummary instance that # should have been rolled back. This ensures that, for instance, a # signing error doesn't leave the version and its autoapprovalsummary # in conflicting states. except (AutoApprovalNotEnoughFilesError, AutoApprovalNoValidationResultError): log.info( 'Version %s was skipped either because it had no ' 'files or because it had no validation attached.', version) self.stats['error'] += 1 except SigningError: statsd.incr('reviewers.auto_approve.approve.failure') log.info('Version %s was skipped because of a signing error', version) self.stats['error'] += 1 finally: # Always clear our own lock no matter what happens (but only ours). if not already_locked: clear_reviewing_cache(version.addon.pk)
def test_raise_when_action_is_invalid(self): # `12345` is an invalid action ID self.scanner_rule.update(action=12345) with pytest.raises(Exception, match='invalid action 12345'): run_action(self.version.id)