Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 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.media.tests;
     18 
     19 import com.android.ddmlib.IDevice;
     20 import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
     21 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
     22 import com.android.tradefed.config.Option;
     23 import com.android.tradefed.device.DeviceNotAvailableException;
     24 import com.android.tradefed.device.ITestDevice;
     25 import com.android.tradefed.log.LogUtil.CLog;
     26 import com.android.tradefed.result.BugreportCollector;
     27 import com.android.tradefed.result.ITestInvocationListener;
     28 import com.android.tradefed.result.InputStreamSource;
     29 import com.android.tradefed.result.LogDataType;
     30 import com.android.tradefed.testtype.IDeviceTest;
     31 import com.android.tradefed.testtype.IRemoteTest;
     32 import com.android.tradefed.util.StreamUtil;
     33 
     34 import org.junit.Assert;
     35 
     36 import java.io.BufferedReader;
     37 import java.io.File;
     38 import java.io.FileReader;
     39 import java.io.IOException;
     40 import java.util.ArrayList;
     41 import java.util.HashMap;
     42 import java.util.ListIterator;
     43 import java.util.Map;
     44 import java.util.concurrent.TimeUnit;
     45 import java.util.regex.Matcher;
     46 import java.util.regex.Pattern;
     47 
     48 /**
     49  * Camera zoom stress test that increments the camera's zoom level across the
     50  * entire range [min, max], taking a picture at each level.
     51  */
     52 public class CameraSettingsTest implements IDeviceTest, IRemoteTest {
     53 
     54     private static final String ZOOM_STANZA = "testStressCameraZoom";
     55     private static final String SCENE_MODES_STANZA = "testStressCameraSceneModes";
     56     private static final Pattern EXPECTED_LOOP_COUNT_PATTERN =
     57             Pattern.compile("(Total number of loops:)(\\s*)(\\d+)");
     58     private static final Pattern ACTUAL_LOOP_COUNT_PATTERN =
     59             Pattern.compile("(No of loop:)(.*,\\s)(\\d+)$");
     60 
     61     private static final String TEST_CLASS_NAME =
     62             "com.android.mediaframeworktest.stress.CameraStressTest";
     63     private static final String TEST_PACKAGE_NAME = "com.android.mediaframeworktest";
     64     private static final String TEST_RUNNER_NAME =
     65             "com.android.mediaframeworktest.CameraStressTestRunner";
     66     private static final String TEST_RU = "CameraApplicationStress";
     67 
     68     private final String mOutputPath = "cameraStressOutput.txt";
     69     private static final int MAX_TIME_OUT = 90 * 60 * 1000; //90 mins
     70 
     71     @Option(name="testMethodName", description="Used to specify a specific test method to run")
     72     private String mTestMethodName = null;
     73 
     74     ITestDevice mTestDevice = null;
     75 
     76     /**
     77      * {@inheritDoc}
     78      */
     79     @Override
     80     public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
     81         Assert.assertNotNull(mTestDevice);
     82 
     83         IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(TEST_PACKAGE_NAME,
     84                 TEST_RUNNER_NAME, mTestDevice.getIDevice());
     85         runner.setClassName(TEST_CLASS_NAME);
     86 
     87         if (mTestMethodName != null) {
     88             runner.setMethodName(TEST_CLASS_NAME, mTestMethodName);
     89         }
     90         runner.setMaxTimeToOutputResponse(MAX_TIME_OUT, TimeUnit.MILLISECONDS);
     91 
     92         BugreportCollector bugListener = new BugreportCollector(listener, mTestDevice);
     93         bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
     94         bugListener.setDescriptiveName(this.getClass().getName());
     95         Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, bugListener));
     96 
     97         Map<String, String> metrics = parseOutputFile();
     98         reportMetrics(bugListener, TEST_RU, metrics);
     99         cleanupDevice();
    100     }
    101 
    102     /**
    103      * {@inheritDoc}
    104      */
    105     @Override
    106     public void setDevice(ITestDevice device) {
    107         mTestDevice = device;
    108     }
    109 
    110     /**
    111      * {@inheritDoc}
    112      */
    113     @Override
    114     public ITestDevice getDevice() {
    115         return mTestDevice;
    116     }
    117 
    118     /**
    119      * Wipes the device's external memory of test collateral from prior runs.
    120      *
    121      * @throws DeviceNotAvailableException If the device is unavailable or
    122      *         something happened while deleting files
    123      */
    124     private void cleanupDevice() throws DeviceNotAvailableException {
    125         String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
    126         mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, mOutputPath));
    127     }
    128 
    129     /**
    130      * Parses the output file generated by the underlying instrumentation test
    131      * and returns it to the main driver for later reporting.
    132      *
    133      * @return The {@link Map} that contains metrics for the test.
    134      * @throws DeviceNotAvailableException If the device is unavailable or
    135      *         something happened while deleting files
    136      */
    137     private Map<String, String> parseOutputFile() throws DeviceNotAvailableException {
    138         File outputFile = null;
    139         BufferedReader reader = null;
    140         ArrayList<String> lines = new ArrayList<String>();
    141         String line = null;
    142         String key = null;
    143         Integer expectedCount = null;
    144         Integer actualCount = null;
    145         ListIterator<String> listIterator = null;
    146         Map<String, String> metrics = new HashMap<String, String>();
    147 
    148         // Read in data
    149         try {
    150             outputFile = mTestDevice.pullFileFromExternal(mOutputPath);
    151             reader = new BufferedReader(new FileReader(outputFile));
    152 
    153             while ((line = reader.readLine()) != null) {
    154                 if (!line.isEmpty()) {
    155                     lines.add(line);
    156                 }
    157             }
    158         } catch (IOException e) {
    159             CLog.e(String.format("IOException reading from file: %s", e.toString()));
    160         } finally {
    161             StreamUtil.close(reader);
    162         }
    163 
    164         // Output file looks like:
    165         // Test name:
    166         // Total number of loops: 123
    167         // No of loop: 0, 1, 2, 3, ..., 122 (0 based)
    168         // Note that the actual count should be +1 as the # of loop is 0 based.
    169         listIterator = lines.listIterator();
    170 
    171         while (listIterator.hasNext()) {
    172             line = listIterator.next();
    173             CLog.d(String.format("Parsing line: \"%s\"", line));
    174 
    175             if (ZOOM_STANZA.equals(line)) {
    176                 key = "CameraZoom";
    177             } else if (SCENE_MODES_STANZA.equals(line)) {
    178                 key = "CameraSceneMode";
    179             }
    180 
    181             Matcher expectedMatcher = EXPECTED_LOOP_COUNT_PATTERN.matcher(line);
    182             if (expectedMatcher.matches()) {
    183                 expectedCount = Integer.valueOf(expectedMatcher.group(3));
    184                 CLog.d(String.format("Found expected count for key \"%s\": %s",
    185                         key, expectedCount));
    186             }
    187 
    188             Matcher actualMatcher = ACTUAL_LOOP_COUNT_PATTERN.matcher(line);
    189             if (actualMatcher.matches()) {
    190                 actualCount = 1 + Integer.valueOf(actualMatcher.group(3));
    191                 CLog.d(String.format("Found actual count for key \"%s\": %s", key, actualCount));
    192             }
    193 
    194             if ((key != null) && (expectedCount != null) && (actualCount != null)) {
    195                 metrics.put(key, String.format("%d", actualCount));
    196                 key = null;
    197                 expectedCount = null;
    198                 actualCount = null;
    199             }
    200         }
    201 
    202         return metrics;
    203     }
    204 
    205     /**
    206      * Report run metrics by creating an empty test run to stick them in.
    207      *
    208      * @param listener The {@link ITestInvocationListener} of test results
    209      * @param runName The test name
    210      * @param metrics The {@link Map} that contains metrics for the given test
    211      */
    212     private void reportMetrics(ITestInvocationListener listener, String runName,
    213             Map<String, String> metrics) {
    214         InputStreamSource bugreport = mTestDevice.getBugreport();
    215         listener.testLog("bugreport", LogDataType.BUGREPORT, bugreport);
    216         bugreport.cancel();
    217 
    218         CLog.d(String.format("About to report metrics: %s", metrics));
    219         listener.testRunStarted(runName, 0);
    220         listener.testRunEnded(0, metrics);
    221     }
    222 }
    223