aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjdesprez <jdesprez@google.com>2017-06-05 14:15:47 -0700
committerJulien Desprez <jdesprez@google.com>2017-06-22 17:06:54 +0000
commit9cd6c25090e5d949325292a88b77f30049987271 (patch)
treec69ce3c488d83c8f9df742f2403d4b06b1a32903 /src
parentc304e037429e79e45d0b9625ad7955e96411b3aa (diff)
downloadtradefederation-9cd6c25090e5d949325292a88b77f30049987271.tar.gz
Parse hprof alloc sites after runsoreo-dev
Parse and report hprof allocation sites to get some memory information about the run. Report them as metrics. Test: unit tests, /tradefed.sh run google/tf/local-unit-launcher --template:map reporters=google/template/reporters/hybrid-reporters --hprof-heap-memory --max-run-time 30m --test-tag hprof-tf-local --folder-path . Bug: 37777349 Change-Id: I58e84c36696fafd1d905fcb15f26e10cfbf1ca91 (cherry picked from commit ceedb3941ac0c07b9571f0fc12fb994924918eb1)
Diffstat (limited to 'src')
-rw-r--r--src/com/android/tradefed/testtype/TfTestLauncher.java48
-rw-r--r--src/com/android/tradefed/util/HprofAllocSiteParser.java98
2 files changed, 139 insertions, 7 deletions
diff --git a/src/com/android/tradefed/testtype/TfTestLauncher.java b/src/com/android/tradefed/testtype/TfTestLauncher.java
index c5cc4eca7..87aae1f17 100644
--- a/src/com/android/tradefed/testtype/TfTestLauncher.java
+++ b/src/com/android/tradefed/testtype/TfTestLauncher.java
@@ -26,6 +26,7 @@ import com.android.tradefed.result.LogDataType;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.HprofAllocSiteParser;
import com.android.tradefed.util.RunUtil;
import com.android.tradefed.util.StreamUtil;
@@ -209,13 +210,7 @@ public class TfTestLauncher extends SubprocessTfLauncher {
}
}
if (mEnableHprof) {
- InputStreamSource memory = null;
- try {
- memory = new FileInputStreamSource(mHprofFile);
- listener.testLog("hprof", LogDataType.TEXT, memory);
- } finally {
- StreamUtil.cancel(memory);
- }
+ logHprofResults(mHprofFile, listener);
}
if (mTmpDir != null) {
@@ -359,4 +354,43 @@ public class TfTestLauncher extends SubprocessTfLauncher {
listener.testEnded(tid, Collections.emptyMap());
listener.testRunEnded(0, Collections.emptyMap());
}
+
+ /**
+ * Helper to log and report as metric the hprof data.
+ *
+ * @param hprofFile file containing the Hprof report
+ * @param listener the {@link ITestInvocationListener} where to report the test.
+ */
+ private void logHprofResults(File hprofFile, ITestInvocationListener listener) {
+ if (hprofFile == null) {
+ CLog.w("Hprof file was null. Skipping parsing.");
+ return;
+ }
+ if (!hprofFile.exists()) {
+ CLog.w("Hprof file %s was not found. Skipping parsing.", hprofFile.getAbsolutePath());
+ return;
+ }
+ InputStreamSource memory = null;
+ try {
+ memory = new FileInputStreamSource(hprofFile);
+ listener.testLog("hprof", LogDataType.TEXT, memory);
+ } finally {
+ StreamUtil.cancel(memory);
+ }
+ HprofAllocSiteParser parser = new HprofAllocSiteParser();
+ try {
+ Map<String, String> results = parser.parse(hprofFile);
+ if (results.isEmpty()) {
+ CLog.d("No allocation site found from hprof file");
+ return;
+ }
+ listener.testRunStarted("hprofAllocSites", 1);
+ TestIdentifier tid = new TestIdentifier("hprof", "allocationSites");
+ listener.testStarted(tid);
+ listener.testEnded(tid, results);
+ listener.testRunEnded(0, Collections.emptyMap());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/src/com/android/tradefed/util/HprofAllocSiteParser.java b/src/com/android/tradefed/util/HprofAllocSiteParser.java
new file mode 100644
index 000000000..53519b726
--- /dev/null
+++ b/src/com/android/tradefed/util/HprofAllocSiteParser.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tradefed.util;
+
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/** Helper class to parse info from an Allocation Sites section of hprof reports. */
+public class HprofAllocSiteParser {
+
+ private static final String ALLOC_SITES_START_PATTERN = "SITES BEGIN";
+ private static final String ALLOC_SITES_END_PATTERN = "SITES END";
+ private boolean mHasAllocSiteStarted = false;
+ // format:
+ // percent live alloc'ed stack class
+ // rank self accum bytes objs bytes objs trace name
+ // 1 12.24% 12.24% 12441616 1 12441616 1 586322 byte[]
+ private static final Pattern RANK_PATTERN =
+ Pattern.compile(
+ "(\\s+)([0-9]*)(\\s+)([0-9]*\\.?[0-9]+%)(\\s+)([0-9]*\\.?[0-9]+%)(\\s+)"
+ + "([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)"
+ + "(\\s+)(.*)");
+
+ /**
+ * Parse a text hprof report.
+ *
+ * @param hprofReport file containing the hprof report.
+ * @return a Map containing the results
+ */
+ public Map<String, String> parse(File hprofReport) throws IOException {
+ Map<String, String> results = new HashMap<>();
+ if (hprofReport == null || !hprofReport.exists()) {
+ return results;
+ }
+ internalParse(hprofReport, results);
+ return results;
+ }
+
+ /**
+ * Actual parsing line by line of the report to extract information.
+ *
+ * @param report the {@link File} containing the hprof report.
+ * @param currentRes the {@link Map} where the allocation sites will be stored.
+ */
+ private void internalParse(File report, Map<String, String> currentRes) throws IOException {
+ try (BufferedReader br = new BufferedReader(new FileReader(report))) {
+ for (String line; (line = br.readLine()) != null; ) {
+ handleAllocSites(line, currentRes);
+ }
+ }
+ }
+
+ /** Handles the allocation sites in the hprof report. */
+ private void handleAllocSites(String line, Map<String, String> currentRes) {
+ if (line.startsWith(ALLOC_SITES_START_PATTERN)) {
+ mHasAllocSiteStarted = true;
+ } else if (line.startsWith(ALLOC_SITES_END_PATTERN)) {
+ mHasAllocSiteStarted = false;
+ } else if (mHasAllocSiteStarted) {
+ Matcher m = RANK_PATTERN.matcher(line);
+ if (m.find()) {
+ CLog.d(
+ "Rank %s-%s-%s-%s-%s-%s-%s-%s-%s",
+ m.group(2),
+ m.group(4),
+ m.group(6),
+ m.group(8),
+ m.group(10),
+ m.group(12),
+ m.group(14),
+ m.group(16),
+ m.group(18));
+ currentRes.put(String.format("Rank%s", m.group(2)), m.group(12));
+ }
+ }
+ }
+}