Home | History | Annotate | Download | only in device
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tradefed.device;
     18 
     19 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
     20 import com.android.ddmlib.IDevice;
     21 import com.android.ddmlib.IDevice.DeviceState;
     22 import com.android.tradefed.command.remote.DeviceDescriptor;
     23 import com.android.tradefed.config.IGlobalConfiguration;
     24 import com.android.tradefed.device.IManagedTestDevice.DeviceEventResponse;
     25 import com.android.tradefed.log.ILogRegistry.EventType;
     26 import com.android.tradefed.util.ArrayUtil;
     27 import com.android.tradefed.util.CommandResult;
     28 import com.android.tradefed.util.CommandStatus;
     29 import com.android.tradefed.util.IRunUtil;
     30 
     31 import com.google.common.util.concurrent.SettableFuture;
     32 
     33 import junit.framework.TestCase;
     34 
     35 import org.easymock.Capture;
     36 import org.easymock.EasyMock;
     37 import org.easymock.IAnswer;
     38 
     39 import java.io.ByteArrayOutputStream;
     40 import java.io.InputStream;
     41 import java.io.OutputStream;
     42 import java.io.PrintWriter;
     43 import java.util.ArrayList;
     44 import java.util.List;
     45 
     46 /**
     47  * Unit tests for {@link DeviceManager}.
     48  */
     49 public class DeviceManagerTest extends TestCase {
     50 
     51     private static final String DEVICE_SERIAL = "serial";
     52     private static final String MAC_ADDRESS = "FF:FF:FF:FF:FF:FF";
     53     private static final String SIM_STATE = "READY";
     54     private static final String SIM_OPERATOR = "operator";
     55 
     56     private IAndroidDebugBridge mMockAdbBridge;
     57     private IDevice mMockIDevice;
     58     private IDeviceStateMonitor mMockStateMonitor;
     59     private IRunUtil mMockRunUtil;
     60     private IManagedTestDevice mMockTestDevice;
     61     private IManagedTestDeviceFactory mMockDeviceFactory;
     62     private IGlobalConfiguration mMockGlobalConfig;
     63 
     64     /**
     65      * a reference to the DeviceManager's IDeviceChangeListener. Used for triggering device
     66      * connection events
     67      */
     68     private IDeviceChangeListener mDeviceListener;
     69 
     70     static class MockProcess extends Process {
     71 
     72         /**
     73          * {@inheritDoc}
     74          */
     75         @Override
     76         public void destroy() {
     77             // ignore
     78         }
     79 
     80         /**
     81          * {@inheritDoc}
     82          */
     83         @Override
     84         public int exitValue() {
     85             return 0;
     86         }
     87 
     88         /**
     89          * {@inheritDoc}
     90          */
     91         @Override
     92         public InputStream getErrorStream() {
     93             return null;
     94         }
     95 
     96         /**
     97          * {@inheritDoc}
     98          */
     99         @Override
    100         public InputStream getInputStream() {
    101             return null;
    102         }
    103 
    104         /**
    105          * {@inheritDoc}
    106          */
    107         @Override
    108         public OutputStream getOutputStream() {
    109             return null;
    110         }
    111 
    112         /**
    113          * {@inheritDoc}
    114          */
    115         @Override
    116         public int waitFor() throws InterruptedException {
    117             return 0;
    118         }
    119     }
    120 
    121     /**
    122      * {@inheritDoc}
    123      */
    124     @Override
    125     protected void setUp() throws Exception {
    126         super.setUp();
    127         mMockAdbBridge = EasyMock.createNiceMock(IAndroidDebugBridge.class);
    128         mMockAdbBridge.addDeviceChangeListener((IDeviceChangeListener) EasyMock.anyObject());
    129         EasyMock.expectLastCall().andDelegateTo(new IAndroidDebugBridge() {
    130             @Override
    131             public void addDeviceChangeListener(final IDeviceChangeListener listener) {
    132                 mDeviceListener = listener;
    133             }
    134             @Override
    135             public IDevice[] getDevices() {
    136                 return null;
    137             }
    138             @Override
    139             public void removeDeviceChangeListener(IDeviceChangeListener listener) {
    140             }
    141             @Override
    142             public void init(boolean clientSupport, String adbOsLocation) {
    143             }
    144             @Override
    145             public void terminate() {
    146             }
    147             @Override
    148             public void disconnectBridge() {
    149             }
    150         });
    151         mMockIDevice = EasyMock.createMock(IDevice.class);
    152         mMockStateMonitor = EasyMock.createMock(IDeviceStateMonitor.class);
    153         mMockRunUtil = EasyMock.createMock(IRunUtil.class);
    154 
    155         mMockTestDevice = EasyMock.createMock(IManagedTestDevice.class);
    156         mMockDeviceFactory = new ManagedTestDeviceFactory(false, null, null) {
    157             @Override
    158             public IManagedTestDevice createDevice(IDevice idevice) {
    159                 mMockTestDevice.setIDevice(idevice);
    160                 return mMockTestDevice;
    161             }
    162             @Override
    163             protected CollectingOutputReceiver createOutputReceiver() {
    164                 return new CollectingOutputReceiver() {
    165                     @Override
    166                     public String getOutput() {
    167                         return "/system/bin/pm";
    168                     }
    169                 };
    170             }
    171             @Override
    172             public void setFastbootEnabled(boolean enable) {
    173                 // ignore
    174             }
    175         };
    176         mMockGlobalConfig = EasyMock.createNiceMock(IGlobalConfiguration.class);
    177 
    178         EasyMock.expect(mMockIDevice.getSerialNumber()).andStubReturn(DEVICE_SERIAL);
    179         EasyMock.expect(mMockStateMonitor.getSerialNumber()).andStubReturn(DEVICE_SERIAL);
    180         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    181         EasyMock.expect(mMockTestDevice.getMacAddress()).andStubReturn(MAC_ADDRESS);
    182         EasyMock.expect(mMockTestDevice.getSimState()).andStubReturn(SIM_STATE);
    183         EasyMock.expect(mMockTestDevice.getSimOperator()).andStubReturn(SIM_OPERATOR);
    184         final Capture<IDevice> capturedIDevice = new Capture<>();
    185         mMockTestDevice.setIDevice(EasyMock.capture(capturedIDevice));
    186         EasyMock.expectLastCall().anyTimes();
    187         EasyMock.expect(mMockTestDevice.getIDevice()).andStubAnswer(new IAnswer<IDevice>() {
    188             @Override
    189             public IDevice answer() throws Throwable {
    190                 return capturedIDevice.getValue();
    191             }
    192         });
    193         EasyMock.expect(mMockTestDevice.getSerialNumber()).andStubAnswer(new IAnswer<String>() {
    194             @Override
    195             public String answer() throws Throwable {
    196                 return capturedIDevice.getValue().getSerialNumber();
    197             }
    198         });
    199         EasyMock.expect(mMockTestDevice.getMonitor()).andStubReturn(mMockStateMonitor);
    200         EasyMock.expect(
    201                 mMockRunUtil.runTimedCmd(EasyMock.anyLong(), (String) EasyMock.anyObject(),
    202                         (String) EasyMock.anyObject())).andStubReturn(new CommandResult());
    203         EasyMock.expect(
    204                 mMockRunUtil.runTimedCmdSilently(EasyMock.anyLong(), (String) EasyMock.anyObject(),
    205                         (String) EasyMock.anyObject())).andStubReturn(new CommandResult());
    206 
    207         EasyMock.expect(mMockGlobalConfig.getDeviceRequirements()).andStubReturn(
    208                 DeviceManager.ANY_DEVICE_OPTIONS);
    209     }
    210 
    211     private DeviceManager createDeviceManager(List<IDeviceMonitor> deviceMonitors,
    212             IDevice... devices) {
    213         DeviceManager mgr = createDeviceManagerNoInit();
    214         mgr.init(null, deviceMonitors, mMockDeviceFactory);
    215         for (IDevice device : devices) {
    216             mDeviceListener.deviceConnected(device);
    217         }
    218         return mgr;
    219     }
    220 
    221     private DeviceManager createDeviceManagerNoInit() {
    222 
    223         DeviceManager mgr =
    224                 new DeviceManager() {
    225                     @Override
    226                     IAndroidDebugBridge createAdbBridge() {
    227                         return mMockAdbBridge;
    228                     }
    229 
    230                     @Override
    231                     void startFastbootMonitor() {}
    232 
    233                     @Override
    234                     void startDeviceRecoverer() {}
    235 
    236                     @Override
    237                     void logDeviceEvent(EventType event, String serial) {}
    238 
    239                     @Override
    240                     IDeviceStateMonitor createStateMonitor(IDevice device) {
    241                         return mMockStateMonitor;
    242                     }
    243 
    244                     @Override
    245                     IGlobalConfiguration getGlobalConfig() {
    246                         return mMockGlobalConfig;
    247                     }
    248 
    249                     @Override
    250                     IRunUtil getRunUtil() {
    251                         return mMockRunUtil;
    252                     }
    253                 };
    254         mgr.setSynchronousMode(true);
    255         mgr.setMaxEmulators(0);
    256         mgr.setMaxNullDevices(0);
    257         mgr.setMaxTcpDevices(0);
    258         return mgr;
    259     }
    260 
    261     /**
    262      * Test @link DeviceManager#allocateDevice()} when a IDevice is present on DeviceManager
    263      * creation.
    264      */
    265     public void testAllocateDevice() {
    266         setCheckAvailableDeviceExpectations();
    267         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    268                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    269 
    270         replayMocks();
    271         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    272         assertNotNull(manager.allocateDevice());
    273         EasyMock.verify(mMockStateMonitor);
    274     }
    275 
    276     /**
    277      * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when device is
    278      * returned.
    279      */
    280     public void testAllocateDevice_match() {
    281         DeviceSelectionOptions options = new DeviceSelectionOptions();
    282         options.addSerial(DEVICE_SERIAL);
    283         setCheckAvailableDeviceExpectations();
    284         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    285                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    286         replayMocks();
    287         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    288         assertEquals(mMockTestDevice, manager.allocateDevice(options));
    289         EasyMock.verify(mMockStateMonitor);
    290     }
    291 
    292     /**
    293      * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when stub emulator
    294      * is requested
    295      */
    296     public void testAllocateDevice_stubEmulator() {
    297         DeviceSelectionOptions options = new DeviceSelectionOptions();
    298         options.setStubEmulatorRequested(true);
    299         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
    300                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    301         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.TRUE);
    302         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    303                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    304         replayMocks();
    305         DeviceManager mgr = createDeviceManagerNoInit();
    306         mgr.setMaxEmulators(1);
    307         mgr.init(null, null, mMockDeviceFactory);
    308         assertNotNull(mgr.allocateDevice(options));
    309         verifyMocks();
    310     }
    311 
    312     /**
    313      * Test freeing an emulator
    314      */
    315     public void testFreeDevice_emulator() {
    316         DeviceSelectionOptions options = new DeviceSelectionOptions();
    317         options.setStubEmulatorRequested(true);
    318         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
    319                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    320         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.TRUE);
    321         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    322                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    323         mMockTestDevice.stopLogcat();
    324         EasyMock.expect(mMockTestDevice.getEmulatorProcess()).andStubReturn(new MockProcess());
    325         EasyMock.expect(mMockTestDevice.waitForDeviceNotAvailable(EasyMock.anyLong())).andReturn(
    326                 Boolean.TRUE);
    327         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_AVAILABLE))
    328                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    329         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    330                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    331         mMockTestDevice.stopEmulatorOutput();
    332         replayMocks();
    333         DeviceManager manager = createDeviceManagerNoInit();
    334         manager.setMaxEmulators(1);
    335         manager.init(null, null, mMockDeviceFactory);
    336         IManagedTestDevice emulator = (IManagedTestDevice) manager.allocateDevice(options);
    337         assertNotNull(emulator);
    338         // a freed 'unavailable' emulator should be returned to the available
    339         // queue.
    340         manager.freeDevice(emulator, FreeDeviceState.UNAVAILABLE);
    341         // ensure device can be allocated again
    342         assertNotNull(manager.allocateDevice(options));
    343         verifyMocks();
    344     }
    345 
    346     /**
    347      * Test {@link DeviceManager#allocateDevice(IDeviceSelection)} when a null device
    348      * is requested.
    349      */
    350     public void testAllocateDevice_nullDevice() {
    351         DeviceSelectionOptions options = new DeviceSelectionOptions();
    352         options.setNullDeviceRequested(true);
    353         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    354         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
    355                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    356         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    357                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    358         replayMocks();
    359         DeviceManager mgr = createDeviceManagerNoInit();
    360         mgr.setMaxNullDevices(1);
    361         mgr.init(null, null, mMockDeviceFactory);
    362         ITestDevice device = mgr.allocateDevice(options);
    363         assertNotNull(device);
    364         assertTrue(device.getIDevice() instanceof NullDevice);
    365         verifyMocks();
    366     }
    367 
    368     /**
    369      * Test that DeviceManager will add devices on fastboot to available queue on startup, and that
    370      * they can be allocated.
    371      */
    372     public void testAllocateDevice_fastboot() {
    373         EasyMock.reset(mMockRunUtil);
    374         // mock 'fastboot help' call
    375         EasyMock.expect(
    376                 mMockRunUtil.runTimedCmdSilently(EasyMock.anyLong(), EasyMock.eq("fastboot"),
    377                         EasyMock.eq("help"))).andReturn(new CommandResult(CommandStatus.SUCCESS));
    378 
    379         // mock 'fastboot devices' call to return one device
    380         CommandResult fastbootResult = new CommandResult(CommandStatus.SUCCESS);
    381         fastbootResult.setStdout("serial        fastboot\n");
    382         EasyMock.expect(
    383                         mMockRunUtil.runTimedCmdSilently(
    384                                 EasyMock.anyLong(),
    385                                 EasyMock.eq("fastboot"),
    386                                 EasyMock.eq("devices")))
    387                 .andReturn(fastbootResult);
    388         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
    389                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    390         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    391                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    392         replayMocks();
    393         DeviceManager manager = createDeviceManager(null);
    394         assertNotNull(manager.allocateDevice());
    395         verifyMocks();
    396     }
    397 
    398     /**
    399      * Test {@link DeviceManager#forceAllocateDevice(String)} when device is unknown
    400      */
    401     public void testForceAllocateDevice() {
    402         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    403                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    404         replayMocks();
    405         DeviceManager manager = createDeviceManager(null);
    406         assertNotNull(manager.forceAllocateDevice("unknownserial"));
    407         verifyMocks();
    408     }
    409 
    410     /**
    411      * Test {@link DeviceManager#forceAllocateDevice(String)} when device is available
    412      */
    413     public void testForceAllocateDevice_available() {
    414         setCheckAvailableDeviceExpectations();
    415         EasyMock.expect(mMockTestDevice.getAllocationState())
    416                 .andReturn(DeviceAllocationState.Available);
    417         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    418                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    419         replayMocks();
    420         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    421         assertNotNull(manager.forceAllocateDevice(DEVICE_SERIAL));
    422         verifyMocks();
    423     }
    424 
    425     /**
    426      * Test {@link DeviceManager#forceAllocateDevice(String)} when device is already allocated
    427      */
    428     public void testForceAllocateDevice_alreadyAllocated() {
    429         setCheckAvailableDeviceExpectations();
    430         EasyMock.expect(mMockTestDevice.getAllocationState())
    431                 .andReturn(DeviceAllocationState.Allocated);
    432         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    433                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    434         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    435                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false));
    436         replayMocks();
    437         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    438         assertNotNull(manager.allocateDevice());
    439         assertNull(manager.forceAllocateDevice(DEVICE_SERIAL));
    440         verifyMocks();
    441     }
    442 
    443     /**
    444      * Test method for {@link DeviceManager#freeDevice(ITestDevice, FreeDeviceState)}.
    445      */
    446     public void testFreeDevice() {
    447         setCheckAvailableDeviceExpectations();
    448         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    449                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    450         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_AVAILABLE))
    451                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    452         mMockTestDevice.stopLogcat();
    453         replayMocks();
    454         DeviceManager manager = createDeviceManager(null);
    455         mDeviceListener.deviceConnected(mMockIDevice);
    456         assertNotNull(manager.allocateDevice());
    457         manager.freeDevice(mMockTestDevice, FreeDeviceState.AVAILABLE);
    458         verifyMocks();
    459     }
    460 
    461     /**
    462      * Verified that {@link DeviceManager#freeDevice(ITestDevice, FreeDeviceState)}
    463      * ignores a call with a device that has not been allocated.
    464      */
    465     public void testFreeDevice_noop() {
    466         setCheckAvailableDeviceExpectations();
    467         IManagedTestDevice testDevice = EasyMock.createNiceMock(IManagedTestDevice.class);
    468         IDevice mockIDevice = EasyMock.createNiceMock(IDevice.class);
    469         EasyMock.expect(testDevice.getIDevice()).andReturn(mockIDevice);
    470         EasyMock.expect(mockIDevice.isEmulator()).andReturn(Boolean.FALSE);
    471 
    472         replayMocks(testDevice, mockIDevice);
    473         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    474         manager.freeDevice(testDevice, FreeDeviceState.AVAILABLE);
    475         verifyMocks(testDevice, mockIDevice);
    476     }
    477 
    478     /**
    479      * Verified that {@link DeviceManager} calls {@link IManagedTestDevice#setIDevice(IDevice)} when
    480      * DDMS allocates a new IDevice on connection.
    481      */
    482     public void testSetIDevice() {
    483         setCheckAvailableDeviceExpectations();
    484         EasyMock.expect(mMockTestDevice.getAllocationState())
    485                 .andReturn(DeviceAllocationState.Available);
    486         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    487                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    488         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.DISCONNECTED)).andReturn(
    489                 new DeviceEventResponse(DeviceAllocationState.Allocated, false));
    490         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE))
    491                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false));
    492         IDevice newMockDevice = EasyMock.createMock(IDevice.class);
    493         EasyMock.expect(newMockDevice.getSerialNumber()).andReturn(DEVICE_SERIAL).anyTimes();
    494         EasyMock.expect(newMockDevice.getState()).andReturn(DeviceState.ONLINE);
    495         mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    496         mMockTestDevice.setDeviceState(TestDeviceState.ONLINE);
    497         replayMocks(newMockDevice);
    498         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    499         ITestDevice device = manager.allocateDevice();
    500         assertNotNull(device);
    501         // now trigger a device disconnect + reconnection
    502         mDeviceListener.deviceDisconnected(mMockIDevice);
    503         mDeviceListener.deviceConnected(newMockDevice);
    504         assertEquals(newMockDevice, device.getIDevice());
    505         verifyMocks(newMockDevice);
    506     }
    507 
    508     /**
    509      * Test {@link DeviceManager#allocateDevice()} when {@link DeviceManager#init()} has not been
    510      * called.
    511      */
    512     public void testAllocateDevice_noInit() {
    513         try {
    514             createDeviceManagerNoInit().allocateDevice();
    515             fail("IllegalStateException not thrown when manager has not been initialized");
    516         } catch (IllegalStateException e) {
    517             // expected
    518         }
    519     }
    520 
    521     /**
    522      * Test {@link DeviceManager#init(IDeviceSelection, List)}
    523      * with a global exclusion filter
    524      */
    525     public void testInit_excludeDevice() throws Exception {
    526         EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
    527         mMockTestDevice.setDeviceState(TestDeviceState.ONLINE);
    528         EasyMock.expectLastCall();
    529         DeviceEventResponse der =
    530                 new DeviceEventResponse(DeviceAllocationState.Checking_Availability, true);
    531         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE))
    532                 .andReturn(der);
    533         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_IGNORED))
    534                 .andReturn(null);
    535         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    536                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Ignored, false));
    537         replayMocks();
    538         DeviceManager manager = createDeviceManagerNoInit();
    539         DeviceSelectionOptions excludeFilter = new DeviceSelectionOptions();
    540         excludeFilter.addExcludeSerial(mMockIDevice.getSerialNumber());
    541         manager.init(excludeFilter, null, mMockDeviceFactory);
    542         mDeviceListener.deviceConnected(mMockIDevice);
    543         assertEquals(1, manager.getDeviceList().size());
    544         assertNull(manager.allocateDevice());
    545         verifyMocks();
    546     }
    547 
    548     /**
    549      * Test {@link DeviceManager#init(IDeviceSelection, List)} with a global inclusion filter
    550      */
    551     public void testInit_includeDevice() throws Exception {
    552         IDevice excludedDevice = EasyMock.createMock(IDevice.class);
    553         EasyMock.expect(excludedDevice.getSerialNumber()).andStubReturn("excluded");
    554         EasyMock.expect(excludedDevice.getState()).andStubReturn(DeviceState.ONLINE);
    555         EasyMock.expect(mMockIDevice.getState()).andStubReturn(DeviceState.ONLINE);
    556         EasyMock.expect(excludedDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    557         mMockTestDevice.setDeviceState(TestDeviceState.ONLINE);
    558         DeviceEventResponse der =
    559                 new DeviceEventResponse(DeviceAllocationState.Checking_Availability, true);
    560         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE))
    561                 .andReturn(der);
    562         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_IGNORED))
    563                 .andReturn(null);
    564         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    565                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Ignored, false));
    566         replayMocks(excludedDevice);
    567         DeviceManager manager = createDeviceManagerNoInit();
    568         DeviceSelectionOptions includeFilter = new DeviceSelectionOptions();
    569         includeFilter.addSerial(mMockIDevice.getSerialNumber());
    570         manager.init(includeFilter, null, mMockDeviceFactory);
    571         mDeviceListener.deviceConnected(excludedDevice);
    572         assertEquals(1, manager.getDeviceList().size());
    573         // ensure excludedDevice cannot be allocated
    574         assertNull(manager.allocateDevice());
    575         verifyMocks(excludedDevice);
    576     }
    577 
    578     /**
    579      * Verified that a disconnected device state gets updated
    580      */
    581     public void testSetState_disconnected() {
    582         setCheckAvailableDeviceExpectations();
    583         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    584                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    585         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.DISCONNECTED))
    586                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false));
    587         mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    588         replayMocks();
    589         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    590         assertEquals(mMockTestDevice, manager.allocateDevice());
    591         mDeviceListener.deviceDisconnected(mMockIDevice);
    592         verifyMocks();
    593     }
    594 
    595     /**
    596      * Verified that a offline device state gets updated
    597      */
    598     public void testSetState_offline() {
    599         setCheckAvailableDeviceExpectations();
    600         EasyMock.expect(mMockTestDevice.getAllocationState())
    601                 .andReturn(DeviceAllocationState.Allocated);
    602         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    603                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    604         mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    605         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.STATE_CHANGE_OFFLINE))
    606                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Unavailable, true));
    607         replayMocks();
    608         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    609         assertEquals(mMockTestDevice, manager.allocateDevice());
    610         IDevice newDevice = EasyMock.createMock(IDevice.class);
    611         EasyMock.expect(newDevice.getSerialNumber()).andReturn(DEVICE_SERIAL).anyTimes();
    612         EasyMock.expect(newDevice.getState()).andReturn(DeviceState.OFFLINE).times(2);
    613         EasyMock.replay(newDevice);
    614         mDeviceListener.deviceChanged(newDevice, IDevice.CHANGE_STATE);
    615         verifyMocks();
    616     }
    617 
    618     // TODO: add test for fastboot state changes
    619 
    620     /**
    621      * Test normal success case for {@link DeviceManager#connectToTcpDevice(String)}
    622      */
    623     public void testConnectToTcpDevice() throws Exception {
    624         final String ipAndPort = "ip:5555";
    625         setConnectToTcpDeviceExpectations(ipAndPort);
    626         mMockTestDevice.waitForDeviceOnline();
    627         replayMocks();
    628         DeviceManager manager = createDeviceManager(null);
    629         IManagedTestDevice device = (IManagedTestDevice) manager.connectToTcpDevice(ipAndPort);
    630         assertNotNull(device);
    631         verifyMocks();
    632     }
    633 
    634     /**
    635      * Test a {@link DeviceManager#connectToTcpDevice(String)} call where device is already
    636      * allocated
    637      */
    638     public void testConnectToTcpDevice_alreadyAllocated() throws Exception {
    639         final String ipAndPort = "ip:5555";
    640         setConnectToTcpDeviceExpectations(ipAndPort);
    641         mMockTestDevice.waitForDeviceOnline();
    642         EasyMock.expect(mMockTestDevice.getAllocationState())
    643                 .andReturn(DeviceAllocationState.Allocated);
    644         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    645                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false));
    646         replayMocks();
    647         DeviceManager manager = createDeviceManager(null);
    648         IManagedTestDevice device = (IManagedTestDevice) manager.connectToTcpDevice(ipAndPort);
    649         assertNotNull(device);
    650         // now attempt to re-allocate
    651         assertNull(manager.connectToTcpDevice(ipAndPort));
    652         verifyMocks();
    653     }
    654 
    655     /**
    656      * Test {@link DeviceManager#connectToTcpDevice(String)} where device does not appear on adb
    657      */
    658     public void testConnectToTcpDevice_notOnline() throws Exception {
    659         final String ipAndPort = "ip:5555";
    660         setConnectToTcpDeviceExpectations(ipAndPort);
    661         mMockTestDevice.waitForDeviceOnline();
    662         EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
    663         mMockTestDevice.stopLogcat();
    664         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)).andReturn(
    665                 new DeviceEventResponse(DeviceAllocationState.Unknown, false));
    666         replayMocks();
    667         DeviceManager manager = createDeviceManager(null);
    668         assertNull(manager.connectToTcpDevice(ipAndPort));
    669         // verify device is not in list
    670         assertEquals(0, manager.getDeviceList().size());
    671         verifyMocks();
    672     }
    673 
    674     /**
    675      * Test {@link DeviceManager#connectToTcpDevice(String)} where the 'adb connect' call fails.
    676      */
    677     public void testConnectToTcpDevice_connectFailed() throws Exception {
    678         final String ipAndPort = "ip:5555";
    679 
    680         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    681                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    682         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN))
    683                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true));
    684         CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS);
    685         connectResult.setStdout(String.format("failed to connect to %s", ipAndPort));
    686         EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("adb"),
    687                 EasyMock.eq("connect"), EasyMock.eq(ipAndPort)))
    688                 .andReturn(connectResult)
    689                 .times(3);
    690         mMockRunUtil.sleep(EasyMock.anyLong());
    691         EasyMock.expectLastCall().times(3);
    692 
    693         mMockTestDevice.stopLogcat();
    694 
    695         replayMocks();
    696         DeviceManager manager = createDeviceManager(null);
    697         assertNull(manager.connectToTcpDevice(ipAndPort));
    698         // verify device is not in list
    699         assertEquals(0, manager.getDeviceList().size());
    700         verifyMocks();
    701     }
    702 
    703     /**
    704      * Test normal success case for {@link DeviceManager#disconnectFromTcpDevice(ITestDevice)}
    705      */
    706     public void testDisconnectFromTcpDevice() throws Exception {
    707         final String ipAndPort = "ip:5555";
    708         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)).andReturn(
    709                 new DeviceEventResponse(DeviceAllocationState.Unknown, true));
    710         setConnectToTcpDeviceExpectations(ipAndPort);
    711         EasyMock.expect(mMockTestDevice.switchToAdbUsb()).andReturn(Boolean.TRUE);
    712         mMockTestDevice.waitForDeviceOnline();
    713         mMockTestDevice.stopLogcat();
    714         replayMocks();
    715         DeviceManager manager = createDeviceManager(null);
    716         assertNotNull(manager.connectToTcpDevice(ipAndPort));
    717         manager.disconnectFromTcpDevice(mMockTestDevice);
    718         // verify device is not in allocated or available list
    719         assertEquals(0, manager.getDeviceList().size());
    720         verifyMocks();
    721     }
    722 
    723     /**
    724      * Test normal success case for {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)}.
    725      */
    726     public void testReconnectDeviceToTcp() throws Exception {
    727         final String ipAndPort = "ip:5555";
    728         // use the mMockTestDevice as the initially connected to usb device
    729         setCheckAvailableDeviceExpectations();
    730         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    731                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    732         EasyMock.expect(mMockTestDevice.switchToAdbTcp()).andReturn(ipAndPort);
    733         setConnectToTcpDeviceExpectations(ipAndPort);
    734         mMockTestDevice.waitForDeviceOnline();
    735         replayMocks();
    736         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    737         assertEquals(mMockTestDevice, manager.allocateDevice());
    738         assertNotNull(manager.reconnectDeviceToTcp(mMockTestDevice));
    739         verifyMocks();
    740     }
    741 
    742     /**
    743      * Test {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)} when tcp connected device does
    744      * not come online.
    745      */
    746     public void testReconnectDeviceToTcp_notOnline() throws Exception {
    747         final String ipAndPort = "ip:5555";
    748         // use the mMockTestDevice as the initially connected to usb device
    749         setCheckAvailableDeviceExpectations();
    750         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    751                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    752         EasyMock.expect(mMockTestDevice.switchToAdbTcp()).andReturn(ipAndPort);
    753         setConnectToTcpDeviceExpectations(ipAndPort);
    754         mMockTestDevice.waitForDeviceOnline();
    755         EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
    756         // expect recover to be attempted on usb device
    757         mMockTestDevice.recoverDevice();
    758         mMockTestDevice.stopLogcat();
    759         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)).andReturn(
    760                 new DeviceEventResponse(DeviceAllocationState.Unknown, true));
    761         replayMocks();
    762         DeviceManager manager = createDeviceManager(null, mMockIDevice);
    763         assertEquals(mMockTestDevice, manager.allocateDevice());
    764         assertNull(manager.reconnectDeviceToTcp(mMockTestDevice));
    765         // verify only usb device is in list
    766         assertEquals(1, manager.getDeviceList().size());
    767         verifyMocks();
    768     }
    769 
    770     /**
    771      * Basic test for {@link DeviceManager#sortDeviceList(List)}
    772      */
    773     public void testSortDeviceList() {
    774         DeviceDescriptor availDevice1 = createDeviceDesc("aaa", DeviceAllocationState.Available);
    775         DeviceDescriptor availDevice2 = createDeviceDesc("bbb", DeviceAllocationState.Available);
    776         DeviceDescriptor allocatedDevice = createDeviceDesc("ccc", DeviceAllocationState.Allocated);
    777         List<DeviceDescriptor> deviceList = ArrayUtil.list(availDevice1, availDevice2,
    778                 allocatedDevice);
    779         List<DeviceDescriptor> sortedList = DeviceManager.sortDeviceList(deviceList);
    780         assertEquals(allocatedDevice, sortedList.get(0));
    781         assertEquals(availDevice1, sortedList.get(1));
    782         assertEquals(availDevice2, sortedList.get(2));
    783     }
    784 
    785     /**
    786      * Helper method to create a {@link DeviceDescriptor} using only serial and state.
    787      */
    788     private DeviceDescriptor createDeviceDesc(String serial, DeviceAllocationState state) {
    789         return new DeviceDescriptor(serial, false, state, null, null, null, null, null);
    790     }
    791 
    792     /**
    793      * Set EasyMock expectations for a successful {@link DeviceManager#connectToTcpDevice(String)}
    794      * call.
    795      *
    796      * @param ipAndPort the ip and port of the device
    797      * @throws DeviceNotAvailableException
    798      */
    799     private void setConnectToTcpDeviceExpectations(final String ipAndPort)
    800             throws DeviceNotAvailableException {
    801         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST))
    802                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    803         mMockTestDevice.setRecovery((IDeviceRecovery) EasyMock.anyObject());
    804         CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS);
    805         connectResult.setStdout(String.format("connected to %s", ipAndPort));
    806         EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("adb"),
    807                 EasyMock.eq("connect"), EasyMock.eq(ipAndPort)))
    808                 .andReturn(connectResult);
    809     }
    810 
    811     /**
    812      * Sets all member mock objects into replay mode.
    813      *
    814      * @param additionalMocks extra local mock objects to set to replay mode
    815      */
    816     private void replayMocks(Object... additionalMocks) {
    817         EasyMock.replay(mMockStateMonitor, mMockTestDevice, mMockIDevice, mMockAdbBridge,
    818                 mMockRunUtil, mMockGlobalConfig);
    819         for (Object mock : additionalMocks) {
    820             EasyMock.replay(mock);
    821         }
    822     }
    823 
    824     /**
    825      * Verify all member mock objects.
    826      *
    827      * @param additionalMocks extra local mock objects to set to verify
    828      */
    829     private void verifyMocks(Object... additionalMocks) {
    830         EasyMock.verify(mMockStateMonitor, mMockTestDevice, mMockIDevice, mMockAdbBridge,
    831                 mMockRunUtil);
    832         for (Object mock : additionalMocks) {
    833             EasyMock.verify(mock);
    834         }
    835     }
    836 
    837     /**
    838      * Configure EasyMock expectations for a
    839      * {@link DeviceManager#checkAndAddAvailableDevice(IManagedTestDevice)} call
    840      * for an online device
    841      */
    842     @SuppressWarnings("javadoc")
    843     private void setCheckAvailableDeviceExpectations() {
    844         setCheckAvailableDeviceExpectations(mMockIDevice);
    845     }
    846 
    847     private void setCheckAvailableDeviceExpectations(IDevice iDevice) {
    848         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    849         EasyMock.expect(iDevice.getState()).andReturn(DeviceState.ONLINE);
    850         EasyMock.expect(mMockStateMonitor.waitForDeviceShell(EasyMock.anyLong())).andReturn(
    851                 Boolean.TRUE);
    852         mMockTestDevice.setDeviceState(TestDeviceState.ONLINE);
    853         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE))
    854                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Checking_Availability,
    855                         true));
    856         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_PASSED))
    857                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    858     }
    859 
    860     /**
    861      * Test freeing a tcp device, it must return to an unavailable status
    862      */
    863     public void testFreeDevice_tcpDevice() {
    864         DeviceSelectionOptions options = new DeviceSelectionOptions();
    865         options.setTcpDeviceRequested(true);
    866         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE))
    867                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    868         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    869         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    870                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    871         mMockTestDevice.stopLogcat();
    872         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST))
    873                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true));
    874         EasyMock.expect(mMockTestDevice.getDeviceState())
    875                 .andReturn(TestDeviceState.NOT_AVAILABLE).times(2);
    876         EasyMock.expect(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN))
    877                 .andReturn(new DeviceEventResponse(DeviceAllocationState.Available, true));
    878         mMockTestDevice.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    879         replayMocks();
    880         DeviceManager manager = createDeviceManagerNoInit();
    881         manager.setMaxTcpDevices(1);
    882         manager.init(null, null, mMockDeviceFactory);
    883         IManagedTestDevice tcpDevice = (IManagedTestDevice) manager.allocateDevice(options);
    884         assertNotNull(tcpDevice);
    885         // a freed 'unavailable' emulator should be returned to the available
    886         // queue.
    887         manager.freeDevice(tcpDevice, FreeDeviceState.UNAVAILABLE);
    888         // ensure device can be allocated again
    889         ITestDevice tcp = manager.allocateDevice(options);
    890         assertNotNull(tcp);
    891         assertTrue(tcp.getDeviceState() == TestDeviceState.NOT_AVAILABLE);
    892         verifyMocks();
    893     }
    894 
    895     /**
    896      * Test freeing a device that was unable but showing in adb devices. Device will become
    897      * Unavailable but still seen by the DeviceManager.
    898      */
    899     public void testFreeDevice_unavailable() {
    900         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    901         EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
    902         EasyMock.expect(mMockStateMonitor.waitForDeviceShell(EasyMock.anyLong()))
    903                 .andReturn(Boolean.TRUE);
    904         mMockStateMonitor.setState(TestDeviceState.NOT_AVAILABLE);
    905 
    906         CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS);
    907         stubAdbDevices.setStdout("List of devices attached\nserial\tdevice\n");
    908         EasyMock.expect(
    909                         mMockRunUtil.runTimedCmd(
    910                                 EasyMock.anyLong(), EasyMock.eq("adb"), EasyMock.eq("devices")))
    911                 .andReturn(stubAdbDevices);
    912 
    913         replayMocks();
    914         IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null);
    915         DeviceManager manager = createDeviceManagerNoInit();
    916         manager.init(
    917                 null,
    918                 null,
    919                 new ManagedTestDeviceFactory(false, null, null) {
    920                     @Override
    921                     public IManagedTestDevice createDevice(IDevice idevice) {
    922                         mMockTestDevice.setIDevice(idevice);
    923                         return testDevice;
    924                     }
    925 
    926                     @Override
    927                     protected CollectingOutputReceiver createOutputReceiver() {
    928                         return new CollectingOutputReceiver() {
    929                             @Override
    930                             public String getOutput() {
    931                                 return "/system/bin/pm";
    932                             }
    933                         };
    934                     }
    935 
    936                     @Override
    937                     public void setFastbootEnabled(boolean enable) {
    938                         // ignore
    939                     }
    940                 });
    941 
    942         mDeviceListener.deviceConnected(mMockIDevice);
    943 
    944         IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice();
    945         assertNotNull(device);
    946         // device becomes unavailable
    947         device.setDeviceState(TestDeviceState.NOT_AVAILABLE);
    948         // a freed 'unavailable' device becomes UNAVAILABLE state
    949         manager.freeDevice(device, FreeDeviceState.UNAVAILABLE);
    950         // ensure device cannot be allocated again
    951         ITestDevice device2 = manager.allocateDevice();
    952         assertNull(device2);
    953         verifyMocks();
    954         // We still have the device in the list
    955         assertEquals(1, manager.getDeviceList().size());
    956     }
    957 
    958     /**
    959      * Test that when freeing an Unavailable device that is not in 'adb devices' we correctly remove
    960      * it from our tracking list.
    961      */
    962     public void testFreeDevice_unknown() {
    963         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
    964         EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
    965         EasyMock.expect(mMockStateMonitor.waitForDeviceShell(EasyMock.anyLong()))
    966                 .andReturn(Boolean.TRUE);
    967         mMockStateMonitor.setState(TestDeviceState.NOT_AVAILABLE);
    968 
    969         CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS);
    970         // device serial is not in the list
    971         stubAdbDevices.setStdout("List of devices attached\n");
    972         EasyMock.expect(
    973                         mMockRunUtil.runTimedCmd(
    974                                 EasyMock.anyLong(), EasyMock.eq("adb"), EasyMock.eq("devices")))
    975                 .andReturn(stubAdbDevices);
    976 
    977         replayMocks();
    978         IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null);
    979         DeviceManager manager = createDeviceManagerNoInit();
    980         manager.init(
    981                 null,
    982                 null,
    983                 new ManagedTestDeviceFactory(false, null, null) {
    984                     @Override
    985                     public IManagedTestDevice createDevice(IDevice idevice) {
    986                         mMockTestDevice.setIDevice(idevice);
    987                         return testDevice;
    988                     }
    989 
    990                     @Override
    991                     protected CollectingOutputReceiver createOutputReceiver() {
    992                         return new CollectingOutputReceiver() {
    993                             @Override
    994                             public String getOutput() {
    995                                 return "/system/bin/pm";
    996                             }
    997                         };
    998                     }
    999 
   1000                     @Override
   1001                     public void setFastbootEnabled(boolean enable) {
   1002                         // ignore
   1003                     }
   1004                 });
   1005 
   1006         mDeviceListener.deviceConnected(mMockIDevice);
   1007 
   1008         IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice();
   1009         assertNotNull(device);
   1010         // device becomes unavailable
   1011         device.setDeviceState(TestDeviceState.NOT_AVAILABLE);
   1012         // a freed 'unavailable' device becomes UNAVAILABLE state
   1013         manager.freeDevice(device, FreeDeviceState.UNAVAILABLE);
   1014         // ensure device cannot be allocated again
   1015         ITestDevice device2 = manager.allocateDevice();
   1016         assertNull(device2);
   1017         verifyMocks();
   1018         // We have 0 device in the list since it was removed
   1019         assertEquals(0, manager.getDeviceList().size());
   1020     }
   1021 
   1022     /**
   1023      * Test that when freeing an Unavailable device that is not in 'adb devices' we correctly remove
   1024      * it from our tracking list even if its serial is a substring of another serial.
   1025      */
   1026     public void testFreeDevice_unknown_subName() {
   1027         EasyMock.expect(mMockIDevice.isEmulator()).andStubReturn(Boolean.FALSE);
   1028         EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
   1029         EasyMock.expect(mMockStateMonitor.waitForDeviceShell(EasyMock.anyLong()))
   1030                 .andReturn(Boolean.TRUE);
   1031         mMockStateMonitor.setState(TestDeviceState.NOT_AVAILABLE);
   1032 
   1033         CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS);
   1034         // device serial is not in the list
   1035         stubAdbDevices.setStdout("List of devices attached\n2serial\tdevice\n");
   1036         EasyMock.expect(
   1037                         mMockRunUtil.runTimedCmd(
   1038                                 EasyMock.anyLong(), EasyMock.eq("adb"), EasyMock.eq("devices")))
   1039                 .andReturn(stubAdbDevices);
   1040 
   1041         replayMocks();
   1042         IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null);
   1043         DeviceManager manager = createDeviceManagerNoInit();
   1044         manager.init(
   1045                 null,
   1046                 null,
   1047                 new ManagedTestDeviceFactory(false, null, null) {
   1048                     @Override
   1049                     public IManagedTestDevice createDevice(IDevice idevice) {
   1050                         mMockTestDevice.setIDevice(idevice);
   1051                         return testDevice;
   1052                     }
   1053 
   1054                     @Override
   1055                     protected CollectingOutputReceiver createOutputReceiver() {
   1056                         return new CollectingOutputReceiver() {
   1057                             @Override
   1058                             public String getOutput() {
   1059                                 return "/system/bin/pm";
   1060                             }
   1061                         };
   1062                     }
   1063 
   1064                     @Override
   1065                     public void setFastbootEnabled(boolean enable) {
   1066                         // ignore
   1067                     }
   1068                 });
   1069 
   1070         mDeviceListener.deviceConnected(mMockIDevice);
   1071 
   1072         IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice();
   1073         assertNotNull(device);
   1074         // device becomes unavailable
   1075         device.setDeviceState(TestDeviceState.NOT_AVAILABLE);
   1076         // a freed 'unavailable' device becomes UNAVAILABLE state
   1077         manager.freeDevice(device, FreeDeviceState.UNAVAILABLE);
   1078         // ensure device cannot be allocated again
   1079         ITestDevice device2 = manager.allocateDevice();
   1080         assertNull(device2);
   1081         verifyMocks();
   1082         // We have 0 device in the list since it was removed
   1083         assertEquals(0, manager.getDeviceList().size());
   1084     }
   1085 
   1086     /**
   1087      * Helper to set the expectation when a {@link DeviceDescriptor} is expected.
   1088      */
   1089     private void setDeviceDescriptorExpectation() {
   1090         EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE);
   1091         EasyMock.expect(mMockTestDevice.getAllocationState())
   1092                 .andReturn(DeviceAllocationState.Available);
   1093         EasyMock.expect(mMockIDevice.getProperty("ro.hardware")).andReturn("hardware_test");
   1094         EasyMock.expect(mMockIDevice.getProperty("ro.product.device")).andReturn("product_test");
   1095         EasyMock.expect(mMockIDevice.getProperty("ro.build.version.sdk")).andReturn("sdk");
   1096         EasyMock.expect(mMockIDevice.getProperty("ro.build.id")).andReturn("bid_test");
   1097         SettableFuture<Integer> future = SettableFuture.create();
   1098         future.set(50);
   1099         EasyMock.expect(mMockIDevice.getBattery()).andReturn(future);
   1100         EasyMock.expect(mMockTestDevice.getDeviceClass()).andReturn("class");
   1101     }
   1102 
   1103     /**
   1104      * Test that {@link DeviceManager#listAllDevices()} returns a list with all devices.
   1105      */
   1106     public void testListAllDevices() throws Exception {
   1107         setCheckAvailableDeviceExpectations();
   1108         setDeviceDescriptorExpectation();
   1109         replayMocks();
   1110         DeviceManager manager = createDeviceManager(null, mMockIDevice);
   1111         List<DeviceDescriptor> res = manager.listAllDevices();
   1112         assertEquals(1, res.size());
   1113         assertEquals("[serial hardware_test:product_test bid_test]", res.get(0).toString());
   1114         assertEquals(MAC_ADDRESS, res.get(0).getMacAddress());
   1115         assertEquals(SIM_STATE, res.get(0).getSimState());
   1116         assertEquals(SIM_OPERATOR, res.get(0).getSimOperator());
   1117         verifyMocks();
   1118     }
   1119 
   1120     /**
   1121      * Test that {@link DeviceManager#displayDevicesInfo(PrintWriter)} properly print out the
   1122      * device info.
   1123      */
   1124     public void testDisplayDevicesInfo() throws Exception {
   1125         setCheckAvailableDeviceExpectations();
   1126         setDeviceDescriptorExpectation();
   1127         replayMocks();
   1128         DeviceManager manager = createDeviceManager(null, mMockIDevice);
   1129         ByteArrayOutputStream out = new ByteArrayOutputStream();
   1130         PrintWriter pw = new PrintWriter(out);
   1131         manager.displayDevicesInfo(pw);
   1132         pw.flush();
   1133         verifyMocks();
   1134         assertEquals("Serial  State   Allocation  Product        Variant       Build     Battery  "
   1135                 + "\nserial  ONLINE  Available   hardware_test  product_test  bid_test  50       "
   1136                 + "\n", out.toString());
   1137     }
   1138 
   1139     /**
   1140      * Test that {@link DeviceManager#shouldAdbBridgeBeRestarted()} properly reports the flag state
   1141      * based on if it was requested or not.
   1142      */
   1143     public void testAdbBridgeFlag() throws Exception {
   1144         setCheckAvailableDeviceExpectations();
   1145         replayMocks();
   1146         DeviceManager manager = createDeviceManager(null, mMockIDevice);
   1147 
   1148         assertFalse(manager.shouldAdbBridgeBeRestarted());
   1149         manager.stopAdbBridge();
   1150         assertTrue(manager.shouldAdbBridgeBeRestarted());
   1151         manager.restartAdbBridge();
   1152         assertFalse(manager.shouldAdbBridgeBeRestarted());
   1153 
   1154         verifyMocks();
   1155     }
   1156 
   1157     /**
   1158      * Test that when a {@link IDeviceMonitor} is available in {@link DeviceManager} it properly
   1159      * goes through its life cycle.
   1160      */
   1161     public void testDeviceMonitorLifeCyle() throws Exception {
   1162         IDeviceMonitor mockMonitor = EasyMock.createMock(IDeviceMonitor.class);
   1163         List<IDeviceMonitor> monitors = new ArrayList<>();
   1164         monitors.add(mockMonitor);
   1165         setCheckAvailableDeviceExpectations();
   1166 
   1167         mockMonitor.setDeviceLister(EasyMock.anyObject());
   1168         mockMonitor.run();
   1169         mockMonitor.stop();
   1170 
   1171         replayMocks(mockMonitor);
   1172         DeviceManager manager = createDeviceManager(monitors, mMockIDevice);
   1173         manager.terminateDeviceMonitor();
   1174         verifyMocks(mockMonitor);
   1175     }
   1176 }
   1177