Back to index

apport  2.4
Public Member Functions | Public Attributes | Private Member Functions
test_ui.T Class Reference

List of all members.

Public Member Functions

def setUp
def update_report_file
def tearDown
def test_format_filesize
def test_get_size_loaded
def test_get_size_constructed
def test_load_report
def test_restart
def test_collect_info_distro
def test_collect_info_exepath
def test_collect_info_package
def test_collect_info_permissions
def test_handle_duplicate
def test_run_nopending
def test_run_report_bug_noargs
def test_run_version
def test_run_report_bug_package
def test_run_report_bug_pid_tags
def test_run_report_bug_wrong_pid
def test_run_report_bug_noperm_pid
def test_run_report_bug_unpackaged_pid
def test_run_report_bug_kernel_thread
def test_run_report_bug_file
def test_run_crash
def test_run_crash_abort
def test_run_crash_broken
def test_run_crash_argv_file
def test_run_crash_unreportable
def test_run_crash_ignore
def test_run_crash_nocore
def test_run_crash_preretraced
def test_run_crash_precollected
def test_run_crash_errors
def test_run_crash_uninstalled
def test_run_crash_updated_binary
def test_run_crash_package
def test_run_crash_kernel
def test_run_crash_anonymity
def test_run_crash_anonymity_order
def test_run_crash_anonymity_substring
def test_run_crash_known
def test_run_update_report_nonexisting_package_from_bug
def test_run_update_report_nonexisting_package_cli
def test_run_update_report_existing_package_from_bug
def test_run_update_report_existing_package_cli_tags
def test_run_update_report_existing_package_cli_cmdname
def test_run_update_report_noninstalled_but_hook
def test_run_update_report_different_binary_source
def test_interactive_hooks_information
def test_interactive_hooks_yesno
def test_interactive_hooks_file
def test_interactive_hooks_choices
def test_interactive_hooks_cancel
def test_run_symptom
def test_run_report_bug_list_symptoms
def test_parse_argv_single_arg
def test_parse_argv_apport_bug
def test_can_examine_locally_crash
def test_can_examine_locally_nocrash
def test_db_no_accept
def test_get_desktop_entry
def test_wait_for_pid

Public Attributes

 orig_report_dir
 orig_symptom_script_dir
 orig_ignore_file
 orig_argv
 ui
 report
 report_file
 hookdir
 orig_hook_dir

Private Member Functions

def _find_unused_pid
def _gen_test_crash
def _run_hook

Detailed Description

Definition at line 122 of file test_ui.py.


Member Function Documentation

def test_ui.T._find_unused_pid (   klass) [private]
Find and return an unused PID

Definition at line 497 of file test_ui.py.

00497 
00498     def _find_unused_pid(klass):
00499         '''Find and return an unused PID'''
00500 
00501         pid = 1
00502         while True:
00503             pid += 1
00504             try:
00505                 os.kill(pid, 0)
00506             except OSError as e:
00507                 if e.errno == errno.ESRCH:
00508                     break
00509         return pid

Here is the caller graph for this function:

def test_ui.T._gen_test_crash (   self) [private]
Generate a Report with real crash data

Definition at line 629 of file test_ui.py.

00629 
00630     def _gen_test_crash(self):
00631         '''Generate a Report with real crash data'''
00632 
00633         # create a test executable
00634         test_executable = '/usr/bin/yes'
00635         assert os.access(test_executable, os.X_OK), test_executable + ' is not executable'
00636         pid = os.fork()
00637         if pid == 0:
00638             os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stdout.fileno())
00639             sys.stdin.close()
00640             os.setsid()
00641             resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
00642             os.chdir(apport.fileutils.report_dir)
00643             os.execv(test_executable, [test_executable])
00644             assert False, 'Could not execute ' + test_executable
00645 
00646         time.sleep(0.5)
00647 
00648         # generate crash report
00649         r = apport.Report()
00650         r['ExecutablePath'] = test_executable
00651         r['Signal'] = '11'
00652         r.add_proc_info(pid)
00653         r.add_user_info()
00654 
00655         # generate a core dump
00656         coredump = os.path.join(apport.fileutils.report_dir, 'core')
00657         os.kill(pid, signal.SIGSEGV)
00658         os.waitpid(pid, 0)
00659         # Otherwise the core dump is empty.
00660         time.sleep(0.5)
00661         assert os.path.exists(coredump)
00662         r['CoreDump'] = (coredump,)
00663 
00664         return r

Here is the caller graph for this function:

def test_ui.T._run_hook (   self,
  code 
) [private]

Definition at line 1435 of file test_ui.py.

01435 
01436     def _run_hook(self, code):
01437         f = open(os.path.join(self.hookdir, 'coreutils.py'), 'w')
01438         f.write('def add_info(report, ui):\n%s\n' %
01439                 '\n'.join(['    ' + l for l in code.splitlines()]))
01440         f.close()
01441         self.ui.options.package = 'coreutils'
01442         self.ui.run_report_bug()

Here is the caller graph for this function:

def test_ui.T.setUp (   self)

Definition at line 123 of file test_ui.py.

00123 
00124     def setUp(self):
00125         # we test a few strings, don't get confused by translations
00126         for v in ['LANG', 'LANGUAGE', 'LC_MESSAGES', 'LC_ALL']:
00127             try:
00128                 del os.environ[v]
00129             except KeyError:
00130                 pass
00131 
00132         self.orig_report_dir = apport.fileutils.report_dir
00133         apport.fileutils.report_dir = tempfile.mkdtemp()
00134         self.orig_symptom_script_dir = apport.ui.symptom_script_dir
00135         apport.ui.symptom_script_dir = tempfile.mkdtemp()
00136         self.orig_ignore_file = apport.report._ignore_file
00137         (fd, apport.report._ignore_file) = tempfile.mkstemp()
00138         os.close(fd)
00139 
00140         # need to do this to not break ui's ctor
00141         self.orig_argv = sys.argv
00142         sys.argv = ['ui-test']
00143         self.ui = TestSuiteUserInterface()
00144 
00145         # demo report
00146         self.report = apport.Report()
00147         self.report['ExecutablePath'] = '/bin/bash'
00148         self.report['Package'] = 'libfoo1 1-1'
00149         self.report['SourcePackage'] = 'foo'
00150         self.report['Foo'] = 'A' * 1000
00151         self.report['CoreDump'] = problem_report.CompressedValue(b'\x01' * 100000)
00152 
00153         # write demo report into temporary file
00154         self.report_file = tempfile.NamedTemporaryFile()
00155         self.update_report_file()
00156 
00157         # set up our local hook directory
00158         self.hookdir = tempfile.mkdtemp()
00159         self.orig_hook_dir = apport.report._hook_dir
00160         apport.report._hook_dir = self.hookdir
00161 
00162         # test suite should not stumble over local packages
00163         os.environ['APPORT_IGNORE_OBSOLETE_PACKAGES'] = '1'
00164         os.environ['APPORT_DISABLE_DISTRO_CHECK'] = '1'

def test_ui.T.tearDown (   self)

Definition at line 171 of file test_ui.py.

00171 
00172     def tearDown(self):
00173         sys.argv = self.orig_argv
00174         shutil.rmtree(apport.fileutils.report_dir)
00175         apport.fileutils.report_dir = self.orig_report_dir
00176         self.orig_report_dir = None
00177         shutil.rmtree(apport.ui.symptom_script_dir)
00178         apport.ui.symptom_script_dir = self.orig_symptom_script_dir
00179         self.orig_symptom_script_dir = None
00180 
00181         os.unlink(apport.report._ignore_file)
00182         apport.report._ignore_file = self.orig_ignore_file
00183 
00184         self.ui = None
00185         self.report_file.close()
00186 
00187         self.assertEqual(subprocess.call(['pidof', '/usr/bin/yes']), 1, 'no stray test processes')
00188 
00189         # clean up apport report from _gen_test_crash()
00190         for f in glob.glob('/var/crash/_usr_bin_yes.*.crash'):
00191             try:
00192                 os.unlink(f)
00193             except OSError:
00194                 pass
00195 
00196         shutil.rmtree(self.hookdir)
00197         apport.report._hook_dir = self.orig_hook_dir

can_examine_locally() for a crash report

Definition at line 1852 of file test_ui.py.

01852 
01853     def test_can_examine_locally_crash(self):
01854         '''can_examine_locally() for a crash report'''
01855 
01856         self.ui.load_report(self.report_file.name)
01857 
01858         orig_path = os.environ['PATH']
01859         orig_fn = self.ui.ui_run_terminal
01860         try:
01861             self.ui.ui_run_terminal = lambda command: True
01862             os.environ['PATH'] = ''
01863             self.assertEqual(self.ui.can_examine_locally(), False)
01864 
01865             src_bindir = os.path.join(
01866                 os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'bin')
01867             # this will only work for running the tests in the source tree
01868             if os.access(os.path.join(src_bindir, 'apport-retrace'), os.X_OK):
01869                 os.environ['PATH'] = src_bindir
01870                 self.assertEqual(self.ui.can_examine_locally(), True)
01871             else:
01872                 # if we run tests in installed system, we just check that
01873                 # it doesn't crash
01874                 self.assertTrue(self.ui.can_examine_locally() in [False, True])
01875 
01876             self.ui.ui_run_terminal = lambda command: False
01877             self.assertEqual(self.ui.can_examine_locally(), False)
01878 
01879             # does not crash on NotImplementedError
01880             self.ui.ui_run_terminal = orig_fn
01881             self.assertEqual(self.ui.can_examine_locally(), False)
01882 
01883         finally:
01884             os.environ['PATH'] = orig_path
01885             self.ui.ui_run_terminal = orig_fn

can_examine_locally() for a non-crash report

Definition at line 1886 of file test_ui.py.

01886 
01887     def test_can_examine_locally_nocrash(self):
01888         '''can_examine_locally() for a non-crash report'''
01889 
01890         self.ui.load_report(self.report_file.name)
01891         del self.ui.report['CoreDump']
01892 
01893         orig_fn = self.ui.ui_run_terminal
01894         try:
01895             self.ui.ui_run_terminal = lambda command: True
01896             self.assertEqual(self.ui.can_examine_locally(), False)
01897         finally:
01898             self.ui.ui_run_terminal = orig_fn

collect_info() on report without information (distro bug)

Definition at line 317 of file test_ui.py.

00317 
00318     def test_collect_info_distro(self):
00319         '''collect_info() on report without information (distro bug)'''
00320 
00321         # report without any information (distro bug)
00322         self.ui.report = apport.Report()
00323         self.ui.collect_info()
00324         self.assertTrue(set(['Date', 'Uname', 'DistroRelease', 'ProblemType']).issubset(
00325             set(self.ui.report.keys())))
00326         self.assertEqual(self.ui.ic_progress_pulses, 0,
00327                          'no progress dialog for distro bug info collection')

collect_info() on report with only ExecutablePath

Definition at line 328 of file test_ui.py.

