620
621
optparser = optparse.OptionParser(_('%prog [options] [symptom|pid|package|program path|.apport/.crash file]'))
621
optparser.add_option('-f', '--file-bug',
622
help=_('Start in bug filing mode. Requires --package and an optional --pid, or just a --pid. If neither is given, display a list of known symptoms. (Implied if a single argument is given.)'),
623
action='store_true', dest='filebug', default=False)
624
optparser.add_option('-u', '--update-bug', type='int',
625
help=_('Start in bug updating mode. Can take an optional --package.'),
626
dest='update_report')
622
optparser.add_option('-f', '--file-bug', action='store_true',
623
dest='filebug', default=False,
624
help=_('Start in bug filing mode. Requires --package and an optional --pid, or just a --pid. If neither is given, display a list of known symptoms. (Implied if a single argument is given.)'))
625
optparser.add_option('-u', '--update-bug', type='int', dest='update_report',
626
help=_('Start in bug updating mode. Can take an optional --package.'))
627
627
optparser.add_option('-s', '--symptom', metavar='SYMPTOM',
628
help=_('File a bug report about a symptom. (Implied if symptom name is given as only argument.)'),
628
help=_('File a bug report about a symptom. (Implied if symptom name is given as only argument.)'))
630
629
optparser.add_option('-p', '--package',
631
help=_('Specify package name in --file-bug mode. This is optional if a --pid is specified. (Implied if package name is given as only argument.)'),
632
action='store', type='string', dest='package', default=None)
633
optparser.add_option('-P', '--pid',
634
help=_('Specify a running program in --file-bug mode. If this is specified, the bug report will contain more information. (Implied if pid is given as only argument.)'),
635
action='store', type='int', dest='pid', default=None)
636
optparser.add_option('-c', '--crash-file',
637
help=_('Report the crash from given .apport or .crash file instead of the pending ones in %s. (Implied if file is given as only argument.)') % apport.fileutils.report_dir,
638
action='store', type='string', dest='crash_file', default=None, metavar='PATH')
639
optparser.add_option('--save',
640
help=_('In --file-bug mode, save the collected information into a file instead of reporting it. This file can then be reported with --crash-file later on.'),
641
type='string', dest='save', default=None, metavar='PATH')
642
optparser.add_option('-v', '--version',
643
help=_('Print the Apport version number.'),
644
action='store_true', dest='version', default=None)
630
help=_('Specify package name in --file-bug mode. This is optional if a --pid is specified. (Implied if package name is given as only argument.)'))
631
optparser.add_option('-P', '--pid', type='int',
632
help=_('Specify a running program in --file-bug mode. If this is specified, the bug report will contain more information. (Implied if pid is given as only argument.)'))
633
optparser.add_option('-c', '--crash-file', metavar='PATH',
634
help=_('Report the crash from given .apport or .crash file instead of the pending ones in %s. (Implied if file is given as only argument.)') % apport.fileutils.report_dir)
635
optparser.add_option('--save', metavar='PATH',
636
help=_('In bug filing mode, save the collected information into a file instead of reporting it. This file can then be reported later on from a different machine.'))
637
optparser.add_option('--tag', action='append', default=[],
638
help=_('Add an extra tag to the report. Can be specified multiple times.'))
639
optparser.add_option('-v', '--version', action='store_true',
640
help=_('Print the Apport version number.'))
642
if len(sys.argv) > 0 and cmd.endswith('-bug'):
643
for o in ('-f', '-u', '-s', '-p', '-P', '-c'):
644
optparser.get_option(o).help = optparse.SUPPRESS_HELP
646
646
(self.options, self.args) = optparser.parse_args()
2521
2537
self.assertRaises(SystemExit, self.ui.run_argv)
2522
2538
err = sys.stderr.getvalue()
2523
2539
sys.stderr = orig_stderr
2524
self.assert_('crash.py crashed:' in err)
2525
self.assert_('ZeroDivisionError:' in err)
2540
self.assertTrue('crash.py crashed:' in err)
2541
self.assertTrue('ZeroDivisionError:' in err)
2527
2543
# working noninteractive script
2528
2544
f = open(os.path.join(symptom_script_dir, 'itching.py'), 'w')
2529
print >> f, 'def run(report, ui):\n report["itch"] = "scratch"\n return "bash"'
2545
f.write('def run(report, ui):\n report["itch"] = "scratch"\n return "bash"\n')
2531
2547
sys.argv = ['ui-test', '-s', 'itching' ]
2532
2548
self.ui = _TestSuiteUserInterface()
2533
2549
self.assertEqual(self.ui.run_argv(), True)
2534
2550
self.assertEqual(self.ui.msg_text, None)
2535
2551
self.assertEqual(self.ui.msg_severity, None)
2536
self.assert_(self.ui.present_details_shown)
2552
self.assertTrue(self.ui.present_details_shown)
2538
2554
self.assertEqual(self.ui.report['itch'], 'scratch')
2539
self.assert_('DistroRelease' in self.ui.report)
2555
self.assertTrue('DistroRelease' in self.ui.report)
2540
2556
self.assertEqual(self.ui.report['SourcePackage'], 'bash')
2541
self.assert_(self.ui.report['Package'].startswith('bash '))
2557
self.assertTrue(self.ui.report['Package'].startswith('bash '))
2542
2558
self.assertEqual(self.ui.report['ProblemType'], 'Bug')
2560
# working noninteractive script with extra tag
2561
sys.argv = ['ui-test', '--tag', 'foo', '-s', 'itching' ]
2562
self.ui = _TestSuiteUserInterface()
2563
self.assertEqual(self.ui.run_argv(), True)
2564
self.assertEqual(self.ui.msg_text, None)
2565
self.assertEqual(self.ui.msg_severity, None)
2566
self.assertTrue(self.ui.present_details_shown)
2568
self.assertEqual(self.ui.report['itch'], 'scratch')
2569
self.assertTrue('foo' in self.ui.report['Tags'])
2544
2571
# working interactive script
2545
2572
f = open(os.path.join(symptom_script_dir, 'itching.py'), 'w')
2546
print >> f, '''def run(report, ui):
2573
f.write('''def run(report, ui):
2547
2574
report['itch'] = 'slap'
2548
2575
report['q'] = str(ui.yesno('do you?'))
2552
2579
sys.argv = ['ui-test', '-s', 'itching' ]
2553
2580
self.ui = _TestSuiteUserInterface()
2554
2581
self.ui.question_yesno_response = True
2555
2582
self.assertEqual(self.ui.run_argv(), True)
2556
self.assert_(self.ui.present_details_shown)
2583
self.assertTrue(self.ui.present_details_shown)
2557
2584
self.assertEqual(self.ui.msg_text, 'do you?')
2559
2586
self.assertEqual(self.ui.report['itch'], 'slap')
2560
self.assert_('DistroRelease' in self.ui.report)
2587
self.assertTrue('DistroRelease' in self.ui.report)
2561
2588
self.assertEqual(self.ui.report['SourcePackage'], 'bash')
2562
self.assert_(self.ui.report['Package'].startswith('bash '))
2589
self.assertTrue(self.ui.report['Package'].startswith('bash '))
2563
2590
self.assertEqual(self.ui.report['ProblemType'], 'Bug')
2564
2591
self.assertEqual(self.ui.report['q'], 'True')
2622
2647
# no arguments -> show pending crashes
2623
2648
_chk('apport-gtk', None, {'filebug': False, 'package': None,
2624
2649
'pid': None, 'crash_file': None, 'symptom': None,
2625
'update_report': None, 'save': None})
2626
# ... except when being called as '*-bug', then default to bug mode
2627
_chk('apport-bug', None, {'filebug': True, 'package': None,
2628
'pid': None, 'crash_file': None, 'symptom': None,
2629
'update_report': None, 'save': None})
2650
'update_report': None, 'save': None, 'tag': []})
2630
2651
# updating report not allowed without args
2631
2652
self.assertRaises(SystemExit, _chk, 'apport-collect', None, {})
2634
2655
_chk('apport-kde', 'coreutils', {'filebug': True, 'package':
2635
2656
'coreutils', 'pid': None, 'crash_file': None, 'symptom': None,
2636
'update_report': None, 'save': None})
2637
_chk('apport-bug', 'coreutils', {'filebug': True, 'package':
2638
'coreutils', 'pid': None, 'crash_file': None, 'symptom': None,
2639
'update_report': None, 'save': None})
2640
_chk('apport-bug', 'coreutils', {'filebug': True, 'package':
2641
'coreutils', 'pid': None, 'crash_file': None, 'symptom': None,
2642
'update_report': None, 'save': 'foo.apport'},
2643
['--save', 'foo.apport'])
2657
'update_report': None, 'save': None, 'tag': []})
2645
2659
# symptom is preferred over package
2646
2660
f = open(os.path.join(symptom_script_dir, 'coreutils.py'), 'w')
2647
print >> f, '''description = 'foo does not work'
2661
f.write('''description = 'foo does not work'
2648
2662
def run(report, ui):
2652
2666
_chk('apport-cli', 'coreutils', {'filebug': True, 'package': None,
2653
2667
'pid': None, 'crash_file': None, 'symptom': 'coreutils',
2654
'update_report': None, 'save': None})
2655
_chk('apport-bug', 'coreutils', {'filebug': True, 'package': None,
2656
'pid': None, 'crash_file': None, 'symptom': 'coreutils',
2657
'update_report': None, 'save': None})
2668
'update_report': None, 'save': None, 'tag': []})
2660
2671
_chk('apport-cli', '1234', {'filebug': True, 'package': None,
2661
2672
'pid': '1234', 'crash_file': None, 'symptom': None,
2662
'update_report': None, 'save': None})
2663
_chk('apport-bug', '1234', {'filebug': True, 'package': None,
2664
'pid': '1234', 'crash_file': None, 'symptom': None,
2665
'update_report': None, 'save': None})
2673
'update_report': None, 'save': None, 'tag': []})
2667
2675
# .crash/.apport files; check correct handling of spaces
2668
2676
for suffix in ('.crash', '.apport'):
2669
for prog in ('apport-cli', 'apport-bug'):
2670
_chk(prog, '/tmp/f oo' + suffix, {'filebug': False,
2671
'package': None, 'pid': None,
2672
'crash_file': '/tmp/f oo' + suffix, 'symptom': None,
2673
'update_report': None, 'save': None})
2677
_chk('apport-cli', '/tmp/f oo' + suffix, {'filebug': False,
2678
'package': None, 'pid': None,
2679
'crash_file': '/tmp/f oo' + suffix, 'symptom': None,
2680
'update_report': None, 'save': None, 'tag': []})
2676
2683
_chk('apport-cli', '/usr/bin/tail', {'filebug': True,
2677
2684
'package': 'coreutils',
2678
2685
'pid': None, 'crash_file': None, 'symptom': None,
2679
'update_report': None, 'save': None})
2680
_chk('apport-bug', '/usr/bin/tail', {'filebug': True,
2681
'package': 'coreutils',
2682
'pid': None, 'crash_file': None, 'symptom': None,
2683
'update_report': None, 'save': None})
2686
'update_report': None, 'save': None, 'tag': []})
2685
2688
# update existing report
2686
2689
_chk('apport-collect', '1234', {'filebug': False, 'package': None,
2687
'crash_file': None, 'symptom': None, 'update_report': 1234})
2690
'crash_file': None, 'symptom': None, 'update_report': 1234,
2688
2692
_chk('apport-update-bug', '1234', {'filebug': False, 'package': None,
2689
'crash_file': None, 'symptom': None, 'update_report': 1234})
2693
'crash_file': None, 'symptom': None, 'update_report': 1234,
2696
def test_parse_argv_apport_bug(self):
2697
'''parse_args() option inference when invoked as *-bug'''
2699
def _chk(args, expected_opts):
2700
sys.argv = ['apport-bug'] + args
2701
orig_stderr = sys.stderr
2702
sys.stderr = open('/dev/null', 'w')
2704
ui = UserInterface()
2707
sys.stderr = orig_stderr
2708
expected_opts['version'] = None
2709
self.assertEqual(ui.args, [])
2710
self.assertEqual(ui.options, expected_opts)
2713
# no arguments: default to 'ask for symptom' bug mode
2715
_chk([], {'filebug': True, 'package': None,
2716
'pid': None, 'crash_file': None, 'symptom': None,
2717
'update_report': None, 'save': None, 'tag': []})
2724
_chk(['coreutils'], {'filebug': True, 'package':
2725
'coreutils', 'pid': None, 'crash_file': None, 'symptom': None,
2726
'update_report': None, 'save': None, 'tag': []})
2728
# symptom (preferred over package)
2729
f = open(os.path.join(symptom_script_dir, 'coreutils.py'), 'w')
2730
f.write('''description = 'foo does not work'
2731
def run(report, ui):
2735
_chk(['coreutils'], {'filebug': True, 'package': None,
2736
'pid': None, 'crash_file': None, 'symptom': 'coreutils',
2737
'update_report': None, 'save': None, 'tag': []})
2738
os.unlink(os.path.join(symptom_script_dir, 'coreutils.py'))
2741
_chk(['1234'], {'filebug': True, 'package': None,
2742
'pid': '1234', 'crash_file': None, 'symptom': None,
2743
'update_report': None, 'save': None, 'tag': []})
2745
# .crash/.apport files; check correct handling of spaces
2746
for suffix in ('.crash', '.apport'):
2747
_chk(['/tmp/f oo' + suffix], {'filebug': False,
2748
'package': None, 'pid': None,
2749
'crash_file': '/tmp/f oo' + suffix, 'symptom': None,
2750
'update_report': None, 'save': None, 'tag': []})
2753
_chk(['/usr/bin/tail'], {'filebug': True, 'package': 'coreutils',
2754
'pid': None, 'crash_file': None, 'symptom': None,
2755
'update_report': None, 'save': None, 'tag': []})
2762
_chk(['--save', 'foo.apport', 'coreutils'], {'filebug': True,
2763
'package': 'coreutils', 'pid': None, 'crash_file': None,
2764
'symptom': None, 'update_report': None, 'save': 'foo.apport',
2768
_chk(['--tag', 'foo', 'coreutils'], {'filebug': True,
2769
'package': 'coreutils', 'pid': None, 'crash_file': None,
2770
'symptom': None, 'update_report': None, 'save': None,
2772
_chk(['--tag', 'foo', '--tag', 'bar', 'coreutils'], {
2773
'filebug': True, 'package': 'coreutils', 'pid': None,
2774
'crash_file': None, 'symptom': None, 'update_report': None,
2775
'save': None, 'tag': ['foo', 'bar']})
2691
2777
unittest.main()