1# Copyright (C) 2013 Google Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions are 5# met: 6# 7# * Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above 10# copyright notice, this list of conditions and the following disclaimer 11# in the documentation and/or other materials provided with the 12# distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29import unittest 30 31import cgi 32 33from webkitpy.common.host import Host 34from webkitpy.common.host_mock import MockHost 35from webkitpy.common.system.executive_mock import MockExecutive 36from webkitpy.layout_tests.breakpad.dump_reader_multipart import DumpReaderMultipart 37 38 39class TestDumpReaderMultipart(unittest.TestCase): 40 _MULTIPART_DUMP = [ 41 '--boundary', 42 'Content-Disposition: form-data; name="prod"', 43 '', 44 'content_shell', 45 '--boundary', 46 'Content-Disposition: form-data; name="pid"', 47 '', 48 '4711', 49 '--boundary', 50 'Content-Disposition: form-data; name="upload_file_minidump"; filename="dump"', 51 'Content-Type: application/octet-stream', 52 '', 53 'MDMP', 54 '--boundary--', 55 ] 56 57 def test_check_generate_breakpad_symbols_actually_exists(self): 58 host = Host() 59 dump_reader = DumpReaderMultipart(host, build_dir=None) 60 self.assertTrue(host.filesystem.exists(dump_reader._path_to_generate_breakpad_symbols())) 61 62 def test_check_is_functional_breakpad_tools_not_found(self): 63 host = MockHost() 64 65 build_dir = "/mock-checkout/out/Debug" 66 host.filesystem.maybe_make_directory(build_dir) 67 dump_reader = DumpReaderMultipart(host, build_dir) 68 dump_reader._file_extension = lambda: 'dmp' 69 dump_reader._binaries_to_symbolize = lambda: ['content_shell'] 70 71 self.assertFalse(dump_reader.check_is_functional()) 72 73 def test_get_pid_from_dump(self): 74 host = MockHost() 75 76 dump_file = '/crash-dumps/dump.dmp' 77 expected_pid = '4711' 78 host.filesystem.write_text_file(dump_file, "\r\n".join(TestDumpReaderMultipart._MULTIPART_DUMP)) 79 build_dir = "/mock-checkout/out/Debug" 80 host.filesystem.maybe_make_directory(build_dir) 81 host.filesystem.exists = lambda x: True 82 83 # The mock file object returned by open_binary_file_for_reading doesn't 84 # have readline(), however, the real File object does. 85 host.filesystem.open_binary_file_for_reading = host.filesystem.open_text_file_for_reading 86 dump_reader = DumpReaderMultipart(host, build_dir) 87 dump_reader._file_extension = lambda: 'dmp' 88 dump_reader._binaries_to_symbolize = lambda: ['content_shell'] 89 90 self.assertTrue(dump_reader.check_is_functional()) 91 self.assertEqual(expected_pid, dump_reader._get_pid_from_dump(dump_file)) 92 93 def test_get_stack_from_dump(self): 94 host = MockHost() 95 96 dump_file = '/crash-dumps/dump.dmp' 97 host.filesystem.write_text_file(dump_file, "\r\n".join(TestDumpReaderMultipart._MULTIPART_DUMP)) 98 build_dir = "/mock-checkout/out/Debug" 99 host.filesystem.maybe_make_directory(build_dir) 100 host.filesystem.exists = lambda x: True 101 102 # The mock file object returned by open_binary_file_for_reading doesn't 103 # have readline(), however, the real File object does. 104 host.filesystem.open_binary_file_for_reading = host.filesystem.open_text_file_for_reading 105 dump_reader = DumpReaderMultipart(host, build_dir) 106 dump_reader._file_extension = lambda: 'dmp' 107 dump_reader._binaries_to_symbolize = lambda: ['content_shell'] 108 109 self.assertTrue(dump_reader.check_is_functional()) 110 self.assertEqual("MOCK output of child process", dump_reader._get_stack_from_dump(dump_file)) 111 self.assertEqual(2, len(host.executive.calls)) 112 cmd_line = " ".join(host.executive.calls[0]) 113 self.assertIn('generate_breakpad_symbols.py', cmd_line) 114 cmd_line = " ".join(host.executive.calls[1]) 115 self.assertIn('minidump_stackwalk', cmd_line) 116