blob: ebd9928764ccdf9950bf87c8de78fc3fe92d26b3 [file] [log] [blame]
Julien Desprez18bf37d2018-10-23 10:43:27 -07001/*
2 * Copyright (C) 2013 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
17package com.android.performance.tests;
18
19import com.android.ddmlib.CollectingOutputReceiver;
20import com.android.tradefed.device.DeviceNotAvailableException;
21import com.android.tradefed.device.ITestDevice;
22import com.android.tradefed.log.LogUtil.CLog;
23import com.android.tradefed.result.ITestInvocationListener;
24import com.android.tradefed.result.TestDescription;
25import com.android.tradefed.testtype.IDeviceTest;
26import com.android.tradefed.testtype.IRemoteTest;
27import com.android.tradefed.util.proto.TfMetricProtoUtil;
28
29import org.json.JSONArray;
30import org.json.JSONException;
31import org.json.JSONObject;
32import org.json.JSONTokener;
33import org.junit.Assert;
34
35import java.io.BufferedReader;
36import java.io.File;
37import java.io.FileReader;
38import java.io.IOException;
39import java.util.Collections;
40import java.util.HashMap;
41import java.util.Map;
42import java.util.concurrent.TimeUnit;
43
44/**
45 * A harness that launches Geekbench and reports result. Requires Geekbench binary and plar file in
46 * device temporary directory.
47 */
48public class GeekbenchTest implements IDeviceTest, IRemoteTest {
49
50 private static final String RUN_KEY = "geekbench3";
51 private static final int MAX_ATTEMPTS = 3;
52 private static final int TIMEOUT_MS = 10 * 60 * 1000;
53
54 private static final String DEVICE_TEMPORARY_DIR_PATH = "/data/local/tmp/";
55 private static final String GEEKBENCH_BINARY_FILENAME = "geekbench_armeabi-v7a_32";
56 private static final String GEEKBENCH_BINARY_DEVICE_PATH =
57 DEVICE_TEMPORARY_DIR_PATH + GEEKBENCH_BINARY_FILENAME;
58 private static final String GEEKBENCH_PLAR_DEVICE_PATH =
59 DEVICE_TEMPORARY_DIR_PATH + "geekbench.plar";
60 private static final String GEEKBENCH_RESULT_DEVICE_PATH =
61 DEVICE_TEMPORARY_DIR_PATH + "result.txt";
62
63 private static final String OVERALL_SCORE_NAME = "Overall Score";
64 private static final Map<String, String> METRICS_KEY_MAP = createMetricsKeyMap();
65
66 private ITestDevice mDevice;
67
68 private static Map<String, String> createMetricsKeyMap() {
69 Map<String, String> result = new HashMap<String, String>();
70 result.put(OVERALL_SCORE_NAME, "overall");
71 result.put("Integer", "integer");
72 result.put("Floating Point", "floating-point");
73 result.put("Memory", "memory");
74 return Collections.unmodifiableMap(result);
75 }
76
77 /** {@inheritDoc} */
78 @Override
79 public void setDevice(ITestDevice device) {
80 mDevice = device;
81 }
82
83 /** {@inheritDoc} */
84 @Override
85 public ITestDevice getDevice() {
86 return mDevice;
87 }
88
89 /** {@inheritDoc} */
90 @Override
91 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
92 TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
93 ITestDevice device = getDevice();
94
95 // delete old results
96 device.executeShellCommand(String.format("rm %s", GEEKBENCH_RESULT_DEVICE_PATH));
97
98 Assert.assertTrue(
99 String.format(
100 "Geekbench binary not found on device: %s", GEEKBENCH_BINARY_DEVICE_PATH),
101 device.doesFileExist(GEEKBENCH_BINARY_DEVICE_PATH));
102 Assert.assertTrue(
103 String.format(
104 "Geekbench binary not found on device: %s", GEEKBENCH_PLAR_DEVICE_PATH),
105 device.doesFileExist(GEEKBENCH_PLAR_DEVICE_PATH));
106
107 listener.testRunStarted(RUN_KEY, 0);
108 listener.testStarted(testId);
109
110 long testStartTime = System.currentTimeMillis();
111 Map<String, String> metrics = new HashMap<String, String>();
112 String errMsg = null;
113
114 // start geekbench and wait for test to complete
115 CollectingOutputReceiver receiver = new CollectingOutputReceiver();
116 device.executeShellCommand(
117 String.format(
118 "%s --no-upload --export-json %s",
119 GEEKBENCH_BINARY_DEVICE_PATH, GEEKBENCH_RESULT_DEVICE_PATH),
120 receiver,
121 TIMEOUT_MS,
122 TimeUnit.MILLISECONDS,
123 MAX_ATTEMPTS);
124 CLog.v(receiver.getOutput());
125
126 // pull result from device
127 File benchmarkReport = device.pullFile(GEEKBENCH_RESULT_DEVICE_PATH);
128 if (benchmarkReport != null) {
129 // parse result
130 CLog.i("== Geekbench 3 result ==");
131 Map<String, String> benchmarkResult = parseResultJSON(benchmarkReport);
132 if (benchmarkResult == null) {
133 errMsg = "Failed to parse Geekbench result JSON.";
134 } else {
135 metrics = benchmarkResult;
136 }
137
138 // delete results from device and host
139 benchmarkReport.delete();
140 device.executeShellCommand("rm " + GEEKBENCH_RESULT_DEVICE_PATH);
141 } else {
142 errMsg = "Geekbench report not found.";
143 }
144
145 if (errMsg != null) {
146 CLog.e(errMsg);
147 listener.testFailed(testId, errMsg);
148 listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
149 listener.testRunFailed(errMsg);
150 } else {
151 long durationMs = System.currentTimeMillis() - testStartTime;
152 listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
153 listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
154 }
155 }
156
157 private Map<String, String> parseResultJSON(File resultJson) {
158 Map<String, String> benchmarkResult = new HashMap<String, String>();
159 try {
160 BufferedReader bufferedReader = new BufferedReader(new FileReader(resultJson));
161 String line = bufferedReader.readLine();
162 bufferedReader.close();
163 if (line != null) {
164 JSONTokener tokener = new JSONTokener(line);
165 JSONObject root = new JSONObject(tokener);
166 String overallScore = root.getString("score");
167 benchmarkResult.put(METRICS_KEY_MAP.get(OVERALL_SCORE_NAME), overallScore);
168 CLog.i(String.format("Overall: %s", overallScore));
169 String overallScoreMulticore = root.getString("multicore_score");
170 benchmarkResult.put(
171 METRICS_KEY_MAP.get(OVERALL_SCORE_NAME) + "-multi", overallScoreMulticore);
172 CLog.i(String.format("Overall-multicore: %s", overallScore));
173 JSONArray arr = root.getJSONArray("sections");
174 for (int i = 0; i < arr.length(); i++) {
175 JSONObject section = arr.getJSONObject(i);
176 String sectionName = section.getString("name");
177 String sectionScore = section.getString("score");
178 String sectionScoreMulticore = section.getString("multicore_score");
179 if (METRICS_KEY_MAP.containsKey(sectionName)) {
180 CLog.i(String.format("%s: %s", sectionName, sectionScore));
181 CLog.i(
182 String.format(
183 "%s-multicore: %s", sectionName, sectionScoreMulticore));
184 benchmarkResult.put(METRICS_KEY_MAP.get(sectionName), sectionScore);
185 CLog.i(
186 String.format(
187 "%s-multicore: %s", sectionName, sectionScoreMulticore));
188 benchmarkResult.put(
189 METRICS_KEY_MAP.get(sectionName) + "-multi", sectionScoreMulticore);
190 }
191 }
192 }
193 } catch (IOException e) {
194 CLog.e("Geekbench3 result file not found.");
195 return null;
196 } catch (JSONException e) {
197 CLog.e("Error parsing Geekbench3 JSON result.");
198 return null;
199 }
200 return benchmarkResult;
201 }
202}