00328 
00329     def test_collect_info_exepath(self):
00330         '''collect_info() on report with only ExecutablePath'''
00331 
00332         # report with only package information
00333         self.report = apport.Report('Bug')
00334         self.report['ExecutablePath'] = '/bin/bash'
00335         self.update_report_file()
00336         self.ui.load_report(self.report_file.name)
00337         # add some tuple values, for robustness testing (might be added by
00338         # apport hooks)
00339         self.ui.report['Fstab'] = ('/etc/fstab', True)
00340         self.ui.report['CompressedValue'] = problem_report.CompressedValue(b'Test')
00341         self.ui.collect_info()
00342         self.assertTrue(set(['SourcePackage', 'Package', 'ProblemType',
00343                              'Uname', 'Dependencies', 'DistroRelease', 'Date',
00344                              'ExecutablePath']).issubset(set(self.ui.report.keys())))
00345         self.assertTrue(self.ui.ic_progress_pulses > 0,
00346                         'progress dialog for package bug info collection')
00347         self.assertEqual(self.ui.ic_progress_active, False,
00348                          'progress dialog for package bug info collection finished')

Here is the call graph for this function:

collect_info() on report with a package

Definition at line 349 of file test_ui.py.

00349 
00350     def test_collect_info_package(self):
00351         '''collect_info() on report with a package'''
00352 
00353         # report with only package information
00354         self.ui.report = apport.Report('Bug')
00355         self.ui.cur_package = 'bash'
00356         self.ui.collect_info()
00357         self.assertTrue(set(['SourcePackage', 'Package', 'ProblemType',
00358                              'Uname', 'Dependencies', 'DistroRelease',
00359                              'Date']).issubset(set(self.ui.report.keys())))
00360         self.assertTrue(self.ui.ic_progress_pulses > 0,
00361                         'progress dialog for package bug info collection')
00362         self.assertEqual(self.ui.ic_progress_active, False,
00363                          'progress dialog for package bug info collection finished')

collect_info() leaves the report accessible to the group

Definition at line 364 of file test_ui.py.

00364 
00365     def test_collect_info_permissions(self):
00366         '''collect_info() leaves the report accessible to the group'''
00367 
00368         self.ui.report = apport.Report('Bug')
00369         self.ui.cur_package = 'bash'
00370         self.ui.report_file = self.report_file.name
00371         self.ui.collect_info()
00372         self.assertTrue(os.stat(self.report_file.name).st_mode & stat.S_IRGRP)

crash database does not accept report

Definition at line 1899 of file test_ui.py.

01899 
01900     def test_db_no_accept(self):
01901         '''crash database does not accept report'''
01902 
01903         # FIXME: This behaviour is not really correct, but necessary as long as
01904         # we only support a single crashdb and have whoopsie hardcoded
01905         # (see LP#957177)
01906 
01907         latest_id_before = self.ui.crashdb.latest_id()
01908 
01909         sys.argv = ['ui-test', '-f', '-p', 'bash']
01910         self.ui = TestSuiteUserInterface()
01911 
01912         # Pretend it does not accept report
01913         self.ui.crashdb.accepts = lambda r: False
01914         self.ui.present_details_response = {'report': True,
01915                                             'blacklist': False,
01916                                             'examine': False,
01917                                             'restart': False}
01918         self.assertEqual(self.ui.run_argv(), True)
01919 
01920         self.assertEqual(self.ui.msg_severity, None)
01921         self.assertEqual(self.ui.msg_title, None)
01922         self.assertTrue(self.ui.present_details_shown)
01923 
01924         # data was collected for whoopsie
01925         self.assertEqual(self.ui.report['SourcePackage'], 'bash')
01926         self.assertTrue('Dependencies' in self.ui.report.keys())
01927         self.assertTrue('ProcEnviron' in self.ui.report.keys())
01928         self.assertEqual(self.ui.report['ProblemType'], 'Bug')
01929 
01930         # no upload happend
01931         self.assertEqual(self.ui.opened_url, None)
01932         self.assertEqual(self.ui.upload_progress_pulses, 0)
01933         self.assertEqual(self.ui.crashdb.latest_id(), latest_id_before)

format_filesize()

Definition at line 198 of file test_ui.py.

00198 
00199     def test_format_filesize(self):
00200         '''format_filesize()'''
00201 
00202         self.assertEqual(self.ui.format_filesize(0), '0.0 KB')
00203         self.assertEqual(self.ui.format_filesize(2048), '2.0 KB')
00204         self.assertEqual(self.ui.format_filesize(2560), '2.6 KB')
00205         self.assertEqual(self.ui.format_filesize(999999), '1000.0 KB')
00206         self.assertEqual(self.ui.format_filesize(1000000), '1.0 MB')
00207         self.assertEqual(self.ui.format_filesize(2.7 * 1000000), '2.7 MB')
00208         self.assertEqual(self.ui.format_filesize(1024 * 1000000), '1.0 GB')
00209         self.assertEqual(self.ui.format_filesize(2560 * 1000000), '2.6 GB')

Definition at line 1934 of file test_ui.py.

01934 
01935     def test_get_desktop_entry(self):
01936         desktop_file = tempfile.NamedTemporaryFile()
01937         desktop_file.write('''[Desktop Entry]
01938 Name=gtranslate
01939 GenericName=Translator
01940 GenericName[de]=√úbersetzer
01941 Exec=gedit %U
01942 Categories=GNOME;GTK;Utility;TextEditor;
01943 '''.encode('UTF-8'))
01944         desktop_file.flush()
01945 
01946         self.report['DesktopFile'] = desktop_file.name
01947         self.ui.report = self.report
01948         info = self.ui.get_desktop_entry()
01949         self.assertEqual(info, {'genericname': 'Translator',
01950                                 'categories': 'GNOME;GTK;Utility;TextEditor;',
01951                                 'name': 'gtranslate',
01952                                 'genericname[de]': '√úbersetzer',
01953                                 'exec': 'gedit %U'})

get_complete_size() and get_reduced_size() for on-the-fly Reports

Definition at line 233 of file test_ui.py.

00233 
00234     def test_get_size_constructed(self):
00235         '''get_complete_size() and get_reduced_size() for on-the-fly Reports'''
00236 
00237         self.ui.report = apport.Report('Bug')
00238         self.ui.report['Hello'] = 'World'
00239 
00240         s = self.ui.get_complete_size()
00241         self.assertTrue(s > 5)
00242         self.assertTrue(s < 100)
00243 
00244         self.assertEqual(s, self.ui.get_reduced_size())

get_complete_size() and get_reduced_size() for loaded Reports

Definition at line 210 of file test_ui.py.

00210 
00211     def test_get_size_loaded(self):
00212         '''get_complete_size() and get_reduced_size() for loaded Reports'''
00213 
00214         self.ui.load_report(self.report_file.name)
00215 
00216         fsize = os.path.getsize(self.report_file.name)
00217         complete_ratio = float(self.ui.get_complete_size()) / fsize
00218         self.assertTrue(complete_ratio >= 0.9 and complete_ratio <= 1.1)
00219 
00220         rs = self.ui.get_reduced_size()
00221         self.assertTrue(rs > 1000)
00222         self.assertTrue(rs < 10000)
00223 
00224         # now add some information (e. g. from package hooks)
00225         self.ui.report['ExtraInfo'] = 'A' * 50000
00226         s = self.ui.get_complete_size()
00227         self.assertTrue(s >= fsize + 49900)
00228         self.assertTrue(s < fsize + 60000)
00229 
00230         rs = self.ui.get_reduced_size()
00231         self.assertTrue(rs > 51000)
00232         self.assertTrue(rs < 60000)

handle_duplicate()

Definition at line 373 of file test_ui.py.

00373 
00374     def test_handle_duplicate(self):
00375         '''handle_duplicate()'''
00376 
00377         self.ui.load_report(self.report_file.name)
00378         self.assertEqual(self.ui.handle_duplicate(), False)
00379         self.assertEqual(self.ui.msg_title, None)
00380         self.assertEqual(self.ui.opened_url, None)
00381 
00382         demo_url = 'http://example.com/1'
00383         self.report['KnownReport'] = demo_url
00384         self.update_report_file()
00385         self.ui.load_report(self.report_file.name)
00386         self.assertEqual(self.ui.handle_duplicate(), True)
00387         self.assertEqual(self.ui.msg_severity, 'info')
00388         self.assertEqual(self.ui.opened_url, demo_url)
00389 
00390         self.ui.opened_url = None
00391         demo_url = 'http://example.com/1'
00392         self.report['KnownReport'] = '1'
00393         self.update_report_file()
00394         self.ui.load_report(self.report_file.name)
00395         self.assertEqual(self.ui.handle_duplicate(), True)
00396         self.assertEqual(self.ui.msg_severity, 'info')
00397         self.assertEqual(self.ui.opened_url, None)

Here is the call graph for this function:

interactive hooks: user cancels

Definition at line 1529 of file test_ui.py.

01529 
01530     def test_interactive_hooks_cancel(self):
01531         '''interactive hooks: user cancels'''
01532 
01533         self.assertRaises(SystemExit, self._run_hook,
01534                           '''report['begin'] = '1'
01535 raise StopIteration
01536 report['end'] = '1'
01537 ''')

Here is the call graph for this function:

interactive hooks: HookUI.choice()

Definition at line 1507 of file test_ui.py.

01507 
01508     def test_interactive_hooks_choices(self):
01509         '''interactive hooks: HookUI.choice()'''
01510 
01511         self.ui.present_details_response = {'report': False,
01512                                             'blacklist': False,
01513                                             'examine': False,
01514                                             'restart': False}
01515         self.ui.question_choice_response = [1]
01516         self._run_hook('''report['begin'] = '1'
01517 report['answer'] = str(ui.choice('YourChoice?', ['foo', 'bar']))
01518 report['end'] = '1'
01519 ''')
01520         self.assertEqual(self.ui.report['begin'], '1')
01521         self.assertEqual(self.ui.report['end'], '1')
01522         self.assertEqual(self.ui.msg_text, 'YourChoice?')
01523         self.assertEqual(self.ui.report['answer'], '[1]')
01524 
01525         self.ui.question_choice_response = None
01526         self.ui.run_report_bug()
01527         self.assertEqual(self.ui.report['answer'], 'None')
01528         self.assertEqual(self.ui.report['end'], '1')

Here is the call graph for this function:

interactive hooks: HookUI.file()

Definition at line 1485 of file test_ui.py.

01485 
01486     def test_interactive_hooks_file(self):
01487         '''interactive hooks: HookUI.file()'''
01488 
01489         self.ui.present_details_response = {'report': False,
01490                                             'blacklist': False,
01491                                             'examine': False,
01492                                             'restart': False}
01493         self.ui.question_file_response = '/etc/fstab'
01494         self._run_hook('''report['begin'] = '1'
01495 report['answer'] = str(ui.file('YourFile?'))
01496 report['end'] = '1'
01497 ''')
01498         self.assertEqual(self.ui.report['begin'], '1')
01499         self.assertEqual(self.ui.report['end'], '1')
01500         self.assertEqual(self.ui.msg_text, 'YourFile?')
01501         self.assertEqual(self.ui.report['answer'], '/etc/fstab')
01502 
01503         self.ui.question_file_response = None
01504         self.ui.run_report_bug()
01505         self.assertEqual(self.ui.report['answer'], 'None')
01506         self.assertEqual(self.ui.report['end'], '1')

Here is the call graph for this function:

interactive hooks: HookUI.information()

Definition at line 1443 of file test_ui.py.

