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