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 {BlockingCallMetricData} from './metricUtils'; 16import {pinBlockingCallHandlerInstance} from './pinBlockingCall'; 17 18const validMetricsTest: { 19 inputMetric: string; 20 expectedOutput: BlockingCallMetricData; 21}[] = [ 22 { 23 inputMetric: 24 'perfetto_android_blocking_call-cuj-name-com.google.android.apps.nexuslauncher-name-TASKBAR_EXPAND-blocking_calls-name-animation-total_dur_ms-mean', 25 expectedOutput: { 26 process: 'com.google.android.apps.nexuslauncher', 27 cujName: 'TASKBAR_EXPAND', 28 blockingCallName: 'animation', 29 aggregation: 'total_dur_ms-mean', 30 }, 31 }, 32 33 { 34 inputMetric: 35 'perfetto_android_blocking_call-cuj-name-com.android.systemui-name-NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse-blocking_calls-name-AIDL::java::IPackageManager::isProtectedBroadcast::server-cnt-mean', 36 expectedOutput: { 37 process: 'com.android.systemui', 38 cujName: 'NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse', 39 blockingCallName: 40 'AIDL::java::IPackageManager::isProtectedBroadcast::server', 41 aggregation: 'cnt-mean', 42 }, 43 }, 44 { 45 inputMetric: 46 'perfetto_android_blocking_call-cuj-name-com.android.systemui-name-SPLASHSCREEN_EXIT_ANIM-blocking_calls-name-AIDL::java::IPackageManager::isProtectedBroadcast::server-cnt-mean', 47 expectedOutput: { 48 process: 'com.android.systemui', 49 cujName: 'SPLASHSCREEN_EXIT_ANIM', 50 blockingCallName: 51 'AIDL::java::IPackageManager::isProtectedBroadcast::server', 52 aggregation: 'cnt-mean', 53 }, 54 }, 55 // test cases for blocking call per-frame metrics. 56 { 57 inputMetric: 58 'perfetto_android_blocking_call_per_frame-cuj-name-com.android.systemui-name-LOCKSCREEN_TRANSITION_FROM_AOD::DEFAULT-blocking_calls-name-Handler: android.widget.DateTimeView-mean_cnt_per_frame-mean', 59 expectedOutput: { 60 process: 'com.android.systemui', 61 cujName: 'LOCKSCREEN_TRANSITION_FROM_AOD::DEFAULT', 62 blockingCallName: 'Handler: android.widget.DateTimeView', 63 aggregation: 'mean_cnt_per_frame-mean', 64 }, 65 }, 66 { 67 inputMetric: 68 'perfetto_android_blocking_call_per_frame-cuj-name-com.google.android.apps.nexuslauncher-name-TASKBAR_EXPAND::Manually unstashed-blocking_calls-name-Handler: android.view.View-max_dur_per_frame_ns-mean', 69 expectedOutput: { 70 process: 'com.google.android.apps.nexuslauncher', 71 cujName: 'TASKBAR_EXPAND::Manually unstashed', 72 blockingCallName: 73 'Handler: android.view.View', 74 aggregation: 'max_dur_per_frame_ns-mean', 75 }, 76 }, 77 { 78 inputMetric: 79 'perfetto_android_blocking_call_per_frame-cuj-name-com.android.systemui-name-NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse-blocking_calls-name-input-mean_dur_per_frame_ns-max', 80 expectedOutput: { 81 process: 'com.android.systemui', 82 cujName: 'NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse', 83 blockingCallName: 84 'input', 85 aggregation: 'mean_dur_per_frame_ns-max', 86 }, 87 }, 88]; 89 90const invalidMetricsTest: string[] = [ 91 'perfetto_ft_launcher-missed_sf_frames-mean', 92 'perfetto_cuj_launcher-RECENTS_SCROLLING-counter_metrics-missed_sf_frames-mean', 93]; 94 95const tester = pinBlockingCallHandlerInstance; 96 97describe('testMetricParser_match', () => { 98 it('parses metrics and returns expected data', () => { 99 for (const testCase of validMetricsTest) { 100 const parsedData = tester.match(testCase.inputMetric); 101 // without this explicit check, undefined also passes the test 102 expect(parsedData).toBeDefined(); 103 if (parsedData) { 104 expect(parsedData).toEqual(testCase.expectedOutput); 105 } 106 } 107 }); 108 it('parses metrics and returns undefined', () => { 109 for (const testCase of invalidMetricsTest) { 110 const parsedData = tester.match(testCase); 111 112 expect(parsedData).toBeUndefined(); 113 } 114 }); 115}); 116