01443 
01444     def test_interactive_hooks_information(self):
01445         '''interactive hooks: HookUI.information()'''
01446 
01447         self.ui.present_details_response = {'report': False,
01448                                             'blacklist': False,
01449                                             'examine': False,
01450                                             'restart': False}
01451         self._run_hook('''report['begin'] = '1'
01452 ui.information('InfoText')
01453 report['end'] = '1'
01454 ''')
01455         self.assertEqual(self.ui.report['begin'], '1')
01456         self.assertEqual(self.ui.report['end'], '1')
01457         self.assertEqual(self.ui.msg_text, 'InfoText')

Here is the call graph for this function:

interactive hooks: HookUI.yesno()

Definition at line 1458 of file test_ui.py.

01458 
01459     def test_interactive_hooks_yesno(self):
01460         '''interactive hooks: HookUI.yesno()'''
01461 
01462         self.ui.present_details_response = {'report': False,
01463                                             'blacklist': False,
01464                                             'examine': False,
01465                                             'restart': False}
01466         self.ui.question_yesno_response = True
01467         self._run_hook('''report['begin'] = '1'
01468 report['answer'] = str(ui.yesno('YesNo?'))
01469 report['end'] = '1'
01470 ''')
01471         self.assertEqual(self.ui.report['begin'], '1')
01472         self.assertEqual(self.ui.report['end'], '1')
01473         self.assertEqual(self.ui.msg_text, 'YesNo?')
01474         self.assertEqual(self.ui.report['answer'], 'True')
01475 
01476         self.ui.question_yesno_response = False
01477         self.ui.run_report_bug()
01478         self.assertEqual(self.ui.report['answer'], 'False')
01479         self.assertEqual(self.ui.report['end'], '1')
01480 
01481         self.ui.question_yesno_response = None
01482         self.ui.run_report_bug()
01483         self.assertEqual(self.ui.report['answer'], 'None')
01484         self.assertEqual(self.ui.report['end'], '1')

Here is the call graph for this function:

load_report()

Definition at line 245 of file test_ui.py.

00245 
00246     def test_load_report(self):
00247         '''load_report()'''
00248 
00249         # valid report
00250         self.ui.load_report(self.report_file.name)
00251         self.assertEqual(set(self.ui.report.keys()), set(self.report.keys()))
00252         self.assertEqual(self.ui.report['Package'], self.report['Package'])
00253         self.assertEqual(self.ui.report['CoreDump'].get_value(),
00254                          self.report['CoreDump'].get_value())
00255         self.assertEqual(self.ui.msg_title, None)
00256 
00257         # report without Package
00258         del self.report['Package']
00259         del self.report['SourcePackage']
00260         del self.report['ExecutablePath']
00261         self.update_report_file()
00262         self.ui.load_report(self.report_file.name)
00263 
00264         self.assertTrue(self.ui.report is None)
00265         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
00266         self.assertEqual(self.ui.msg_severity, 'info')
00267 
00268         self.ui.clear_msg()
00269 
00270         # invalid base64 encoding
00271         self.report_file.seek(0)
00272         self.report_file.truncate()
00273         self.report_file.write(b'''Type: test
00274 Package: foo 1-1
00275 CoreDump: base64
00276 bOgUs=
00277 ''')
00278         self.report_file.flush()
00279 
00280         self.ui.load_report(self.report_file.name)
00281         self.assertTrue(self.ui.report is None)
00282         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
00283         self.assertEqual(self.ui.msg_severity, 'error')

Here is the call graph for this function:

parse_args() option inference when invoked as *-bug

Definition at line 1765 of file test_ui.py.

01765 
01766     def test_parse_argv_apport_bug(self):
01767         '''parse_args() option inference when invoked as *-bug'''
01768 
01769         def _chk(args, expected_opts):
01770             sys.argv = ['apport-bug'] + args
01771             orig_stderr = sys.stderr
01772             sys.stderr = open('/dev/null', 'w')
01773             try:
01774                 ui = apport.ui.UserInterface()
01775             finally:
01776                 sys.stderr.close()
01777                 sys.stderr = orig_stderr
01778             expected_opts['version'] = None
01779             self.assertEqual(ui.args, [])
01780             self.assertEqual(ui.options, expected_opts)
01781 
01782         #
01783         # no arguments: default to 'ask for symptom' bug mode
01784         #
01785         _chk([], {'filebug': True, 'package': None, 'pid': None, 'crash_file':
01786                   None, 'symptom': None, 'update_report': None, 'save': None,
01787                   'window': False, 'tag': [], 'hanging': False})
01788 
01789         #
01790         # single arguments
01791         #
01792 
01793         # package
01794         _chk(['coreutils'], {'filebug': True, 'package': 'coreutils', 'pid':
01795                              None, 'crash_file': None, 'symptom': None,
01796                              'update_report': None, 'save': None, 'window':
01797                              False, 'tag': [], 'hanging': False})
01798 
01799         # symptom (preferred over package)
01800         f = open(os.path.join(apport.ui.symptom_script_dir, 'coreutils.py'), 'w')
01801         f.write('''description = 'foo does not work'
01802 def run(report, ui):
01803 return 'bash'
01804 ''')
01805         f.close()
01806         _chk(['coreutils'], {'filebug': True, 'package': None, 'pid': None,
01807                              'crash_file': None, 'symptom': 'coreutils',
01808                              'update_report': None, 'save': None, 'window':
01809                              False, 'tag': [], 'hanging': False})
01810         os.unlink(os.path.join(apport.ui.symptom_script_dir, 'coreutils.py'))
01811 
01812         # PID
01813         _chk(['1234'], {'filebug': True, 'package': None, 'pid': '1234',
01814                         'crash_file': None, 'symptom': None, 'update_report':
01815                         None, 'save': None, 'window': False, 'tag': [],
01816                         'hanging': False})
01817 
01818         # .crash/.apport files; check correct handling of spaces
01819         for suffix in ('.crash', '.apport'):
01820             _chk(['/tmp/f oo' + suffix],
01821                  {'filebug': False, 'package': None, 'pid': None, 'crash_file':
01822                   '/tmp/f oo' + suffix, 'symptom': None, 'update_report': None,
01823                   'save': None, 'window': False, 'tag': [], 'hanging': False})
01824 
01825         # executable name
01826         _chk(['/usr/bin/tail'],
01827              {'filebug': True, 'package': 'coreutils', 'pid': None,
01828               'crash_file': None, 'symptom': None, 'update_report': None,
01829               'save': None, 'window': False, 'tag': [], 'hanging': False})
01830 
01831         #
01832         # supported options
01833         #
01834 
01835         # --save
01836         _chk(['--save', 'foo.apport', 'coreutils'],
01837              {'filebug': True, 'package': 'coreutils', 'pid': None,
01838               'crash_file': None, 'symptom': None, 'update_report': None,
01839               'save': 'foo.apport', 'window': False, 'tag': [],
01840               'hanging': False})
01841 
01842         # --tag
01843         _chk(['--tag', 'foo', 'coreutils'],
01844              {'filebug': True, 'package': 'coreutils', 'pid': None,
01845               'crash_file': None, 'symptom': None, 'update_report': None,
01846               'save': None, 'window': False, 'tag': ['foo'], 'hanging': False})
01847         _chk(['--tag', 'foo', '--tag', 'bar', 'coreutils'],
01848              {'filebug': True, 'package': 'coreutils', 'pid': None,
01849               'crash_file': None, 'symptom': None, 'update_report': None,
01850               'save': None, 'window': False, 'tag': ['foo', 'bar'],
01851               'hanging': False})

parse_args() option inference for a single argument

Definition at line 1692 of file test_ui.py.

01692 
01693     def test_parse_argv_single_arg(self):
01694         '''parse_args() option inference for a single argument'''
01695 
01696         def _chk(program_name, arg, expected_opts):
01697             sys.argv = [program_name]
01698             if arg:
01699                 sys.argv.append(arg)
01700             orig_stderr = sys.stderr
01701             sys.stderr = open('/dev/null', 'w')
01702             try:
01703                 ui = apport.ui.UserInterface()
01704             finally:
01705                 sys.stderr.close()
01706                 sys.stderr = orig_stderr
01707             expected_opts['version'] = None
01708             self.assertEqual(ui.args, [])
01709             self.assertEqual(ui.options, expected_opts)
01710 
01711         # no arguments -> show pending crashes
01712         _chk('apport-gtk', None,
01713              {'filebug': False, 'package': None, 'pid': None, 'crash_file':
01714               None, 'symptom': None, 'update_report': None, 'save': None,
01715               'window': False, 'tag': [], 'hanging': False})
01716         # updating report not allowed without args
01717         self.assertRaises(SystemExit, _chk, 'apport-collect', None, {})
01718 
01719         # package
01720         _chk('apport-kde', 'coreutils',
01721              {'filebug': True, 'package': 'coreutils', 'pid': None,
01722               'crash_file': None, 'symptom': None, 'update_report': None,
01723               'save': None, 'window': False, 'tag': [], 'hanging': False})
01724 
01725         # symptom is preferred over package
01726         f = open(os.path.join(apport.ui.symptom_script_dir, 'coreutils.py'), 'w')
01727         f.write('''description = 'foo does not work'
01728 def run(report, ui):
01729 return 'bash'
01730 ''')
01731         f.close()
01732         _chk('apport-cli', 'coreutils',
01733              {'filebug': True, 'package': None, 'pid': None, 'crash_file':
01734               None, 'symptom': 'coreutils', 'update_report': None, 'save':
01735               None, 'window': False, 'tag': [], 'hanging': False})
01736 
01737         # PID
01738         _chk('apport-cli', '1234', {'filebug': True, 'package': None,
01739              'pid': '1234', 'crash_file': None, 'symptom': None,
01740              'update_report': None, 'save': None, 'window': False,
01741              'tag': [], 'hanging': False})
01742 
01743         # .crash/.apport files; check correct handling of spaces
01744         for suffix in ('.crash', '.apport'):
01745             _chk('apport-cli', '/tmp/f oo' + suffix, {'filebug': False,
01746                  'package': None, 'pid': None,
01747                  'crash_file': '/tmp/f oo' + suffix, 'symptom': None,
01748                  'update_report': None, 'save': None, 'window': False,
01749                  'tag': [], 'hanging': False})
01750 
01751         # executable
01752         _chk('apport-cli', '/usr/bin/tail', {'filebug': True,
01753              'package': 'coreutils',
01754              'pid': None, 'crash_file': None, 'symptom': None,
01755              'update_report': None, 'save': None, 'window': False,
01756              'tag': [], 'hanging': False})
01757 
01758         # update existing report
01759         _chk('apport-collect', '1234', {'filebug': False, 'package': None,
01760              'crash_file': None, 'symptom': None, 'update_report': 1234,
01761              'tag': []})
01762         _chk('apport-update-bug', '1234', {'filebug': False, 'package': None,
01763              'crash_file': None, 'symptom': None, 'update_report': 1234,
01764              'tag': []})

def test_ui.T.test_restart (   self)
restart()

Definition at line 284 of file test_ui.py.

