• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.compatibility.common.tradefed.targetprep;
18 
19 import com.android.ddmlib.IDevice;
20 import com.android.ddmlib.Log;
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.targetprep.ITargetCleaner;
27 import com.android.tradefed.targetprep.TargetSetupError;
28 import com.android.tradefed.targetprep.BuildError;
29 import com.android.tradefed.testtype.IAbi;
30 import com.android.tradefed.testtype.IAbiReceiver;
31 import com.android.tradefed.util.StreamUtil;
32 
33 import java.io.File;
34 import java.io.InputStream;
35 import java.io.IOException;
36 import java.nio.file.Paths;
37 import java.util.NoSuchElementException;
38 
39 import org.json.JSONException;
40 import org.json.JSONObject;
41 
42 /**
43  * A {@link HidlProfilerPreparer} that attempts to enable and disable HIDL profiling on a target device.
44  * <p />
45  * This is used when one wants to do such setup and cleanup operations in Java instead of the
46  * VTS Python runner, Python test template, or Python test case.
47  */
48 @OptionClass(alias = "push-file")
49 public class HidlProfilerPreparer implements ITargetCleaner, IAbiReceiver {
50     private static final String LOG_TAG = "HidlProfilerPreparer";
51 
52     private static final String TARGET_PROFILING_TRACE_PATH = "/data/local/tmp/";
53     private static final String TARGET_PROFILING_LIBRARY_PATH = "/data/local/tmp/<bitness>/hw/";
54     private static final String HOST_PROFILING_TRACE_PATH = "/tmp/vts-trace/record-replay/";
55     private static final String HOST_PROFILING_TRACE_PATH_KEY = "profiling_trace_path";
56 
57     private static final String VENDOR_TEST_CONFIG_FILE_PATH =
58             "/config/google-tradefed-vts-config.config";
59 
60     @Option(name="target-profiling-trace-path", description=
61             "The target-side path to store the profiling trace file(s).")
62     private String mTargetProfilingTracePath = TARGET_PROFILING_TRACE_PATH;
63 
64     @Option(name="target-profiling-library-path", description=
65             "The target-side path to store the profiling trace file(s). " +
66             "Use <bitness> to auto fill in 32 or 64 depending on the target device bitness.")
67     private String mTargetProfilingLibraryPath = TARGET_PROFILING_LIBRARY_PATH;
68 
69     @Option(name="copy-generated-trace-files", description=
70             "Whether to copy the generated trace files to a host-side, " +
71             "designated destination dir")
72     private boolean mCopyGeneratedTraceFiles = false;
73 
74     @Option(name="host-profiling-trace-path", description=
75             "The host-side path to store the profiling trace file(s).")
76     private String mHostProfilingTracePath = HOST_PROFILING_TRACE_PATH;
77 
78     private IAbi mAbi = null;
79 
80     /**
81      * Set mTargetProfilingTracePath.  Exposed for testing.
82      */
setTargetProfilingTracePath(String path)83     void setTargetProfilingTracePath(String path) {
84         mTargetProfilingTracePath = path;
85     }
86 
87     /**
88      * Set mTargetProfilingLibraryPath.  Exposed for testing.
89      */
setTargetProfilingLibraryPath(String path)90     void setTargetProfilingLibraryPath(String path) {
91         mTargetProfilingLibraryPath = path;
92     }
93 
94     /**
95      * {@inheritDoc}
96      */
97     @Override
setAbi(IAbi abi)98     public void setAbi(IAbi abi){
99         mAbi = abi;
100     }
101 
102     /**
103      * {@inheritDoc}
104      */
105     @Override
setUp(ITestDevice device, IBuildInfo buildInfo)106     public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError, BuildError,
107             DeviceNotAvailableException, RuntimeException {
108         readVtsTradeFedVendorConfig();
109 
110         // Cleanup any existing traces
111         Log.d(LOG_TAG, String.format("Deleting any existing target-side trace files in %s.",
112               mTargetProfilingTracePath));
113         device.executeShellCommand(
114                 String.format("rm %s/*.vts.trace", mTargetProfilingTracePath));
115 
116         Log.d(LOG_TAG, String.format("Starting the HIDL profiling (bitness: %s).",
117                                      mAbi.getBitness()));
118         mTargetProfilingLibraryPath = mTargetProfilingLibraryPath.replace(
119                 "<bitness>", mAbi.getBitness());
120         Log.d(LOG_TAG, String.format("Target Profiling Library Path: %s",
121                                      mTargetProfilingLibraryPath));
122 
123         String result =
124             device.executeShellCommand("setenforce 0");
125         Log.d(LOG_TAG, String.format("setenforce: %s", result));
126 
127         // profiler runs as a different user and thus 777 is needed.
128         result =
129             device.executeShellCommand("chmod 777 /data");
130         Log.d(LOG_TAG, String.format("chmod: %s", result));
131         result =
132             device.executeShellCommand("chmod 777 /data/local");
133         Log.d(LOG_TAG, String.format("chmod: %s", result));
134         result =
135             device.executeShellCommand("chmod 777 /data/local/tmp");
136         Log.d(LOG_TAG, String.format("chmod: %s", result));
137 
138         result =
139             device.executeShellCommand("chmod 755 /data/local/tmp/vts_profiling_configure");
140         Log.d(LOG_TAG, String.format("chmod: %s", result));
141         result = device.executeShellCommand(
142             String.format("/data/local/tmp/vts_profiling_configure enable"));
143         Log.d(LOG_TAG, String.format("start profiling: %s", result));
144     }
145 
146     /**
147      * {@inheritDoc}
148      */
149     @Override
tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)150     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
151             throws DeviceNotAvailableException {
152         Log.d(LOG_TAG, "Stopping the HIDL Profiling.");
153         // Disables VTS Profiling
154         device.executeShellCommand("chmod 755 /data/local/tmp/vts_profiling_configure");
155         String result = device.executeShellCommand(
156             "/data/local/tmp/vts_profiling_configure disable clear");
157         Log.d(LOG_TAG, String.format("stop profiling: %s", result));
158 
159         // Gets trace files from the target.
160         if (!mTargetProfilingTracePath.endsWith("/")) {
161             mTargetProfilingTracePath += "/";
162         }
163         String traceFileListString = device.executeShellCommand(
164                 String.format("ls %s*.vts.trace", mTargetProfilingTracePath));
165         if (!traceFileListString.contains("No such file or directory")) {
166             Log.d(LOG_TAG, String.format("Generated trace files: %s",
167                                          traceFileListString));
168             if (mCopyGeneratedTraceFiles) {
169                 File destDir = new File(mHostProfilingTracePath);
170                 if (!destDir.exists() && !destDir.mkdirs()) {
171                     Log.e(LOG_TAG, String.format("Couldn't create a dir, %s.",
172                                                  mHostProfilingTracePath));
173                 } else {
174                     for (String traceFilePath : traceFileListString.split("\\s+")) {
175                         File traceFile = new File(traceFilePath);
176                         File destFile = new File(destDir, traceFile.getName());
177                         Log.d(LOG_TAG, String.format("Copying a trace file: %s -> %s",
178                                                      traceFilePath, destFile));
179                         if (device.pullFile(traceFilePath, destFile)) {
180                             Log.d(LOG_TAG, "Copying a trace file succeeded.");
181                         } else {
182                             Log.e(LOG_TAG, "Copying a trace file failed.");
183                         }
184                     }
185                 }
186             }
187         } else {
188             Log.d(LOG_TAG, "Generated trace files: none");
189         }
190     }
191 
192     /**
193      * Reads HOST_PROFILING_TRACE_PATH_KEY value from VENDOR_TEST_CONFIG_FILE_PATH.
194      */
readVtsTradeFedVendorConfig()195     private void readVtsTradeFedVendorConfig() throws RuntimeException {
196         Log.d(LOG_TAG, String.format("Load vendor test config %s",
197                                      VENDOR_TEST_CONFIG_FILE_PATH));
198         InputStream config = getClass().getResourceAsStream(
199                 VENDOR_TEST_CONFIG_FILE_PATH);
200         if (config == null) {
201             Log.d(LOG_TAG,
202                   String.format("Vendor test config file %s does not exist.",
203                                 VENDOR_TEST_CONFIG_FILE_PATH));
204             return;
205         }
206 
207         try {
208             String content = StreamUtil.getStringFromStream(config);
209             Log.d(LOG_TAG, String.format("Loaded vendor test config %s",
210                                          content));
211             if (content != null) {
212                 JSONObject vendorConfigJson = new JSONObject(content);
213                 try {
214                     String tracePath = vendorConfigJson.getString(
215                             HOST_PROFILING_TRACE_PATH_KEY);
216                     if (tracePath.length() > 0) {
217                         mHostProfilingTracePath = tracePath;
218                     }
219                 } catch (NoSuchElementException e) {
220                     Log.d(LOG_TAG,
221                           String.format(
222                                   "Vendor config does not define %s",
223                                   HOST_PROFILING_TRACE_PATH_KEY));
224                 }
225             }
226         } catch (IOException e) {
227             throw new RuntimeException(
228                     "Failed to read vendor config json file");
229         } catch (JSONException e) {
230             throw new RuntimeException(
231                     "Failed to build updated vendor config json data");
232         }
233     }
234 }
235