Merge "Reboot less in FuseDaemonHostTest"
diff --git a/tests/jni/FuseDaemonTest/FuseDaemonHostTest.xml b/tests/jni/FuseDaemonTest/FuseDaemonHostTest.xml
index 12f464f..2974c31 100644
--- a/tests/jni/FuseDaemonTest/FuseDaemonHostTest.xml
+++ b/tests/jni/FuseDaemonTest/FuseDaemonHostTest.xml
@@ -20,6 +20,7 @@
<option name="test-file-name" value="FuseDaemonTest.apk" />
<option name="test-file-name" value="FuseDaemonLegacyTest.apk" />
</target_preparer>
+ <target_preparer class="com.android.tests.fused.host.FuseTargetPreparer"/>
<test class="com.android.tradefed.testtype.HostTest" >
<option name="class" value="com.android.tests.fused.host.LegacyAccessHostTest" />
<option name="class" value="com.android.tests.fused.host.FuseDaemonHostTest" />
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonBaseHostTest.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonBaseHostTest.java
deleted file mode 100644
index 282abd6..0000000
--- a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonBaseHostTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.fused.host;
-
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Base class for host tests that run FuseDaemon tests.
- * The main utility of this class is that it toggles FUSE and restarts the device if it's not
- * already on, then restores the original settings after the test has finished.
- *
- * @see {@link #enableFuseIfNecessary()}
- * @see {@link #restoreFuseSettings()}
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-abstract public class FuseDaemonBaseHostTest extends BaseHostJUnit4Test {
- private static final String PROP_FUSE = "persist.sys.fuse";
- private static final String PROP_SETTINGS_FUSE = "persist.sys.fflag.override.settings_fuse";
- private static ITestDevice sDevice = null;
- // Flag to determine whether FUSE was initially enabled, so we know what state to restore the
- // device to when we're done. 0 means we haven't checked yet, 1 is enabled and -1 is disabled.
- private static int sFuseInitialState = 0;
-
- private boolean isFuseEnabled() throws Exception {
- String enabled = getDevice().getProperty(PROP_FUSE);
- if (enabled == null) {
- return false; // current default value of PROP_FUSE
- }
- return enabled.contains("true") || enabled.contains("1");
- }
-
- /* {@link #sDevice} must be initialized before calling this method */
- private static void toggleFuse(boolean enable) throws Exception {
- final String strEnable = enable ? "true" : "false";
- if (strEnable.equals(sDevice.getProperty(PROP_SETTINGS_FUSE))) {
- return;
- }
- // root settings will be reset once device has rebooted
- sDevice.enableAdbRoot();
- sDevice.setProperty(PROP_SETTINGS_FUSE, (enable ? "true" : "false"));
- Thread.sleep(TimeUnit.SECONDS.toMillis(1));
- sDevice.reboot();
- }
-
- /**
- * Snapshots {@link #sFuseInitialState} only once - if called while {@link #sFuseInitialState}
- * is not {@code 0}, it will be a no-op.
- */
- private static void snapshotFuseInitialState(boolean enabled) {
- if (sFuseInitialState != 0) {
- return;
- }
- sFuseInitialState = enabled ? 1 : -1;
- }
-
- private static boolean getFuseInitialState() {
- return sFuseInitialState == 1;
- }
-
- private void enableFuseAndRebootDeviceIfNecessary() throws Exception {
- if (isFuseEnabled()) {
- snapshotFuseInitialState(true);
- return;
- }
- snapshotFuseInitialState(false);
- sDevice = getDevice();
- toggleFuse(true);
- }
-
- @Before
- public void enableFuseIfNecessary() throws Exception {
- enableFuseAndRebootDeviceIfNecessary();
- }
-
- @AfterClass
- public static void restoreFuseSettings() throws Exception {
- if (sDevice != null) {
- toggleFuse(getFuseInitialState());
- }
- }
-
- protected String executeShellCommand(String cmd) throws Exception {
- return getDevice().executeShellCommand(cmd);
- }
-}
\ No newline at end of file
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
index 6bedbce..e174655 100644
--- a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
+++ b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseDaemonHostTest.java
@@ -20,10 +20,10 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,7 +31,7 @@
* Runs the FuseDaemon tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class FuseDaemonHostTest extends FuseDaemonBaseHostTest {
+public class FuseDaemonHostTest extends BaseHostJUnit4Test {
/**
* Runs the given phase of FilePathAccessTest by calling into the device.
* Throws an exception if the test phase fails.
@@ -42,6 +42,10 @@
phase));
}
+ private String executeShellCommand(String cmd) throws Exception {
+ return getDevice().executeShellCommand(cmd);
+ }
+
@Before
public void setup() throws Exception {
executeShellCommand("mkdir /sdcard/Android/data/com.android.shell");
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseTargetPreparer.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseTargetPreparer.java
new file mode 100644
index 0000000..35be0c2
--- /dev/null
+++ b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/FuseTargetPreparer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tests.fused.host;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.targetprep.BaseTargetPreparer;
+
+public class FuseTargetPreparer extends BaseTargetPreparer {
+ private static final String PROP_FUSE = "persist.sys.fuse";
+ private static final String PROP_SETTINGS_FUSE = "persist.sys.fflag.override.settings_fuse";
+ private static boolean sFuseInitialState = false;
+
+ private static boolean isFuseEnabled(ITestDevice device) throws DeviceNotAvailableException {
+ String enabled = device.getProperty(PROP_FUSE);
+ if (enabled == null) {
+ return false; // current default value of PROP_FUSE
+ }
+ return enabled.contains("true") || enabled.contains("1");
+ }
+
+ private static void toggleFuse(boolean enable, ITestDevice device)
+ throws DeviceNotAvailableException {
+ final String strEnable = Boolean.toString(enable);
+ if (strEnable.equals(device.getProperty(PROP_SETTINGS_FUSE))) {
+ return;
+ }
+ // root settings will be reset once device has rebooted
+ device.enableAdbRoot();
+ device.setProperty(PROP_SETTINGS_FUSE, strEnable);
+ device.reboot();
+ }
+
+ private static void enableFuseAndRebootDeviceIfNecessary(ITestDevice device)
+ throws DeviceNotAvailableException {
+ sFuseInitialState = isFuseEnabled(device);
+ if (sFuseInitialState) {
+ // Nothing to do if it's enabled
+ return;
+ }
+ toggleFuse(true, device);
+ }
+
+ public static void restoreFuseSettings(ITestDevice device) throws DeviceNotAvailableException {
+ toggleFuse(sFuseInitialState, device);
+ }
+
+ @Override
+ public void setUp(TestInformation testInformation) throws DeviceNotAvailableException {
+ enableFuseAndRebootDeviceIfNecessary(testInformation.getDevice());
+ }
+
+ @Override
+ public void tearDown(TestInformation testInformation, Throwable e)
+ throws DeviceNotAvailableException {
+ restoreFuseSettings(testInformation.getDevice());
+ }
+}
diff --git a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/LegacyAccessHostTest.java b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/LegacyAccessHostTest.java
index cfc69d8..f88deb3 100644
--- a/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/LegacyAccessHostTest.java
+++ b/tests/jni/FuseDaemonTest/host/src/com/android/tests/fused/host/LegacyAccessHostTest.java
@@ -20,10 +20,10 @@
import static com.google.common.truth.Truth.assertThat;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,10 +31,14 @@
* Runs the legacy file path access tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class LegacyAccessHostTest extends FuseDaemonBaseHostTest {
+public class LegacyAccessHostTest extends BaseHostJUnit4Test {
public static final String SHELL_FILE = "/sdcard/LegacyAccessHostTest_shell";
+ private String executeShellCommand(String cmd) throws Exception {
+ return getDevice().executeShellCommand(cmd);
+ }
+
/**
* Runs the given phase of LegacyFileAccessTest by calling into the device.
* Throws an exception if the test phase fails.
@@ -84,17 +88,18 @@
@Test
public void testCreateFilesInRandomPlaces_hasW() throws Exception {
revokePermissions("android.permission.READ_EXTERNAL_STORAGE");
+ executeShellCommand("mkdir -p /sdcard/Android/data/com.android.shell");
runDeviceTest("testCreateFilesInRandomPlaces_hasW");
}
@Test
public void testMkdirInRandomPlaces_hasW() throws Exception {
revokePermissions("android.permission.READ_EXTERNAL_STORAGE");
+ executeShellCommand("mkdir -p /sdcard/Android/data/com.android.shell");
runDeviceTest("testMkdirInRandomPlaces_hasW");
}
@Test
- @Ignore("b/146189163")
public void testReadOnlyExternalStorage_hasR() throws Exception {
revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE");
createFile(SHELL_FILE);
@@ -106,7 +111,6 @@
}
@Test
- @Ignore("b/146189163")
public void testCantAccessExternalStorage() throws Exception {
revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE");
diff --git a/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java b/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
index 500a7e9..39efda1 100644
--- a/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
+++ b/tests/jni/FuseDaemonTest/legacy/src/com/android/tests/fused/legacy/LegacyFileAccessTest.java
@@ -77,15 +77,16 @@
"LegacyFileAccessTest");
assertCanCreateFile(file);
- // Can even create another app's external storage dir
+ // However, even legacy apps can't create files under other app's directories
final File otherAppDir = new File(Environment.getExternalStorageDirectory(),
"Android/data/com.android.shell");
file = new File(otherAppDir, "LegacyFileAccessTest.txt");
+
+ // otherAppDir was already created by the host test
try {
- otherAppDir.mkdir();
- assertCanCreateFile(file);
- } finally {
- otherAppDir.delete();
+ file.createNewFile();
+ fail("File creation expected to fail: " + file);
+ } catch (IOException expected) {
}
}
@@ -105,14 +106,10 @@
final File otherAppDir = new File(Environment.getExternalStorageDirectory(),
"Android/data/com.android.shell");
- // Can create a directory under another app's private directory
+ // However, even legacy apps can't create dirs under other app's directories
final File subDir = new File(otherAppDir, "LegacyFileAccessTest");
- try {
- otherAppDir.mkdir();
- assertCanCreateDir(subDir);
- } finally {
- otherAppDir.delete();
- }
+ // otherAppDir was already created by the host test
+ assertThat(subDir.mkdir()).isFalse();
// Try to list a directory and fail because it requires READ permission
assertThat(new File(Environment.getExternalStorageDirectory(),