def test_accepts_default(self): '''accepts(): default configuration''' # by default crash DBs accept any type self.assertTrue(self.crashes.accepts(apport.Report('Crash'))) self.assertTrue(self.crashes.accepts(apport.Report('Bug'))) self.assertTrue(self.crashes.accepts(apport.Report('weirdtype')))
def test_check_duplicate_multiple_masters(self): '''check_duplicate() with multiple master bugs Due to the unavoidable jitter in gdb stack traces, it can happen that a bug B has the same symbolic signature as a bug S, but the same address signature as a bug A, where A and S have slightly different symbolic and address signatures and thus were not identified as duplicates. In that case we want the lowest ID to become the new master bug, and the other two duplicates. ''' a = apport.Report() a['SourcePackage'] = 'bash' a['Package'] = 'bash 5' a.crash_signature = lambda: '/bin/bash:11:read:main' a.crash_signature_addresses = lambda: '/bin/bash:11:/lib/libc.so+123:/bin/bash+DEAD' self.assertEqual(self.crashes.get_comment_url(a, self.crashes.upload(a)), 'http://bash.bugs.example.com/5') s = apport.Report() s['SourcePackage'] = 'bash' s['Package'] = 'bash 5' s.crash_signature = lambda: '/bin/bash:11:__getch:read:main' s.crash_signature_addresses = lambda: '/bin/bash:11:/lib/libc.so+BEEF:/lib/libc.so+123:/bin/bash+DEAD' self.assertEqual(self.crashes.get_comment_url(s, self.crashes.upload(s)), 'http://bash.bugs.example.com/6') # same addr sig as a, same symbolic sig as s b = apport.Report() b['SourcePackage'] = 'bash' b['Package'] = 'bash 5' b.crash_signature = lambda: '/bin/bash:11:__getch:read:main' b.crash_signature_addresses = lambda: '/bin/bash:11:/lib/libc.so+123:/bin/bash+DEAD' self.assertEqual(self.crashes.get_comment_url(b, self.crashes.upload(b)), 'http://bash.bugs.example.com/7') self.crashes.init_duplicate_db(':memory:') self.assertEqual(self.crashes.check_duplicate(5, a), None) # a and s have slightly different sigs -> no dupe self.assertEqual(self.crashes.check_duplicate(6, s), None) # now throw the interesting b at it self.assertEqual(self.crashes.check_duplicate(7, b), (5, None)) # s and b should now be duplicates of a self.assertEqual(self.crashes.duplicate_of(5), None) self.assertEqual(self.crashes.duplicate_of(6), 5) self.assertEqual(self.crashes.duplicate_of(7), 5) # sig DB should only have a now self.assertEqual(self.crashes._duplicate_db_dump(), {'/bin/bash:11:read:main': (5, None)}) # addr DB should have both possible patterns on a self.assertEqual(self.crashes._duplicate_search_address_signature(b.crash_signature_addresses()), 5) self.assertEqual(self.crashes._duplicate_search_address_signature(s.crash_signature_addresses()), 5)
def test_1_report_python(self): '''upload() and get_comment_url() for Python crash This needs to run early, since it sets python_report. ''' r = apport.Report('Crash') r['ExecutablePath'] = '/bin/foo' r['Traceback'] = '''Traceback (most recent call last): File "/bin/foo", line 67, in fuzz print weird NameError: global name 'weird' is not defined''' r.add_package_info(self.test_package) r.add_os_info() r.add_user_info() self.assertEqual(r.standard_title(), 'foo crashed with NameError in fuzz()') handle = self.crashdb.upload(r) self.assert_(handle) url = self.crashdb.get_comment_url(r, handle) self.assert_(url) id = self._fill_bug_form(url) self.assert_(id > 0) global python_report python_report = id print >> sys.stderr, '(https://staging.launchpad.net/bugs/%i) ' % id,
def upload_file_to_bug(bugnum, file_): if not APPORT: # We guard against this by checking for APPORT when the script # first runs (see bottom of this file). Just in case we get # here without apport, inform the user and skip this routine. print("Apport not available in this environment. " "Skipping upload file to bug.") return crashdb = crashdb = apport.crashdb.get_crashdb(None) if not crashdb.can_update(bugnum): print( dedent(""" You are not the reporter or subscriber of this problem report, or the report is a duplicate or already closed. Please create a new report on https://bugs.launchpad.net/charms. """)) return False is_reporter = crashdb.is_reporter(bugnum) report = apport.Report('Bug') apport.hookutils.attach_file(report, file_, overwrite=False) if len(report) != 0: print("Starting upload to lp:%s" % bugnum) crashdb.update(bugnum, report, 'apport information', change_description=is_reporter, attachment_comment='juju crashdump')
def test_apport_bug_package_layout_load_file(self): '''bug layout from a loaded report''' self.app.report_file = '/tmp/foo.apport' self.app.report = apport.Report('Bug') self.app.report['Package'] = 'libfoo1' self.app.report['SourcePackage'] = 'foo' GLib.idle_add(Gtk.main_quit) self.app.ui_present_report_details(True) self.assertEqual( self.app.w('title_label').get_text(), _('Send problem report to the developers?')) self.assertFalse(self.app.w('subtitle_label').get_property('visible')) send_error_report = self.app.w('send_error_report') self.assertFalse(send_error_report.get_property('visible')) self.assertTrue(send_error_report.get_active()) self.assertFalse(self.app.w('show_details').get_property('visible')) self.assertTrue(self.app.w('continue_button').get_property('visible')) self.assertEqual(self.app.w('continue_button').get_label(), _('Send')) self.assertFalse(self.app.w('closed_button').get_property('visible')) self.assertTrue(self.app.w('cancel_button').get_property('visible')) self.assertTrue( self.app.w('details_scrolledwindow').get_property('visible')) self.assertTrue(self.app.w('dialog_crash_new').get_resizable())
def test_gcc_ide_hook_file(self): '''gcc_ice_hook with a temporary file.''' (gcc_version, gcc_path) = self._gcc_version_path() test_source = tempfile.NamedTemporaryFile() test_source.write(b'int f(int x);') test_source.flush() test_source.seek(0) self.assertEqual( subprocess.call( ['%s/gcc_ice_hook' % datadir, gcc_path, test_source.name]), 0, 'gcc_ice_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'gcc_ice_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'Crash') self.assertEqual(r['ExecutablePath'], gcc_path) self.assertEqual(r['PreprocessedSource'], test_source.read().decode()) r.add_package_info() self.assertEqual(r['Package'].split()[0], 'gcc-' + gcc_version) self.assertTrue(r['SourcePackage'].startswith('gcc'))
def setUp(self): self.report_dir = tempfile.mkdtemp() apport.fileutils.report_dir = self.report_dir os.environ['APPORT_REPORT_DIR'] = self.report_dir # do not cause eternal hangs because of error dialog boxes os.environ['APPORT_DISABLE_DISTRO_CHECK'] = '1' saved = sys.argv[0] # Work around GTKUserInterface using basename to find the GtkBuilder UI # file. sys.argv[0] = apport_gtk_path self.app = GTKUserInterface() sys.argv[0] = saved # use in-memory crashdb self.app.crashdb = apport.crashdb_impl.memory.CrashDatabase(None, {}) # test report self.app.report_file = os.path.join(self.report_dir, 'bash.crash') self.app.report = apport.Report() self.app.report['ExecutablePath'] = '/bin/bash' self.app.report['Signal'] = '11' self.app.report['CoreDump'] = b'\x01\x02' self.app.report['DistroRelease'] = self.distro with open(self.app.report_file, 'wb') as f: self.app.report.write(f) # disable package hooks, as they might ask for sudo password and other # interactive bits; allow tests to install their own hooks self.hook_dir = tempfile.mkdtemp() apport.report._hook_dir = self.hook_dir apport.report._common_hook_dir = self.hook_dir
def test_gcc_ide_hook_pipe(self): '''gcc_ice_hook with piping.''' (gcc_version, gcc_path) = self._gcc_version_path() test_source = 'int f(int x);' hook = subprocess.Popen(['%s/gcc_ice_hook' % datadir, gcc_path, '-'], stdin=subprocess.PIPE) hook.communicate(test_source.encode()) self.assertEqual(hook.returncode, 0, 'gcc_ice_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'gcc_ice_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'Crash') self.assertEqual(r['ExecutablePath'], gcc_path) self.assertEqual(r['PreprocessedSource'], test_source) r.add_package_info() self.assertEqual(r['Package'].split()[0], 'gcc-' + gcc_version) self.assertTrue(r['SourcePackage'].startswith('gcc'))
def test_kernel_oops_hook(self): test_source = '''------------[ cut here ]------------ kernel BUG at /tmp/oops.c:5! invalid opcode: 0000 [#1] SMP Modules linked in: oops cpufreq_stats ext2 i915 drm nf_conntrack_ipv4 ipt_REJECT iptable_filter ip_tables nf_conntrack_ipv6 xt_state nf_conntrack xt_tcpudp ip6t_ipv6header ip6t_REJECT ip6table_filter ip6_tables x_tables ipv6 loop dm_multipath rtc_cmos iTCO_wdt iTCO_vendor_support pcspkr i2c_i801 i2c_core battery video ac output power_supply button sg joydev usb_storage dm_snapshot dm_zero dm_mirror dm_mod ahci pata_acpi ata_generic ata_piix libata sd_mod scsi_mod ext3 jbd mbcache uhci_hcd ohci_hcd ehci_hcd ''' hook = subprocess.Popen(['%s/kernel_oops' % datadir], stdin=subprocess.PIPE) hook.communicate(test_source.encode()) self.assertEqual(hook.returncode, 0, 'kernel_oops finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'kernel_oops created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'KernelOops') self.assertEqual(r['OopsText'], test_source) r.add_package_info(r['Package']) self.assertTrue(r['Package'].startswith('linux-image-')) self.assertIn('Uname', r)
def test_check_duplicate_custom_signature(self): '''check_duplicate() with custom DuplicateSignature: field''' r = apport.Report() r['SourcePackage'] = 'bash' r['Package'] = 'bash 5' r['DuplicateSignature'] = 'Code42Blue' self.assertEqual( self.crashes.get_comment_url(r, self.crashes.upload(r)), 'http://bash.bugs.example.com/5') self.crashes.init_duplicate_db(':memory:') self.assertEqual(self.crashes.check_duplicate(5), None) self.assertEqual(self.crashes._duplicate_db_dump(), {'Code42Blue': (5, None)}) # this one has a standard crash_signature self.assertEqual(self.crashes.check_duplicate(0), None) # ... but DuplicateSignature wins self.crashes.download(0)['DuplicateSignature'] = 'Code42Blue' self.assertEqual(self.crashes.check_duplicate(0), (5, None)) self.crashes.download(1)['DuplicateSignature'] = 'CodeRed' self.assertEqual(self.crashes.check_duplicate(1), None) self.assertEqual( self.crashes._duplicate_db_dump(), { 'Code42Blue': (5, None), 'CodeRed': (1, None), self.crashes.download(0).crash_signature(): (0, None) })
def test_kernel_crashdump_kexec(self): '''kernel_crashdump using kexec-tools.''' f = open(os.path.join(apport.fileutils.report_dir, 'vmcore'), 'wb') f.write(b'\x01' * 100) f.close() f = open(os.path.join(apport.fileutils.report_dir, 'vmcore.log'), 'w') f.write('vmcore successfully dumped') f.close() self.assertEqual(subprocess.call('%s/kernel_crashdump' % datadir), 0, 'kernel_crashdump finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'kernel_crashdump created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual( set(r.keys()), set([ 'Date', 'Package', 'ProblemType', 'VmCore', 'VmCoreLog', 'Uname', 'Architecture', 'DistroRelease' ])) self.assertEqual(r['ProblemType'], 'KernelCrash') self.assertEqual(r['VmCoreLog'], 'vmcore successfully dumped') self.assertEqual(r['VmCore'], b'\x01' * 100) self.assertTrue('linux' in r['Package']) self.assertTrue(os.uname()[2].split('-')[0] in r['Package']) r.add_package_info(r['Package']) self.assertTrue(' ' in r['Package']) # appended version number
def setUp(self): global crashdb if not crashdb: crashdb = self._get_instance() self.crashdb = crashdb # create a local reference report so that we can compare # DistroRelease, Architecture, etc. self.ref_report = apport.Report() self.ref_report.add_os_info() self.ref_report.add_user_info()
def test_accepts_problem_types(self): '''accepts(): problem_types option in crashdb.conf''' # create a crash DB with type limits crashdb_conf = tempfile.NamedTemporaryFile() crashdb_conf.write(b'''default = 'testsuite' databases = { 'testsuite': { 'impl': 'memory', 'problem_types': ['Bug', 'Kernel'], }, } ''') crashdb_conf.flush() db = apport.crashdb.get_crashdb(None, None, crashdb_conf.name) self.assertTrue(db.accepts(apport.Report('Bug'))) self.assertFalse(db.accepts(apport.Report('Crash'))) self.assertFalse(db.accepts(apport.Report('weirdtype')))
def create_report_from_bson(data): report = apport.Report() for key in data: try: report[key.encode('UTF-8')] = data[key].encode('UTF-8') except AssertionError: # apport raises an AssertionError if a key is invalid, given that # the crash has already been written to the OOPS CF, skip the key # and continue bucketing metrics.meter('invalid.invalid_key') msg = 'Invalid key (%s) in report' % (key) logger.info(msg) continue return report
def from_file(cls, reporter, fpath): base = os.path.splitext(os.path.basename(fpath))[0] report = cls( reporter, base, pr=apport.Report(date='???'), state=ErrorReportState.LOADING, file=open(fpath, 'rb'), context=reporter.context.child(base)) try: fp = open(report.meta_path, 'r') except FileNotFoundError: pass else: with fp: report.meta = json.load(fp) return report
def test_project(self): '''reporting crashes against a project instead of a distro''' # crash database for langpack-o-matic project (this does not have # packages in any distro) crashdb = CrashDatabase(os.environ.get('LP_CREDENTIALS'), '', { 'project': 'langpack-o-matic', 'staging': True }) self.assertEqual(crashdb.distro, None) # create Python crash report r = apport.Report('Crash') r['ExecutablePath'] = '/bin/foo' r['Traceback'] = '''Traceback (most recent call last): File "/bin/foo", line 67, in fuzz print weird NameError: global name 'weird' is not defined''' r.add_os_info() r.add_user_info() self.assertEqual(r.standard_title(), 'foo crashed with NameError in fuzz()') # file it handle = crashdb.upload(r) self.assert_(handle) url = crashdb.get_comment_url(r, handle) self.assert_('launchpad.net/langpack-o-matic/+filebug' in url) id = self._fill_bug_form_project(url) self.assert_(id > 0) print >> sys.stderr, '(https://staging.launchpad.net/bugs/%i) ' % id, # update r = crashdb.download(id) r['StacktraceTop'] = 'read () from /lib/libc.6.so\nfoo (i=1) from /usr/lib/libfoo.so' r['Stacktrace'] = 'long\ntrace' r['ThreadStacktrace'] = 'thread\neven longer\ntrace' crashdb.update(id, r, 'good retrace!') r = crashdb.download(id) # test fixed version self.assertEqual(crashdb.get_fixed_version(id), None) crashdb.close_duplicate(id, self.known_test_id) self.assertEqual(crashdb.duplicate_of(id), self.known_test_id) self.assertEqual(crashdb.get_fixed_version(id), 'invalid') crashdb.close_duplicate(id, None) self.assertEqual(crashdb.duplicate_of(id), None) self.assertEqual(crashdb.get_fixed_version(id), None)
def new(cls, controller, kind): base = "installer.{:.9f}.{}".format(time.time(), kind.name.lower()) crash_file = open( os.path.join(controller.crash_directory, base + ".crash"), 'wb') pr = apport.Report('Bug') pr['CrashDB'] = repr(controller.crashdb_spec) r = cls(controller=controller, base=base, pr=pr, file=crash_file, state=ErrorReportState.INCOMPLETE) r.set_meta("kind", kind.name) return r
def test_update_traces(self): '''update_traces()''' r = apport.Report() r['Package'] = 'new' r['FooBar'] = 'Bogus' r['StacktraceTop'] = 'Fresh!' self.crashes.update_traces(1, r, 'muhaha') self.assertEqual(self.crashes.reports[1]['comment'], 'muhaha') self.assertEqual(self.crashes.download(1)['Package'], 'libfoo1 1.2-4') self.assertEqual(self.crashes.download(1)['StacktraceTop'], 'Fresh!') self.assertFalse('FooBar' in self.crashes.download(1)) self.assertRaises(IndexError, self.crashes.update_traces, 5, None)
def test_update(self): '''update()''' r = apport.Report() r['Package'] = 'new' r['FooBar'] = 'Bogus' r['StacktraceTop'] = 'Fresh!' self.crashes.update(1, r, 'muhaha') self.assertEqual(self.crashes.reports[1]['comment'], 'muhaha') self.assertEqual(self.crashes.download(1)['Package'], 'new') self.assertEqual(self.crashes.download(1)['StacktraceTop'], 'Fresh!') self.assertEqual(self.crashes.download(1)['FooBar'], 'Bogus') self.assertRaises(IndexError, self.crashes.update, 5, None, '')
def test_package_hook_logs(self): '''package_hook with a log dir and a log file.''' with open(os.path.join(self.workdir, 'log_1.log'), 'w') as f: f.write('Log 1\nbla') with open(os.path.join(self.workdir, 'log2'), 'w') as f: f.write('Yet\nanother\nlog') os.mkdir(os.path.join(self.workdir, 'logsub')) with open(os.path.join(self.workdir, 'logsub', 'notme.log'), 'w') as f: f.write('not me!') ph = subprocess.Popen([ '%s/package_hook' % datadir, '-p', 'bash', '-l', os.path.realpath(sys.argv[0]), '-l', self.workdir ], stdin=subprocess.PIPE) ph.communicate(b'something is wrong') self.assertEqual(ph.returncode, 0, 'package_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'package_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) filekey = None log1key = None log2key = None for k in r.keys(): if k.endswith('Testhookspy'): filekey = k elif k.endswith('Log1log'): log1key = k elif k.endswith('Log2'): log2key = k elif 'sub' in k: self.fail('logsub should not go into log files') self.assertTrue(filekey) self.assertTrue(log1key) self.assertTrue(log2key) self.assertTrue('0234lkjas' in r[filekey]) self.assertEqual(len(r[filekey]), os.path.getsize(sys.argv[0])) self.assertEqual(r[log1key], 'Log 1\nbla') self.assertEqual(r[log2key], 'Yet\nanother\nlog')
def _check_crash_report(self, main_file): '''Check that we have one crash report, and verify its contents''' reports = apport.fileutils.get_new_reports() self.assertEqual(len(reports), 1, 'did not create a crash report') r = apport.Report() with open(reports[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'Crash') self.assertTrue(r['ProcCmdline'].startswith('java -classpath'), r) self.assertTrue(r['StackTrace'].startswith( "java.lang.RuntimeException: Can't catch this")) if '.jar!' in main_file: self.assertEqual(r['MainClassUrl'], 'jar:file:' + main_file) else: self.assertEqual(r['MainClassUrl'], 'file:' + main_file) self.assertTrue('DistroRelease' in r) self.assertTrue('ProcCwd' in r)
def create_report(error, traceback, trans=None): """Create an apport problem report for a given crash. :param error: The summary of the error. :param traceback: The traceback of the exception. :param trans: The optional transaction in which the crash occured. """ if not apport.packaging.enabled() or os.getcwd() != "/": return uid = 0 report = apport.Report("Crash") report["Title"] = error package = "aptdaemon" try: package_version = apport.packaging.get_version(package) except ValueError as e: if 'does not exist' in e.message: package_version = 'unknown' report['Package'] = '%s %s' % (package, package_version) report["SourcePackage"] = "aptdaemon" report["Traceback"] = traceback report["ExecutablePath"] = "/usr/sbin/aptd" report.add_os_info() # Attach information about the transaction if trans: report["Annotation"] = enums.get_role_error_from_enum(trans.role) report["TransactionRole"] = trans.role report["TransactionPackages"] = str([list(l) for l in trans.packages]) report["TransactionDepends"] = str([list(l) for l in trans.depends]) report["TransactionKwargs"] = str(trans.kwargs) report["TransactionLocale"] = trans.locale report["TransactionOutput"] = trans.output report["TransactionErrorCode"] = trans._error_property[0] report["TransactionErrorDetails"] = trans._error_property[1] uid = os.path.basename(trans.tid) # Write report report_path = apport.fileutils.make_report_path(report, uid) if not os.path.exists(report_path): report.write(open(report_path, 'wb'))
def test_package_hook_uninstalled(self): '''package_hook on an uninstalled package (might fail to install).''' pkg = apport.packaging.get_uninstalled_package() ph = subprocess.Popen(['%s/package_hook' % datadir, '-p', pkg], stdin=subprocess.PIPE) ph.communicate(b'something is wrong') self.assertEqual(ph.returncode, 0, 'package_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'package_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'Package') self.assertEqual(r['Package'], pkg + ' (not installed)') self.assertEqual(r['ErrorMessage'], 'something is wrong')
def test_package_hook_nologs(self): '''package_hook without any log files.''' ph = subprocess.Popen(['%s/package_hook' % datadir, '-p', 'bash'], stdin=subprocess.PIPE) ph.communicate(b'something is wrong') self.assertEqual(ph.returncode, 0, 'package_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'package_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['ProblemType'], 'Package') self.assertEqual(r['Package'], 'bash') self.assertEqual(r['SourcePackage'], 'bash') self.assertEqual(r['ErrorMessage'], 'something is wrong')
def setUp(self): super(TestBinarySubmission, self).setUp() self.stack_addr_sig = ( '/usr/bin/foo:11:x86_64/lib/x86_64-linux-gnu/libc-2.15.so+e4d93:' '/usr/bin/foo+1e071') report = apport.Report() report['ProblemType'] = 'Crash' report['StacktraceAddressSignature'] = self.stack_addr_sig report['ExecutablePath'] = '/usr/bin/foo' report['Package'] = 'whoopsie 1.2.3' report['DistroRelease'] = 'Ubuntu 12.04' report['StacktraceTop'] = 'raise () from /lib/i386-linux-gnu/libc.so.6' report['Signal'] = '11' report_bson = bson.BSON.encode(report.data) report_io = StringIO(report_bson) self.environ = { 'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': sha512_system_uuid, 'wsgi.input': report_io }
def test_package_hook_tags(self): '''package_hook with extra tags argument.''' ph = subprocess.Popen([ '%s/package_hook' % datadir, '-p', 'bash', '-t', 'dist-upgrade, verybad' ], stdin=subprocess.PIPE) ph.communicate(b'something is wrong') self.assertEqual(ph.returncode, 0, 'package_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'package_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['Tags'], 'dist-upgrade verybad')
def test_check_duplicate_utf8(self): '''check_duplicate() with UTF-8 strings''' # assertion failure, with UTF-8 strings r = apport.Report() r['Package'] = 'bash 5' r['SourcePackage'] = 'bash' r['DistroRelease'] = 'Testux 2.2' r['ExecutablePath'] = '/bin/bash' r['Signal'] = '6' r['AssertionMessage'] = 'Afirmação x != 0' self.assertEqual(self.crashes.get_comment_url(r, self.crashes.upload(r)), 'http://bash.bugs.example.com/5') self.assertEqual(self.crashes.get_comment_url(r, self.crashes.upload(r)), 'http://bash.bugs.example.com/6') self.crashes.init_duplicate_db(':memory:') self.assertEqual(self.crashes.check_duplicate(5), None) self.assertEqual(self.crashes.check_duplicate(6), (5, None)) self.crashes.duplicate_db_publish(self.dupdb_dir)
def test_gcc_ide_hook_file_binary(self): '''gcc_ice_hook with a temporary file with binary data.''' (gcc_version, gcc_path) = self._gcc_version_path() test_source = tempfile.NamedTemporaryFile() test_source.write(b'int f(int x); \xFF\xFF') test_source.flush() test_source.seek(0) self.assertEqual( subprocess.call( ['%s/gcc_ice_hook' % datadir, gcc_path, test_source.name]), 0, 'gcc_ice_hook finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'gcc_ice_hook created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual(r['PreprocessedSource'], test_source.read())
def main(): for key, o in oops_cf.get_range(**kwargs): print_totals() if 'DuplicateSignature' in o: handle_duplicate_signature(key, o) continue report = apport.Report() for k in o: report[k.encode('utf-8')] = o[k][0].encode('utf-8') crash_signature = report.crash_signature() if crash_signature: crash_signature = crash_signature[:32768] if 'Traceback' in o: counts['python'] += 1 elif 'OopsText' in o: counts['kernel_oops'] += 1 update_bucketversions(crash_signature, o, key) elif 'StacktraceTop' in o and 'Signal' in o: if 'StacktraceAddressSignature' not in o: counts['no_sas'] += 1 if not repair_sas(key, o, report): continue handle_binary(key, o) else: if 'Signal' in o: # We don't have a stacktrace for this signal failure. sig = o['Signal'][0] counts['sig%s' % sig] += 1 if 'Traceback' in o: # We don't have a long enough Traceback to form a signature. # These should be replaced with a better signature function # that works with short tracebacks. counts['poor_tb'] += 1 counts['unknown'] += 1 print_totals(force=True)
def test_kernel_crashdump_kdump(self): '''kernel_crashdump using kdump-tools.''' timedir = datetime.strftime(datetime.now(), '%Y%m%d%H%M') vmcore_dir = os.path.join(apport.fileutils.report_dir, timedir) os.mkdir(vmcore_dir) dmesgfile = os.path.join(vmcore_dir, 'dmesg.' + timedir) f = open(dmesgfile, 'wt') f.write('1' * 100) f.close() self.assertEqual(subprocess.call('%s/kernel_crashdump' % datadir), 0, 'kernel_crashdump finished successfully') reps = apport.fileutils.get_new_reports() self.assertEqual(len(reps), 1, 'kernel_crashdump created a report') r = apport.Report() with open(reps[0], 'rb') as f: r.load(f) self.assertEqual( set(r.keys()), set([ 'Date', 'Package', 'ProblemType', 'VmCoreDmesg', 'Uname', 'Architecture', 'DistroRelease' ])) self.assertEqual(r['ProblemType'], 'KernelCrash') self.assertEqual(r['VmCoreDmesg'], '1' * 100) self.assertTrue('linux' in r['Package']) self.assertTrue(os.uname()[2].split('-')[0] in r['Package']) r.add_package_info(r['Package']) self.assertTrue(' ' in r['Package']) # appended version number