00284 
00285     def test_restart(self):
00286         '''restart()'''
00287 
00288         # test with only ProcCmdline
00289         p = os.path.join(apport.fileutils.report_dir, 'ProcCmdline')
00290         r = os.path.join(apport.fileutils.report_dir, 'Custom')
00291         self.report['ProcCmdline'] = 'touch ' + p
00292         self.update_report_file()
00293         self.ui.load_report(self.report_file.name)
00294 
00295         self.ui.restart()
00296         time.sleep(1)  # FIXME: race condition
00297         self.assertTrue(os.path.exists(p))
00298         self.assertTrue(not os.path.exists(r))
00299         os.unlink(p)
00300 
00301         # test with RespawnCommand
00302         self.report['RespawnCommand'] = 'touch ' + r
00303         self.update_report_file()
00304         self.ui.load_report(self.report_file.name)
00305 
00306         self.ui.restart()
00307         time.sleep(1)  # FIXME: race condition
00308         self.assertTrue(not os.path.exists(p))
00309         self.assertTrue(os.path.exists(r))
00310         os.unlink(r)
00311 
00312         # test that invalid command does not make us fall apart
00313         del self.report['RespawnCommand']
00314         self.report['ProcCmdline'] = '/nonexisting'
00315         self.update_report_file()
00316         self.ui.load_report(self.report_file.name)

Here is the call graph for this function:

def test_ui.T.test_run_crash (   self)
run_crash()

Definition at line 665 of file test_ui.py.

00665 
00666     def test_run_crash(self):
00667         '''run_crash()'''
00668 
00669         r = self._gen_test_crash()
00670 
00671         # write crash report
00672         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00673 
00674         # cancel crash notification dialog
00675         with open(report_file, 'wb') as f:
00676             r.write(f)
00677         self.ui = TestSuiteUserInterface()
00678         self.ui.present_details_response = {'report': False,
00679                                             'blacklist': False,
00680                                             'examine': False,
00681                                             'restart': False}
00682         self.ui.run_crash(report_file)
00683         self.assertEqual(self.ui.msg_severity, None)
00684         self.assertEqual(self.ui.msg_title, None)
00685         self.assertEqual(self.ui.opened_url, None)
00686         self.assertEqual(self.ui.ic_progress_pulses, 0)
00687 
00688         # report in crash notification dialog, send full report
00689         with open(report_file, 'wb') as f:
00690             r.write(f)
00691         self.ui = TestSuiteUserInterface()
00692         self.ui.present_details_response = {'report': True,
00693                                             'blacklist': False,
00694                                             'examine': False,
00695                                             'restart': False}
00696         self.ui.run_crash(report_file)
00697         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
00698         self.assertEqual(self.ui.msg_title, None)
00699         self.assertEqual(self.ui.opened_url, 'http://coreutils.bugs.example.com/%i' % self.ui.crashdb.latest_id())
00700         self.assertFalse(self.ui.ic_progress_active)
00701         self.assertNotEqual(self.ui.ic_progress_pulses, 0)
00702         self.assertTrue(self.ui.present_details_shown)
00703 
00704         self.assertTrue('SourcePackage' in self.ui.report.keys())
00705         self.assertTrue('Dependencies' in self.ui.report.keys())
00706         self.assertTrue('Stacktrace' in self.ui.report.keys())
00707         self.assertTrue('ProcEnviron' in self.ui.report.keys())
00708         self.assertFalse('ExecutableTimestamp' in self.ui.report.keys())
00709         self.assertFalse('StacktraceAddressSignature' in self.ui.report.keys())
00710         self.assertEqual(self.ui.report['ProblemType'], 'Crash')
00711         self.assertTrue(len(self.ui.report['CoreDump']) > 10000)
00712         self.assertTrue(self.ui.report['Title'].startswith('yes crashed with SIGSEGV'))
00713 
00714         # so far we did not blacklist, verify that
00715         self.assertTrue(not self.ui.report.check_ignored())
00716 
00717         # cancel crash notification dialog and blacklist
00718         with open(report_file, 'wb') as f:
00719             r.write(f)
00720         self.ui = TestSuiteUserInterface()
00721         self.ui.present_details_response = {'report': False,
00722                                             'blacklist': True,
00723                                             'examine': False,
00724                                             'restart': False}
00725         self.ui.run_crash(report_file)
00726         self.assertEqual(self.ui.msg_severity, None)
00727         self.assertEqual(self.ui.msg_title, None)
00728         self.assertEqual(self.ui.opened_url, None)
00729         self.assertEqual(self.ui.ic_progress_pulses, 0)
00730 
00731         self.assertTrue(self.ui.report.check_ignored())

Here is the call graph for this function:

run_crash() for an abort() without assertion message

Definition at line 732 of file test_ui.py.

00732 
00733     def test_run_crash_abort(self):
00734         '''run_crash() for an abort() without assertion message'''
00735 
00736         r = self._gen_test_crash()
00737         r['Signal'] = '6'
00738         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00739         with open(report_file, 'wb') as f:
00740             r.write(f)
00741 
00742         self.ui.present_details_response = {'report': True,
00743                                             'blacklist': False,
00744                                             'examine': False,
00745                                             'restart': False}
00746         self.ui.run_crash(report_file)
00747         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
00748 
00749         self.assertTrue('SourcePackage' in self.ui.report.keys())
00750         self.assertTrue('Dependencies' in self.ui.report.keys())
00751         self.assertTrue('Stacktrace' in self.ui.report.keys())
00752         self.assertTrue('ProcEnviron' in self.ui.report.keys())
00753         self.assertFalse('ExecutableTimestamp' in self.ui.report.keys())
00754         self.assertEqual(self.ui.report['Signal'], '6')
00755 
00756         # we disable the ABRT filtering, we want these crashes after all
00757         #self.assertTrue('assert' in self.ui.msg_text, '%s: %s' %
00758         #    (self.ui.msg_title, self.ui.msg_text))
00759         #self.assertEqual(self.ui.msg_severity, 'info')
00760         self.assertEqual(self.ui.msg_severity, None)
00761         self.assertTrue(self.ui.present_details_shown)

Here is the call graph for this function:

run_crash() anonymization

Definition at line 1145 of file test_ui.py.

01145 
01146     def test_run_crash_anonymity(self):
01147         '''run_crash() anonymization'''
01148 
01149         r = self._gen_test_crash()
01150         utf8_val = b'\xc3\xa4 ' + os.uname()[1].encode('UTF-8') + b' \xe2\x99\xa5 '
01151         r['ProcUnicodeValue'] = utf8_val.decode('UTF-8')
01152         r['ProcByteArrayValue'] = utf8_val
01153         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01154         with open(report_file, 'wb') as f:
01155             r.write(f)
01156         self.ui = TestSuiteUserInterface()
01157         self.ui.present_details_response = {'report': True,
01158                                             'blacklist': False,
01159                                             'examine': False,
01160                                             'restart': False}
01161         self.ui.run_crash(report_file)
01162         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01163 
01164         self.assertFalse('ProcCwd' in self.ui.report)
01165 
01166         dump = BytesIO()
01167         self.ui.report.write(dump)
01168         report = dump.getvalue().decode('UTF-8')
01169 
01170         p = pwd.getpwuid(os.getuid())
01171         bad_strings = [os.uname()[1], p[0], p[4], p[5], os.getcwd()]
01172 
01173         for s in bad_strings:
01174             self.assertFalse(s in report, 'dump contains sensitive string: %s' % s)

Here is the call graph for this function:

run_crash() anonymization runs after info and duplicate collection

Definition at line 1175 of file test_ui.py.

01175 
01176     def test_run_crash_anonymity_order(self):
01177         '''run_crash() anonymization runs after info and duplicate collection'''
01178 
01179         # pretend the hostname looks like a hex number which matches
01180         # the stack trace address
01181         uname = os.uname()
01182         uname = (uname[0], '0xDEADBEEF', uname[2], uname[3], uname[4])
01183         orig_uname = os.uname
01184         orig_add_gdb_info = apport.report.Report.add_gdb_info
01185         os.uname = lambda: uname
01186 
01187         def fake_add_gdb_info(self):
01188             self['Stacktrace'] = '''#0  0xDEADBEEF in h (p=0x0) at crash.c:25
01189 #1  0x10000042 in g (x=1, y=42) at crash.c:26
01190 #1  0x10000001 in main () at crash.c:40
01191 '''
01192             self['ProcMaps'] = '''
01193 10000000-DEADBEF0 r-xp 00000000 08:02 100000           /bin/crash
01194 '''
01195             assert self.crash_signature_addresses() is not None
01196 
01197         try:
01198             r = self._gen_test_crash()
01199             apport.report.Report.add_gdb_info = fake_add_gdb_info
01200             r['ProcAuxInfo'] = 'my 0xDEADBEEF'
01201             report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01202             with open(report_file, 'wb') as f:
01203                 r.write(f)
01204 
01205             # if this runs anonymization before the duplicate signature, then this
01206             # will fail, as 0xDEADhostname is an invalid address
01207             self.ui = TestSuiteUserInterface()
01208             self.ui.present_details_response = {'report': True,
01209                                                 'blacklist': False,
01210                                                 'examine': False,
01211                                                 'restart': False}
01212             self.ui.run_crash(report_file)
01213             self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01214 
01215             self.assertEqual(self.ui.report['ProcAuxInfo'], 'my hostname')
01216             # after anonymization this should mess up Stacktrace; this mostly
01217             # confirms that our test logic works
01218             self.assertEqual(self.ui.report.crash_signature_addresses(), None)
01219         finally:
01220             os.uname = orig_uname
01221             apport.report.Report.add_gdb_info = orig_add_gdb_info

Here is the call graph for this function:

run_crash() anonymization only catches whole words

Definition at line 1222 of file test_ui.py.

01222 
01223     def test_run_crash_anonymity_substring(self):
01224         '''run_crash() anonymization only catches whole words'''
01225 
01226         # pretend the hostname is "ed", a substring of e. g. "crashed"
01227         uname = os.uname()
01228         uname = (uname[0], 'ed', uname[2], uname[3], uname[4])
01229         orig_uname = os.uname
01230         os.uname = lambda: uname
01231 
01232         try:
01233             r = self._gen_test_crash()
01234             r['ProcInfo1'] = 'my ed'
01235             r['ProcInfo2'] = '"ed.localnet"'
01236             r['ProcInfo3'] = 'education'
01237             report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01238             with open(report_file, 'wb') as f:
01239                 r.write(f)
01240 
01241             self.ui = TestSuiteUserInterface()
01242             self.ui.present_details_response = {'report': True,
01243                                                 'blacklist': False,
01244                                                 'examine': False,
01245                                                 'restart': False}
01246             self.ui.run_crash(report_file)
01247             self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01248 
01249             self.assertTrue(self.ui.report['Title'].startswith('yes crashed with SIGSEGV'),
01250                             self.ui.report['Title'])
01251             self.assertEqual(self.ui.report['ProcInfo1'], 'my hostname')
01252             self.assertEqual(self.ui.report['ProcInfo2'], '"hostname.localnet"')
01253             self.assertEqual(self.ui.report['ProcInfo3'], 'education')
01254         finally:
01255             os.uname = orig_uname

Here is the call graph for this function:

run_crash() through a file specified on the command line

Definition at line 786 of file test_ui.py.

