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