| Index: appengine/findit/crash/test/crash_pipeline_test.py
|
| diff --git a/appengine/findit/crash/test/crash_pipeline_test.py b/appengine/findit/crash/test/crash_pipeline_test.py
|
| index 634fb7972de839340f775a5dbce4114832189fdd..67972cf9f381cd4c7a81349c5e18c037e66e62fb 100644
|
| --- a/appengine/findit/crash/test/crash_pipeline_test.py
|
| +++ b/appengine/findit/crash/test/crash_pipeline_test.py
|
| @@ -5,126 +5,131 @@ import copy
|
| import json
|
|
|
| from google.appengine.api import app_identity
|
| +from webtest.app import AppError
|
|
|
| from common.pipeline_wrapper import pipeline_handlers
|
| from crash import crash_pipeline
|
| from crash import findit_for_chromecrash
|
| +from crash.culprit import Culprit
|
| +from crash.crash_report import CrashReport
|
| +from crash.findit_for_chromecrash import FinditForFracas
|
| +from crash.stacktrace import Stacktrace
|
| from crash.test.crash_testcase import CrashTestCase
|
| +from crash.type_enums import CrashClient
|
| from model import analysis_status
|
| from model.crash.fracas_crash_analysis import FracasCrashAnalysis
|
|
|
|
|
| +def DummyCrashData(
|
| + version='1',
|
| + signature='signature',
|
| + platform='win',
|
| + stack_trace=None,
|
| + regression_range=None,
|
| + channel='canary',
|
| + historical_metadata=None,
|
| + crash_identifiers=True,
|
| + process_type='browser'):
|
| + if crash_identifiers is True:
|
| + crash_identifiers = {
|
| + 'chrome_version': version,
|
| + 'signature': signature,
|
| + 'channel': channel,
|
| + 'platform': platform,
|
| + 'process_type': process_type,
|
| + }
|
| + return {
|
| + 'crashed_version': version,
|
| + 'signature': signature,
|
| + 'platform': platform,
|
| + 'stack_trace': stack_trace,
|
| + 'regression_range': regression_range,
|
| + 'crash_identifiers': crash_identifiers,
|
| + 'customized_data': {
|
| + 'historical_metadata': None,
|
| + 'channel': channel,
|
| + },
|
| + }
|
| +
|
| +
|
| class CrashPipelineTest(CrashTestCase):
|
| app_module = pipeline_handlers._APP
|
|
|
| def testNoAnalysisIfLastOneIsNotFailed(self):
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': 'canary',
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| + crash_data = DummyCrashData()
|
| + crash_identifiers = crash_data['crash_identifiers']
|
| for status in (analysis_status.PENDING, analysis_status.RUNNING,
|
| analysis_status.COMPLETED, analysis_status.SKIPPED):
|
| analysis = FracasCrashAnalysis.Create(crash_identifiers)
|
| analysis.status = status
|
| analysis.put()
|
| - self.assertFalse(crash_pipeline._NeedsNewAnalysis(
|
| - crash_identifiers, chrome_version, signature, 'fracas',
|
| - platform, None, {'channel': 'canary'}))
|
| + self.assertFalse(FinditForFracas()._NeedsNewAnalysis(crash_data))
|
|
|
| def testAnalysisNeededIfLastOneFailed(self):
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': 'canary',
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| + crash_data = DummyCrashData()
|
| + crash_identifiers = crash_data['crash_identifiers']
|
| analysis = FracasCrashAnalysis.Create(crash_identifiers)
|
| analysis.status = analysis_status.ERROR
|
| analysis.put()
|
| - self.assertTrue(crash_pipeline._NeedsNewAnalysis(
|
| - crash_identifiers, chrome_version, signature, 'fracas',
|
| - platform, None, {'channel': 'canary'}))
|
| + self.assertTrue(FinditForFracas()._NeedsNewAnalysis(crash_data))
|
|
|
| def testAnalysisNeededIfNoAnalysisYet(self):
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': 'canary',
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| - self.assertTrue(crash_pipeline._NeedsNewAnalysis(
|
| - crash_identifiers, chrome_version, signature, 'fracas',
|
| - platform, None, {'channel': 'canary'}))
|
| + crash_data = DummyCrashData()
|
| + self.assertTrue(FinditForFracas()._NeedsNewAnalysis(crash_data))
|
|
|
| def testUnsupportedChannelOrPlatformSkipped(self):
|
| - self.assertFalse(
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - {}, None, None, 'fracas', 'win',
|
| - None, {'channel': 'unsupported_channel',
|
| - 'historical_metadata': None}))
|
| - self.assertFalse(
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - {}, None, None, 'fracas', 'unsupported_platform',
|
| - None, {'channel': 'unsupported_channel',
|
| - 'historical_metadata': None}))
|
| -
|
| - def testBlackListSignatureSipped(self):
|
| - self.assertFalse(
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - {}, None, 'Blacklist marker signature', 'fracas', 'win',
|
| - None, {'channel': 'canary',
|
| - 'historical_metadata': None}))
|
| + crash_data = DummyCrashData(
|
| + version = None,
|
| + signature = None,
|
| + crash_identifiers = {},
|
| + channel = 'unsupported_channel')
|
| + self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
|
| + crash_data['platform'] = 'unsupported_platform'
|
| + self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
|
| +
|
| + def testBlackListSignatureSkipped(self):
|
| + crash_data = DummyCrashData(
|
| + version = None,
|
| + signature = 'Blacklist marker signature',
|
| + crash_identifiers = {})
|
| + self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
|
|
|
| def testPlatformRename(self):
|
| - def _MockNeedsNewAnalysis(*args):
|
| - self.assertEqual(args,
|
| - ({}, None, 'signature', 'fracas', 'unix', None,
|
| - {'channel': 'canary'}))
|
| - return False
|
| -
|
| - self.mock(crash_pipeline, '_NeedsNewAnalysis', _MockNeedsNewAnalysis)
|
| -
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - {}, None, 'signature', 'fracas', 'linux',
|
| - None, {'channel': 'canary'})
|
| + old_crash_data = DummyCrashData(
|
| + version = None,
|
| + platform = 'unix',
|
| + crash_identifiers = {})
|
| + del old_crash_data['customized_data']['historical_metadata']
|
| +
|
| + testcase = self
|
| + class _MockFinditForFracas(FinditForFracas):
|
| + def _NeedsNewAnalysis(self, new_crash_data):
|
| + testcase.assertEqual(self.client_id, CrashClient.FRACAS)
|
| + testcase.assertDictEqual(new_crash_data, old_crash_data)
|
| + return False
|
| +
|
| + new_crash_data = copy.deepcopy(old_crash_data)
|
| + new_crash_data['platform'] = 'linux'
|
| + _MockFinditForFracas().ScheduleNewAnalysis(new_crash_data)
|
|
|
| def testNoAnalysisNeeded(self):
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - channel = 'canary'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': channel,
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| + crash_data = DummyCrashData()
|
| + crash_identifiers = crash_data['crash_identifiers']
|
| analysis = FracasCrashAnalysis.Create(crash_identifiers)
|
| analysis.status = analysis_status.COMPLETED
|
| analysis.put()
|
| -
|
| - self.assertFalse(
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - crash_identifiers, chrome_version, signature, 'fracas',
|
| - platform, None, {'channel': channel,
|
| - 'historical_metadata': None}))
|
| + self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
|
|
|
| def _TestRunningAnalysisForResult(self, analysis_result, analysis_tags):
|
| + # Reconstruct the culprit that gives rise to the analysis_{result,tags}
|
| + mock_culprit = Culprit(
|
| + project = analysis_result.get('suspected_project', None),
|
| + components = analysis_result.get('suspected_components', None),
|
| + cls = analysis_result.get('suspected_cls', None),
|
| + regression_range = analysis_result.get('regression_range', (None, None)),
|
| + algorithm = analysis_tags.get('solution', None),
|
| + )
|
| +
|
| pubsub_publish_requests = []
|
| def Mocked_PublishMessagesToTopic(messages_data, topic):
|
| pubsub_publish_requests.append((messages_data, topic))
|
| @@ -132,40 +137,24 @@ class CrashPipelineTest(CrashTestCase):
|
| Mocked_PublishMessagesToTopic)
|
|
|
| analyzed_crashes = []
|
| - class Mocked_FinditForChromeCrash(object):
|
| - def __init__(self, *_):
|
| - pass
|
| + class _MockFinditForFracas(FinditForFracas):
|
| def FindCulprit(self, *args):
|
| analyzed_crashes.append(args)
|
| - return analysis_result, analysis_tags
|
| - self.mock(findit_for_chromecrash, 'FinditForChromeCrash',
|
| - Mocked_FinditForChromeCrash)
|
| -
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - channel = 'canary'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': channel,
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| - stack_trace = 'frame1\nframe2\nframe3'
|
| - chrome_version = '50.2500.0.1'
|
| - historical_metadata = None
|
| + return mock_culprit
|
|
|
| mock_host = 'https://host.com'
|
| self.mock(app_identity, 'get_default_version_hostname', lambda: mock_host)
|
|
|
| - self.assertTrue(
|
| - crash_pipeline.ScheduleNewAnalysisForCrash(
|
| - crash_identifiers, chrome_version, signature, 'fracas',
|
| - platform, stack_trace,
|
| - {'channel': channel, 'historical_metadata': historical_metadata}))
|
| + crash_data = DummyCrashData(
|
| + version = '50.2500.0.1',
|
| + stack_trace = 'frame1\nframe2\nframe3')
|
| + self.assertTrue(_MockFinditForFracas().ScheduleNewAnalysis(crash_data))
|
|
|
| - self.execute_queued_tasks()
|
| + # We catch and re-raise to clean up the callstack that's reported.
|
| + try:
|
| + self.execute_queued_tasks()
|
| + except AppError, e:
|
| + raise e
|
|
|
| self.assertEqual(1, len(pubsub_publish_requests))
|
|
|
| @@ -181,7 +170,7 @@ class CrashPipelineTest(CrashTestCase):
|
| cl.pop('reason', None)
|
|
|
| expected_messages_data = [json.dumps({
|
| - 'crash_identifiers': crash_identifiers,
|
| + 'crash_identifiers': crash_data['crash_identifiers'],
|
| 'client_id': 'fracas',
|
| 'result': processed_analysis_result,
|
| }, sort_keys=True)]
|
| @@ -189,14 +178,14 @@ class CrashPipelineTest(CrashTestCase):
|
|
|
| self.assertEqual(1, len(analyzed_crashes))
|
| self.assertEqual(
|
| - (signature, platform, stack_trace, chrome_version, None),
|
| + (crash_data['signature'], crash_data['platform'],
|
| + crash_data['stack_trace'], crash_data['chrome_version'], None),
|
| analyzed_crashes[0])
|
|
|
| - analysis = FracasCrashAnalysis.Get(crash_identifiers)
|
| + analysis = FracasCrashAnalysis.Get(crash_data['crash_identifiers'])
|
| self.assertEqual(analysis_result, analysis.result)
|
| return analysis
|
|
|
| -
|
| def testRunningAnalysis(self):
|
| analysis_result = {
|
| 'found': True,
|
| @@ -257,21 +246,14 @@ class CrashPipelineTest(CrashTestCase):
|
| self.assertEqual('core', analysis.solution)
|
|
|
| def testAnalysisAborted(self):
|
| - chrome_version = '1'
|
| - signature = 'signature'
|
| - platform = 'win'
|
| - crash_identifiers = {
|
| - 'chrome_version': chrome_version,
|
| - 'signature': signature,
|
| - 'channel': 'canary',
|
| - 'platform': platform,
|
| - 'process_type': 'browser',
|
| - }
|
| + crash_data = DummyCrashData()
|
| + crash_identifiers = crash_data['crash_identifiers']
|
| analysis = FracasCrashAnalysis.Create(crash_identifiers)
|
| analysis.status = analysis_status.RUNNING
|
| analysis.put()
|
|
|
| - pipeline = crash_pipeline.CrashAnalysisPipeline(crash_identifiers, 'fracas')
|
| - pipeline._SetErrorIfAborted(True)
|
| + pipeline = crash_pipeline.CrashAnalysisPipeline(FinditForFracas(),
|
| + crash_identifiers)
|
| + pipeline._PutAbortedError()
|
| analysis = FracasCrashAnalysis.Get(crash_identifiers)
|
| self.assertEqual(analysis_status.ERROR, analysis.status)
|
|
|