00786 
00787     def test_run_crash_argv_file(self):
00788         '''run_crash() through a file specified on the command line'''
00789 
00790         # valid
00791         self.report['Package'] = 'bash'
00792         self.update_report_file()
00793 
00794         sys.argv = ['ui-test', '-c', self.report_file.name]
00795         self.ui = TestSuiteUserInterface()
00796         self.ui.present_details_response = {'report': True,
00797                                             'blacklist': False,
00798                                             'examine': False,
00799                                             'restart': False}
00800 
00801         self.assertEqual(self.ui.run_argv(), True)
00802 
00803         self.assertEqual(self.ui.msg_text, None)
00804         self.assertEqual(self.ui.msg_severity, None)
00805         self.assertTrue(self.ui.present_details_shown)
00806 
00807         # unreportable
00808         self.report['Package'] = 'bash'
00809         self.report['UnreportableReason'] = b'It stinks. \xe2\x99\xa5'.decode('UTF-8')
00810         self.update_report_file()
00811 
00812         sys.argv = ['ui-test', '-c', self.report_file.name]
00813         self.ui = TestSuiteUserInterface()
00814         self.ui.present_details_response = {'report': True,
00815                                             'blacklist': False,
00816                                             'examine': False,
00817                                             'restart': False}
00818         self.assertEqual(self.ui.run_argv(), True)
00819 
00820         self.assertTrue('It stinks.' in self.ui.msg_text, '%s: %s' %
00821                         (self.ui.msg_title, self.ui.msg_text))
00822         self.assertEqual(self.ui.msg_severity, 'info')
00823 
00824         # should not die with an exception on an invalid name
00825         sys.argv = ['ui-test', '-c', '/nonexisting.crash']
00826         self.ui = TestSuiteUserInterface()
00827         self.assertEqual(self.ui.run_argv(), True)
00828         self.assertEqual(self.ui.msg_severity, 'error')

Here is the call graph for this function:

run_crash() for an invalid core dump

Definition at line 762 of file test_ui.py.

00762 
00763     def test_run_crash_broken(self):
00764         '''run_crash() for an invalid core dump'''
00765 
00766         # generate broken crash report
00767         r = apport.Report()
00768         r['ExecutablePath'] = '/usr/bin/yes'
00769         r['Signal'] = '11'
00770         r['CoreDump'] = problem_report.CompressedValue()
00771         r['CoreDump'].gzipvalue = b'AAAAAAAA'
00772         r.add_user_info()
00773 
00774         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00775         with open(report_file, 'wb') as f:
00776             r.write(f)
00777 
00778         self.ui.present_details_response = {'report': True,
00779                                             'blacklist': False,
00780                                             'examine': False,
00781                                             'restart': False}
00782         self.ui.run_crash(report_file)
00783         self.assertEqual(self.ui.msg_severity, 'error', self.ui.msg_text)
00784         self.assertTrue('decompress' in self.ui.msg_text)
00785         self.assertTrue(self.ui.present_details_shown)

run_crash() on various error conditions

Definition at line 955 of file test_ui.py.

00955 
00956     def test_run_crash_errors(self):
00957         '''run_crash() on various error conditions'''
00958 
00959         # crash report with invalid Package name
00960         r = apport.Report()
00961         r['ExecutablePath'] = '/bin/bash'
00962         r['Package'] = 'foobarbaz'
00963         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00964         with open(report_file, 'wb') as f:
00965             r.write(f)
00966 
00967         self.ui.present_details_response = {'report': True,
00968                                             'blacklist': False,
00969                                             'examine': False,
00970                                             'restart': False}
00971         self.ui.run_crash(report_file)
00972 
00973         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
00974         self.assertEqual(self.ui.msg_severity, 'error')

run_crash() on a crash with the Ignore field

Definition at line 847 of file test_ui.py.

00847 
00848     def test_run_crash_ignore(self):
00849         '''run_crash() on a crash with the Ignore field'''
00850         self.report['Ignore'] = 'True'
00851         self.report['ExecutablePath'] = '/bin/bash'
00852         self.report['Package'] = 'bash 1'
00853         self.update_report_file()
00854 
00855         self.ui.run_crash(self.report_file.name)
00856         self.assertEqual(self.ui.msg_severity, None)

Here is the call graph for this function:

run_crash() for a kernel error

Definition at line 1091 of file test_ui.py.

01091 
01092     def test_run_crash_kernel(self):
01093         '''run_crash() for a kernel error'''
01094 
01095         # set up hook
01096         f = open(os.path.join(self.hookdir, 'source_linux.py'), 'w')
01097         f.write('''def add_info(report, ui):
01098     report['KernelDebug'] = 'LotsMoreInfo'
01099 ''')
01100         f.close()
01101 
01102         # generate crash report
01103         r = apport.Report('KernelCrash')
01104         r['Package'] = apport.packaging.get_kernel_package()
01105         r['SourcePackage'] = 'linux'
01106 
01107         # write crash report
01108         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01109 
01110         # cancel crash notification dialog
01111         with open(report_file, 'wb') as f:
01112             r.write(f)
01113         self.ui = TestSuiteUserInterface()
01114         self.ui.present_details_response = {'report': False,
01115                                             'blacklist': False,
01116                                             'examine': False,
01117                                             'restart': False}
01118         self.ui.run_crash(report_file)
01119         self.assertEqual(self.ui.msg_severity, None, 'error: %s - %s' %
01120                          (self.ui.msg_title, self.ui.msg_text))
01121         self.assertEqual(self.ui.msg_title, None)
01122         self.assertEqual(self.ui.opened_url, None)
01123         self.assertEqual(self.ui.ic_progress_pulses, 0)
01124         self.assertTrue(self.ui.present_details_shown)
01125 
01126         # report in crash notification dialog, send report
01127         with open(report_file, 'wb') as f:
01128             r.write(f)
01129         self.ui = TestSuiteUserInterface()
01130         self.ui.present_details_response = {'report': True,
01131                                             'blacklist': False,
01132                                             'examine': False,
01133                                             'restart': False}
01134         self.ui.run_crash(report_file)
01135         self.assertEqual(self.ui.msg_severity, None, str(self.ui.msg_title) +
01136                          ' ' + str(self.ui.msg_text))
01137         self.assertEqual(self.ui.msg_title, None)
01138         self.assertEqual(self.ui.opened_url, 'http://linux.bugs.example.com/%i' % self.ui.crashdb.latest_id())
01139         self.assertTrue(self.ui.present_details_shown)
01140 
01141         self.assertTrue('SourcePackage' in self.ui.report.keys())
01142         # did we run the hooks properly?
01143         self.assertTrue('KernelDebug' in self.ui.report.keys())
01144         self.assertEqual(self.ui.report['ProblemType'], 'KernelCrash')

run_crash() for already known problem

Definition at line 1256 of file test_ui.py.

01256 
01257     def test_run_crash_known(self):
01258         '''run_crash() for already known problem'''
01259 
01260         r = self._gen_test_crash()
01261         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01262         self.ui = TestSuiteUserInterface()
01263         self.ui.present_details_response = {'report': True,
01264                                             'blacklist': False,
01265                                             'examine': False,
01266                                             'restart': False}
01267 
01268         # known without URL
01269         with open(report_file, 'wb') as f:
01270             r.write(f)
01271         self.ui.crashdb.known = lambda r: True
01272         self.ui.run_crash(report_file)
01273         self.assertEqual(self.ui.report['KnownReport'], '1')
01274         self.assertEqual(self.ui.msg_severity, 'info')
01275         self.assertEqual(self.ui.opened_url, None)
01276 
01277         self.ui = TestSuiteUserInterface()
01278         self.ui.present_details_response = {'report': True,
01279                                             'blacklist': False,
01280                                             'examine': False,
01281                                             'restart': False}
01282         # known with URL
01283         with open(report_file, 'wb') as f:
01284             r.write(f)
01285         self.ui.crashdb.known = lambda r: 'http://myreport/1'
01286         self.ui.run_crash(report_file)
01287         self.assertEqual(self.ui.report['KnownReport'], 'http://myreport/1')
01288         self.assertEqual(self.ui.msg_severity, 'info')
01289         self.assertEqual(self.ui.opened_url, 'http://myreport/1')

Here is the call graph for this function:

run_crash() for a crash dump without CoreDump

Definition at line 857 of file test_ui.py.

00857 
00858     def test_run_crash_nocore(self):
00859         '''run_crash() for a crash dump without CoreDump'''
00860 
00861         # create a test executable
00862         test_executable = '/usr/bin/yes'
00863         assert os.access(test_executable, os.X_OK), test_executable + ' is not executable'
00864         pid = os.fork()
00865         if pid == 0:
00866             os.setsid()
00867             os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stdout.fileno())
00868             os.execv(test_executable, [test_executable])
00869             assert False, 'Could not execute ' + test_executable
00870 
00871         try:
00872             time.sleep(0.5)
00873             # generate crash report
00874             r = apport.Report()
00875             r['ExecutablePath'] = test_executable
00876             r['Signal'] = '42'
00877             r.add_proc_info(pid)
00878             r.add_user_info()
00879         finally:
00880             # kill test executable
00881             os.kill(pid, signal.SIGKILL)
00882             os.waitpid(pid, 0)
00883 
00884         # write crash report
00885         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00886         with open(report_file, 'wb') as f:
00887             r.write(f)
00888 
00889         # run
00890         self.ui = TestSuiteUserInterface()
00891         self.ui.run_crash(report_file)
00892         self.assertEqual(self.ui.msg_severity, 'error')
00893         self.assertTrue('memory' in self.ui.msg_text, '%s: %s' %
00894                         (self.ui.msg_title, self.ui.msg_text))

run_crash() for a package error

Definition at line 1039 of file test_ui.py.

01039 
01040     def test_run_crash_package(self):
01041         '''run_crash() for a package error'''
01042 
01043         # generate crash report
01044         r = apport.Report('Package')
01045         r['Package'] = 'bash'
01046         r['SourcePackage'] = 'bash'
01047         r['ErrorMessage'] = 'It broke'
01048         r['VarLogPackagerlog'] = 'foo\nbar'
01049         r.add_os_info()
01050 
01051         # write crash report
01052         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01053 
01054         # cancel crash notification dialog
01055         with open(report_file, 'wb') as f:
01056             r.write(f)
01057         self.ui = TestSuiteUserInterface()
01058         self.ui.present_details_response = {'report': False,
01059                                             'blacklist': False,
01060                                             'examine': False,
01061                                             'restart': False}
01062         self.ui.run_crash(report_file)
01063         self.assertEqual(self.ui.msg_severity, None)
01064         self.assertEqual(self.ui.msg_title, None)
01065         self.assertEqual(self.ui.opened_url, None)
01066         self.assertEqual(self.ui.ic_progress_pulses, 0)
01067         self.assertTrue(self.ui.present_details_shown)
01068 
01069         # report in crash notification dialog, send report
01070         with open(report_file, 'wb') as f:
01071             r.write(f)
01072         self.ui = TestSuiteUserInterface()
01073         self.ui.present_details_response = {'report': True,
01074                                             'blacklist': False,
01075                                             'examine': False,
01076                                             'restart': False}
01077         self.ui.run_crash(report_file)
01078         self.assertEqual(self.ui.msg_severity, None)
01079         self.assertEqual(self.ui.msg_title, None)
01080         self.assertEqual(self.ui.opened_url, 'http://bash.bugs.example.com/%i' % self.ui.crashdb.latest_id())
01081         self.assertTrue(self.ui.present_details_shown)
01082 
01083         self.assertTrue('SourcePackage' in self.ui.report.keys())
01084         self.assertTrue('Package' in self.ui.report.keys())
01085         self.assertEqual(self.ui.report['ProblemType'], 'Package')
01086 
01087         # verify that additional information has been collected
01088         self.assertTrue('Architecture' in self.ui.report.keys())
01089         self.assertTrue('DistroRelease' in self.ui.report.keys())
01090         self.assertTrue('Uname' in self.ui.report.keys())

