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 18from python.generators.diff_tests.testing import DiffTestBlueprint 19from python.generators.diff_tests.testing import TestSuite 20 21 22class StdlibIntervals(TestSuite): 23 24 def test_intervals_overlap_count(self): 25 return DiffTestBlueprint( 26 trace=TextProto(""), 27 query=""" 28 INCLUDE PERFETTO MODULE intervals.overlap; 29 30 WITH data(ts, dur) AS ( 31 VALUES 32 (10, 40), 33 (20, 10), 34 (25, 10), 35 (60, 10), 36 (70, 20), 37 (80, -1) 38 ) 39 SELECT * 40 FROM intervals_overlap_count!(data, ts, dur) 41 """, 42 out=Csv(""" 43 "ts","value" 44 10,1 45 20,2 46 25,3 47 30,2 48 35,1 49 50,0 50 60,1 51 70,1 52 80,2 53 90,1 54 """)) 55 56 def test_intervals_overlap_count_by_group(self): 57 return DiffTestBlueprint( 58 trace=TextProto(""), 59 query=""" 60 INCLUDE PERFETTO MODULE intervals.overlap; 61 62 WITH data(ts, dur, group_name) AS ( 63 VALUES 64 (10, 40, "A"), 65 (15, 30, "B"), 66 (20, 10, "A"), 67 (25, 10, "B"), 68 (30, 10, "B"), 69 (60, 10, "A"), 70 (60, -1, "B"), 71 (70, 20, "A"), 72 (80, -1, "A") 73 ) 74 SELECT * 75 FROM intervals_overlap_count_by_group!(data, ts, dur, group_name) 76 """, 77 out=Csv(""" 78 "ts","value","group_name" 79 10,1,"A" 80 15,1,"B" 81 20,2,"A" 82 25,2,"B" 83 30,1,"A" 84 30,3,"B" 85 35,2,"B" 86 40,1,"B" 87 45,0,"B" 88 50,0,"A" 89 60,1,"A" 90 60,1,"B" 91 70,1,"A" 92 80,2,"A" 93 90,1,"A" 94 """)) 95 96 def test_intervals_overlap_in_table(self): 97 return DiffTestBlueprint( 98 trace=TextProto(""), 99 query=""" 100 INCLUDE PERFETTO MODULE intervals.overlap; 101 102 WITH data_no_overlaps(ts, dur) AS ( 103 VALUES 104 (10, 10), 105 (30, 10) 106 ), 107 data_with_overlaps(ts, dur) AS ( 108 VALUES 109 (10, 10), 110 (15, 10) 111 ) 112 SELECT * FROM ( 113 SELECT * 114 FROM _intervals_overlap_in_table!(data_no_overlaps) 115 UNION 116 SELECT * 117 FROM _intervals_overlap_in_table!(data_with_overlaps) 118 ) 119 """, 120 out=Csv(""" 121 "has_overlaps" 122 0 123 1 124 """)) 125 126 def test_intervals_flatten(self): 127 return DiffTestBlueprint( 128 trace=TextProto(""), 129 query=""" 130 INCLUDE PERFETTO MODULE intervals.overlap; 131 132 WITH roots_data (id, ts, dur) AS ( 133 VALUES 134 (0, 0, 9), 135 (1, 9, 1) 136 ), children_data (root_id, id, parent_id, ts, dur) AS ( 137 VALUES 138 (0, 2, 0, 1, 3), 139 (0, 3, 0, 5, 1), 140 (0, 4, 0, 6, 1), 141 (0, 5, 0, 7, 0), 142 (0, 6, 0, 7, 1), 143 (0, 7, 2, 2, 1) 144 ) 145 SELECT ts, dur, id, root_id 146 FROM _intervals_flatten!(_intervals_merge_root_and_children!(roots_data, children_data)) ORDER BY ts 147 """, 148 out=Csv(""" 149 "ts","dur","id","root_id" 150 0,1,0,0 151 1,1,2,0 152 2,1,7,0 153 3,1,2,0 154 4,1,0,0 155 5,1,3,0 156 6,1,4,0 157 7,1,6,0 158 8,1,0,0 159 9,1,1,1 160 """)) 161 162 def test_intervals_flatten_by_intersection(self): 163 return DiffTestBlueprint( 164 trace=TextProto(""), 165 query=""" 166 INCLUDE PERFETTO MODULE intervals.overlap; 167 168 CREATE PERFETTO TABLE foo AS 169 WITH roots_data (id, ts, dur, utid) AS ( 170 VALUES 171 (0, 0, 9, 0), 172 (0, 0, 9, 1), 173 (1, 9, 1, 2) 174 ), children_data (id, parent_id, ts, dur, utid) AS ( 175 VALUES 176 (2, 0, 1, 3, 0), 177 (3, 0, 5, 1, 0), 178 (4, 0, 6, 1, 0), 179 (5, 0, 7, 0, 0), 180 (6, 0, 7, 1, 0), 181 (7, 2, 2, 1, 0) 182 ) 183 SELECT * 184 FROM _intervals_merge_root_and_children_by_intersection!(roots_data, children_data, utid); 185 186 SELECT ts, dur, id, root_id FROM _intervals_flatten!(foo) ORDER BY ts; 187 """, 188 out=Csv(""" 189 "ts","dur","id","root_id" 190 0,1,0,0 191 1,1,2,0 192 2,1,7,0 193 3,1,2,0 194 4,1,0,0 195 5,1,3,0 196 6,1,4,0 197 7,1,6,0 198 8,1,0,0 199 """)) 200 201 def test_intervals_flatten_by_intersection_no_matching_key(self): 202 return DiffTestBlueprint( 203 trace=TextProto(""), 204 query=""" 205 INCLUDE PERFETTO MODULE intervals.overlap; 206 207 CREATE PERFETTO TABLE foo AS 208 WITH roots_data (id, ts, dur, utid) AS ( 209 VALUES 210 (0, 0, 9, 1), 211 (0, 0, 9, 2), 212 (1, 9, 1, 3) 213 ), children_data (id, parent_id, ts, dur, utid) AS ( 214 VALUES 215 (2, 0, 1, 3, 0), 216 (3, 0, 5, 1, 0), 217 (4, 0, 6, 1, 0), 218 (5, 0, 7, 0, 0), 219 (6, 0, 7, 1, 0), 220 (7, 2, 2, 1, 0) 221 ) 222 SELECT * 223 FROM _intervals_merge_root_and_children_by_intersection!(roots_data, children_data, utid); 224 225 SELECT ts, dur, id, root_id FROM _intervals_flatten!(foo) ORDER BY ts; 226 """, 227 out=Csv(""" 228 "ts","dur","id","root_id" 229 """)) 230 231 232 def test_remove_overlap(self): 233 return DiffTestBlueprint( 234 trace=TextProto(""), 235 query=""" 236 INCLUDE PERFETTO MODULE intervals.overlap; 237 238 WITH 239 data(ts, dur) AS ( 240 VALUES 241 -- partial overlap 242 (1, 4), 243 (2, 4), 244 -- end within epsilon of start 245 (10, 3), 246 (14, 2), 247 -- end not within epsilon of start 248 (20, 3), 249 (26, 2), 250 -- nested 251 (30, 4), 252 (31, 2) 253 ) 254 SELECT * 255 FROM interval_remove_overlap!(data, 1); 256 """, 257 out=Csv(""" 258 "ts","dur" 259 1,5 260 10,6 261 20,3 262 26,2 263 30,4 264 """)) 265 266 def test_intersect_list(self): 267 return DiffTestBlueprint( 268 trace=TextProto(""), 269 query=""" 270 INCLUDE PERFETTO MODULE intervals.intersect; 271 272 WITH 273 data(ts, dur, id) AS ( 274 VALUES 275 (10, 100, 0), 276 (20, 40, 1), 277 (30, 120, 2), 278 (200, 10, 3), 279 (200, 20, 4), 280 (300, 10, 5) 281 ) 282 SELECT * 283 FROM interval_self_intersect!(data) 284 ORDER BY ts ASC, id ASC; 285 """, 286 out=Csv(""" 287 "ts","dur","group_id","id","interval_ends_at_ts" 288 10,10,1,0,0 289 20,10,2,0,0 290 20,10,2,1,0 291 30,30,3,0,0 292 30,30,3,1,0 293 30,30,3,2,0 294 60,50,4,0,0 295 60,50,4,1,1 296 60,50,4,2,0 297 110,40,5,0,1 298 110,40,5,2,0 299 150,50,6,2,1 300 200,10,7,3,0 301 200,10,7,4,0 302 210,10,8,3,1 303 210,10,8,4,0 304 220,80,9,4,1 305 300,10,10,5,0 306 310,0,11,5,1 307 """)) 308