Home | History | Annotate | Download | only in testtype
      1 /*
      2  * Copyright (C) 2016 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.testtype;
     17 
     18 import com.android.ddmlib.MultiLineReceiver;
     19 import com.android.ddmlib.testrunner.ITestRunListener;
     20 import com.android.ddmlib.testrunner.TestIdentifier;
     21 import com.android.tradefed.log.LogUtil.CLog;
     22 
     23 import java.util.ArrayList;
     24 import java.util.Collections;
     25 import java.util.List;
     26 import java.util.Map;
     27 import java.util.regex.Matcher;
     28 import java.util.regex.Pattern;
     29 /**
     30  * A result parser for gtest dry run mode with "--gtest_list_tests" parameter.
     31  *
     32  */
     33 public class GTestListTestParser extends MultiLineReceiver {
     34 
     35     private String mLastTestClassName = null;
     36     private String mTestRunName = null;
     37     private ITestRunListener mTestRunListener = null;
     38     /** Whether or not to prepend filename to classname. */
     39     private boolean mPrependFileName = false;
     40 
     41     // test class name should start without leading spaces, and end with a "."
     42     // example: <line start>RecordingCanvas.<line end>
     43     private static final Pattern TEST_CLASS = Pattern.compile("^([a-zA-Z]+.*)\\.$");
     44     // test method name should start with leading spaces, named as however valid as a C function
     45     // example: <line start>  emptyPlayback<line end>
     46     private static final Pattern TEST_METHOD = Pattern.compile("\\s+(\\w+)$");
     47 
     48     // exposed for unit testing
     49     protected List<TestIdentifier> mTests = new ArrayList<>();
     50 
     51     /**
     52      * Creates the GTestListTestParser for a single listener.
     53      *
     54      * @param testRunName the test run name to provide to
     55      *            {@link ITestRunListener#testRunStarted(String, int)}
     56      * @param listener informed of test results as the tests are executing
     57      */
     58     public GTestListTestParser(String testRunName, ITestRunListener listener) {
     59         mTestRunName = testRunName;
     60         mTestRunListener = listener;
     61         // don't trim, since we need the leading whitespace
     62         setTrimLine(false);
     63     }
     64 
     65     /**
     66      * {@inheritDoc}
     67      */
     68     @Override
     69     public boolean isCancelled() {
     70         return false;
     71     }
     72 
     73     /**
     74      * {@inheritDoc}
     75      */
     76     @Override
     77     public void processNewLines(String[] lines) {
     78         for (String line : lines) {
     79             parse(line);
     80         }
     81     }
     82 
     83     private String getTestClass(String name) {
     84         if (mPrependFileName) {
     85             StringBuilder sb = new StringBuilder();
     86             sb.append(mTestRunName);
     87             sb.append(".");
     88             sb.append(name);
     89             return sb.toString();
     90         }
     91         return name;
     92     }
     93 
     94     private void parse(String line) {
     95         Matcher classMatcher = TEST_CLASS.matcher(line);
     96         Matcher methodMatcher = TEST_METHOD.matcher(line);
     97         if (classMatcher.matches()) {
     98             // New test class name found
     99             mLastTestClassName = classMatcher.group(1);
    100         } else if (methodMatcher.matches()) {
    101             if (mLastTestClassName == null) {
    102                 throw new IllegalStateException(String.format(
    103                         "parsed new test case name %s but no test class name has been set", line));
    104             }
    105             // Test method name found
    106             mTests.add(new TestIdentifier(
    107                     getTestClass(mLastTestClassName), methodMatcher.group(1)));
    108         } else {
    109             CLog.v("line ignored: %s", line);
    110         }
    111     }
    112 
    113     public void setPrependFileName(boolean prepend) {
    114         mPrependFileName = prepend;
    115     }
    116 
    117     public boolean getPrependFileName() {
    118         return mPrependFileName;
    119     }
    120 
    121     /**
    122      * {@inheritDoc}
    123      */
    124     @Override
    125     public void done() {
    126         // now we send out all the test callbacks
    127         final Map<String, String> empty = Collections.<String, String>emptyMap();
    128         mTestRunListener.testRunStarted(mTestRunName, mTests.size());
    129         for (TestIdentifier id : mTests) {
    130             mTestRunListener.testStarted(id);
    131             mTestRunListener.testEnded(id, empty);
    132         }
    133         mTestRunListener.testRunEnded(0, empty);
    134         super.done();
    135     }
    136 }
    137