1#!/usr/bin/env python3 2# Copyright (C) 2023 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License a 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from python.generators.diff_tests.testing import Path, DataPath, Metric 17from python.generators.diff_tests.testing import Csv, Json, TextProto, BinaryProto 18from python.generators.diff_tests.testing import DiffTestBlueprint 19from python.generators.diff_tests.testing import TestSuite 20from python.generators.diff_tests.testing import PrintProfileProto 21from google.protobuf import text_format 22 23 24class PerfettoFunction(TestSuite): 25 26 def test_create_function(self): 27 return DiffTestBlueprint( 28 trace=TextProto(""), 29 query=""" 30 CREATE PERFETTO FUNCTION f(x INT) RETURNS INT AS SELECT $x + 1; 31 32 SELECT f(5) as result; 33 """, 34 out=Csv(""" 35 "result" 36 6 37 """)) 38 39 def test_replace_function(self): 40 return DiffTestBlueprint( 41 trace=TextProto(""), 42 query=""" 43 CREATE PERFETTO FUNCTION f(x INT) RETURNS INT AS SELECT $x + 1; 44 CREATE OR REPLACE PERFETTO FUNCTION f(x INT) RETURNS INT AS SELECT $x + 2; 45 46 SELECT f(5) as result; 47 """, 48 out=Csv(""" 49 "result" 50 7 51 """)) 52 53 def test_legacy_create_function(self): 54 return DiffTestBlueprint( 55 trace=TextProto(""), 56 query=""" 57 SELECT create_function('f(x INT)', 'INT', 'SELECT $x + 1'); 58 59 SELECT f(5) as result; 60 """, 61 out=Csv(""" 62 "result" 63 6 64 """)) 65 66 def test_legacy_create_function_returns_string(self): 67 return DiffTestBlueprint( 68 trace=TextProto(""), 69 query=""" 70 SELECT create_function('f(x INT)', 'STRING', 'SELECT "value_" || $x'); 71 72 SELECT f(5) as result; 73 """, 74 out=Csv(""" 75 "result" 76 "value_5" 77 """)) 78 79 def test_legacy_create_function_duplicated(self): 80 return DiffTestBlueprint( 81 trace=TextProto(""), 82 query=""" 83 SELECT create_function('f()', 'INT', 'SELECT 1'); 84 SELECT create_function('f()', 'INT', 'SELECT 1'); 85 86 SELECT f() as result; 87 """, 88 out=Csv(""" 89 "result" 90 1 91 """)) 92 93 def test_legacy_create_function_recursive(self): 94 return DiffTestBlueprint( 95 trace=TextProto(""), 96 query=""" 97 -- Compute factorial. 98 SELECT create_function('f(x INT)', 'INT', 99 ' 100 SELECT IIF($x = 0, 1, $x * f($x - 1)) 101 '); 102 103 SELECT f(5) as result; 104 """, 105 out=Csv(""" 106 "result" 107 120 108 """)) 109 110 def test_legacy_create_function_recursive_string(self): 111 return DiffTestBlueprint( 112 trace=TextProto(""), 113 query=""" 114 -- Compute factorial. 115 SELECT create_function('f(x INT)', 'STRING', 116 ' 117 SELECT IIF( 118 $x = 0, 119 "", 120 -- 97 is the ASCII code for "a". 121 f($x - 1) || char(96 + $x) || f($x - 1)) 122 '); 123 124 SELECT f(4) as result; 125 """, 126 out=Csv(""" 127 "result" 128 "abacabadabacaba" 129 """)) 130 131 def test_legacy_create_function_recursive_string_memoized(self): 132 return DiffTestBlueprint( 133 trace=TextProto(""), 134 query=""" 135 -- Compute factorial. 136 SELECT create_function('f(x INT)', 'STRING', 137 ' 138 SELECT IIF( 139 $x = 0, 140 "", 141 -- 97 is the ASCII code for "a". 142 f($x - 1) || char(96 + $x) || f($x - 1)) 143 '); 144 145 SELECT experimental_memoize('f'); 146 147 SELECT f(4) as result; 148 """, 149 out=Csv(""" 150 "result" 151 "abacabadabacaba" 152 """)) 153 154 def test_legacy_create_function_memoize(self): 155 return DiffTestBlueprint( 156 trace=TextProto(""), 157 query=""" 158 -- Compute 2^n inefficiently to test memoization. 159 -- If it times out, memoization is not working. 160 SELECT create_function('f(x INT)', 'INT', 161 ' 162 SELECT IIF($x = 0, 1, f($x - 1) + f($x - 1)) 163 '); 164 165 SELECT EXPERIMENTAL_MEMOIZE('f'); 166 167 -- 2^50 is too expensive to compute, but memoization makes it fast. 168 SELECT f(50) as result; 169 """, 170 out=Csv(""" 171 "result" 172 1125899906842624 173 """)) 174 175 def test_legacy_create_function_memoize_float(self): 176 return DiffTestBlueprint( 177 trace=TextProto(""), 178 query=""" 179 -- Compute 2^n inefficiently to test memoization. 180 -- If it times out, memoization is not working. 181 SELECT create_function('f(x INT)', 'FLOAT', 182 ' 183 SELECT $x + 0.5 184 '); 185 186 SELECT EXPERIMENTAL_MEMOIZE('f'); 187 188 SELECT printf("%.1f", f(1)) as result 189 UNION ALL 190 SELECT printf("%.1f", f(1)) as result 191 UNION ALL 192 SELECT printf("%.1f", f(1)) as result 193 """, 194 out=Csv(""" 195 "result" 196 "1.5" 197 "1.5" 198 "1.5" 199 """)) 200 201 def test_legacy_create_function_memoize_intermittent_memoization(self): 202 return DiffTestBlueprint( 203 trace=TextProto(""), 204 query=""" 205 -- This function returns NULL for odd numbers and 1 for even numbers. 206 -- As we do not memoize NULL results, we would only memoize the results 207 -- for even numbers. 208 SELECT create_function('f(x INT)', 'INT', 209 ' 210 SELECT IIF($x = 0, 1, 211 IIF(f($x - 1) IS NULL, 1, NULL) 212 ) 213 '); 214 215 SELECT EXPERIMENTAL_MEMOIZE('f'); 216 217 SELECT 218 f(50) as f_50, 219 f(51) as f_51; 220 """, 221 out=Csv(""" 222 "f_50","f_51" 223 1,"[NULL]" 224 """)) 225 226 def test_legacy_create_function_memoize_subtree_size(self): 227 # Tree: 228 # 1 229 # / \ 230 # / \ 231 # / \ 232 # 2 3 233 # / \ / \ 234 # 4 5 6 7 235 # / \ | | | \ 236 # 8 9 10 11 12 13 237 # | | 238 # 14 15 239 return DiffTestBlueprint( 240 trace=TextProto(""), 241 query=""" 242 CREATE PERFETTO TABLE tree AS 243 WITH data(id, parent_id) as (VALUES 244 (1, NULL), 245 (2, 1), 246 (3, 1), 247 (4, 2), 248 (5, 2), 249 (6, 3), 250 (7, 3), 251 (8, 4), 252 (9, 4), 253 (10, 5), 254 (11, 6), 255 (12, 7), 256 (13, 7), 257 (14, 8), 258 (15, 9) 259 ) 260 SELECT * FROM data; 261 262 SELECT create_function('subtree_size(id INT)', 'INT', 263 ' 264 SELECT 1 + IFNULL(( 265 SELECT 266 SUM(subtree_size(child.id)) 267 FROM tree child 268 WHERE child.parent_id = $id 269 ), 0) 270 '); 271 272 SELECT EXPERIMENTAL_MEMOIZE('subtree_size'); 273 274 SELECT 275 id, subtree_size(id) as size 276 FROM tree 277 ORDER BY id; 278 """, 279 out=Csv(""" 280 "id","size" 281 1,15 282 2,8 283 3,6 284 4,5 285 5,2 286 6,2 287 7,3 288 8,2 289 9,2 290 10,1 291 11,1 292 12,1 293 13,1 294 14,1 295 15,1 296 """))