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 package com.android.tradefed.device; 17 18 import com.google.common.util.concurrent.SettableFuture; 19 20 import com.android.ddmlib.IDevice; 21 import com.android.ddmlib.TimeoutException; 22 import com.android.tradefed.config.OptionSetter; 23 import com.android.tradefed.util.CommandResult; 24 import com.android.tradefed.util.CommandStatus; 25 import com.android.tradefed.util.IRunUtil; 26 27 import junit.framework.TestCase; 28 29 import org.easymock.EasyMock; 30 31 import java.io.IOException; 32 33 /** 34 * Unit tests for {@link WaitDeviceRecovery}. 35 */ 36 public class WaitDeviceRecoveryTest extends TestCase { 37 38 private IRunUtil mMockRunUtil; 39 private WaitDeviceRecovery mRecovery; 40 private IDeviceStateMonitor mMockMonitor; 41 private IDevice mMockDevice; 42 43 /** 44 * {@inheritDoc} 45 */ 46 @Override 47 protected void setUp() throws Exception { 48 super.setUp(); 49 mMockRunUtil = EasyMock.createMock(IRunUtil.class); 50 mRecovery = new WaitDeviceRecovery() { 51 @Override 52 protected IRunUtil getRunUtil() { 53 return mMockRunUtil; 54 } 55 }; 56 mMockMonitor = EasyMock.createMock(IDeviceStateMonitor.class); 57 EasyMock.expect(mMockMonitor.getSerialNumber()).andStubReturn("serial"); 58 mMockDevice = EasyMock.createMock(IDevice.class); 59 } 60 61 /** 62 * Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} 63 * when devices comes back online on its own accord. 64 */ 65 public void testRecoverDevice_success() throws DeviceNotAvailableException { 66 // expect initial sleep 67 mMockRunUtil.sleep(EasyMock.anyLong()); 68 mMockMonitor.waitForDeviceBootloaderStateUpdate(); 69 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.NOT_AVAILABLE); 70 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())).andReturn(mMockDevice); 71 EasyMock.expect(mMockMonitor.waitForDeviceShell(EasyMock.anyLong())).andReturn(true); 72 EasyMock.expect(mMockMonitor.waitForDeviceAvailable(EasyMock.anyLong())).andReturn( 73 mMockDevice); 74 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())).andReturn(mMockDevice); 75 replayMocks(); 76 mRecovery.recoverDevice(mMockMonitor, false); 77 verifyMocks(); 78 } 79 80 /** 81 * Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is 82 * not available. 83 */ 84 public void testRecoverDevice_unavailable() { 85 // expect initial sleep 86 mMockRunUtil.sleep(EasyMock.anyLong()); 87 mMockMonitor.waitForDeviceBootloaderStateUpdate(); 88 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.NOT_AVAILABLE); 89 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())).andReturn(null); 90 replayMocks(); 91 try { 92 mRecovery.recoverDevice(mMockMonitor, false); 93 fail("DeviceNotAvailableException not thrown"); 94 } catch (DeviceNotAvailableException e) { 95 // expected 96 } 97 verifyMocks(); 98 } 99 100 /** 101 * Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is 102 * not responsive. 103 */ 104 public void testRecoverDevice_unresponsive() throws Exception { 105 // expect initial sleep 106 mMockRunUtil.sleep(EasyMock.anyLong()); 107 mMockMonitor.waitForDeviceBootloaderStateUpdate(); 108 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.ONLINE); 109 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())) 110 .andReturn(mMockDevice).anyTimes(); 111 EasyMock.expect(mMockMonitor.waitForDeviceShell(EasyMock.anyLong())).andReturn(true); 112 EasyMock.expect(mMockMonitor.waitForDeviceAvailable(EasyMock.anyLong())) 113 .andReturn(null).anyTimes(); 114 mMockDevice.reboot((String)EasyMock.isNull()); 115 replayMocks(); 116 try { 117 mRecovery.recoverDevice(mMockMonitor, false); 118 fail("DeviceUnresponsiveException not thrown"); 119 } catch (DeviceUnresponsiveException e) { 120 // expected 121 } 122 verifyMocks(); 123 } 124 125 /** 126 * Test {@link WaitDeviceRecovery#recoverDevice(IDeviceStateMonitor, boolean)} when device is 127 * in fastboot. 128 */ 129 public void testRecoverDevice_fastboot() throws DeviceNotAvailableException { 130 // expect initial sleep 131 mMockRunUtil.sleep(EasyMock.anyLong()); 132 mMockMonitor.waitForDeviceBootloaderStateUpdate(); 133 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.FASTBOOT); 134 CommandResult result = new CommandResult(); 135 result.setStatus(CommandStatus.SUCCESS); 136 // expect reboot 137 EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), 138 EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("reboot"))). 139 andReturn(result); 140 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())) 141 .andReturn(mMockDevice); 142 EasyMock.expect(mMockMonitor.waitForDeviceShell(EasyMock.anyLong())).andReturn(true); 143 EasyMock.expect(mMockMonitor.waitForDeviceAvailable(EasyMock.anyLong())).andReturn( 144 mMockDevice); 145 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())) 146 .andReturn(mMockDevice); 147 replayMocks(); 148 mRecovery.recoverDevice(mMockMonitor, false); 149 verifyMocks(); 150 } 151 152 /** 153 * Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is 154 * already in bootloader 155 */ 156 public void testRecoverDeviceBootloader_fastboot() throws DeviceNotAvailableException { 157 mMockRunUtil.sleep(EasyMock.anyLong()); 158 // expect reboot 159 EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), 160 EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("reboot-bootloader"))). 161 andReturn(new CommandResult(CommandStatus.SUCCESS)); 162 EasyMock.expect(mMockMonitor.waitForDeviceNotAvailable(EasyMock.anyLong())).andReturn( 163 Boolean.TRUE); 164 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 165 Boolean.TRUE).times(2); 166 EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), 167 EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("getvar"), 168 EasyMock.eq("product"))). 169 andReturn(new CommandResult(CommandStatus.SUCCESS)); 170 replayMocks(); 171 mRecovery.recoverDeviceBootloader(mMockMonitor); 172 verifyMocks(); 173 } 174 175 /** 176 * Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is 177 * unavailable but comes back to bootloader on its own 178 */ 179 public void testRecoverDeviceBootloader_unavailable() throws DeviceNotAvailableException { 180 mMockRunUtil.sleep(EasyMock.anyLong()); 181 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 182 Boolean.FALSE); 183 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.NOT_AVAILABLE); 184 // expect reboot 185 EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), 186 EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("reboot-bootloader"))). 187 andReturn(new CommandResult(CommandStatus.SUCCESS)); 188 EasyMock.expect(mMockMonitor.waitForDeviceNotAvailable(EasyMock.anyLong())).andReturn( 189 Boolean.TRUE); 190 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 191 Boolean.TRUE).times(2); 192 EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), 193 EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("getvar"), 194 EasyMock.eq("product"))). 195 andReturn(new CommandResult(CommandStatus.SUCCESS)); 196 replayMocks(); 197 mRecovery.recoverDeviceBootloader(mMockMonitor); 198 verifyMocks(); 199 } 200 201 /** 202 * Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is 203 * online when bootloader is expected 204 */ 205 public void testRecoverDeviceBootloader_online() throws Exception { 206 mMockRunUtil.sleep(EasyMock.anyLong()); 207 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 208 Boolean.FALSE); 209 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.ONLINE); 210 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())) 211 .andReturn(mMockDevice); 212 mMockDevice.reboot("bootloader"); 213 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 214 Boolean.TRUE); 215 replayMocks(); 216 mRecovery.recoverDeviceBootloader(mMockMonitor); 217 verifyMocks(); 218 } 219 220 /** 221 * Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is 222 * initially unavailable, then comes online when bootloader is expected 223 */ 224 public void testRecoverDeviceBootloader_unavailable_online() throws Exception { 225 mMockRunUtil.sleep(EasyMock.anyLong()); 226 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 227 Boolean.FALSE); 228 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.NOT_AVAILABLE); 229 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 230 Boolean.FALSE); 231 EasyMock.expect(mMockMonitor.getDeviceState()).andReturn(TestDeviceState.ONLINE); 232 EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())) 233 .andReturn(mMockDevice); 234 mMockDevice.reboot("bootloader"); 235 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andReturn( 236 Boolean.TRUE); 237 replayMocks(); 238 mRecovery.recoverDeviceBootloader(mMockMonitor); 239 verifyMocks(); 240 } 241 242 /** 243 * Test {@link WaitDeviceRecovery#recoverDeviceBootloader(IDeviceStateMonitor)} when device is 244 * unavailable 245 */ 246 public void testRecoverDeviceBootloader_unavailable_failure() throws Exception { 247 mMockRunUtil.sleep(EasyMock.anyLong()); 248 EasyMock.expect(mMockMonitor.waitForDeviceBootloader(EasyMock.anyLong())).andStubReturn( 249 Boolean.FALSE); 250 EasyMock.expect(mMockMonitor.getDeviceState()).andStubReturn(TestDeviceState.NOT_AVAILABLE); 251 replayMocks(); 252 try { 253 mRecovery.recoverDeviceBootloader(mMockMonitor); 254 fail("DeviceNotAvailableException not thrown"); 255 } catch (DeviceNotAvailableException e) { 256 // expected 257 } 258 verifyMocks(); 259 } 260 261 /** 262 * Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} throws an exception if battery 263 * level is not readable. 264 */ 265 public void testCheckMinBatteryLevel_unreadable() throws Exception { 266 OptionSetter setter = new OptionSetter(mRecovery); 267 setter.setOptionValue("min-battery-after-recovery", "50"); 268 SettableFuture<Integer> future = SettableFuture.create(); 269 future.set(null); 270 EasyMock.expect(mMockDevice.getBattery()).andReturn(future); 271 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 272 replayMocks(); 273 try { 274 mRecovery.checkMinBatteryLevel(mMockDevice); 275 fail("DeviceNotAvailableException not thrown"); 276 } catch (DeviceNotAvailableException expected) { 277 assertEquals("Cannot read battery level but a min is required", expected.getMessage()); 278 } 279 verifyMocks(); 280 } 281 282 /** 283 * Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} throws an exception if battery 284 * level is below the minimal expected. 285 */ 286 public void testCheckMinBatteryLevel_belowLevel() throws Exception { 287 OptionSetter setter = new OptionSetter(mRecovery); 288 setter.setOptionValue("min-battery-after-recovery", "50"); 289 SettableFuture<Integer> future = SettableFuture.create(); 290 future.set(49); 291 EasyMock.expect(mMockDevice.getBattery()).andReturn(future); 292 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 293 replayMocks(); 294 try { 295 mRecovery.checkMinBatteryLevel(mMockDevice); 296 fail("DeviceNotAvailableException not thrown"); 297 } catch (DeviceNotAvailableException expected) { 298 assertEquals("After recovery, device battery level 49 is lower than required minimum " 299 + "50", expected.getMessage()); 300 } 301 verifyMocks(); 302 } 303 304 /** 305 * Test {@link WaitDeviceRecovery#checkMinBatteryLevel(IDevice)} returns without exception when 306 * battery level after recovery is above or equals minimum expected. 307 */ 308 public void testCheckMinBatteryLevel() throws Exception { 309 OptionSetter setter = new OptionSetter(mRecovery); 310 setter.setOptionValue("min-battery-after-recovery", "50"); 311 SettableFuture<Integer> future = SettableFuture.create(); 312 future.set(50); 313 EasyMock.expect(mMockDevice.getBattery()).andReturn(future); 314 replayMocks(); 315 mRecovery.checkMinBatteryLevel(mMockDevice); 316 verifyMocks(); 317 } 318 319 /** 320 * Test {@link WaitDeviceRecovery#rebootDeviceIntoBootloader(IDevice)} does throw when reboot 321 * bootloader throws an IO exception. 322 */ 323 public void testRebootDeviceIntoBootloader_IOException() throws Exception { 324 mMockDevice.reboot("bootloader"); 325 EasyMock.expectLastCall().andThrow(new IOException()); 326 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 327 replayMocks(); 328 mRecovery.rebootDeviceIntoBootloader(mMockDevice); 329 verifyMocks(); 330 } 331 332 /** 333 * Test {@link WaitDeviceRecovery#rebootDeviceIntoBootloader(IDevice)} does throw when reboot 334 * bootloader throws an timeout exception. 335 */ 336 public void testRebootDeviceIntoBootloader_timeoutException() throws Exception { 337 mMockDevice.reboot("bootloader"); 338 EasyMock.expectLastCall().andThrow(new TimeoutException()); 339 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 340 replayMocks(); 341 mRecovery.rebootDeviceIntoBootloader(mMockDevice); 342 verifyMocks(); 343 } 344 345 /** 346 * Test {@link WaitDeviceRecovery#rebootDevice(IDevice)} does throw when reboot 347 * throws an IO exception. 348 */ 349 public void testReboot_IOException() throws Exception { 350 mMockDevice.reboot(null); 351 EasyMock.expectLastCall().andThrow(new IOException()); 352 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 353 replayMocks(); 354 mRecovery.rebootDevice(mMockDevice); 355 verifyMocks(); 356 } 357 358 /** 359 * Test {@link WaitDeviceRecovery#rebootDevice(IDevice)} does throw when reboot 360 * throws an IO exception. 361 */ 362 public void testReboot_timeoutException() throws Exception { 363 mMockDevice.reboot(null); 364 EasyMock.expectLastCall().andThrow(new TimeoutException()); 365 EasyMock.expect(mMockDevice.getSerialNumber()).andReturn("SERIAL"); 366 replayMocks(); 367 mRecovery.rebootDevice(mMockDevice); 368 verifyMocks(); 369 } 370 371 /** 372 * Verify all the mock objects 373 */ 374 private void verifyMocks() { 375 EasyMock.verify(mMockRunUtil, mMockMonitor, mMockDevice); 376 } 377 378 /** 379 * Switch all the mock objects to replay mode 380 */ 381 private void replayMocks() { 382 EasyMock.replay(mMockRunUtil, mMockMonitor, mMockDevice); 383 } 384 385 } 386