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