blob: 56340c63008ee4efaad0c0588f06af09a577e754 [file] [log] [blame]
/*
* Copyright (C) 2010 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.device;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import com.android.ddmlib.IDevice;
import com.android.helper.aoa.UsbDevice;
import com.android.helper.aoa.UsbHelper;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.IRunUtil;
import com.google.common.util.concurrent.SettableFuture;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
/** Unit tests for {@link WaitDeviceRecovery}. */
@RunWith(JUnit4.class)
public class WaitDeviceRecoveryTest {
@Mock IRunUtil mMockRunUtil;
private WaitDeviceRecovery mRecovery;
@Mock IDeviceStateMonitor mMockMonitor;
@Mock IDevice mMockDevice;
private UsbHelper mMockUsbHelper;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mMockUsbHelper = Mockito.mock(UsbHelper.class);
mRecovery =
new WaitDeviceRecovery() {
@Override
protected IRunUtil getRunUtil() {
return mMockRunUtil;
}
@Override
UsbHelper getUsbHelper() {
return mMockUsbHelper;
}
};
when(mMockMonitor.getSerialNumber()).thenReturn("serial");
}
/**
* Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when devices
* comes back online on its own accord.
*/
@Test
public void testRecoverDevice_success() throws DeviceNotAvailableException {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(true);
when(mMockMonitor.waitForDeviceAvailable(Mockito.anyLong())).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
mRecovery.recoverDevice(mMockMonitor, false);
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
}
/**
* Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is
* not available.
*/
@Test
public void testRecoverDevice_unavailable() {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(null);
try {
mRecovery.recoverDevice(mMockMonitor, false);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException e) {
// expected
}
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
}
@Test
public void testRecoverDevice_unavailable_recovers() throws Exception {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(null);
UsbDevice mockDevice = Mockito.mock(UsbDevice.class);
doReturn(mockDevice).when(mMockUsbHelper).getDevice("serial");
when(mMockMonitor.waitForDeviceAvailable()).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
// Device recovers successfully
mRecovery.recoverDevice(mMockMonitor, false);
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
verify(mockDevice).reset();
}
@Test
public void testRecoverDevice_unavailable_recovery_fail() throws Exception {
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.RECOVERY);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(null);
try {
mRecovery.recoverDevice(mMockMonitor, false);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException e) {
// expected
}
verify(mMockMonitor, times(2)).getDeviceState();
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
}
@Test
public void testRecoverDevice_unavailable_fastboot() throws Exception {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.FASTBOOT);
CommandResult result = new CommandResult();
result.setStatus(CommandStatus.SUCCESS);
// expect reboot
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("reboot")))
.thenReturn(result);
when(mMockMonitor.getFastbootSerialNumber()).thenReturn("serial");
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(null);
try {
mRecovery.recoverDevice(mMockMonitor, false);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException e) {
// expected
}
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
}
/**
* Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is
* not responsive.
*/
@Test
public void testRecoverDevice_unresponsive() throws Exception {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.ONLINE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(true);
when(mMockMonitor.waitForDeviceAvailable(Mockito.anyLong())).thenReturn(null);
try {
mRecovery.recoverDevice(mMockMonitor, false);
fail("DeviceUnresponsiveException not thrown");
} catch (DeviceUnresponsiveException e) {
// expected
}
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
verify(mMockDevice).reboot((String) Mockito.isNull());
}
/**
* Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is in
* fastboot.
*/
@Test
public void testRecoverDevice_fastboot() throws DeviceNotAvailableException {
// expect initial sleep
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.FASTBOOT);
CommandResult result = new CommandResult();
result.setStatus(CommandStatus.SUCCESS);
// expect reboot
when(mMockMonitor.getFastbootSerialNumber()).thenReturn("serial");
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("reboot")))
.thenReturn(result);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(true);
when(mMockMonitor.waitForDeviceAvailable(Mockito.anyLong())).thenReturn(mMockDevice);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
mRecovery.recoverDevice(mMockMonitor, false);
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockMonitor).waitForDeviceBootloaderStateUpdate();
}
/**
* Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is
* already in bootloader
*/
@Test
public void testRecoverDeviceBootloader_fastboot() throws DeviceNotAvailableException {
// expect reboot
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("reboot-bootloader")))
.thenReturn(new CommandResult(CommandStatus.SUCCESS));
when(mMockMonitor.waitForDeviceNotAvailable(Mockito.anyLong())).thenReturn(Boolean.TRUE);
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong())).thenReturn(Boolean.TRUE);
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("getvar"),
Mockito.eq("product")))
.thenReturn(new CommandResult(CommandStatus.SUCCESS));
mRecovery.recoverDeviceBootloader(mMockMonitor);
verify(mMockMonitor, times(2)).waitForDeviceBootloader(Mockito.anyLong());
verify(mMockRunUtil).sleep(Mockito.anyLong());
}
/**
* Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is
* unavailable but comes back to bootloader on its own
*/
@Test
public void testRecoverDeviceBootloader_unavailable() throws DeviceNotAvailableException {
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong())).thenReturn(Boolean.FALSE);
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE);
// expect reboot
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("reboot-bootloader")))
.thenReturn(new CommandResult(CommandStatus.SUCCESS));
when(mMockMonitor.waitForDeviceNotAvailable(Mockito.anyLong())).thenReturn(Boolean.TRUE);
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong())).thenReturn(Boolean.TRUE);
when(mMockRunUtil.runTimedCmd(
Mockito.anyLong(),
Mockito.eq("fastboot"),
Mockito.eq("-s"),
Mockito.eq("serial"),
Mockito.eq("getvar"),
Mockito.eq("product")))
.thenReturn(new CommandResult(CommandStatus.SUCCESS));
mRecovery.recoverDeviceBootloader(mMockMonitor);
verify(mMockMonitor, times(2)).waitForDeviceBootloader(Mockito.anyLong());
verify(mMockRunUtil).sleep(Mockito.anyLong());
}
/**
* Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is
* online when bootloader is expected
*/
@Test
public void testRecoverDeviceBootloader_online() throws Exception {
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong()))
.thenReturn(Boolean.FALSE, Boolean.TRUE);
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.ONLINE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
mRecovery.recoverDeviceBootloader(mMockMonitor);
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockDevice).reboot("bootloader");
}
/**
* Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is
* initially unavailable, then comes online when bootloader is expected
*/
@Test
public void testRecoverDeviceBootloader_unavailable_online() throws Exception {
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong()))
.thenReturn(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE);
when(mMockMonitor.getDeviceState())
.thenReturn(TestDeviceState.NOT_AVAILABLE, TestDeviceState.ONLINE);
when(mMockMonitor.waitForDeviceOnline(Mockito.anyLong())).thenReturn(mMockDevice);
mRecovery.recoverDeviceBootloader(mMockMonitor);
verify(mMockRunUtil).sleep(Mockito.anyLong());
verify(mMockDevice).reboot("bootloader");
}
/**
* Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is
* unavailable
*/
@Test
public void testRecoverDeviceBootloader_unavailable_failure() throws Exception {
when(mMockMonitor.waitForDeviceBootloader(Mockito.anyLong())).thenReturn(Boolean.FALSE);
when(mMockMonitor.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE);
try {
mRecovery.recoverDeviceBootloader(mMockMonitor);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException e) {
// expected
}
verify(mMockRunUtil).sleep(Mockito.anyLong());
}
/**
* Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} throws an exception if battery
* level is not readable.
*/
@Test
public void testCheckMinBatteryLevel_unreadable() throws Exception {
OptionSetter setter = new OptionSetter(mRecovery);
setter.setOptionValue("min-battery-after-recovery", "50");
SettableFuture<Integer> future = SettableFuture.create();
future.set(null);
when(mMockDevice.getBattery()).thenReturn(future);
when(mMockDevice.getSerialNumber()).thenReturn("SERIAL");
try {
mRecovery.checkMinBatteryLevel(mMockDevice);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException expected) {
assertEquals("Cannot read battery level but a min is required", expected.getMessage());
}
}
/**
* Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} throws an exception if battery
* level is below the minimal expected.
*/
@Test
public void testCheckMinBatteryLevel_belowLevel() throws Exception {
OptionSetter setter = new OptionSetter(mRecovery);
setter.setOptionValue("min-battery-after-recovery", "50");
SettableFuture<Integer> future = SettableFuture.create();
future.set(49);
when(mMockDevice.getBattery()).thenReturn(future);
when(mMockDevice.getSerialNumber()).thenReturn("SERIAL");
try {
mRecovery.checkMinBatteryLevel(mMockDevice);
fail("DeviceNotAvailableException not thrown");
} catch (DeviceNotAvailableException expected) {
assertEquals("After recovery, device battery level 49 is lower than required minimum "
+ "50", expected.getMessage());
}
}
/**
* Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} returns without exception when
* battery level after recovery is above or equals minimum expected.
*/
@Test
public void testCheckMinBatteryLevel() throws Exception {
OptionSetter setter = new OptionSetter(mRecovery);
setter.setOptionValue("min-battery-after-recovery", "50");
SettableFuture<Integer> future = SettableFuture.create();
future.set(50);
when(mMockDevice.getBattery()).thenReturn(future);
mRecovery.checkMinBatteryLevel(mMockDevice);
}
}