Home | History | Annotate | Download | only in build
      1 /*
      2  * Copyright (C) 2013 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.tradefed.build;
     18 
     19 import com.android.tradefed.config.Option;
     20 import com.android.tradefed.config.OptionClass;
     21 import com.android.tradefed.device.DeviceNotAvailableException;
     22 import com.android.tradefed.device.ITestDevice;
     23 import com.android.tradefed.log.LogUtil.CLog;
     24 import com.android.tradefed.util.FileUtil;
     25 
     26 import java.io.File;
     27 import java.io.IOException;
     28 
     29 /**
     30  * A {@link IDeviceBuildProvider} that bootstraps build info from the test device
     31  *
     32  * <p>
     33  * This is typically used for devices with an externally supplied build, i.e. not generated by
     34  * in-house build system. Certain information, specifically the branch, is not actually available
     35  * from the device, therefore it's artificially generated.
     36  *
     37  * <p>All build meta data info comes from various ro.* property fields on device
     38  *
     39  * <p>Currently this build provider generates meta data as follows:
     40  * <ul>
     41  * <li>branch:
     42  * $(ro.product.brand)-$(ro.product.name)-$(ro.product.device)-$(ro.build.version.release),
     43  * for example:
     44  * <ul>
     45  *   <li>for Google Play edition Samsung S4 running Android 4.2: samsung-jgedlteue-jgedlte-4.2
     46  *   <li>for Nexus 7 running Android 4.2: google-nakasi-grouper-4.2
     47  * </ul>
     48  * <li>build flavor: as provided by {@link ITestDevice#getBuildFlavor()}
     49  * <li>build alias: as provided by {@link ITestDevice#getBuildAlias()}
     50  * <li>build id: as provided by {@link ITestDevice#getBuildId()}
     51  */
     52 @OptionClass(alias = "bootstrap-build")
     53 public class BootstrapBuildProvider implements IDeviceBuildProvider {
     54 
     55     @Option(name="build-target", description="build target name to supply.")
     56     private String mBuildTargetName = "bootstrapped";
     57 
     58     @Option(name="branch", description="build branch name to supply.")
     59     private String mBranch = null;
     60 
     61     @Option(name="shell-available-timeout",
     62             description="Time to wait in seconds for device shell to become available. " +
     63             "Default to 300 seconds.")
     64     private long mShellAvailableTimeout = 5 * 60;
     65 
     66     @Option(name="tests-dir", description="Path to top directory of expanded tests zip")
     67     private File mTestsDir = null;
     68 
     69     private boolean mCreatedTestDir = false;
     70 
     71     @Override
     72     public IBuildInfo getBuild() throws BuildRetrievalError {
     73         throw new UnsupportedOperationException("Call getBuild(ITestDevice)");
     74     }
     75 
     76     @Override
     77     public void buildNotTested(IBuildInfo info) {
     78         // no op
     79         CLog.i("ignoring buildNotTested call, build = %s ", info.getBuildId());
     80     }
     81 
     82     @Override
     83     public void cleanUp(IBuildInfo info) {
     84         // If we created the tests dir, we delete it.
     85         if (mCreatedTestDir) {
     86             FileUtil.recursiveDelete(((IDeviceBuildInfo) info).getTestsDir());
     87         }
     88     }
     89 
     90     @Override
     91     public IBuildInfo getBuild(ITestDevice device) throws BuildRetrievalError,
     92             DeviceNotAvailableException {
     93         String buildId = device.getBuildId();
     94         IBuildInfo info = new DeviceBuildInfo(buildId, mBuildTargetName);
     95         if (!device.waitForDeviceShell(mShellAvailableTimeout * 1000)) {
     96             throw new DeviceNotAvailableException(
     97                     String.format("Shell did not become available in %d seconds",
     98                             mShellAvailableTimeout), device.getSerialNumber());
     99         }
    100         if (mBranch == null) {
    101             mBranch = String.format("%s-%s-%s-%s",
    102                     device.getProperty("ro.product.brand"),
    103                     device.getProperty("ro.product.name"),
    104                     device.getProductVariant(),
    105                     device.getProperty("ro.build.version.release"));
    106         }
    107         info.setBuildBranch(mBranch);
    108         info.setBuildFlavor(device.getBuildFlavor());
    109         info.addBuildAttribute("build_alias", device.getBuildAlias());
    110         if (mTestsDir != null && mTestsDir.isDirectory()) {
    111             info.setFile("testsdir", mTestsDir, buildId);
    112         }
    113         // Avoid tests dir being null, by creating a temporary dir.
    114         if (mTestsDir == null) {
    115             mCreatedTestDir = true;
    116             try {
    117                 mTestsDir = FileUtil.createTempDir("bootstrap-test-dir");
    118             } catch (IOException e) {
    119                 throw new BuildRetrievalError(e.getMessage(), e);
    120             }
    121             ((IDeviceBuildInfo) info).setTestsDir(mTestsDir, "1");
    122         }
    123         return info;
    124     }
    125 }
    126