run_crash() on complete report on uninstalled package

This happens when reporting a problem from a different machine through
copying a .crash file.

Definition at line 924 of file test_ui.py.

00924 
00925     def test_run_crash_precollected(self):
00926         '''run_crash() on complete report on uninstalled package
00927 
00928         This happens when reporting a problem from a different machine through
00929         copying a .crash file.
00930         '''
00931         self.ui.report = self._gen_test_crash()
00932         self.ui.collect_info()
00933 
00934         # now pretend to move it to a machine where the package is not
00935         # installed
00936         self.ui.report['Package'] = 'uninstalled_pkg 1'
00937 
00938         # write crash report
00939         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00940         with open(report_file, 'wb') as f:
00941             self.ui.report.write(f)
00942 
00943         # report it
00944         self.ui = TestSuiteUserInterface()
00945         self.ui.present_details_response = {'report': True,
00946                                             'blacklist': False,
00947                                             'examine': False,
00948                                             'restart': False}
00949         self.ui.run_crash(report_file)
00950         self.assertEqual(self.ui.cur_package, 'uninstalled_pkg')
00951         self.assertEqual(self.ui.msg_severity, None, 'has %s message: %s: %s' % (
00952             self.ui.msg_severity, str(self.ui.msg_title), str(self.ui.msg_text)))
00953         self.assertTrue(self.ui.opened_url.startswith('http://coreutils.bugs.example.com'))
00954         self.assertTrue(self.ui.present_details_shown)

Here is the call graph for this function:

run_crash() pre-retraced reports.

This happens with crashes which are pre-processed by
apport-retrace.

Definition at line 895 of file test_ui.py.

00895 
00896     def test_run_crash_preretraced(self):
00897         '''run_crash() pre-retraced reports.
00898 
00899         This happens with crashes which are pre-processed by
00900         apport-retrace.
00901         '''
00902         r = self._gen_test_crash()
00903 
00904         #  effect of apport-retrace -c
00905         r.add_gdb_info()
00906         del r['CoreDump']
00907 
00908         # write crash report
00909         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00910 
00911         # report in crash notification dialog, cancel details report
00912         with open(report_file, 'wb') as f:
00913             r.write(f)
00914         self.ui = TestSuiteUserInterface()
00915         self.ui.present_details_response = {'report': False,
00916                                             'blacklist': False,
00917                                             'examine': False,
00918                                             'restart': False}
00919         self.ui.run_crash(report_file)
00920         self.assertEqual(self.ui.msg_severity, None, 'has %s message: %s: %s' % (
00921             self.ui.msg_severity, str(self.ui.msg_title), str(self.ui.msg_text)))
00922         self.assertEqual(self.ui.msg_title, None)
00923         self.assertTrue(self.ui.present_details_shown)

Here is the call graph for this function:

run_crash() on reports with subsequently uninstalled packages

Definition at line 975 of file test_ui.py.

00975 
00976     def test_run_crash_uninstalled(self):
00977         '''run_crash() on reports with subsequently uninstalled packages'''
00978 
00979         # program got uninstalled between crash and report
00980         r = self._gen_test_crash()
00981         r['ExecutablePath'] = '/bin/nonexisting'
00982         r['Package'] = 'bash'
00983         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
00984         with open(report_file, 'wb') as f:
00985             r.write(f)
00986 
00987         self.ui.present_details_response = {'report': True,
00988                                             'blacklist': False,
00989                                             'examine': False,
00990                                             'restart': False}
00991         self.ui.run_crash(report_file)
00992 
00993         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
00994         self.assertEqual(self.ui.msg_severity, 'info')
00995 
00996         # interpreted program got uninstalled between crash and report
00997         r = apport.Report()
00998         r['ExecutablePath'] = '/bin/nonexisting'
00999         r['InterpreterPath'] = '/usr/bin/python'
01000         r['Traceback'] = 'ZeroDivisionError: integer division or modulo by zero'
01001 
01002         self.ui.run_crash(report_file)
01003 
01004         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
01005         self.assertEqual(self.ui.msg_severity, 'info')
01006 
01007         # interpreter got uninstalled between crash and report
01008         r = apport.Report()
01009         r['ExecutablePath'] = '/bin/sh'
01010         r['InterpreterPath'] = '/usr/bin/nonexisting'
01011         r['Traceback'] = 'ZeroDivisionError: integer division or modulo by zero'
01012 
01013         self.ui.run_crash(report_file)
01014 
01015         self.assertEqual(self.ui.msg_title, _('Invalid problem report'))
01016         self.assertEqual(self.ui.msg_severity, 'info')

Here is the call graph for this function:

run_crash() on a crash with the UnreportableReason field

Definition at line 829 of file test_ui.py.

00829 
00830     def test_run_crash_unreportable(self):
00831         '''run_crash() on a crash with the UnreportableReason field'''
00832 
00833         self.report['UnreportableReason'] = 'It stinks.'
00834         self.report['ExecutablePath'] = '/bin/bash'
00835         self.report['Package'] = 'bash 1'
00836         self.update_report_file()
00837         self.ui.present_details_response = {'report': True,
00838                                             'blacklist': False,
00839                                             'examine': False,
00840                                             'restart': False}
00841 
00842         self.ui.run_crash(self.report_file.name)
00843 
00844         self.assertTrue('It stinks.' in self.ui.msg_text, '%s: %s' %
00845                         (self.ui.msg_title, self.ui.msg_text))
00846         self.assertEqual(self.ui.msg_severity, 'info')

Here is the call graph for this function:

run_crash() on binary that got updated in the meantime

Definition at line 1017 of file test_ui.py.

01017 
01018     def test_run_crash_updated_binary(self):
01019         '''run_crash() on binary that got updated in the meantime'''
01020 
01021         r = self._gen_test_crash()
01022         r['ExecutableTimestamp'] = str(int(r['ExecutableTimestamp']) - 10)
01023         report_file = os.path.join(apport.fileutils.report_dir, 'test.crash')
01024         with open(report_file, 'wb') as f:
01025             r.write(f)
01026 
01027         self.ui.present_details_response = {'report': True,
01028                                             'blacklist': False,
01029                                             'examine': False,
01030                                             'restart': False}
01031         self.ui.run_crash(report_file)
01032 
01033         self.assertFalse('ExecutableTimestamp' in self.ui.report)
01034         self.assertTrue(self.ui.report['ExecutablePath'] in self.ui.msg_text, '%s: %s' %
01035                         (self.ui.msg_title, self.ui.msg_text))
01036         self.assertTrue('changed' in self.ui.msg_text, '%s: %s' %
01037                         (self.ui.msg_title, self.ui.msg_text))
01038         self.assertEqual(self.ui.msg_severity, 'info')

Here is the call graph for this function:

running the frontend without any pending reports

Definition at line 398 of file test_ui.py.

00398 
00399     def test_run_nopending(self):
00400         '''running the frontend without any pending reports'''
00401 
00402         sys.argv = []
00403         self.ui = TestSuiteUserInterface()
00404         self.assertEqual(self.ui.run_argv(), False)

run_report_bug() with saving report into a file

Definition at line 589 of file test_ui.py.

00589 
00590     def test_run_report_bug_file(self):
00591         '''run_report_bug() with saving report into a file'''
00592 
00593         d = os.path.join(apport.fileutils.report_dir, 'home')
00594         os.mkdir(d)
00595         reportfile = os.path.join(d, 'bashisbad.apport')
00596 
00597         sys.argv = ['ui-test', '-f', '-p', 'bash', '--save', reportfile]
00598         self.ui = TestSuiteUserInterface()
00599         self.assertEqual(self.ui.run_argv(), True)
00600 
00601         self.assertEqual(self.ui.msg_severity, None)
00602         self.assertEqual(self.ui.msg_title, None)
00603         self.assertEqual(self.ui.opened_url, None)
00604         self.assertFalse(self.ui.present_details_shown)
00605 
00606         self.assertTrue(self.ui.ic_progress_pulses > 0)
00607 
00608         r = apport.Report()
00609         with open(reportfile, 'rb') as f:
00610             r.load(f)
00611 
00612         self.assertEqual(r['SourcePackage'], 'bash')
00613         self.assertTrue('Dependencies' in r.keys())
00614         self.assertTrue('ProcEnviron' in r.keys())
00615         self.assertEqual(r['ProblemType'], 'Bug')
00616 
00617         # report it
00618         sys.argv = ['ui-test', '-c', reportfile]
00619         self.ui = TestSuiteUserInterface()
00620         self.ui.present_details_response = {'report': True,
00621                                             'blacklist': False,
00622                                             'examine': False,
00623                                             'restart': False}
00624         self.assertEqual(self.ui.run_argv(), True)
00625 
00626         self.assertEqual(self.ui.msg_text, None)
00627         self.assertEqual(self.ui.msg_severity, None)
00628         self.assertTrue(self.ui.present_details_shown)

run_report_bug() for a pid of a kernel thread

Definition at line 566 of file test_ui.py.

00566 
00567     def test_run_report_bug_kernel_thread(self):
00568         '''run_report_bug() for a pid of a kernel thread'''
00569 
00570         pid = None
00571         for path in glob.glob('/proc/[0-9]*/stat'):
00572             with open(path) as f:
00573                 stat = f.read().split()
00574             flags = int(stat[8])
00575             if flags & apport.ui.PF_KTHREAD:
00576                 pid = int(stat[0])
00577                 break
00578 
00579         self.assertFalse(pid is None)
00580         sys.argv = ['ui-test', '-f', '-P', str(pid)]
00581         self.ui = TestSuiteUserInterface()
00582         self.ui.present_details_response = {'report': True,
00583                                             'blacklist': False,
00584                                             'examine': False,
00585                                             'restart': False}
00586         self.ui.run_argv()
00587 
00588         self.assertTrue(self.ui.report['Package'].startswith(apport.packaging.get_kernel_package()))

run_report_bug() without specifying arguments and available symptoms

Definition at line 1652 of file test_ui.py.

01652 
01653     def test_run_report_bug_list_symptoms(self):
01654         '''run_report_bug() without specifying arguments and available symptoms'''
01655 
01656         f = open(os.path.join(apport.ui.symptom_script_dir, 'foo.py'), 'w')
01657         f.write('''description = 'foo does not work'
01658 def run(report, ui):
01659     return 'bash'
01660 ''')
01661         f.close()
01662         f = open(os.path.join(apport.ui.symptom_script_dir, 'bar.py'), 'w')
01663         f.write('def run(report, ui):\n  return "coreutils"\n')
01664         f.close()
01665 
01666         sys.argv = ['ui-test', '-f']
01667         self.ui = TestSuiteUserInterface()
01668         self.ui.present_details_response = {'report': True,
01669                                             'blacklist': False,
01670                                             'examine': False,
01671                                             'restart': False}
01672 
01673         self.ui.question_choice_response = None
01674         self.assertEqual(self.ui.run_argv(), True)
01675         self.assertEqual(self.ui.msg_severity, None)
01676         self.assertTrue('kind of problem' in self.ui.msg_text)
01677         self.assertEqual(set(self.ui.msg_choices),
01678                          set(['bar', 'foo does not work', 'Other problem']))
01679 
01680         # cancelled
01681         self.assertEqual(self.ui.ic_progress_pulses, 0)
01682         self.assertEqual(self.ui.report, None)
01683         self.assertFalse(self.ui.present_details_shown)
01684 
01685         # now, choose foo -> bash report
01686         self.ui.question_choice_response = [self.ui.msg_choices.index('foo does not work')]
01687         self.assertEqual(self.ui.run_argv(), True)
01688         self.assertEqual(self.ui.msg_severity, None)
01689         self.assertTrue(self.ui.ic_progress_pulses > 0)
01690         self.assertTrue(self.ui.present_details_shown)
01691         self.assertTrue(self.ui.report['Package'].startswith('bash'))

