1 /* 2 * Copyright (C) 2012 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 at 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 */ 16 17 package com.android.framework.tests; 18 19 import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner; 20 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; 21 import com.android.tradefed.device.DeviceNotAvailableException; 22 import com.android.tradefed.device.ITestDevice; 23 import com.android.tradefed.log.LogUtil.CLog; 24 import com.android.tradefed.result.CollectingTestListener; 25 import com.android.tradefed.result.ITestInvocationListener; 26 import com.android.tradefed.result.TestResult; 27 import com.android.tradefed.testtype.IDeviceTest; 28 import com.android.tradefed.testtype.IRemoteTest; 29 import com.android.tradefed.util.IRunUtil; 30 import com.android.tradefed.util.RunUtil; 31 import com.android.tradefed.util.proto.TfMetricProtoUtil; 32 33 import com.google.common.collect.ImmutableMap; 34 35 import org.junit.Assert; 36 37 import java.util.ArrayList; 38 import java.util.Collection; 39 import java.util.HashMap; 40 import java.util.List; 41 import java.util.Map; 42 import java.util.concurrent.TimeUnit; 43 44 /** 45 * Test that measures the average latency of foreground and background operations in various 46 * scenarios. 47 */ 48 public class FrameworkPerfTest implements IRemoteTest, IDeviceTest { 49 50 private static final String TEST_PACKAGE_NAME = "com.android.frameworkperffg"; 51 private static final String TEST_RUNNER_NAME = "android.test.InstrumentationTestRunner"; 52 private static final int PERF_TIMEOUT = 30 * 60 * 1000; // 30 minutes timeout 53 private static final int PRE_TEST_SLEEP_MS = 30 * 1000; // 30s sleep prior to test start 54 55 private static final String LAYOUT = "frameworkfg_perf_layout"; 56 private static final String GC = "frameworkfg_perf_gc"; 57 private static final String XML = "frameworkfg_perf_xml"; 58 private static final String BITMAP = "frameworkfg_perf_bitmap"; 59 private static final String FILE = "frameworkfg_perf_file"; 60 private static final String OTHER = "frameworkfg_perf_other"; 61 private static final String MAP = "frameworkfg_perf_map"; 62 private static final ImmutableMap<String, String> TEST_TAG_MAP = 63 new ImmutableMap.Builder<String, String>() 64 .put("ReadFile", FILE) 65 .put("CreateWriteFile", FILE) 66 .put("CreateWriteSyncFile", FILE) 67 .put("WriteFile", FILE) 68 .put("CreateFile", FILE) 69 .put("CreateRecycleBitmap", BITMAP) 70 .put("LoadLargeScaledBitmap", BITMAP) 71 .put("LoadSmallScaledBitmap", BITMAP) 72 .put("LoadRecycleSmallBitmap", BITMAP) 73 .put("LoadLargeBitmap", BITMAP) 74 .put("CreateBitmap", BITMAP) 75 .put("LoadSmallBitmap", BITMAP) 76 .put("LayoutInflaterButton", LAYOUT) 77 .put("LayoutInflaterImageButton", LAYOUT) 78 .put("LayoutInflaterLarge", LAYOUT) 79 .put("LayoutInflaterView", LAYOUT) 80 .put("LayoutInflater", LAYOUT) 81 .put("Gc", GC) 82 .put("PaintGc", GC) 83 .put("ObjectGc", GC) 84 .put("FinalizingGc", GC) 85 .put("OpenXmlRes", XML) 86 .put("ParseXmlRes", XML) 87 .put("ReadXmlAttrs", XML) 88 .put("ParseLargeXmlRes", XML) 89 .put("Sched", OTHER) 90 .put("CPU", OTHER) 91 .put("MethodCall", OTHER) 92 .put("Ipc", OTHER) 93 .put("GrowLargeArrayMap", MAP) 94 .put("GrowLargeHashMap", MAP) 95 .put("LookupSmallHashMap", MAP) 96 .put("LookupSmallArrayMap", MAP) 97 .put("LookupTinyHashMap", MAP) 98 .put("GrowTinyHashMap", MAP) 99 .put("LookupLargeHashMap", MAP) 100 .put("LookupTinyArrayMap", MAP) 101 .put("LookupLargeArrayMap", MAP) 102 .put("GrowTinyArrayMap", MAP) 103 .put("GrowSmallHashMap", MAP) 104 .put("GrowSmallArrayMap", MAP) 105 .build(); 106 107 private ITestDevice mTestDevice = null; 108 109 /** {@inheritDoc} */ 110 @Override run(ITestInvocationListener listener)111 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 112 Assert.assertNotNull(mTestDevice); 113 114 getDevice().reboot(); 115 getRunUtil().sleep(PRE_TEST_SLEEP_MS); 116 IRemoteAndroidTestRunner runner = 117 new RemoteAndroidTestRunner( 118 TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice()); 119 runner.setMaxTimeToOutputResponse(PERF_TIMEOUT, TimeUnit.MILLISECONDS); 120 121 CollectingTestListener collectingListener = new CollectingTestListener(); 122 Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, collectingListener)); 123 124 Collection<TestResult> testResultsCollection = 125 collectingListener.getCurrentRunResults().getTestResults().values(); 126 127 List<TestResult> testResults = new ArrayList<TestResult>(testResultsCollection); 128 129 if (!testResults.isEmpty()) { 130 Map<String, String> testMetrics = testResults.get(0).getMetrics(); 131 if (testMetrics != null) { 132 reportMetrics(listener, testMetrics); 133 } 134 } 135 } 136 137 /** {@inheritDoc} */ 138 @Override getDevice()139 public ITestDevice getDevice() { 140 return mTestDevice; 141 } 142 143 /** {@inheritDoc} */ 144 @Override setDevice(ITestDevice device)145 public void setDevice(ITestDevice device) { 146 mTestDevice = device; 147 } 148 149 /** 150 * Report run metrics by creating an empty test run to stick them in. 151 * 152 * @param listener The {@link ITestInvocationListener} of test results 153 * @param metrics The {@link Map} that contains metrics for the given test 154 */ reportMetrics(ITestInvocationListener listener, Map<String, String> metrics)155 private void reportMetrics(ITestInvocationListener listener, Map<String, String> metrics) { 156 // Parse out only averages 157 Map<String, Map<String, String>> allMetrics = new HashMap<String, Map<String, String>>(); 158 for (String key : metrics.keySet()) { 159 String testLabel = TEST_TAG_MAP.get(key); 160 if (testLabel == null) { 161 testLabel = OTHER; 162 } 163 if (!allMetrics.containsKey(testLabel)) { 164 allMetrics.put(testLabel, new HashMap<String, String>()); 165 } 166 allMetrics.get(testLabel).put(key, metrics.get(key)); 167 } 168 169 for (String section : allMetrics.keySet()) { 170 Map<String, String> sectionMetrics = allMetrics.get(section); 171 if (sectionMetrics != null && !sectionMetrics.isEmpty()) { 172 for (String section2 : sectionMetrics.keySet()) { 173 CLog.i("%s ::'%s' : %s", section, section2, sectionMetrics.get(section2)); 174 } 175 listener.testRunStarted(section, 0); 176 listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(sectionMetrics)); 177 } 178 } 179 } 180 getRunUtil()181 IRunUtil getRunUtil() { 182 return RunUtil.getDefault(); 183 } 184 } 185