blob: 7add2347c2e1462a009f7e5faa4adda514ba673f [file]
# 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 textwrap
from analysis import callstack_detectors
from analysis.analysis_testcase import AnalysisTestCase
from analysis.clusterfuzz_parser import ClusterfuzzParser
from analysis.clusterfuzz_parser import GetCallStackDetectors
from analysis.stacktrace import StackFrame
from analysis.stacktrace import CallStack
from analysis.stacktrace import Stacktrace
from analysis.type_enums import CallStackFormatType
from analysis.type_enums import CrashType
from analysis.type_enums import LanguageType
from analysis.type_enums import SanitizerType
from libs.deps.dependency import Dependency
class ClusterfuzzParserTest(AnalysisTestCase):
def testGetCallStackDetectors(self):
self.assertTrue(
isinstance(GetCallStackDetectors('android_job', 'abrt')[0],
callstack_detectors.AndroidJobDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', CrashType.DIRECT_LEAK)[0],
callstack_detectors.DirectLeakDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', CrashType.INDIRECT_LEAK)[0],
callstack_detectors.IndirectLeakDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[0],
callstack_detectors.AsanDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[1],
callstack_detectors.MsanDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[2],
callstack_detectors.SyzyasanDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[3],
callstack_detectors.UbsanDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[4],
callstack_detectors.LibFuzzerDetector))
self.assertTrue(
isinstance(GetCallStackDetectors('job', 'abrt')[5],
callstack_detectors.TsanDetector))
def testReturnNoneForEmptyString(self):
parser = ClusterfuzzParser()
deps = {'src': Dependency('src', 'https://repo', '1')}
self.assertIsNone(parser.Parse('', deps, 'asan_job', 'abrt'))
def testReturnNoneForDummyJobType(self):
parser = ClusterfuzzParser()
deps = {'src': Dependency('src', 'https://repo', '1')}
self.assertIsNone(parser.Parse('Crash stack:', deps, 'dummy_job', 'abrt'))
def testChromeCrashParserParseLineMalformatedCallstack(self):
parser = ClusterfuzzParser()
deps = {'src': Dependency('src', 'https://repo', '1')}
stacktrace_string = textwrap.dedent(
"""
Blabla...
==1==ERROR: AddressSanitizer: stack-overflow on address 0x7ffec59ebec0
#0 dummy
#1 dummy
#2 dummy
"""
)
self.assertIsNone(parser.Parse(stacktrace_string, deps, 'asan_job', 'abrt'))
def testClusterfuzzParserParseStacktrace(self):
parser = ClusterfuzzParser()
deps = {'src': Dependency('src', 'https://repo', '1')}
stacktrace_string = textwrap.dedent(
"""
Blabla...
==1==ERROR: AddressSanitizer: stack-overflow on address 0x7ffec59ebec0
#0 0x7f5b944a37bb in a::aa(p* d) src/a.h:225
#1 0x7f5b9449a880 in b::bb(p* d) src/b.h:266:1
#2 0x7f5b9449a880 in c::cc(p* d) src/c.h:281
"""
)
stacktrace = parser.Parse(stacktrace_string, deps, 'asan_job', 'abrt')
stack = CallStack(0, frame_list=[
StackFrame(0, 'src', 'a::aa(p* d)', 'a.h', 'src/a.h', [225]),
StackFrame(1, 'src', 'b::bb(p* d)', 'b.h', 'src/b.h', [266, 267]),
StackFrame(2, 'src', 'c::cc(p* d)', 'c.h', 'src/c.h', [281])])
expected_stacktrace = Stacktrace([stack], stack)
self._VerifyTwoStacktracesEqual(stacktrace, expected_stacktrace)