run_report_bug() without specifying arguments

Definition at line 405 of file test_ui.py.

00405 
00406     def test_run_report_bug_noargs(self):
00407         '''run_report_bug() without specifying arguments'''
00408 
00409         sys.argv = ['ui-test', '-f']
00410         self.ui = TestSuiteUserInterface()
00411         self.assertEqual(self.ui.run_argv(), False)
00412         self.assertEqual(self.ui.msg_severity, 'error')

run_report_bug() for a pid which runs as a different user

Definition at line 520 of file test_ui.py.

00520 
00521     def test_run_report_bug_noperm_pid(self):
00522         '''run_report_bug() for a pid which runs as a different user'''
00523 
00524         restore_root = False
00525         if os.getuid() == 0:
00526             # temporarily drop to normal user "mail"
00527             os.setresuid(8, 8, -1)
00528             restore_root = True
00529 
00530         try:
00531             sys.argv = ['ui-test', '-f', '-P', '1']
00532             self.ui = TestSuiteUserInterface()
00533             self.ui.run_argv()
00534 
00535             self.assertEqual(self.ui.msg_severity, 'error')
00536         finally:
00537             if restore_root:
00538                 os.setresuid(0, 0, -1)

run_report_bug() for a package

Definition at line 425 of file test_ui.py.

00425 
00426     def test_run_report_bug_package(self):
00427         '''run_report_bug() for a package'''
00428 
00429         sys.argv = ['ui-test', '-f', '-p', 'bash']
00430         self.ui = TestSuiteUserInterface()
00431         self.ui.present_details_response = {'report': True,
00432                                             'blacklist': False,
00433                                             'examine': False,
00434                                             'restart': False}
00435         self.assertEqual(self.ui.run_argv(), True)
00436 
00437         self.assertEqual(self.ui.msg_severity, None)
00438         self.assertEqual(self.ui.msg_title, None)
00439         self.assertTrue(self.ui.present_details_shown)
00440         self.assertEqual(self.ui.opened_url, 'http://bash.bugs.example.com/%i' % self.ui.crashdb.latest_id())
00441 
00442         self.assertTrue(self.ui.ic_progress_pulses > 0)
00443         self.assertEqual(self.ui.report['SourcePackage'], 'bash')
00444         self.assertTrue('Dependencies' in self.ui.report.keys())
00445         self.assertTrue('ProcEnviron' in self.ui.report.keys())
00446         self.assertEqual(self.ui.report['ProblemType'], 'Bug')
00447 
00448         # should not crash on nonexisting package
00449         sys.argv = ['ui-test', '-f', '-p', 'nonexisting_gibberish']
00450         self.ui = TestSuiteUserInterface()
00451         self.ui.run_argv()
00452 
00453         self.assertEqual(self.ui.msg_severity, 'error')

run_report_bug() for a pid with extra tags

Definition at line 454 of file test_ui.py.

00454 
00455     def test_run_report_bug_pid_tags(self):
00456         '''run_report_bug() for a pid with extra tags'''
00457 
00458         # fork a test process
00459         pid = os.fork()
00460         if pid == 0:
00461             os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stdout.fileno())
00462             os.execv('/usr/bin/yes', ['yes'])
00463             assert False, 'Could not execute /usr/bin/yes'
00464 
00465         time.sleep(0.5)
00466 
00467         try:
00468             # report a bug on yes process
00469             sys.argv = ['ui-test', '-f', '--tag', 'foo', '-P', str(pid)]
00470             self.ui = TestSuiteUserInterface()
00471             self.ui.present_details_response = {'report': True,
00472                                                 'blacklist': False,
00473                                                 'examine': False,
00474                                                 'restart': False}
00475             self.assertEqual(self.ui.run_argv(), True)
00476         finally:
00477             # kill test process
00478             os.kill(pid, signal.SIGKILL)
00479             os.waitpid(pid, 0)
00480 
00481         self.assertTrue('SourcePackage' in self.ui.report.keys())
00482         self.assertTrue('Dependencies' in self.ui.report.keys())
00483         self.assertTrue('ProcMaps' in self.ui.report.keys())
00484         self.assertEqual(self.ui.report['ExecutablePath'], '/usr/bin/yes')
00485         self.assertFalse('ProcCmdline' in self.ui.report)  # privacy!
00486         self.assertTrue('ProcEnviron' in self.ui.report.keys())
00487         self.assertEqual(self.ui.report['ProblemType'], 'Bug')
00488         self.assertTrue('Tags' in self.ui.report.keys())
00489         self.assertTrue('foo' in self.ui.report['Tags'])
00490 
00491         self.assertEqual(self.ui.msg_severity, None)
00492         self.assertEqual(self.ui.msg_title, None)
00493         self.assertEqual(self.ui.opened_url, 'http://coreutils.bugs.example.com/%i' % self.ui.crashdb.latest_id())
00494         self.assertTrue(self.ui.present_details_shown)
00495         self.assertTrue(self.ui.ic_progress_pulses > 0)

run_report_bug() for a pid of an unpackaged program

Definition at line 539 of file test_ui.py.

00539 
00540     def test_run_report_bug_unpackaged_pid(self):
00541         '''run_report_bug() for a pid of an unpackaged program'''
00542 
00543         # create unpackaged test program
00544         (fd, exename) = tempfile.mkstemp()
00545         with open('/usr/bin/yes', 'rb') as f:
00546             os.write(fd, f.read())
00547         os.close(fd)
00548         os.chmod(exename, 0o755)
00549 
00550         # unpackaged test process
00551         pid = os.fork()
00552         if pid == 0:
00553             os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stdout.fileno())
00554             os.execv(exename, [exename])
00555 
00556         try:
00557             sys.argv = ['ui-test', '-f', '-P', str(pid)]
00558             self.ui = TestSuiteUserInterface()
00559             self.assertRaises(SystemExit, self.ui.run_argv)
00560         finally:
00561             os.kill(pid, signal.SIGKILL)
00562             os.wait()
00563             os.unlink(exename)
00564 
00565         self.assertEqual(self.ui.msg_severity, 'error')

run_report_bug() for a nonexisting pid

Definition at line 510 of file test_ui.py.

00510 
00511     def test_run_report_bug_wrong_pid(self):
00512         '''run_report_bug() for a nonexisting pid'''
00513 
00514         # silently ignore missing PID; this happens when the user closes
00515         # the application prematurely
00516         pid = self._find_unused_pid()
00517         sys.argv = ['ui-test', '-f', '-P', str(pid)]
00518         self.ui = TestSuiteUserInterface()
00519         self.ui.run_argv()

Here is the call graph for this function:

run_symptom()

Definition at line 1538 of file test_ui.py.

01538 
01539     def test_run_symptom(self):
01540         '''run_symptom()'''
01541 
01542         # unknown symptom
01543         sys.argv = ['ui-test', '-s', 'foobar']
01544         self.ui = TestSuiteUserInterface()
01545         self.ui.present_details_response = {'report': True,
01546                                             'blacklist': False,
01547                                             'examine': False,
01548                                             'restart': False}
01549         self.assertEqual(self.ui.run_argv(), True)
01550         self.assertTrue('foobar" is not known' in self.ui.msg_text)
01551         self.assertEqual(self.ui.msg_severity, 'error')
01552 
01553         # does not determine package
01554         f = open(os.path.join(apport.ui.symptom_script_dir, 'nopkg.py'), 'w')
01555         f.write('def run(report, ui):\n    pass\n')
01556         f.close()
01557         orig_stderr = sys.stderr
01558         sys.argv = ['ui-test', '-s', 'nopkg']
01559         self.ui = TestSuiteUserInterface()
01560         sys.stderr = StringIO()
01561         self.assertRaises(SystemExit, self.ui.run_argv)
01562         err = sys.stderr.getvalue()
01563         sys.stderr = orig_stderr
01564         self.assertTrue('did not determine the affected package' in err)
01565 
01566         # does not define run()
01567         f = open(os.path.join(apport.ui.symptom_script_dir, 'norun.py'), 'w')
01568         f.write('def something(x, y):\n    return 1\n')
01569         f.close()
01570         sys.argv = ['ui-test', '-s', 'norun']
01571         self.ui = TestSuiteUserInterface()
01572         sys.stderr = StringIO()
01573         self.assertRaises(SystemExit, self.ui.run_argv)
01574         err = sys.stderr.getvalue()
01575         sys.stderr = orig_stderr
01576         self.assertTrue('norun.py crashed:' in err)
01577 
01578         # crashing script
01579         f = open(os.path.join(apport.ui.symptom_script_dir, 'crash.py'), 'w')
01580         f.write('def run(report, ui):\n    return 1/0\n')
01581         f.close()
01582         sys.argv = ['ui-test', '-s', 'crash']
01583         self.ui = TestSuiteUserInterface()
01584         sys.stderr = StringIO()
01585         self.assertRaises(SystemExit, self.ui.run_argv)
01586         err = sys.stderr.getvalue()
01587         sys.stderr = orig_stderr
01588         self.assertTrue('crash.py crashed:' in err)
01589         self.assertTrue('ZeroDivisionError:' in err)
01590 
01591         # working noninteractive script
01592         f = open(os.path.join(apport.ui.symptom_script_dir, 'itching.py'), 'w')
01593         f.write('def run(report, ui):\n  report["itch"] = "scratch"\n  return "bash"\n')
01594         f.close()
01595         sys.argv = ['ui-test', '-s', 'itching']
01596         self.ui = TestSuiteUserInterface()
01597         self.ui.present_details_response = {'report': True,
01598                                             'blacklist': False,
01599                                             'examine': False,
01600                                             'restart': False}
01601         self.assertEqual(self.ui.run_argv(), True)
01602         self.assertEqual(self.ui.msg_text, None)
01603         self.assertEqual(self.ui.msg_severity, None)
01604         self.assertTrue(self.ui.present_details_shown)
01605 
01606         self.assertEqual(self.ui.report['itch'], 'scratch')
01607         self.assertTrue('DistroRelease' in self.ui.report)
01608         self.assertEqual(self.ui.report['SourcePackage'], 'bash')
01609         self.assertTrue(self.ui.report['Package'].startswith('bash '))
01610         self.assertEqual(self.ui.report['ProblemType'], 'Bug')
01611 
01612         # working noninteractive script with extra tag
01613         sys.argv = ['ui-test', '--tag', 'foo', '-s', 'itching']
01614         self.ui = TestSuiteUserInterface()
01615         self.ui.present_details_response = {'report': True,
01616                                             'blacklist': False,
01617                                             'examine': False,
01618                                             'restart': False}
01619         self.assertEqual(self.ui.run_argv(), True)
01620         self.assertEqual(self.ui.msg_text, None)
01621         self.assertEqual(self.ui.msg_severity, None)
01622         self.assertTrue(self.ui.present_details_shown)
01623 
01624         self.assertEqual(self.ui.report['itch'], 'scratch')
01625         self.assertTrue('foo' in self.ui.report['Tags'])
01626 
01627         # working interactive script
01628         f = open(os.path.join(apport.ui.symptom_script_dir, 'itching.py'), 'w')
01629         f.write('''def run(report, ui):
01630     report['itch'] = 'slap'
01631     report['q'] = str(ui.yesno('do you?'))
01632     return 'bash'
01633 ''')
01634         f.close()
01635         sys.argv = ['ui-test', '-s', 'itching']
01636         self.ui = TestSuiteUserInterface()
01637         self.ui.present_details_response = {'report': True,
01638                                             'blacklist': False,
01639                                             'examine': False,
01640                                             'restart': False}
01641         self.ui.question_yesno_response = True
01642         self.assertEqual(self.ui.run_argv(), True)
01643         self.assertTrue(self.ui.present_details_shown)
01644         self.assertEqual(self.ui.msg_text, 'do you?')
01645 
01646         self.assertEqual(self.ui.report['itch'], 'slap')
01647         self.assertTrue('DistroRelease' in self.ui.report)
01648         self.assertEqual(self.ui.report['SourcePackage'], 'bash')
01649         self.assertTrue(self.ui.report['Package'].startswith('bash '))
01650         self.assertEqual(self.ui.report['ProblemType'], 'Bug')
01651         self.assertEqual(self.ui.report['q'], 'True')

