1 /* 2 * Copyright (C) 2016 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.performance.tests; 18 19 import com.android.tradefed.config.Option; 20 import com.android.tradefed.device.DeviceNotAvailableException; 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.log.LogUtil.CLog; 23 import com.android.tradefed.result.ByteArrayInputStreamSource; 24 import com.android.tradefed.result.ITestInvocationListener; 25 import com.android.tradefed.result.LogDataType; 26 import com.android.tradefed.testtype.IDeviceTest; 27 import com.android.tradefed.testtype.IRemoteTest; 28 import com.android.tradefed.util.StreamUtil; 29 import com.android.tradefed.util.proto.TfMetricProtoUtil; 30 import java.util.HashMap; 31 import java.util.Map; 32 33 /** Test to gather post boot System memory usage */ 34 public class SystemMemoryTest implements IDeviceTest, IRemoteTest { 35 36 private static final String PROC_MEMINFO = "cat /proc/meminfo"; 37 private static final String MEMTOTAL = "MemTotal"; 38 private static final String MEMFREE = "MemFree"; 39 private static final String CACHED = "Cached"; 40 private static final String SEPARATOR = "\\s+"; 41 private static final String LINE_SEPARATOR = "\\n"; 42 43 @Option( 44 name = "reporting-key", 45 description = 46 "Reporting key is the unique identifier" 47 + "used to report data in the dashboard.") 48 private String mRuKey = ""; 49 50 private ITestDevice mTestDevice = null; 51 private ITestInvocationListener mlistener = null; 52 private Map<String, String> mMetrics = new HashMap<>(); 53 54 @Override run(ITestInvocationListener listener)55 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 56 mlistener = listener; 57 String memInfo = mTestDevice.executeShellCommand(PROC_MEMINFO); 58 if (!memInfo.isEmpty()) { 59 60 uploadLogFile(memInfo, "System MemInfo"); 61 parseProcInfo(memInfo); 62 } else { 63 CLog.e("Not able to collect the /proc/meminfo before launching app"); 64 } 65 reportMetrics(mlistener, mRuKey, mMetrics); 66 } 67 68 /** 69 * Method to write the data to test logs. 70 * 71 * @param data 72 * @param fileName 73 */ uploadLogFile(String data, String fileName)74 private void uploadLogFile(String data, String fileName) { 75 ByteArrayInputStreamSource inputStreamSrc = null; 76 try { 77 inputStreamSrc = new ByteArrayInputStreamSource(data.getBytes()); 78 mlistener.testLog(fileName, LogDataType.TEXT, inputStreamSrc); 79 } finally { 80 StreamUtil.cancel(inputStreamSrc); 81 } 82 } 83 84 /** 85 * Method to parse the system memory details 86 * 87 * @param memInfo string dump of cat /proc/meminfo 88 */ parseProcInfo(String memInfo)89 private void parseProcInfo(String memInfo) { 90 for (String line : memInfo.split(LINE_SEPARATOR)) { 91 line = line.replace(":", "").trim(); 92 String dataSplit[] = line.split(SEPARATOR); 93 switch (dataSplit[0].toLowerCase()) { 94 case "memtotal": 95 mMetrics.put("System_MEMTOTAL", dataSplit[1]); 96 break; 97 case "memfree": 98 mMetrics.put("System_MEMFREE", dataSplit[1]); 99 break; 100 case "cached": 101 mMetrics.put("System_CACHED", dataSplit[1]); 102 break; 103 } 104 } 105 } 106 107 /** 108 * Report run metrics by creating an empty test run to stick them in 109 * 110 * @param listener the {@link ITestInvocationListener} of test results 111 * @param runName the test name 112 * @param metrics the {@link Map} that contains metrics for the given test 113 */ reportMetrics( ITestInvocationListener listener, String runName, Map<String, String> metrics)114 void reportMetrics( 115 ITestInvocationListener listener, String runName, Map<String, String> metrics) { 116 // Create an empty testRun to report the parsed runMetrics 117 CLog.d("About to report metrics: %s", metrics); 118 listener.testRunStarted(runName, 0); 119 listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics)); 120 } 121 122 @Override setDevice(ITestDevice device)123 public void setDevice(ITestDevice device) { 124 mTestDevice = device; 125 } 126 127 @Override getDevice()128 public ITestDevice getDevice() { 129 return mTestDevice; 130 } 131 } 132