diff options
author | jdesprez <jdesprez@google.com> | 2017-06-05 14:15:47 -0700 |
---|---|---|
committer | Julien Desprez <jdesprez@google.com> | 2017-06-22 17:06:54 +0000 |
commit | 9cd6c25090e5d949325292a88b77f30049987271 (patch) | |
tree | c69ce3c488d83c8f9df742f2403d4b06b1a32903 /src | |
parent | c304e037429e79e45d0b9625ad7955e96411b3aa (diff) | |
download | tradefederation-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.java | 48 | ||||
-rw-r--r-- | src/com/android/tradefed/util/HprofAllocSiteParser.java | 98 |
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)); + } + } + } +} |