1 /*
2  * Copyright (C) 2020 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.sts.common;
18 
19 import static org.junit.Assert.*;
20 import static org.junit.Assume.*;
21 
22 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
23 import com.android.tradefed.build.IBuildInfo;
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.testtype.IAbi;
28 
29 import org.junit.rules.TestWatcher;
30 import org.junit.runner.Description;
31 
32 import java.io.File;
33 import java.io.FileNotFoundException;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.Set;
37 
38 /** Utilities to help push a native PoC executable to the device */
39 public class PocPusher extends TestWatcher {
40     private ITestDevice device = null;
41     private CompatibilityBuildHelper buildHelper = null;
42     private IAbi abi = null;
43 
44     private Set<String> filesToCleanup = new HashSet();
45     public boolean bitness32 = true;
46     public boolean bitness64 = true;
47     public boolean appendBitness = true;
48     public boolean cleanup = true;
49 
50     @Override
starting(Description d)51     protected void starting(Description d) {
52         bothBitness();
53         appendBitness = true;
54         cleanup = true;
55     }
56 
57     @Override
finished(Description d)58     protected void finished(Description d) {
59         for (Iterator<String> it = filesToCleanup.iterator(); it.hasNext(); ) {
60             String file = it.next();
61             try {
62                 CLog.i("Cleaning up %s", file);
63                 device.deleteFile(file);
64             } catch (DeviceNotAvailableException e) {
65                 CLog.e("Device unavailable when cleaning up %s", file);
66                 continue; // try to remove next time
67             }
68             it.remove();
69         }
70     }
71 
setDevice(ITestDevice device)72     public PocPusher setDevice(ITestDevice device) {
73         this.device = device;
74         return this;
75     }
76 
setAbi(IAbi abi)77     public PocPusher setAbi(IAbi abi) {
78         this.abi = abi;
79         return this;
80     }
81 
setBuild(IBuildInfo buildInfo)82     public PocPusher setBuild(IBuildInfo buildInfo) {
83         buildHelper = new CompatibilityBuildHelper(buildInfo);
84         return this;
85     }
86 
appendBitness(boolean append)87     public PocPusher appendBitness(boolean append) {
88         this.appendBitness = append;
89         return this;
90     }
91 
cleanup(boolean cleanup)92     public PocPusher cleanup(boolean cleanup) {
93         this.cleanup = cleanup;
94         return this;
95     }
96 
only32()97     public PocPusher only32() {
98         bitness32 = true;
99         bitness64 = false;
100         return this;
101     }
102 
only64()103     public PocPusher only64() {
104         bitness32 = false;
105         bitness64 = true;
106         return this;
107     }
108 
bothBitness()109     public PocPusher bothBitness() {
110         bitness32 = true;
111         bitness64 = true;
112         return this;
113     }
114 
pushFile(String testFile, String remoteFile)115     public void pushFile(String testFile, String remoteFile)
116             throws FileNotFoundException, DeviceNotAvailableException {
117         if (appendBitness) {
118             // if neither 32 or 64, nothing would ever be pushed.
119             assertTrue("bitness must be 32, 64, or both.", bitness32 || bitness64);
120 
121             String bitness = abi.getBitness().trim();
122 
123             // 32-bit doesn't have a 64-bit compatibility layer; skipping.
124             assumeFalse(bitness.equals("32") && !bitness32);
125 
126             // push the 32-bit file on 64-bit device if a 64-bit file doesn't exist.
127             if (bitness.equals("64") && !bitness64) {
128                 bitness = "32";
129                 CLog.i("Pushing a 32-bit file onto a 64-bit device.");
130             }
131             testFile += bitness;
132         }
133         CLog.i("Pushing local: %s to remote: %s", testFile.toString(), remoteFile);
134         File localFile = buildHelper.getTestFile(testFile);
135         device.pushFile(localFile, remoteFile);
136         if (cleanup) {
137             filesToCleanup.add(remoteFile);
138         }
139     }
140 }
141