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