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, TraceInjector 19from python.generators.diff_tests.testing import TestSuite 20 21 22class Parsing(TestSuite): 23 # Contains tests for parsing events which are applicable to more than one 24 # "area". Generally, events here are of high importance (e.g. sched_switch 25 # tested here is and is used by every embedder of trace processor) Note: 26 # generally *not* advisable to add tests here. Check the guidance provided 27 # http://perfetto/dev/docs/analysis/trace-processor#diff-tests for choosing 28 # folder to add a new test to. TODO(lalitm): some tests here should be moved 29 # of here and into the area folders; they are only here because they predate 30 # modularisation of diff tests. Sched 31 def test_ts_desc_filter_android_sched_and_ps(self): 32 return DiffTestBlueprint( 33 trace=DataPath('android_sched_and_ps.pb'), 34 query=""" 35 SELECT ts 36 FROM sched 37 JOIN thread USING(utid) 38 WHERE tid = 23850 39 ORDER BY ts DESC 40 LIMIT 10; 41 """, 42 out=Csv(""" 43 "ts" 44 81492536383477 45 81491101817952 46 81491101296858 47 81491101029618 48 81491099541806 49 81491099514618 50 81491099495504 51 81491099477014 52 81491098894566 53 81491096076181 54 """)) 55 56 # Sched reason 57 def test_android_sched_and_ps_end_reason_eq(self): 58 return DiffTestBlueprint( 59 trace=DataPath('android_sched_and_ps.pb'), 60 query=""" 61 SELECT end_state, count(*) 62 FROM sched 63 WHERE end_state = 'D' 64 GROUP BY end_state; 65 """, 66 out=Csv(""" 67 "end_state","count(*)" 68 "D",10503 69 """)) 70 71 def test_android_sched_and_ps_end_reason_neq(self): 72 return DiffTestBlueprint( 73 trace=DataPath('android_sched_and_ps.pb'), 74 query=""" 75 SELECT end_state, count(*) 76 FROM sched 77 WHERE end_state != 'D' 78 GROUP BY end_state; 79 """, 80 out=Csv(""" 81 "end_state","count(*)" 82 "DK",30 83 "R",91189 84 "R+",9428 85 "S",110560 86 "x",82 87 """)) 88 89 # CPU Frequency 90 def test_cpu_counters_b120487929(self): 91 return DiffTestBlueprint( 92 trace=DataPath('cpu_counters.pb'), 93 query=Path('b120487929_test.sql'), 94 out=Path('cpu_counters_b120487929.out')) 95 96 # Test the filtering of ftrace events before tracing_start. 97 def test_ftrace_with_tracing_start_list_sched_slice_spans(self): 98 return DiffTestBlueprint( 99 trace=Path('ftrace_with_tracing_start.py'), 100 query=""" 101 SELECT ts, dur, tid 102 FROM sched 103 JOIN thread USING(utid) 104 ORDER BY ts; 105 """, 106 out=Csv(""" 107 "ts","dur","tid" 108 100,10,1 109 110,-1,2 110 """)) 111 112 # Scheduling slices from sched_switch events. There are two tests, one for 113 # typical encoding of sched_switch events, and one for the same trace 114 # in the compact format. The output should be identical apart from the 115 # having one slice fewer for each cpu (the first compact sched_switch event 116 # start a slice). Six slices in this case. 117 def test_sched_slices_sched_switch_original(self): 118 return DiffTestBlueprint( 119 trace=DataPath('sched_switch_original.pb'), 120 query=""" 121 SELECT ts, cpu, dur, ts_end, end_state, priority, tid, name 122 FROM sched JOIN thread ON sched.utid = thread.utid 123 ORDER BY cpu, sched.ts ASC; 124 """, 125 out=Path('sched_slices_sched_switch_original.out')) 126 127 def test_sched_slices_sched_switch_compact(self): 128 return DiffTestBlueprint( 129 trace=DataPath('sched_switch_compact.pb'), 130 query=""" 131 SELECT ts, cpu, dur, ts_end, end_state, priority, tid, name 132 FROM sched JOIN thread ON sched.utid = thread.utid 133 ORDER BY cpu, sched.ts ASC; 134 """, 135 out=Path('sched_slices_sched_switch_compact.out')) 136 137 # Decoding of sched_waking events from a trace with compact scheduling 138 # Verifies the contents of raw & instants tables. 139 def test_sched_waking_raw_compact_sched(self): 140 return DiffTestBlueprint( 141 trace=DataPath('compact_sched.pb'), 142 query=Path('sched_waking_raw_test.sql'), 143 out=Path('sched_waking_raw_compact_sched.out')) 144 145 def test_sched_waking_instants_compact_sched(self): 146 return DiffTestBlueprint( 147 trace=DataPath('compact_sched.pb'), 148 query=""" 149 SELECT ts, thread.name, thread.tid 150 FROM thread_state 151 JOIN thread USING (utid) 152 WHERE state = 'R' 153 ORDER BY ts; 154 """, 155 out=Path('sched_waking_instants_compact_sched.out')) 156 157 # Mm Event 158 def test_mm_event(self): 159 return DiffTestBlueprint( 160 trace=DataPath('mm_event.pb'), 161 query=""" 162 SELECT ts, name, value 163 FROM counter 164 JOIN counter_track 165 ON counter.track_id = counter_track.id 166 WHERE name GLOB 'mem.mm.*' 167 ORDER BY ts 168 LIMIT 40; 169 """, 170 out=Path('mm_event.out')) 171 172 # Check the systrace conversion code in the raw table. Print events 173 def test_print_systrace_lmk_userspace(self): 174 return DiffTestBlueprint( 175 trace=DataPath('lmk_userspace.pb'), 176 query=""" 177 SELECT to_ftrace(id) 178 FROM ftrace_event; 179 """, 180 out=Path('print_systrace_lmk_userspace.out')) 181 182 def test_kernel_tmw_counter_process_counter_and_track(self): 183 return DiffTestBlueprint( 184 trace=Path('kernel_tmw_counter.textproto'), 185 query=""" 186 SELECT ts, pct.name, value, pid 187 FROM counter c 188 JOIN process_counter_track pct ON c.track_id = pct.id 189 JOIN process USING (upid) 190 ORDER BY ts; 191 """, 192 out=Csv(""" 193 "ts","name","value","pid" 194 795572805481,"g2d_frame_hw#15",0.000000,237 195 795572870504,"g2d_frame_sw#15",0.000000,237 196 795620516581,"g2d_frame_sw#15",1.000000,237 197 795620943421,"g2d_frame_hw#15",1.000000,237 198 795623633810,"g2d_frame_hw#15",0.000000,237 199 795623633810,"g2d_frame_hw#15",0.000000,237 200 795623739848,"g2d_frame_sw#15",0.000000,237 201 """)) 202 203 def test_kernel_dpu_tmw_counter_process_counter_and_track(self): 204 return DiffTestBlueprint( 205 trace=TextProto(r""" 206 packet { 207 ftrace_events { 208 cpu: 2 209 event { 210 timestamp: 795572805481 211 pid: 237 212 dpu_tracing_mark_write { 213 pid: 237 214 name: "dpu_vote_clock" 215 type: 67 216 value: 123 217 } 218 } 219 event { 220 timestamp: 795572870504 221 pid: 515 222 dpu_tracing_mark_write { 223 pid: 237 224 name: "dpu_vote_clock" 225 type: 67 226 value: 100 227 } 228 } 229 event { 230 timestamp: 795620516581 231 pid: 237 232 dpu_tracing_mark_write { 233 pid: 237 234 name: "dpu_vote_clock" 235 type: 67 236 value: 125 237 } 238 } 239 event { 240 timestamp: 795620943421 241 pid: 515 242 dpu_tracing_mark_write { 243 pid: 237 244 name: "dpu_vote_clock" 245 type: 67 246 value: 100 247 } 248 } 249 } 250 trusted_uid: 9999 251 trusted_packet_sequence_id: 3 252 } 253 """), 254 query=""" 255 SELECT ts, pct.name, value, pid 256 FROM counter c 257 JOIN process_counter_track pct ON c.track_id = pct.id 258 JOIN process USING (upid) 259 ORDER BY ts; 260 """, 261 out=Csv(""" 262 "ts","name","value","pid" 263 795572805481,"dpu_vote_clock",123.000000,237 264 795572870504,"dpu_vote_clock",100.000000,237 265 795620516581,"dpu_vote_clock",125.000000,237 266 795620943421,"dpu_vote_clock",100.000000,237 267 """)) 268 269 # Unsigned integers 270 def test_print_systrace_unsigned(self): 271 return DiffTestBlueprint( 272 trace=Path('print_systrace_unsigned.py'), 273 query=""" 274 SELECT to_ftrace(id) 275 FROM ftrace_event; 276 """, 277 out=Path('print_systrace_unsigned.out')) 278 279 # cgroup_attach_task systrace conversion. 280 def test_cgroup_attach_task_pre_s_print_systrace(self): 281 return DiffTestBlueprint( 282 trace=TextProto(r""" 283 packet { 284 ftrace_events { 285 cpu: 3 286 event { 287 timestamp: 74289018336 288 pid: 1 289 cgroup_attach_task { 290 dst_root: 1 291 dst_id: 2 292 pid: 3 293 comm: "foo" 294 cname: "bar" 295 } 296 } 297 } 298 } 299 """), 300 query=""" 301 SELECT to_ftrace(id) 302 FROM ftrace_event; 303 """, 304 out=Path('cgroup_attach_task_pre_s_print_systrace.out')) 305 306 def test_cgroup_attach_task_post_s_print_systrace(self): 307 return DiffTestBlueprint( 308 trace=TextProto(r""" 309 packet { 310 ftrace_events { 311 cpu: 3 312 event { 313 timestamp: 74289018336 314 pid: 1 315 cgroup_attach_task { 316 dst_root: 1 317 dst_id: 2 318 pid: 3 319 comm: "foo" 320 dst_level: 4 321 dst_path: "bar" 322 } 323 } 324 } 325 } 326 """), 327 query=""" 328 SELECT to_ftrace(id) 329 FROM ftrace_event; 330 """, 331 out=Path('cgroup_attach_task_post_s_print_systrace.out')) 332 333 # Parsing systrace files 334 def test_systrace_html(self): 335 return DiffTestBlueprint( 336 trace=DataPath('systrace.html'), 337 query=""" 338 SELECT ts, cpu, dur, ts_end, utid, end_state, priority, upid, name, tid 339 FROM sched 340 JOIN thread USING(utid) 341 ORDER BY ts, sched.id; 342 """, 343 out=Path('systrace_html.out')) 344 345 def test_sched_smoke_trailing_empty(self): 346 return DiffTestBlueprint( 347 trace=DataPath('trailing_empty.systrace'), 348 query=""" 349 SELECT COUNT(1) 350 FROM sched; 351 """, 352 out=Csv(""" 353 "COUNT(1)" 354 2 355 """)) 356 357 # LMK handling 358 def test_lmk_userspace_lmk(self): 359 return DiffTestBlueprint( 360 trace=DataPath('lmk_userspace.pb'), 361 query=""" 362 SELECT ts, process.pid 363 FROM instant 364 JOIN process_track ON instant.track_id = process_track.id 365 JOIN process USING (upid); 366 """, 367 out=Csv(""" 368 "ts","pid" 369 732246100696424,17924 370 732246180149452,21090 371 732246388596557,21120 372 732246415955101,21151 373 """)) 374 375 def test_oom_kill(self): 376 return DiffTestBlueprint( 377 trace=TextProto(r""" 378 packet { 379 process_tree { 380 processes { 381 pid: 1000 382 ppid: 1 383 cmdline: "com.google.android.gm" 384 } 385 threads { 386 tid: 1001 387 tgid: 1000 388 } 389 } 390 } 391 packet { 392 ftrace_events { 393 cpu: 4 394 event { 395 timestamp: 1234 396 pid: 4321 397 mark_victim { 398 pid: 1001 399 } 400 } 401 } 402 } 403 """), 404 query=""" 405 SELECT ts, instant.name, process.pid, process.name 406 FROM instant 407 JOIN thread_track ON instant.track_id = thread_track.id 408 JOIN thread USING (utid) 409 JOIN process USING (upid); 410 """, 411 out=Csv(""" 412 "ts","name","pid","name" 413 1234,"mem.oom_kill",1000,"com.google.android.gm" 414 """)) 415 416 # Logcat 417 def test_android_log_counts(self): 418 return DiffTestBlueprint( 419 trace=DataPath('android_log.pb'), 420 query=Path('android_log_counts_test.sql'), 421 out=Csv(""" 422 "cnt" 423 2249 424 431 425 264 426 2 427 4 428 31 429 246 430 """)) 431 432 def test_android_log_msgs(self): 433 return DiffTestBlueprint( 434 trace=DataPath('android_log.pb'), 435 query=Path('android_log_msgs_test.sql'), 436 out=Path('android_log_msgs.out')) 437 438 def test_android_log_ring_buffer_mode(self): 439 return DiffTestBlueprint( 440 trace=DataPath('android_log_ring_buffer_mode.pb'), 441 query=""" 442 SELECT count(*) FROM android_logs; 443 """, 444 out=Csv(""" 445 "count(*)" 446 26 447 """)) 448 449 # Oom Score 450 def test_synth_oom_oom_query(self): 451 return DiffTestBlueprint( 452 trace=Path('synth_oom.py'), 453 query=Path('oom_query_test.sql'), 454 out=Path('synth_oom_oom_query.out')) 455 456 def test_process_stats_poll_oom_score(self): 457 return DiffTestBlueprint( 458 trace=DataPath('process_stats_poll.pb'), 459 query=""" 460 SELECT ts, name, value, upid 461 FROM counter c 462 JOIN process_counter_track t 463 ON c.track_id = t.id 464 WHERE name = "oom_score_adj" 465 ORDER BY ts 466 LIMIT 20; 467 """, 468 out=Path('process_stats_poll_oom_score.out')) 469 470 # Stats 471 def test_android_sched_and_ps_stats(self): 472 return DiffTestBlueprint( 473 trace=DataPath('android_sched_and_ps.pb'), 474 query=""" 475 SELECT name, idx, severity, source, value 476 FROM stats WHERE name GLOB 'ftrace_cpu_*' OR name GLOB 'traced_buf_*'; 477 """, 478 out=Path('android_sched_and_ps_stats.out')) 479 480 # Syscalls 481 def test_sys_syscall(self): 482 return DiffTestBlueprint( 483 trace=Path('syscall.py'), 484 query=""" 485 SELECT ts, dur, name 486 FROM slices 487 LIMIT 10; 488 """, 489 out=Csv(""" 490 "ts","dur","name" 491 100,6,"sys_io_setup" 492 105,5,"sys_io_destroy" 493 """)) 494 495 # thread_slice tables. 496 def test_thread_time_in_thread_slice(self): 497 return DiffTestBlueprint( 498 trace=Path('flow_events_json_v2.json'), 499 query=""" 500 SELECT 501 name, thread_ts, thread_dur 502 FROM slice; 503 """, 504 out=Csv(""" 505 "name","thread_ts","thread_dur" 506 "SenderB",1000,5000 507 "Blergh","[NULL]","[NULL]" 508 "SenderA",3005000,7000 509 "OtherSlice",3204000,100000 510 "SomeSlice",3335000,340000 511 "SomeOtherSlice",3335000,996000 512 "SomeOtherSliceInstant","[NULL]","[NULL]" 513 """)) 514 515 # Initial display state 516 def test_initial_display_state(self): 517 return DiffTestBlueprint( 518 trace=TextProto(r""" 519 packet: { 520 timestamp: 1 521 initial_display_state: { 522 display_state: 2 523 brightness: 0.5 524 } 525 } 526 packet { 527 ftrace_events { 528 cpu: 0 529 event { 530 timestamp: 1000 531 pid: 1234 532 print { 533 buf: "C|5678|ScreenState|0\n" 534 } 535 } 536 } 537 } 538 """), 539 query=""" 540 SELECT t.name, 541 c.ts, 542 c.value 543 FROM counter_track t 544 JOIN counter c ON t.id = c.track_id 545 WHERE t.name = 'ScreenState'; 546 """, 547 out=Csv(""" 548 "name","ts","value" 549 "ScreenState",1,2.000000 550 "ScreenState",1000,0.000000 551 """)) 552 553 # Config & metadata 554 def test_config_metadata(self): 555 return DiffTestBlueprint( 556 trace=TextProto(r""" 557 packet { 558 clock_snapshot { 559 clocks { 560 clock_id: 6 561 timestamp: 101000002 562 } 563 clocks { 564 clock_id: 128 565 timestamp: 2 566 } 567 } 568 timestamp: 101000002 569 } 570 packet { 571 trace_config { 572 trace_uuid_msb: 1314564453825188563 573 trace_uuid_lsb: -6605018796207623390 574 } 575 } 576 packet { 577 system_info { 578 android_build_fingerprint: "the fingerprint" 579 } 580 } 581 """), 582 query=""" 583 SELECT name, str_value FROM metadata WHERE str_value IS NOT NULL ORDER BY name; 584 """, 585 out=Csv(""" 586 "name","str_value" 587 "android_build_fingerprint","the fingerprint" 588 "trace_config_pbtxt","trace_uuid_msb: 1314564453825188563 589 trace_uuid_lsb: -6605018796207623390" 590 "trace_type","proto" 591 "trace_uuid","123e4567-e89b-12d3-a456-426655443322" 592 """)) 593 594 def test_triggers_packets_trigger_packet_trace(self): 595 return DiffTestBlueprint( 596 trace=TextProto(r""" 597 packet { 598 trigger { 599 trigger_name: "test1" 600 trusted_producer_uid: 3 601 producer_name: "producer1" 602 } 603 timestamp: 101000002 604 } 605 packet { 606 trigger { 607 trigger_name: "test2" 608 trusted_producer_uid: 4 609 producer_name: "producer2" 610 } 611 timestamp: 101000004 612 } 613 """), 614 query=Path('triggers_packets_test.sql'), 615 out=Csv(""" 616 "ts","name","string_value","int_value" 617 101000002,"test1","producer1",3 618 101000004,"test2","producer2",4 619 """)) 620 621 def test_chrome_metadata(self): 622 return DiffTestBlueprint( 623 trace=TextProto(r""" 624 packet { 625 clock_snapshot { 626 clocks { 627 clock_id: 6 628 timestamp: 101000002 629 } 630 } 631 trusted_packet_sequence_id: 1 632 timestamp: 101000002 633 } 634 packet { 635 chrome_trigger { 636 trigger_name_hash: 1595654158 637 } 638 trusted_packet_sequence_id: 1 639 timestamp: 101000002 640 } 641 packet { 642 trusted_packet_sequence_id: 1 643 timestamp: 101000002 644 chrome_metadata { 645 background_tracing_metadata { 646 triggered_rule { 647 name_hash: 1595654158 648 } 649 scenario_name_hash: 3005533841 650 } 651 chrome_version_code: 101 652 enabled_categories: "cat1,cat2,cat3" 653 field_trial_hashes { 654 name: 123 655 group: 456 656 } 657 field_trial_hashes { 658 name: 789 659 group: 120 660 } 661 } 662 } 663 """), 664 query=""" 665 SELECT * FROM metadata; 666 """, 667 out=Path('chrome_metadata.out')) 668 669 def test_chrome_metadata_multiple(self): 670 return DiffTestBlueprint( 671 trace=TextProto(r""" 672 packet { 673 clock_snapshot { 674 clocks { 675 clock_id: 6 676 timestamp: 101000002 677 } 678 } 679 trusted_packet_sequence_id: 1 680 timestamp: 101000002 681 } 682 packet { 683 trusted_packet_sequence_id: 1 684 timestamp: 101000002 685 chrome_metadata { 686 chrome_version_code: 101 687 enabled_categories: "cat1,cat2,cat3" 688 field_trial_hashes { 689 name: 123 690 group: 456 691 } 692 field_trial_hashes { 693 name: 789 694 group: 120 695 } 696 } 697 } 698 packet { 699 trusted_packet_sequence_id: 1 700 timestamp: 101000002 701 chrome_metadata { 702 chrome_version_code: 102 703 enabled_categories: "cat3,cat4,cat5" 704 field_trial_hashes { 705 name: 1234 706 group: 5678 707 } 708 field_trial_hashes { 709 name: 9012 710 group: 3456 711 } 712 } 713 } 714 """), 715 query=""" 716 SELECT * FROM metadata; 717 """, 718 out=Csv(""" 719 "id","type","name","key_type","int_value","str_value" 720 0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-0de8-df55233147f0" 721 1,"metadata","trace_time_clock_id","single",6,"[NULL]" 722 2,"metadata","cr-a-playstore_version_code","single",101,"[NULL]" 723 3,"metadata","cr-a-enabled_categories","single","[NULL]","cat1,cat2,cat3" 724 4,"metadata","cr-a-field_trial_hashes","single","[NULL]","{ name: 123, group: 456 } { name: 789, group: 120 } " 725 5,"metadata","cr-b-playstore_version_code","single",102,"[NULL]" 726 6,"metadata","cr-b-enabled_categories","single","[NULL]","cat3,cat4,cat5" 727 7,"metadata","cr-b-field_trial_hashes","single","[NULL]","{ name: 1234, group: 5678 } { name: 9012, group: 3456 } " 728 8,"metadata","trace_size_bytes","single",110,"[NULL]" 729 9,"metadata","trace_type","single","[NULL]","proto" 730 """)) 731 732 # CPU info 733 def test_cpu(self): 734 return DiffTestBlueprint( 735 trace=Path('cpu_info.textproto'), 736 query=""" 737 SELECT 738 cpu, 739 cluster_id, 740 processor 741 FROM cpu; 742 """, 743 out=Csv(""" 744 "cpu","cluster_id","processor" 745 0,0,"AArch64 Processor rev 13 (aarch64)" 746 1,0,"AArch64 Processor rev 13 (aarch64)" 747 2,0,"AArch64 Processor rev 13 (aarch64)" 748 3,0,"AArch64 Processor rev 13 (aarch64)" 749 4,0,"AArch64 Processor rev 13 (aarch64)" 750 5,0,"AArch64 Processor rev 13 (aarch64)" 751 6,1,"AArch64 Processor rev 13 (aarch64)" 752 7,1,"AArch64 Processor rev 13 (aarch64)" 753 """)) 754 755 def test_cpu_freq(self): 756 return DiffTestBlueprint( 757 trace=Path('cpu_info.textproto'), 758 query=""" 759 SELECT 760 freq, 761 GROUP_CONCAT(cpu) AS cpus 762 FROM cpu_frequencies 763 GROUP BY freq 764 ORDER BY freq; 765 """, 766 out=Path('cpu_freq.out')) 767 768 # Trace size 769 def test_android_sched_and_ps_trace_size(self): 770 return DiffTestBlueprint( 771 trace=DataPath('android_sched_and_ps.pb'), 772 query=""" 773 SELECT int_value FROM metadata WHERE name = 'trace_size_bytes'; 774 """, 775 out=Csv(""" 776 "int_value" 777 18761615 778 """)) 779 780 # Package list handling 781 def test_android_package_list(self): 782 return DiffTestBlueprint( 783 trace=Path('android_package_list.py'), 784 query=Metric('android_package_list'), 785 out=TextProto(r""" 786 android_package_list { 787 packages { 788 package_name: "com.my.pkg" 789 uid: 123 790 version_code: 456000 791 } 792 } 793 """)) 794 795 # Ensures process -> package matching works as expected. 796 def test_process_metadata_matching(self): 797 return DiffTestBlueprint( 798 trace=TextProto(r""" 799 packet { 800 process_tree { 801 processes { 802 pid: 1 803 ppid: 0 804 cmdline: "init" 805 uid: 0 806 } 807 processes { 808 pid: 2 809 ppid: 1 810 cmdline: "system_server" 811 uid: 1000 812 } 813 processes { 814 pid: 3 815 ppid: 1 816 cmdline: "com.google.android.gms" 817 uid: 10100 818 } 819 processes { 820 pid: 4 821 ppid: 1 822 cmdline: "com.google.android.gms.persistent" 823 uid: 10100 824 } 825 processes { 826 pid: 5 827 ppid: 1 828 cmdline: "com.google.android.gms" 829 uid: 1010100 830 } 831 } 832 } 833 packet { 834 packages_list { 835 packages { 836 name: "com.google.android.gms" 837 uid: 10100 838 version_code: 1234 839 } 840 packages { 841 name: "com.google.android.gsf" 842 uid: 10100 843 version_code: 1 844 } 845 } 846 } 847 """), 848 query=""" 849 SELECT RUN_METRIC('android/process_metadata.sql'); 850 851 SELECT upid, process_name, uid, shared_uid, package_name, version_code 852 FROM process_metadata_table 853 WHERE upid != 0; 854 """, 855 out=Csv(""" 856 "upid","process_name","uid","shared_uid","package_name","version_code" 857 1,"init",0,"[NULL]","[NULL]","[NULL]" 858 2,"system_server",1000,"[NULL]","[NULL]","[NULL]" 859 3,"com.google.android.gms",10100,1,"com.google.android.gms",1234 860 4,"com.google.android.gms.persistent",10100,1,"com.google.android.gms",1234 861 5,"com.google.android.gms",10100,1,"com.google.android.gms",1234 862 """)) 863 864 # Flow events importing from json 865 def test_flow_events_json_v1(self): 866 return DiffTestBlueprint( 867 trace=Path('flow_events_json_v1.json'), 868 query=""" 869 SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t 870 JOIN slice t1 ON t.slice_out = t1.slice_id 871 JOIN slice t2 ON t.slice_in = t2.slice_id; 872 """, 873 out=Csv(""" 874 "slice_out","slice_in" 875 "SenderB","Blergh" 876 "SenderA","OtherSlice" 877 "OtherSlice","SomeSlice" 878 """)) 879 880 def test_flow_events_json_v2(self): 881 return DiffTestBlueprint( 882 trace=Path('flow_events_json_v2.json'), 883 query=""" 884 SELECT t1.name AS slice_out, t2.name AS slice_in FROM flow t 885 JOIN slice t1 ON t.slice_out = t1.slice_id 886 JOIN slice t2 ON t.slice_in = t2.slice_id; 887 """, 888 out=Csv(""" 889 "slice_out","slice_in" 890 "SenderB","Blergh" 891 "SenderA","OtherSlice" 892 "OtherSlice","SomeSlice" 893 "OtherSlice","SomeOtherSlice" 894 """)) 895 896 # Importing displayTimeUnit 897 def test_display_time_unit_slices(self): 898 return DiffTestBlueprint( 899 trace=Json(r""" 900 {"displayTimeUnit":"ns","traceEvents":[ 901 { 902 "name": "process_name", 903 "pid": 1, 904 "ph": "M", 905 "args": { 906 "name": "api-service-65fc94b8c7-68w9w" 907 } 908 }, 909 { 910 "name": "add_graph", 911 "pid": 1, 912 "tid": 1, 913 "ph": "B", 914 "ts": 1597071955492308 915 }, 916 { 917 "name": "add_graph", 918 "pid": 1, 919 "tid": 1, 920 "ph": "E", 921 "ts": 1597071955703771 922 } 923 ] 924 } 925 """), 926 query=""" 927 SELECT ts, dur, name FROM slice ORDER BY ts DESC; 928 """, 929 out=Csv(""" 930 "ts","dur","name" 931 1597071955492308000,211463000,"add_graph" 932 """)) 933 934 # Parsing sched_blocked_reason 935 def test_sched_blocked_proto_sched_blocked_reason(self): 936 return DiffTestBlueprint( 937 trace=Path('sched_blocked_proto.py'), 938 query=""" 939 SELECT ts, tid, io_wait 940 FROM thread_state 941 JOIN thread USING (utid) 942 WHERE state = 'D' 943 ORDER BY ts; 944 """, 945 out=Csv(""" 946 "ts","tid","io_wait" 947 100,1,0 948 110,2,1 949 """)) 950 951 def test_sched_blocked_systrace_sched_blocked_reason(self): 952 return DiffTestBlueprint( 953 trace=Path('sched_blocked_systrace.systrace'), 954 query=""" 955 SELECT ts, tid, io_wait 956 FROM thread_state 957 JOIN thread USING (utid) 958 WHERE state = 'D' 959 ORDER BY ts; 960 """, 961 out=Csv(""" 962 "ts","tid","io_wait" 963 20258854000,269,0 964 21123838000,2172,1 965 """)) 966 967 # Kernel symbolization 968 def test_sched_blocked_reason_symbolized_sched_blocked_reason_function(self): 969 return DiffTestBlueprint( 970 trace=Path('sched_blocked_reason_symbolized.textproto'), 971 query=""" 972 SELECT 973 ts, 974 thread.tid AS pid, 975 blocked_function AS func 976 FROM thread_state 977 JOIN thread USING (utid) 978 WHERE state = 'D' 979 ORDER BY ts; 980 """, 981 out=Csv(""" 982 "ts","pid","func" 983 999000,105,"some_fn" 984 999000,102,"filemap_fault" 985 1000000,100,"filemap_fault" 986 1001000,101,"[NULL]" 987 1002000,103,"[NULL]" 988 1003000,100,"some_other_fn" 989 1005000,104,"filemap_fault" 990 """)) 991 992 def test_sched_blocked_reason_symbolized_to_systrace(self): 993 return DiffTestBlueprint( 994 trace=Path('sched_blocked_reason_symbolized.textproto'), 995 query=""" 996 SELECT to_ftrace(id) AS line 997 FROM ftrace_event; 998 """, 999 out=Path('sched_blocked_reason_symbolized_to_systrace.out')) 1000 1001 # Floating point numbers 1002 def test_decimal_timestamp_slices(self): 1003 return DiffTestBlueprint( 1004 trace=Json(r""" 1005 { 1006 "traceEvents": [{ 1007 "pid": 1234, 1008 "tid": 1234, 1009 "ts": 5.1, 1010 "dur": 500.1, 1011 "name": "name.exec", 1012 "ph": "XXX", 1013 "cat": "aaa" 1014 }] 1015 } 1016 """), 1017 query=""" 1018 SELECT ts, dur, name FROM slice ORDER BY ts DESC; 1019 """, 1020 out=Csv(""" 1021 "ts","dur","name" 1022 5100,500100,"name.exec" 1023 """)) 1024 1025 # JSON instants and counters 1026 def test_counters_json_counters(self): 1027 return DiffTestBlueprint( 1028 trace=Json(r""" 1029 1030 [ 1031 {"pid": "1000", "name": "ctr", "ph": "C", "ts": 0, "args": {"cats": 0}}, 1032 {"pid": "1000", "name": "ctr", "ph": "C", "ts": 10, "args": {"cats": 10}}, 1033 {"pid": "1000", "name": "ctr", "ph": "C", "ts": 20, "args": {"cats": 0}} 1034 ] 1035 """), 1036 query=""" 1037 SELECT 1038 process_counter_track.name, 1039 counter.ts, 1040 counter.value 1041 FROM counter 1042 JOIN process_counter_track ON (counter.track_id = process_counter_track.id); 1043 """, 1044 out=Csv(""" 1045 "name","ts","value" 1046 "ctr cats",0,0.000000 1047 "ctr cats",10000,10.000000 1048 "ctr cats",20000,0.000000 1049 """)) 1050 1051 def test_instants_json_instants(self): 1052 return DiffTestBlueprint( 1053 trace=DataPath('instants.json'), 1054 query=""" 1055 SELECT 1056 slice.ts, 1057 slice.name AS slice_name, 1058 thread.tid, 1059 process.pid 1060 FROM slice 1061 JOIN track ON (slice.track_id = track.id) 1062 LEFT JOIN thread_track ON (slice.track_id = thread_track.id) 1063 LEFT JOIN thread ON (thread_track.utid = thread.utid) 1064 LEFT JOIN process_track ON (slice.track_id = process_track.id) 1065 LEFT JOIN process ON (process_track.upid = process.upid) 1066 WHERE dur = 0; 1067 """, 1068 out=Csv(""" 1069 "ts","slice_name","tid","pid" 1070 1234523300,"Thread",2347,"[NULL]" 1071 1235523300,"Global","[NULL]","[NULL]" 1072 1236523300,"Process","[NULL]",2320 1073 1237523300,"Nonei",6790,"[NULL]" 1074 1238523300,"NoneI",6790,"[NULL]" 1075 1239523300,"NoneR",6790,"[NULL]" 1076 """)) 1077 1078 # Trace quality metric 1079 def test_very_long_sched_android_trace_quality(self): 1080 return DiffTestBlueprint( 1081 trace=Path('very_long_sched.py'), 1082 query=Metric('android_trace_quality'), 1083 out=TextProto(r""" 1084 android_trace_quality { 1085 failures { 1086 name: "sched_slice_too_long" 1087 } 1088 } 1089 """)) 1090 1091 # Regression test for b/193721088 (infra prepending " done\n" to atrace) 1092 def test_sched_smoke_trailing_empty_2(self): 1093 return DiffTestBlueprint( 1094 trace=DataPath('atrace_b_193721088.atr'), 1095 query=""" 1096 SELECT COUNT(1) 1097 FROM sched; 1098 """, 1099 out=Csv(""" 1100 "COUNT(1)" 1101 2 1102 """)) 1103 1104 # Multiuser 1105 def test_android_multiuser_switch(self): 1106 return DiffTestBlueprint( 1107 trace=Path('android_multiuser_switch.textproto'), 1108 query=Metric('android_multiuser'), 1109 out=TextProto(r""" 1110 android_multiuser: { 1111 user_switch: { 1112 duration_ms: 4900 1113 } 1114 } 1115 """)) 1116 1117 # Output of atrace -z. 1118 def test_atrace_compressed_sched_count(self): 1119 return DiffTestBlueprint( 1120 trace=DataPath('atrace_compressed.ctrace'), 1121 query=""" 1122 SELECT COUNT(1) 1123 FROM sched; 1124 """, 1125 out=Csv(""" 1126 "COUNT(1)" 1127 1120 1128 """)) 1129 1130 # Output of adb shell "atrace -t 1 sched" > out.txt". It has extra garbage 1131 # from stderr before the TRACE: marker. See b/208691037. 1132 def test_atrace_uncompressed_sched_count(self): 1133 return DiffTestBlueprint( 1134 trace=DataPath('atrace_uncompressed_b_208691037'), 1135 query=""" 1136 SELECT COUNT(1) 1137 FROM sched; 1138 """, 1139 out=Csv(""" 1140 "COUNT(1)" 1141 9 1142 """)) 1143 1144 def test_otheruuids_android_other_traces(self): 1145 return DiffTestBlueprint( 1146 trace=Path('otheruuids.textproto'), 1147 query=Metric('android_other_traces'), 1148 out=TextProto(r""" 1149 android_other_traces { 1150 finalized_traces_uuid: "75e4c6d0-d8f6-4f82-fa4b-9e09c5512288" 1151 finalized_traces_uuid: "ad836701-3113-3fb1-be4f-f7731e23fbbf" 1152 finalized_traces_uuid: "0de1a010-efa1-a081-2345-969b1186a6ab" 1153 } 1154 """)) 1155 1156 # Per-process Binder transaction metrics 1157 def test_android_binder(self): 1158 return DiffTestBlueprint( 1159 trace=Path('android_binder.py'), 1160 query=Metric('android_binder'), 1161 out=TextProto(r""" 1162 android_binder { 1163 process_breakdown { 1164 process_name: "test_process_a" 1165 pid: 1 1166 slice_name: "binder transaction" 1167 count: 2 1168 } 1169 process_breakdown { 1170 process_name: "test_process_b" 1171 pid: 2 1172 slice_name: "binder reply" 1173 count: 1 1174 } 1175 process_breakdown { 1176 process_name: "test_process_c" 1177 pid: 3 1178 slice_name: "binder reply" 1179 count: 1 1180 } 1181 } 1182 """)) 1183 1184 # Statsd Atoms 1185 def test_statsd_atoms_all_atoms(self): 1186 return DiffTestBlueprint( 1187 trace=DataPath('statsd_atoms.pb'), 1188 query=Path('all_atoms_test.sql'), 1189 out=Path('statsd_atoms_all_atoms.out')) 1190 1191 # Statsd Atoms 1192 def test_statsd_atoms_unknown_atoms(self): 1193 return DiffTestBlueprint( 1194 trace=DataPath('statsd_atoms_oem.pb'), 1195 query=Path('all_atoms_test.sql'), 1196 out=Csv(""" 1197 "name","key","display_value" 1198 "atom_202001","field_1","1" 1199 """)) 1200 1201 # Kernel function tracing. 1202 def test_funcgraph_trace_funcgraph(self): 1203 return DiffTestBlueprint( 1204 trace=Path('funcgraph_trace.textproto'), 1205 query=""" 1206 SELECT ts, dur, tid, s.name, depth 1207 FROM slices s 1208 JOIN thread_track tt ON (s.track_id = tt.id) 1209 JOIN thread USING (utid) 1210 WHERE tid = 385482; 1211 """, 1212 out=Csv(""" 1213 "ts","dur","tid","name","depth" 1214 679375600673065,3797,385482,"__handle_mm_fault",0 1215 679375600673769,1726,385482,"alloc_pages_vma",1 1216 """)) 1217 1218 # Kernel task_newtask waker_utid parsing 1219 def test_task_newtask_waker_utid(self): 1220 return DiffTestBlueprint( 1221 trace=TextProto(r""" 1222 packet { 1223 first_packet_on_sequence: true 1224 ftrace_events { 1225 cpu: 1 1226 event { 1227 timestamp: 201315132677 1228 pid: 518 1229 task_newtask { 1230 pid: 3294 1231 comm: "adbd" 1232 clone_flags: 18874368 1233 oom_score_adj: -1000 1234 } 1235 } 1236 event { 1237 timestamp: 201319417828 1238 pid: 518 1239 task_newtask { 1240 pid: 3295 1241 comm: "adbd" 1242 clone_flags: 4001536 1243 oom_score_adj: -1000 1244 } 1245 } 1246 } 1247 trusted_uid: 9999 1248 trusted_packet_sequence_id: 2 1249 trusted_pid: 521 1250 previous_packet_dropped: true 1251 } 1252 """), 1253 query=""" 1254 SELECT waker_utid FROM thread_state 1255 """, 1256 out=Csv(""" 1257 "waker_utid" 1258 1 1259 1 1260 """)) 1261 1262 # Parsing of mdss/tracing_mark_write events 1263 def test_slice_mdss_tracing_mark_write(self): 1264 # Note that tracing_mark_write below is an ftrace event from the mdss 1265 # group (see mdss.proto and aosp/2622569). Events with the same name 1266 # from other groups (e.g. sde) listed after mdss in ftrace_proto_gen 1267 # are prefixed with the group name to avoid conflicts. 1268 return DiffTestBlueprint( 1269 trace=TextProto(r""" 1270 packet { 1271 ftrace_events { 1272 cpu: 0 1273 event { 1274 timestamp: 100 1275 pid: 584 1276 tracing_mark_write { 1277 pid: 584 1278 trace_name: "test_event" 1279 trace_begin: 1 1280 } 1281 } 1282 event { 1283 timestamp: 200 1284 pid: 584 1285 tracing_mark_write { 1286 pid: 584 1287 trace_name: "test_event" 1288 trace_begin: 0 1289 } 1290 } 1291 } 1292 } 1293 """), 1294 query=""" 1295 SELECT s.name, dur, tid 1296 FROM slice s 1297 JOIN thread_track t ON s.track_id = t.id 1298 JOIN thread USING(utid) 1299 """, 1300 out=Csv(""" 1301 "name","dur","tid" 1302 "test_event",100,584 1303 """)) 1304 1305 def test_all_data_source_flushed_metadata(self): 1306 return DiffTestBlueprint( 1307 trace=TextProto(r""" 1308 packet { 1309 timestamp: 12344 1310 service_event { 1311 all_data_sources_flushed: true 1312 } 1313 } 1314 packet { 1315 timestamp: 12345 1316 service_event { 1317 all_data_sources_flushed: true 1318 } 1319 } 1320 """), 1321 query=""" 1322 SELECT name, int_value FROM metadata WHERE name = 'all_data_source_flushed_ns'""", 1323 out=Csv(""" 1324 "name","int_value" 1325 "all_data_source_flushed_ns",12344 1326 "all_data_source_flushed_ns",12345 1327 """)) 1328 1329 def test_ftrace_abi_errors_skipped_zero_data_length(self): 1330 return DiffTestBlueprint( 1331 trace=TextProto(r""" 1332 packet { 1333 ftrace_stats { 1334 phase: END_OF_TRACE 1335 cpu_stats { 1336 cpu: 0 1337 entries: 14 1338 overrun: 0 1339 commit_overrun: 0 1340 bytes_read: 840 1341 oldest_event_ts: 86557.552705 1342 now_ts: 86557.574310 1343 dropped_events: 0 1344 read_events: 199966062 1345 } 1346 kernel_symbols_parsed: 128611 1347 kernel_symbols_mem_kb: 1322 1348 ftrace_parse_errors: FTRACE_STATUS_ABI_ZERO_DATA_LENGTH 1349 } 1350 trusted_uid: 9999 1351 trusted_packet_sequence_id: 2 1352 trusted_pid: 1069 1353 } 1354 """), 1355 query=""" 1356 select name, severity, value 1357 from stats 1358 where name = "ftrace_abi_errors_skipped_zero_data_length" 1359 """, 1360 out=Csv(""" 1361 "name","severity","value" 1362 "ftrace_abi_errors_skipped_zero_data_length","info",1 1363 """)) 1364 1365 # CPU info 1366 def test_cpu_machine_id(self): 1367 return DiffTestBlueprint( 1368 trace=Path('cpu_info.textproto'), 1369 trace_modifier=TraceInjector(['cpu_info'], {'machine_id': 1001}), 1370 query=""" 1371 SELECT 1372 cpu, 1373 cluster_id, 1374 processor 1375 FROM cpu 1376 WHERE machine_id is not NULL; 1377 """, 1378 out=Csv(""" 1379 "cpu","cluster_id","processor" 1380 0,0,"AArch64 Processor rev 13 (aarch64)" 1381 1,0,"AArch64 Processor rev 13 (aarch64)" 1382 2,0,"AArch64 Processor rev 13 (aarch64)" 1383 3,0,"AArch64 Processor rev 13 (aarch64)" 1384 4,0,"AArch64 Processor rev 13 (aarch64)" 1385 5,0,"AArch64 Processor rev 13 (aarch64)" 1386 6,1,"AArch64 Processor rev 13 (aarch64)" 1387 7,1,"AArch64 Processor rev 13 (aarch64)" 1388 """)) 1389 1390 def test_cpu_freq_machine_id(self): 1391 return DiffTestBlueprint( 1392 trace=Path('cpu_info.textproto'), 1393 trace_modifier=TraceInjector(['cpu_info'], {'machine_id': 1001}), 1394 query=""" 1395 SELECT 1396 freq, 1397 GROUP_CONCAT(cpu.cpu) AS cpus 1398 FROM cpu_frequencies 1399 JOIN cpu using (ucpu) 1400 WHERE machine_id is not NULL 1401 GROUP BY freq 1402 ORDER BY freq; 1403 """, 1404 out=Path('cpu_freq.out')) 1405 1406 def test_sched_waking_instants_compact_sched_machine_id(self): 1407 return DiffTestBlueprint( 1408 trace=DataPath('compact_sched.pb'), 1409 trace_modifier=TraceInjector( 1410 ['ftrace_events', 'ftrace_stats', 'system_info'], 1411 {'machine_id': 1001}), 1412 query=""" 1413 SELECT ts, thread.name, thread.tid 1414 FROM thread_state 1415 JOIN thread USING (utid) 1416 WHERE state = 'R' AND thread.machine_id is not NULL 1417 ORDER BY ts; 1418 """, 1419 out=Path('sched_waking_instants_compact_sched.out')) 1420