aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Desprez <jdesprez@google.com>2017-09-18 17:17:34 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-09-18 17:17:34 +0000
commit9bb93530cd94ee5a1971cb9af720a86f43936c9d (patch)
tree9eb3b93ef855cd7e2e2c6fc0b10f1b359e669674
parentd71b225027b0800cd78598ce78a2486c87991b46 (diff)
parent9d45b589f877525175701fe5895e56973b15f622 (diff)
downloadtradefederation-9bb93530cd94ee5a1971cb9af720a86f43936c9d.tar.gz
Merge "Create SandboxConfigurationFactory" into oc-dev am: bd4ec445c3
am: 9d45b589f8 Change-Id: I6b1b201a2824882a9e285c2b8176862ecc0bd8de
-rw-r--r--src/com/android/tradefed/command/CommandScheduler.java6
-rw-r--r--src/com/android/tradefed/config/ConfigurationFactory.java9
-rw-r--r--src/com/android/tradefed/config/GlobalConfiguration.java6
-rw-r--r--src/com/android/tradefed/config/SandboxConfigurationFactory.java93
-rw-r--r--src/com/android/tradefed/sandbox/SandboxConfigUtil.java45
-rw-r--r--tests/src/com/android/tradefed/UnitTests.java2
-rw-r--r--tests/src/com/android/tradefed/config/SandboxConfigurationFactoryTest.java135
7 files changed, 241 insertions, 55 deletions
diff --git a/src/com/android/tradefed/command/CommandScheduler.java b/src/com/android/tradefed/command/CommandScheduler.java
index 3cc7e3220..8cdb7e2e5 100644
--- a/src/com/android/tradefed/command/CommandScheduler.java
+++ b/src/com/android/tradefed/command/CommandScheduler.java
@@ -36,6 +36,7 @@ import com.android.tradefed.config.IConfigurationFactory;
import com.android.tradefed.config.IDeviceConfiguration;
import com.android.tradefed.config.IGlobalConfiguration;
import com.android.tradefed.config.Option;
+import com.android.tradefed.config.SandboxConfigurationFactory;
import com.android.tradefed.device.DeviceAllocationState;
import com.android.tradefed.device.DeviceManager;
import com.android.tradefed.device.DeviceNotAvailableException;
@@ -60,7 +61,6 @@ import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.result.ResultForwarder;
import com.android.tradefed.sandbox.ISandbox;
-import com.android.tradefed.sandbox.SandboxConfigUtil;
import com.android.tradefed.sandbox.TradefedSandbox;
import com.android.tradefed.util.ArrayUtil;
import com.android.tradefed.util.FileUtil;
@@ -1122,8 +1122,8 @@ public class CommandScheduler extends Thread implements ICommandScheduler, IComm
if (isCommandSandboxed(args)) {
// Create an sandboxed configuration based on the sandbox of the scheduler.
ISandbox sandbox = createSandbox();
- return SandboxConfigUtil.createSandboxConfiguration(
- args, sandbox, getConfigFactory(), getKeyStoreClient());
+ return SandboxConfigurationFactory.getInstance()
+ .createConfigurationFromArgs(args, getKeyStoreClient(), sandbox, new RunUtil());
}
return getConfigFactory().createConfigurationFromArgs(args, null, getKeyStoreClient());
}
diff --git a/src/com/android/tradefed/config/ConfigurationFactory.java b/src/com/android/tradefed/config/ConfigurationFactory.java
index d200b1f6c..ab30f6454 100644
--- a/src/com/android/tradefed/config/ConfigurationFactory.java
+++ b/src/com/android/tradefed/config/ConfigurationFactory.java
@@ -414,13 +414,14 @@ public class ConfigurationFactory implements IConfigurationFactory {
/**
* Retrieve the {@link ConfigurationDef} for the given name
*
- * @param name the name of a built-in configuration to load or a file path
- * to configuration xml to load
+ * @param name the name of a built-in configuration to load or a file path to configuration xml
+ * to load
* @return {@link ConfigurationDef}
* @throws ConfigurationException if an error occurred loading the config
*/
- private ConfigurationDef getConfigurationDef(String name, boolean isGlobal,
- Map<String, String> templateMap) throws ConfigurationException {
+ ConfigurationDef getConfigurationDef(
+ String name, boolean isGlobal, Map<String, String> templateMap)
+ throws ConfigurationException {
return new ConfigLoader(isGlobal).getConfigurationDef(name, templateMap);
}
diff --git a/src/com/android/tradefed/config/GlobalConfiguration.java b/src/com/android/tradefed/config/GlobalConfiguration.java
index 80d26cb3e..cef3da655 100644
--- a/src/com/android/tradefed/config/GlobalConfiguration.java
+++ b/src/com/android/tradefed/config/GlobalConfiguration.java
@@ -64,13 +64,13 @@ public class GlobalConfiguration implements IGlobalConfiguration {
public static final String KEY_STORE_TYPE_NAME = "key_store";
public static final String SHARDING_STRATEGY_TYPE_NAME = "sharding_strategy";
+ public static final String GLOBAL_CONFIG_VARIABLE = "TF_GLOBAL_CONFIG";
+ private static final String GLOBAL_CONFIG_FILENAME = "tf_global_config.xml";
+
private static Map<String, ObjTypeInfo> sObjTypeMap = null;
private static IGlobalConfiguration sInstance = null;
private static final Object sInstanceLock = new Object();
- private static final String GLOBAL_CONFIG_VARIABLE = "TF_GLOBAL_CONFIG";
- private static final String GLOBAL_CONFIG_FILENAME = "tf_global_config.xml";
-
// Empty embedded configuration available by default
private static final String DEFAULT_EMPTY_CONFIG_NAME = "empty";
diff --git a/src/com/android/tradefed/config/SandboxConfigurationFactory.java b/src/com/android/tradefed/config/SandboxConfigurationFactory.java
new file mode 100644
index 000000000..b4d06baea
--- /dev/null
+++ b/src/com/android/tradefed/config/SandboxConfigurationFactory.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 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.config;
+
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.sandbox.ISandbox;
+import com.android.tradefed.sandbox.SandboxConfigDump.DumpCmd;
+import com.android.tradefed.sandbox.SandboxConfigUtil;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.IRunUtil;
+import com.android.tradefed.util.keystore.IKeyStoreClient;
+
+import java.io.File;
+import java.util.Map;
+
+/** Special Configuration factory to handle creation of configurations for Sandboxing purpose. */
+public class SandboxConfigurationFactory extends ConfigurationFactory {
+
+ private static SandboxConfigurationFactory sInstance = null;
+
+ /** Get the singleton {@link IConfigurationFactory} instance. */
+ public static SandboxConfigurationFactory getInstance() {
+ if (sInstance == null) {
+ sInstance = new SandboxConfigurationFactory();
+ }
+ return sInstance;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ ConfigurationDef getConfigurationDef(
+ String name, boolean isGlobal, Map<String, String> templateMap)
+ throws ConfigurationException {
+ // TODO: Extend ConfigurationDef to possibly create a different IConfiguration type and
+ // handle more elegantly the parent/subprocess incompatibilities.
+ ConfigurationDef def = new ConfigurationDef(name);
+ new ConfigLoader(isGlobal).loadConfiguration(name, def, templateMap);
+ return def;
+ }
+
+ /**
+ * Create a {@link IConfiguration} based on the command line and sandbox provided.
+ *
+ * @param args the command line for the run.
+ * @param keyStoreClient the {@link IKeyStoreClient} where to load the key from.
+ * @param sandbox the {@link ISandbox} used for the run.
+ * @param runUtil the {@link IRunUtil} to run commands.
+ * @return a {@link IConfiguration} valid for the sandbox.
+ * @throws ConfigurationException
+ */
+ public IConfiguration createConfigurationFromArgs(
+ String[] args, IKeyStoreClient keyStoreClient, ISandbox sandbox, IRunUtil runUtil)
+ throws ConfigurationException {
+ IConfiguration config = null;
+ File xmlConfig = null;
+ try {
+ runUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
+ File tfDir = sandbox.getTradefedEnvironment(args);
+ // TODO: dump using the keystore too
+ xmlConfig =
+ SandboxConfigUtil.dumpConfigForVersion(
+ tfDir, runUtil, args, DumpCmd.NON_VERSIONED_CONFIG);
+ // Get the non version part of the configuration in order to do proper allocation
+ // of devices and such.
+ config =
+ super.createConfigurationFromArgs(
+ new String[] {xmlConfig.getAbsolutePath()}, null, keyStoreClient);
+ // Reset the command line to the original one.
+ config.setCommandLine(args);
+ config.setConfigurationObject(Configuration.SANDBOX_TYPE_NAME, sandbox);
+ } catch (ConfigurationException e) {
+ CLog.e(e);
+ sandbox.tearDown();
+ throw e;
+ } finally {
+ FileUtil.deleteFile(xmlConfig);
+ }
+ return config;
+ }
+}
diff --git a/src/com/android/tradefed/sandbox/SandboxConfigUtil.java b/src/com/android/tradefed/sandbox/SandboxConfigUtil.java
index e0c0159d2..5aaa4e71d 100644
--- a/src/com/android/tradefed/sandbox/SandboxConfigUtil.java
+++ b/src/com/android/tradefed/sandbox/SandboxConfigUtil.java
@@ -15,18 +15,13 @@
*/
package com.android.tradefed.sandbox;
-import com.android.tradefed.config.Configuration;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationFactory;
-import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.sandbox.SandboxConfigDump.DumpCmd;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.keystore.IKeyStoreClient;
import java.io.File;
import java.io.IOException;
@@ -75,44 +70,4 @@ public class SandboxConfigUtil {
FileUtil.deleteFile(destination);
throw new ConfigurationException(result.getStderr());
}
-
- /**
- * Create a {@link IConfiguration} based on the command line and sandbox provided.
- *
- * @param args the command line for the run.
- * @param sandbox the {@link ISandbox} used for the run.
- * @param configFactory the {@link IConfigurationFactory} used to load the config on parent side
- * @param keystore the {@link IKeyStoreClient} where to load the key from.
- * @return a {@link IConfiguration} valid for the sandbox.
- * @throws ConfigurationException
- */
- public static IConfiguration createSandboxConfiguration(
- String args[],
- ISandbox sandbox,
- IConfigurationFactory configFactory,
- IKeyStoreClient keystore)
- throws ConfigurationException {
- IConfiguration config = null;
- File xmlConfig = null;
- try {
- File tfDir = sandbox.getTradefedEnvironment(args);
- xmlConfig =
- dumpConfigForVersion(tfDir, new RunUtil(), args, DumpCmd.NON_VERSIONED_CONFIG);
- // Get the non version part of the configuration in order to do proper allocation
- // of devices and such.
- config =
- configFactory.createConfigurationFromArgs(
- new String[] {xmlConfig.getAbsolutePath()}, null, keystore);
- // Reset the command line to the original one.
- config.setCommandLine(args);
- config.setConfigurationObject(Configuration.SANDBOX_TYPE_NAME, sandbox);
- } catch (ConfigurationException e) {
- CLog.e(e);
- sandbox.tearDown();
- throw e;
- } finally {
- FileUtil.deleteFile(xmlConfig);
- }
- return config;
- }
}
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index 1b34b75ef..5b9e12e1f 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -45,6 +45,7 @@ import com.android.tradefed.config.GlobalConfigurationTest;
import com.android.tradefed.config.OptionCopierTest;
import com.android.tradefed.config.OptionSetterTest;
import com.android.tradefed.config.OptionUpdateRuleTest;
+import com.android.tradefed.config.SandboxConfigurationFactoryTest;
import com.android.tradefed.device.BackgroundDeviceActionTest;
import com.android.tradefed.device.CpuStatsCollectorTest;
import com.android.tradefed.device.DeviceManagerTest;
@@ -274,6 +275,7 @@ import org.junit.runners.Suite.SuiteClasses;
OptionCopierTest.class,
OptionSetterTest.class,
OptionUpdateRuleTest.class,
+ SandboxConfigurationFactoryTest.class,
// device
BackgroundDeviceActionTest.class,
diff --git a/tests/src/com/android/tradefed/config/SandboxConfigurationFactoryTest.java b/tests/src/com/android/tradefed/config/SandboxConfigurationFactoryTest.java
new file mode 100644
index 000000000..c61065c96
--- /dev/null
+++ b/tests/src/com/android/tradefed/config/SandboxConfigurationFactoryTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 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.config;
+
+import static org.easymock.EasyMock.eq;
+import static org.junit.Assert.*;
+
+import com.android.tradefed.sandbox.ISandbox;
+import com.android.tradefed.sandbox.SandboxConfigDump;
+import com.android.tradefed.sandbox.SandboxConfigDump.DumpCmd;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.IRunUtil;
+import com.android.tradefed.util.keystore.StubKeyStoreClient;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.io.IOException;
+
+/** Unit tests for {@link SandboxConfigurationFactory}. */
+@RunWith(JUnit4.class)
+public class SandboxConfigurationFactoryTest {
+
+ private SandboxConfigurationFactory mFactory;
+ private File mConfig;
+ private File mTmpEnvDir;
+ private ISandbox mFakeSandbox;
+ private IRunUtil mMockRunUtil;
+
+ @Before
+ public void setUp() throws IOException {
+ mFactory = SandboxConfigurationFactory.getInstance();
+ mConfig = FileUtil.createTempFile("sandbox-config-test", ".xml");
+ mTmpEnvDir = FileUtil.createTempDir("sandbox-tmp-dir");
+ mFakeSandbox = EasyMock.createMock(ISandbox.class);
+ mMockRunUtil = EasyMock.createMock(IRunUtil.class);
+ }
+
+ @After
+ public void tearDown() {
+ FileUtil.recursiveDelete(mTmpEnvDir);
+ FileUtil.deleteFile(mConfig);
+ }
+
+ private void expectDumpCmd(CommandResult res) {
+ EasyMock.expect(
+ mMockRunUtil.runTimedCmd(
+ EasyMock.anyLong(),
+ eq("java"),
+ eq("-cp"),
+ eq(new File(mTmpEnvDir, "*").getAbsolutePath()),
+ eq(SandboxConfigDump.class.getCanonicalName()),
+ eq(DumpCmd.NON_VERSIONED_CONFIG.toString()),
+ EasyMock.anyObject(),
+ eq(mConfig.getAbsolutePath())))
+ .andAnswer(
+ new IAnswer<CommandResult>() {
+ @Override
+ public CommandResult answer() throws Throwable {
+ String resFile = (String) EasyMock.getCurrentArguments()[6];
+ FileUtil.writeToFile(
+ "<configuration><test class=\"com.android.tradefed.test"
+ + "type.StubTest\" /></configuration>",
+ new File(resFile));
+ return res;
+ }
+ });
+ }
+
+ /**
+ * Test that creating a configuration using a sandbox properly create a {@link IConfiguration}.
+ */
+ @Test
+ public void testCreateConfigurationFromArgs() throws ConfigurationException {
+ String[] args = new String[] {mConfig.getAbsolutePath()};
+ EasyMock.expect(mFakeSandbox.getTradefedEnvironment(EasyMock.anyObject()))
+ .andReturn(mTmpEnvDir);
+ mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
+ CommandResult results = new CommandResult();
+ results.setStatus(CommandStatus.SUCCESS);
+ expectDumpCmd(results);
+ EasyMock.replay(mFakeSandbox, mMockRunUtil);
+ IConfiguration config =
+ mFactory.createConfigurationFromArgs(
+ args, new StubKeyStoreClient(), mFakeSandbox, mMockRunUtil);
+ EasyMock.verify(mFakeSandbox, mMockRunUtil);
+ assertNotNull(config.getConfigurationObject(Configuration.SANDBOX_TYPE_NAME));
+ assertEquals(mFakeSandbox, config.getConfigurationObject(Configuration.SANDBOX_TYPE_NAME));
+ }
+
+ /** Test that when the dump config failed, we throw a ConfigurationException. */
+ @Test
+ public void testCreateConfigurationFromArgs_fail() throws ConfigurationException {
+ String[] args = new String[] {mConfig.getAbsolutePath()};
+ EasyMock.expect(mFakeSandbox.getTradefedEnvironment(EasyMock.anyObject()))
+ .andReturn(mTmpEnvDir);
+ mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
+ CommandResult results = new CommandResult();
+ results.setStatus(CommandStatus.FAILED);
+ results.setStderr("I failed");
+ expectDumpCmd(results);
+ // in case of failure, tearDown is called right away for cleaning up
+ mFakeSandbox.tearDown();
+ EasyMock.replay(mFakeSandbox, mMockRunUtil);
+ try {
+ mFactory.createConfigurationFromArgs(
+ args, new StubKeyStoreClient(), mFakeSandbox, mMockRunUtil);
+ fail("Should have thrown an exception.");
+ } catch (ConfigurationException expected) {
+ // expected
+ }
+ EasyMock.verify(mFakeSandbox, mMockRunUtil);
+ }
+}