Home | History | Annotate | Download | only in targetprep
      1 /*
      2  * Copyright (C) 2016 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.targetprep;
     17 
     18 import static org.junit.Assert.assertEquals;
     19 import static org.junit.Assert.fail;
     20 import static org.mockito.Mockito.doReturn;
     21 import static org.mockito.Mockito.times;
     22 
     23 import com.android.tradefed.build.BuildInfo;
     24 import com.android.tradefed.build.IAppBuildInfo;
     25 import com.android.tradefed.build.IBuildInfo;
     26 import com.android.tradefed.build.VersionedFile;
     27 import com.android.tradefed.config.OptionSetter;
     28 import com.android.tradefed.device.DeviceNotAvailableException;
     29 import com.android.tradefed.device.ITestDevice;
     30 import com.android.tradefed.util.AaptParser;
     31 import com.android.tradefed.util.FileUtil;
     32 
     33 import java.io.File;
     34 import java.util.ArrayList;
     35 import java.util.HashSet;
     36 import java.util.List;
     37 import java.util.Set;
     38 import java.util.concurrent.TimeUnit;
     39 
     40 import org.easymock.EasyMock;
     41 import org.junit.Before;
     42 import org.junit.Test;
     43 import org.junit.runner.RunWith;
     44 import org.junit.runners.JUnit4;
     45 import org.mockito.Mockito;
     46 
     47 /**
     48  * Unit Tests for {@link AppSetup}.
     49  */
     50 @RunWith(JUnit4.class)
     51 public class AppSetupTest {
     52 
     53     private static final String SERIAL = "serial";
     54     private AppSetup mAppSetup;
     55     private ITestDevice mMockDevice;
     56     private IAppBuildInfo mMockBuildInfo;
     57     private AaptParser mMockAaptParser;
     58 
     59     @Before
     60     public void setUp() {
     61         mAppSetup = new AppSetup();
     62         mMockDevice = EasyMock.createMock(ITestDevice.class);
     63         EasyMock.expect(mMockDevice.getSerialNumber()).andStubReturn(SERIAL);
     64         EasyMock.expect(mMockDevice.getDeviceDescriptor()).andStubReturn(null);
     65         mMockBuildInfo = EasyMock.createMock(IAppBuildInfo.class);
     66         mMockAaptParser = Mockito.mock(AaptParser.class);
     67     }
     68 
     69     private void replayMocks() {
     70         EasyMock.replay(mMockDevice, mMockBuildInfo);
     71     }
     72 
     73     private void verifyMocks() {
     74         EasyMock.verify(mMockDevice, mMockBuildInfo);
     75     }
     76 
     77     /**
     78      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when the IBuildInfo is not an
     79      * instance of {@link IAppBuildInfo}.
     80      */
     81     @Test
     82     public void testSetup_notIAppBuildInfo() throws Exception {
     83         replayMocks();
     84         try {
     85             mAppSetup.setUp(mMockDevice, new BuildInfo());
     86             fail("Should have thrown an exception.");
     87         } catch (IllegalArgumentException expected) {
     88             assertEquals("Provided buildInfo is not a AppBuildInfo", expected.getMessage());
     89         }
     90         verifyMocks();
     91     }
     92 
     93     /**
     94      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when the apk installation fails
     95      * with some error.
     96      */
     97     @Test
     98     public void testSetup_failToInstall() throws Exception {
     99         List<VersionedFile> files = new ArrayList<>();
    100         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    101         try {
    102             files.add(new VersionedFile(tmpFile, "1"));
    103             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    104             EasyMock.expect(mMockDevice.installPackage(EasyMock.eq(tmpFile), EasyMock.eq(true)))
    105                     .andReturn("Error");
    106             replayMocks();
    107             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    108             fail("Should have thrown an exception.");
    109         } catch (BuildError expected) {
    110             assertEquals(String.format("Failed to install %s on %s. Reason: Error null",
    111                     tmpFile.getName(), SERIAL), expected.getMessage());
    112         } finally {
    113             FileUtil.deleteFile(tmpFile);
    114             verifyMocks();
    115         }
    116     }
    117 
    118     /**
    119      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when installation succeed but we
    120      * cannot get any aapt info from the apk.
    121      */
    122     @Test
    123     public void testSetup_aaptCannotParse() throws Exception {
    124         List<VersionedFile> files = new ArrayList<>();
    125         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    126         try {
    127             files.add(new VersionedFile(tmpFile, "1"));
    128             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    129             EasyMock.expect(mMockDevice.installPackage(EasyMock.eq(tmpFile), EasyMock.eq(true)))
    130                     .andReturn(null);
    131             replayMocks();
    132             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    133             fail("Should have thrown an exception.");
    134         } catch (TargetSetupError expected) {
    135             assertEquals(String.format("Failed to extract info from '%s' using aapt null",
    136                     tmpFile.getAbsolutePath()), expected.getMessage());
    137         } finally {
    138             FileUtil.deleteFile(tmpFile);
    139             verifyMocks();
    140         }
    141     }
    142 
    143     /**
    144      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when the install succeed but we
    145      * cannot find any package name on the apk.
    146      */
    147     @Test
    148     public void testSetup_noPackageName() throws Exception {
    149         mAppSetup = new AppSetup() {
    150             @Override
    151             AaptParser doAaptParse(File apkFile) {
    152                 return mMockAaptParser;
    153             }
    154         };
    155         List<VersionedFile> files = new ArrayList<>();
    156         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    157         try {
    158             files.add(new VersionedFile(tmpFile, "1"));
    159             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    160             EasyMock.expect(mMockDevice.installPackage(EasyMock.eq(tmpFile), EasyMock.eq(true)))
    161                     .andReturn(null);
    162             doReturn(null).when(mMockAaptParser).getPackageName();
    163             replayMocks();
    164             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    165             fail("Should have thrown an exception.");
    166         } catch (TargetSetupError expected) {
    167             assertEquals(String.format("Failed to find package name for '%s' using aapt null",
    168                     tmpFile.getAbsolutePath()), expected.getMessage());
    169         } finally {
    170             FileUtil.deleteFile(tmpFile);
    171             verifyMocks();
    172             Mockito.verify(mMockAaptParser, times(1)).getPackageName();
    173         }
    174     }
    175 
    176     /**
    177      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when checking min sdk is enabled
    178      * and we fail to parse the file.
    179      */
    180     @Test
    181     public void testSetup_checkMinSdk_failParsing() throws Exception {
    182         mAppSetup = new AppSetup() {
    183             @Override
    184             AaptParser doAaptParse(File apkFile) {
    185                 return null;
    186             }
    187         };
    188         OptionSetter setter = new OptionSetter(mAppSetup);
    189         setter.setOptionValue("check-min-sdk", "true");
    190         List<VersionedFile> files = new ArrayList<>();
    191         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    192         try {
    193             files.add(new VersionedFile(tmpFile, "1"));
    194             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    195             replayMocks();
    196             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    197             fail("Should have thrown an exception.");
    198         } catch (TargetSetupError expected) {
    199             assertEquals(String.format("Failed to extract info from '%s' using aapt null",
    200                     tmpFile.getName()), expected.getMessage());
    201         } finally {
    202             FileUtil.deleteFile(tmpFile);
    203             verifyMocks();
    204         }
    205     }
    206 
    207     /**
    208      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when we check the min sdk level
    209      * and the device API level is too low. Install should be skipped.
    210      */
    211     @Test
    212     public void testSetup_checkMinSdk_apiLow() throws Exception {
    213         mAppSetup = new AppSetup() {
    214             @Override
    215             AaptParser doAaptParse(File apkFile) {
    216                 return mMockAaptParser;
    217             }
    218         };
    219         OptionSetter setter = new OptionSetter(mAppSetup);
    220         setter.setOptionValue("check-min-sdk", "true");
    221         List<VersionedFile> files = new ArrayList<>();
    222         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    223         try {
    224             files.add(new VersionedFile(tmpFile, "1"));
    225             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    226             EasyMock.expect(mMockDevice.getApiLevel()).andReturn(21).times(2);
    227             doReturn(22).when(mMockAaptParser).getSdkVersion();
    228             replayMocks();
    229             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    230         } finally {
    231             FileUtil.deleteFile(tmpFile);
    232             verifyMocks();
    233             Mockito.verify(mMockAaptParser, times(2)).getSdkVersion();
    234         }
    235     }
    236 
    237     /**
    238      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when api level of device is high
    239      * enough to install the apk.
    240      */
    241     @Test
    242     public void testSetup_checkMinSdk_apiOk() throws Exception {
    243         mAppSetup = new AppSetup() {
    244             @Override
    245             AaptParser doAaptParse(File apkFile) {
    246                 return mMockAaptParser;
    247             }
    248         };
    249         OptionSetter setter = new OptionSetter(mAppSetup);
    250         setter.setOptionValue("check-min-sdk", "true");
    251         List<VersionedFile> files = new ArrayList<>();
    252         File tmpFile = FileUtil.createTempFile("versioned", ".test");
    253         try {
    254             files.add(new VersionedFile(tmpFile, "1"));
    255             EasyMock.expect(mMockBuildInfo.getAppPackageFiles()).andReturn(files);
    256             EasyMock.expect(mMockDevice.getApiLevel()).andReturn(23);
    257             doReturn(22).when(mMockAaptParser).getSdkVersion();
    258             EasyMock.expect(mMockDevice.installPackage(EasyMock.eq(tmpFile), EasyMock.eq(true)))
    259                     .andReturn(null);
    260             doReturn("com.fake.package").when(mMockAaptParser).getPackageName();
    261             replayMocks();
    262             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    263         } finally {
    264             FileUtil.deleteFile(tmpFile);
    265             verifyMocks();
    266             Mockito.verify(mMockAaptParser, times(2)).getPackageName();
    267             Mockito.verify(mMockAaptParser, times(1)).getSdkVersion();
    268         }
    269     }
    270 
    271     /**
    272      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when running a post install
    273      * command.
    274      */
    275     @Test
    276     public void testSetup_executePostInstall() throws Exception {
    277         final String fakeCmd = "fake command";
    278         OptionSetter setter = new OptionSetter(mAppSetup);
    279         setter.setOptionValue("install", "false");
    280         setter.setOptionValue("post-install-cmd", fakeCmd);
    281         mMockDevice.executeShellCommand(EasyMock.eq(fakeCmd), EasyMock.anyObject(),
    282                 EasyMock.anyLong(), EasyMock.eq(TimeUnit.MILLISECONDS), EasyMock.eq(1));
    283         EasyMock.expectLastCall();
    284         replayMocks();
    285         mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    286         verifyMocks();
    287     }
    288 
    289     /**
    290      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when uninstall all package is
    291      * requested but there is no package to uninstall.
    292      */
    293     @Test
    294     public void testSetup_uninstallAll_noPackage() throws Exception {
    295         OptionSetter setter = new OptionSetter(mAppSetup);
    296         setter.setOptionValue("install", "false");
    297         setter.setOptionValue("uninstall-all", "true");
    298         Set<String> res = new HashSet<>();
    299         EasyMock.expect(mMockDevice.getUninstallablePackageNames()).andReturn(res);
    300         replayMocks();
    301         mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    302         verifyMocks();
    303     }
    304 
    305     /**
    306      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when uninstall is working and all
    307      * package to be uninstalled are uninstalled.
    308      */
    309     @Test
    310     public void testSetup_uninstallAll() throws Exception {
    311         OptionSetter setter = new OptionSetter(mAppSetup);
    312         setter.setOptionValue("install", "false");
    313         setter.setOptionValue("uninstall-all", "true");
    314         Set<String> res = new HashSet<>();
    315         res.add("com.fake1");
    316         EasyMock.expect(mMockDevice.getUninstallablePackageNames()).andReturn(res).times(2);
    317         EasyMock.expect(mMockDevice.uninstallPackage("com.fake1")).andReturn(null).times(2);
    318         EasyMock.expect(mMockDevice.getUninstallablePackageNames()).andReturn(new HashSet<>());
    319         replayMocks();
    320         mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    321         verifyMocks();
    322     }
    323 
    324     /**
    325      * Test for {@link AppSetup#setUp(ITestDevice, IBuildInfo)} when uninstall is failing.
    326      */
    327     @Test
    328     public void testSetup_uninstallAll_fails() throws Exception {
    329         OptionSetter setter = new OptionSetter(mAppSetup);
    330         setter.setOptionValue("install", "false");
    331         setter.setOptionValue("uninstall-all", "true");
    332         Set<String> res = new HashSet<>();
    333         res.add("com.fake1");
    334         EasyMock.expect(mMockDevice.getUninstallablePackageNames()).andReturn(res).times(4);
    335         EasyMock.expect(mMockDevice.uninstallPackage("com.fake1")).andReturn("error").times(3);
    336         replayMocks();
    337         try {
    338             mAppSetup.setUp(mMockDevice, mMockBuildInfo);
    339             fail("Should have thrown an exception.");
    340         } catch (DeviceNotAvailableException expected) {
    341             assertEquals("Failed to uninstall apps on " + SERIAL, expected.getMessage());
    342         }
    343         verifyMocks();
    344     }
    345 
    346     /**
    347      * Test for {@link AppSetup#tearDown(ITestDevice, IBuildInfo, Throwable)} when throwable is
    348      * a DNAE instance, it should just return.
    349      */
    350     @Test
    351     public void testTearDown_DNAE() throws Exception {
    352         replayMocks();
    353         mAppSetup.tearDown(mMockDevice, mMockBuildInfo, new DeviceNotAvailableException());
    354         verifyMocks();
    355     }
    356 
    357     /**
    358      * Test for {@link AppSetup#tearDown(ITestDevice, IBuildInfo, Throwable)}.
    359      */
    360     @Test
    361     public void testTearDown() throws Exception {
    362         mMockDevice.reboot();
    363         EasyMock.expectLastCall();
    364         replayMocks();
    365         mAppSetup.tearDown(mMockDevice, mMockBuildInfo, null);
    366         verifyMocks();
    367     }
    368 }
    369