• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.sandbox;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 
24 import com.android.tradefed.command.CommandOptions;
25 import com.android.tradefed.config.Configuration;
26 import com.android.tradefed.config.ConfigurationDescriptor;
27 import com.android.tradefed.config.ConfigurationException;
28 import com.android.tradefed.config.GlobalConfiguration;
29 import com.android.tradefed.config.IConfiguration;
30 import com.android.tradefed.config.OptionSetter;
31 import com.android.tradefed.invoker.IInvocationContext;
32 import com.android.tradefed.invoker.InvocationContext;
33 import com.android.tradefed.result.ITestInvocationListener;
34 import com.android.tradefed.result.LogDataType;
35 import com.android.tradefed.util.CommandResult;
36 import com.android.tradefed.util.CommandStatus;
37 import com.android.tradefed.util.FileUtil;
38 import com.android.tradefed.util.IRunUtil;
39 import com.android.tradefed.util.IRunUtil.EnvPriority;
40 
41 import org.easymock.EasyMock;
42 import org.junit.After;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.junit.runners.JUnit4;
47 
48 import java.io.File;
49 
50 /** Unit tests for {@link com.android.tradefed.sandbox.TradefedSandbox}. */
51 @RunWith(JUnit4.class)
52 public class TradefedSandboxTest {
53     private static final String TF_JAR_DIR = "TF_JAR_DIR";
54     private String mCachedProperty;
55     private File mTmpFolder;
56 
57     private TradefedSandbox mSandbox;
58     private ITestInvocationListener mMockListener;
59     private IConfiguration mMockConfig;
60     private IInvocationContext mMockContext;
61     private IRunUtil mMockRunUtil;
62 
63     @Before
setUp()64     public void setUp() throws Exception {
65         mMockRunUtil = EasyMock.createMock(IRunUtil.class);
66         mSandbox =
67                 new TradefedSandbox() {
68                     @Override
69                     IRunUtil createRunUtil() {
70                         return mMockRunUtil;
71                     }
72                 };
73         mMockListener = EasyMock.createMock(ITestInvocationListener.class);
74         mMockConfig = EasyMock.createMock(IConfiguration.class);
75         EasyMock.expect(mMockConfig.getConfigurationObject(Configuration.SANBOX_OPTIONS_TYPE_NAME))
76                 .andStubReturn(new SandboxOptions());
77         mMockContext = new InvocationContext();
78         mMockContext.setConfigurationDescriptor(new ConfigurationDescriptor());
79 
80         mTmpFolder = FileUtil.createTempDir("tmp-tf-jar-dir");
81 
82         if (System.getProperty(TF_JAR_DIR) != null) {
83             mCachedProperty = System.getProperty(TF_JAR_DIR);
84         }
85         System.setProperty(TF_JAR_DIR, mTmpFolder.getAbsolutePath());
86         try {
87             GlobalConfiguration.createGlobalConfiguration(new String[] {});
88         } catch (IllegalStateException ignore) {
89             // ignore the global config re-init
90         }
91     }
92 
93     @After
tearDown()94     public void tearDown() {
95         if (mCachedProperty != null) {
96             System.setProperty(TF_JAR_DIR, mCachedProperty);
97         }
98         FileUtil.recursiveDelete(mTmpFolder);
99         mSandbox.tearDown();
100     }
101 
102     /**
103      * Test a case where the {@link
104      * com.android.tradefed.sandbox.TradefedSandbox#prepareEnvironment(IInvocationContext,
105      * IConfiguration, ITestInvocationListener)} succeed and does not have any exception.
106      */
107     @Test
testPrepareEnvironment()108     public void testPrepareEnvironment() throws Exception {
109         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
110         EasyMock.expectLastCall().times(2);
111         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_SERVER_CONFIG_VARIABLE);
112         EasyMock.expectLastCall().times(2);
113         mMockRunUtil.setEnvVariable(
114                 EasyMock.eq(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE), EasyMock.anyObject());
115         mMockRunUtil.setEnvVariablePriority(EnvPriority.SET);
116         mMockListener.testLog(
117                 EasyMock.eq("sandbox-global-config"),
118                 EasyMock.eq(LogDataType.XML),
119                 EasyMock.anyObject());
120         CommandResult result = new CommandResult();
121         result.setStatus(CommandStatus.SUCCESS);
122         EasyMock.expect(
123                         mMockRunUtil.runTimedCmd(
124                                 EasyMock.anyLong(),
125                                 EasyMock.eq("java"),
126                                 EasyMock.eq("-cp"),
127                                 EasyMock.anyObject(),
128                                 EasyMock.eq(SandboxConfigDump.class.getCanonicalName()),
129                                 EasyMock.eq("RUN_CONFIG"),
130                                 EasyMock.anyObject(),
131                                 EasyMock.eq("empty"),
132                                 EasyMock.eq("--arg"),
133                                 EasyMock.eq("1"),
134                                 EasyMock.eq("--use-proto-reporter")))
135                 .andReturn(result);
136         setPrepareConfigurationExpectations();
137         EasyMock.replay(mMockConfig, mMockListener, mMockRunUtil);
138         Exception res = mSandbox.prepareEnvironment(mMockContext, mMockConfig, mMockListener);
139         EasyMock.verify(mMockConfig, mMockListener, mMockRunUtil);
140         assertNull(res);
141     }
142 
143     /**
144      * Test a case where the {@link
145      * com.android.tradefed.sandbox.TradefedSandbox#prepareEnvironment(IInvocationContext,
146      * IConfiguration, ITestInvocationListener)} fails to dump the configuration, in that case the
147      * std err from the dump utility is used for the exception.
148      */
149     @Test
testPrepareEnvironment_dumpConfigFail()150     public void testPrepareEnvironment_dumpConfigFail() throws Exception {
151         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
152         EasyMock.expectLastCall().times(2);
153         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_SERVER_CONFIG_VARIABLE);
154         EasyMock.expectLastCall().times(2);
155         mMockRunUtil.setEnvVariable(
156                 EasyMock.eq(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE), EasyMock.anyObject());
157         mMockRunUtil.setEnvVariablePriority(EnvPriority.SET);
158         mMockListener.testLog(
159                 EasyMock.eq("sandbox-global-config"),
160                 EasyMock.eq(LogDataType.XML),
161                 EasyMock.anyObject());
162         CommandResult result = new CommandResult();
163         result.setStatus(CommandStatus.FAILED);
164         result.setStderr("Ouch I failed.");
165         EasyMock.expect(
166                         mMockRunUtil.runTimedCmd(
167                                 EasyMock.anyLong(),
168                                 EasyMock.eq("java"),
169                                 EasyMock.eq("-cp"),
170                                 EasyMock.anyObject(),
171                                 EasyMock.eq(SandboxConfigDump.class.getCanonicalName()),
172                                 EasyMock.eq("RUN_CONFIG"),
173                                 EasyMock.anyObject(),
174                                 EasyMock.eq("empty"),
175                                 EasyMock.eq("--arg"),
176                                 EasyMock.eq("1"),
177                                 EasyMock.eq("--use-proto-reporter")))
178                 .andReturn(result);
179         setPrepareConfigurationExpectations();
180         EasyMock.replay(mMockConfig, mMockListener, mMockRunUtil);
181         Exception res = mSandbox.prepareEnvironment(mMockContext, mMockConfig, mMockListener);
182         EasyMock.verify(mMockConfig, mMockListener, mMockRunUtil);
183         assertNotNull(res);
184         assertTrue(res instanceof ConfigurationException);
185         assertEquals("Error when dumping the config. stderr: Ouch I failed.", res.getMessage());
186     }
187 
188     /**
189      * Test a case where the {@link
190      * com.android.tradefed.sandbox.TradefedSandbox#prepareEnvironment(IInvocationContext,
191      * IConfiguration, ITestInvocationListener)} throws an exception because TF_JAR_DIR was not set.
192      */
193     @Test
testPrepareEnvironment_noTfDirJar()194     public void testPrepareEnvironment_noTfDirJar() throws Exception {
195         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_VARIABLE);
196         mMockRunUtil.unsetEnvVariable(GlobalConfiguration.GLOBAL_CONFIG_SERVER_CONFIG_VARIABLE);
197         EasyMock.expect(mMockConfig.getCommandLine()).andReturn("empty --arg 1");
198         EasyMock.expect(mMockConfig.getCommandOptions()).andStubReturn(new CommandOptions());
199         System.setProperty(TF_JAR_DIR, "");
200         EasyMock.replay(mMockConfig, mMockListener, mMockRunUtil);
201         Exception res = mSandbox.prepareEnvironment(mMockContext, mMockConfig, mMockListener);
202         EasyMock.verify(mMockConfig, mMockListener, mMockRunUtil);
203         assertNotNull(res);
204         assertTrue(res instanceof ConfigurationException);
205         assertEquals(
206                 "Could not read TF_JAR_DIR to get current Tradefed instance.", res.getMessage());
207     }
208 
setPrepareConfigurationExpectations()209     private void setPrepareConfigurationExpectations() throws Exception {
210         EasyMock.expect(mMockConfig.getCommandLine()).andReturn("empty --arg 1").times(2);
211         EasyMock.expect(mMockConfig.getCommandOptions()).andStubReturn(new CommandOptions());
212     }
213 
214     /**
215      * Test that when the sandbox option received a TF location, it uses it instead of the current
216      * one.
217      */
218     @Test
testSandboxOptions()219     public void testSandboxOptions() throws Exception {
220         File tmpDir = FileUtil.createTempDir("tmp-sandbox-dir");
221         try {
222             mMockConfig = new Configuration("NAME", "DESC");
223             mMockConfig.setCommandLine(new String[] {"empty", "--arg", "1"});
224             SandboxOptions options = new SandboxOptions();
225             OptionSetter setter = new OptionSetter(options);
226             setter.setOptionValue("sandbox:tf-location", tmpDir.getAbsolutePath());
227             mMockConfig.setConfigurationObject(Configuration.SANBOX_OPTIONS_TYPE_NAME, options);
228 
229             EasyMock.replay(mMockListener, mMockRunUtil);
230             File res =
231                     mSandbox.getTradefedSandboxEnvironment(
232                             mMockContext, mMockConfig, new String[] {"empty", "--arg", "1"});
233             EasyMock.verify(mMockListener, mMockRunUtil);
234             assertEquals(tmpDir, res);
235         } finally {
236             FileUtil.recursiveDelete(tmpDir);
237         }
238     }
239 
240     /**
241      * Test that when the sandbox option received a TF location and a build id at the same time that
242      * it is rejected, because that combination is not supported.
243      */
244     @Test
testSandboxOptions_exclusion()245     public void testSandboxOptions_exclusion() throws Exception {
246         File tmpDir = FileUtil.createTempDir("tmp-sandbox-dir");
247         try {
248             mMockConfig = new Configuration("NAME", "DESC");
249             mMockConfig.setCommandLine(new String[] {"empty", "--arg", "1"});
250             SandboxOptions options = new SandboxOptions();
251             OptionSetter setter = new OptionSetter(options);
252             setter.setOptionValue("sandbox:tf-location", tmpDir.getAbsolutePath());
253             setter.setOptionValue("sandbox:sandbox-build-id", "9999");
254             mMockConfig.setConfigurationObject(Configuration.SANBOX_OPTIONS_TYPE_NAME, options);
255 
256             EasyMock.replay(mMockListener, mMockRunUtil);
257             try {
258                 mSandbox.getTradefedSandboxEnvironment(
259                         mMockContext, mMockConfig, new String[] {"empty", "--arg", "1"});
260                 fail("Should have thrown an exception.");
261             } catch (ConfigurationException expected) {
262                 assertEquals(
263                         "Sandbox options tf-location and sandbox-build-id cannot be set at "
264                                 + "the same time",
265                         expected.getMessage());
266             }
267             EasyMock.verify(mMockListener, mMockRunUtil);
268         } finally {
269             FileUtil.recursiveDelete(tmpDir);
270         }
271     }
272 }
273