• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 
17 package com.android.cts.util;
18 
19 import java.util.LinkedList;
20 import java.util.List;
21 
22 import junit.framework.Assert;
23 
24 
25 /**
26  * Utility class to print performance measurement result back to host.
27  * For now, throws know exception with message.
28  *
29  * Format:
30  * Message = summary log SUMMARY_SEPARATOR [LOG_SEPARATOR log]*
31  * summary = message|target|unit|type|value, target can be " " if there is no target set.
32  * log for array = classMethodName:line_number|message|unit|type|space seSummaryparated values
33  */
34 public class ReportLog {
35     private static final String LOG_SEPARATOR = "+++";
36     private static final String SUMMARY_SEPARATOR = "++++";
37     private static final String LOG_ELEM_SEPARATOR = "|";
38 
39     private List<String> mMessages = new LinkedList<String> ();
40     private String mSummary = null;
41     protected static int mDepth = 3;
42 
43     /**
44      * print array of values to output log
45      */
printArray(String message, double[] values, ResultType type, ResultUnit unit)46     public void printArray(String message, double[] values, ResultType type, ResultUnit unit) {
47         doPrintArray(message, values, type, unit);
48     }
49 
50     /**
51      * Print a value to output log
52      */
printValue(String message, double value, ResultType type, ResultUnit unit)53     public void printValue(String message, double value, ResultType type, ResultUnit unit) {
54         double[] vals = { value };
55         doPrintArray(message, vals, type, unit);
56     }
57 
doPrintArray(String message, double[] values, ResultType type, ResultUnit unit)58     private void doPrintArray(String message, double[] values, ResultType type, ResultUnit unit) {
59         StringBuilder builder = new StringBuilder();
60         // note mDepth + 1 as this function will be called by printVaue or printArray
61         // and we need caller of printValue / printArray
62         builder.append(getClassMethodNames(mDepth + 1, true) + LOG_ELEM_SEPARATOR + message +
63                 LOG_ELEM_SEPARATOR + type.getXmlString() + LOG_ELEM_SEPARATOR +
64                 unit.getXmlString() + LOG_ELEM_SEPARATOR);
65         for (double v : values) {
66             builder.append(v);
67             builder.append(" ");
68         }
69         mMessages.add(builder.toString());
70         printLog(builder.toString());
71     }
72 
73     /**
74      * record the result of benchmarking with performance target.
75      * Depending on the ResultType, the function can fail if the result
76      * does not meet the target. For example, for the type of HIGHER_BETTER,
77      * value of 1.0 with target of 2.0 will fail.
78      *
79      * @param message message to be printed in the final report
80      * @param target target performance for the benchmarking
81      * @param value measured value
82      * @param type
83      * @param unit
84      */
printSummaryWithTarget(String message, double target, double value, ResultType type, ResultUnit unit)85     public void printSummaryWithTarget(String message, double target, double value,
86             ResultType type, ResultUnit unit) {
87         mSummary = message + LOG_ELEM_SEPARATOR + target + LOG_ELEM_SEPARATOR + type.getXmlString()
88                 + LOG_ELEM_SEPARATOR + unit.getXmlString() + LOG_ELEM_SEPARATOR + value;
89         boolean resultOk = true;
90         if (type == ResultType.HIGHER_BETTER) {
91             resultOk = value >= target;
92         } else if (type == ResultType.LOWER_BETTER) {
93             resultOk = value <= target;
94         }
95         if (!resultOk) {
96             Assert.fail("Measured result " + value + " does not meet perf target " + target +
97                     " with type " + type.getXmlString());
98         }
99     }
100 
101     /**
102      * For standard report summary without target value.
103      * Note that this function will not fail as there is no target.
104      * @param message
105      * @param value
106      * @param type type of the value
107      * @param unit unit of the data
108      */
printSummary(String message, double value, ResultType type, ResultUnit unit)109     public void printSummary(String message, double value, ResultType type, ResultUnit unit) {
110         mSummary = message + LOG_ELEM_SEPARATOR + " " + LOG_ELEM_SEPARATOR + type.getXmlString() +
111                 LOG_ELEM_SEPARATOR + unit.getXmlString() + LOG_ELEM_SEPARATOR + value;
112     }
113 
114     /**
115      * @return a string representation of this report.
116      */
generateReport()117     protected String generateReport() {
118         if ((mSummary == null) && mMessages.isEmpty()) {
119             // just return empty string
120             return "";
121         }
122         StringBuilder builder = new StringBuilder();
123         builder.append(mSummary);
124         builder.append(SUMMARY_SEPARATOR);
125         for (String entry : mMessages) {
126             builder.append(entry);
127             builder.append(LOG_SEPARATOR);
128         }
129         // delete the last separator
130         if (builder.length() >= LOG_SEPARATOR.length()) {
131             builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
132         }
133         mSummary = null;
134         mMessages.clear();
135         return builder.toString();
136     }
137 
138     /**
139      * calculate rate per sec for given change happened during given timeInMSec.
140      * timeInSec with 0 value will be changed to small value to prevent divide by zero.
141      * @param change total change of quality for the given duration timeInMSec.
142      * @param timeInMSec
143      * @return
144      */
calcRatePerSec(double change, double timeInMSec)145     public static double calcRatePerSec(double change, double timeInMSec) {
146         if (timeInMSec == 0) {
147             return change * 1000.0 / 0.001; // do not allow zero
148         } else {
149             return change * 1000.0 / timeInMSec;
150         }
151     }
152 
153     /**
154      * array version of calcRatePerSecArray
155      */
calcRatePerSecArray(double change, double[] timeInMSec)156     public static double[] calcRatePerSecArray(double change, double[] timeInMSec) {
157         double[] result = new double[timeInMSec.length];
158         change *= 1000.0;
159         for (int i = 0; i < timeInMSec.length; i++) {
160             if (timeInMSec[i] == 0) {
161                 result[i] = change / 0.001;
162             } else {
163                 result[i] = change / timeInMSec[i];
164             }
165         }
166         return result;
167     }
168 
169     /**
170      * copy array from src to dst with given offset in dst.
171      * dst should be big enough to hold src
172      */
copyArray(double[] src, double[] dst, int dstOffset)173     public static void copyArray(double[] src, double[] dst, int dstOffset) {
174         for (int i = 0; i < src.length; i++) {
175             dst[dstOffset + i] = src[i];
176         }
177     }
178 
179     /**
180      * get classname#methodname from call stack of the current thread
181      */
getClassMethodNames()182     public static String getClassMethodNames() {
183         return getClassMethodNames(mDepth, false);
184     }
185 
getClassMethodNames(int depth, boolean addLineNumber)186     private static String getClassMethodNames(int depth, boolean addLineNumber) {
187         StackTraceElement[] elements = Thread.currentThread().getStackTrace();
188         String names = elements[depth].getClassName() + "#" + elements[depth].getMethodName() +
189                 (addLineNumber ? ":" + elements[depth].getLineNumber() : "");
190         return names;
191     }
192 
193     /**
194      * to be overridden by child to print message to be passed
195      */
printLog(String msg)196     protected void printLog(String msg) {
197 
198     }
199 }
200