• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.invoker.sandbox;
17 
18 import com.android.tradefed.build.BuildInfoKey.BuildInfoFileKey;
19 import com.android.tradefed.build.BuildRetrievalError;
20 import com.android.tradefed.build.IBuildInfo;
21 import com.android.tradefed.build.IBuildProvider;
22 import com.android.tradefed.build.VersionedFile;
23 import com.android.tradefed.config.IConfiguration;
24 import com.android.tradefed.config.IDeviceConfiguration;
25 import com.android.tradefed.device.DeviceNotAvailableException;
26 import com.android.tradefed.invoker.ExecutionFiles;
27 import com.android.tradefed.invoker.ExecutionFiles.FilesKey;
28 import com.android.tradefed.invoker.IInvocationContext;
29 import com.android.tradefed.invoker.IRescheduler;
30 import com.android.tradefed.invoker.InvocationExecution;
31 import com.android.tradefed.invoker.TestInformation;
32 import com.android.tradefed.log.ITestLogger;
33 import com.android.tradefed.log.LogUtil.CLog;
34 import com.android.tradefed.result.ITestInvocationListener;
35 import com.android.tradefed.targetprep.ITargetPreparer;
36 import com.android.tradefed.testtype.IInvocationContextReceiver;
37 
38 import java.io.File;
39 import java.util.ArrayList;
40 import java.util.List;
41 
42 /**
43  * Special sandbox execution of the invocation: This is the InvocationExection for when we are
44  * inside the sandbox running the command. The build should already be available in the context.
45  */
46 public class SandboxedInvocationExecution extends InvocationExecution {
47 
48     /** {@inheritDoc} */
49     @Override
fetchBuild( TestInformation testInfo, IConfiguration config, IRescheduler rescheduler, ITestInvocationListener listener)50     public boolean fetchBuild(
51             TestInformation testInfo,
52             IConfiguration config,
53             IRescheduler rescheduler,
54             ITestInvocationListener listener)
55             throws DeviceNotAvailableException, BuildRetrievalError {
56         // If the invocation is currently sandboxed, builds have already been downloaded.
57         CLog.d("Skipping download in the sandbox.");
58         if (!config.getConfigurationDescription().shouldUseSandbox()) {
59             throw new RuntimeException(
60                     "We should only skip download if we are a sandbox. Something went very wrong.");
61         }
62         // Even if we don't call them directly here, ensure they receive their dependencies for the
63         // buildNotTested callback.
64         for (String deviceName : testInfo.getContext().getDeviceConfigNames()) {
65             IDeviceConfiguration deviceConfig = config.getDeviceConfigByName(deviceName);
66             IBuildProvider provider = deviceConfig.getBuildProvider();
67             // Inject the context to the provider if it can receive it
68             if (provider instanceof IInvocationContextReceiver) {
69                 ((IInvocationContextReceiver) provider).setInvocationContext(testInfo.getContext());
70             }
71         }
72 
73         // Still set the test-tag on build infos for proper reporting
74         for (IBuildInfo info : testInfo.getContext().getBuildInfos()) {
75             setTestTag(info, config);
76             // Force the linking again in case there was no original testsdir
77             // this is inop if the linking already occurred.
78             super.linkExternalDirs(info, testInfo);
79         }
80         backFillTestInformation(testInfo, testInfo.getBuildInfo());
81         return true;
82     }
83 
84     @Override
cleanUpBuilds(IInvocationContext context, IConfiguration config)85     public void cleanUpBuilds(IInvocationContext context, IConfiguration config) {
86         // Don't clean the build info in subprocess. Let the parents do it.
87     }
88 
89     /** {@inheritDoc} */
90     @Override
getTargetPreparersToRun( IConfiguration config, String deviceName)91     protected List<ITargetPreparer> getTargetPreparersToRun(
92             IConfiguration config, String deviceName) {
93         List<ITargetPreparer> preparersToRun = new ArrayList<>();
94         preparersToRun.addAll(config.getDeviceConfigByName(deviceName).getTargetPreparers());
95         return preparersToRun;
96     }
97 
98     /** {@inheritDoc} */
99     @Override
getLabPreparersToRun(IConfiguration config, String deviceName)100     protected List<ITargetPreparer> getLabPreparersToRun(IConfiguration config, String deviceName) {
101         return new ArrayList<>();
102     }
103 
104     /**
105      * In order for sandbox to work without currently receiving the parent TestInformation back-fill
106      * some information to find artifacts properly.
107      */
backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild)108     private void backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild) {
109         ExecutionFiles execFiles = testInfo.executionFiles();
110         if (execFiles.get(FilesKey.TESTS_DIRECTORY) == null) {
111             File testsDir = primaryBuild.getFile(BuildInfoFileKey.TESTDIR_IMAGE);
112             if (testsDir != null && testsDir.exists()) {
113                 execFiles.put(FilesKey.TESTS_DIRECTORY, testsDir, true);
114             }
115         }
116         if (execFiles.get(FilesKey.TARGET_TESTS_DIRECTORY) == null) {
117             File targetDir = primaryBuild.getFile(BuildInfoFileKey.TARGET_LINKED_DIR);
118             if (targetDir != null && targetDir.exists()) {
119                 execFiles.put(FilesKey.TARGET_TESTS_DIRECTORY, targetDir, true);
120             }
121         }
122         if (execFiles.get(FilesKey.HOST_TESTS_DIRECTORY) == null) {
123             File hostDir = primaryBuild.getFile(BuildInfoFileKey.HOST_LINKED_DIR);
124             if (hostDir != null && hostDir.exists()) {
125                 execFiles.put(FilesKey.HOST_TESTS_DIRECTORY, hostDir, true);
126             }
127         }
128         // Link the remaining buildInfo files.
129         for (String key : primaryBuild.getVersionedFileKeys()) {
130             VersionedFile versionedFile = primaryBuild.getVersionedFile(key);
131             if (versionedFile != null
132                     && versionedFile.getFile().exists()
133                     && !execFiles.containsKey(key)) {
134                 execFiles.put(key, versionedFile.getFile());
135             }
136         }
137     }
138 
139     @Override
logHostAdb(IConfiguration config, ITestLogger logger)140     protected void logHostAdb(IConfiguration config, ITestLogger logger) {
141         // Do nothing, the parent sandbox will log it.
142     }
143 }
144