run_update_report() on a source package which does not have a binary of the same name

Definition at line 1400 of file test_ui.py.

01400 
01401     def test_run_update_report_different_binary_source(self):
01402         '''run_update_report() on a source package which does not have a binary of the same name'''
01403 
01404         kernel_pkg = apport.packaging.get_kernel_package()
01405         kernel_src = apport.packaging.get_source(kernel_pkg)
01406         self.assertNotEqual(kernel_pkg, kernel_src,
01407                             'this test assumes that the kernel binary package != kernel source package')
01408         self.assertNotEqual(apport.packaging.get_version(kernel_pkg), '',
01409                             'this test assumes that the kernel binary package %s is installed' % kernel_pkg)
01410 
01411         # this test assumes that the kernel source package name is not an
01412         # installed binary package
01413         self.assertRaises(ValueError, apport.packaging.get_version, kernel_src)
01414 
01415         sys.argv = ['ui-test', '-p', kernel_src, '-u', '1']
01416         self.ui = TestSuiteUserInterface()
01417         self.ui.present_details_response = {'report': True,
01418                                             'blacklist': False,
01419                                             'examine': False,
01420                                             'restart': False}
01421 
01422         with open(os.path.join(self.hookdir, 'source_%s.py' % kernel_src), 'w') as f:
01423             f.write('def add_info(r, ui):\n  r["MachineType"]="Laptop"\n')
01424 
01425         self.assertEqual(self.ui.run_argv(), True, self.ui.report)
01426         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01427         self.assertEqual(self.ui.msg_title, None)
01428         self.assertEqual(self.ui.opened_url, None)
01429         self.assertTrue(self.ui.present_details_shown)
01430 
01431         self.assertTrue(self.ui.ic_progress_pulses > 0)
01432         self.assertEqual(self.ui.report['Package'], '%s (not installed)' % kernel_src)
01433         self.assertEqual(self.ui.report['MachineType'], 'Laptop')
01434         self.assertTrue('ProcEnviron' in self.ui.report.keys())

run_update_report() on an existing package (-collect program)

Definition at line 1355 of file test_ui.py.

01355 
01356     def test_run_update_report_existing_package_cli_cmdname(self):
01357         '''run_update_report() on an existing package (-collect program)'''
01358 
01359         sys.argv = ['apport-collect', '-p', 'bash', '1']
01360         self.ui = TestSuiteUserInterface()
01361         self.ui.present_details_response = {'report': True,
01362                                             'blacklist': False,
01363                                             'examine': False,
01364                                             'restart': False}
01365 
01366         self.assertEqual(self.ui.run_argv(), True)
01367         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01368         self.assertEqual(self.ui.msg_title, None)
01369         self.assertEqual(self.ui.opened_url, None)
01370         self.assertTrue(self.ui.present_details_shown)
01371 
01372         self.assertTrue(self.ui.ic_progress_pulses > 0)
01373         self.assertTrue(self.ui.report['Package'].startswith('bash '))
01374         self.assertTrue('Dependencies' in self.ui.report.keys())
01375         self.assertTrue('ProcEnviron' in self.ui.report.keys())

run_update_report() on an existing package (CLI argument) with extra tag

Definition at line 1333 of file test_ui.py.

01333 
01334     def test_run_update_report_existing_package_cli_tags(self):
01335         '''run_update_report() on an existing package (CLI argument) with extra tag'''
01336 
01337         sys.argv = ['ui-test', '-u', '1', '-p', 'bash', '--tag', 'foo']
01338         self.ui = TestSuiteUserInterface()
01339         self.ui.present_details_response = {'report': True,
01340                                             'blacklist': False,
01341                                             'examine': False,
01342                                             'restart': False}
01343 
01344         self.assertEqual(self.ui.run_argv(), True)
01345         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01346         self.assertEqual(self.ui.msg_title, None)
01347         self.assertEqual(self.ui.opened_url, None)
01348         self.assertTrue(self.ui.present_details_shown)
01349 
01350         self.assertTrue(self.ui.ic_progress_pulses > 0)
01351         self.assertTrue(self.ui.report['Package'].startswith('bash '))
01352         self.assertTrue('Dependencies' in self.ui.report.keys())
01353         self.assertTrue('ProcEnviron' in self.ui.report.keys())
01354         self.assertTrue('foo' in self.ui.report['Tags'])

run_update_report() on an existing package (from bug)

Definition at line 1310 of file test_ui.py.

01310 
01311     def test_run_update_report_existing_package_from_bug(self):
01312         '''run_update_report() on an existing package (from bug)'''
01313 
01314         sys.argv = ['ui-test', '-u', '1']
01315         self.ui = TestSuiteUserInterface()
01316         self.ui.present_details_response = {'report': True,
01317                                             'blacklist': False,
01318                                             'examine': False,
01319                                             'restart': False}
01320 
01321         self.ui.crashdb.download(1)['SourcePackage'] = 'bash'
01322         self.ui.crashdb.download(1)['Package'] = 'bash'
01323         self.assertEqual(self.ui.run_argv(), True)
01324         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01325         self.assertEqual(self.ui.msg_title, None)
01326         self.assertEqual(self.ui.opened_url, None)
01327         self.assertTrue(self.ui.present_details_shown)
01328 
01329         self.assertTrue(self.ui.ic_progress_pulses > 0)
01330         self.assertTrue(self.ui.report['Package'].startswith('bash '))
01331         self.assertTrue('Dependencies' in self.ui.report.keys())
01332         self.assertTrue('ProcEnviron' in self.ui.report.keys())

run_update_report() on a nonexisting package (CLI argument)

Definition at line 1300 of file test_ui.py.

01300 
01301     def test_run_update_report_nonexisting_package_cli(self):
01302         '''run_update_report() on a nonexisting package (CLI argument)'''
01303 
01304         sys.argv = ['ui-test', '-u', '1', '-p', 'bar']
01305         self.ui = TestSuiteUserInterface()
01306 
01307         self.assertEqual(self.ui.run_argv(), False)
01308         self.assertTrue('No additional information collected.' in self.ui.msg_text)
01309         self.assertFalse(self.ui.present_details_shown)

run_update_report() on a nonexisting package (from bug)

Definition at line 1290 of file test_ui.py.

01290 
01291     def test_run_update_report_nonexisting_package_from_bug(self):
01292         '''run_update_report() on a nonexisting package (from bug)'''
01293 
01294         sys.argv = ['ui-test', '-u', '1']
01295         self.ui = TestSuiteUserInterface()
01296 
01297         self.assertEqual(self.ui.run_argv(), False)
01298         self.assertTrue('No additional information collected.' in self.ui.msg_text)
01299         self.assertFalse(self.ui.present_details_shown)

run_update_report() on an uninstalled package with a source hook

Definition at line 1376 of file test_ui.py.

01376 
01377     def test_run_update_report_noninstalled_but_hook(self):
01378         '''run_update_report() on an uninstalled package with a source hook'''
01379 
01380         sys.argv = ['ui-test', '-u', '1']
01381         self.ui = TestSuiteUserInterface()
01382         self.ui.present_details_response = {'report': True,
01383                                             'blacklist': False,
01384                                             'examine': False,
01385                                             'restart': False}
01386 
01387         with open(os.path.join(self.hookdir, 'source_foo.py'), 'w') as f:
01388             f.write('def add_info(r, ui):\n  r["MachineType"]="Laptop"\n')
01389 
01390         self.assertEqual(self.ui.run_argv(), True, self.ui.report)
01391         self.assertEqual(self.ui.msg_severity, None, self.ui.msg_text)
01392         self.assertEqual(self.ui.msg_title, None)
01393         self.assertEqual(self.ui.opened_url, None)
01394         self.assertTrue(self.ui.present_details_shown)
01395 
01396         self.assertTrue(self.ui.ic_progress_pulses > 0)
01397         self.assertEqual(self.ui.report['Package'], 'foo (not installed)')
01398         self.assertEqual(self.ui.report['MachineType'], 'Laptop')
01399         self.assertTrue('ProcEnviron' in self.ui.report.keys())

run_report_bug() as "ubuntu-bug" with version argument

Definition at line 413 of file test_ui.py.

00413 
00414     def test_run_version(self):
00415         '''run_report_bug() as "ubuntu-bug" with version argument'''
00416 
00417         sys.argv = ['ubuntu-bug', '-v']
00418         self.ui = TestSuiteUserInterface()
00419         orig_stdout = sys.stdout
00420         sys.stdout = StringIO()
00421         self.assertEqual(self.ui.run_argv(), True)
00422         output = sys.stdout.getvalue()
00423         sys.stdout = orig_stdout
00424         self.assertEqual(output, apport.ui.__version__ + '\n')

Definition at line 1954 of file test_ui.py.

01954 
01955     def test_wait_for_pid(self):
01956         # fork a test process
01957         pid = os.fork()
01958         if pid == 0:
01959             os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stdout.fileno())
01960             os.execv('/usr/bin/yes', ['yes'])
01961             assert False, 'Could not execute /usr/bin/yes'
01962 
01963         time.sleep(0.5)
01964         os.kill(pid, signal.SIGKILL)
01965         os.waitpid(pid, 0)
01966         self.ui.wait_for_pid(pid)
01967 
01968 
01969 unittest.main()

Definition at line 165 of file test_ui.py.

00165 
00166     def update_report_file(self):
00167         self.report_file.seek(0)
00168         self.report_file.truncate()
00169         self.report.write(self.report_file)
00170         self.report_file.flush()

Here is the caller graph for this function:


Member Data Documentation

Definition at line 157 of file test_ui.py.

Definition at line 140 of file test_ui.py.

Definition at line 158 of file test_ui.py.

Definition at line 135 of file test_ui.py.

Definition at line 131 of file test_ui.py.

Definition at line 133 of file test_ui.py.

Definition at line 145 of file test_ui.py.

Definition at line 153 of file test_ui.py.

Definition at line 142 of file test_ui.py.


The documentation for this class was generated from the following file: