• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.helpers;
2 
3 import android.app.Instrumentation;
4 import android.os.ParcelFileDescriptor;
5 import android.util.Log;
6 
7 import java.io.ByteArrayOutputStream;
8 import java.io.InputStream;
9 import java.io.IOException;
10 import java.text.DecimalFormat;
11 import java.text.ParseException;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 
16 /**
17  * MetricUtility consist of basic utility methods to construct the metrics
18  * reported at the end of the test.
19  */
20 public class MetricUtility {
21 
22     private static final String TAG = MetricUtility.class.getSimpleName();
23     private static final String KEY_JOIN = "_";
24     public static final String METRIC_SEPARATOR = ",";
25 
26     public static final int BUFFER_SIZE = 1024;
27     private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("#0.000001");
28 
29     /**
30      * Append the given array of string to construct the final key used to track the metrics.
31      *
32      * @param keys to append using KEY_JOIN
33      */
constructKey(String... keys)34     public static String constructKey(String... keys) {
35         return String.join(KEY_JOIN, keys);
36     }
37 
38     /**
39      * Add metric to the result map. If metric key already exist append the new metric.
40      *
41      * @param metricKey Unique key to track the metric.
42      * @param metric metric to track.
43      * @param resultMap map of all the metrics.
44      */
addMetric(String metricKey, long metric, Map<String, StringBuilder> resultMap)45     public static void addMetric(String metricKey, long metric, Map<String,
46             StringBuilder> resultMap) {
47         resultMap.compute(metricKey, (key, value) -> (value == null) ?
48                 new StringBuilder().append(metric) : value.append(METRIC_SEPARATOR).append(metric));
49     }
50 
51     /**
52      * Add metric to the result map. If metric key already exist append the new metric.
53      *
54      * @param metricKey Unique key to track the metric.
55      * @param metric metric to track.
56      * @param resultMap map of all the metrics.
57      */
addMetric( String metricKey, double metric, Map<String, StringBuilder> resultMap)58     public static void addMetric(
59             String metricKey, double metric, Map<String, StringBuilder> resultMap) {
60         resultMap.compute(
61                 metricKey,
62                 (key, value) ->
63                         (value == null ? new StringBuilder() : value.append(METRIC_SEPARATOR))
64                                 .append(DOUBLE_FORMAT.format(metric)));
65     }
66 
67     /**
68      * Add metric to the result map. If metric key already exist increment the value by 1.
69      *
70      * @param metricKey Unique key to track the metric.
71      * @param resultMap map of all the metrics.
72      */
addMetric(String metricKey, Map<String, Integer> resultMap)73     public static void addMetric(String metricKey, Map<String,
74             Integer> resultMap) {
75         resultMap.compute(metricKey, (key, value) -> (value == null) ? 1 : value + 1);
76     }
77 
78     /**
79      * Get metric values from result map.
80      *
81      * @param metricKey Unique key to track the metric.
82      * @param resultMap Map of all the metrics.
83      * @return Double List of metric values for metric key
84      */
getMetricDoubles( String metricKey, Map<String, StringBuilder> resultMap)85     public static List<Double> getMetricDoubles(
86             String metricKey, Map<String, StringBuilder> resultMap) {
87         List<Double> result = new ArrayList<Double>();
88         if (!resultMap.containsKey(metricKey)) {
89             Log.e(TAG, String.format("No such metric key %s", metricKey));
90             return result;
91         } else {
92             String value = resultMap.get(metricKey).toString();
93             if (value.length() == 0) {
94                 Log.e(TAG, String.format("Missed value of metric key %s", metricKey));
95                 return result;
96             } else {
97                 String[] values = value.split(METRIC_SEPARATOR);
98                 for (int i = 0; i < values.length; i++) {
99                     try {
100                         result.add(DOUBLE_FORMAT.parse(values[i]).doubleValue());
101                     } catch (ParseException e) {
102                         Log.e(
103                                 TAG,
104                                 String.format(
105                                         "Error parsing value of metric key %s: #%d of value %s",
106                                         metricKey, i, value));
107                         return new ArrayList<Double>();
108                     }
109                 }
110             }
111         }
112         return result;
113     }
114 
115     /**
116      * Turn executeShellCommand into a blocking operation.
117      *
118      * @param command shell command to be executed.
119      * @param instr used to run the shell command.
120      * @return byte array of execution result
121      */
executeCommandBlocking(String command, Instrumentation instr)122     public static byte[] executeCommandBlocking(String command, Instrumentation instr) {
123         try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(instr.getUiAutomation()
124                 .executeShellCommand(command));
125                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
126             byte[] buf = new byte[BUFFER_SIZE];
127             int length;
128             Log.i(TAG, "Start reading the data");
129             while ((length = is.read(buf)) >= 0) {
130                 out.write(buf, 0, length);
131             }
132             Log.i(TAG, "Stop reading the data");
133             return out.toByteArray();
134         } catch (IOException e) {
135             Log.e(TAG, "Error executing: " + command, e);
136             return null;
137         }
138     }
139 
140 }
141