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