blob: d7ad1676846988e7fc7659d71a19d7041eda99cb [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tradefed.invoker.sandbox;
import com.android.annotations.VisibleForTesting;
import com.android.tradefed.build.BuildRetrievalError;
import com.android.tradefed.config.Configuration;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.ConfigurationFactory;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.IConfigurationFactory;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.IRescheduler;
import com.android.tradefed.invoker.InvocationExecution;
import com.android.tradefed.invoker.TestInvocation.Stage;
import com.android.tradefed.log.ITestLogger;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.sandbox.SandboxInvocationRunner;
import com.android.tradefed.sandbox.SandboxOptions;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
/**
* Version of {@link InvocationExecution} for the parent invocation special actions when running a
* sandbox.
*/
public class ParentSandboxInvocationExecution extends InvocationExecution {
private IConfiguration mParentPreparerConfig = null;
@Override
public boolean fetchBuild(
IInvocationContext context,
IConfiguration config,
IRescheduler rescheduler,
ITestInvocationListener listener)
throws DeviceNotAvailableException, BuildRetrievalError {
if (!context.getBuildInfos().isEmpty()) {
CLog.d(
"Context already contains builds: %s. Skipping download as we are in "
+ "sandbox-test-mode.",
context.getBuildInfos());
return true;
}
return super.fetchBuild(context, config, rescheduler, listener);
}
@Override
public void doSetup(IInvocationContext context, IConfiguration config, ITestLogger logger)
throws TargetSetupError, BuildError, DeviceNotAvailableException {
// Skip
mParentPreparerConfig = getParentTargetConfig(config);
if (mParentPreparerConfig == null) {
return;
}
CLog.d("Using %s to run in the parent setup.", SandboxOptions.PARENT_PREPARER_CONFIG);
super.doSetup(context, mParentPreparerConfig, logger);
}
@Override
public void doTeardown(
IInvocationContext context,
IConfiguration config,
ITestLogger logger,
Throwable exception)
throws Throwable {
// Skip
// If we are the parent invocation of the sandbox, setUp has been skipped since it's
// done in the sandbox, so tearDown should be skipped.
mParentPreparerConfig = getParentTargetConfig(config);
if (mParentPreparerConfig == null) {
return;
}
CLog.d("Using %s to run in the parent tear down.", SandboxOptions.PARENT_PREPARER_CONFIG);
super.doTeardown(context, mParentPreparerConfig, logger, exception);
}
@Override
public void doCleanUp(IInvocationContext context, IConfiguration config, Throwable exception) {
// Skip
if (mParentPreparerConfig == null) {
return;
}
CLog.d("Using %s to run in the parent clean up.", SandboxOptions.PARENT_PREPARER_CONFIG);
super.doCleanUp(context, mParentPreparerConfig, exception);
}
@Override
public void runTests(
IInvocationContext context, IConfiguration config, ITestInvocationListener listener)
throws Throwable {
// If the invocation is sandboxed run as a sandbox instead.
SandboxInvocationRunner.prepareAndRun(config, context, listener);
}
@Override
public void reportLogs(ITestDevice device, ITestLogger logger, Stage stage) {
// If it's not a major error we do not report it if no setup or teardown ran.
if (mParentPreparerConfig == null || !Stage.ERROR.equals(stage)) {
return;
}
super.reportLogs(device, logger, stage);
}
/** Returns the {@link IConfigurationFactory} used to created configurations. */
@VisibleForTesting
protected IConfigurationFactory getFactory() {
return ConfigurationFactory.getInstance();
}
private IConfiguration getParentTargetConfig(IConfiguration config) throws TargetSetupError {
if (mParentPreparerConfig != null) {
return mParentPreparerConfig;
}
SandboxOptions options =
(SandboxOptions)
config.getConfigurationObject(Configuration.SANBOX_OPTIONS_TYPE_NAME);
if (options != null && options.getParentPreparerConfig() != null) {
try {
return getFactory()
.createConfigurationFromArgs(
new String[] {options.getParentPreparerConfig()});
} catch (ConfigurationException e) {
String message =
String.format(
"Check your --%s option: %s",
SandboxOptions.PARENT_PREPARER_CONFIG, e.getMessage());
CLog.e(message);
CLog.e(e);
throw new TargetSetupError(message, e, null);
}
}
return null;
}
}