xref: /aosp_15_r20/external/perfetto/python/test/stdlib_unittest.py (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker#
3*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker#
7*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker#
9*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerimport os
16*6dbdd20aSAndroid Build Coastguard Workerimport sys
17*6dbdd20aSAndroid Build Coastguard Workerimport unittest
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard WorkerROOT_DIR = os.path.dirname(
20*6dbdd20aSAndroid Build Coastguard Worker    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
21*6dbdd20aSAndroid Build Coastguard Workersys.path.append(os.path.join(ROOT_DIR))
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Workerfrom python.generators.sql_processing.docs_parse import Arg, parse_file
24*6dbdd20aSAndroid Build Coastguard Worker
25*6dbdd20aSAndroid Build Coastguard Worker
26*6dbdd20aSAndroid Build Coastguard Workerclass TestStdlib(unittest.TestCase):
27*6dbdd20aSAndroid Build Coastguard Worker
28*6dbdd20aSAndroid Build Coastguard Worker  # Checks that custom prefixes (cr for chrome/util) are allowed.
29*6dbdd20aSAndroid Build Coastguard Worker  def test_custom_module_prefix(self):
30*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
31*6dbdd20aSAndroid Build Coastguard Worker        'chrome/util/test.sql', f'''
32*6dbdd20aSAndroid Build Coastguard Worker-- Comment
33*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO TABLE cr_table(
34*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
35*6dbdd20aSAndroid Build Coastguard Worker    x LONG
36*6dbdd20aSAndroid Build Coastguard Worker) AS
37*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
38*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
39*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
40*6dbdd20aSAndroid Build Coastguard Worker
41*6dbdd20aSAndroid Build Coastguard Worker    fn = res.table_views[0]
42*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'cr_table')
43*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Comment')
44*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.cols, {
45*6dbdd20aSAndroid Build Coastguard Worker        'x': Arg('LONG', 'LONG', 'Column.', None),
46*6dbdd20aSAndroid Build Coastguard Worker    })
47*6dbdd20aSAndroid Build Coastguard Worker
48*6dbdd20aSAndroid Build Coastguard Worker  # Checks that when custom prefixes (cr for chrome/util) are present,
49*6dbdd20aSAndroid Build Coastguard Worker  # the full module name (chrome) is still accepted.
50*6dbdd20aSAndroid Build Coastguard Worker  def test_custom_module_prefix_full_module_name(self):
51*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
52*6dbdd20aSAndroid Build Coastguard Worker        'chrome/util/test.sql', f'''
53*6dbdd20aSAndroid Build Coastguard Worker-- Comment
54*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO TABLE chrome_table(
55*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
56*6dbdd20aSAndroid Build Coastguard Worker    x LONG
57*6dbdd20aSAndroid Build Coastguard Worker) AS
58*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
59*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
60*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Worker    fn = res.table_views[0]
63*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'chrome_table')
64*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Comment')
65*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.cols, {
66*6dbdd20aSAndroid Build Coastguard Worker        'x': Arg('LONG', 'LONG', 'Column.', None),
67*6dbdd20aSAndroid Build Coastguard Worker    })
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker  # Checks that when custom prefixes (cr for chrome/util) are present,
70*6dbdd20aSAndroid Build Coastguard Worker  # the incorrect prefixes (foo) are not accepted.
71*6dbdd20aSAndroid Build Coastguard Worker  def test_custom_module_prefix_incorrect(self):
72*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
73*6dbdd20aSAndroid Build Coastguard Worker        'chrome/util/test.sql', f'''
74*6dbdd20aSAndroid Build Coastguard Worker-- Comment
75*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO TABLE foo_table(
76*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
77*6dbdd20aSAndroid Build Coastguard Worker    x LONG
78*6dbdd20aSAndroid Build Coastguard Worker) AS
79*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
80*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
81*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: table prefix (foo) is not allowed for a given path
82*6dbdd20aSAndroid Build Coastguard Worker    # (allowed: chrome, cr).
83*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
84*6dbdd20aSAndroid Build Coastguard Worker
85*6dbdd20aSAndroid Build Coastguard Worker  # Checks that when custom prefixes (cr for chrome/util) are present,
86*6dbdd20aSAndroid Build Coastguard Worker  # they do not apply outside of the path scope.
87*6dbdd20aSAndroid Build Coastguard Worker  def test_custom_module_prefix_does_not_apply_outside(self):
88*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
89*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
90*6dbdd20aSAndroid Build Coastguard Worker-- Comment
91*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO TABLE cr_table(
92*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
93*6dbdd20aSAndroid Build Coastguard Worker    x LONG
94*6dbdd20aSAndroid Build Coastguard Worker) AS
95*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
96*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
97*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: table prefix (foo) is not allowed for a given path
98*6dbdd20aSAndroid Build Coastguard Worker    # (allowed: foo).
99*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
100*6dbdd20aSAndroid Build Coastguard Worker
101*6dbdd20aSAndroid Build Coastguard Worker  def test_ret_no_desc(self):
102*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
103*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
104*6dbdd20aSAndroid Build Coastguard Worker-- Comment
105*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn()
106*6dbdd20aSAndroid Build Coastguard Worker--
107*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
108*6dbdd20aSAndroid Build Coastguard WorkerAS
109*6dbdd20aSAndroid Build Coastguard WorkerSELECT TRUE;
110*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
111*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: return value is missing a description.
112*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Worker  def test_multiline_desc(self):
115*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
116*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
117*6dbdd20aSAndroid Build Coastguard Worker-- This
118*6dbdd20aSAndroid Build Coastguard Worker-- is
119*6dbdd20aSAndroid Build Coastguard Worker--
120*6dbdd20aSAndroid Build Coastguard Worker-- a
121*6dbdd20aSAndroid Build Coastguard Worker--      very
122*6dbdd20aSAndroid Build Coastguard Worker--
123*6dbdd20aSAndroid Build Coastguard Worker-- long
124*6dbdd20aSAndroid Build Coastguard Worker--
125*6dbdd20aSAndroid Build Coastguard Worker-- description.
126*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn()
127*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
128*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
129*6dbdd20aSAndroid Build Coastguard WorkerAS
130*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
131*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
132*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
133*6dbdd20aSAndroid Build Coastguard Worker
134*6dbdd20aSAndroid Build Coastguard Worker    fn = res.functions[0]
135*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc,
136*6dbdd20aSAndroid Build Coastguard Worker                     'This\n is\n\n a\n      very\n\n long\n\n description.')
137*6dbdd20aSAndroid Build Coastguard Worker
138*6dbdd20aSAndroid Build Coastguard Worker
139*6dbdd20aSAndroid Build Coastguard Worker  def test_function_name_style(self):
140*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
141*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
142*6dbdd20aSAndroid Build Coastguard Worker-- Function comment.
143*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_SnakeCase()
144*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
145*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
146*6dbdd20aSAndroid Build Coastguard WorkerAS
147*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
148*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
149*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: function name should be using hacker_style.
150*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
151*6dbdd20aSAndroid Build Coastguard Worker
152*6dbdd20aSAndroid Build Coastguard Worker  def test_table_with_schema(self):
153*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
154*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
155*6dbdd20aSAndroid Build Coastguard Worker-- Table comment.
156*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO TABLE foo_table(
157*6dbdd20aSAndroid Build Coastguard Worker    -- Id of slice.
158*6dbdd20aSAndroid Build Coastguard Worker    id LONG
159*6dbdd20aSAndroid Build Coastguard Worker) AS
160*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1 as id;
161*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
162*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
163*6dbdd20aSAndroid Build Coastguard Worker
164*6dbdd20aSAndroid Build Coastguard Worker    table = res.table_views[0]
165*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.name, 'foo_table')
166*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.desc, 'Table comment.')
167*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.type, 'TABLE')
168*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.cols, {
169*6dbdd20aSAndroid Build Coastguard Worker        'id': Arg('LONG', 'LONG', 'Id of slice.', None),
170*6dbdd20aSAndroid Build Coastguard Worker    })
171*6dbdd20aSAndroid Build Coastguard Worker
172*6dbdd20aSAndroid Build Coastguard Worker  def test_perfetto_view_with_schema(self):
173*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
174*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
175*6dbdd20aSAndroid Build Coastguard Worker-- View comment.
176*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO VIEW foo_table(
177*6dbdd20aSAndroid Build Coastguard Worker    -- Foo.
178*6dbdd20aSAndroid Build Coastguard Worker    foo LONG,
179*6dbdd20aSAndroid Build Coastguard Worker    -- Bar.
180*6dbdd20aSAndroid Build Coastguard Worker    bar STRING
181*6dbdd20aSAndroid Build Coastguard Worker) AS
182*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
183*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
184*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
185*6dbdd20aSAndroid Build Coastguard Worker
186*6dbdd20aSAndroid Build Coastguard Worker    table = res.table_views[0]
187*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.name, 'foo_table')
188*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.desc, 'View comment.')
189*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(table.type, 'VIEW')
190*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(
191*6dbdd20aSAndroid Build Coastguard Worker        table.cols, {
192*6dbdd20aSAndroid Build Coastguard Worker            'foo': Arg('LONG', 'LONG', 'Foo.', None),
193*6dbdd20aSAndroid Build Coastguard Worker            'bar': Arg('STRING', 'STRING', 'Bar.', None),
194*6dbdd20aSAndroid Build Coastguard Worker        })
195*6dbdd20aSAndroid Build Coastguard Worker
196*6dbdd20aSAndroid Build Coastguard Worker  def test_function_with_new_style_docs(self):
197*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
198*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
199*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
200*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn(
201*6dbdd20aSAndroid Build Coastguard Worker    -- Utid of thread.
202*6dbdd20aSAndroid Build Coastguard Worker    utid LONG,
203*6dbdd20aSAndroid Build Coastguard Worker    -- String name.
204*6dbdd20aSAndroid Build Coastguard Worker    name STRING)
205*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
206*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
207*6dbdd20aSAndroid Build Coastguard WorkerAS
208*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
209*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
210*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
211*6dbdd20aSAndroid Build Coastguard Worker
212*6dbdd20aSAndroid Build Coastguard Worker    fn = res.functions[0]
213*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'foo_fn')
214*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Function foo.')
215*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(
216*6dbdd20aSAndroid Build Coastguard Worker        fn.args, {
217*6dbdd20aSAndroid Build Coastguard Worker            'utid': Arg('LONG', 'LONG', 'Utid of thread.', None),
218*6dbdd20aSAndroid Build Coastguard Worker            'name': Arg('STRING', 'STRING', 'String name.', None),
219*6dbdd20aSAndroid Build Coastguard Worker        })
220*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_type, 'BOOL')
221*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_desc, 'Exists.')
222*6dbdd20aSAndroid Build Coastguard Worker
223*6dbdd20aSAndroid Build Coastguard Worker  def test_function_returns_table_with_new_style_docs(self):
224*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
225*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
226*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
227*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn(
228*6dbdd20aSAndroid Build Coastguard Worker    -- Utid of thread.
229*6dbdd20aSAndroid Build Coastguard Worker    utid LONG)
230*6dbdd20aSAndroid Build Coastguard Worker-- Impl comment.
231*6dbdd20aSAndroid Build Coastguard WorkerRETURNS TABLE(
232*6dbdd20aSAndroid Build Coastguard Worker    -- Count.
233*6dbdd20aSAndroid Build Coastguard Worker    count LONG
234*6dbdd20aSAndroid Build Coastguard Worker)
235*6dbdd20aSAndroid Build Coastguard WorkerAS
236*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
237*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
238*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
239*6dbdd20aSAndroid Build Coastguard Worker
240*6dbdd20aSAndroid Build Coastguard Worker    fn = res.table_functions[0]
241*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'foo_fn')
242*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Function foo.')
243*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.args, {
244*6dbdd20aSAndroid Build Coastguard Worker        'utid': Arg('LONG', 'LONG', 'Utid of thread.', None),
245*6dbdd20aSAndroid Build Coastguard Worker    })
246*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.cols, {
247*6dbdd20aSAndroid Build Coastguard Worker        'count': Arg('LONG', 'LONG', 'Count.', None),
248*6dbdd20aSAndroid Build Coastguard Worker    })
249*6dbdd20aSAndroid Build Coastguard Worker
250*6dbdd20aSAndroid Build Coastguard Worker  def test_function_with_new_style_docs_multiline_comment(self):
251*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
252*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
253*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
254*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn(
255*6dbdd20aSAndroid Build Coastguard Worker    -- Multi
256*6dbdd20aSAndroid Build Coastguard Worker    -- line
257*6dbdd20aSAndroid Build Coastguard Worker    --
258*6dbdd20aSAndroid Build Coastguard Worker    -- comment.
259*6dbdd20aSAndroid Build Coastguard Worker    arg LONG)
260*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
261*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
262*6dbdd20aSAndroid Build Coastguard WorkerAS
263*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
264*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
265*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
266*6dbdd20aSAndroid Build Coastguard Worker
267*6dbdd20aSAndroid Build Coastguard Worker    fn = res.functions[0]
268*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'foo_fn')
269*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Function foo.')
270*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.args, {
271*6dbdd20aSAndroid Build Coastguard Worker        'arg': Arg('LONG', 'LONG', 'Multi line  comment.', None),
272*6dbdd20aSAndroid Build Coastguard Worker    })
273*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_type, 'BOOL')
274*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_desc, 'Exists.')
275*6dbdd20aSAndroid Build Coastguard Worker
276*6dbdd20aSAndroid Build Coastguard Worker  def test_function_with_multiline_return_comment(self):
277*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
278*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
279*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
280*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn(
281*6dbdd20aSAndroid Build Coastguard Worker    -- Arg
282*6dbdd20aSAndroid Build Coastguard Worker    arg LONG)
283*6dbdd20aSAndroid Build Coastguard Worker-- Multi
284*6dbdd20aSAndroid Build Coastguard Worker-- line
285*6dbdd20aSAndroid Build Coastguard Worker-- return
286*6dbdd20aSAndroid Build Coastguard Worker-- comment.
287*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
288*6dbdd20aSAndroid Build Coastguard WorkerAS
289*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
290*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
291*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
292*6dbdd20aSAndroid Build Coastguard Worker
293*6dbdd20aSAndroid Build Coastguard Worker    fn = res.functions[0]
294*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'foo_fn')
295*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Function foo.')
296*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.args, {
297*6dbdd20aSAndroid Build Coastguard Worker        'arg': Arg('LONG', 'LONG', 'Arg', None),
298*6dbdd20aSAndroid Build Coastguard Worker    })
299*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_type, 'BOOL')
300*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_desc, 'Multi line return comment.')
301*6dbdd20aSAndroid Build Coastguard Worker
302*6dbdd20aSAndroid Build Coastguard Worker  def test_create_or_replace_table_banned(self):
303*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
304*6dbdd20aSAndroid Build Coastguard Worker        'common/bar.sql', f'''
305*6dbdd20aSAndroid Build Coastguard Worker-- Table.
306*6dbdd20aSAndroid Build Coastguard WorkerCREATE OR REPLACE PERFETTO TABLE foo(
307*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
308*6dbdd20aSAndroid Build Coastguard Worker    x LONG
309*6dbdd20aSAndroid Build Coastguard Worker)
310*6dbdd20aSAndroid Build Coastguard WorkerAS
311*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
312*6dbdd20aSAndroid Build Coastguard Worker
313*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
314*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
315*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
316*6dbdd20aSAndroid Build Coastguard Worker
317*6dbdd20aSAndroid Build Coastguard Worker  def test_create_or_replace_view_banned(self):
318*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
319*6dbdd20aSAndroid Build Coastguard Worker        'common/bar.sql', f'''
320*6dbdd20aSAndroid Build Coastguard Worker-- Table.
321*6dbdd20aSAndroid Build Coastguard WorkerCREATE OR REPLACE PERFETTO VIEW foo(
322*6dbdd20aSAndroid Build Coastguard Worker    -- Column.
323*6dbdd20aSAndroid Build Coastguard Worker    x LONG
324*6dbdd20aSAndroid Build Coastguard Worker)
325*6dbdd20aSAndroid Build Coastguard WorkerAS
326*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
327*6dbdd20aSAndroid Build Coastguard Worker
328*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
329*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
330*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
331*6dbdd20aSAndroid Build Coastguard Worker
332*6dbdd20aSAndroid Build Coastguard Worker  def test_create_or_replace_function_banned(self):
333*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
334*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
335*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
336*6dbdd20aSAndroid Build Coastguard WorkerCREATE OR REPLACE PERFETTO FUNCTION foo_fn()
337*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
338*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
339*6dbdd20aSAndroid Build Coastguard WorkerAS
340*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
341*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
342*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
343*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
344*6dbdd20aSAndroid Build Coastguard Worker
345*6dbdd20aSAndroid Build Coastguard Worker  def test_function_with_new_style_docs_with_parenthesis(self):
346*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
347*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
348*6dbdd20aSAndroid Build Coastguard Worker-- Function foo.
349*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO FUNCTION foo_fn(
350*6dbdd20aSAndroid Build Coastguard Worker    -- Utid of thread (important).
351*6dbdd20aSAndroid Build Coastguard Worker    utid LONG)
352*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
353*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
354*6dbdd20aSAndroid Build Coastguard WorkerAS
355*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
356*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
357*6dbdd20aSAndroid Build Coastguard Worker    self.assertListEqual(res.errors, [])
358*6dbdd20aSAndroid Build Coastguard Worker
359*6dbdd20aSAndroid Build Coastguard Worker    fn = res.functions[0]
360*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.name, 'foo_fn')
361*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.desc, 'Function foo.')
362*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.args, {
363*6dbdd20aSAndroid Build Coastguard Worker        'utid': Arg('LONG', 'LONG', 'Utid of thread (important).', None),
364*6dbdd20aSAndroid Build Coastguard Worker    })
365*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_type, 'BOOL')
366*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(fn.return_desc, 'Exists.')
367*6dbdd20aSAndroid Build Coastguard Worker
368*6dbdd20aSAndroid Build Coastguard Worker  def test_macro(self):
369*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
370*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
371*6dbdd20aSAndroid Build Coastguard Worker-- Macro
372*6dbdd20aSAndroid Build Coastguard WorkerCREATE OR REPLACE PERFETTO FUNCTION foo_fn()
373*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
374*6dbdd20aSAndroid Build Coastguard WorkerRETURNS BOOL
375*6dbdd20aSAndroid Build Coastguard WorkerAS
376*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
377*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
378*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
379*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
380*6dbdd20aSAndroid Build Coastguard Worker
381*6dbdd20aSAndroid Build Coastguard Worker  def test_create_or_replace_macro_smoke(self):
382*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
383*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
384*6dbdd20aSAndroid Build Coastguard Worker-- Macro
385*6dbdd20aSAndroid Build Coastguard WorkerCREATE PERFETTO MACRO foo_macro(
386*6dbdd20aSAndroid Build Coastguard Worker  -- x Arg.
387*6dbdd20aSAndroid Build Coastguard Worker  x TableOrSubquery
388*6dbdd20aSAndroid Build Coastguard Worker)
389*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
390*6dbdd20aSAndroid Build Coastguard WorkerRETURNS TableOrSubquery
391*6dbdd20aSAndroid Build Coastguard WorkerAS
392*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
393*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
394*6dbdd20aSAndroid Build Coastguard Worker
395*6dbdd20aSAndroid Build Coastguard Worker    macro = res.macros[0]
396*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(macro.name, 'foo_macro')
397*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(macro.desc, 'Macro')
398*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(macro.args, {
399*6dbdd20aSAndroid Build Coastguard Worker        'x': Arg('TableOrSubquery', 'TableOrSubquery', 'x Arg.', None),
400*6dbdd20aSAndroid Build Coastguard Worker    })
401*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(macro.return_type, 'TableOrSubquery')
402*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(macro.return_desc, 'Exists.')
403*6dbdd20aSAndroid Build Coastguard Worker
404*6dbdd20aSAndroid Build Coastguard Worker  def test_create_or_replace_macro_banned(self):
405*6dbdd20aSAndroid Build Coastguard Worker    res = parse_file(
406*6dbdd20aSAndroid Build Coastguard Worker        'foo/bar.sql', f'''
407*6dbdd20aSAndroid Build Coastguard Worker-- Macro
408*6dbdd20aSAndroid Build Coastguard WorkerCREATE OR REPLACE PERFETTO MACRO foo_macro(
409*6dbdd20aSAndroid Build Coastguard Worker  -- x Arg.
410*6dbdd20aSAndroid Build Coastguard Worker  x TableOrSubquery
411*6dbdd20aSAndroid Build Coastguard Worker)
412*6dbdd20aSAndroid Build Coastguard Worker-- Exists.
413*6dbdd20aSAndroid Build Coastguard WorkerRETURNS TableOrSubquery
414*6dbdd20aSAndroid Build Coastguard WorkerAS
415*6dbdd20aSAndroid Build Coastguard WorkerSELECT 1;
416*6dbdd20aSAndroid Build Coastguard Worker    '''.strip())
417*6dbdd20aSAndroid Build Coastguard Worker    # Expecting an error: CREATE OR REPLACE is not allowed in stdlib.
418*6dbdd20aSAndroid Build Coastguard Worker    self.assertEqual(len(res.errors), 1)
419