Merge "Ensure python tests use the provided adb"
diff --git a/src/com/android/tradefed/command/CommandScheduler.java b/src/com/android/tradefed/command/CommandScheduler.java
index 545c2f6..eb67a0d 100644
--- a/src/com/android/tradefed/command/CommandScheduler.java
+++ b/src/com/android/tradefed/command/CommandScheduler.java
@@ -1401,7 +1401,9 @@
         synchronized(this) {
             if (!config.getDeviceConfig().isEmpty()) {
                 for (IDeviceConfiguration deviceConfig : config.getDeviceConfig()) {
-                    device = manager.allocateDevice(deviceConfig.getDeviceRequirements());
+                    device =
+                            manager.allocateDevice(
+                                    deviceConfig.getDeviceRequirements(), deviceConfig.isFake());
                     if (device != null) {
                         devices.put(deviceConfig.getDeviceName(), device);
                     } else {
diff --git a/src/com/android/tradefed/device/DeviceManager.java b/src/com/android/tradefed/device/DeviceManager.java
index 5531521..4b22920 100644
--- a/src/com/android/tradefed/device/DeviceManager.java
+++ b/src/com/android/tradefed/device/DeviceManager.java
@@ -58,6 +58,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
@@ -507,7 +508,7 @@
      */
     @Override
     public ITestDevice allocateDevice() {
-        return allocateDevice(ANY_DEVICE_OPTIONS);
+        return allocateDevice(ANY_DEVICE_OPTIONS, false);
     }
 
     /**
@@ -515,7 +516,19 @@
      */
     @Override
     public ITestDevice allocateDevice(IDeviceSelection options) {
+        return allocateDevice(options, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ITestDevice allocateDevice(IDeviceSelection options, boolean isTemporary) {
         checkInit();
+        if (isTemporary) {
+            String rand = UUID.randomUUID().toString();
+            String serial = String.format("%s-temp-%s", NULL_DEVICE_SERIAL_PREFIX, rand);
+            addAvailableDevice(new NullDevice(serial, true));
+            options.setSerial(serial);
+        }
         return mManagedDeviceList.allocate(options);
     }
 
@@ -555,6 +568,18 @@
         // force stop capturing logcat just to be sure
         managedDevice.stopLogcat();
         IDevice ideviceToReturn = device.getIDevice();
+        if (ideviceToReturn instanceof NullDevice) {
+            NullDevice nullDevice = (NullDevice) ideviceToReturn;
+            if (nullDevice.isTemporary()) {
+                DeviceEventResponse r =
+                        mManagedDeviceList.handleDeviceEvent(
+                                managedDevice, DeviceEvent.FREE_UNKNOWN);
+                CLog.d(
+                        "Temporary device '%s' final allocation state: '%s'",
+                        device.getSerialNumber(), r.allocationState.toString());
+                return;
+            }
+        }
         // don't kill emulator if it wasn't launched by launchEmulator (ie emulatorProcess is null).
         if (ideviceToReturn.isEmulator() && managedDevice.getEmulatorProcess() != null) {
             try {
diff --git a/src/com/android/tradefed/device/IDeviceManager.java b/src/com/android/tradefed/device/IDeviceManager.java
index e34e2a2..3673140 100644
--- a/src/com/android/tradefed/device/IDeviceManager.java
+++ b/src/com/android/tradefed/device/IDeviceManager.java
@@ -68,6 +68,15 @@
     public ITestDevice allocateDevice(IDeviceSelection options);
 
     /**
+     * Request a device for testing that meets certain criteria.
+     *
+     * @param options the {@link IDeviceSelection} the device should meet.
+     * @param isTemporary whether or not a temporary NullDevice should be created.
+     * @return a {@link ITestDevice} for testing, or <code>null</code> if one is not available
+     */
+    public ITestDevice allocateDevice(IDeviceSelection options, boolean isTemporary);
+
+    /**
      * Rudely allocate a device, even if its not currently available.
      * <p/>
      * Will have no effect if device is already allocated.
diff --git a/src/com/android/tradefed/device/NullDevice.java b/src/com/android/tradefed/device/NullDevice.java
index cefe2a5..83e445e 100644
--- a/src/com/android/tradefed/device/NullDevice.java
+++ b/src/com/android/tradefed/device/NullDevice.java
@@ -23,7 +23,22 @@
  */
 public class NullDevice extends StubDevice {
 
+    private boolean mTemporaryDevice = false;
+
     public NullDevice(String serial) {
         super(serial, false);
     }
+
+    public NullDevice(String serial, boolean isTemporary) {
+        this(serial);
+        mTemporaryDevice = isTemporary;
+    }
+
+    /**
+     * Returns true if the device was created temporarily for the invocation and should be deleted
+     * afterward.
+     */
+    public final boolean isTemporary() {
+        return mTemporaryDevice;
+    }
 }
diff --git a/src/com/android/tradefed/device/RemoteAndroidDevice.java b/src/com/android/tradefed/device/RemoteAndroidDevice.java
index de31d78..3b971e6 100644
--- a/src/com/android/tradefed/device/RemoteAndroidDevice.java
+++ b/src/com/android/tradefed/device/RemoteAndroidDevice.java
@@ -57,6 +57,12 @@
         super(device, stateMonitor, allocationMonitor);
     }
 
+    @Override
+    public void postInvocationTearDown() {
+        super.postInvocationTearDown();
+        FileUtil.deleteFile(mAdbConnectLogs);
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/src/com/android/tradefed/device/StubDevice.java b/src/com/android/tradefed/device/StubDevice.java
index 729a95f..64d24ea 100644
--- a/src/com/android/tradefed/device/StubDevice.java
+++ b/src/com/android/tradefed/device/StubDevice.java
@@ -58,7 +58,6 @@
         mIsEmulator = isEmulator;
     }
 
-
     public void setSerial(String serial) {
         mSerial = serial;
     }
diff --git a/src/com/android/tradefed/sandbox/TradefedSandbox.java b/src/com/android/tradefed/sandbox/TradefedSandbox.java
index 39d6318..55c4a62 100644
--- a/src/com/android/tradefed/sandbox/TradefedSandbox.java
+++ b/src/com/android/tradefed/sandbox/TradefedSandbox.java
@@ -107,6 +107,7 @@
         }
 
         long timeout = config.getCommandOptions().getInvocationTimeout();
+        mRunUtil.allowInterrupt(false);
         CommandResult result =
                 mRunUtil.runTimedCmd(timeout, mStdout, mStderr, mCmdArgs.toArray(new String[0]));
         // Log stdout and stderr
diff --git a/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparer.java b/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparer.java
new file mode 100644
index 0000000..4344fcf
--- /dev/null
+++ b/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparer.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+
+/**
+ * Target preparer that disables SELinux if enabled.
+ *
+ * <p>Will restore back to original state on tear down.
+ */
+@OptionClass(alias = "disable-selinux-preparer")
+public class DisableSELinuxTargetPreparer extends BaseTargetPreparer implements ITargetCleaner {
+
+    private boolean mWasRoot = false;
+    private boolean mWasPermissive = false;
+    private static final String PERMISSIVE = "Permissive";
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException {
+        CommandResult result = device.executeShellV2Command("getenforce");
+        mWasPermissive = result.getStdout().contains(PERMISSIVE);
+        if (mWasPermissive) {
+            CLog.d(
+                    "SELinux was not enabled therefore DisableSELinuxTargetPreparer will do "
+                            + "nothing. This is because enabling 'setenforce 1' blindly on "
+                            + "tearDown can cause problems on devices that don't support it, "
+                            + "i.e. on gce avds the GPU will crash.");
+            return;
+        }
+        mWasRoot = device.isAdbRoot();
+        if (!mWasRoot && !device.enableAdbRoot()) {
+            throw new TargetSetupError("Failed to adb root device", device.getDeviceDescriptor());
+        }
+        CLog.d("Disabling SELinux.");
+        result = device.executeShellV2Command("setenforce 0");
+        if (result.getStatus() != CommandStatus.SUCCESS) {
+            throw new TargetSetupError(
+                    "Disabling SELinux failed with status: " + result.getStatus());
+        }
+        if (!mWasRoot) {
+            device.disableAdbRoot();
+        }
+    }
+
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e)
+            throws DeviceNotAvailableException {
+        if (mWasPermissive) {
+            return;
+        }
+        if (!mWasRoot) {
+            device.enableAdbRoot();
+        }
+        CLog.d("Enabling SELinux.");
+        CommandResult result = device.executeShellV2Command("setenforce 1");
+        if (!mWasRoot) {
+            device.disableAdbRoot();
+        }
+    }
+}
diff --git a/src/com/android/tradefed/targetprep/companion/CompanionDeviceTracker.java b/src/com/android/tradefed/targetprep/companion/CompanionDeviceTracker.java
index 2edd1f5..c9edfee 100644
--- a/src/com/android/tradefed/targetprep/companion/CompanionDeviceTracker.java
+++ b/src/com/android/tradefed/targetprep/companion/CompanionDeviceTracker.java
@@ -59,7 +59,7 @@
      * @return the device allocated or <code>null</code> if none available
      */
     public ITestDevice allocateCompanionDevice(ITestDevice device, DeviceSelectionOptions opt) {
-        ITestDevice companion = getDeviceManager().allocateDevice(opt);
+        ITestDevice companion = getDeviceManager().allocateDevice(opt, false);
         if (companion != null) {
             if (mDeviceMapping.containsKey(device)) {
                 CLog.w("device %s already has an allocated companion %s",
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index 17af8b2..259e1e1 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -154,6 +154,7 @@
 import com.android.tradefed.targetprep.DeviceSetupTest;
 import com.android.tradefed.targetprep.DeviceStorageFillerTest;
 import com.android.tradefed.targetprep.DeviceStringPusherTest;
+import com.android.tradefed.targetprep.DisableSELinuxTargetPreparerTest;
 import com.android.tradefed.targetprep.FastbootDeviceFlasherTest;
 import com.android.tradefed.targetprep.FlashingResourcesParserTest;
 import com.android.tradefed.targetprep.InstallAllTestZipAppsSetupTest;
@@ -482,6 +483,7 @@
     DeviceSetupTest.class,
     DeviceStorageFillerTest.class,
     DeviceStringPusherTest.class,
+    DisableSELinuxTargetPreparerTest.class,
     FastbootDeviceFlasherTest.class,
     FlashingResourcesParserTest.class,
     InstallAllTestZipAppsSetupTest.class,
diff --git a/tests/src/com/android/tradefed/device/DeviceManagerTest.java b/tests/src/com/android/tradefed/device/DeviceManagerTest.java
index 743143d..917dca7 100644
--- a/tests/src/com/android/tradefed/device/DeviceManagerTest.java
+++ b/tests/src/com/android/tradefed/device/DeviceManagerTest.java
@@ -17,7 +17,6 @@
 package com.android.tradefed.device;
 
 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-
 import com.android.ddmlib.IDevice;
 import com.android.ddmlib.IDevice.DeviceState;
 import com.android.tradefed.command.remote.DeviceDescriptor;
@@ -30,6 +29,7 @@
 import com.android.tradefed.util.CommandStatus;
 import com.android.tradefed.util.IRunUtil;
 import com.android.tradefed.util.RunUtil;
+
 import com.google.common.util.concurrent.SettableFuture;
 
 import junit.framework.TestCase;
@@ -37,6 +37,7 @@
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
+
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -294,8 +295,7 @@
     }
 
     /**
-     * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when device is
-     * returned.
+     * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean)} when device is returned.
      */
     public void testAllocateDevice_match() {
         DeviceSelectionOptions options = new DeviceSelectionOptions();
@@ -305,13 +305,51 @@
                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
         replayMocks();
         DeviceManager manager = createDeviceManager(null, mMockIDevice);
-        assertEquals(mMockTestDevice, manager.allocateDevice(options));
+        assertEquals(mMockTestDevice, manager.allocateDevice(options, false));
         EasyMock.verify(mMockStateMonitor);
     }
 
     /**
-     * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when stub emulator
-     * is requested
+     * Test that when allocating a fake device we create a placeholder then delete it at the end.
+     */
+    public void testAllocateDevice_match_temporary() {
+        DeviceSelectionOptions options = new DeviceSelectionOptions();
+        options.setNullDeviceRequested(true);
+        options.addSerial(DEVICE_SERIAL);
+        // Force create a device
+        EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
+                .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
+        // Device get allocated
+        EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
+                .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
+
+        mMockTestDevice.stopLogcat();
+
+        // De-allocate
+        EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN))
+                .andReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true));
+
+        replayMocks();
+        DeviceManager manager = createDeviceManager(null);
+        assertEquals(mMockTestDevice, manager.allocateDevice(options, true));
+        String serial = mMockTestDevice.getSerialNumber();
+        assertTrue(serial.startsWith("null-device-temp-"));
+
+        // Release device
+        manager.freeDevice(mMockTestDevice, FreeDeviceState.AVAILABLE);
+        // Check that temp device was deleted.
+        DeviceSelectionOptions validation = new DeviceSelectionOptions();
+        validation.setNullDeviceRequested(true);
+        validation.addSerial(serial);
+        // If we request the particular null-device again it doesn't exists.
+        assertNull(manager.allocateDevice(validation, false));
+
+        EasyMock.verify(mMockStateMonitor);
+    }
+
+    /**
+     * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean)} when stub emulator is
+     * requested
      */
     public void testAllocateDevice_stubEmulator() {
         DeviceSelectionOptions options = new DeviceSelectionOptions();
@@ -325,7 +363,7 @@
         DeviceManager mgr = createDeviceManagerNoInit();
         mgr.setMaxEmulators(1);
         mgr.init(null, null, mMockDeviceFactory);
-        assertNotNull(mgr.allocateDevice(options));
+        assertNotNull(mgr.allocateDevice(options, false));
         verifyMocks();
     }
 
@@ -353,19 +391,19 @@
         DeviceManager manager = createDeviceManagerNoInit();
         manager.setMaxEmulators(1);
         manager.init(null, null, mMockDeviceFactory);
-        IManagedTestDevice emulator = (IManagedTestDevice) manager.allocateDevice(options);
+        IManagedTestDevice emulator = (IManagedTestDevice) manager.allocateDevice(options, false);
         assertNotNull(emulator);
         // a freed 'unavailable' emulator should be returned to the available
         // queue.
         manager.freeDevice(emulator, FreeDeviceState.UNAVAILABLE);
         // ensure device can be allocated again
-        assertNotNull(manager.allocateDevice(options));
+        assertNotNull(manager.allocateDevice(options, false));
         verifyMocks();
     }
 
     /**
-     * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when a null device
-     * is requested.
+     * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean} when a null device is
+     * requested.
      */
     public void testAllocateDevice_nullDevice() {
         DeviceSelectionOptions options = new DeviceSelectionOptions();
@@ -379,7 +417,7 @@
         DeviceManager mgr = createDeviceManagerNoInit();
         mgr.setMaxNullDevices(1);
         mgr.init(null, null, mMockDeviceFactory);
-        ITestDevice device = mgr.allocateDevice(options);
+        ITestDevice device = mgr.allocateDevice(options, false);
         assertNotNull(device);
         assertTrue(device.getIDevice() instanceof NullDevice);
         verifyMocks();
@@ -900,13 +938,13 @@
         DeviceManager manager = createDeviceManagerNoInit();
         manager.setMaxTcpDevices(1);
         manager.init(null, null, mMockDeviceFactory);
-        IManagedTestDevice tcpDevice = (IManagedTestDevice) manager.allocateDevice(options);
+        IManagedTestDevice tcpDevice = (IManagedTestDevice) manager.allocateDevice(options, false);
         assertNotNull(tcpDevice);
         // a freed 'unavailable' emulator should be returned to the available
         // queue.
         manager.freeDevice(tcpDevice, FreeDeviceState.UNAVAILABLE);
         // ensure device can be allocated again
-        ITestDevice tcp = manager.allocateDevice(options);
+        ITestDevice tcp = manager.allocateDevice(options, false);
         assertNotNull(tcp);
         assertTrue(tcp.getDeviceState() == TestDeviceState.NOT_AVAILABLE);
         verifyMocks();
diff --git a/tests/src/com/android/tradefed/device/MockDeviceManager.java b/tests/src/com/android/tradefed/device/MockDeviceManager.java
index bab1b42..f23e3d1 100644
--- a/tests/src/com/android/tradefed/device/MockDeviceManager.java
+++ b/tests/src/com/android/tradefed/device/MockDeviceManager.java
@@ -246,6 +246,12 @@
     /** {@inheritDoc} */
     @Override
     public ITestDevice allocateDevice(IDeviceSelection options) {
+        return allocateDevice(options, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ITestDevice allocateDevice(IDeviceSelection options, boolean isTemporary) {
         if (mTcpDeviceRequested) {
             ((DeviceSelectionOptions)options).setTcpDeviceRequested(true);
         }
diff --git a/tests/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparerTest.java b/tests/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparerTest.java
new file mode 100644
index 0000000..42f5c4a
--- /dev/null
+++ b/tests/src/com/android/tradefed/targetprep/DisableSELinuxTargetPreparerTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 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.tradefed.targetprep;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit Tests for {@link DisableSELinuxTargetPreparerTest}. */
+@RunWith(JUnit4.class)
+public class DisableSELinuxTargetPreparerTest {
+
+    private DisableSELinuxTargetPreparer mDisableSELinuxTargetPreparer;
+    private ITestDevice mMockDevice;
+    private IBuildInfo mMockBuildInfo;
+    private static final String PERMISSIVE = "Permissive";
+    private static final String ENFORCED = "Enforced";
+    private static final String GETENFORCE = "getenforce";
+    private static final String SETENFORCE = "setenforce ";
+
+    @Before
+    public void setUp() {
+        mDisableSELinuxTargetPreparer = new DisableSELinuxTargetPreparer();
+        mMockDevice = EasyMock.createMock(ITestDevice.class);
+        mMockBuildInfo = EasyMock.createMock(IBuildInfo.class);
+    }
+
+    @Test
+    public void testSetUpSuccess_permissive() throws Exception {
+        CommandResult result = new CommandResult();
+        result.setStdout(PERMISSIVE);
+        result.setStatus(CommandStatus.SUCCESS);
+        EasyMock.expect(mMockDevice.executeShellV2Command(GETENFORCE)).andReturn(result).once();
+        EasyMock.replay(mMockDevice, mMockBuildInfo);
+
+        mDisableSELinuxTargetPreparer.setUp(mMockDevice, mMockBuildInfo);
+        mDisableSELinuxTargetPreparer.tearDown(mMockDevice, mMockBuildInfo, null);
+        EasyMock.verify(mMockDevice, mMockBuildInfo);
+    }
+
+    @Test
+    public void testSetUpSuccess_enforced_rootBefore() throws Exception {
+        CommandResult result = new CommandResult();
+        result.setStdout(ENFORCED);
+        result.setStatus(CommandStatus.SUCCESS);
+        EasyMock.expect(mMockDevice.executeShellV2Command(GETENFORCE)).andReturn(result).once();
+        EasyMock.expect(mMockDevice.isAdbRoot()).andReturn(true).once();
+        EasyMock.expect(mMockDevice.executeShellV2Command(SETENFORCE + "0"))
+                .andReturn(result)
+                .once();
+        EasyMock.expect(mMockDevice.executeShellV2Command(SETENFORCE + "1"))
+                .andReturn(result)
+                .once();
+        EasyMock.replay(mMockDevice, mMockBuildInfo);
+
+        mDisableSELinuxTargetPreparer.setUp(mMockDevice, mMockBuildInfo);
+        mDisableSELinuxTargetPreparer.tearDown(mMockDevice, mMockBuildInfo, null);
+        EasyMock.verify(mMockDevice, mMockBuildInfo);
+    }
+
+    @Test
+    public void testSetUpSuccess_enforced_notRootBefore() throws Exception {
+        CommandResult result = new CommandResult();
+        result.setStdout(ENFORCED);
+        result.setStatus(CommandStatus.SUCCESS);
+        EasyMock.expect(mMockDevice.executeShellV2Command(GETENFORCE)).andReturn(result).once();
+        EasyMock.expect(mMockDevice.isAdbRoot()).andReturn(false).once();
+        EasyMock.expect(mMockDevice.enableAdbRoot()).andReturn(true).times(2);
+        EasyMock.expect(mMockDevice.disableAdbRoot()).andReturn(true).times(2);
+
+        EasyMock.expect(mMockDevice.executeShellV2Command(SETENFORCE + "0"))
+                .andReturn(result)
+                .once();
+        EasyMock.expect(mMockDevice.executeShellV2Command(SETENFORCE + "1"))
+                .andReturn(result)
+                .once();
+        EasyMock.replay(mMockDevice, mMockBuildInfo);
+
+        mDisableSELinuxTargetPreparer.setUp(mMockDevice, mMockBuildInfo);
+        mDisableSELinuxTargetPreparer.tearDown(mMockDevice, mMockBuildInfo, null);
+        EasyMock.verify(mMockDevice, mMockBuildInfo);
+    }
+
+    @Test(expected = TargetSetupError.class)
+    public void testSetUp_rootFail() throws Exception {
+        CommandResult result = new CommandResult();
+        result.setStdout(ENFORCED);
+        EasyMock.expect(mMockDevice.executeShellV2Command(GETENFORCE)).andReturn(result).once();
+        EasyMock.expect(mMockDevice.isAdbRoot()).andReturn(false).once();
+        EasyMock.expect(mMockDevice.enableAdbRoot()).andReturn(false).once();
+        EasyMock.expect(mMockDevice.getDeviceDescriptor()).andReturn(null).once();
+        try {
+            EasyMock.replay(mMockDevice, mMockBuildInfo);
+            mDisableSELinuxTargetPreparer.setUp(mMockDevice, mMockBuildInfo);
+        } finally {
+            EasyMock.verify(mMockDevice, mMockBuildInfo);
+        }
+    }
+
+    @Test(expected = TargetSetupError.class)
+    public void testSetUp_disableSELinuxFail() throws Exception {
+        CommandResult result = new CommandResult();
+        result.setStdout(ENFORCED);
+        result.setStatus(CommandStatus.FAILED);
+        EasyMock.expect(mMockDevice.executeShellV2Command(GETENFORCE)).andReturn(result).once();
+        EasyMock.expect(mMockDevice.isAdbRoot()).andReturn(false).once();
+        EasyMock.expect(mMockDevice.enableAdbRoot()).andReturn(true).once();
+        EasyMock.expect(mMockDevice.executeShellV2Command(SETENFORCE + "0"))
+                .andReturn(result)
+                .once();
+        try {
+            EasyMock.replay(mMockDevice, mMockBuildInfo);
+            mDisableSELinuxTargetPreparer.setUp(mMockDevice, mMockBuildInfo);
+        } finally {
+            EasyMock.verify(mMockDevice, mMockBuildInfo);
+        }
+    }
+}