Back to index

apport  2.4
test_java_crashes.py
Go to the documentation of this file.
00001 # Copyright (C) 2010 Canonical Ltd.
00002 # Author: Martin Pitt <martin.pitt@ubuntu.com>
00003 #
00004 # This program is free software; you can redistribute it and/or modify it
00005 # under the terms of the GNU General Public License as published by the
00006 # Free Software Foundation; either version 2 of the License, or (at your
00007 # option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
00008 # the full text of the license.
00009 
00010 import tempfile, unittest, subprocess, sys, os, os.path, shutil
00011 
00012 import apport, apport.fileutils
00013 
00014 
00015 class T(unittest.TestCase):
00016     def setUp(self):
00017         mydir = os.path.dirname(os.path.realpath(sys.argv[0]))
00018         datadir = os.environ.get('APPORT_DATA_DIR', '/usr/share/apport')
00019         self.srcdir = os.path.dirname(mydir)
00020         self.orig_report_dir = apport.fileutils.report_dir
00021         apport.fileutils.report_dir = tempfile.mkdtemp()
00022         os.environ['APPORT_REPORT_DIR'] = apport.fileutils.report_dir
00023         os.environ['APPORT_JAVA_EXCEPTION_HANDLER'] = os.path.join(
00024             datadir, 'java_uncaught_exception')
00025         if os.environ.get('APPORT_TEST_LOCAL'):
00026             self.crash_jar_path = os.path.join(self.srcdir, 'java', 'crash.jar')
00027             self.apport_jar_path = os.path.join(self.srcdir, 'java', 'apport.jar')
00028         else:
00029             self.crash_jar_path = os.path.join(mydir, 'crash.jar')
00030             self.apport_jar_path = os.path.join(datadir, 'apport.jar')
00031 
00032     def tearDown(self):
00033         shutil.rmtree(apport.fileutils.report_dir)
00034         apport.fileutils.report_dir = self.orig_report_dir
00035 
00036     def test_crash_class(self):
00037         '''Crash in a .class file'''
00038 
00039         p = subprocess.Popen(['java', '-classpath',
00040                               self.apport_jar_path + ':' + os.path.dirname(self.crash_jar_path), 'crash'],
00041                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
00042         (out, err) = p.communicate()
00043         self.assertNotEqual(p.returncode, 0, 'crash must exit with nonzero code')
00044         self.assertTrue(b"Can't catch this" in err,
00045                         'crash handler must print original exception:\n' + err.decode())
00046 
00047         self._check_crash_report(os.path.dirname(self.crash_jar_path) + '/crash.class')
00048 
00049     def test_crash_jar(self):
00050         '''Crash in a .jar file'''
00051 
00052         p = subprocess.Popen(['java', '-classpath',
00053                               self.apport_jar_path + ':' + self.crash_jar_path, 'crash'],
00054                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
00055         (out, err) = p.communicate()
00056         self.assertNotEqual(p.returncode, 0, 'crash must exit with nonzero code')
00057         self.assertTrue(b"Can't catch this" in err,
00058                         'crash handler must print original exception:\n' + err.decode())
00059 
00060         self._check_crash_report(self.crash_jar_path + '!/crash.class')
00061 
00062     def _check_crash_report(self, main_file):
00063         '''Check that we have one crash report, and verify its contents'''
00064 
00065         reports = apport.fileutils.get_new_reports()
00066         self.assertEqual(len(reports), 1, 'did not create a crash report')
00067         r = apport.Report()
00068         with open(reports[0], 'rb') as f:
00069             r.load(f)
00070         self.assertEqual(r['ProblemType'], 'Crash')
00071         self.assertTrue(r['ProcCmdline'].startswith('java -classpath'), r)
00072         self.assertTrue(r['StackTrace'].startswith(
00073             "java.lang.RuntimeException: Can't catch this"))
00074         if '.jar!' in main_file:
00075             self.assertEqual(r['MainClassUrl'], 'jar:file:' + main_file)
00076         else:
00077             self.assertEqual(r['MainClassUrl'], 'file:' + main_file)
00078         self.assertTrue('DistroRelease' in r)
00079         self.assertTrue('ProcCwd' in r)
00080 
00081 #
00082 # main
00083 #
00084 
00085 try:
00086     subprocess.check_call(['java', '-version'], stdout=subprocess.PIPE,
00087                           stderr=subprocess.PIPE)
00088 except OSError:
00089     apport.warning('Java not available, skipping')
00090     sys.exit(0)
00091 
00092 unittest.main()