Home | History | Annotate | Download | only in testtype
      1 /*
      2  * Copyright (C) 2014 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.cts.tradefed.testtype;
     18 
     19 import com.android.cts.tradefed.build.CtsBuildHelper;
     20 import com.android.cts.tradefed.targetprep.SettingsToggler;
     21 import com.android.cts.util.AbiUtils;
     22 import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
     23 import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner.TestSize;
     24 import com.android.tradefed.build.IBuildInfo;
     25 import com.android.tradefed.device.DeviceNotAvailableException;
     26 import com.android.tradefed.device.ITestDevice;
     27 import com.android.tradefed.result.ITestInvocationListener;
     28 import com.android.tradefed.testtype.IAbi;
     29 import com.android.tradefed.testtype.IBuildReceiver;
     30 import com.android.tradefed.testtype.IDeviceTest;
     31 import com.android.tradefed.testtype.IRemoteTest;
     32 import com.android.tradefed.util.StringEscapeUtils;
     33 
     34 import java.io.FileNotFoundException;
     35 import java.util.HashMap;
     36 import java.util.Map;
     37 import java.util.concurrent.TimeUnit;
     38 
     39 /**
     40  * Running the print tests requires modification of secure settings. Secure
     41  * settings cannot be changed from device CTS tests since system signature
     42  * permission is required. Such settings can be modified by the shell user,
     43  * so a host side test driver is used for enabling these services, running
     44  * the tests, and disabling the services.
     45  */
     46 public class PrintTestRunner implements IBuildReceiver, IRemoteTest, IDeviceTest  {
     47 
     48     private static final String PRINT_TEST_AND_SERVICES_APP_NAME =
     49             "CtsPrintTestCases.apk";
     50 
     51     private static final String PRINT_TESTS_PACKAGE_NAME =
     52             "com.android.cts.print";
     53 
     54     private static final String FIRST_PRINT_SERVICE_NAME =
     55             "android.print.cts.services.FirstPrintService";
     56 
     57     private static final String SECOND_PRINT_SERVICE_NAME =
     58             "android.print.cts.services.SecondPrintService";
     59 
     60     private static final String SHELL_USER_FOLDER = "data/local/tmp";
     61 
     62     private static final String PRINT_INSTRUMENT_JAR = "CtsPrintInstrument.jar";
     63 
     64     private static final String PRINT_INSTRUMENT_SCRIPT = "print-instrument";
     65 
     66     private ITestDevice mDevice;
     67 
     68     private CtsBuildHelper mCtsBuild;
     69 
     70     private IAbi mAbi;
     71     private String mPackageName;
     72     private String mRunnerName = "android.test.InstrumentationTestRunner";
     73     private String mTestClassName;
     74     private String mTestMethodName;
     75     private String mTestPackageName;
     76     private int mTestTimeout = 10 * 60 * 1000;  // 10 minutes
     77     private String mTestSize;
     78     private String mRunName = null;
     79     private Map<String, String> mInstrArgMap = new HashMap<String, String>();
     80 
     81     /**
     82      * @param abi The ABI to run the test on
     83      */
     84     public void setAbi(IAbi abi) {
     85         mAbi = abi;
     86     }
     87 
     88     @Override
     89     public void setBuild(IBuildInfo buildInfo) {
     90         mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
     91     }
     92 
     93     @Override
     94     public void setDevice(ITestDevice device) {
     95         mDevice = device;
     96     }
     97 
     98     @Override
     99     public ITestDevice getDevice() {
    100         return mDevice;
    101     }
    102 
    103     public void setPackageName(String packageName) {
    104         mPackageName = packageName;
    105     }
    106 
    107     public void setRunnerName(String runnerName) {
    108         mRunnerName = runnerName;
    109     }
    110 
    111     public void setClassName(String testClassName) {
    112         mTestClassName = testClassName;
    113     }
    114 
    115     public void setMethodName(String testMethodName) {
    116         mTestMethodName = StringEscapeUtils.escapeShell(testMethodName);
    117     }
    118 
    119     public void setTestPackageName(String testPackageName) {
    120         mTestPackageName = testPackageName;
    121     }
    122 
    123     public void setTestSize(String size) {
    124         mTestSize = size;
    125     }
    126 
    127     public void setRunName(String runName) {
    128         mRunName = runName;
    129     }
    130 
    131     @Override
    132     public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
    133         installShellProgramAndScriptFiles();
    134         installTestsAndServicesApk();
    135         enablePrintServices();
    136         doRunTests(listener);
    137         disablePrintServices();
    138         uninstallTestsAndServicesApk();
    139         uninstallShellProgramAndScriptFiles();
    140     }
    141 
    142     private void doRunTests(ITestInvocationListener listener)
    143             throws DeviceNotAvailableException {
    144         if (mPackageName == null) {
    145             throw new IllegalArgumentException("package name has not been set");
    146         }
    147         if (mDevice == null) {
    148             throw new IllegalArgumentException("Device has not been set");
    149         }
    150 
    151         IRemoteAndroidTestRunner runner =  new PrintTestRemoteTestRunner(mPackageName,
    152                 mRunnerName, mDevice.getIDevice());
    153 
    154         if (mTestClassName != null) {
    155             if (mTestMethodName != null) {
    156                 runner.setMethodName(mTestClassName, mTestMethodName);
    157             } else {
    158                 runner.setClassName(mTestClassName);
    159             }
    160         } else if (mTestPackageName != null) {
    161             runner.setTestPackageName(mTestPackageName);
    162         }
    163         if (mTestSize != null) {
    164             runner.setTestSize(TestSize.getTestSize(mTestSize));
    165         }
    166         runner.setMaxTimeToOutputResponse(mTestTimeout, TimeUnit.MILLISECONDS);
    167         if (mRunName != null) {
    168             runner.setRunName(mRunName);
    169         }
    170         for (Map.Entry<String, String> argEntry : mInstrArgMap.entrySet()) {
    171             runner.addInstrumentationArg(argEntry.getKey(), argEntry.getValue());
    172         }
    173 
    174         mDevice.runInstrumentationTests(runner, listener);
    175     }
    176 
    177     private void installShellProgramAndScriptFiles() throws DeviceNotAvailableException {
    178         installFile(PRINT_INSTRUMENT_JAR);
    179         installFile(PRINT_INSTRUMENT_SCRIPT);
    180     }
    181 
    182     private void installFile(String fileName) throws DeviceNotAvailableException {
    183         try {
    184             final boolean success = getDevice().pushFile(mCtsBuild.getTestApp(
    185                     fileName), SHELL_USER_FOLDER + "/" + fileName);
    186             if (!success) {
    187                 throw new IllegalArgumentException("Failed to install "
    188                         + fileName + " on " + getDevice().getSerialNumber());
    189            }
    190         } catch (FileNotFoundException fnfe) {
    191             throw new IllegalArgumentException("Cannot find file: " + fileName);
    192         }
    193     }
    194 
    195     private void uninstallShellProgramAndScriptFiles() throws DeviceNotAvailableException {
    196         getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
    197                 + PRINT_INSTRUMENT_JAR);
    198         getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
    199                 + PRINT_INSTRUMENT_SCRIPT);
    200     }
    201 
    202     private void installTestsAndServicesApk() throws DeviceNotAvailableException {
    203         try {
    204             String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
    205             String installCode = getDevice().installPackage(mCtsBuild.getTestApp(
    206                     PRINT_TEST_AND_SERVICES_APP_NAME), true, options);
    207             if (installCode != null) {
    208                 throw new IllegalArgumentException("Failed to install "
    209                         + PRINT_TEST_AND_SERVICES_APP_NAME + " on " + getDevice().getSerialNumber()
    210                         + ". Reason: " + installCode);
    211            }
    212         } catch (FileNotFoundException fnfe) {
    213             throw new IllegalArgumentException("Cannot find file: "
    214                     + PRINT_TEST_AND_SERVICES_APP_NAME);
    215         }
    216     }
    217 
    218     private void uninstallTestsAndServicesApk() throws DeviceNotAvailableException {
    219         getDevice().uninstallPackage(PRINT_TESTS_PACKAGE_NAME);
    220     }
    221 
    222     private void enablePrintServices() throws DeviceNotAvailableException {
    223         String enabledServicesValue = PRINT_TESTS_PACKAGE_NAME + "/" + FIRST_PRINT_SERVICE_NAME
    224                 + ":" + PRINT_TESTS_PACKAGE_NAME + "/" + SECOND_PRINT_SERVICE_NAME;
    225         SettingsToggler.setSecureString(getDevice(), "enabled_print_services",
    226                 enabledServicesValue);
    227     }
    228 
    229     private void disablePrintServices() throws DeviceNotAvailableException {
    230         SettingsToggler.setSecureString(getDevice(), "enabled_print_services", "");
    231     }
    232 }
    233