1 /* 2 * Copyright (C) 2018 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.util.proto; 17 18 import com.android.tradefed.log.LogUtil.CLog; 19 import com.android.tradefed.metrics.proto.MetricMeasurement.DataType; 20 import com.android.tradefed.metrics.proto.MetricMeasurement.Directionality; 21 import com.android.tradefed.metrics.proto.MetricMeasurement.Measurements; 22 import com.android.tradefed.metrics.proto.MetricMeasurement.Measurements.MeasurementCase; 23 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 24 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric.Builder; 25 26 import java.util.HashMap; 27 import java.util.LinkedHashMap; 28 import java.util.Map; 29 30 /** Utility class to help with the Map<String, String> to Map<String, Metric> transition. */ 31 public class TfMetricProtoUtil { 32 33 /** 34 * Conversion of Map<String, Metric> to Map<String, String>. All the single value string 35 * representation are used, list representation are not converted and will be lost. 36 */ compatibleConvert(Map<String, Metric> map)37 public static Map<String, String> compatibleConvert(Map<String, Metric> map) { 38 Map<String, String> oldFormat = new LinkedHashMap<>(); 39 for (String key : map.keySet()) { 40 Measurements measures = map.get(key).getMeasurements(); 41 MeasurementCase set = measures.getMeasurementCase(); 42 String value = ""; 43 switch (set) { 44 case SINGLE_DOUBLE: 45 value = Double.toString(measures.getSingleDouble()); 46 break; 47 case SINGLE_INT: 48 value = Long.toString(measures.getSingleInt()); 49 break; 50 case SINGLE_STRING: 51 value = measures.getSingleString(); 52 break; 53 case MEASUREMENT_NOT_SET: 54 CLog.d("No measurements was set for key '%s'", key); 55 continue; 56 default: 57 CLog.d( 58 "Could not convert complex '%s' type to String. Use the new metric " 59 + "interface.", 60 set); 61 continue; 62 } 63 oldFormat.put(key, value); 64 } 65 return oldFormat; 66 } 67 68 /** 69 * Conversion from Map<String, String> to HashMap<String, Metric>. In order to go to the new 70 * interface. Information might only be partially populated because of the old format 71 * limitations. 72 */ upgradeConvert(Map<String, String> metrics)73 public static HashMap<String, Metric> upgradeConvert(Map<String, String> metrics) { 74 return upgradeConvert(metrics, false); 75 } 76 77 /** 78 * Conversion from Map<String, String> to HashMap<String, Metric>. In order to go to the new 79 * interface. Information might only be partially populated because of the old format 80 * limitations. 81 * 82 * @param smartNumbers convert numbers to int metrics 83 */ upgradeConvert( Map<String, String> metrics, boolean smartNumbers)84 public static HashMap<String, Metric> upgradeConvert( 85 Map<String, String> metrics, boolean smartNumbers) { 86 HashMap<String, Metric> newFormat = new LinkedHashMap<>(); 87 for (String key : metrics.keySet()) { 88 Metric metric = null; 89 String stringMetric = metrics.get(key); 90 if (smartNumbers) { 91 Long numMetric = isLong(stringMetric); 92 if (numMetric != null) { 93 metric = createSingleValue(numMetric.longValue(), null); 94 } 95 } 96 // Default to String metric 97 if (metric == null) { 98 metric = stringToMetric(stringMetric); 99 } 100 newFormat.put(key, metric); 101 } 102 return newFormat; 103 } 104 isLong(String strNum)105 private static Long isLong(String strNum) { 106 if (strNum == null) { 107 return null; 108 } 109 try { 110 return Long.parseLong(strNum); 111 } catch (NumberFormatException nfe) { 112 return null; 113 } 114 } 115 116 /** 117 * Convert a simple String metric (old format) to a {@link Metric} (new format). 118 * 119 * @param metric The string containing a metric. 120 * @return The created {@link Metric} 121 */ stringToMetric(String metric)122 public static Metric stringToMetric(String metric) { 123 Measurements measures = Measurements.newBuilder().setSingleString(metric).build(); 124 Metric m = 125 Metric.newBuilder() 126 .setMeasurements(measures) 127 .setDirection(Directionality.DIRECTIONALITY_UNSPECIFIED) 128 .setType(DataType.RAW) 129 .build(); 130 return m; 131 } 132 133 /** 134 * Create a {@link Metric} for a single long/int value, and optionally provide a unit. 135 * 136 * @param value The value that will be stored. 137 * @param unit the unit of the value, or null if no unit. 138 * @return a {@link Metric} populated with the informations. 139 */ createSingleValue(long value, String unit)140 public static Metric createSingleValue(long value, String unit) { 141 Measurements measure = Measurements.newBuilder().setSingleInt(value).build(); 142 Builder metricBuilder = Metric.newBuilder().setType(DataType.RAW).setMeasurements(measure); 143 if (unit != null) { 144 metricBuilder.setUnit(unit); 145 } 146 return metricBuilder.build(); 147 } 148 } 149