blob: 9443a33218dccad89d84dc9e8869713657f72b1d [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 com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IDevice.DeviceState;
import com.android.tradefed.device.IDeviceManager.FreeDeviceState;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.IRunUtil;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
/**
* Unit tests for {@link DeviceManager}.
*/
public class DeviceManagerTest extends TestCase {
/**
* A wait time value to provide to allocateDevice that results in reliable test results.
* <p/>
* Setting this constant to a value less than 100 may cause actual wait times to be much
* higher.
*/
private static final int MIN_ALLOCATE_WAIT_TIME = 100;
private static final String DEVICE_SERIAL = "serial";
/**
* Helper interface to mock behavior for
* {@link DeviceManager#createTestDevice(IDevice, IDeviceStateMonitor)}.
*/
private interface ITestDeviceFactory {
IManagedTestDevice createDevice();
}
private IAndroidDebugBridge mMockAdbBridge;
private IDevice mMockIDevice;
private IDeviceStateMonitor mMockMonitor;
private IManagedTestDevice mMockTestDevice;
private IRunUtil mMockRunUtil;
private ITestDeviceFactory mMockDeviceFactory;
/** a reference to the DeviceManager's IDeviceChangeListener. Used for triggering device
* connection events */
private IDeviceChangeListener mDeviceListener;
static class MockProcess extends Process {
/**
* {@inheritDoc}
*/
@Override
public void destroy() {
// ignore
}
/**
* {@inheritDoc}
*/
@Override
public int exitValue() {
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getErrorStream() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public InputStream getInputStream() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public OutputStream getOutputStream() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public int waitFor() throws InterruptedException {
return 0;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void setUp() throws Exception {
super.setUp();
mMockAdbBridge = EasyMock.createNiceMock(IAndroidDebugBridge.class);
mMockAdbBridge.addDeviceChangeListener((IDeviceChangeListener)EasyMock.anyObject());
EasyMock.expectLastCall().andDelegateTo(new IAndroidDebugBridge() {
public void addDeviceChangeListener(final IDeviceChangeListener listener) {
mDeviceListener = listener;
}
public IDevice[] getDevices() {
return null;
}
public void removeDeviceChangeListener(IDeviceChangeListener listener) {
}
public void init(boolean clientSupport, String adbOsLocation) {
}
public void terminate() {
}
@Override
public void disconnectBridge() {
}
});
mMockIDevice = EasyMock.createMock(IDevice.class);
mMockMonitor = EasyMock.createMock(IDeviceStateMonitor.class);
mMockTestDevice = EasyMock.createMock(IManagedTestDevice.class);
mMockRunUtil = EasyMock.createMock(IRunUtil.class);
mMockDeviceFactory = EasyMock.createMock(ITestDeviceFactory.class);
EasyMock.expect(mMockIDevice.getSerialNumber()).andStubReturn(DEVICE_SERIAL);
EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
EasyMock.expect(mMockTestDevice.getSerialNumber()).andStubReturn(DEVICE_SERIAL);
EasyMock.expect(mMockTestDevice.getIDevice()).andStubReturn(mMockIDevice);
EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), (String)EasyMock.anyObject(),
(String)EasyMock.anyObject())).andStubReturn(new CommandResult());
EasyMock.expect(mMockRunUtil.runTimedCmdSilently(EasyMock.anyLong(), (String)EasyMock.
anyObject(), (String)EasyMock.anyObject())).andStubReturn(new CommandResult());
}
private DeviceManager createDeviceManager(IDevice... devices) {
DeviceManager mgr = createDeviceManagerNoInit();
mgr.init();
for (IDevice device : devices) {
mDeviceListener.deviceConnected(device);
}
return mgr;
}
private DeviceManager createDeviceManagerNoInit() {
DeviceManager mgr = new DeviceManager() {
@Override
IAndroidDebugBridge createAdbBridge() {
return mMockAdbBridge;
}
@Override
void startFastbootMonitor() {
}
@Override
IDeviceStateMonitor createStateMonitor(IDevice device) {
return mMockMonitor;
}
@Override
IManagedTestDevice createTestDevice(IDevice allocatedDevice,
IDeviceStateMonitor monitor) {
return mMockDeviceFactory.createDevice();
}
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
}
};
mgr.setEnableLogcat(false);
mgr.setSynchronousMode(true);
return mgr;
}
/**
* Test @link DeviceManager#allocateDevice()} when a IDevice is present on DeviceManager
* creation.
*/
public void testAllocateDevice() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
EasyMock.verify(mMockMonitor);
}
/**
* Verify that {@link DeviceManager#allocateDevice()} can allocate an asynchronously-connected
* device.
*/
public void testAllocateDevice_wait() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager();
// call the listener back on a different thread
new Thread() {
@Override
public void run() {
mDeviceListener.deviceConnected(mMockIDevice);
}
}.start();
assertEquals(mMockTestDevice, manager.allocateDevice());
EasyMock.verify(mMockMonitor);
}
/**
* Test {@link DeviceManager#allocateDevice(long))} when device is returned
*/
public void testAllocateDevice_time() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice(100));
EasyMock.verify(mMockMonitor);
}
/**
* Test {@link DeviceManager#allocateDevice(long))} when timeout is reached.
*/
public void testAllocateDevice_timeout() throws DeviceNotAvailableException {
replayMocks();
DeviceManager manager = createDeviceManager();
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Test {@link DeviceManager#allocateDevice(long, DeviceSelectionOptions))} when device is
* returned.
*/
public void testAllocateDevice_match() throws DeviceNotAvailableException {
DeviceSelectionOptions options = new DeviceSelectionOptions();
options.addSerial(DEVICE_SERIAL);
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice(100, options));
EasyMock.verify(mMockMonitor);
}
/**
* Test {@link DeviceManager#allocateDevice(long, DeviceSelectionOptions))} when timeout is
* reached.
*/
public void testAllocateDevice_matchTimeout() throws DeviceNotAvailableException {
DeviceSelectionOptions options = new DeviceSelectionOptions();
options.addExcludeSerial(DEVICE_SERIAL);
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME, options));
assertNotNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Test {@link DeviceManager#allocateDevice(long, DeviceSelectionOptions))} when emulator is
* requested
*/
public void testAllocateDevice_emulator() throws DeviceNotAvailableException {
DeviceSelectionOptions options = new DeviceSelectionOptions();
options.setEmulatorRequested(true);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
replayMocks();
DeviceManager manager = createDeviceManager();
assertNotNull(manager.allocateDevice(100, options));
}
/**
* Test freeing an emulator
*/
public void testFreeDevice_emulator() throws DeviceNotAvailableException {
DeviceSelectionOptions options = new DeviceSelectionOptions();
options.setEmulatorRequested(true);
IManagedTestDevice mockEmulator = EasyMock.createMock(IManagedTestDevice.class);
EasyMock.expect(mockEmulator.getSerialNumber()).andStubReturn("emulator-5554");
// allocate call
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mockEmulator).times(2);
// simulate a emulator launch
EasyMock.expect(mockEmulator.getEmulatorProcess()).andReturn(new MockProcess()).times(2);
IDevice mockIEmulator = EasyMock.createMock(IDevice.class);
EasyMock.expect(mockIEmulator.getSerialNumber()).andStubReturn("emulator-5554");
EasyMock.expect(mockEmulator.getIDevice()).andStubReturn(mockIEmulator);
EasyMock.expect(mockIEmulator.isEmulator()).andReturn(Boolean.TRUE);
EasyMock.expect(mockEmulator.waitForDeviceNotAvailable(EasyMock.anyLong())).andReturn(
Boolean.TRUE);
mockEmulator.stopLogcat();
replayMocks(mockEmulator, mockIEmulator);
DeviceManager manager = createDeviceManager();
assertEquals(mockEmulator, manager.allocateDevice(100, options));
// a freed 'unavailable' emulator should be returned to the available queue.
manager.freeDevice(mockEmulator, FreeDeviceState.UNAVAILABLE);
// ensure device can be allocated again
assertEquals(mockEmulator, manager.allocateDevice(100, options));
}
/**
* Test {@link DeviceManager#allocateDevice(long, DeviceSelectionOptions))} when a null device
* is requested.
*/
public void testAllocateDevice_nullDevice() throws DeviceNotAvailableException {
DeviceSelectionOptions options = new DeviceSelectionOptions();
options.setNullDeviceRequested(true);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
replayMocks();
DeviceManager manager = createDeviceManager();
assertNotNull(manager.allocateDevice(100, options));
}
/**
* Test that DeviceManager will add devices on fastboot to available queue on startup, and
* that they can be allocated.
*/
public void testAllocateDevice_fastboot() throws DeviceNotAvailableException {
EasyMock.reset(mMockRunUtil);
// mock 'fastboot help' call
EasyMock.expect(mMockRunUtil.runTimedCmdSilently(EasyMock.anyLong(),
EasyMock.eq("fastboot"), EasyMock.eq("help"))).andReturn(new CommandResult(
CommandStatus.SUCCESS));
// mock 'fastboot devices' call to return one device
CommandResult fastbootResult = new CommandResult(
CommandStatus.SUCCESS);
fastbootResult.setStdout("serial fastboot\n");
EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(),
EasyMock.eq("fastboot"), EasyMock.eq("devices"))).andReturn(fastbootResult);
mMockTestDevice.setDeviceState(TestDeviceState.FASTBOOT);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
replayMocks();
DeviceManager manager = createDeviceManager();
assertNotNull(manager.allocateDevice(100));
}
/**
* Test method for {@link DeviceManager#freeDevice(ITestDevice)}.
*/
public void testFreeDevice() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
mMockTestDevice.stopLogcat();
// mock the second allocate device call
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
replayMocks();
DeviceManager manager = createDeviceManager();
mDeviceListener.deviceConnected(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
manager.freeDevice(mMockTestDevice, FreeDeviceState.AVAILABLE);
// verify same device can be allocated again
assertEquals(mMockTestDevice, manager.allocateDevice());
}
/**
* Verified that {@link DeviceManager#freeDevice(ITestDevice)} ignores a call with a device
* that has not been allocated.
*/
public void testFreeDevice_noop() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
IManagedTestDevice testDevice = EasyMock.createNiceMock(IManagedTestDevice.class);
EasyMock.expect(testDevice.getSerialNumber()).andReturn("dontexist");
EasyMock.expect(testDevice.getIDevice()).andReturn(EasyMock.createNiceMock(IDevice.class));
replayMocks(testDevice);
DeviceManager manager = createDeviceManager(mMockIDevice);
manager.freeDevice(testDevice, FreeDeviceState.AVAILABLE);
}
/**
* Verified that {@link DeviceManager} calls {@link IManagedTestDevice#setIDevice(IDevice)}
* when DDMS allocates a new IDevice on connection.
*/
public void testSetIDevice() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
IDevice newMockDevice = EasyMock.createMock(IDevice.class);
EasyMock.expect(newMockDevice.getSerialNumber()).andReturn(DEVICE_SERIAL).anyTimes();
EasyMock.expect(newMockDevice.getState()).andReturn(DeviceState.ONLINE);
mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
mMockTestDevice.setIDevice(newMockDevice);
mMockTestDevice.setDeviceState(TestDeviceState.ONLINE);
replayMocks(newMockDevice);
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
// now trigger a device disconnect + reconnection
mDeviceListener.deviceDisconnected(mMockIDevice);
mDeviceListener.deviceConnected(newMockDevice);
EasyMock.verify(mMockTestDevice);
}
/**
* Verified that a disconnected device cannot be allocated
*/
public void testAllocateDevice_disconnected() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
mMockTestDevice.stopLogcat();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
// allocate and free the device first to handle the asynchronous checkAvailableDevice()
// stuff
ITestDevice device = manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME);
assertNotNull(device);
manager.freeDevice(device, FreeDeviceState.AVAILABLE);
mDeviceListener.deviceDisconnected(mMockIDevice);
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Verified that a offline device cannot be allocated
*/
public void testAllocateDevice_offline() throws DeviceNotAvailableException {
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.OFFLINE);
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Verified that a newly connected offline device cannot be allocated
*/
public void testAllocateDevice_connectedOffline() throws DeviceNotAvailableException {
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.OFFLINE);
replayMocks();
DeviceManager manager = createDeviceManager();
mDeviceListener.deviceConnected(mMockIDevice);
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Verified that a offline device that becomes online can be allocated
*/
public void testAllocateDevice_offlineOnline() throws DeviceNotAvailableException {
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.OFFLINE);
setCheckAvailableDeviceExpectations();
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
mDeviceListener.deviceChanged(mMockIDevice, IDevice.CHANGE_STATE);
assertNotNull(manager.allocateDevice());
}
/**
* Test {@link DeviceManager#allocateDevice()} when {@link DeviceManager#init()} has not
* been called.
*/
public void testAllocateDevice_noInit() throws DeviceNotAvailableException {
try {
createDeviceManagerNoInit().allocateDevice();
fail("IllegalStateException not thrown when manager has not been initialized");
} catch (IllegalStateException e) {
// expected
}
}
/**
* Verify {@link DeviceManager#allocateDevice()} serves callers in a first-called-first-served
* order.
*/
public void testAllocateDevice_firstCalledFirstServed() throws Exception {
setCheckAvailableDeviceExpectations();
// keep EasyMock happy - expect stopLogcat call on each freeDevice call
mMockTestDevice.stopLogcat();
EasyMock.expectLastCall().times(2);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice).times(2);
replayMocks();
// simulate no devices available on DeviceManager start up
DeviceManager manager = createDeviceManager();
AllocateCaller firstCaller = new AllocateCaller(manager);
AllocateCaller secondCaller = new AllocateCaller(manager);
AllocateCaller thirdCaller = new AllocateCaller(manager);
firstCaller.startAndWait();
secondCaller.startAndWait();
thirdCaller.startAndWait();
// add a device which can be allocated
mDeviceListener.deviceConnected(mMockIDevice);
// expect that the firstCaller receives this device
assertTrue(firstCaller.waitForAllocate());
manager.freeDevice(firstCaller.mAllocatedDevice, FreeDeviceState.AVAILABLE);
// expect that the second caller gets the device once freed
assertTrue(secondCaller.waitForAllocate());
manager.freeDevice(secondCaller.mAllocatedDevice, FreeDeviceState.AVAILABLE);
// expect that, finally, the thirdCaller gets the device once freed for the second time
assertTrue(thirdCaller.waitForAllocate());
}
/**
* A helper class for performing {@link DeviceManager#allocateDevice()} calls on a background
* thread
*/
private static class AllocateCaller extends Thread {
ITestDevice mAllocatedDevice = null;
final IDeviceManager mManager;
AllocateCaller(IDeviceManager manager) {
mManager = manager;
}
@Override
public void run() {
synchronized (this) {
notify();
}
mAllocatedDevice = mManager.allocateDevice();
synchronized (this) {
notify();
}
}
/**
* Starts this thread, and blocks until it actually starts
*/
public void startAndWait() throws InterruptedException {
mAllocatedDevice = null;
synchronized (this) {
start();
wait();
}
// hack, sleep a small amount for allocate call to really occur
Thread.sleep(10);
}
/**
* Waits for the {@link DeviceManager#allocateDevice()} call to occur. Assumes thread is
* already started
* @return <code>true</code> if device was allocated, <code>false</code> otherwise
* @throws InterruptedException
*/
public boolean waitForAllocate() throws InterruptedException {
synchronized (this) {
wait(MIN_ALLOCATE_WAIT_TIME);
}
return mAllocatedDevice != null;
}
}
/**
* Test {@link DeviceManager#init(IDeviceSelectionOptions)} with a global exclusion filter
*/
public void testInit_excludeDevice() throws DeviceNotAvailableException {
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
replayMocks();
DeviceManager manager = createDeviceManagerNoInit();
DeviceSelectionOptions excludeFilter = new DeviceSelectionOptions();
excludeFilter.addExcludeSerial(mMockIDevice.getSerialNumber());
manager.init(excludeFilter);
mDeviceListener.deviceConnected(mMockIDevice);
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
}
/**
* Test {@link DeviceManager#init(IDeviceSelectionOptions)} with a global inclusion filter
*/
public void testInit_includeDevice() throws DeviceNotAvailableException {
IDevice excludedDevice = EasyMock.createMock(IDevice.class);
EasyMock.expect(excludedDevice.getSerialNumber()).andStubReturn("excluded");
EasyMock.expect(excludedDevice.getState()).andStubReturn(DeviceState.ONLINE);
setCheckAvailableDeviceExpectations();
replayMocks(excludedDevice);
DeviceManager manager = createDeviceManagerNoInit();
DeviceSelectionOptions includeFilter = new DeviceSelectionOptions();
includeFilter.addSerial(mMockIDevice.getSerialNumber());
manager.init(includeFilter);
mDeviceListener.deviceConnected(mMockIDevice);
mDeviceListener.deviceConnected(excludedDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
// ensure excludedDevice cannot be allocated
assertNull(manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
EasyMock.verify(mMockMonitor);
}
/**
* Verified that a online device that becomes offline can be allocated
*/
public void testAllocateDevice_onlineOffline() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.OFFLINE);
mMockTestDevice.stopLogcat();
mMockTestDevice.setDeviceState(TestDeviceState.OFFLINE);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
mDeviceListener.deviceChanged(mMockIDevice, IDevice.CHANGE_STATE);
// verify device can still be allocated even though its in offline state
// this is desired because then recovery can attempt to resurrect the device
assertEquals(mMockTestDevice, manager.allocateDevice());
}
/**
* Verified that a disconnected device state gets updated
*/
public void testSetState_disconnected() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
mDeviceListener.deviceDisconnected(mMockIDevice);
EasyMock.verify(mMockTestDevice);
}
/**
* Verified that a offline device state gets updated
*/
public void testSetState_offline() throws DeviceNotAvailableException {
setCheckAvailableDeviceExpectations();
mMockTestDevice.setDeviceState(TestDeviceState.OFFLINE);
replayMocks();
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice());
IDevice newDevice = EasyMock.createMock(IDevice.class);
EasyMock.expect(newDevice.getSerialNumber()).andReturn(DEVICE_SERIAL).anyTimes();
EasyMock.expect(newDevice.getState()).andReturn(DeviceState.OFFLINE);
EasyMock.replay(newDevice);
mDeviceListener.deviceChanged(newDevice, IDevice.CHANGE_STATE);
}
// TODO: add test for fastboot state changes
/**
* Verify the 'fastboot devices' output parsing
*/
public void testParseDevicesOnFastboot() {
Collection<String> deviceSerials = DeviceManager.parseDevicesOnFastboot(
"04035EEB0B01F01C fastboot\n" +
"HT99PP800024 fastboot\n" +
"???????????? fastboot");
assertEquals(2, deviceSerials.size());
assertTrue(deviceSerials.contains("04035EEB0B01F01C"));
assertTrue(deviceSerials.contains("HT99PP800024"));
}
/**
* Verify the 'fastboot devices' output parsing when empty
*/
public void testParseDevicesOnFastboot_empty() {
Collection<String> deviceSerials = DeviceManager.parseDevicesOnFastboot("");
assertEquals(0, deviceSerials.size());
}
/**
* Test normal success case for {@link DeviceManager#connectToTcpDevice(String)}
*/
public void testConnectToTcpDevice() throws Exception {
final String ipAndPort ="ip:5555";
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager();
assertNotNull(manager.connectToTcpDevice(ipAndPort));
// verify device is in allocated list
assertTrue(manager.getAllocatedDevices().contains(ipAndPort));
verifyMocks(mockTcpDevice);
}
/**
* Test a {@link DeviceManager#connectToTcpDevice(String)} call where device is already
* allocated
*/
public void testConnectToTcpDevice_alreadyAllocated() throws Exception {
final String ipAndPort ="ip:5555";
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager();
assertNotNull(manager.connectToTcpDevice(ipAndPort));
// now attempt to re-allocate
assertNull(manager.connectToTcpDevice(ipAndPort));
verifyMocks(mockTcpDevice);
}
/**
* Test {@link DeviceManager#connectToTcpDevice(String)} where device does not appear on adb
*/
public void testConnectToTcpDevice_notOnline() throws Exception {
final String ipAndPort ="ip:5555";
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
// assume last call is waitForOnline
EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
EasyMock.expect(mockTcpDevice.getIDevice()).andStubReturn(mMockIDevice);
mockTcpDevice.stopLogcat();
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager();
assertNull(manager.connectToTcpDevice(ipAndPort));
// verify device is not in allocated list
assertFalse(manager.getAllocatedDevices().contains(ipAndPort));
verifyMocks(mockTcpDevice);
}
/**
* Test {@link DeviceManager#connectToTcpDevice(String)} where the 'adb connect' call fails.
*/
public void testConnectToTcpDevice_connectFailed() throws Exception {
final String ipAndPort ="ip:5555";
IManagedTestDevice mockTcpDevice = EasyMock.createMock(IManagedTestDevice.class);
EasyMock.expect(mockTcpDevice.getSerialNumber()).andStubReturn(ipAndPort);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mockTcpDevice);
CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS);
connectResult.setStdout(String.format("failed to connect to %s", ipAndPort));
EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("adb"),
EasyMock.eq("connect"), EasyMock.eq(ipAndPort))).andReturn(connectResult).times(3);
mMockRunUtil.sleep(EasyMock.anyLong());
EasyMock.expectLastCall().times(3);
mockTcpDevice.stopLogcat();
EasyMock.expect(mockTcpDevice.getIDevice()).andStubReturn(mMockIDevice);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager();
assertNull(manager.connectToTcpDevice(ipAndPort));
// verify device is not in allocated list
assertFalse(manager.getAllocatedDevices().contains(ipAndPort));
verifyMocks(mockTcpDevice);
}
/**
* Test normal success case for {@link DeviceManager#disconnectFromTcpDevice(ITestDevice)}
*/
public void testDisconnectFromTcpDevice() throws Exception {
final String ipAndPort ="ip:5555";
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
EasyMock.expect(mockTcpDevice.switchToAdbUsb()).andReturn(Boolean.TRUE);
mockTcpDevice.stopLogcat();
EasyMock.expect(mockTcpDevice.getIDevice()).andStubReturn(mMockIDevice);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager();
assertNotNull(manager.connectToTcpDevice(ipAndPort));
manager.disconnectFromTcpDevice(mockTcpDevice);
// verify device is not in allocated or available list
assertFalse(manager.getAllocatedDevices().contains(ipAndPort));
assertFalse(manager.getAvailableDevices().contains(ipAndPort));
verifyMocks(mockTcpDevice);
}
/**
* Test normal success case for {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)}.
*/
public void testReconnectDeviceToTcp() throws Exception {
final String ipAndPort = "ip:5555";
// use the mMockTestDevice as the initially connected to usb device
setCheckAvailableDeviceExpectations();
EasyMock.expect(mMockTestDevice.switchToAdbTcp()).andReturn(ipAndPort);
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
assertEquals(mockTcpDevice, manager.reconnectDeviceToTcp(mMockTestDevice));
verifyMocks();
}
/**
* Test {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)} when tcp connected device does
* not come online.
*/
public void testReconnectDeviceToTcp_notOnline() throws Exception {
final String ipAndPort = "ip:5555";
// use the mMockTestDevice as the initially connected to usb device
setCheckAvailableDeviceExpectations();
EasyMock.expect(mMockTestDevice.switchToAdbTcp()).andReturn(ipAndPort);
IManagedTestDevice mockTcpDevice = setConnectToTcpDeviceExpectations(ipAndPort);
EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
// expect recover to be attempted on usb device
mMockTestDevice.recoverDevice();
mockTcpDevice.stopLogcat();
EasyMock.expect(mockTcpDevice.getIDevice()).andStubReturn(mMockIDevice);
replayMocks(mockTcpDevice);
DeviceManager manager = createDeviceManager(mMockIDevice);
assertEquals(mMockTestDevice, manager.allocateDevice(MIN_ALLOCATE_WAIT_TIME));
assertNull(manager.reconnectDeviceToTcp(mMockTestDevice));
// verify device is not in allocated list
assertFalse(manager.getAllocatedDevices().contains(ipAndPort));
verifyMocks();
}
/**
* Set EasyMock expectations for a successful {@link DeviceManager#connectToTcpDevice(String)}
* call.
*
* @param ipAndPort the ip and port of the device
* @return the mock tcp connected {@link IManagedTestDevice}
* @throws DeviceNotAvailableException
*/
private IManagedTestDevice setConnectToTcpDeviceExpectations(final String ipAndPort)
throws DeviceNotAvailableException {
IManagedTestDevice mockTcpDevice = EasyMock.createMock(IManagedTestDevice.class);
EasyMock.expect(mockTcpDevice.getSerialNumber()).andStubReturn(ipAndPort);
CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS);
connectResult.setStdout(String.format("connected to %s", ipAndPort));
EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("adb"),
EasyMock.eq("connect"), EasyMock.eq(ipAndPort))).andReturn(connectResult);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mockTcpDevice);
mockTcpDevice.setRecovery((IDeviceRecovery)EasyMock.anyObject());
mockTcpDevice.waitForDeviceOnline();
return mockTcpDevice;
}
/**
* Sets all member mock objects into replay mode.
*
* @param additionalMocks extra local mock objects to set to replay mode
*/
private void replayMocks(Object... additionalMocks) {
EasyMock.replay(mMockMonitor, mMockTestDevice, mMockIDevice, mMockAdbBridge, mMockRunUtil,
mMockDeviceFactory);
for (Object mock : additionalMocks) {
EasyMock.replay(mock);
}
}
/**
* Verify all member mock objects.
*
* @param additionalMocks extra local mock objects to set to verify
*/
private void verifyMocks(Object... additionalMocks) {
EasyMock.verify(mMockMonitor, mMockTestDevice, mMockIDevice, mMockAdbBridge, mMockRunUtil);
for (Object mock : additionalMocks) {
EasyMock.verify(mock);
}
}
/**
* Configure EasyMock expectations for a {@link DeviceManager#checkAndAddAvailableDevice()} call
* for an online device
*/
private void setCheckAvailableDeviceExpectations() {
EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
EasyMock.expect(mMockMonitor.waitForDeviceShell(EasyMock.anyLong())).andReturn(
Boolean.TRUE);
EasyMock.expect(mMockDeviceFactory.createDevice()).andReturn(mMockTestDevice);
}
}