Example #1
0
    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')))
Example #2
0
    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)
Example #3
0
        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,
Example #4
0
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')
Example #5
0
    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())
Example #6
0
    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'))
Example #7
0
    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
Example #8
0
    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'))
Example #9
0
    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)
Example #10
0
    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)
            })
Example #11
0
    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
Example #12
0
        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()
Example #13
0
    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')))
Example #14
0
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
Example #15
0
 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
Example #16
0
        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)
Example #17
0
    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
Example #18
0
    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)
Example #19
0
    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, '')
Example #20
0
    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)
Example #22
0
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'))
Example #23
0
    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')
Example #24
0
    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')
Example #25
0
 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
     }
Example #26
0
    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')
Example #27
0
    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)
Example #28
0
    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())
Example #29
0
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)
Example #30
0
    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