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 static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.doNothing; 27 import static org.mockito.Mockito.doThrow; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener; 34 import com.android.ddmlib.IDevice; 35 import com.android.ddmlib.IDevice.DeviceState; 36 import com.android.tradefed.command.remote.DeviceDescriptor; 37 import com.android.tradefed.config.IGlobalConfiguration; 38 import com.android.tradefed.config.OptionSetter; 39 import com.android.tradefed.device.IManagedTestDevice.DeviceEventResponse; 40 import com.android.tradefed.host.HostOptions; 41 import com.android.tradefed.host.IHostOptions; 42 import com.android.tradefed.log.ILogRegistry.EventType; 43 import com.android.tradefed.util.ArrayUtil; 44 import com.android.tradefed.util.CommandResult; 45 import com.android.tradefed.util.CommandStatus; 46 import com.android.tradefed.util.FileUtil; 47 import com.android.tradefed.util.IRunUtil; 48 import com.android.tradefed.util.ZipUtil; 49 50 import org.junit.Before; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.junit.runners.JUnit4; 54 import org.mockito.ArgumentCaptor; 55 import org.mockito.Mock; 56 import org.mockito.Mockito; 57 import org.mockito.MockitoAnnotations; 58 59 import java.io.ByteArrayOutputStream; 60 import java.io.File; 61 import java.io.InputStream; 62 import java.io.OutputStream; 63 import java.io.PrintWriter; 64 import java.util.ArrayList; 65 import java.util.List; 66 import java.util.concurrent.TimeUnit; 67 68 /** Unit tests for {@link DeviceManager}. */ 69 @RunWith(JUnit4.class) 70 public class DeviceManagerTest { 71 72 private static final String DEVICE_SERIAL = "serial"; 73 private static final String MAC_ADDRESS = "FF:FF:FF:FF:FF:FF"; 74 private static final String SIM_STATE = "READY"; 75 private static final String SIM_OPERATOR = "operator"; 76 77 @Mock IAndroidDebugBridge mMockAdbBridge; 78 @Mock IDevice mMockIDevice; 79 @Mock IDeviceStateMonitor mMockStateMonitor; 80 @Mock IRunUtil mMockRunUtil; 81 @Mock IHostOptions mMockHostOptions; 82 @Mock IManagedTestDevice mMockTestDevice; 83 private IManagedTestDeviceFactory mMockDeviceFactory; 84 @Mock IGlobalConfiguration mMockGlobalConfig; 85 private DeviceSelectionOptions mDeviceSelections; 86 87 /** 88 * a reference to the DeviceManager's IDeviceChangeListener. Used for triggering device 89 * connection events 90 */ 91 private IDeviceChangeListener mDeviceListener; 92 93 static class MockProcess extends Process { 94 /** {@inheritDoc} */ 95 @Override destroy()96 public void destroy() { 97 // ignore 98 } 99 100 /** {@inheritDoc} */ 101 @Override exitValue()102 public int exitValue() { 103 return 0; 104 } 105 106 /** {@inheritDoc} */ 107 @Override getErrorStream()108 public InputStream getErrorStream() { 109 return null; 110 } 111 112 /** {@inheritDoc} */ 113 @Override getInputStream()114 public InputStream getInputStream() { 115 return null; 116 } 117 118 /** {@inheritDoc} */ 119 @Override getOutputStream()120 public OutputStream getOutputStream() { 121 return null; 122 } 123 124 /** {@inheritDoc} */ 125 @Override waitFor()126 public int waitFor() throws InterruptedException { 127 return 0; 128 } 129 } 130 131 @Before setUp()132 public void setUp() throws Exception { 133 MockitoAnnotations.initMocks(this); 134 135 doAnswer( 136 invocation -> { 137 Object arg0 = invocation.getArgument(0); 138 mDeviceListener = (IDeviceChangeListener) arg0; 139 return null; 140 }) 141 .when(mMockAdbBridge) 142 .addDeviceChangeListener((IDeviceChangeListener) Mockito.any()); 143 144 mMockDeviceFactory = 145 new ManagedTestDeviceFactory(false, null, null) { 146 @Override 147 public IManagedTestDevice createDevice(IDevice idevice) { 148 mMockTestDevice.setIDevice(idevice); 149 return mMockTestDevice; 150 } 151 152 @Override 153 protected CollectingOutputReceiver createOutputReceiver() { 154 return new CollectingOutputReceiver() { 155 @Override 156 public String getOutput() { 157 return "/system/bin/pm"; 158 } 159 }; 160 } 161 162 @Override 163 public void setFastbootEnabled(boolean enable) { 164 // ignore 165 } 166 }; 167 168 when(mMockGlobalConfig.getHostOptions()).thenReturn(new HostOptions()); 169 170 when(mMockIDevice.getSerialNumber()).thenReturn(DEVICE_SERIAL); 171 when(mMockStateMonitor.getSerialNumber()).thenReturn(DEVICE_SERIAL); 172 173 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 174 when(mMockTestDevice.getMacAddress()).thenReturn(MAC_ADDRESS); 175 when(mMockTestDevice.getSimState()).thenReturn(SIM_STATE); 176 when(mMockTestDevice.getSimOperator()).thenReturn(SIM_OPERATOR); 177 final ArgumentCaptor<IDevice> capturedIDevice = ArgumentCaptor.forClass(IDevice.class); 178 doNothing().when(mMockTestDevice).setIDevice(capturedIDevice.capture()); 179 180 when(mMockTestDevice.getIDevice()) 181 .thenAnswer( 182 invocation -> { 183 return capturedIDevice.getValue(); 184 }); 185 when(mMockTestDevice.getSerialNumber()) 186 .thenAnswer( 187 invocation -> { 188 return capturedIDevice.getValue().getSerialNumber(); 189 }); 190 when(mMockTestDevice.getMonitor()).thenReturn(mMockStateMonitor); 191 when(mMockRunUtil.runTimedCmd( 192 Mockito.anyLong(), (String) Mockito.any(), (String) Mockito.any())) 193 .thenReturn(new CommandResult()); 194 when(mMockRunUtil.runTimedCmdSilently( 195 Mockito.anyLong(), (String) Mockito.any(), (String) Mockito.any())) 196 .thenReturn(new CommandResult()); 197 // Avoid any issue related to env. variable. 198 mDeviceSelections = 199 new DeviceSelectionOptions() { 200 @Override 201 public String fetchEnvironmentVariable(String name) { 202 return null; 203 } 204 }; 205 when(mMockGlobalConfig.getDeviceRequirements()).thenReturn(mDeviceSelections); 206 } 207 createDeviceManager( List<IDeviceMonitor> deviceMonitors, IDevice... devices)208 private DeviceManager createDeviceManager( 209 List<IDeviceMonitor> deviceMonitors, IDevice... devices) { 210 DeviceManager mgr = createDeviceManagerNoInit(); 211 mgr.init(null, deviceMonitors, mMockDeviceFactory); 212 for (IDevice device : devices) { 213 mDeviceListener.deviceConnected(device); 214 } 215 return mgr; 216 } 217 createDeviceManagerNoInit()218 private DeviceManager createDeviceManagerNoInit() { 219 220 DeviceManager mgr = 221 new DeviceManager() { 222 @Override 223 IAndroidDebugBridge createAdbBridge() { 224 return mMockAdbBridge; 225 } 226 227 @Override 228 void startFastbootMonitor() {} 229 230 @Override 231 void startDeviceRecoverer() {} 232 233 @Override 234 void logDeviceEvent(EventType event, String serial) {} 235 236 @Override 237 IDeviceStateMonitor createStateMonitor(IDevice device) { 238 return mMockStateMonitor; 239 } 240 241 @Override 242 IGlobalConfiguration getGlobalConfig() { 243 return mMockGlobalConfig; 244 } 245 246 @Override 247 IRunUtil getRunUtil() { 248 return mMockRunUtil; 249 } 250 251 @Override 252 IHostOptions getHostOptions() { 253 return mMockHostOptions; 254 } 255 }; 256 mgr.setSynchronousMode(true); 257 mgr.setMaxEmulators(0); 258 mgr.setMaxNullDevices(0); 259 mgr.setMaxGceDevices(0); 260 mgr.setMaxRemoteDevices(0); 261 return mgr; 262 } 263 264 /** 265 * Test @link DeviceManager#allocateDevice()} when a IDevice is present on DeviceManager 266 * creation. 267 */ 268 @Test testAllocateDevice()269 public void testAllocateDevice() { 270 setCheckAvailableDeviceExpectations(); 271 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 272 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 273 274 DeviceManager manager = createDeviceManager(null, mMockIDevice); 275 assertNotNull(manager.allocateDevice(mDeviceSelections)); 276 } 277 278 /** 279 * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean)} when device is returned. 280 */ 281 @Test testAllocateDevice_match()282 public void testAllocateDevice_match() { 283 mDeviceSelections.addSerial(DEVICE_SERIAL); 284 setCheckAvailableDeviceExpectations(); 285 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.EXPLICIT_ALLOCATE_REQUEST)) 286 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 287 288 DeviceManager manager = createDeviceManager(null, mMockIDevice); 289 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections, false)); 290 } 291 292 /** 293 * Test that when allocating a fake device we create a placeholder then delete it at the end. 294 */ 295 @Test testAllocateDevice_match_temporary()296 public void testAllocateDevice_match_temporary() { 297 mDeviceSelections.setNullDeviceRequested(true); 298 mDeviceSelections.addSerial(DEVICE_SERIAL); 299 // Force create a device 300 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE)) 301 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 302 // Device get allocated 303 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.EXPLICIT_ALLOCATE_REQUEST)) 304 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 305 306 mMockTestDevice.stopLogcat(); 307 308 // De-allocate 309 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 310 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true)); 311 312 DeviceManager manager = createDeviceManager(null); 313 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections, true)); 314 String serial = mMockTestDevice.getSerialNumber(); 315 assertTrue(serial.startsWith("null-device-temp-")); 316 317 // Release device 318 manager.freeDevice(mMockTestDevice, FreeDeviceState.AVAILABLE); 319 // Check that temp device was deleted. 320 DeviceSelectionOptions validation = new DeviceSelectionOptions(); 321 validation.setNullDeviceRequested(true); 322 validation.addSerial(serial); 323 // If we request the particular null-device again it doesn't exists. 324 assertNull(manager.allocateDevice(validation, false)); 325 } 326 327 /** 328 * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean)} when stub emulator is 329 * requested. 330 */ 331 @Test testAllocateDevice_stubEmulator()332 public void testAllocateDevice_stubEmulator() { 333 mDeviceSelections.setStubEmulatorRequested(true); 334 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE)) 335 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 336 when(mMockIDevice.isEmulator()).thenReturn(Boolean.TRUE); 337 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 338 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 339 340 DeviceManager mgr = createDeviceManagerNoInit(); 341 mgr.setMaxEmulators(1); 342 mgr.init(null, null, mMockDeviceFactory); 343 assertNotNull(mgr.allocateDevice(mDeviceSelections, false)); 344 } 345 346 /** Test that when a zipped fastboot file is provided we unpack it and use it. */ 347 @Test testUnpackZippedFastboot()348 public void testUnpackZippedFastboot() throws Exception { 349 File tmpDir = FileUtil.createTempDir("fake-fastbootdir"); 350 File fastboot = new File(tmpDir, "fastboot"); 351 FileUtil.writeToFile("TEST", fastboot); 352 File zipDir = ZipUtil.createZip(tmpDir); 353 354 DeviceManager mgr = createDeviceManagerNoInit(); 355 try { 356 OptionSetter setter = new OptionSetter(mgr); 357 setter.setOptionValue("fastboot-path", zipDir.getAbsolutePath()); 358 mgr.init(null, null, mMockDeviceFactory); 359 assertTrue(mgr.getFastbootPath().contains("fastboot")); 360 assertEquals("TEST", FileUtil.readStringFromFile(new File(mgr.getFastbootPath()))); 361 } finally { 362 FileUtil.recursiveDelete(tmpDir); 363 FileUtil.deleteFile(zipDir); 364 mgr.terminate(); 365 } 366 } 367 368 /** Test freeing an emulator */ 369 @Test testFreeDevice_emulator()370 public void testFreeDevice_emulator() throws DeviceNotAvailableException { 371 mDeviceSelections.setStubEmulatorRequested(true); 372 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE)) 373 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 374 when(mMockIDevice.isEmulator()).thenReturn(Boolean.TRUE); 375 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 376 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 377 378 when(mMockTestDevice.executeAdbCommand("emu", "kill")).thenReturn(""); 379 when(mMockTestDevice.getEmulatorProcess()).thenReturn(new MockProcess()); 380 when(mMockTestDevice.waitForDeviceNotAvailable(Mockito.anyLong())).thenReturn(Boolean.TRUE); 381 when(mMockTestDevice.waitForDeviceNotAvailable(Mockito.anyLong())).thenReturn(Boolean.TRUE); 382 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_AVAILABLE)) 383 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 384 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 385 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 386 387 DeviceManager manager = createDeviceManagerNoInit(); 388 manager.setMaxEmulators(1); 389 manager.init(null, null, mMockDeviceFactory); 390 IManagedTestDevice emulator = 391 (IManagedTestDevice) manager.allocateDevice(mDeviceSelections, false); 392 assertNotNull(emulator); 393 // a freed 'unavailable' emulator should be returned to the available 394 // queue. 395 manager.freeDevice(emulator, FreeDeviceState.UNAVAILABLE); 396 // ensure device can be allocated again 397 assertNotNull(manager.allocateDevice(mDeviceSelections, false)); 398 399 verify(mMockTestDevice).stopLogcat(); 400 verify(mMockTestDevice).stopEmulatorOutput(); 401 } 402 403 /** 404 * Test {@link DeviceManager#allocateDevice(IDeviceSelection, boolean)} when a null device is 405 * requested. 406 */ 407 @Test testAllocateDevice_nullDevice()408 public void testAllocateDevice_nullDevice() { 409 mDeviceSelections.setNullDeviceRequested(true); 410 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 411 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE)) 412 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 413 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 414 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 415 416 DeviceManager mgr = createDeviceManagerNoInit(); 417 mgr.setMaxNullDevices(1); 418 mgr.init(null, null, mMockDeviceFactory); 419 ITestDevice device = mgr.allocateDevice(mDeviceSelections, false); 420 assertNotNull(device); 421 assertTrue(device.getIDevice() instanceof NullDevice); 422 } 423 424 /** Test {@link DeviceManager#forceAllocateDevice(String)} when device is unknown */ 425 @Test testForceAllocateDevice()426 public void testForceAllocateDevice() { 427 428 DeviceManager manager = createDeviceManager(null); 429 assertNull(manager.forceAllocateDevice("unknownserial")); 430 } 431 432 /** Test {@link DeviceManager#forceAllocateDevice(String)} when device is available */ 433 @Test testForceAllocateDevice_available()434 public void testForceAllocateDevice_available() { 435 setCheckAvailableDeviceExpectations(); 436 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST)) 437 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 438 439 DeviceManager manager = createDeviceManager(null, mMockIDevice); 440 assertNotNull(manager.forceAllocateDevice(DEVICE_SERIAL)); 441 } 442 443 /** Test {@link DeviceManager#forceAllocateDevice(String)} when device is already allocated */ 444 @Test testForceAllocateDevice_alreadyAllocated()445 public void testForceAllocateDevice_alreadyAllocated() { 446 setCheckAvailableDeviceExpectations(); 447 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 448 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 449 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST)) 450 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false)); 451 452 DeviceManager manager = createDeviceManager(null, mMockIDevice); 453 assertNotNull(manager.allocateDevice(mDeviceSelections)); 454 assertNull(manager.forceAllocateDevice(DEVICE_SERIAL)); 455 } 456 457 /** Test method for {@link DeviceManager#freeDevice(ITestDevice, FreeDeviceState)}. */ 458 @Test testFreeDevice()459 public void testFreeDevice() { 460 setCheckAvailableDeviceExpectations(); 461 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 462 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 463 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_AVAILABLE)) 464 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 465 466 DeviceManager manager = createDeviceManager(null); 467 mDeviceListener.deviceConnected(mMockIDevice); 468 assertNotNull(manager.allocateDevice(mDeviceSelections)); 469 manager.freeDevice(mMockTestDevice, FreeDeviceState.AVAILABLE); 470 471 verify(mMockTestDevice).stopLogcat(); 472 } 473 474 /** 475 * Verified that {@link DeviceManager#freeDevice(ITestDevice, FreeDeviceState)} ignores a call 476 * with a device that has not been allocated. 477 */ 478 @Test testFreeDevice_noop()479 public void testFreeDevice_noop() { 480 setCheckAvailableDeviceExpectations(); 481 IManagedTestDevice testDevice = mock(IManagedTestDevice.class); 482 IDevice mockIDevice = mock(IDevice.class); 483 when(testDevice.getIDevice()).thenReturn(mockIDevice); 484 when(mockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 485 486 DeviceManager manager = createDeviceManager(null, mMockIDevice); 487 manager.freeDevice(testDevice, FreeDeviceState.AVAILABLE); 488 } 489 490 /** 491 * Verified that {@link DeviceManager} calls {@link IManagedTestDevice#setIDevice(IDevice)} when 492 * DDMS allocates a new IDevice on connection. 493 */ 494 @Test testSetIDevice()495 public void testSetIDevice() { 496 setCheckAvailableDeviceExpectations(); 497 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Available); 498 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 499 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 500 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.DISCONNECTED)) 501 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false)); 502 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE)) 503 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false)); 504 IDevice newMockDevice = mock(IDevice.class); 505 when(newMockDevice.getSerialNumber()).thenReturn(DEVICE_SERIAL); 506 when(newMockDevice.getState()).thenReturn(DeviceState.ONLINE); 507 508 DeviceManager manager = createDeviceManager(null, mMockIDevice); 509 ITestDevice device = manager.allocateDevice(mDeviceSelections); 510 assertNotNull(device); 511 // now trigger a device disconnect + reconnection 512 mDeviceListener.deviceDisconnected(mMockIDevice); 513 mDeviceListener.deviceConnected(newMockDevice); 514 assertEquals(newMockDevice, device.getIDevice()); 515 516 verify(mMockTestDevice, times(1)).setDeviceState(TestDeviceState.NOT_AVAILABLE); 517 verify(mMockTestDevice, times(2)).setDeviceState(TestDeviceState.ONLINE); 518 } 519 520 /** 521 * Test {@link DeviceManager#allocateDevice()} when {@link DeviceManager#init()} has not been 522 * called. 523 */ 524 @Test testAllocateDevice_noInit()525 public void testAllocateDevice_noInit() { 526 try { 527 createDeviceManagerNoInit().allocateDevice(mDeviceSelections); 528 fail("IllegalStateException not thrown when manager has not been initialized"); 529 } catch (IllegalStateException e) { 530 // expected 531 } 532 } 533 534 /** Test {@link DeviceManager#init(IDeviceSelection, List)} with a global exclusion filter */ 535 @Test testInit_excludeDevice()536 public void testInit_excludeDevice() throws Exception { 537 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 538 539 DeviceEventResponse der = 540 new DeviceEventResponse(DeviceAllocationState.Checking_Availability, true); 541 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE)).thenReturn(der); 542 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_IGNORED)) 543 .thenReturn(null); 544 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 545 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Ignored, false)); 546 547 DeviceManager manager = createDeviceManagerNoInit(); 548 DeviceSelectionOptions excludeFilter = new DeviceSelectionOptions(); 549 excludeFilter.addExcludeSerial(mMockIDevice.getSerialNumber()); 550 manager.init(excludeFilter, null, mMockDeviceFactory); 551 mDeviceListener.deviceConnected(mMockIDevice); 552 assertEquals(1, manager.getDeviceList().size()); 553 assertNull(manager.allocateDevice(mDeviceSelections)); 554 verify(mMockTestDevice, times(1)).setDeviceState(TestDeviceState.ONLINE); 555 } 556 557 /** Test {@link DeviceManager#init(IDeviceSelection, List)} with a global inclusion filter */ 558 @Test testInit_includeDevice()559 public void testInit_includeDevice() throws Exception { 560 IDevice excludedDevice = mock(IDevice.class); 561 when(excludedDevice.getSerialNumber()).thenReturn("excluded"); 562 when(excludedDevice.getState()).thenReturn(DeviceState.ONLINE); 563 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 564 when(excludedDevice.isEmulator()).thenReturn(Boolean.FALSE); 565 566 DeviceEventResponse der = 567 new DeviceEventResponse(DeviceAllocationState.Checking_Availability, true); 568 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE)).thenReturn(der); 569 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_IGNORED)) 570 .thenReturn(null); 571 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 572 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Ignored, false)); 573 574 DeviceManager manager = createDeviceManagerNoInit(); 575 mDeviceSelections.addSerial(mMockIDevice.getSerialNumber()); 576 manager.init(mDeviceSelections, null, mMockDeviceFactory); 577 mDeviceListener.deviceConnected(excludedDevice); 578 assertEquals(1, manager.getDeviceList().size()); 579 // ensure excludedDevice cannot be allocated 580 assertNull(manager.allocateDevice()); 581 582 verify(mMockTestDevice).setDeviceState(TestDeviceState.ONLINE); 583 } 584 585 /** Verified that a disconnected device state gets updated */ 586 @Test testSetState_disconnected()587 public void testSetState_disconnected() { 588 setCheckAvailableDeviceExpectations(); 589 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 590 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 591 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.DISCONNECTED)) 592 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false)); 593 594 DeviceManager manager = createDeviceManager(null, mMockIDevice); 595 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections)); 596 mDeviceListener.deviceDisconnected(mMockIDevice); 597 598 verify(mMockTestDevice).setDeviceState(TestDeviceState.NOT_AVAILABLE); 599 } 600 601 /** Verified that a offline device state gets updated */ 602 @Test testSetState_offline()603 public void testSetState_offline() { 604 setCheckAvailableDeviceExpectations(); 605 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Allocated); 606 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 607 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 608 609 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.STATE_CHANGE_OFFLINE)) 610 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unavailable, true)); 611 612 DeviceManager manager = createDeviceManager(null, mMockIDevice); 613 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections)); 614 IDevice newDevice = mock(IDevice.class); 615 when(newDevice.getSerialNumber()).thenReturn(DEVICE_SERIAL); 616 when(newDevice.getState()).thenReturn(DeviceState.OFFLINE); 617 618 mDeviceListener.deviceChanged(newDevice, IDevice.CHANGE_STATE); 619 620 verify(mMockTestDevice).setDeviceState(TestDeviceState.NOT_AVAILABLE); 621 622 verify(newDevice, times(2)).getState(); 623 } 624 625 // TODO: add test for fastboot state changes 626 627 /** Test normal success case for {@link DeviceManager#connectToTcpDevice(String)} */ 628 @Test testConnectToTcpDevice()629 public void testConnectToTcpDevice() throws Exception { 630 final String ipAndPort = "ip:5555"; 631 setConnectToTcpDeviceExpectations(ipAndPort); 632 633 DeviceManager manager = createDeviceManager(null); 634 IManagedTestDevice device = (IManagedTestDevice) manager.connectToTcpDevice(ipAndPort); 635 assertNotNull(device); 636 637 verify(mMockTestDevice).waitForDeviceOnline(); 638 } 639 640 /** 641 * Test a {@link DeviceManager#connectToTcpDevice(String)} call where device is already 642 * allocated 643 */ 644 @Test testConnectToTcpDevice_alreadyAllocated()645 public void testConnectToTcpDevice_alreadyAllocated() throws Exception { 646 final String ipAndPort = "ip:5555"; 647 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST)) 648 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)) 649 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, false)); 650 CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS); 651 connectResult.setStdout(String.format("connected to %s", ipAndPort)); 652 when(mMockRunUtil.runTimedCmd( 653 Mockito.anyLong(), 654 Mockito.eq("adb"), 655 Mockito.eq("connect"), 656 Mockito.eq(ipAndPort))) 657 .thenReturn(connectResult); 658 659 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Allocated); 660 661 DeviceManager manager = createDeviceManager(null); 662 IManagedTestDevice device = (IManagedTestDevice) manager.connectToTcpDevice(ipAndPort); 663 assertNotNull(device); 664 // now attempt to re-allocate 665 assertNull(manager.connectToTcpDevice(ipAndPort)); 666 667 verify(mMockTestDevice).waitForDeviceOnline(); 668 } 669 670 /** Test {@link DeviceManager#connectToTcpDevice(String)} where device does not appear on adb */ 671 @Test testConnectToTcpDevice_notOnline()672 public void testConnectToTcpDevice_notOnline() throws Exception { 673 final String ipAndPort = "ip:5555"; 674 setConnectToTcpDeviceExpectations(ipAndPort); 675 doThrow(new DeviceNotAvailableException("test", "serial")) 676 .when(mMockTestDevice) 677 .waitForDeviceOnline(); 678 679 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 680 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, false)); 681 682 DeviceManager manager = createDeviceManager(null); 683 assertNull(manager.connectToTcpDevice(ipAndPort)); 684 // verify device is not in list 685 assertEquals(0, manager.getDeviceList().size()); 686 687 verify(mMockTestDevice).stopLogcat(); 688 } 689 690 /** Test {@link DeviceManager#connectToTcpDevice(String)} where the 'adb connect' call fails. */ 691 @Test testConnectToTcpDevice_connectFailed()692 public void testConnectToTcpDevice_connectFailed() throws Exception { 693 final String ipAndPort = "ip:5555"; 694 695 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST)) 696 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 697 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 698 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true)); 699 CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS); 700 connectResult.setStdout(String.format("failed to connect to %s", ipAndPort)); 701 when(mMockRunUtil.runTimedCmd( 702 Mockito.anyLong(), 703 Mockito.eq("adb"), 704 Mockito.eq("connect"), 705 Mockito.eq(ipAndPort))) 706 .thenReturn(connectResult); 707 708 DeviceManager manager = createDeviceManager(null); 709 assertNull(manager.connectToTcpDevice(ipAndPort)); 710 // verify device is not in list 711 assertEquals(0, manager.getDeviceList().size()); 712 verify(mMockRunUtil, times(3)).sleep(Mockito.anyLong()); 713 verify(mMockRunUtil, times(3)) 714 .runTimedCmd( 715 Mockito.anyLong(), 716 Mockito.eq("adb"), 717 Mockito.eq("connect"), 718 Mockito.eq(ipAndPort)); 719 verify(mMockTestDevice).stopLogcat(); 720 } 721 722 /** Test normal success case for {@link DeviceManager#disconnectFromTcpDevice(ITestDevice)} */ 723 @Test testDisconnectFromTcpDevice()724 public void testDisconnectFromTcpDevice() throws Exception { 725 final String ipAndPort = "ip:5555"; 726 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 727 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true)); 728 setConnectToTcpDeviceExpectations(ipAndPort); 729 when(mMockTestDevice.switchToAdbUsb()).thenReturn(Boolean.TRUE); 730 731 DeviceManager manager = createDeviceManager(null); 732 assertNotNull(manager.connectToTcpDevice(ipAndPort)); 733 manager.disconnectFromTcpDevice(mMockTestDevice); 734 // verify device is not in allocated or available list 735 assertEquals(0, manager.getDeviceList().size()); 736 737 verify(mMockTestDevice).waitForDeviceOnline(); 738 verify(mMockTestDevice).stopLogcat(); 739 } 740 741 /** Test normal success case for {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)}. */ 742 @Test testReconnectDeviceToTcp()743 public void testReconnectDeviceToTcp() throws Exception { 744 final String ipAndPort = "ip:5555"; 745 // use the mMockTestDevice as the initially connected to usb device 746 setCheckAvailableDeviceExpectations(); 747 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 748 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 749 when(mMockTestDevice.switchToAdbTcp()).thenReturn(ipAndPort); 750 setConnectToTcpDeviceExpectations(ipAndPort); 751 752 DeviceManager manager = createDeviceManager(null, mMockIDevice); 753 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections)); 754 assertNotNull(manager.reconnectDeviceToTcp(mMockTestDevice)); 755 756 verify(mMockTestDevice).waitForDeviceOnline(); 757 } 758 759 /** 760 * Test {@link DeviceManager#reconnectDeviceToTcp(ITestDevice)} when tcp connected device does 761 * not come online. 762 */ 763 @Test testReconnectDeviceToTcp_notOnline()764 public void testReconnectDeviceToTcp_notOnline() throws Exception { 765 final String ipAndPort = "ip:5555"; 766 // use the mMockTestDevice as the initially connected to usb device 767 setCheckAvailableDeviceExpectations(); 768 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 769 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 770 when(mMockTestDevice.switchToAdbTcp()).thenReturn(ipAndPort); 771 setConnectToTcpDeviceExpectations(ipAndPort); 772 doThrow(new DeviceNotAvailableException("test", "serial")) 773 .when(mMockTestDevice) 774 .waitForDeviceOnline(); 775 // expect recover to be attempted on usb device 776 777 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 778 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Unknown, true)); 779 780 DeviceManager manager = createDeviceManager(null, mMockIDevice); 781 assertEquals(mMockTestDevice, manager.allocateDevice(mDeviceSelections)); 782 assertNull(manager.reconnectDeviceToTcp(mMockTestDevice)); 783 // verify only usb device is in list 784 assertEquals(1, manager.getDeviceList().size()); 785 786 verify(mMockTestDevice).recoverDevice(); 787 verify(mMockTestDevice).stopLogcat(); 788 } 789 790 /** Basic test for {@link DeviceManager#sortDeviceList(List)} */ 791 @Test testSortDeviceList()792 public void testSortDeviceList() { 793 DeviceDescriptor availDevice1 = createDeviceDesc("aaa", DeviceAllocationState.Available); 794 DeviceDescriptor availDevice2 = createDeviceDesc("bbb", DeviceAllocationState.Available); 795 DeviceDescriptor allocatedDevice = createDeviceDesc("ccc", DeviceAllocationState.Allocated); 796 List<DeviceDescriptor> deviceList = 797 ArrayUtil.list(availDevice1, availDevice2, allocatedDevice); 798 List<DeviceDescriptor> sortedList = DeviceManager.sortDeviceList(deviceList); 799 assertEquals(allocatedDevice, sortedList.get(0)); 800 assertEquals(availDevice1, sortedList.get(1)); 801 assertEquals(availDevice2, sortedList.get(2)); 802 } 803 804 /** Helper method to create a {@link DeviceDescriptor} using only serial and state. */ createDeviceDesc(String serial, DeviceAllocationState state)805 private DeviceDescriptor createDeviceDesc(String serial, DeviceAllocationState state) { 806 return new DeviceDescriptor(serial, false, state, null, null, null, null, null); 807 } 808 809 /** 810 * Set expectations for a successful {@link DeviceManager#connectToTcpDevice(String)} 811 * call. 812 * 813 * @param ipAndPort the ip and port of the device 814 * @throws DeviceNotAvailableException 815 */ setConnectToTcpDeviceExpectations(final String ipAndPort)816 private void setConnectToTcpDeviceExpectations(final String ipAndPort) 817 throws DeviceNotAvailableException { 818 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_ALLOCATE_REQUEST)) 819 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 820 mMockTestDevice.setRecovery((IDeviceRecovery) Mockito.any()); 821 CommandResult connectResult = new CommandResult(CommandStatus.SUCCESS); 822 connectResult.setStdout(String.format("connected to %s", ipAndPort)); 823 when(mMockRunUtil.runTimedCmd( 824 Mockito.anyLong(), 825 Mockito.eq("adb"), 826 Mockito.eq("connect"), 827 Mockito.eq(ipAndPort))) 828 .thenReturn(connectResult); 829 } 830 831 /** 832 * Configure expectations for a {@link 833 * DeviceManager#checkAndAddAvailableDevice(IManagedTestDevice)} call for an online device 834 */ 835 @SuppressWarnings("javadoc") setCheckAvailableDeviceExpectations()836 private void setCheckAvailableDeviceExpectations() { 837 setCheckAvailableDeviceExpectations(mMockIDevice); 838 } 839 setCheckAvailableDeviceExpectations(IDevice iDevice)840 private void setCheckAvailableDeviceExpectations(IDevice iDevice) { 841 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 842 when(iDevice.getState()).thenReturn(DeviceState.ONLINE); 843 when(mMockStateMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(Boolean.TRUE); 844 when(mMockTestDevice.getDeviceState()).thenReturn(TestDeviceState.ONLINE); 845 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.CONNECTED_ONLINE)) 846 .thenReturn( 847 new DeviceEventResponse(DeviceAllocationState.Checking_Availability, true)); 848 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.AVAILABLE_CHECK_PASSED)) 849 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 850 } 851 852 /** Test freeing a tcp device, it must return to an unavailable status */ 853 @Test testFreeDevice_tcpDevice()854 public void testFreeDevice_tcpDevice() { 855 mDeviceSelections.setGceDeviceRequested(true); 856 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FORCE_AVAILABLE)) 857 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 858 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 859 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 860 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 861 862 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.ALLOCATE_REQUEST)) 863 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Allocated, true)); 864 when(mMockTestDevice.getDeviceState()).thenReturn(TestDeviceState.NOT_AVAILABLE); 865 when(mMockTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN)) 866 .thenReturn(new DeviceEventResponse(DeviceAllocationState.Available, true)); 867 868 DeviceManager manager = createDeviceManagerNoInit(); 869 manager.setMaxGceDevices(1); 870 manager.init(null, null, mMockDeviceFactory); 871 IManagedTestDevice tcpDevice = 872 (IManagedTestDevice) manager.allocateDevice(mDeviceSelections, false); 873 assertNotNull(tcpDevice); 874 // a freed 'unavailable' emulator should be returned to the available 875 // queue. 876 manager.freeDevice(tcpDevice, FreeDeviceState.UNAVAILABLE); 877 // ensure device can be allocated again 878 ITestDevice tcp = manager.allocateDevice(mDeviceSelections, false); 879 assertNotNull(tcp); 880 assertTrue(tcp.getDeviceState() == TestDeviceState.NOT_AVAILABLE); 881 verify(mMockTestDevice, times(2)).getDeviceState(); 882 verify(mMockTestDevice).stopLogcat(); 883 verify(mMockTestDevice).setDeviceState(TestDeviceState.NOT_AVAILABLE); 884 } 885 886 /** 887 * Test freeing a device that was unable but showing in adb devices. Device will become 888 * Unavailable but still seen by the DeviceManager. 889 */ 890 @Test testFreeDevice_unavailable()891 public void testFreeDevice_unavailable() { 892 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 893 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 894 when(mMockStateMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(Boolean.TRUE); 895 896 CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS); 897 stubAdbDevices.setStdout("List of devices attached\nserial\toffline\n"); 898 when(mMockRunUtil.runTimedCmd(Mockito.anyLong(), Mockito.eq("adb"), Mockito.eq("devices"))) 899 .thenReturn(stubAdbDevices); 900 901 IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null); 902 DeviceManager manager = createDeviceManagerNoInit(); 903 manager.init( 904 null, 905 null, 906 new ManagedTestDeviceFactory(false, null, null) { 907 @Override 908 public IManagedTestDevice createDevice(IDevice idevice) { 909 mMockTestDevice.setIDevice(idevice); 910 return testDevice; 911 } 912 913 @Override 914 protected CollectingOutputReceiver createOutputReceiver() { 915 return new CollectingOutputReceiver() { 916 @Override 917 public String getOutput() { 918 return "/system/bin/pm"; 919 } 920 }; 921 } 922 923 @Override 924 public void setFastbootEnabled(boolean enable) { 925 // ignore 926 } 927 }); 928 929 mDeviceListener.deviceConnected(mMockIDevice); 930 931 IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice(mDeviceSelections); 932 assertNotNull(device); 933 // device becomes unavailable 934 device.setDeviceState(TestDeviceState.NOT_AVAILABLE); 935 // a freed 'unavailable' device becomes UNAVAILABLE state 936 manager.freeDevice(device, FreeDeviceState.UNAVAILABLE); 937 // ensure device cannot be allocated again 938 ITestDevice device2 = manager.allocateDevice(mDeviceSelections); 939 assertNull(device2); 940 941 verify(mMockStateMonitor).setState(TestDeviceState.NOT_AVAILABLE); 942 943 // We still have the device in the list 944 assertEquals(1, manager.getDeviceList().size()); 945 } 946 947 /** Ensure that an unavailable device in recovery mode is released properly. */ 948 @Test testFreeDevice_recovery()949 public void testFreeDevice_recovery() { 950 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 951 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 952 when(mMockStateMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(Boolean.TRUE); 953 954 CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS); 955 stubAdbDevices.setStdout("List of devices attached\nserial\trecovery\n"); 956 when(mMockRunUtil.runTimedCmd(Mockito.anyLong(), Mockito.eq("adb"), Mockito.eq("devices"))) 957 .thenReturn(stubAdbDevices); 958 959 IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null); 960 DeviceManager manager = createDeviceManagerNoInit(); 961 manager.init( 962 null, 963 null, 964 new ManagedTestDeviceFactory(false, null, null) { 965 @Override 966 public IManagedTestDevice createDevice(IDevice idevice) { 967 mMockTestDevice.setIDevice(idevice); 968 return testDevice; 969 } 970 971 @Override 972 protected CollectingOutputReceiver createOutputReceiver() { 973 return new CollectingOutputReceiver() { 974 @Override 975 public String getOutput() { 976 return "/system/bin/pm"; 977 } 978 }; 979 } 980 981 @Override 982 public void setFastbootEnabled(boolean enable) { 983 // ignore 984 } 985 }); 986 987 mDeviceListener.deviceConnected(mMockIDevice); 988 989 IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice(mDeviceSelections); 990 assertNotNull(device); 991 // Device becomes unavailable 992 device.setDeviceState(TestDeviceState.NOT_AVAILABLE); 993 // A freed 'unavailable' device becomes UNAVAILABLE state 994 manager.freeDevice(device, FreeDeviceState.UNAVAILABLE); 995 // Ensure device cannot be allocated again 996 ITestDevice device2 = manager.allocateDevice(mDeviceSelections); 997 assertNull(device2); 998 999 verify(mMockStateMonitor).setState(TestDeviceState.NOT_AVAILABLE); 1000 1001 // We still have the device in the list because device is not lost. 1002 assertEquals(1, manager.getDeviceList().size()); 1003 } 1004 1005 /** 1006 * Test that when freeing an Unavailable device that is not in 'adb devices' we correctly remove 1007 * it from our tracking list. 1008 */ 1009 @Test testFreeDevice_unknown()1010 public void testFreeDevice_unknown() { 1011 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 1012 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 1013 when(mMockStateMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(Boolean.TRUE); 1014 1015 CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS); 1016 // device serial is not in the list 1017 stubAdbDevices.setStdout("List of devices attached\n"); 1018 when(mMockRunUtil.runTimedCmd(Mockito.anyLong(), Mockito.eq("adb"), Mockito.eq("devices"))) 1019 .thenReturn(stubAdbDevices); 1020 1021 IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null); 1022 DeviceManager manager = createDeviceManagerNoInit(); 1023 manager.init( 1024 null, 1025 null, 1026 new ManagedTestDeviceFactory(false, null, null) { 1027 @Override 1028 public IManagedTestDevice createDevice(IDevice idevice) { 1029 mMockTestDevice.setIDevice(idevice); 1030 return testDevice; 1031 } 1032 1033 @Override 1034 protected CollectingOutputReceiver createOutputReceiver() { 1035 return new CollectingOutputReceiver() { 1036 @Override 1037 public String getOutput() { 1038 return "/system/bin/pm"; 1039 } 1040 }; 1041 } 1042 1043 @Override 1044 public void setFastbootEnabled(boolean enable) { 1045 // ignore 1046 } 1047 }); 1048 1049 mDeviceListener.deviceConnected(mMockIDevice); 1050 1051 IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice(mDeviceSelections); 1052 assertNotNull(device); 1053 // device becomes unavailable 1054 device.setDeviceState(TestDeviceState.NOT_AVAILABLE); 1055 // a freed 'unavailable' device becomes UNAVAILABLE state 1056 manager.freeDevice(device, FreeDeviceState.UNAVAILABLE); 1057 // ensure device cannot be allocated again 1058 ITestDevice device2 = manager.allocateDevice(mDeviceSelections); 1059 assertNull(device2); 1060 1061 verify(mMockStateMonitor).setState(TestDeviceState.NOT_AVAILABLE); 1062 1063 // We have 0 device in the list since it was removed 1064 assertEquals(0, manager.getDeviceList().size()); 1065 } 1066 1067 /** 1068 * Test that when freeing an Unavailable device that is not in 'adb devices' we correctly remove 1069 * it from our tracking list even if its serial is a substring of another serial. 1070 */ 1071 @Test testFreeDevice_unknown_subName()1072 public void testFreeDevice_unknown_subName() { 1073 when(mMockIDevice.isEmulator()).thenReturn(Boolean.FALSE); 1074 when(mMockIDevice.getState()).thenReturn(DeviceState.ONLINE); 1075 when(mMockStateMonitor.waitForDeviceShell(Mockito.anyLong())).thenReturn(Boolean.TRUE); 1076 1077 CommandResult stubAdbDevices = new CommandResult(CommandStatus.SUCCESS); 1078 // device serial is not in the list 1079 stubAdbDevices.setStdout("List of devices attached\n2serial\tdevice\n"); 1080 when(mMockRunUtil.runTimedCmd(Mockito.anyLong(), Mockito.eq("adb"), Mockito.eq("devices"))) 1081 .thenReturn(stubAdbDevices); 1082 1083 IManagedTestDevice testDevice = new TestDevice(mMockIDevice, mMockStateMonitor, null); 1084 DeviceManager manager = createDeviceManagerNoInit(); 1085 manager.init( 1086 null, 1087 null, 1088 new ManagedTestDeviceFactory(false, null, null) { 1089 @Override 1090 public IManagedTestDevice createDevice(IDevice idevice) { 1091 mMockTestDevice.setIDevice(idevice); 1092 return testDevice; 1093 } 1094 1095 @Override 1096 protected CollectingOutputReceiver createOutputReceiver() { 1097 return new CollectingOutputReceiver() { 1098 @Override 1099 public String getOutput() { 1100 return "/system/bin/pm"; 1101 } 1102 }; 1103 } 1104 1105 @Override 1106 public void setFastbootEnabled(boolean enable) { 1107 // ignore 1108 } 1109 }); 1110 1111 mDeviceListener.deviceConnected(mMockIDevice); 1112 1113 IManagedTestDevice device = (IManagedTestDevice) manager.allocateDevice(mDeviceSelections); 1114 assertNotNull(device); 1115 // device becomes unavailable 1116 device.setDeviceState(TestDeviceState.NOT_AVAILABLE); 1117 // a freed 'unavailable' device becomes UNAVAILABLE state 1118 manager.freeDevice(device, FreeDeviceState.UNAVAILABLE); 1119 // ensure device cannot be allocated again 1120 ITestDevice device2 = manager.allocateDevice(mDeviceSelections); 1121 assertNull(device2); 1122 1123 verify(mMockStateMonitor).setState(TestDeviceState.NOT_AVAILABLE); 1124 1125 // We have 0 device in the list since it was removed 1126 assertEquals(0, manager.getDeviceList().size()); 1127 } 1128 1129 /** Helper to set the expectation when a {@link DeviceDescriptor} is expected. */ setDeviceDescriptorExpectation(boolean cached)1130 private void setDeviceDescriptorExpectation(boolean cached) { 1131 DeviceDescriptor descriptor = 1132 new DeviceDescriptor( 1133 "serial", 1134 null, 1135 false, 1136 DeviceState.ONLINE, 1137 DeviceAllocationState.Available, 1138 TestDeviceState.ONLINE, 1139 "hardware_test", 1140 "product_test", 1141 "sdk", 1142 "bid_test", 1143 null, 1144 "50", 1145 "class", 1146 MAC_ADDRESS, 1147 SIM_STATE, 1148 SIM_OPERATOR, 1149 false, 1150 null, 1151 null, 1152 null); 1153 if (cached) { 1154 when(mMockTestDevice.getCachedDeviceDescriptor(false)).thenReturn(descriptor); 1155 } else { 1156 when(mMockTestDevice.getDeviceDescriptor(false)).thenReturn(descriptor); 1157 } 1158 } 1159 1160 /** Test that {@link DeviceManager#listAllDevices()} returns a list with all devices. */ 1161 @Test testListAllDevices()1162 public void testListAllDevices() throws Exception { 1163 setCheckAvailableDeviceExpectations(); 1164 setDeviceDescriptorExpectation(true); 1165 1166 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1167 List<DeviceDescriptor> res = manager.listAllDevices(); 1168 assertEquals(1, res.size()); 1169 assertEquals("[serial hardware_test:product_test bid_test]", res.get(0).toString()); 1170 assertEquals(MAC_ADDRESS, res.get(0).getMacAddress()); 1171 assertEquals(SIM_STATE, res.get(0).getSimState()); 1172 assertEquals(SIM_OPERATOR, res.get(0).getSimOperator()); 1173 } 1174 1175 /** 1176 * Test {@link DeviceManager#getDeviceDescriptor(String)} returns the device with the given 1177 * serial. 1178 */ 1179 @Test testGetDeviceDescriptor()1180 public void testGetDeviceDescriptor() throws Exception { 1181 setCheckAvailableDeviceExpectations(); 1182 setDeviceDescriptorExpectation(false); 1183 1184 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1185 DeviceDescriptor res = manager.getDeviceDescriptor(mMockIDevice.getSerialNumber()); 1186 assertEquals("[serial hardware_test:product_test bid_test]", res.toString()); 1187 assertEquals(MAC_ADDRESS, res.getMacAddress()); 1188 assertEquals(SIM_STATE, res.getSimState()); 1189 assertEquals(SIM_OPERATOR, res.getSimOperator()); 1190 } 1191 1192 /** 1193 * Test that {@link DeviceManager#getDeviceDescriptor(String)} returns null if there are no 1194 * devices with the given serial. 1195 */ 1196 @Test testGetDeviceDescriptor_noMatch()1197 public void testGetDeviceDescriptor_noMatch() throws Exception { 1198 setCheckAvailableDeviceExpectations(); 1199 1200 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1201 DeviceDescriptor res = manager.getDeviceDescriptor("nomatch"); 1202 assertNull(res); 1203 } 1204 1205 /** 1206 * Test that {@link DeviceManager#displayDevicesInfo(PrintWriter, boolean)} properly print out 1207 * the device info. 1208 */ 1209 @Test testDisplayDevicesInfo()1210 public void testDisplayDevicesInfo() throws Exception { 1211 setCheckAvailableDeviceExpectations(); 1212 setDeviceDescriptorExpectation(true); 1213 1214 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1215 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1216 PrintWriter pw = new PrintWriter(out); 1217 manager.displayDevicesInfo(pw, false); 1218 pw.flush(); 1219 1220 assertEquals( 1221 "Serial State Allocation Product Variant Build Battery \n" 1222 + "serial ONLINE Available hardware_test product_test bid_test 50 " 1223 + " \n", 1224 out.toString()); 1225 } 1226 1227 /** 1228 * Test that {@link DeviceManager#shouldAdbBridgeBeRestarted()} properly reports the flag state 1229 * based on if it was requested or not. 1230 */ 1231 @Test testAdbBridgeFlag()1232 public void testAdbBridgeFlag() throws Exception { 1233 setCheckAvailableDeviceExpectations(); 1234 1235 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1236 1237 assertFalse(manager.shouldAdbBridgeBeRestarted()); 1238 manager.stopAdbBridge(); 1239 assertTrue(manager.shouldAdbBridgeBeRestarted()); 1240 manager.restartAdbBridge(); 1241 assertFalse(manager.shouldAdbBridgeBeRestarted()); 1242 } 1243 1244 /** 1245 * Test that when a {@link IDeviceMonitor} is available in {@link DeviceManager} it properly 1246 * goes through its life cycle. 1247 */ 1248 @Test testDeviceMonitorLifeCycle()1249 public void testDeviceMonitorLifeCycle() throws Exception { 1250 IDeviceMonitor mockMonitor = mock(IDeviceMonitor.class); 1251 List<IDeviceMonitor> monitors = new ArrayList<>(); 1252 monitors.add(mockMonitor); 1253 setCheckAvailableDeviceExpectations(); 1254 1255 DeviceManager manager = createDeviceManager(monitors, mMockIDevice); 1256 manager.terminateDeviceMonitor(); 1257 1258 verify(mockMonitor).setDeviceLister(Mockito.any()); 1259 verify(mockMonitor).run(); 1260 verify(mockMonitor).stop(); 1261 } 1262 1263 /** Ensure that restarting adb bridge doesn't restart {@link IDeviceMonitor}. */ 1264 @Test testDeviceMonitorLifeCycleWhenAdbRestarts()1265 public void testDeviceMonitorLifeCycleWhenAdbRestarts() throws Exception { 1266 IDeviceMonitor mockMonitor = mock(IDeviceMonitor.class); 1267 List<IDeviceMonitor> monitors = new ArrayList<>(); 1268 monitors.add(mockMonitor); 1269 setCheckAvailableDeviceExpectations(); 1270 1271 DeviceManager manager = createDeviceManager(monitors, mMockIDevice); 1272 manager.stopAdbBridge(); 1273 manager.restartAdbBridge(); 1274 manager.terminateDeviceMonitor(); 1275 1276 verify(mockMonitor).setDeviceLister(Mockito.any()); 1277 verify(mockMonitor).run(); 1278 verify(mockMonitor).stop(); 1279 } 1280 1281 /** Test the command fails without execution when the device is not available. */ 1282 @Test testExecCmdOnAvailableDevice_deviceNotAvailable()1283 public void testExecCmdOnAvailableDevice_deviceNotAvailable() { 1284 setCheckAvailableDeviceExpectations(); 1285 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Allocated); 1286 1287 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1288 CommandResult res = 1289 manager.executeCmdOnAvailableDevice( 1290 mMockTestDevice.getSerialNumber(), "mock cmd", 1, TimeUnit.SECONDS); 1291 assertEquals(CommandStatus.FAILED, res.getStatus()); 1292 assertEquals( 1293 "The device 'serial' is not available to execute the command", res.getStderr()); 1294 } 1295 1296 /** Test the command fails with long timeout. */ 1297 @Test testExecCmdOnAvailableDevice_longRunCmd()1298 public void testExecCmdOnAvailableDevice_longRunCmd() throws DeviceNotAvailableException { 1299 setCheckAvailableDeviceExpectations(); 1300 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Available); 1301 when(mMockTestDevice.executeShellV2Command("foo", 2, TimeUnit.SECONDS)) 1302 .thenReturn(new CommandResult(CommandStatus.SUCCESS)); 1303 1304 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1305 CommandResult res = 1306 manager.executeCmdOnAvailableDevice( 1307 mMockTestDevice.getSerialNumber(), "mock cmd", 2, TimeUnit.SECONDS); 1308 assertEquals(res.getStatus(), CommandStatus.FAILED); 1309 assertEquals(res.getStderr(), "The maximum timeout value is 1000 ms, but got 2000 ms."); 1310 } 1311 1312 /** Test the command success. */ 1313 @Test testExecCmdOnAvailableDevice_success()1314 public void testExecCmdOnAvailableDevice_success() throws DeviceNotAvailableException { 1315 setCheckAvailableDeviceExpectations(); 1316 when(mMockTestDevice.getAllocationState()).thenReturn(DeviceAllocationState.Available); 1317 when(mMockTestDevice.executeShellV2Command("foo", 1, TimeUnit.SECONDS)) 1318 .thenReturn( 1319 new CommandResult() { 1320 @Override 1321 public CommandStatus getStatus() { 1322 return CommandStatus.SUCCESS; 1323 } 1324 1325 @Override 1326 public String getStdout() { 1327 return "bar"; 1328 } 1329 }); 1330 1331 DeviceManager manager = createDeviceManager(null, mMockIDevice); 1332 CommandResult res = 1333 manager.executeCmdOnAvailableDevice( 1334 mMockTestDevice.getSerialNumber(), "foo", 1, TimeUnit.SECONDS); 1335 assertEquals(CommandStatus.SUCCESS, res.getStatus()); 1336 assertEquals("bar", res.getStdout()); 1337 } 1338 } 1339