Home | History | Annotate | Download | only in invoker
      1 /*
      2  * Copyright (C) 2017 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.invoker;
     17 
     18 import static org.junit.Assert.assertEquals;
     19 import static org.junit.Assert.fail;
     20 import static org.mockito.Mockito.mock;
     21 
     22 import com.android.tradefed.config.Configuration;
     23 import com.android.tradefed.config.DeviceConfigurationHolder;
     24 import com.android.tradefed.config.IConfiguration;
     25 import com.android.tradefed.config.IDeviceConfiguration;
     26 import com.android.tradefed.device.DeviceNotAvailableException;
     27 import com.android.tradefed.device.ITestDevice;
     28 import com.android.tradefed.device.metric.BaseDeviceMetricCollector;
     29 import com.android.tradefed.device.metric.IMetricCollector;
     30 import com.android.tradefed.device.metric.IMetricCollectorReceiver;
     31 import com.android.tradefed.result.ITestInvocationListener;
     32 import com.android.tradefed.targetprep.IHostCleaner;
     33 import com.android.tradefed.targetprep.ITargetCleaner;
     34 import com.android.tradefed.targetprep.ITargetPreparer;
     35 import com.android.tradefed.targetprep.multi.IMultiTargetPreparer;
     36 import com.android.tradefed.testtype.IRemoteTest;
     37 import com.android.tradefed.util.IDisableable;
     38 
     39 import org.easymock.EasyMock;
     40 import org.junit.Before;
     41 import org.junit.Test;
     42 import org.junit.runner.RunWith;
     43 import org.junit.runners.JUnit4;
     44 import org.mockito.InOrder;
     45 import org.mockito.Mockito;
     46 
     47 import java.util.ArrayList;
     48 import java.util.Arrays;
     49 import java.util.List;
     50 
     51 /**
     52  * Unit tests for {@link InvocationExecution}. Tests for each individual interface of
     53  * InvocationExecution, integration tests for orders or calls should be in {@link
     54  * TestInvocationTest}.
     55  */
     56 @RunWith(JUnit4.class)
     57 public class InvocationExecutionTest {
     58     private InvocationExecution mExec;
     59     private IInvocationContext mContext;
     60     private IConfiguration mConfig;
     61     private ITestInvocationListener mMockListener;
     62 
     63     @Before
     64     public void setUp() {
     65         mExec = new InvocationExecution();
     66         mContext = new InvocationContext();
     67         mConfig = new Configuration("test", "test");
     68         mMockListener = mock(ITestInvocationListener.class);
     69     }
     70 
     71     /** Test class for a target preparer class that also do host cleaner. */
     72     public interface ITargetHostCleaner extends ITargetPreparer, IHostCleaner {}
     73 
     74     /**
     75      * Test that {@link InvocationExecution#doCleanUp(IInvocationContext, IConfiguration,
     76      * Throwable)} properly use {@link IDisableable} to let an object run.
     77      */
     78     @Test
     79     public void testCleanUp() throws Exception {
     80         DeviceConfigurationHolder holder = new DeviceConfigurationHolder("default");
     81         ITargetHostCleaner cleaner = EasyMock.createMock(ITargetHostCleaner.class);
     82         holder.addSpecificConfig(cleaner);
     83         mConfig.setDeviceConfig(holder);
     84         mContext.addAllocatedDevice("default", EasyMock.createMock(ITestDevice.class));
     85         EasyMock.expect(cleaner.isDisabled()).andReturn(false);
     86         EasyMock.expect(cleaner.isTearDownDisabled()).andReturn(false);
     87         cleaner.cleanUp(null, null);
     88         EasyMock.replay(cleaner);
     89         mExec.doCleanUp(mContext, mConfig, null);
     90         EasyMock.verify(cleaner);
     91     }
     92 
     93     /**
     94      * Test that {@link InvocationExecution#doCleanUp(IInvocationContext, IConfiguration,
     95      * Throwable)} properly use {@link IDisableable} to prevent an object from running.
     96      */
     97     @Test
     98     public void testCleanUp_disabled() throws Exception {
     99         DeviceConfigurationHolder holder = new DeviceConfigurationHolder("default");
    100         ITargetHostCleaner cleaner = EasyMock.createMock(ITargetHostCleaner.class);
    101         holder.addSpecificConfig(cleaner);
    102         mConfig.setDeviceConfig(holder);
    103         mContext.addAllocatedDevice("default", EasyMock.createMock(ITestDevice.class));
    104         EasyMock.expect(cleaner.isDisabled()).andReturn(true);
    105         // cleaner.isTearDownDisabled not expected, because isDisabled true stops || execution.
    106         // cleanUp call is not expected
    107         EasyMock.replay(cleaner);
    108         mExec.doCleanUp(mContext, mConfig, null);
    109         EasyMock.verify(cleaner);
    110     }
    111 
    112     /**
    113      * Test that {@link InvocationExecution#doCleanUp(IInvocationContext, IConfiguration,
    114      * Throwable)} properly use {@link IDisableable} isTearDownDisabled to prevent cleanup step.
    115      */
    116     @Test
    117     public void testCleanUp_tearDownDisabled() throws Exception {
    118         DeviceConfigurationHolder holder = new DeviceConfigurationHolder("default");
    119         ITargetHostCleaner cleaner = EasyMock.createMock(ITargetHostCleaner.class);
    120         holder.addSpecificConfig(cleaner);
    121         mConfig.setDeviceConfig(holder);
    122         mContext.addAllocatedDevice("default", EasyMock.createMock(ITestDevice.class));
    123         EasyMock.expect(cleaner.isDisabled()).andReturn(false);
    124         EasyMock.expect(cleaner.isTearDownDisabled()).andReturn(true);
    125         // cleanUp call is not expected
    126         EasyMock.replay(cleaner);
    127         mExec.doCleanUp(mContext, mConfig, null);
    128         EasyMock.verify(cleaner);
    129     }
    130 
    131     /**
    132      * Test {@link IRemoteTest} that also implements {@link IMetricCollectorReceiver} to test the
    133      * init behavior.
    134      */
    135     private static class RemoteTestCollector implements IRemoteTest, IMetricCollectorReceiver {
    136 
    137         private List<IMetricCollector> mCollectors;
    138 
    139         @Override
    140         public void setMetricCollectors(List<IMetricCollector> collectors) {
    141             mCollectors = collectors;
    142         }
    143 
    144         @Override
    145         public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
    146             for (IMetricCollector collector : mCollectors) {
    147                 collector.init(new InvocationContext(), new ITestInvocationListener() {});
    148             }
    149         }
    150     }
    151 
    152     public static class TestBaseMetricCollector extends BaseDeviceMetricCollector {
    153         public static int sTotalInit = 0;
    154         private boolean mFirstInit = true;
    155 
    156         @Override
    157         public ITestInvocationListener init(
    158                 IInvocationContext context, ITestInvocationListener listener) {
    159             if (mFirstInit) {
    160                 sTotalInit++;
    161                 mFirstInit = false;
    162             } else {
    163                 fail("Init should only be called once per instance.");
    164             }
    165             return super.init(context, listener);
    166         }
    167     }
    168 
    169     /**
    170      * Test that the collectors always run with the right context no matter where they are
    171      * (re)initialized.
    172      */
    173     @Test
    174     public void testRun_metricCollectors() throws Exception {
    175         List<IRemoteTest> tests = new ArrayList<>();
    176         // First add an IMetricCollectorReceiver
    177         tests.add(new RemoteTestCollector());
    178         // Then a regular non IMetricCollectorReceiver
    179         tests.add(
    180                 new IRemoteTest() {
    181                     @Override
    182                     public void run(ITestInvocationListener listener)
    183                             throws DeviceNotAvailableException {}
    184                 });
    185         mConfig.setTests(tests);
    186         List<IMetricCollector> collectors = new ArrayList<>();
    187         collectors.add(new TestBaseMetricCollector());
    188         mConfig.setDeviceMetricCollectors(collectors);
    189         mExec.runTests(mContext, mConfig, mMockListener);
    190         // Init was called twice in total on the class, but only once per instance.
    191         assertEquals(2, TestBaseMetricCollector.sTotalInit);
    192     }
    193 
    194     /**
    195      * Test the ordering of multi_pre_target_preparer/target_preparer/multi_target_preparer during
    196      * setup and tearDown.
    197      */
    198     @Test
    199     public void testDoSetup() throws Throwable {
    200         IMultiTargetPreparer stub1 = mock(IMultiTargetPreparer.class);
    201         IMultiTargetPreparer stub2 = mock(IMultiTargetPreparer.class);
    202         IMultiTargetPreparer stub3 = mock(IMultiTargetPreparer.class);
    203         IMultiTargetPreparer stub4 = mock(IMultiTargetPreparer.class);
    204         mConfig.setMultiPreTargetPreparers(Arrays.asList(stub1, stub2));
    205         mConfig.setMultiTargetPreparers(Arrays.asList(stub3, stub4));
    206 
    207         ITargetCleaner cleaner = mock(ITargetCleaner.class);
    208         IDeviceConfiguration holder = new DeviceConfigurationHolder("default");
    209         holder.addSpecificConfig(cleaner);
    210         mConfig.setDeviceConfig(holder);
    211         mContext.addAllocatedDevice("default", mock(ITestDevice.class));
    212 
    213         mExec.doSetup(mContext, mConfig, mMockListener);
    214         mExec.doTeardown(mContext, mConfig, null);
    215 
    216         // Pre multi preparers are always called before.
    217         InOrder inOrder = Mockito.inOrder(stub1, stub2, stub3, stub4, cleaner);
    218         inOrder.verify(stub1).isDisabled();
    219         inOrder.verify(stub1).setUp(mContext);
    220         inOrder.verify(stub2).isDisabled();
    221         inOrder.verify(stub2).setUp(mContext);
    222 
    223         inOrder.verify(cleaner).setUp(Mockito.any(), Mockito.any());
    224 
    225         inOrder.verify(stub3).isDisabled();
    226         inOrder.verify(stub3).setUp(mContext);
    227         inOrder.verify(stub4).isDisabled();
    228         inOrder.verify(stub4).setUp(mContext);
    229 
    230         // tear down
    231         inOrder.verify(stub4).isDisabled();
    232         inOrder.verify(stub4).tearDown(mContext, null);
    233         inOrder.verify(stub3).isDisabled();
    234         inOrder.verify(stub3).tearDown(mContext, null);
    235 
    236         inOrder.verify(cleaner).tearDown(Mockito.any(), Mockito.any(), Mockito.any());
    237 
    238         inOrder.verify(stub2).isDisabled();
    239         inOrder.verify(stub2).tearDown(mContext, null);
    240         inOrder.verify(stub1).isDisabled();
    241         inOrder.verify(stub1).tearDown(mContext, null);
    242     }
    243 }
    244