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.annotations.VisibleForTesting; 19 import com.android.tradefed.build.BuildRetrievalError; 20 import com.android.tradefed.config.Configuration; 21 import com.android.tradefed.config.ConfigurationException; 22 import com.android.tradefed.config.ConfigurationFactory; 23 import com.android.tradefed.config.IConfiguration; 24 import com.android.tradefed.config.IConfigurationFactory; 25 import com.android.tradefed.device.DeviceNotAvailableException; 26 import com.android.tradefed.device.ITestDevice; 27 import com.android.tradefed.invoker.IInvocationContext; 28 import com.android.tradefed.invoker.IRescheduler; 29 import com.android.tradefed.invoker.InvocationExecution; 30 import com.android.tradefed.invoker.TestInvocation.Stage; 31 import com.android.tradefed.log.ITestLogger; 32 import com.android.tradefed.log.LogUtil.CLog; 33 import com.android.tradefed.result.ITestInvocationListener; 34 import com.android.tradefed.sandbox.SandboxInvocationRunner; 35 import com.android.tradefed.sandbox.SandboxOptions; 36 import com.android.tradefed.targetprep.BuildError; 37 import com.android.tradefed.targetprep.TargetSetupError; 38 39 /** 40 * Version of {@link InvocationExecution} for the parent invocation special actions when running a 41 * sandbox. 42 */ 43 public class ParentSandboxInvocationExecution extends InvocationExecution { 44 45 private IConfiguration mParentPreparerConfig = null; 46 47 @Override fetchBuild( IInvocationContext context, IConfiguration config, IRescheduler rescheduler, ITestInvocationListener listener)48 public boolean fetchBuild( 49 IInvocationContext context, 50 IConfiguration config, 51 IRescheduler rescheduler, 52 ITestInvocationListener listener) 53 throws DeviceNotAvailableException, BuildRetrievalError { 54 if (!context.getBuildInfos().isEmpty()) { 55 CLog.d( 56 "Context already contains builds: %s. Skipping download as we are in " 57 + "sandbox-test-mode.", 58 context.getBuildInfos()); 59 return true; 60 } 61 return super.fetchBuild(context, config, rescheduler, listener); 62 } 63 64 @Override doSetup( IInvocationContext context, IConfiguration config, ITestInvocationListener listener)65 public void doSetup( 66 IInvocationContext context, IConfiguration config, ITestInvocationListener listener) 67 throws TargetSetupError, BuildError, DeviceNotAvailableException { 68 // Skip 69 mParentPreparerConfig = getParentTargetConfig(config); 70 if (mParentPreparerConfig == null) { 71 return; 72 } 73 CLog.d("Using %s to run in the parent setup.", SandboxOptions.PARENT_PREPARER_CONFIG); 74 super.doSetup(context, mParentPreparerConfig, listener); 75 } 76 77 @Override doTeardown( IInvocationContext context, IConfiguration config, ITestLogger logger, Throwable exception)78 public void doTeardown( 79 IInvocationContext context, 80 IConfiguration config, 81 ITestLogger logger, 82 Throwable exception) 83 throws Throwable { 84 // Skip 85 // If we are the parent invocation of the sandbox, setUp has been skipped since it's 86 // done in the sandbox, so tearDown should be skipped. 87 mParentPreparerConfig = getParentTargetConfig(config); 88 if (mParentPreparerConfig == null) { 89 return; 90 } 91 CLog.d("Using %s to run in the parent tear down.", SandboxOptions.PARENT_PREPARER_CONFIG); 92 super.doTeardown(context, mParentPreparerConfig, logger, exception); 93 } 94 95 @Override doCleanUp(IInvocationContext context, IConfiguration config, Throwable exception)96 public void doCleanUp(IInvocationContext context, IConfiguration config, Throwable exception) { 97 // Skip 98 if (mParentPreparerConfig == null) { 99 return; 100 } 101 CLog.d("Using %s to run in the parent clean up.", SandboxOptions.PARENT_PREPARER_CONFIG); 102 super.doCleanUp(context, mParentPreparerConfig, exception); 103 } 104 105 @Override runTests( IInvocationContext context, IConfiguration config, ITestInvocationListener listener)106 public void runTests( 107 IInvocationContext context, IConfiguration config, ITestInvocationListener listener) 108 throws Throwable { 109 // If the invocation is sandboxed run as a sandbox instead. 110 SandboxInvocationRunner.prepareAndRun(config, context, listener); 111 } 112 113 @Override reportLogs(ITestDevice device, ITestInvocationListener listener, Stage stage)114 public void reportLogs(ITestDevice device, ITestInvocationListener listener, Stage stage) { 115 // If it's not a major error we do not report it if no setup or teardown ran. 116 if (mParentPreparerConfig == null || !Stage.ERROR.equals(stage)) { 117 return; 118 } 119 super.reportLogs(device, listener, stage); 120 } 121 122 /** Returns the {@link IConfigurationFactory} used to created configurations. */ 123 @VisibleForTesting getFactory()124 protected IConfigurationFactory getFactory() { 125 return ConfigurationFactory.getInstance(); 126 } 127 getParentTargetConfig(IConfiguration config)128 private IConfiguration getParentTargetConfig(IConfiguration config) throws TargetSetupError { 129 if (mParentPreparerConfig != null) { 130 return mParentPreparerConfig; 131 } 132 SandboxOptions options = 133 (SandboxOptions) 134 config.getConfigurationObject(Configuration.SANBOX_OPTIONS_TYPE_NAME); 135 if (options != null && options.getParentPreparerConfig() != null) { 136 try { 137 return getFactory() 138 .createConfigurationFromArgs( 139 new String[] {options.getParentPreparerConfig()}); 140 } catch (ConfigurationException e) { 141 String message = 142 String.format( 143 "Check your --%s option: %s", 144 SandboxOptions.PARENT_PREPARER_CONFIG, e.getMessage()); 145 CLog.e(message); 146 CLog.e(e); 147 throw new TargetSetupError(message, e, null); 148 } 149 } 150 return null; 151 } 152 } 153