add performance tests to tf.
Change-Id: I6be0ea28b7edf63f49f0af28908891f99050be8b
diff --git a/src/com/android/performance/tests/StartupMetricsTest.java b/src/com/android/performance/tests/StartupMetricsTest.java
index 3c281e4..945e451 100644
--- a/src/com/android/performance/tests/StartupMetricsTest.java
+++ b/src/com/android/performance/tests/StartupMetricsTest.java
@@ -16,13 +16,22 @@
package com.android.performance.tests;
-import com.android.ddmlib.Log;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
import com.android.tradefed.testtype.IDeviceTest;
import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.util.brillopad.BugreportParser;
+import com.android.tradefed.util.brillopad.ItemList;
+import com.android.tradefed.util.brillopad.item.GenericMapItem;
+import com.android.tradefed.util.brillopad.item.IItem;
+import com.android.tradefed.util.brillopad.section.MemInfoParser;
+import com.android.tradefed.util.brillopad.section.ProcRankParser;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -32,7 +41,7 @@
* Tests to gather device metrics from during and immediately after boot
*/
public class StartupMetricsTest implements IDeviceTest, IRemoteTest {
- private static final String LOG_TAG = "StartupMetricsTest";
+ public static final String BUGREPORT_LOG_NAME = "bugreport_startup.txt";
ITestDevice mTestDevice = null;
@@ -41,10 +50,15 @@
Assert.assertNotNull(mTestDevice);
executeRebootTest(listener);
+ fetchBugReportMetrics(listener);
+ // TODO: pass build metrics? does it make sense to have it here?
}
/**
- * Check how long the device takes to come online and become available after a reboot
+ * Check how long the device takes to come online and become available after
+ * a reboot
+ *
+ * @param listener the {@link ITestInvocationListener} of test results
*/
void executeRebootTest(ITestInvocationListener listener) throws DeviceNotAvailableException {
Map<String, String> runMetrics = new HashMap<String, String>();
@@ -57,27 +71,140 @@
long offlineDuration = onlineTime - startTime;
long unavailDuration = availableTime - startTime;
- Log.d(LOG_TAG, String.format("Reboot: %d millis until online, %d until available",
- offlineDuration, unavailDuration));
- runMetrics.put("offline", Long.toString(offlineDuration));
- runMetrics.put("unavail", Long.toString(unavailDuration));
+ CLog.d("Reboot: %d millis until online, %d until available",
+ offlineDuration, unavailDuration);
+ runMetrics.put("online", Long.toString(offlineDuration));
+ runMetrics.put("bootcomplete", Long.toString(unavailDuration));
- reportMetrics(listener, "reboot", runMetrics);
+ reportMetrics(listener, "boottime", runMetrics);
+ }
+
+ /**
+ * Fetch proc rank metrics from the bugreport after reboot
+ *
+ * @param listener the {@link ITestInvocationListener} of test results
+ */
+ @SuppressWarnings("unchecked")
+ void fetchBugReportMetrics(ITestInvocationListener listener) {
+ BugreportParser parser = new BugreportParser();
+ ItemList bugreport = null;
+ // Retrieve bugreport
+ InputStreamSource bugSource = mTestDevice.getBugreport();
+ try {
+ listener.testLog(BUGREPORT_LOG_NAME, LogDataType.TEXT, bugSource);
+ bugreport = parser.parse(bugSource);
+ } catch (IOException e) {
+ Assert.fail(String.format("Failed to fetch and parse bugreport for device %s: %s",
+ mTestDevice.getSerialNumber(), e));
+ } finally {
+ bugSource.cancel();
+ }
+ // Process meminfo information and post it to the dashboard
+ IItem item = bugreport.getFirstItemByType(MemInfoParser.SECTION_NAME);
+ if (item != null) {
+ Map<String, String> memInfoMap = convertMap((GenericMapItem<String, Integer>) item);
+ reportMetrics(listener, "startup-meminfo", memInfoMap);
+ }
+
+ // Process procrank information and post it to the dashboard
+ item = bugreport.getFirstItemByType(ProcRankParser.SECTION_NAME);
+ if (item != null) {
+ Map <String, Map<String, Integer>> procRankMap =
+ (GenericMapItem<String, Map<String, Integer>>) item;
+ parseProcRankMap(listener, procRankMap);
+ }
+ }
+
+ /**
+ * Helper method to convert Map<String, Integer> to Map<String, String>
+ *
+ * @param input the {@link Map} to convert from
+ * @return output the converted {@link Map}
+ */
+ Map<String, String> convertMap(Map<String, Integer> input) {
+ Map<String, String> output = new HashMap<String, String>();
+ for (Map.Entry<String, Integer> entry : input.entrySet()) {
+ output.put(entry.getKey(), entry.getValue().toString());
+ }
+ return output;
}
/**
* Report run metrics by creating an empty test run to stick them in
* <p />
* Exposed for unit testing
+ *
+ * @param listener the {@link ITestInvocationListener} of test results
+ * @param runName the test name
+ * @param metrics the {@link Map} that contains metrics for the given test
*/
void reportMetrics(ITestInvocationListener listener, String runName,
Map<String, String> metrics) {
// Create an empty testRun to report the parsed runMetrics
- Log.d(LOG_TAG, String.format("About to report metrics: %s", metrics));
+ CLog.d("About to report metrics: %s", metrics);
listener.testRunStarted(runName, 0);
listener.testRunEnded(0, metrics);
}
+ /**
+ * Aggregates the procrank data by the pss, rss, and uss values.
+ *
+ * @param listener the {@link ITestInvocationListener} of test results
+ * @param procRankMap the {@link Map} parsed from brillopad for the procrank
+ * section
+ */
+ void parseProcRankMap(ITestInvocationListener listener,
+ Map<String, Map<String, Integer>> procRankMap) {
+ // final maps for pss, rss, and uss.
+ Map<String, String> pssOutput = new HashMap<String, String>();
+ Map<String, String> rssOutput = new HashMap<String, String>();
+ Map<String, String> ussOutput = new HashMap<String, String>();
+ // total number of processes.
+ Integer numProcess = 0;
+ // aggregate pss, rss, uss across all processes.
+ Integer pssTotal = 0;
+ Integer rssTotal = 0;
+ Integer ussTotal = 0;
+
+ for (Map.Entry<String, Map<String, Integer>> entry : procRankMap.entrySet()) {
+ // Skip empty processes.
+ if (entry.getKey() == null)
+ continue;
+ if (entry.getKey().length() == 0)
+ continue;
+
+ numProcess++;
+ Map<String, Integer> valueMap = entry.getValue();
+ Integer pss = valueMap.get("Pss");
+ Integer rss = valueMap.get("Rss");
+ Integer uss = valueMap.get("Uss");
+ if (pss != null) {
+ pssTotal += pss;
+ pssOutput.put(entry.getKey(), pss.toString());
+ }
+ if (rss != null) {
+ rssTotal += rss;
+ rssOutput.put(entry.getKey(), rss.toString());
+ }
+ if (uss != null) {
+ ussTotal += pss;
+ ussOutput.put(entry.getKey(), uss.toString());
+ }
+ }
+ // Add aggregation data.
+ pssOutput.put("count", numProcess.toString());
+ pssOutput.put("total", pssTotal.toString());
+ rssOutput.put("count", numProcess.toString());
+ rssOutput.put("total", rssTotal.toString());
+ ussOutput.put("count", numProcess.toString());
+ ussOutput.put("total", ussTotal.toString());
+
+ // Report metrics to dashboard
+ reportMetrics(listener, "startup-procrank-pss", pssOutput);
+ reportMetrics(listener, "startup-procrank-rss", rssOutput);
+ reportMetrics(listener, "startup-procrank-uss", ussOutput);
+ }
+
@Override
public void setDevice(ITestDevice device) {
mTestDevice = device;
@@ -88,4 +215,3 @@
return mTestDevice;
}
}
-