Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Unified Diff: appengine/findit/crash/test/findit_test.py

Issue 2414523002: [Findit] Reorganizing findit_for_*.py (Closed)
Patch Set: linting for coverage Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine/findit/crash/test/findit_test.py
diff --git a/appengine/findit/crash/test/findit_test.py b/appengine/findit/crash/test/findit_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e9718c8c163d80dcdd758c8daf386a6adabf376
--- /dev/null
+++ b/appengine/findit/crash/test/findit_test.py
@@ -0,0 +1,220 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+import logging
+
+from crash.crash_report import CrashReport
+from crash.culprit import NullCulprit
+from crash.findit_for_chromecrash import FinditForChromeCrash
+from crash.findit_for_chromecrash import FinditForFracas
+from crash.findit import Findit
+from crash.stacktrace import Stacktrace
+from crash.test.crash_pipeline_test import DummyCrashData
+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
+
+# In production we'd use CrashWrapperPipeline. And that'd work fine here,
+# since we never actually call the method that uses it. But just to be
+# absolutely sure we don't go over the wire due to some mocking failure,
+# we'll use this dummy class instead. (In fact, since it's never used,
+# we don't even need to give a real class; |None| works just fine.)
+MOCK_PIPELINE_CLS = None
+
+def _FinditForFracas():
+ """A helper to pass in the standard pipeline class."""
+ return FinditForFracas(MOCK_PIPELINE_CLS)
+
+
+class UnsupportedClient(Findit): # pylint: disable=W0223
+ @property
+ def client_id(self):
+ return self._client_id
+
+ def __init__(self, client_id=None):
+ super(UnsupportedClient, self).__init__(MOCK_PIPELINE_CLS)
+ if client_id is None:
+ client_id = 'unsupported_client'
+ self._client_id = client_id
+
+
+class FindTest(CrashTestCase):
+
+ # TODO(wrengr): make this test more straightforward/immediate; or give
+ # it a better name.
+ def testPlatformRename(self):
+ old_crash_data = DummyCrashData(
+ version = None,
+ platform = 'unix',
+ crash_identifiers = {})
+ # This is just here to match the old tests. Shouldn't actually be necessary.
+ del old_crash_data['customized_data']['historical_metadata']
+
+ testcase = self
+ class _MockFindit(FinditForFracas):
+ def __init__(self):
+ super(_MockFindit, self).__init__(MOCK_PIPELINE_CLS)
+
+ 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'
+ self.assertFalse(_MockFindit().ScheduleNewAnalysis(new_crash_data))
+
+ def testCheckPolicyUnsupportedClient(self):
+ self.assertIsNone(UnsupportedClient().CheckPolicy(DummyCrashData(
+ platform = 'canary',
+ signature = 'sig',
+ )))
+
+ def testCheckPolicyUnsupportedPlatform(self):
+ self.assertIsNone(_FinditForFracas().CheckPolicy(DummyCrashData(
+ platform = 'unsupported_platform')))
+
+ def testCheckPolicyBlacklistedSignature(self):
+ self.assertIsNone(_FinditForFracas().CheckPolicy(DummyCrashData(
+ signature = 'Blacklist marker signature')))
+
+ def testCheckPolicyPlatformRename(self):
+ new_crash_data = _FinditForFracas().CheckPolicy(DummyCrashData(
+ platform = 'linux'))
+ self.assertIsNotNone(new_crash_data,
+ 'FinditForFracas.CheckPolicy unexpectedly returned None')
+ self.assertEqual(new_crash_data['platform'], 'unix')
+
+ def testCreateAnalysisForFracas(self):
+ self.assertIsNotNone(_FinditForFracas().CreateAnalysis(
+ {'signature': 'sig'}))
+
+ def testCreateAnalysisForUnsupportedClientId(self):
+ self.assertIsNone(UnsupportedClient('unsupported_id').CreateAnalysis(
+ {'signature': 'sig'}))
+
+ def testGetAnalysisForFracas(self):
+ crash_identifiers = {'signature': 'sig'}
+ # TODO(wrengr): would be less fragile to call
+ # FinditForFracas.CreateAnalysis instead.
+ analysis = FracasCrashAnalysis.Create(crash_identifiers)
+ analysis.put()
+ self.assertEqual(_FinditForFracas().GetAnalysis(crash_identifiers),
+ analysis)
+
+ def testGetAnalysisForUnsuportedClient(self):
+ crash_identifiers = {'signature': 'sig'}
+ # TODO(wrengr): it'd be less fragile to call FinditForFracas.CreateAnalysis
+ # instead. But we'd need to make UnsupportedClient inherit that
+ # implementation then, rather than inheriting the one from the Findit
+ # base class.
+ analysis = FracasCrashAnalysis.Create(crash_identifiers)
+ analysis.put()
+ self.assertIsNone(
+ UnsupportedClient('Unsupported_client').GetAnalysis(crash_identifiers),
+ 'Unsupported client unexpectedly got analysis %s via identifiers %s'
+ % (analysis, crash_identifiers))
+
+ def testInitializeAnalysisForFracas(self):
+ crash_data = DummyCrashData(platform = 'linux')
+ crash_identifiers = crash_data['crash_identifiers']
+
+ findit_client = _FinditForFracas()
+ analysis = findit_client.CreateAnalysis(crash_identifiers)
+ findit_client._InitializeAnalysis(analysis, crash_data)
+ analysis.put()
+ analysis = findit_client.GetAnalysis(crash_identifiers)
+ self.assertIsNotNone(analysis,
+ 'FinditForFracas.GetAnalysis unexpectedly returned None')
+
+ self.assertEqual(analysis.crashed_version, crash_data['crashed_version'])
+ self.assertEqual(analysis.signature, crash_data['signature'])
+ self.assertEqual(analysis.platform, crash_data['platform'])
+ self.assertEqual(analysis.stack_trace, crash_data['stack_trace'])
+ channel = crash_data['customized_data'].get('channel', None)
+ self.assertIsNotNone(channel,
+ 'channel is unexpectedly not defined in crash_data')
+ self.assertEqual(analysis.channel, channel)
+
+ # TODO(wrengr): what was the purpose of this test? As written it's
+ # just testing that mocking works. I'm guessing it was to check that
+ # we fail when the analysis is for the wrong client_id; but if so,
+ # then we shouldn't need to mock FindCulprit...
+ def testFindCulprit(self):
+ self.mock(FinditForChromeCrash, 'FindCulprit',
+ lambda self, *_: NullCulprit())
+
+ # TODO(wrengr): would be less fragile to call
+ # FinditForFracas.CreateAnalysis instead; though if I'm right about
+ # the original purpose of this test, then this is one of the few
+ # places where calling FracasCrashAnalysis directly would actually
+ # make sense.
+ analysis = FracasCrashAnalysis.Create({'signature': 'sig'})
+ # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set
+ # the client_id?
+ analysis.client_id = CrashClient.FRACAS
+
+ # TODO(wrengr): just test for the NullCulprit directly; instead of
+ # going through |ToDicts|.
+ result, tags = FinditForChromeCrash(MOCK_PIPELINE_CLS
+ ).FindCulprit(analysis).ToDicts()
+ expected_result, expected_tags = NullCulprit().ToDicts()
+ self.assertDictEqual(result, expected_result)
+ self.assertDictEqual(tags, expected_tags)
+
+ def testNeedsNewAnalysisIsTrueIfNoAnalysisYet(self):
+ self.assertTrue(_FinditForFracas()._NeedsNewAnalysis(DummyCrashData()))
+
+ def testNeedsNewAnalysisIsTrueIfLastOneFailed(self):
+ crash_data = DummyCrashData()
+ # TODO(wrengr): would be less fragile to call
+ # FinditForFracas.CreateAnalysis instead.
+ analysis = FracasCrashAnalysis.Create(crash_data['crash_identifiers'])
+ analysis.status = analysis_status.ERROR
+ analysis.put()
+ self.assertTrue(_FinditForFracas()._NeedsNewAnalysis(crash_data))
+
+ def testNeedsNewAnalysisIsFalseIfLastOneIsNotFailed(self):
+ crash_data = DummyCrashData()
+ crash_identifiers = crash_data['crash_identifiers']
+ for status in (analysis_status.PENDING, analysis_status.RUNNING,
+ analysis_status.COMPLETED, analysis_status.SKIPPED):
+ # TODO(wrengr): would be less fragile to call
+ # FinditForFracas.CreateAnalysis instead.
+ analysis = FracasCrashAnalysis.Create(crash_identifiers)
+ analysis.status = status
+ analysis.put()
+ self.assertFalse(_FinditForFracas()._NeedsNewAnalysis(crash_data))
+
+ def testScheduleNewAnalysisSkipsUnsupportedChannel(self):
+ self.assertFalse(_FinditForFracas().ScheduleNewAnalysis(DummyCrashData(
+ version = None,
+ signature = None,
+ crash_identifiers = {},
+ channel = 'unsupported_channel')))
+
+ def testScheduleNewAnalysisSkipsUnsupportedPlatform(self):
+ self.assertFalse(_FinditForFracas().ScheduleNewAnalysis(DummyCrashData(
+ version = None,
+ signature = None,
+ platform = 'unsupported_platform',
+ crash_identifiers = {})))
+
+ def testScheduleNewAnalysisSkipsBlackListSignature(self):
+ self.assertFalse(_FinditForFracas().ScheduleNewAnalysis(DummyCrashData(
+ version = None,
+ signature = 'Blacklist marker signature',
+ crash_identifiers = {})))
+
+ def testScheduleNewAnalysisSkipsIfAlreadyCompleted(self):
+ crash_data = DummyCrashData()
+ crash_identifiers = crash_data['crash_identifiers']
+ # TODO(wrengr): would be less fragile to call
+ # FinditForFracas.CreateAnalysis instead.
+ analysis = FracasCrashAnalysis.Create(crash_identifiers)
+ analysis.status = analysis_status.COMPLETED
+ analysis.put()
+ self.assertFalse(_FinditForFracas().ScheduleNewAnalysis(crash_data))

Powered by Google App Engine
This is Rietveld 408576698