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.IRescheduler; 29 import com.android.tradefed.invoker.InvocationExecution; 30 import com.android.tradefed.invoker.TestInformation; 31 import com.android.tradefed.log.LogUtil.CLog; 32 import com.android.tradefed.result.ITestInvocationListener; 33 import com.android.tradefed.testtype.IInvocationContextReceiver; 34 35 import java.io.File; 36 37 /** 38 * Special sandbox execution of the invocation: This is the InvocationExection for when we are 39 * inside the sandbox running the command. The build should already be available in the context. 40 */ 41 public class SandboxedInvocationExecution extends InvocationExecution { 42 43 /** {@inheritDoc} */ 44 @Override fetchBuild( TestInformation testInfo, IConfiguration config, IRescheduler rescheduler, ITestInvocationListener listener)45 public boolean fetchBuild( 46 TestInformation testInfo, 47 IConfiguration config, 48 IRescheduler rescheduler, 49 ITestInvocationListener listener) 50 throws DeviceNotAvailableException, BuildRetrievalError { 51 // If the invocation is currently sandboxed, builds have already been downloaded. 52 CLog.d("Skipping download in the sandbox."); 53 if (!config.getConfigurationDescription().shouldUseSandbox()) { 54 throw new RuntimeException( 55 "We should only skip download if we are a sandbox. Something went very wrong."); 56 } 57 // Even if we don't call them directly here, ensure they receive their dependencies for the 58 // buildNotTested callback. 59 for (String deviceName : testInfo.getContext().getDeviceConfigNames()) { 60 IDeviceConfiguration deviceConfig = config.getDeviceConfigByName(deviceName); 61 IBuildProvider provider = deviceConfig.getBuildProvider(); 62 // Inject the context to the provider if it can receive it 63 if (provider instanceof IInvocationContextReceiver) { 64 ((IInvocationContextReceiver) provider).setInvocationContext(testInfo.getContext()); 65 } 66 } 67 68 // Still set the test-tag on build infos for proper reporting 69 for (IBuildInfo info : testInfo.getContext().getBuildInfos()) { 70 setTestTag(info, config); 71 } 72 backFillTestInformation(testInfo, testInfo.getBuildInfo()); 73 return true; 74 } 75 76 /** 77 * In order for sandbox to work without currently receiving the parent TestInformation back-fill 78 * some information to find artifacts properly. 79 */ backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild)80 private void backFillTestInformation(TestInformation testInfo, IBuildInfo primaryBuild) { 81 ExecutionFiles execFiles = testInfo.executionFiles(); 82 if (execFiles.get(FilesKey.TESTS_DIRECTORY) == null) { 83 File testsDir = primaryBuild.getFile(BuildInfoFileKey.TESTDIR_IMAGE); 84 if (testsDir != null && testsDir.exists()) { 85 execFiles.put(FilesKey.TESTS_DIRECTORY, testsDir); 86 } 87 } 88 if (execFiles.get(FilesKey.TARGET_TESTS_DIRECTORY) == null) { 89 File targetDir = primaryBuild.getFile(BuildInfoFileKey.TARGET_LINKED_DIR); 90 if (targetDir != null && targetDir.exists()) { 91 execFiles.put(FilesKey.TARGET_TESTS_DIRECTORY, targetDir, true); 92 } 93 } 94 if (execFiles.get(FilesKey.HOST_TESTS_DIRECTORY) == null) { 95 File hostDir = primaryBuild.getFile(BuildInfoFileKey.HOST_LINKED_DIR); 96 if (hostDir != null && hostDir.exists()) { 97 execFiles.put(FilesKey.HOST_TESTS_DIRECTORY, hostDir, true); 98 } 99 } 100 // Link the remaining buildInfo files. 101 for (String key : primaryBuild.getVersionedFileKeys()) { 102 VersionedFile versionedFile = primaryBuild.getVersionedFile(key); 103 if (versionedFile != null 104 && versionedFile.getFile().exists() 105 && !execFiles.containsKey(key)) { 106 execFiles.put(key, versionedFile.getFile()); 107 } 108 } 109 } 110 } 111