1# Copyright (C) 2024 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import os 16import perfetto.bigtrace.api 17import subprocess 18import unittest 19 20from perfetto.common.exceptions import PerfettoException 21 22class BigtraceTest(unittest.TestCase): 23 24 @classmethod 25 def setUpClass(self): 26 self.root_dir = os.environ["ROOT_DIR"] 27 self.worker_1 = subprocess.Popen( 28 [os.environ["WORKER_PATH"], "-s", "127.0.0.1:5052"]) 29 self.worker_2 = subprocess.Popen( 30 [os.environ["WORKER_PATH"], "-s", "127.0.0.1:5053"]) 31 self.worker_3 = subprocess.Popen( 32 [os.environ["WORKER_PATH"], "-s", "127.0.0.1:5054"]) 33 self.orchestrator = subprocess.Popen([ 34 os.environ["ORCHESTRATOR_PATH"], "-n", "3", "-w", "127.0.0.1", "-p", 35 "5052" 36 ]) 37 self.client = perfetto.bigtrace.api.Bigtrace( 38 wait_for_ready_for_testing=True) 39 40 @classmethod 41 def tearDownClass(self): 42 self.worker_1.kill() 43 self.worker_1.wait() 44 self.worker_2.kill() 45 self.worker_2.wait() 46 self.worker_3.kill() 47 self.worker_3.wait() 48 self.orchestrator.kill() 49 self.orchestrator.wait() 50 del self.client 51 52 def test_simple_valid_request(self): 53 result = self.client.query([ 54 f"/local/{self.root_dir}/test/data/api24_startup_cold.perfetto-trace", 55 f"/local/{self.root_dir}/test/data/api24_startup_hot.perfetto-trace" 56 ], "SELECT count(1) as count FROM slice LIMIT 5") 57 58 self.assertEqual( 59 result.loc[result['_trace_address'] == 60 f"/local/{self.root_dir}/test/data/" 61 "api24_startup_cold.perfetto-trace", 'count'].iloc[0], 9726) 62 self.assertEqual( 63 result.loc[result['_trace_address'] == 64 f"/local/{self.root_dir}/test/data/" 65 "api24_startup_hot.perfetto-trace", 'count'].iloc[0], 5726) 66 67 def test_include_perfetto_module_query(self): 68 traces = [ 69 f"/local/{self.root_dir}/test/data/android_startup_real.perfetto_trace" 70 ] 71 result = self.client.query( 72 traces, "INCLUDE PERFETTO MODULE android.binder; " 73 "SELECT client_process FROM android_binder_txns") 74 self.assertEqual(len(result), 15874) 75 self.assertEqual(len(result.columns), 2) 76 77 def test_empty_trace_list(self): 78 with self.assertRaises(PerfettoException): 79 result = self.client.query([], "SELECT count(1) FROM slice LIMIT 5") 80 81 def test_empty_sql_string(self): 82 with self.assertRaises(PerfettoException): 83 result = self.client.query([ 84 f"/local/{self.root_dir}/test/data/api24_startup_cold.perfetto-trace", 85 f"/local/{self.root_dir}/test/data/api24_startup_hot.perfetto-trace" 86 ], "") 87 88 def test_empty_trace_string(self): 89 with self.assertRaises(PerfettoException): 90 result = self.client.query([""], "SELECT count(1) FROM slice LIMIT 5") 91 92 def test_prefix_present_no_trace_path(self): 93 with self.assertRaises(PerfettoException): 94 result = self.client.query(["/local"], 95 "SELECT count(1) FROM slice LIMIT 5") 96 97 def test_invalid_prefix_format(self): 98 with self.assertRaises(PerfettoException): 99 result = self.client.query([ 100 f"??{self.root_dir}/test/data/api24_startup_cold.perfetto-trace", 101 ], "") 102 103 def test_invalid_prefix_name(self): 104 with self.assertRaises(PerfettoException): 105 result = self.client.query([ 106 f"/badprefix/{self.root_dir}/test/data/" 107 "api24_startup_cold.perfetto-trace" 108 ], "SELECT count(1) FROM slice LIMIT 5"), 109 110 def test_no_prefix(self): 111 with self.assertRaises(PerfettoException): 112 result = self.client.query( 113 [f"/{self.root_dir}/test/data/api24_startup_cold.perfetto-trace"], 114 "SELECT count(1) FROM slice LIMIT 5") 115 116 def test_unauthenticated_gcs(self): 117 with self.assertRaises(PerfettoException): 118 result = self.client.query( 119 [f"/gcs/trace_bucket_example/o/api24_startup_cold.perfetto-trace"], 120 "SELECT count(1) FROM slice LIMIT 5") 121