1 /* 2 * Copyright (C) 2017 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 android.cts.backup; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assume.assumeTrue; 22 23 import android.platform.test.annotations.AppModeFull; 24 25 import com.android.compatibility.common.util.BackupUtils; 26 import com.android.compatibility.common.util.LogcatInspector; 27 import com.android.tradefed.device.DeviceNotAvailableException; 28 import com.android.tradefed.device.ITestDevice; 29 import com.android.tradefed.log.LogUtil.CLog; 30 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 31 import com.android.tradefed.testtype.ITestInformationReceiver; 32 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 33 34 import org.junit.After; 35 import org.junit.AssumptionViolatedException; 36 import org.junit.Before; 37 import org.junit.Rule; 38 import org.junit.rules.TestRule; 39 import org.junit.runner.Description; 40 import org.junit.runner.RunWith; 41 import org.junit.runners.model.Statement; 42 43 import java.io.ByteArrayInputStream; 44 import java.io.IOException; 45 import java.io.InputStream; 46 import java.nio.charset.StandardCharsets; 47 import java.util.regex.Matcher; 48 import java.util.regex.Pattern; 49 50 /** 51 * Base class for CTS backup/restore hostside tests 52 */ 53 @RunWith(DeviceJUnit4ClassRunner.class) 54 @AppModeFull 55 public abstract class BaseBackupHostSideTest extends BaseHostJUnit4Test { 56 /** Value of PackageManager.FEATURE_BACKUP */ 57 private static final String FEATURE_BACKUP = "android.software.backup"; 58 59 protected static final String LOCAL_TRANSPORT = 60 "com.android.localtransport/.LocalTransport"; 61 62 @Rule 63 public final RequiredFeatureRule mBackupRequiredRule = new RequiredFeatureRule(this, 64 FEATURE_BACKUP); 65 66 private BackupUtils mBackupUtils = new BackupUtils() { 67 @Override 68 protected InputStream executeShellCommand(String command) throws IOException { 69 return executeDeviceShellCommand(getDevice(), command); 70 } 71 }; 72 73 protected final LogcatInspector mLogcatInspector = new LogcatInspector() { 74 @Override 75 protected InputStream executeShellCommand(String command) throws IOException { 76 return executeDeviceShellCommand(getDevice(), command); 77 } 78 }; 79 80 @Before setUp()81 public void setUp() throws Exception { 82 // Check that the backup wasn't disabled and the transport wasn't switched unexpectedly. 83 assertTrue("Backup was unexpectedly disabled during the module test run", 84 getBackupUtils().isBackupEnabled()); 85 assertEquals("LocalTransport should be selected at this point", LOCAL_TRANSPORT, 86 getCurrentTransport()); 87 mBackupUtils.wakeAndUnlockDevice(); 88 } 89 getBackupUtils()90 protected BackupUtils getBackupUtils() { 91 return mBackupUtils; 92 } 93 94 /** 95 * Attempts to clear the device log. 96 */ clearLogcat()97 protected void clearLogcat() throws DeviceNotAvailableException { 98 getDevice().executeAdbCommand("logcat", "-c"); 99 } 100 101 /** 102 * Run test <testName> in test <className> found in package <packageName> on the device, and 103 * assert it is successful. 104 */ checkDeviceTest(String packageName, String className, String testName)105 protected void checkDeviceTest(String packageName, String className, String testName) 106 throws DeviceNotAvailableException { 107 boolean result = runDeviceTests(packageName, className, testName); 108 assertTrue("Device test failed: " + testName, result); 109 } 110 startActivityInPackageAndWait(String packageName, String className)111 protected void startActivityInPackageAndWait(String packageName, String className) 112 throws DeviceNotAvailableException { 113 getDevice().executeShellCommand(String.format( 114 "am start -W -a android.intent.action.MAIN -n %s/%s.%s", packageName, 115 packageName, 116 className)); 117 } 118 119 /** 120 * Clears backup data stored in Local Transport for a package. 121 * NB: 'bmgr wipe' does not produce any useful output if the package or transport not found, 122 * so we cannot really check the success of the operation 123 */ clearBackupDataInLocalTransport(String packageName)124 protected void clearBackupDataInLocalTransport(String packageName) 125 throws DeviceNotAvailableException { 126 getDevice().executeShellCommand( 127 String.format("bmgr wipe %s %s", LOCAL_TRANSPORT, packageName)); 128 } 129 130 /** 131 * Clears package data 132 */ clearPackageData(String packageName)133 protected void clearPackageData(String packageName) throws DeviceNotAvailableException { 134 getDevice().executeShellCommand(String.format("pm clear %s", packageName)); 135 } 136 getCurrentTransport()137 protected String getCurrentTransport() throws DeviceNotAvailableException { 138 String output = getDevice().executeShellCommand("bmgr list transports"); 139 Pattern pattern = Pattern.compile("\\* (.*)"); 140 Matcher matcher = pattern.matcher(output); 141 if (matcher.find()) { 142 return matcher.group(1); 143 } else { 144 throw new RuntimeException("non-parsable output setting bmgr transport: " + output); 145 } 146 } 147 setLocalTransportParameters(String parameters)148 protected void setLocalTransportParameters(String parameters) throws Exception { 149 getDevice().executeShellCommand("settings put secure backup_local_transport_parameters " 150 + parameters); 151 } 152 getLocalTransportParameters()153 protected String getLocalTransportParameters() throws DeviceNotAvailableException { 154 return getDevice().executeShellCommand( 155 "settings get secure backup_local_transport_parameters"); 156 } 157 enableFakeEncryptionOnTransport()158 protected void enableFakeEncryptionOnTransport() throws Exception { 159 setLocalTransportParameters("fake_encryption_flag=true"); 160 } 161 disableFakeEncryptionOnTransport()162 protected void disableFakeEncryptionOnTransport() throws Exception { 163 setLocalTransportParameters("fake_encryption_flag=false"); 164 } 165 executeDeviceShellCommand( ITestDevice device, String command)166 static InputStream executeDeviceShellCommand( 167 ITestDevice device, String command) throws IOException { 168 try { 169 String result = device.executeShellCommand(command); 170 return new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8)); 171 } catch (DeviceNotAvailableException e) { 172 throw new IOException(e); 173 } 174 } 175 176 // TODO(b/169341308): move to common infra code 177 private static final class RequiredFeatureRule implements TestRule { 178 179 private final ITestInformationReceiver mReceiver; 180 private final String mFeature; 181 RequiredFeatureRule(ITestInformationReceiver receiver, String feature)182 RequiredFeatureRule(ITestInformationReceiver receiver, String feature) { 183 mReceiver = receiver; 184 mFeature = feature; 185 } 186 187 @Override apply(Statement base, Description description)188 public Statement apply(Statement base, Description description) { 189 return new Statement() { 190 191 @Override 192 public void evaluate() throws Throwable { 193 boolean hasFeature = false; 194 try { 195 hasFeature = mReceiver.getTestInformation().getDevice() 196 .hasFeature(mFeature); 197 } catch (DeviceNotAvailableException e) { 198 CLog.e("Could not check if device has feature %s: %e", mFeature, e); 199 return; 200 } 201 202 if (!hasFeature) { 203 CLog.d("skipping %s#%s" 204 + " because device does not have feature '%s'", 205 description.getClassName(), description.getMethodName(), mFeature); 206 throw new AssumptionViolatedException("Device does not have feature '" 207 + mFeature + "'"); 208 } 209 base.evaluate(); 210 } 211 }; 212 } 213 214 @Override toString()215 public String toString() { 216 return "RequiredFeatureRule[" + mFeature + "]"; 217 } 218 } 219 } 220