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 } 77 backFillTestInformation(testInfo, testInfo.getBuildInfo()); 78 return true; 79 } 80 81 @Override cleanUpBuilds(IInvocationContext context, IConfiguration config)82 public void cleanUpBuilds(IInvocationContext context, IConfiguration config) { 83 // Don't clean the build info in subprocess. Let the parents do it. 84 } 85 86 /** {@inheritDoc} */ 87 @Override getTargetPreparersToRun( IConfiguration config, String deviceName)88 protected List<ITargetPreparer> getTargetPreparersToRun( 89 IConfiguration config, String deviceName) { 90 List<ITargetPreparer> preparersToRun = new ArrayList<>(); 91 preparersToRun.addAll(config.getDeviceConfigByName(deviceName).getTargetPreparers()); 92 return preparersToRun; 93 } 94 95 /** {@inheritDoc} */ 96 @Override getLabPreparersToRun(IConfiguration config, String deviceName)97 protected List<ITargetPreparer> getLabPreparersToRun(IConfiguration config, String deviceName) { 98 return new ArrayList<>(); 99 } 100 101 /** 102 * In order for sandbox to work without currently receiving the parent TestInformation back-fill 103 * some information to find artifacts properly. 104 */ backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild)105 private void backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild) { 106 ExecutionFiles execFiles = testInfo.executionFiles(); 107 if (execFiles.get(FilesKey.TESTS_DIRECTORY) == null) { 108 File testsDir = primaryBuild.getFile(BuildInfoFileKey.TESTDIR_IMAGE); 109 if (testsDir != null && testsDir.exists()) { 110 execFiles.put(FilesKey.TESTS_DIRECTORY, testsDir, true); 111 } 112 } 113 if (execFiles.get(FilesKey.TARGET_TESTS_DIRECTORY) == null) { 114 File targetDir = primaryBuild.getFile(BuildInfoFileKey.TARGET_LINKED_DIR); 115 if (targetDir != null && targetDir.exists()) { 116 execFiles.put(FilesKey.TARGET_TESTS_DIRECTORY, targetDir, true); 117 } 118 } 119 if (execFiles.get(FilesKey.HOST_TESTS_DIRECTORY) == null) { 120 File hostDir = primaryBuild.getFile(BuildInfoFileKey.HOST_LINKED_DIR); 121 if (hostDir != null && hostDir.exists()) { 122 execFiles.put(FilesKey.HOST_TESTS_DIRECTORY, hostDir, true); 123 } 124 } 125 // Link the remaining buildInfo files. 126 for (String key : primaryBuild.getVersionedFileKeys()) { 127 VersionedFile versionedFile = primaryBuild.getVersionedFile(key); 128 if (versionedFile != null 129 && versionedFile.getFile().exists() 130 && !execFiles.containsKey(key)) { 131 execFiles.put(key, versionedFile.getFile()); 132 } 133 } 134 } 135 136 @Override logHostAdb(IConfiguration config, ITestLogger logger)137 protected void logHostAdb(IConfiguration config, ITestLogger logger) { 138 // Do nothing, the parent sandbox will log it. 139 } 140 } 141