Home | History | Annotate | Download | only in targetprep
      1 /*
      2  * Copyright (C) 2017 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.compatibility.common.tradefed.targetprep;
     18 
     19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
     20 import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
     21 import com.android.tradefed.build.IBuildInfo;
     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 
     27 import java.nio.file.Paths;
     28 import java.io.File;
     29 import java.io.FileNotFoundException;
     30 import java.util.Map;
     31 import java.util.HashMap;
     32 
     33 /**
     34  * An {@link PreconditionPreparer} that collects one device file.
     35  */
     36 public class DeviceFileCollector extends PreconditionPreparer {
     37 
     38     @Option(name = CompatibilityTest.SKIP_DEVICE_INFO_OPTION,
     39             shortName = 'd',
     40             description = "Whether device info collection should be skipped")
     41     private boolean mSkipDeviceInfo = false;
     42 
     43     @Option(name = "src-file", description = "The file path to copy to the results dir")
     44     private String mSrcFile;
     45 
     46     @Option(name = "dest-file", description = "The destination file path under the result")
     47     private String mDestFile;
     48 
     49     /**
     50      * If device.getProperty(key) is not value for all properties listed, the collection will be
     51      * skipped. If this map is empty, mSrcFile will always be collected.
     52      *
     53      * This can be specified by the following option:
     54      * {@code <option name="property" key="foo" value="bar"/>}
     55      */
     56     @Option(name = "property", description = "run this test on device with this property value")
     57     private Map<String, String> mPropertyMap = new HashMap<>();
     58 
     59     private File mResultFile;
     60 
     61     /**
     62      * {@inheritDoc}
     63      */
     64     @Override
     65     public void run(ITestDevice device, IBuildInfo buildInfo) {
     66         if (mSkipDeviceInfo)
     67             return;
     68 
     69         if (!matchProperties(device))
     70             return;
     71 
     72         createResultDir(buildInfo);
     73         if (mResultFile != null && !mResultFile.isDirectory() &&
     74             mSrcFile != null && !mSrcFile.isEmpty()) {
     75 
     76             try {
     77                 if (device.doesFileExist(mSrcFile)) {
     78                     device.pullFile(mSrcFile, mResultFile);
     79                 } else {
     80                     CLog.w(String.format("File does not exist on device: \"%s\"", mSrcFile));
     81                 }
     82             } catch (DeviceNotAvailableException e) {
     83                 CLog.e("Caught exception during pull.");
     84                 CLog.e(e);
     85             }
     86         }
     87     }
     88 
     89     private void createResultDir(IBuildInfo buildInfo) {
     90         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(buildInfo);
     91         try {
     92             File resultDir = buildHelper.getResultDir();
     93             if (mDestFile == null || mDestFile.isEmpty()) {
     94                 mDestFile = Paths.get(mSrcFile).getFileName().toString();
     95             }
     96             mResultFile = Paths.get(resultDir.getAbsolutePath(), mDestFile).toFile();
     97             resultDir = mResultFile.getParentFile();
     98             resultDir.mkdirs();
     99             if (!resultDir.isDirectory()) {
    100                 CLog.e("%s is not a directory", resultDir.getAbsolutePath());
    101                 return;
    102             }
    103         } catch (FileNotFoundException fnfe) {
    104             fnfe.printStackTrace();
    105         }
    106     }
    107 
    108     private boolean matchProperties(ITestDevice device) {
    109         for (Map.Entry<String, String> propEntry : mPropertyMap.entrySet()) {
    110             try {
    111                 String actualValue = device.getProperty(propEntry.getKey());
    112                 if (!propEntry.getValue().equals(actualValue)) {
    113                     CLog.i("Skipping '%s' because property doesn't match. "
    114                            + "(key=%s, expected=%s, actual=%s)",
    115                            mSrcFile, propEntry.getKey(), propEntry.getValue(), actualValue);
    116                     return false;
    117                 }
    118             } catch (DeviceNotAvailableException e) {
    119                 CLog.e("Caught exception during property check.");
    120                 CLog.e(e);
    121                 return false;
    122             }
    123         }
    124         return true;
    125     }
    126 }
    127