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.device.DeviceNotAvailableException;
     23 import com.android.tradefed.device.ITestDevice;
     24 import com.android.tradefed.log.LogUtil.CLog;
     25 import com.android.tradefed.result.BugreportCollector;
     26 import com.android.tradefed.result.ITestInvocationListener;
     27 import com.android.tradefed.result.InputStreamSource;
     28 import com.android.tradefed.result.LogDataType;
     29 import com.android.tradefed.testtype.IDeviceTest;
     30 import com.android.tradefed.testtype.IRemoteTest;
     31 
     32 import org.junit.Assert;
     33 
     34 import java.io.BufferedReader;
     35 import java.io.File;
     36 import java.io.FileReader;
     37 import java.io.IOException;
     38 import java.util.HashMap;
     39 import java.util.Map;
     40 import java.util.regex.Matcher;
     41 import java.util.regex.Pattern;
     42 
     43 public class CameraShotToShotLatencyTest implements IDeviceTest, IRemoteTest {
     44 
     45     private static final Pattern MEAN_PATTERN =
     46             Pattern.compile("(Shot to shot latency - mean:)(\\s*)(\\d+\\.\\d*)");
     47     private static final Pattern STANDARD_DEVIATION_PATTERN =
     48             Pattern.compile("(Shot to shot latency - standard deviation:)(\\s*)(\\d+\\.\\d*)");
     49 
     50     private static final String TEST_CLASS_NAME = "com.android.camera.stress.ShotToShotLatency";
     51     private static final String TEST_PACKAGE_NAME = "com.google.android.camera.tests";
     52     private static final String TEST_RUNNER_NAME = "android.test.InstrumentationTestRunner";
     53 
     54     private static final String LATENCY_KEY_MEAN = "Shot2ShotLatencyMean";
     55     private static final String LATENCY_KEY_SD = "Shot2ShotLatencySD";
     56     private static final String TEST_RU = "CameraLatency";
     57 
     58     private final String mOutputPath = "mediaStressOut.txt";
     59     ITestDevice mTestDevice = null;
     60 
     61     /**
     62      * {@inheritDoc}
     63      */
     64     @Override
     65     public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
     66         Assert.assertNotNull(mTestDevice);
     67 
     68         IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(TEST_PACKAGE_NAME,
     69                 TEST_RUNNER_NAME, mTestDevice.getIDevice());
     70         runner.setClassName(TEST_CLASS_NAME);
     71 
     72         BugreportCollector bugListener = new BugreportCollector(listener, mTestDevice);
     73         bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
     74         bugListener.setDescriptiveName(this.getClass().getName());
     75         Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, bugListener));
     76 
     77         Map<String, String> metrics = parseOutputFile();
     78         reportMetrics(bugListener, TEST_RU, metrics);
     79         cleanupDevice();
     80     }
     81 
     82     /**
     83      * {@inheritDoc}
     84      */
     85     @Override
     86     public void setDevice(ITestDevice device) {
     87         mTestDevice = device;
     88     }
     89 
     90     /**
     91      * {@inheritDoc}
     92      */
     93     @Override
     94     public ITestDevice getDevice() {
     95         return mTestDevice;
     96     }
     97 
     98     /**
     99      * Wipes the device's external memory of test collateral from prior runs.
    100      * Note that all photos on the test device will be removed.
    101      * @throws DeviceNotAvailableException If the device is unavailable or
    102      *         something happened while deleting files
    103      */
    104     private void cleanupDevice() throws DeviceNotAvailableException {
    105         String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
    106         mTestDevice.executeShellCommand(String.format("rm -r %s/DCIM", extStore));
    107         mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, mOutputPath));
    108     }
    109 
    110     /**
    111      * Parses the output file generated by the underlying instrumentation test
    112      * and returns the metrics to the main driver for later reporting.
    113      * @return The {@link Map} that contains metrics for the test.
    114      * @throws DeviceNotAvailableException If the device is unavailable or
    115      *         something happened while deleting files
    116      */
    117     private Map<String, String> parseOutputFile() throws DeviceNotAvailableException {
    118         BufferedReader reader = null;
    119         File outputFile = null;
    120         String lineMean = null, lineSd = null;
    121         Matcher m = null;
    122         Map<String, String> metrics = new HashMap<String, String>();
    123 
    124         // Read in data
    125         // Output file is only 2 lines and should look something like:
    126         // "Shot to shot latency - mean: 1234.5678901"
    127         // "Shot to shot latency - standard deviation: 123.45678901"
    128         try {
    129             outputFile = mTestDevice.pullFileFromExternal(mOutputPath);
    130             reader = new BufferedReader(new FileReader(outputFile));
    131 
    132             lineMean = reader.readLine();
    133             lineSd = reader.readLine();
    134 
    135             if ((lineMean == null) || (lineSd == null)) {
    136                 CLog.e(String.format("Unable to find output data; hit EOF: \nmean:%s\nsd:%s",
    137                         lineMean, lineSd));
    138             } else {
    139                 m = MEAN_PATTERN.matcher(lineMean);
    140                 if (m.matches()) {
    141                     metrics.put(LATENCY_KEY_MEAN, m.group(3));
    142                 } else {
    143                     CLog.e(String.format("Unable to find mean: %s", lineMean));
    144                 }
    145 
    146                 m = STANDARD_DEVIATION_PATTERN.matcher(lineSd);
    147                 if (m.matches()) {
    148                     metrics.put(LATENCY_KEY_SD, m.group(3));
    149                 } else {
    150                     CLog.e(String.format("Unable to find standard deviation: %s", lineSd));
    151                 }
    152             }
    153         } catch (IOException e) {
    154             CLog.e(String.format("IOException reading from file: %s", e.toString()));
    155         } finally {
    156             if (reader != null) {
    157                 try {
    158                     reader.close();
    159                 } catch (IOException e) {
    160                     CLog.e(String.format("IOException closing file: %s", e.toString()));
    161                 }
    162             }
    163         }
    164 
    165         return metrics;
    166     }
    167 
    168     /**
    169      * Report run metrics by creating an empty test run to stick them in.
    170      * @param listener The {@link ITestInvocationListener} of test results
    171      * @param runName The test name
    172      * @param metrics The {@link Map} that contains metrics for the given test
    173      */
    174     private void reportMetrics(ITestInvocationListener listener, String runName,
    175             Map<String, String> metrics) {
    176         InputStreamSource bugreport = mTestDevice.getBugreport();
    177         listener.testLog("bugreport", LogDataType.BUGREPORT, bugreport);
    178         bugreport.cancel();
    179 
    180         CLog.d(String.format("About to report metrics: %s", metrics));
    181         listener.testRunStarted(runName, 0);
    182         listener.testRunEnded(0, metrics);
    183     }
    184 }
    185