1#!/usr/bin/env python3 2# 3# Copyright (C) 2021 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import os 18import re 19import tempfile 20from typing import List, Optional, Set 21 22from . test_utils import TestBase, TestHelper 23from simpleperf_utils import remove 24 25 26class TestReportSample(TestBase): 27 def get_record_data_string(self, record_file: str, options: Optional[List[str]] = None): 28 args = ['report_sample.py', '-i', TestHelper.testdata_path(record_file)] 29 if options: 30 args += options 31 report = self.run_cmd(args, return_output=True) 32 return report.replace('\r', '') 33 34 def test_no_flags(self): 35 got = self.get_record_data_string('perf_display_bitmaps.data') 36 with open(TestHelper.testdata_path('perf_display_bitmaps.perf-script')) as f: 37 want = f.read() 38 self.assertEqual(got, want) 39 40 def test_output_flag(self): 41 # Test short form flag. 42 remove('some.output') 43 got = self.get_record_data_string('perf_display_bitmaps.data', 44 ['-o', 'some.output']) 45 self.assertEqual(got, '') 46 self.check_exist(filename='some.output') 47 48 # Test long form flag 49 remove("some.output") 50 got = self.get_record_data_string('perf_display_bitmaps.data', 51 ['--output_file', 'some.output']) 52 self.assertEqual(got, '') 53 self.check_exist(filename="some.output") 54 55 # Verify that the output file contains expected data 56 with open(TestHelper.testdata_path('perf_display_bitmaps.perf-script')) as f: 57 want = f.read() 58 with open('some.output') as f: 59 got = f.read() 60 self.assertEqual(got, want) 61 62 # Verify that an output spec of '-' is stdout 63 remove("some.output") 64 got = self.get_record_data_string('perf_display_bitmaps.data', ['-o', '-']) 65 self.assertEqual(got, want) 66 67 def test_comm_filter_to_renderthread(self): 68 got = self.get_record_data_string('perf_display_bitmaps.data', ['--comm', 'RenderThread']) 69 self.assertIn('RenderThread', got) 70 self.assertNotIn('com.example.android.displayingbitmaps', got) 71 72 with open(TestHelper.testdata_path('perf_display_bitmaps.RenderThread.perf-script')) as f: 73 want = f.read() 74 self.assertEqual(got, want) 75 76 def test_comm_filter_to_ui_thread(self): 77 got = self.get_record_data_string('perf_display_bitmaps.data', [ 78 '--comm', 'com.example.android.displayingbitmaps']) 79 self.assertIn('com.example.android.displayingbitmaps', got) 80 self.assertNotIn('RenderThread', got) 81 with open(TestHelper.testdata_path('perf_display_bitmaps.UiThread.perf-script')) as f: 82 want = f.read() 83 self.assertEqual(got, want) 84 85 def test_header(self): 86 got = self.get_record_data_string('perf_display_bitmaps.data', ['--header']) 87 with open(TestHelper.testdata_path('perf_display_bitmaps.header.perf-script')) as f: 88 want = f.read() 89 self.assertEqual(got, want) 90 91 def test_trace_offcpu(self): 92 got = self.get_record_data_string('perf_with_trace_offcpu_v2.data', [ 93 '--trace-offcpu', 'on-cpu']) 94 self.assertIn('cpu-clock:u', got) 95 self.assertNotIn('sched:sched_switch', got) 96 97 def test_sample_filters(self): 98 def get_threads_for_filter(filter: str) -> Set[int]: 99 report = self.get_record_data_string('perf_display_bitmaps.data', filter.split()) 100 pattern = re.compile(r'\s+31850/(\d+)\s+') 101 threads = set() 102 for m in re.finditer(pattern, report): 103 threads.add(int(m.group(1))) 104 return threads 105 106 self.assertNotIn(31850, get_threads_for_filter('--exclude-pid 31850')) 107 self.assertIn(31850, get_threads_for_filter('--include-pid 31850')) 108 self.assertIn(31850, get_threads_for_filter('--pid 31850')) 109 self.assertNotIn(31881, get_threads_for_filter('--exclude-tid 31881')) 110 self.assertIn(31881, get_threads_for_filter('--include-tid 31881')) 111 self.assertIn(31881, get_threads_for_filter('--tid 31881')) 112 self.assertNotIn(31881, get_threads_for_filter( 113 '--exclude-process-name com.example.android.displayingbitmaps')) 114 self.assertIn(31881, get_threads_for_filter( 115 '--include-process-name com.example.android.displayingbitmaps')) 116 self.assertNotIn(31850, get_threads_for_filter( 117 '--exclude-thread-name com.example.android.displayingbitmaps')) 118 self.assertIn(31850, get_threads_for_filter( 119 '--include-thread-name com.example.android.displayingbitmaps')) 120 121 with tempfile.NamedTemporaryFile('w', delete=False) as filter_file: 122 filter_file.write('GLOBAL_BEGIN 684943449406175\nGLOBAL_END 684943449406176') 123 filter_file.flush() 124 threads = get_threads_for_filter('--filter-file ' + filter_file.name) 125 self.assertIn(31881, threads) 126 self.assertNotIn(31850, threads) 127 os.unlink(filter_file.name) 128 129 def test_show_art_frames(self): 130 art_frame_str = 'art::interpreter::DoCall' 131 report = self.get_record_data_string('perf_with_interpreter_frames.data') 132 self.assertNotIn(art_frame_str, report) 133 report = self.get_record_data_string( 134 'perf_with_interpreter_frames.data', ['--show-art-frames']) 135 self.assertIn(art_frame_str, report) 136