testing/mozbase/mozcrash/tests/test.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #!/usr/bin/env python
     2 #
     3 # This Source Code Form is subject to the terms of the Mozilla Public
     4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5 # You can obtain one at http://mozilla.org/MPL/2.0/.
     7 import os, unittest, subprocess, tempfile, shutil, urlparse, zipfile, StringIO
     8 import mozcrash, mozlog, mozhttpd
    10 # Make logs go away
    11 log = mozlog.getLogger("mozcrash", handler=mozlog.FileHandler(os.devnull))
    13 def popen_factory(stdouts):
    14     """
    15     Generate a class that can mock subprocess.Popen. |stdouts| is an iterable that
    16     should return an iterable for the stdout of each process in turn.
    17     """
    18     class mock_popen(object):
    19         def __init__(self, args, *args_rest, **kwargs):
    20             self.stdout = stdouts.next()
    21             self.returncode = 0
    23         def wait(self):
    24             return 0
    26         def communicate(self):
    27             return (self.stdout.next(), "")
    29     return mock_popen
    31 class TestCrash(unittest.TestCase):
    32     def setUp(self):
    33         self.tempdir = tempfile.mkdtemp()
    34         # a fake file to use as a stackwalk binary
    35         self.stackwalk = os.path.join(self.tempdir, "stackwalk")
    36         open(self.stackwalk, "w").write("fake binary")
    37         self._subprocess_popen = subprocess.Popen
    38         subprocess.Popen = popen_factory(self.next_mock_stdout())
    39         self.stdouts = []
    41     def tearDown(self):
    42         subprocess.Popen = self._subprocess_popen
    43         shutil.rmtree(self.tempdir)
    45     def next_mock_stdout(self):
    46         if not self.stdouts:
    47             yield iter([])
    48         for s in self.stdouts:
    49             yield iter(s)
    51     def test_nodumps(self):
    52         """
    53         Test that check_for_crashes returns False if no dumps are present.
    54         """
    55         self.stdouts.append(["this is some output"])
    56         self.assertFalse(mozcrash.check_for_crashes(self.tempdir,
    57                                                     'symbols_path',
    58                                                     stackwalk_binary=self.stackwalk,
    59                                                     quiet=True))
    61     def test_simple(self):
    62         """
    63         Test that check_for_crashes returns True if a dump is present.
    64         """
    65         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
    66         self.stdouts.append(["this is some output"])
    67         self.assert_(mozcrash.check_for_crashes(self.tempdir,
    68                                                 'symbols_path',
    69                                                 stackwalk_binary=self.stackwalk,
    70                                                 quiet=True))
    72     def test_stackwalk_envvar(self):
    73         """
    74         Test that check_for_crashes uses the MINIDUMP_STACKWALK environment var.
    75         """
    76         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
    77         self.stdouts.append(["this is some output"])
    78         os.environ['MINIDUMP_STACKWALK'] = self.stackwalk
    79         self.assert_(mozcrash.check_for_crashes(self.tempdir,
    80                                                 'symbols_path',
    81                                                 quiet=True))
    82         del os.environ['MINIDUMP_STACKWALK']
    84     def test_save_path(self):
    85         """
    86         Test that dump_save_path works.
    87         """
    88         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
    89         open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
    90         save_path = os.path.join(self.tempdir, "saved")
    91         os.mkdir(save_path)
    92         self.stdouts.append(["this is some output"])
    93         self.assert_(mozcrash.check_for_crashes(self.tempdir,
    94                                                 'symbols_path',
    95                                                 stackwalk_binary=self.stackwalk,
    96                                                 dump_save_path=save_path,
    97                                                 quiet=True))
    98         self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
    99         self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
   101     def test_save_path_not_present(self):
   102         """
   103         Test that dump_save_path works when the directory doesn't exist.
   104         """
   105         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
   106         open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
   107         save_path = os.path.join(self.tempdir, "saved")
   108         self.stdouts.append(["this is some output"])
   109         self.assert_(mozcrash.check_for_crashes(self.tempdir,
   110                                                 'symbols_path',
   111                                                 stackwalk_binary=self.stackwalk,
   112                                                 dump_save_path=save_path,
   113                                                 quiet=True))
   114         self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
   115         self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
   117     def test_save_path_isfile(self):
   118         """
   119         Test that dump_save_path works when the directory doesn't exist,
   120         but a file with the same name exists.
   121         """
   122         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
   123         open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
   124         save_path = os.path.join(self.tempdir, "saved")
   125         open(save_path, "w").write("junk")
   126         self.stdouts.append(["this is some output"])
   127         self.assert_(mozcrash.check_for_crashes(self.tempdir,
   128                                                 'symbols_path',
   129                                                 stackwalk_binary=self.stackwalk,
   130                                                 dump_save_path=save_path,
   131                                                 quiet=True))
   132         self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
   133         self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
   135     def test_save_path_envvar(self):
   136         """
   137         Test that the MINDUMP_SAVE_PATH environment variable works.
   138         """
   139         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
   140         open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
   141         save_path = os.path.join(self.tempdir, "saved")
   142         os.mkdir(save_path)
   143         self.stdouts.append(["this is some output"])
   144         os.environ['MINIDUMP_SAVE_PATH'] = save_path
   145         self.assert_(mozcrash.check_for_crashes(self.tempdir,
   146                                                 'symbols_path',
   147                                                 stackwalk_binary=self.stackwalk,
   148                                                 quiet=True))
   149         del os.environ['MINIDUMP_SAVE_PATH']
   150         self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
   151         self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
   153     def test_symbol_path_url(self):
   154         """
   155         Test that passing a URL as symbols_path correctly fetches the URL.
   156         """
   157         open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
   158         self.stdouts.append(["this is some output"])
   160         def make_zipfile():
   161             data = StringIO.StringIO()
   162             z = zipfile.ZipFile(data, 'w')
   163             z.writestr("symbols.txt", "abc/xyz")
   164             z.close()
   165             return data.getvalue()
   166         def get_symbols(req):
   167             headers = {}
   168             return (200, headers, make_zipfile())
   169         httpd = mozhttpd.MozHttpd(port=0,
   170                                   urlhandlers=[{'method':'GET', 'path':'/symbols', 'function':get_symbols}])
   171         httpd.start()
   172         symbol_url = urlparse.urlunsplit(('http', '%s:%d' % httpd.httpd.server_address,
   173                                         '/symbols','',''))
   174         self.assert_(mozcrash.check_for_crashes(self.tempdir,
   175                                                 symbol_url,
   176                                                 stackwalk_binary=self.stackwalk,
   177                                                 quiet=True))
   179 class TestJavaException(unittest.TestCase):
   180        def setUp(self):
   181                self.test_log = ["01-30 20:15:41.937 E/GeckoAppShell( 1703): >>> REPORTING UNCAUGHT EXCEPTION FROM THREAD 9 (\"GeckoBackgroundThread\")",
   182                        "01-30 20:15:41.937 E/GeckoAppShell( 1703): java.lang.NullPointerException",
   183                        "01-30 20:15:41.937 E/GeckoAppShell( 1703):    at org.mozilla.gecko.GeckoApp$21.run(GeckoApp.java:1833)",
   184                        "01-30 20:15:41.937 E/GeckoAppShell( 1703):    at android.os.Handler.handleCallback(Handler.java:587)"]
   186        def test_uncaught_exception(self):
   187                """
   188                Test for an exception which should be caught
   189                """
   190                self.assert_(mozcrash.check_for_java_exception(self.test_log, quiet=True))
   192        def test_fatal_exception(self):
   193                """
   194                Test for an exception which should be caught
   195                """
   196                fatal_log = list(self.test_log)
   197                fatal_log[0] = "01-30 20:15:41.937 E/GeckoAppShell( 1703): >>> FATAL EXCEPTION FROM THREAD 9 (\"GeckoBackgroundThread\")"
   198                self.assert_(mozcrash.check_for_java_exception(fatal_log, quiet=True))
   200        def test_truncated_exception(self):
   201                """
   202                Test for an exception which should be caught which
   203                was truncated
   204                """
   205                truncated_log = list(self.test_log)
   206                truncated_log[0], truncated_log[1] = truncated_log[1], truncated_log[0]
   207                self.assert_(mozcrash.check_for_java_exception(truncated_log, quiet=True))
   209        def test_unchecked_exception(self):
   210                """
   211                Test for an exception which should not be caught
   212                """
   213                passable_log = list(self.test_log)
   214                passable_log[0] = "01-30 20:15:41.937 E/GeckoAppShell( 1703): >>> NOT-SO-BAD EXCEPTION FROM THREAD 9 (\"GeckoBackgroundThread\")"
   215                self.assert_(not mozcrash.check_for_java_exception(passable_log, quiet=True))
   217 if __name__ == '__main__':
   218     unittest.main()

mercurial