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 package android.core.vm.targetprep;
17 
18 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
19 import com.android.tradefed.build.IBuildInfo;
20 import com.android.tradefed.config.Option;
21 import com.android.tradefed.config.OptionClass;
22 import com.android.tradefed.device.DeviceNotAvailableException;
23 import com.android.tradefed.device.ITestDevice;
24 import com.android.tradefed.log.LogUtil.CLog;
25 import com.android.tradefed.targetprep.BuildError;
26 import com.android.tradefed.targetprep.ITargetCleaner;
27 import com.android.tradefed.targetprep.TargetSetupError;
28 import com.android.tradefed.util.FileUtil;
29 
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.zip.ZipFile;
33 
34 /**
35  * Configures the device to run VM tests.
36  */
37 @OptionClass(alias="vm-test-preparer")
38 public class VmTestPreparer implements ITargetCleaner {
39 
40     private static final String JAR_FILE = "android.core.vm-tests-tf.jar";
41     private static final String TEMP_DIR = "/data/local/tmp";
42     private static final String VM_TEMP_DIR = TEMP_DIR +"/vm-tests";
43 
44     /**
45      * {@inheritDoc}
46      */
47     @Override
setUp(ITestDevice device, IBuildInfo buildInfo)48     public void setUp(ITestDevice device, IBuildInfo buildInfo)
49             throws TargetSetupError, BuildError, DeviceNotAvailableException {
50         CompatibilityBuildHelper helper = new CompatibilityBuildHelper(buildInfo);
51         if (!installVmPrereqs(device, helper)) {
52             throw new RuntimeException(String.format(
53                     "Failed to install vm-tests prereqs on device %s",
54                     device.getSerialNumber()));
55         }
56     }
57 
58     /**
59      * {@inheritDoc}
60      */
61     @Override
tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)62     public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
63             throws DeviceNotAvailableException {
64         cleanupDeviceFiles(device);
65     }
66 
67     /**
68      * Install pre-requisite jars for running vm-tests, creates temp directories for test.
69      *
70      * @param device the {@link ITestDevice}
71      * @param ctsBuild the {@link CompatibilityBuildHelper}
72      * @throws DeviceNotAvailableException
73      * @return true if test jar files are extracted and pushed to device successfully
74      */
installVmPrereqs(ITestDevice device, CompatibilityBuildHelper ctsBuild)75     private boolean installVmPrereqs(ITestDevice device, CompatibilityBuildHelper ctsBuild)
76             throws DeviceNotAvailableException {
77         cleanupDeviceFiles(device);
78         // Creates temp directory recursively. We also need to create the dalvik-cache directory
79         // which is used by the dalvikvm to optimize things. Without the dalvik-cache, there will be
80         // a sigsev thrown by the vm.
81         createRemoteDir(device, VM_TEMP_DIR + "/dalvik-cache" );
82         try {
83             File tmpDir = new File(System.getProperty("java.io.tmpdir"));
84             File localTmpDir = FileUtil.createTempDir("cts-vm", tmpDir);
85             File jarFile = new File(ctsBuild.getTestsDir(), JAR_FILE);
86             if (!jarFile.exists()) {
87                 CLog.e("Missing jar file %s", jarFile.getPath());
88                 return false;
89             }
90             ZipFile zipFile = new ZipFile(jarFile);
91             FileUtil.extractZip(zipFile, localTmpDir);
92             File localTestTmpDir = new File(localTmpDir, "tests");
93             if (!device.pushDir(localTestTmpDir, VM_TEMP_DIR)) {
94                 CLog.e("Failed to push vm test files");
95                 return false;
96             }
97             FileUtil.recursiveDelete(localTmpDir);
98         } catch (IOException e) {
99             CLog.e("Failed to extract jar file %s and sync it to device %s.",
100                     JAR_FILE, device.getSerialNumber());
101             return false;
102         }
103         return true;
104     }
105 
106     /**
107      * Removes temporary file directory from device
108      *
109      * @param device
110      * @throws DeviceNotAvailableException
111      */
cleanupDeviceFiles(ITestDevice device)112     private void cleanupDeviceFiles(ITestDevice device) throws DeviceNotAvailableException {
113         if (device.doesFileExist(VM_TEMP_DIR)) {
114             device.executeShellCommand(String.format("rm -r %s", VM_TEMP_DIR));
115         }
116     }
117 
118     /**
119      * Creates the file directory recursively in the device.
120      *
121      * @param device the {@link ITestDevice}
122      * @param remoteFilePath the absolute path.
123      * @throws DeviceNotAvailableException
124      */
createRemoteDir(ITestDevice device, String remoteFilePath)125     private void createRemoteDir(ITestDevice device, String remoteFilePath)
126             throws DeviceNotAvailableException {
127         if (device.doesFileExist(remoteFilePath)) {
128             return;
129         }
130         if (!(device.doesFileExist(TEMP_DIR))) {
131             CLog.e("Error: %s does not exist", TEMP_DIR);
132         }
133         device.executeShellCommand(String.format("mkdir %s", VM_TEMP_DIR));
134         device.executeShellCommand(String.format("mkdir %s", remoteFilePath));
135     }
136 }