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 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