1 /*
2  * Copyright (C) 2011 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 package com.android.tradefed.testtype;
17 
18 import com.android.ddmlib.IShellOutputReceiver;
19 import com.android.ddmlib.MultiLineReceiver;
20 import com.android.tradefed.log.LogUtil.CLog;
21 
22 import java.text.DecimalFormat;
23 import java.text.ParseException;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 
27 /**
28 * A {@link IShellOutputReceiver} that parses the benchmark test data output, collecting metrics on
29 * average time per operation.
30 * <p/>
31 * Looks for the following output
32 * <p/>
33 * <code>
34 * Time per iteration min: X avg: Y max: Z
35 * </code>
36 */
37 public class NativeBenchmarkTestParser extends MultiLineReceiver {
38 
39     // just parse any string
40     private final static String FLOAT_STRING = "\\s*(.*)\\s*";
41     private final static String COMPLETE_STRING = String.format(
42             "Time per iteration min:%savg:%smax:%s", FLOAT_STRING, FLOAT_STRING, FLOAT_STRING);
43     private final static Pattern COMPLETE_PATTERN = Pattern.compile(COMPLETE_STRING);
44 
45     private final String mTestRunName;
46     private boolean mIsCanceled = false;
47     private double mMinOpTime = 0;
48     private double mAvgOpTime = 0;
49     private double mMaxOpTime = 0;
50 
51     /**
52      * Creates a {@link NativeBenchmarkTestParser}.
53      *
54      * @param runName the run name. Used for logging purposes.
55      */
NativeBenchmarkTestParser(String runName)56     public NativeBenchmarkTestParser(String runName) {
57         mTestRunName = runName;
58     }
59 
60     /**
61      * {@inheritDoc}
62      */
63     @Override
processNewLines(String[] lines)64     public void processNewLines(String[] lines) {
65         for (String line : lines) {
66             parseLine(line);
67         }
68     }
69 
parseLine(String line)70     private void parseLine(String line) {
71         CLog.d(line);
72         Matcher matcher = COMPLETE_PATTERN.matcher(line);
73         if (matcher.find()) {
74             CLog.i("Found result for benchmark %s: %s", getRunName(), line);
75             mMinOpTime = parseDoubleValue(line, matcher.group(1));
76             mAvgOpTime = parseDoubleValue(line, matcher.group(2));
77             mMaxOpTime = parseDoubleValue(line, matcher.group(3));
78         }
79     }
80 
parseDoubleValue(String line, String valueString)81     private double parseDoubleValue(String line, String valueString) {
82         try {
83             return Double.parseDouble(valueString);
84         } catch (NumberFormatException e) {
85             // fall through
86         }
87         CLog.w("Value was not a double (%s), trying for scientfic", line);
88         DecimalFormat format = new DecimalFormat("0.0E0");
89         try {
90             Number num = format.parse(valueString);
91             return num.doubleValue();
92         } catch (ParseException e) {
93             CLog.e("Could not parse double value in (%s)", line);
94         }
95         return 0;
96     }
97 
98     /**
99      * {@inheritDoc}
100      */
101     @Override
isCancelled()102     public boolean isCancelled() {
103         return mIsCanceled;
104     }
105 
106     /**
107      * @return The name of the Test Run.
108      */
getRunName()109     public String getRunName() {
110         return mTestRunName;
111     }
112 
113     /**
114      * @return the average operation time
115      */
getAvgOperationTime()116     public double getAvgOperationTime() {
117         return mAvgOpTime;
118     }
119 
120     /**
121      * @return the minimum operation time
122      */
getMinOperationTime()123     public double getMinOperationTime() {
124         return mMinOpTime;
125     }
126 
127     /**
128      * @return the maximum operation time
129      */
getMaxOperationTime()130     public double getMaxOperationTime() {
131         return mMaxOpTime;
132     }
133 }
134