diff options
author | Oliver Nguyen <olivernguyen@google.com> | 2020-09-09 12:45:34 -0700 |
---|---|---|
committer | Oliver Nguyen <olivernguyen@google.com> | 2020-10-07 20:50:10 +0000 |
commit | 54ad41b840d2a467db6474f256bfcec4eaeec8eb (patch) | |
tree | 7da3bfcdfe651f06495472dfabcf1778e213d638 | |
parent | c25fc46b617f76f42bd1cac6a0ccf4a16ca009d6 (diff) | |
download | tradefederation-54ad41b840d2a467db6474f256bfcec4eaeec8eb.tar.gz |
Add utility class to temporarily elevate adb root.
Test: Unit tests
Bug: 159843590
Change-Id: Ie96a40ba8c47deef601cf73ddea786d4dbf0516c
Merged-In: Ie96a40ba8c47deef601cf73ddea786d4dbf0516c
-rw-r--r-- | src/com/android/tradefed/util/AdbRootElevator.java | 49 | ||||
-rw-r--r-- | tests/src/com/android/tradefed/UnitTests.java | 2 | ||||
-rw-r--r-- | tests/src/com/android/tradefed/util/AdbRootElevatorTest.java | 102 |
3 files changed, 153 insertions, 0 deletions
diff --git a/src/com/android/tradefed/util/AdbRootElevator.java b/src/com/android/tradefed/util/AdbRootElevator.java new file mode 100644 index 000000000..fa6eb0cea --- /dev/null +++ b/src/com/android/tradefed/util/AdbRootElevator.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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.util; + +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.INativeDevice; + +/** + * An {@link java.lang.AutoCloseable} that enables adb root when constructed if needed and restores + * root state when complete. + */ +public class AdbRootElevator implements AutoCloseable { + private final boolean mWasRoot; + private final INativeDevice mDevice; + + public AdbRootElevator(INativeDevice device) throws DeviceNotAvailableException { + mDevice = device; + mWasRoot = mDevice.isAdbRoot(); + if (!mWasRoot) { + if (!mDevice.enableAdbRoot()) { + throw new RuntimeException("Failed to enable adb root."); + } + } + } + + @Override + public void close() { + if (!mWasRoot) { + try { + mDevice.disableAdbRoot(); + } catch (DeviceNotAvailableException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java index b9ec8821e..60bc4bfb6 100644 --- a/tests/src/com/android/tradefed/UnitTests.java +++ b/tests/src/com/android/tradefed/UnitTests.java @@ -335,6 +335,7 @@ import com.android.tradefed.testtype.suite.retry.RetryReschedulerTest; import com.android.tradefed.util.AaptParserTest; import com.android.tradefed.util.AbiFormatterTest; import com.android.tradefed.util.AbiUtilsTest; +import com.android.tradefed.util.AdbRootElevatorTest; import com.android.tradefed.util.AppVersionFetcherTest; import com.android.tradefed.util.ArrayUtilTest; import com.android.tradefed.util.BluetoothUtilsTest; @@ -848,6 +849,7 @@ import org.junit.runners.Suite.SuiteClasses; AaptParserTest.class, AbiFormatterTest.class, AbiUtilsTest.class, + AdbRootElevatorTest.class, AppVersionFetcherTest.class, ArrayUtilTest.class, BluetoothUtilsTest.class, diff --git a/tests/src/com/android/tradefed/util/AdbRootElevatorTest.java b/tests/src/com/android/tradefed/util/AdbRootElevatorTest.java new file mode 100644 index 000000000..2e808d341 --- /dev/null +++ b/tests/src/com/android/tradefed/util/AdbRootElevatorTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 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.util; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.INativeDevice; + +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link AdbRootElevator}. */ +@RunWith(JUnit4.class) +public class AdbRootElevatorTest { + @Mock INativeDevice mMockDevice; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testEnablesAndDisablesRoot() throws Exception { + when(mMockDevice.isAdbRoot()).thenReturn(false); + when(mMockDevice.enableAdbRoot()).thenReturn(true); + + try (AdbRootElevator adbRoot = new AdbRootElevator(mMockDevice)) { + mMockDevice.waitForDeviceAvailable(); + } + + InOrder inOrder = Mockito.inOrder(mMockDevice); + inOrder.verify(mMockDevice).isAdbRoot(); + inOrder.verify(mMockDevice).enableAdbRoot(); + inOrder.verify(mMockDevice).waitForDeviceAvailable(); + inOrder.verify(mMockDevice).disableAdbRoot(); + } + + @Test + public void testRootAlreadyEnabled_doesNotEnableOrDisableRoot() throws Exception { + when(mMockDevice.isAdbRoot()).thenReturn(true); + + try (AdbRootElevator adbRoot = new AdbRootElevator(mMockDevice)) { + mMockDevice.waitForDeviceAvailable(); + } + + InOrder inOrder = Mockito.inOrder(mMockDevice); + inOrder.verify(mMockDevice).isAdbRoot(); + inOrder.verify(mMockDevice).waitForDeviceAvailable(); + inOrder.verifyNoMoreInteractions(); + } + + @Test + public void testFailsToEnableAdbRoot_throwsException() throws Exception { + when(mMockDevice.isAdbRoot()).thenReturn(false); + when(mMockDevice.enableAdbRoot()).thenReturn(false); + + try (AdbRootElevator adbRoot = new AdbRootElevator(mMockDevice)) { + fail("Exception should have already been thrown."); + } catch (Exception e) { + // Expected. + } + + verify(mMockDevice, never()).disableAdbRoot(); + } + + @Test + public void testDeviceNotAvailableOnRoot_throwsException() throws Exception { + when(mMockDevice.isAdbRoot()).thenReturn(false); + when(mMockDevice.enableAdbRoot()).thenThrow(new DeviceNotAvailableException()); + + try (AdbRootElevator adbRoot = new AdbRootElevator(mMockDevice)) { + fail("Exception should have already been thrown."); + } catch (DeviceNotAvailableException e) { + // Expected. + } + + verify(mMockDevice, never()).disableAdbRoot(); + } +} |