Unreviewed, fix build failure
[WebKit-https.git] / Tools / lldb / lldb_webkit_unittest.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright (C) 2018 Apple Inc. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1.  Redistributions of source code must retain the above copyright
10 #     notice, this list of conditions and the following disclaimer.
11 # 2.  Redistributions in binary form must reproduce the above copyright
12 #     notice, this list of conditions and the following disclaimer in the
13 #     documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
16 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 import atexit
27 import lldb
28 import lldb_webkit
29 import os
30 import sys
31 import unittest
32
33 from webkitpy.common.system.systemhost import SystemHost
34
35 # Run just the tests in this file with ./Tools/Scripts/test-webkitpy lldb_webkit_unittest
36
37 # We cache the lldb debug session state so that we don't create it again for each call to a serial_test_ method.
38 # We store it in a global variable so that we can delete this cached state on exit(3).
39 # FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule()
40 # are called exactly once per class/module).
41 cached_debug_session = None
42
43
44 # FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule()
45 # are called exactly once per class/module).
46 @atexit.register
47 def destroy_cached_debug_session():
48     if cached_debug_session:
49         cached_debug_session.tearDown()
50
51
52 class LLDBDebugSession(object):
53     @classmethod
54     def setup(cls):
55         BREAK_FOR_TESTING_FUNCTION_NAME = 'breakForTestingSummaryProviders'
56
57         cls.sbDebugger = lldb.SBDebugger.Create()
58         cls.sbDebugger.SetAsync(False)
59
60         cls.lldbWebKitTesterExecutable = str(os.environ['LLDB_WEBKIT_TESTER_EXECUTABLE'])
61
62         cls.sbTarget = cls.sbDebugger.CreateTarget(cls.lldbWebKitTesterExecutable)
63         assert cls.sbTarget
64         cls.sbTarget.BreakpointCreateByName(BREAK_FOR_TESTING_FUNCTION_NAME, cls.sbTarget.GetExecutable().GetFilename())
65
66         argv = None
67         envp = None
68         cls.sbProcess = cls.sbTarget.LaunchSimple(argv, envp, os.getcwd())
69         assert cls.sbProcess
70         assert cls.sbProcess.GetState() == lldb.eStateStopped
71
72         cls.sbThread = cls.sbProcess.GetThreadAtIndex(0)
73         assert cls.sbThread
74
75         # Frame 0 is the function with name BREAK_FOR_TESTING_FUNCTION_NAME. We want the frame of the caller of
76         # BREAK_FOR_TESTING_FUNCTION_NAME because it has all the interesting local variables we want to test.
77         cls.sbFrame = cls.sbThread.GetFrameAtIndex(1)
78         assert cls.sbFrame
79
80     @classmethod
81     def tearDown(cls):
82         cls.sbProcess.Kill()
83
84
85 class TestSummaryProviders(unittest.TestCase):
86     @classmethod
87     def shouldSkip(cls):
88         return not SystemHost().platform.is_mac()
89
90     @classmethod
91     def setUpClass(cls):
92         global cached_debug_session
93         if not cached_debug_session:
94             cached_debug_session = LLDBDebugSession()
95             cached_debug_session.setup()
96
97     @property
98     def _sbFrame(self):
99         return cached_debug_session.sbFrame
100
101     # The LLDB Python module does not work with Python multiprocessing and causes errors of the form:
102     #     objc[76794]: +[__MDQuery initialize] may have been in progress in another thread when fork() was called.
103     #                  We cannot safely call it or ignore it in the fork() child process. Crashing instead.
104     # So, we run the following tests serially.
105
106     # MARK: WTFStringImpl_SummaryProvider test cases
107
108     def serial_test_WTFStringImpl_SummaryProvider_null_string(self):
109         summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('aNullStringImpl'), {})
110         self.assertEqual(summary, "{ length = 0, is8bit = 1, contents = '' }")
111
112     def serial_test_WTFStringImpl_SummaryProvider_empty_string(self):
113         summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('anEmptyStringImpl'), {})
114         self.assertEqual(summary, "{ length = 0, is8bit = 1, contents = '' }")
115
116     def serial_test_WTFStringImpl_SummaryProvider_8bit_string(self):
117         summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('an8BitStringImpl'), {})
118         self.assertEqual(summary, "{ length = 8, is8bit = 1, contents = 'r\\xe9sum\\xe9' }")
119
120     def serial_test_WTFStringImpl_SummaryProvider_16bit_string(self):
121         summary = lldb_webkit.WTFStringImpl_SummaryProvider(self._sbFrame.FindVariable('a16BitStringImpl'), {})
122         self.assertEqual(summary, u"{ length = 13, is8bit = 0, contents = '\\u1680Cappuccino\\u1680\\x00' }")
123
124     # MARK: WTFString_SummaryProvider test cases
125
126     def serial_test_WTFString_SummaryProvider_null_string(self):
127         summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('aNullString'), {})
128         self.assertEqual(summary, "{ length = 0, contents = '' }")
129
130     def serial_test_WTFString_SummaryProvider_empty_string(self):
131         summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('anEmptyString'), {})
132         self.assertEqual(summary, "{ length = 0, contents = '' }")
133
134     def serial_test_WTFString_SummaryProvider_8bit_string(self):
135         summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('an8BitString'), {})
136         self.assertEqual(summary, "{ length = 8, contents = 'r\\xe9sum\\xe9' }")
137
138     def serial_test_WTFString_SummaryProvider_16bit_string(self):
139         summary = lldb_webkit.WTFString_SummaryProvider(self._sbFrame.FindVariable('a16BitString'), {})
140         self.assertEqual(summary, u"{ length = 13, contents = '\\u1680Cappuccino\\u1680\\x00' }")
141
142     # MARK: WTFVector_SummaryProvider test cases
143
144     def serial_test_WTFVectorProvider_empty_vector(self):
145         variable = self._sbFrame.FindVariable('anEmptyVector');
146         summary = lldb_webkit.WTFVector_SummaryProvider(variable, {})
147         self.assertEqual(summary, "{ size = 0, capacity = 0 }")
148
149     def serial_test_WTFVectorProvider_vector_size_and_capacity(self):
150         variable = self._sbFrame.FindVariable('aVectorWithOneItem');
151         summary = lldb_webkit.WTFVector_SummaryProvider(variable, {})
152         self.assertEqual(summary, "{ size = 1, capacity = 16 }")
153
154     # MARK: WTFHashMap_SummaryProvider and WTFHashSet_SummaryProvider test cases
155
156     def serial_test_WTFHashMap_tablesize_and_size(self):
157         variable = self._sbFrame.FindVariable('hashMapOfInts')
158         summary = lldb_webkit.WTFHashMap_SummaryProvider(variable, {})
159         self.assertEqual(summary, "{ tableSize = 8, keyCount = 2 }")
160
161     def serial_test_WTFHashMap_of_vectors_tablesize_and_size(self):
162         variable = self._sbFrame.FindVariable('hashMapOfVectors')
163         summary = lldb_webkit.WTFHashMap_SummaryProvider(variable, {})
164         self.assertEqual(summary, "{ tableSize = 8, keyCount = 1 }")
165
166     def serial_test_WTFHashSet_tablesize_and_size(self):
167         variable = self._sbFrame.FindVariable('hashSetOfInts')
168         summary = lldb_webkit.WTFHashSet_SummaryProvider(variable, {})
169         self.assertEqual(summary, "{ tableSize = 8, keyCount = 1 }")
170
171     # MARK: WTFOptionSet_SummaryProvider test cases
172
173     def serial_test_WTFOptionSet_SummaryProvider_empty(self):
174         variable = self._sbFrame.FindVariable('exampleFlagsEmpty')
175         summary = lldb_webkit.WTFOptionSet_SummaryProvider(variable, {})
176         self.assertEqual(summary, "{ size = 0 }")
177
178     def serial_test_WTFOptionSet_SummaryProvider_simple(self):
179         variable = self._sbFrame.FindVariable('exampleFlagsSimple')
180         summary = lldb_webkit.WTFOptionSet_SummaryProvider(variable, {})
181         self.assertEqual(summary, "{ size = 3 }")
182
183     # MARK: WTFOptionSetProvider test cases
184
185     def serial_test_WTFOptionSetProvider_empty(self):
186         variable = self._sbFrame.FindVariable('exampleFlagsEmpty')
187         provider = lldb_webkit.WTFOptionSetProvider(variable, {})
188         self.assertEqual(provider.get_child_at_index(0), None)
189
190     def serial_test_WTFOptionSetProvider_simple(self):
191         variable = self._sbFrame.FindVariable('exampleFlagsSimple')
192         provider = lldb_webkit.WTFOptionSetProvider(variable, {})
193         self.assertEqual(provider.get_child_at_index(0).GetName(), 'A')
194         self.assertEqual(provider.get_child_at_index(0).GetValue(), '1')
195         self.assertEqual(provider.get_child_at_index(1).GetName(), 'C')
196         self.assertEqual(provider.get_child_at_index(1).GetValue(), '4')
197         self.assertEqual(provider.get_child_at_index(2).GetName(), 'D')
198         self.assertEqual(provider.get_child_at_index(2).GetValue(), '8')
199
200     def serial_test_WTFOptionSetProvider_aliased_flag(self):
201         variable = self._sbFrame.FindVariable('exampleFlagsAliasedFlag')
202         provider = lldb_webkit.WTFOptionSetProvider(variable, {})
203         self.assertEqual(provider.get_child_at_index(0).GetName(), 'A')
204         self.assertEqual(provider.get_child_at_index(0).GetValue(), '1')
205         self.assertEqual(provider.get_child_at_index(1).GetName(), 'D')
206         self.assertEqual(provider.get_child_at_index(1).GetValue(), '8')