Provide an lldb type summary for WebCore::Color
[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 from webkitpy.port.config import Config
35
36 # Run just the tests in this file with ./Tools/Scripts/test-webkitpy lldb_webkit_unittest
37
38 # We cache the lldb debug session state so that we don't create it again for each call to a serial_test_ method.
39 # We store it in a global variable so that we can delete this cached state on exit(3).
40 # FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule()
41 # are called exactly once per class/module).
42 cached_debug_session = None
43
44
45 # FIXME: Remove this once test-webkitpy supports class and module fixtures (i.e. setUpClass()/setUpModule()
46 # are called exactly once per class/module).
47 @atexit.register
48 def destroy_cached_debug_session():
49     if cached_debug_session:
50         cached_debug_session.tearDown()
51
52
53 class LLDBDebugSession(object):
54     @classmethod
55     def setup(cls):
56         LLDB_WEBKIT_TESTER_NAME = 'lldbWebKitTester'
57         BREAK_FOR_TESTING_FUNCTION_NAME = 'breakForTestingSummaryProviders'
58
59         cls.sbDebugger = lldb.SBDebugger.Create()
60         cls.sbDebugger.SetAsync(False)
61
62         host = SystemHost()
63         config = Config(host.executive, host.filesystem)
64         cls.lldbWebKitTesterExecutable = os.path.join(config.build_directory(config.default_configuration()), LLDB_WEBKIT_TESTER_NAME)
65
66         cls.sbTarget = cls.sbDebugger.CreateTarget(str(cls.lldbWebKitTesterExecutable))
67         assert cls.sbTarget
68         cls.sbTarget.BreakpointCreateByName(BREAK_FOR_TESTING_FUNCTION_NAME, cls.sbTarget.GetExecutable().GetFilename())
69
70         argv = None
71         envp = None
72         cls.sbProcess = cls.sbTarget.LaunchSimple(argv, envp, os.getcwd())
73         assert cls.sbProcess
74         assert cls.sbProcess.GetState() == lldb.eStateStopped
75
76         cls.sbThread = cls.sbProcess.GetThreadAtIndex(0)
77         assert cls.sbThread
78
79         # Frame 0 is the function with name BREAK_FOR_TESTING_FUNCTION_NAME. We want the frame of the caller of
80         # BREAK_FOR_TESTING_FUNCTION_NAME because it has all the interesting local variables we want to test.
81         cls.sbFrame = cls.sbThread.GetFrameAtIndex(1)
82         assert cls.sbFrame
83
84     @classmethod
85     def tearDown(cls):
86         cls.sbProcess.Kill()
87
88
89 class TestSummaryProviders(unittest.TestCase):
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         self.assertIsNotNone(variable)
147         summary = lldb_webkit.WTFVector_SummaryProvider(variable, {})
148         self.assertEqual(summary, "{ size = 0, capacity = 0 }")
149
150     def serial_test_WTFVectorProvider_vector_size_and_capacity(self):
151         variable = self._sbFrame.FindVariable('aVectorWithOneItem');
152         self.assertIsNotNone(variable)
153         summary = lldb_webkit.WTFVector_SummaryProvider(variable, {})
154         self.assertEqual(summary, "{ size = 1, capacity = 16 }")
155
156     # MARK: WebCoreColor_SummaryProvider test cases
157
158     def serial_test_WebCoreColorProvider_invalid_color(self):
159         variable = self._sbFrame.FindVariable('invalidColor');
160         summary = lldb_webkit.WebCoreColor_SummaryProvider(variable, {})
161         self.assertEqual(summary, "{ invalid }")
162
163     def serial_test_WebCoreColorProvider_extended_color(self):
164         variable = self._sbFrame.FindVariable('extendedColor');
165         summary = lldb_webkit.WebCoreColor_SummaryProvider(variable, {})
166         self.assertEqual(summary, "{ color(display-p3 0.10 0.20 0.30 / 0.40) }")
167
168     def serial_test_WebCoreColorProvider_rgb_color(self):
169         variable = self._sbFrame.FindVariable('rgbColor');
170         summary = lldb_webkit.WebCoreColor_SummaryProvider(variable, {})
171         self.assertEqual(summary, "{ rgba(255, 128, 64, 1.00) }")
172
173     def serial_test_WebCoreColorProvider_rgba_color(self):
174         variable = self._sbFrame.FindVariable('rgbaColor');
175         summary = lldb_webkit.WebCoreColor_SummaryProvider(variable, {})
176         self.assertEqual(summary, "{ rgba(255, 128, 64, 0.50) }")
177
178     def serial_test_WebCoreColorProvider_semantic_color(self):
179         variable = self._sbFrame.FindVariable('semanticColor');
180         summary = lldb_webkit.WebCoreColor_SummaryProvider(variable, {})
181         self.assertEqual(summary, "{ rgba(255, 255, 255, 1.00) semantic }")
182