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 17 package com.android.tradefed.targetprep; 18 19 import com.android.annotations.VisibleForTesting; 20 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 21 import com.android.tradefed.build.IBuildInfo; 22 import com.android.tradefed.config.Option; 23 import com.android.tradefed.config.OptionClass; 24 import com.android.tradefed.device.DeviceNotAvailableException; 25 import com.android.tradefed.device.ITestDevice; 26 import com.android.tradefed.log.LogUtil.CLog; 27 import com.android.tradefed.targetprep.TargetSetupError; 28 29 import java.io.File; 30 import java.io.FileNotFoundException; 31 import java.io.IOException; 32 import java.util.NoSuchElementException; 33 34 /** 35 * Preparer class for collect HAL traces during the test run. 36 * 37 * Currently used for collecting HAL traces for CTS tests. In test setup, pushes 38 * the profiler libs to device, sets up the permissions, and calls 39 * vts_profiling_configure to enable profiling for HAL services. In test 40 * tear down, pulls the traces to the host, resets permissions and cleans up the 41 * trace files and profiler libs on the device. 42 */ 43 @OptionClass(alias = "vts-trace-collect-preparer") 44 public class VtsTraceCollectPreparer implements ITargetPreparer, ITargetCleaner { 45 static final String SELINUX_DISABLED = "Disabled"; // selinux disabled 46 static final String SELINUX_PERMISSIVE = "Permissive"; // selinux permissive mode 47 48 // Relative path to vts 32 bit lib directory. 49 static final String VTS_LIB_DIR_32 = "DATA/lib/"; 50 // Relative path to vts 64 bit lib directory. 51 static final String VTS_LIB_DIR_64 = "DATA/lib64/"; 52 // Relative path to vts binary directory. 53 static final String VTS_BINARY_DIR = "DATA/bin/"; 54 // Path of 32 bit test libs on target device. 55 static final String VTS_TMP_LIB_DIR_32 = "/data/local/tmp/32/"; 56 // Path of 64 bit test libs on target device. 57 static final String VTS_TMP_LIB_DIR_64 = "/data/local/tmp/64/"; 58 // Path of vts test directory on target device. 59 static final String VTS_TMP_DIR = "/data/local/tmp/"; 60 // Default path to store trace files locally. 61 static final String LOCAL_TRACE_DIR = "vts-profiling"; 62 63 static final String VTS_PROFILER_SUFFIX = "vts.profiler.so"; 64 static final String VTS_LIB_PREFIX = "libvts"; 65 static final String PROFILING_CONFIGURE_BINARY = "vts_profiling_configure"; 66 static final String TRACE_PATH = "trace_path"; 67 68 private String mEnforcingState = null; // start state for selinux enforcement 69 70 @Option(name = "local-trace-dir", description = "Local directory to store trace.") 71 private String mLocalTraceDir = LOCAL_TRACE_DIR; 72 73 /** {@inheritDoc} */ 74 @Override setUp(ITestDevice device, IBuildInfo buildInfo)75 public void setUp(ITestDevice device, IBuildInfo buildInfo) 76 throws DeviceNotAvailableException, TargetSetupError { 77 CompatibilityBuildHelper buildHelper = createBuildHelper(buildInfo); 78 try { 79 // adb root. 80 device.enableAdbRoot(); 81 // Push 32 bit profiler libs. 82 pushProfilerLib(device, new File(buildHelper.getTestsDir(), VTS_LIB_DIR_32), 83 VTS_TMP_LIB_DIR_32); 84 // Push 64 bit profiler libs. 85 pushProfilerLib(device, new File(buildHelper.getTestsDir(), VTS_LIB_DIR_64), 86 VTS_TMP_LIB_DIR_64); 87 // Push vts_profiling_configure 88 device.pushFile(new File(buildHelper.getTestsDir(), 89 VTS_BINARY_DIR + PROFILING_CONFIGURE_BINARY), 90 VTS_TMP_DIR + PROFILING_CONFIGURE_BINARY); 91 } catch (IOException | NoSuchElementException e) { 92 // Cleanup profiler libs. 93 removeProfilerLib(device); 94 throw new TargetSetupError("Could not push profiler."); 95 } 96 // Create directory to store the trace files. 97 try { 98 File resultDir = buildHelper.getResultDir(); 99 File traceDir = new File(resultDir, mLocalTraceDir); 100 buildInfo.addBuildAttribute(TRACE_PATH, traceDir.getAbsolutePath()); 101 } catch (FileNotFoundException e) { 102 CLog.e("Failed to get traceDir: " + e.getMessage()); 103 // Cleanup profiler libs. 104 removeProfilerLib(device); 105 throw new TargetSetupError("Failed to get traceDir."); 106 } 107 // Set selinux permissive mode. 108 mEnforcingState = device.executeShellCommand("getenforce"); 109 if (mEnforcingState == null 110 || (!mEnforcingState.equals(SELINUX_DISABLED) 111 && !mEnforcingState.equals(SELINUX_PERMISSIVE))) { 112 device.executeShellCommand("setenforce " + SELINUX_PERMISSIVE); 113 } 114 } 115 116 /** {@inheritDoc} */ 117 @Override tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)118 public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e) 119 throws DeviceNotAvailableException { 120 // Reset selinux permission mode. 121 if (mEnforcingState != null && !mEnforcingState.equals(SELINUX_DISABLED)) { 122 device.executeShellCommand("setenforce " + mEnforcingState); 123 } 124 // Cleanup profiler libs. 125 removeProfilerLib(device); 126 } 127 128 /** 129 * Create and return a {@link CompatibilityBuildHelper} to use during the preparer. 130 */ 131 @VisibleForTesting createBuildHelper(IBuildInfo buildInfo)132 CompatibilityBuildHelper createBuildHelper(IBuildInfo buildInfo) { 133 return new CompatibilityBuildHelper(buildInfo); 134 } 135 136 /** 137 * Push all the profiler libraries (with pattern *.vts-profiler.so) and VTS 138 * profiling related libraries (with pattern libvts*.so) to device. 139 * 140 * @param device device object 141 * @param profilerLibDir directory to lookup for profiler libraries. 142 * @param destDirName target directory on device to push to. 143 * @throws DeviceNotAvailableException 144 */ pushProfilerLib(ITestDevice device, File profilerLibDir, String destDirName)145 private void pushProfilerLib(ITestDevice device, File profilerLibDir, String destDirName) 146 throws DeviceNotAvailableException { 147 File[] files = profilerLibDir.listFiles(); 148 if (files == null) { 149 CLog.d("No files found in %s", profilerLibDir.getAbsolutePath()); 150 return; 151 } 152 for (File f : files) { 153 String fileName = f.getName(); 154 if (f.isFile() 155 && (fileName.endsWith(VTS_PROFILER_SUFFIX) 156 || fileName.startsWith(VTS_LIB_PREFIX))) { 157 CLog.d("Pushing %s", fileName); 158 device.pushFile(f, destDirName + fileName); 159 } 160 } 161 } 162 163 /** 164 * Remove all profiler and VTS profiling libraries from device. 165 * 166 * @param device device object 167 * @throws DeviceNotAvailableException 168 */ removeProfilerLib(ITestDevice device)169 private void removeProfilerLib(ITestDevice device) throws DeviceNotAvailableException { 170 device.executeShellCommand(String.format("rm -rf %s/*vts.profiler.so", VTS_TMP_LIB_DIR_32)); 171 device.executeShellCommand(String.format("rm -rf %s/*vts.profiler.so", VTS_TMP_LIB_DIR_64)); 172 device.executeShellCommand(String.format("rm -rf %s/libvts_*.so", VTS_TMP_LIB_DIR_32)); 173 device.executeShellCommand(String.format("rm -rf %s/libvts_*.so", VTS_TMP_LIB_DIR_64)); 174 device.executeShellCommand(String.format("rm %s/vts_profiling_configure", VTS_TMP_DIR)); 175 } 176 } 177