1 /* 2 * Copyright (C) 2010 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; 17 18 import static org.mockito.Mockito.doReturn; 19 20 import com.android.ddmlib.IDevice; 21 import com.android.tradefed.build.BuildInfo; 22 import com.android.tradefed.build.BuildInfoKey.BuildInfoFileKey; 23 import com.android.tradefed.build.BuildRetrievalError; 24 import com.android.tradefed.build.IBuildInfo; 25 import com.android.tradefed.build.IBuildInfo.BuildInfoProperties; 26 import com.android.tradefed.build.IBuildProvider; 27 import com.android.tradefed.build.IDeviceBuildInfo; 28 import com.android.tradefed.build.IDeviceBuildProvider; 29 import com.android.tradefed.command.CommandOptions; 30 import com.android.tradefed.command.CommandRunner.ExitCode; 31 import com.android.tradefed.command.FatalHostError; 32 import com.android.tradefed.command.ICommandOptions; 33 import com.android.tradefed.command.remote.DeviceDescriptor; 34 import com.android.tradefed.config.Configuration; 35 import com.android.tradefed.config.ConfigurationDef; 36 import com.android.tradefed.config.DeviceConfigurationHolder; 37 import com.android.tradefed.config.IConfiguration; 38 import com.android.tradefed.config.IConfigurationFactory; 39 import com.android.tradefed.config.IDeviceConfiguration; 40 import com.android.tradefed.config.Option; 41 import com.android.tradefed.config.OptionSetter; 42 import com.android.tradefed.device.DeviceAllocationState; 43 import com.android.tradefed.device.DeviceNotAvailableException; 44 import com.android.tradefed.device.IDeviceRecovery; 45 import com.android.tradefed.device.INativeDevice; 46 import com.android.tradefed.device.ITestDevice; 47 import com.android.tradefed.device.ITestDevice.RecoveryMode; 48 import com.android.tradefed.device.StubDevice; 49 import com.android.tradefed.device.TestDeviceOptions; 50 import com.android.tradefed.device.metric.BaseDeviceMetricCollector; 51 import com.android.tradefed.device.metric.DeviceMetricData; 52 import com.android.tradefed.device.metric.IMetricCollector; 53 import com.android.tradefed.guice.InvocationScope; 54 import com.android.tradefed.invoker.shard.IShardHelper; 55 import com.android.tradefed.invoker.shard.ShardHelper; 56 import com.android.tradefed.invoker.shard.StrictShardHelper; 57 import com.android.tradefed.log.ILeveledLogOutput; 58 import com.android.tradefed.log.ILogRegistry; 59 import com.android.tradefed.metrics.proto.MetricMeasurement.Measurements; 60 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 61 import com.android.tradefed.result.ByteArrayInputStreamSource; 62 import com.android.tradefed.result.ILogSaver; 63 import com.android.tradefed.result.ILogSaverListener; 64 import com.android.tradefed.result.ITestInvocationListener; 65 import com.android.tradefed.result.ITestSummaryListener; 66 import com.android.tradefed.result.InputStreamSource; 67 import com.android.tradefed.result.InvocationStatus; 68 import com.android.tradefed.result.LogDataType; 69 import com.android.tradefed.result.LogFile; 70 import com.android.tradefed.result.TestDescription; 71 import com.android.tradefed.result.TestSummary; 72 import com.android.tradefed.targetprep.BuildError; 73 import com.android.tradefed.targetprep.ITargetCleaner; 74 import com.android.tradefed.targetprep.ITargetPreparer; 75 import com.android.tradefed.testtype.IDeviceTest; 76 import com.android.tradefed.testtype.IInvocationContextReceiver; 77 import com.android.tradefed.testtype.IRemoteTest; 78 import com.android.tradefed.testtype.IResumableTest; 79 import com.android.tradefed.testtype.IRetriableTest; 80 import com.android.tradefed.testtype.IShardableTest; 81 import com.android.tradefed.testtype.IStrictShardableTest; 82 import com.android.tradefed.testtype.StubTest; 83 import com.android.tradefed.util.FileUtil; 84 import com.android.tradefed.util.SystemUtil.EnvVariable; 85 86 import com.google.common.util.concurrent.SettableFuture; 87 88 import junit.framework.Test; 89 import junit.framework.TestCase; 90 91 import org.easymock.Capture; 92 import org.easymock.EasyMock; 93 import org.mockito.Mockito; 94 95 import java.io.File; 96 import java.io.IOException; 97 import java.io.InputStream; 98 import java.util.ArrayList; 99 import java.util.Collections; 100 import java.util.HashMap; 101 import java.util.HashSet; 102 import java.util.List; 103 import java.util.Map; 104 import java.util.Set; 105 106 /** Unit tests for {@link TestInvocation}. */ 107 @SuppressWarnings("MustBeClosedChecker") 108 public class TestInvocationTest extends TestCase { 109 110 private static final String SERIAL = "serial"; 111 private static final Map<String, String> EMPTY_MAP = Collections.emptyMap(); 112 private static final String PATH = "path"; 113 private static final String URL = "url"; 114 private static final TestSummary mSummary = new TestSummary("http://www.url.com/report.txt"); 115 private static final InputStreamSource EMPTY_STREAM_SOURCE = 116 new ByteArrayInputStreamSource(new byte[0]); 117 private static final String LOGCAT_NAME_ERROR = 118 TestInvocation.getDeviceLogName(TestInvocation.Stage.ERROR); 119 private static final String LOGCAT_NAME_SETUP = 120 TestInvocation.getDeviceLogName(TestInvocation.Stage.SETUP); 121 private static final String LOGCAT_NAME_TEST = 122 TestInvocation.getDeviceLogName(TestInvocation.Stage.TEST); 123 private static final String LOGCAT_NAME_TEARDOWN = 124 TestInvocation.getDeviceLogName(TestInvocation.Stage.TEARDOWN); 125 /** The {@link TestInvocation} under test, with all dependencies mocked out */ 126 private TestInvocation mTestInvocation; 127 128 private IConfiguration mStubConfiguration; 129 private IConfiguration mStubMultiConfiguration; 130 131 private IInvocationContext mStubInvocationMetadata; 132 133 // The mock objects. 134 private ITestDevice mMockDevice; 135 private ITargetPreparer mMockPreparer; 136 private IBuildProvider mMockBuildProvider; 137 private IBuildInfo mMockBuildInfo; 138 private ITestInvocationListener mMockTestListener; 139 private ITestSummaryListener mMockSummaryListener; 140 private ILeveledLogOutput mMockLogger; 141 private ILogSaver mMockLogSaver; 142 private IDeviceRecovery mMockRecovery; 143 private Capture<List<TestSummary>> mUriCapture; 144 private ILogRegistry mMockLogRegistry; 145 private IConfigurationFactory mMockConfigFactory; 146 private IRescheduler mockRescheduler; 147 private DeviceDescriptor mFakeDescriptor; 148 149 @Override 150 protected void setUp() throws Exception { 151 super.setUp(); 152 153 mStubConfiguration = new Configuration("foo", "bar"); 154 mStubMultiConfiguration = new Configuration("foo", "bar"); 155 156 mMockDevice = EasyMock.createMock(ITestDevice.class); 157 mMockRecovery = EasyMock.createMock(IDeviceRecovery.class); 158 mMockPreparer = EasyMock.createMock(ITargetPreparer.class); 159 mMockBuildProvider = EasyMock.createMock(IBuildProvider.class); 160 161 // Use strict mocks here since the order of Listener calls is important 162 mMockTestListener = EasyMock.createStrictMock(ITestInvocationListener.class); 163 mMockSummaryListener = EasyMock.createStrictMock(ITestSummaryListener.class); 164 mMockBuildInfo = EasyMock.createMock(IBuildInfo.class); 165 mMockLogger = EasyMock.createMock(ILeveledLogOutput.class); 166 mMockLogRegistry = EasyMock.createMock(ILogRegistry.class); 167 mMockLogSaver = EasyMock.createMock(ILogSaver.class); 168 mMockConfigFactory = EasyMock.createMock(IConfigurationFactory.class); 169 mockRescheduler = EasyMock.createMock(IRescheduler.class); 170 171 mStubConfiguration.setDeviceRecovery(mMockRecovery); 172 mStubConfiguration.setTargetPreparer(mMockPreparer); 173 mStubConfiguration.setBuildProvider(mMockBuildProvider); 174 175 EasyMock.expect(mMockPreparer.isDisabled()).andStubReturn(false); 176 EasyMock.expect(mMockPreparer.isTearDownDisabled()).andStubReturn(false); 177 178 List<IDeviceConfiguration> deviceConfigs = new ArrayList<IDeviceConfiguration>(); 179 IDeviceConfiguration device1 = 180 new DeviceConfigurationHolder(ConfigurationDef.DEFAULT_DEVICE_NAME); 181 device1.addSpecificConfig(mMockRecovery); 182 device1.addSpecificConfig(mMockPreparer); 183 device1.addSpecificConfig(mMockBuildProvider); 184 deviceConfigs.add(device1); 185 mStubMultiConfiguration.setDeviceConfigList(deviceConfigs); 186 187 mStubConfiguration.setLogSaver(mMockLogSaver); 188 mStubMultiConfiguration.setLogSaver(mMockLogSaver); 189 190 List<ITestInvocationListener> listenerList = new ArrayList<ITestInvocationListener>(1); 191 listenerList.add(mMockTestListener); 192 listenerList.add(mMockSummaryListener); 193 mStubConfiguration.setTestInvocationListeners(listenerList); 194 mStubMultiConfiguration.setTestInvocationListeners(listenerList); 195 196 mStubConfiguration.setLogOutput(mMockLogger); 197 mStubMultiConfiguration.setLogOutput(mMockLogger); 198 EasyMock.expect(mMockDevice.getSerialNumber()).andStubReturn(SERIAL); 199 EasyMock.expect(mMockDevice.getIDevice()).andStubReturn(null); 200 mMockDevice.setRecovery(mMockRecovery); 201 mMockDevice.preInvocationSetup((IBuildInfo)EasyMock.anyObject()); 202 EasyMock.expectLastCall().anyTimes(); 203 mMockDevice.postInvocationTearDown(); 204 EasyMock.expectLastCall().anyTimes(); 205 mFakeDescriptor = new DeviceDescriptor(SERIAL, false, DeviceAllocationState.Available, 206 "unknown", "unknown", "unknown", "unknown", "unknown"); 207 EasyMock.expect(mMockDevice.getDeviceDescriptor()).andStubReturn(mFakeDescriptor); 208 209 EasyMock.expect(mMockBuildInfo.getBuildId()).andStubReturn("1"); 210 EasyMock.expect(mMockBuildInfo.getBuildAttributes()).andStubReturn(EMPTY_MAP); 211 EasyMock.expect(mMockBuildInfo.getBuildBranch()).andStubReturn("branch"); 212 EasyMock.expect(mMockBuildInfo.getBuildFlavor()).andStubReturn("flavor"); 213 EasyMock.expect(mMockBuildInfo.getProperties()).andStubReturn(new HashSet<>()); 214 215 // always expect logger initialization and cleanup calls 216 mMockLogRegistry.registerLogger(mMockLogger); 217 mMockLogger.init(); 218 mMockLogger.closeLog(); 219 mMockLogRegistry.unregisterLogger(); 220 mUriCapture = new Capture<List<TestSummary>>(); 221 222 mStubInvocationMetadata = new InvocationContext(); 223 mStubInvocationMetadata.addAllocatedDevice(ConfigurationDef.DEFAULT_DEVICE_NAME, 224 mMockDevice); 225 mStubInvocationMetadata.addDeviceBuildInfo(ConfigurationDef.DEFAULT_DEVICE_NAME, 226 mMockBuildInfo); 227 228 // create the BaseTestInvocation to test 229 mTestInvocation = 230 new TestInvocation() { 231 @Override 232 ILogRegistry getLogRegistry() { 233 return mMockLogRegistry; 234 } 235 236 @Override 237 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 238 return new InvocationExecution() { 239 @Override 240 protected IShardHelper createShardHelper() { 241 return new ShardHelper(); 242 } 243 }; 244 } 245 246 @Override 247 protected void setExitCode(ExitCode code, Throwable stack) { 248 // empty on purpose 249 } 250 251 @Override 252 InvocationScope getInvocationScope() { 253 // Avoid re-entry in the current TF invocation scope for unit tests. 254 return new InvocationScope(); 255 } 256 }; 257 } 258 259 @Override 260 protected void tearDown() throws Exception { 261 super.tearDown(); 262 263 } 264 265 /** 266 * Test the normal case invoke scenario with a {@link IRemoteTest}. 267 * <p/> 268 * Verifies that all external interfaces get notified as expected. 269 */ 270 public void testInvoke_RemoteTest() throws Throwable { 271 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 272 setupMockSuccessListeners(); 273 274 test.run((ITestInvocationListener)EasyMock.anyObject()); 275 setupNormalInvoke(test); 276 EasyMock.replay(mockRescheduler); 277 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 278 verifyMocks(test, mockRescheduler); 279 verifySummaryListener(); 280 } 281 282 /** 283 * Test the normal case for multi invoke scenario with a {@link IRemoteTest}. 284 * <p/> 285 * Verifies that all external interfaces get notified as expected. 286 */ 287 public void testInvokeMulti_RemoteTest() throws Throwable { 288 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 289 setupMockSuccessListeners(); 290 291 test.run((ITestInvocationListener)EasyMock.anyObject()); 292 setupNormalInvoke(test); 293 EasyMock.replay(mockRescheduler); 294 mTestInvocation.invoke(mStubInvocationMetadata, mStubMultiConfiguration, mockRescheduler); 295 verifyMocks(test, mockRescheduler); 296 verifySummaryListener(); 297 } 298 299 /** 300 * Test the normal case invoke scenario with an {@link ITestSummaryListener} masquerading as 301 * an {@link ITestInvocationListener}. 302 * <p/> 303 * Verifies that all external interfaces get notified as expected. 304 */ 305 public void testInvoke_twoSummary() throws Throwable { 306 307 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 308 setupMockSuccessListeners(); 309 310 test.run((ITestInvocationListener)EasyMock.anyObject()); 311 setupNormalInvoke(test); 312 EasyMock.replay(mockRescheduler); 313 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 314 verifyMocks(test, mockRescheduler); 315 verifySummaryListener(); 316 } 317 318 /** 319 * Test the invoke scenario where build retrieve fails. 320 * <p/> 321 * An invocation will be started in this scenario. 322 */ 323 public void testInvoke_buildFailed() throws Throwable { 324 BuildRetrievalError exception = new BuildRetrievalError("error", null, mMockBuildInfo); 325 EasyMock.expect(mMockBuildProvider.getBuild()).andThrow(exception); 326 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(null); 327 setupMockFailureListeners(exception); 328 setupInvoke(); 329 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 330 CommandOptions cmdOptions = new CommandOptions(); 331 final String expectedTestTag = "TEST_TAG"; 332 cmdOptions.setTestTag(expectedTestTag); 333 mStubConfiguration.setCommandOptions(cmdOptions); 334 mStubConfiguration.setTest(test); 335 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 336 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(2); 337 mMockDevice.clearLogcat(); 338 EasyMock.expectLastCall().times(2); 339 mMockLogRegistry.unregisterLogger(); 340 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 341 mMockLogger.closeLog(); 342 mMockBuildProvider.cleanUp(mMockBuildInfo); 343 replayMocks(test, mockRescheduler); 344 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 345 verifyMocks(test, mockRescheduler); 346 // invocation test tag was updated. 347 assertEquals(expectedTestTag, mStubInvocationMetadata.getTestTag()); 348 } 349 350 /** 351 * Test the invoke scenario where there is no build to test. 352 */ 353 public void testInvoke_noBuild() throws Throwable { 354 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(null); 355 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 356 mStubConfiguration.setTest(test); 357 mMockBuildProvider.cleanUp(mMockBuildInfo); 358 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 359 setupInvoke(); 360 replayMocks(test, mockRescheduler); 361 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 362 verifyMocks(test); 363 } 364 365 /** 366 * Test the invoke scenario where there is no build to test for a {@link IRetriableTest}. 367 */ 368 public void testInvoke_noBuildRetry() throws Throwable { 369 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(null); 370 371 IRetriableTest test = EasyMock.createMock(IRetriableTest.class); 372 EasyMock.expect(test.isRetriable()).andReturn(Boolean.TRUE); 373 374 EasyMock.expect(mockRescheduler.rescheduleCommand()).andReturn(EasyMock.anyBoolean()); 375 376 mStubConfiguration.setTest(test); 377 mStubConfiguration.getCommandOptions().setLoopMode(false); 378 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 379 EasyMock.expectLastCall().times(1); 380 setupInvoke(); 381 mMockBuildProvider.cleanUp(mMockBuildInfo); 382 replayMocks(test); 383 EasyMock.replay(mockRescheduler); 384 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 385 EasyMock.verify(mockRescheduler); 386 verifyMocks(test); 387 } 388 389 /** 390 * Test the{@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 391 * ITestInvocationListener[])} scenario 392 * where the test is a {@link IDeviceTest} 393 */ 394 public void testInvoke_deviceTest() throws Throwable { 395 DeviceConfigTest mockDeviceTest = EasyMock.createMock(DeviceConfigTest.class); 396 mStubConfiguration.setTest(mockDeviceTest); 397 mockDeviceTest.setDevice(mMockDevice); 398 mockDeviceTest.run((ITestInvocationListener)EasyMock.anyObject()); 399 setupMockSuccessListeners(); 400 setupNormalInvoke(mockDeviceTest); 401 EasyMock.replay(mockRescheduler); 402 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 403 verifyMocks(mockDeviceTest, mockRescheduler); 404 verifySummaryListener(); 405 } 406 407 /** 408 * Test the invoke scenario where test run throws {@link IllegalArgumentException} 409 * 410 * @throws Exception if unexpected error occurs 411 */ 412 public void testInvoke_testFail() throws Throwable { 413 IllegalArgumentException exception = new IllegalArgumentException(); 414 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 415 test.run((ITestInvocationListener)EasyMock.anyObject()); 416 EasyMock.expectLastCall().andThrow(exception); 417 setupMockFailureListeners(exception); 418 mMockBuildProvider.buildNotTested(mMockBuildInfo); 419 setupNormalInvoke(test); 420 EasyMock.replay(mockRescheduler); 421 try { 422 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 423 fail("IllegalArgumentException was not rethrown"); 424 } catch (IllegalArgumentException e) { 425 // expected 426 } 427 verifyMocks(test, mockRescheduler); 428 verifySummaryListener(); 429 } 430 431 /** 432 * Test the invoke scenario where test run throws {@link FatalHostError} 433 * 434 * @throws Exception if unexpected error occurs 435 */ 436 public void testInvoke_fatalError() throws Throwable { 437 FatalHostError exception = new FatalHostError("error"); 438 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 439 test.run((ITestInvocationListener)EasyMock.anyObject()); 440 EasyMock.expectLastCall().andThrow(exception); 441 setupMockFailureListeners(exception); 442 mMockBuildProvider.buildNotTested(mMockBuildInfo); 443 setupNormalInvoke(test); 444 EasyMock.replay(mockRescheduler); 445 try { 446 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 447 fail("FatalHostError was not rethrown"); 448 } catch (FatalHostError e) { 449 // expected 450 } 451 verifyMocks(test, mockRescheduler); 452 verifySummaryListener(); 453 } 454 455 /** 456 * Test the invoke scenario where test run throws {@link DeviceNotAvailableException} 457 * 458 * @throws Exception if unexpected error occurs 459 */ 460 public void testInvoke_deviceNotAvail() throws Throwable { 461 DeviceNotAvailableException exception = new DeviceNotAvailableException("ERROR", SERIAL); 462 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 463 test.run((ITestInvocationListener)EasyMock.anyObject()); 464 EasyMock.expectLastCall().andThrow(exception); 465 mMockDevice.setRecoveryMode(RecoveryMode.NONE); 466 EasyMock.expectLastCall(); 467 setupMockFailureListeners(exception); 468 mMockBuildProvider.buildNotTested(mMockBuildInfo); 469 setupNormalInvoke(test); 470 EasyMock.replay(mockRescheduler); 471 try { 472 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 473 fail("DeviceNotAvailableException not thrown"); 474 } catch (DeviceNotAvailableException e) { 475 // expected 476 } 477 verifyMocks(test, mockRescheduler); 478 verifySummaryListener(); 479 } 480 481 /** 482 * Test the invoke scenario where preparer throws {@link BuildError} 483 * 484 * @throws Exception if unexpected error occurs 485 */ 486 public void testInvoke_buildError() throws Throwable { 487 BuildError exception = new BuildError("error", mFakeDescriptor); 488 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 489 mStubConfiguration.setTest(test); 490 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 491 492 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 493 EasyMock.expectLastCall().andThrow(exception); 494 setupMockFailureListeners(exception); 495 EasyMock.expect(mMockDevice.getBugreport()).andReturn(EMPTY_STREAM_SOURCE); 496 setupInvokeWithBuild(); 497 replayMocks(test); 498 EasyMock.replay(mockRescheduler); 499 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 500 verifyMocks(test, mockRescheduler); 501 verifySummaryListener(); 502 } 503 504 /** 505 * Test the invoke scenario for a {@link IResumableTest}. 506 * 507 * @throws Exception if unexpected error occurs 508 */ 509 public void testInvoke_resume() throws Throwable { 510 IResumableTest resumableTest = EasyMock.createMock(IResumableTest.class); 511 mStubConfiguration.setTest(resumableTest); 512 ITestInvocationListener resumeListener = EasyMock.createStrictMock( 513 ITestInvocationListener.class); 514 mStubConfiguration.setTestInvocationListener(resumeListener); 515 516 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 517 resumeListener.invocationStarted(mStubInvocationMetadata); 518 mMockDevice.clearLastConnectedWifiNetwork(); 519 mMockDevice.setOptions((TestDeviceOptions)EasyMock.anyObject()); 520 mMockBuildInfo.setDeviceSerial(SERIAL); 521 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(""); 522 mMockDevice.startLogcat(); 523 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 524 525 resumableTest.run((ITestInvocationListener) EasyMock.anyObject()); 526 EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException("ERROR", SERIAL)); 527 EasyMock.expect(resumableTest.isResumable()).andReturn(Boolean.TRUE); 528 mMockDevice.setRecoveryMode(RecoveryMode.NONE); 529 EasyMock.expectLastCall(); 530 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 531 mMockDevice.clearLogcat(); 532 EasyMock.expectLastCall().times(3); 533 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 534 EasyMock.expect( 535 mMockLogSaver.saveLogData( 536 EasyMock.eq(LOGCAT_NAME_SETUP), 537 EasyMock.eq(LogDataType.LOGCAT), 538 (InputStream) EasyMock.anyObject())) 539 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 540 EasyMock.expect( 541 mMockLogSaver.saveLogData( 542 EasyMock.eq(LOGCAT_NAME_TEST), 543 EasyMock.eq(LogDataType.LOGCAT), 544 (InputStream) EasyMock.anyObject())) 545 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 546 EasyMock.expect( 547 mMockLogSaver.saveLogData( 548 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 549 EasyMock.eq(LogDataType.LOGCAT), 550 (InputStream) EasyMock.anyObject())) 551 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 552 EasyMock.expect( 553 mMockLogSaver.saveLogData( 554 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 555 EasyMock.eq(LogDataType.TEXT), 556 (InputStream) EasyMock.anyObject())) 557 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 558 resumeListener.testLog( 559 EasyMock.eq(LOGCAT_NAME_SETUP), 560 EasyMock.eq(LogDataType.LOGCAT), 561 (InputStreamSource) EasyMock.anyObject()); 562 resumeListener.testLog( 563 EasyMock.eq(LOGCAT_NAME_TEST), 564 EasyMock.eq(LogDataType.LOGCAT), 565 (InputStreamSource) EasyMock.anyObject()); 566 resumeListener.testLog( 567 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 568 EasyMock.eq(LogDataType.LOGCAT), 569 (InputStreamSource) EasyMock.anyObject()); 570 resumeListener.testLog(EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 571 EasyMock.eq(LogDataType.TEXT), (InputStreamSource)EasyMock.anyObject()); 572 573 // just return same build and logger for simplicity 574 EasyMock.expect(mMockBuildInfo.clone()).andReturn(mMockBuildInfo); 575 EasyMock.expect(mMockLogger.clone()).andReturn(mMockLogger); 576 IRescheduler mockRescheduler = EasyMock.createMock(IRescheduler.class); 577 Capture<IConfiguration> capturedConfig = new Capture<IConfiguration>(); 578 EasyMock.expect(mockRescheduler.scheduleConfig(EasyMock.capture(capturedConfig))) 579 .andReturn(Boolean.TRUE); 580 // When resuming the original build provider is still going to handle the clean up. 581 mMockBuildProvider.cleanUp(mMockBuildInfo); 582 EasyMock.expectLastCall().times(4); 583 mMockDevice.clearLastConnectedWifiNetwork(); 584 mMockDevice.stopLogcat(); 585 586 mMockLogger.init(); 587 mMockLogSaver.invocationStarted(mStubInvocationMetadata); 588 // now set resumed invocation expectations 589 mMockDevice.clearLastConnectedWifiNetwork(); 590 mMockDevice.setOptions((TestDeviceOptions)EasyMock.anyObject()); 591 mMockBuildInfo.setDeviceSerial(SERIAL); 592 mMockBuildInfo.setTestTag(EasyMock.eq("stub")); 593 EasyMock.expectLastCall().times(2); 594 mMockDevice.startLogcat(); 595 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 596 mMockLogSaver.invocationStarted(mStubInvocationMetadata); 597 mMockDevice.setRecovery(mMockRecovery); 598 resumableTest.run((ITestInvocationListener)EasyMock.anyObject()); 599 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 600 mMockDevice.clearLogcat(); 601 EasyMock.expectLastCall().times(3); 602 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 603 EasyMock.expect( 604 mMockLogSaver.saveLogData( 605 EasyMock.eq(LOGCAT_NAME_SETUP), 606 EasyMock.eq(LogDataType.LOGCAT), 607 (InputStream) EasyMock.anyObject())) 608 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 609 EasyMock.expect( 610 mMockLogSaver.saveLogData( 611 EasyMock.eq(LOGCAT_NAME_TEST), 612 EasyMock.eq(LogDataType.LOGCAT), 613 (InputStream) EasyMock.anyObject())) 614 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 615 EasyMock.expect( 616 mMockLogSaver.saveLogData( 617 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 618 EasyMock.eq(LogDataType.LOGCAT), 619 (InputStream) EasyMock.anyObject())) 620 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 621 EasyMock.expect( 622 mMockLogSaver.saveLogData( 623 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 624 EasyMock.eq(LogDataType.TEXT), 625 (InputStream) EasyMock.anyObject())) 626 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 627 resumeListener.testLog( 628 EasyMock.eq(LOGCAT_NAME_SETUP), 629 EasyMock.eq(LogDataType.LOGCAT), 630 (InputStreamSource) EasyMock.anyObject()); 631 resumeListener.testLog( 632 EasyMock.eq(LOGCAT_NAME_TEST), 633 EasyMock.eq(LogDataType.LOGCAT), 634 (InputStreamSource) EasyMock.anyObject()); 635 resumeListener.testLog( 636 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 637 EasyMock.eq(LogDataType.LOGCAT), 638 (InputStreamSource) EasyMock.anyObject()); 639 resumeListener.testLog( 640 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 641 EasyMock.eq(LogDataType.TEXT), 642 (InputStreamSource) EasyMock.anyObject()); 643 resumeListener.invocationEnded(EasyMock.anyLong()); 644 mMockLogSaver.invocationEnded(EasyMock.anyLong()); 645 EasyMock.expect(resumeListener.getSummary()).andReturn(null); 646 mMockLogger.closeLog(); 647 EasyMock.expectLastCall().times(3); 648 mMockDevice.clearLastConnectedWifiNetwork(); 649 mMockDevice.stopLogcat(); 650 EasyMock.replay(mockRescheduler, resumeListener, resumableTest, mMockPreparer, 651 mMockBuildProvider, mMockLogger, mMockLogSaver, mMockDevice, mMockBuildInfo); 652 653 try { 654 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 655 fail("DeviceNotAvailableException not thrown"); 656 } catch (DeviceNotAvailableException e) { 657 // expect 658 } 659 // now call again, and expect invocation to be resumed properly 660 mTestInvocation.invoke(mStubInvocationMetadata, capturedConfig.getValue(), mockRescheduler); 661 662 EasyMock.verify(mockRescheduler, resumeListener, resumableTest, mMockPreparer, 663 mMockBuildProvider, mMockLogger, mMockLogSaver, mMockDevice, mMockBuildInfo); 664 } 665 666 /** 667 * Test the invoke scenario for a {@link IRetriableTest}. 668 * 669 * @throws Exception if unexpected error occurs 670 */ 671 public void testInvoke_retry() throws Throwable { 672 AssertionError exception = new AssertionError(); 673 IRetriableTest test = EasyMock.createMock(IRetriableTest.class); 674 test.run((ITestInvocationListener)EasyMock.anyObject()); 675 EasyMock.expectLastCall().andThrow(exception); 676 EasyMock.expect(test.isRetriable()).andReturn(Boolean.TRUE); 677 mStubConfiguration.getCommandOptions().setLoopMode(false); 678 IRescheduler mockRescheduler = EasyMock.createMock(IRescheduler.class); 679 EasyMock.expect(mockRescheduler.rescheduleCommand()).andReturn(EasyMock.anyBoolean()); 680 mMockBuildProvider.buildNotTested(mMockBuildInfo); 681 setupMockFailureListeners(exception); 682 setupNormalInvoke(test); 683 EasyMock.replay(mockRescheduler); 684 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 685 verifyMocks(test, mockRescheduler); 686 verifySummaryListener(); 687 } 688 689 /** 690 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 691 * ITestInvocationListener[])} scenario 692 * when a {@link ITargetCleaner} is part of the config. 693 */ 694 public void testInvoke_tearDown() throws Throwable { 695 IRemoteTest test = EasyMock.createNiceMock(IRemoteTest.class); 696 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 697 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 698 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 699 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 700 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, null); 701 mStubConfiguration.getTargetPreparers().add(mockCleaner); 702 setupMockSuccessListeners(); 703 setupNormalInvoke(test); 704 EasyMock.replay(mockCleaner, mockRescheduler); 705 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 706 verifyMocks(mockCleaner, mockRescheduler); 707 verifySummaryListener(); 708 } 709 710 /** 711 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 712 * ITestInvocationListener[])} scenario 713 * when a {@link ITargetCleaner} is part of the config, and the test throws a 714 * {@link DeviceNotAvailableException}. 715 */ 716 public void testInvoke_tearDown_deviceNotAvail() throws Throwable { 717 DeviceNotAvailableException exception = new DeviceNotAvailableException("ERROR", SERIAL); 718 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 719 test.run((ITestInvocationListener)EasyMock.anyObject()); 720 EasyMock.expectLastCall().andThrow(exception); 721 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 722 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 723 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 724 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 725 EasyMock.expectLastCall(); 726 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, exception); 727 EasyMock.expectLastCall(); 728 mMockDevice.setRecoveryMode(RecoveryMode.NONE); 729 EasyMock.expectLastCall(); 730 EasyMock.replay(mockCleaner, mockRescheduler); 731 mStubConfiguration.getTargetPreparers().add(mockCleaner); 732 setupMockFailureListeners(exception); 733 mMockBuildProvider.buildNotTested(mMockBuildInfo); 734 setupNormalInvoke(test); 735 try { 736 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 737 fail("DeviceNotAvailableException not thrown"); 738 } catch (DeviceNotAvailableException e) { 739 // expected 740 } 741 verifyMocks(mockCleaner, mockRescheduler); 742 verifySummaryListener(); 743 } 744 745 /** 746 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 747 * ITestInvocationListener[])} scenario 748 * when a {@link ITargetCleaner} is part of the config, and the test throws a 749 * {@link RuntimeException}. 750 */ 751 public void testInvoke_tearDown_runtime() throws Throwable { 752 RuntimeException exception = new RuntimeException(); 753 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 754 test.run((ITestInvocationListener)EasyMock.anyObject()); 755 EasyMock.expectLastCall().andThrow(exception); 756 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 757 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 758 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 759 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 760 // tearDown should be called 761 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, exception); 762 mStubConfiguration.getTargetPreparers().add(mockCleaner); 763 setupMockFailureListeners(exception); 764 mMockBuildProvider.buildNotTested(mMockBuildInfo); 765 setupNormalInvoke(test); 766 EasyMock.replay(mockCleaner, mockRescheduler); 767 try { 768 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 769 fail("RuntimeException not thrown"); 770 } catch (RuntimeException e) { 771 // expected 772 } 773 verifyMocks(mockCleaner, mockRescheduler); 774 verifySummaryListener(); 775 } 776 777 /** 778 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 779 * ITestInvocationListener[])} scenario 780 * when there is {@link ITestInvocationListener} which implements the {@link ILogSaverListener} 781 * interface. 782 */ 783 public void testInvoke_logFileSaved() throws Throwable { 784 List<ITestInvocationListener> listenerList = 785 mStubConfiguration.getTestInvocationListeners(); 786 ILogSaverListener logSaverListener = EasyMock.createMock(ILogSaverListener.class); 787 listenerList.add(logSaverListener); 788 mStubConfiguration.setTestInvocationListeners(listenerList); 789 790 logSaverListener.setLogSaver(mMockLogSaver); 791 logSaverListener.invocationStarted(mStubInvocationMetadata); 792 logSaverListener.testLog( 793 EasyMock.eq(LOGCAT_NAME_SETUP), 794 EasyMock.eq(LogDataType.LOGCAT), 795 (InputStreamSource) EasyMock.anyObject()); 796 logSaverListener.testLogSaved( 797 EasyMock.eq(LOGCAT_NAME_SETUP), 798 EasyMock.eq(LogDataType.LOGCAT), 799 (InputStreamSource) EasyMock.anyObject(), 800 (LogFile) EasyMock.anyObject()); 801 logSaverListener.logAssociation(EasyMock.eq(LOGCAT_NAME_SETUP), EasyMock.anyObject()); 802 logSaverListener.testLog( 803 EasyMock.eq(LOGCAT_NAME_TEST), 804 EasyMock.eq(LogDataType.LOGCAT), 805 (InputStreamSource) EasyMock.anyObject()); 806 logSaverListener.testLogSaved( 807 EasyMock.eq(LOGCAT_NAME_TEST), 808 EasyMock.eq(LogDataType.LOGCAT), 809 (InputStreamSource) EasyMock.anyObject(), 810 (LogFile) EasyMock.anyObject()); 811 logSaverListener.logAssociation(EasyMock.eq(LOGCAT_NAME_TEST), EasyMock.anyObject()); 812 logSaverListener.testLog( 813 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 814 EasyMock.eq(LogDataType.LOGCAT), 815 (InputStreamSource) EasyMock.anyObject()); 816 logSaverListener.testLogSaved( 817 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 818 EasyMock.eq(LogDataType.LOGCAT), 819 (InputStreamSource) EasyMock.anyObject(), 820 (LogFile) EasyMock.anyObject()); 821 logSaverListener.logAssociation(EasyMock.eq(LOGCAT_NAME_TEARDOWN), EasyMock.anyObject()); 822 logSaverListener.testLog( 823 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 824 EasyMock.eq(LogDataType.TEXT), 825 (InputStreamSource) EasyMock.anyObject()); 826 logSaverListener.testLogSaved( 827 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 828 EasyMock.eq(LogDataType.TEXT), 829 (InputStreamSource) EasyMock.anyObject(), 830 (LogFile) EasyMock.anyObject()); 831 logSaverListener.logAssociation( 832 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), EasyMock.anyObject()); 833 logSaverListener.invocationEnded(EasyMock.anyLong()); 834 EasyMock.expect(logSaverListener.getSummary()).andReturn(mSummary); 835 836 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 837 setupMockSuccessListeners(); 838 test.run((ITestInvocationListener)EasyMock.anyObject()); 839 setupNormalInvoke(test); 840 EasyMock.replay(logSaverListener, mockRescheduler); 841 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 842 verifyMocks(test, logSaverListener, mockRescheduler); 843 assertEquals(2, mUriCapture.getValue().size()); 844 } 845 846 /** 847 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 848 * ITestInvocationListener[])} 849 * scenario with {@link IStrictShardableTest} when a shard index is given. 850 */ 851 public void testInvoke_strictShardableTest_withShardIndex() throws Throwable { 852 mTestInvocation = 853 new TestInvocation() { 854 @Override 855 ILogRegistry getLogRegistry() { 856 return mMockLogRegistry; 857 } 858 859 @Override 860 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 861 return new InvocationExecution() { 862 @Override 863 protected IShardHelper createShardHelper() { 864 return new StrictShardHelper(); 865 } 866 }; 867 } 868 869 @Override 870 protected void setExitCode(ExitCode code, Throwable stack) { 871 // empty on purpose 872 } 873 874 @Override 875 InvocationScope getInvocationScope() { 876 // Avoid re-entry in the current TF invocation scope for unit tests. 877 return new InvocationScope(); 878 } 879 }; 880 String[] commandLine = {"config", "arg"}; 881 int shardCount = 10; 882 int shardIndex = 5; 883 IStrictShardableTest test = EasyMock.createMock(IStrictShardableTest.class); 884 IRemoteTest testShard = EasyMock.createMock(IRemoteTest.class); 885 mStubConfiguration.setTest(test); 886 mStubConfiguration.setCommandLine(commandLine); 887 mStubConfiguration.getCommandOptions().setShardCount(shardCount); 888 mStubConfiguration.getCommandOptions().setShardIndex(shardIndex); 889 890 setupInvokeWithBuild(); 891 setupMockSuccessListeners(); 892 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 893 mMockBuildInfo.addBuildAttribute("command_line_args", "config arg"); 894 mMockBuildInfo.addBuildAttribute("shard_count", "10"); 895 mMockBuildInfo.addBuildAttribute("shard_index", "5"); 896 EasyMock.expect(test.getTestShard(shardCount, shardIndex)).andReturn(testShard); 897 testShard.run((ITestInvocationListener)EasyMock.anyObject()); 898 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 899 replayMocks(test, testShard); 900 901 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 902 903 verifyMocks(test, testShard); 904 } 905 906 /** 907 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 908 * ITestInvocationListener[])} 909 * scenario with non-{@link IStrictShardableTest} when shard index 0 is given. 910 */ 911 public void testInvoke_nonStrictShardableTest_withShardIndexZero() throws Throwable { 912 String[] commandLine = {"config", "arg"}; 913 int shardCount = 10; 914 int shardIndex = 0; 915 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 916 mStubConfiguration.setTest(test); 917 mStubConfiguration.setCommandLine(commandLine); 918 mStubConfiguration.getCommandOptions().setShardCount(shardCount); 919 mStubConfiguration.getCommandOptions().setShardIndex(shardIndex); 920 921 setupInvokeWithBuild(); 922 setupMockSuccessListeners(); 923 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 924 mMockBuildInfo.addBuildAttribute("command_line_args", "config arg"); 925 mMockBuildInfo.addBuildAttribute("shard_count", "10"); 926 mMockBuildInfo.addBuildAttribute("shard_index", "0"); 927 test.run((ITestInvocationListener)EasyMock.anyObject()); 928 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 929 replayMocks(test); 930 931 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 932 933 verifyMocks(test); 934 } 935 936 /** 937 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 938 * ITestInvocationListener[])} 939 * scenario with non-{@link IStrictShardableTest} when a shard index non-0 is given. 940 */ 941 public void testInvoke_nonStrictShardableTest_withShardIndexNonZero() throws Throwable { 942 mTestInvocation = 943 new TestInvocation() { 944 @Override 945 ILogRegistry getLogRegistry() { 946 return mMockLogRegistry; 947 } 948 949 @Override 950 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 951 return new InvocationExecution() { 952 @Override 953 protected IShardHelper createShardHelper() { 954 return new StrictShardHelper(); 955 } 956 }; 957 } 958 959 @Override 960 protected void setExitCode(ExitCode code, Throwable stack) { 961 // empty on purpose 962 } 963 964 @Override 965 InvocationScope getInvocationScope() { 966 // Avoid re-entry in the current TF invocation scope for unit tests. 967 return new InvocationScope(); 968 } 969 }; 970 String[] commandLine = {"config", "arg"}; 971 int shardCount = 10; 972 int shardIndex = 1; 973 IStrictShardableTest shardableTest = EasyMock.createMock(IStrictShardableTest.class); 974 IRemoteTest test = EasyMock.createMock(IRemoteTest.class); 975 EasyMock.expect(shardableTest.getTestShard(10, 1)).andReturn(test); 976 test.run((ITestInvocationListener)EasyMock.anyObject()); 977 EasyMock.expectLastCall(); 978 mStubConfiguration.setTest(shardableTest); 979 mStubConfiguration.setCommandLine(commandLine); 980 mStubConfiguration.getCommandOptions().setShardCount(shardCount); 981 mStubConfiguration.getCommandOptions().setShardIndex(shardIndex); 982 983 setupInvokeWithBuild(); 984 setupMockSuccessListeners(); 985 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 986 mMockBuildInfo.addBuildAttribute("command_line_args", "config arg"); 987 mMockBuildInfo.addBuildAttribute("shard_count", "10"); 988 mMockBuildInfo.addBuildAttribute("shard_index", "1"); 989 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 990 replayMocks(shardableTest, test); 991 992 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 993 994 verifyMocks(shardableTest, test); 995 } 996 997 /** 998 * Test the test-tag is set when the IBuildInfo's test-tag is not. 999 */ 1000 public void testInvoke_testtag() throws Throwable { 1001 String[] commandLine = {"run", "empty"}; 1002 mStubConfiguration.setCommandLine(commandLine); 1003 mStubConfiguration.getCommandOptions().setTestTag("not-default"); 1004 1005 setupInvoke(); 1006 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 1007 mMockDevice.clearLogcat(); 1008 EasyMock.expectLastCall().times(3); 1009 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 1010 mMockBuildInfo.setDeviceSerial(SERIAL); 1011 mMockBuildProvider.cleanUp(mMockBuildInfo); 1012 EasyMock.expectLastCall().times(2); 1013 setupMockSuccessListeners(); 1014 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 1015 mMockBuildInfo.addBuildAttribute("command_line_args", "run empty"); 1016 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 1017 // Default build is "stub" so we set the test-tag 1018 mMockBuildInfo.setTestTag(EasyMock.eq("not-default")); 1019 EasyMock.expectLastCall(); 1020 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn("stub"); 1021 mMockLogRegistry.unregisterLogger(); 1022 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1023 mMockLogger.closeLog(); 1024 replayMocks(); 1025 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1026 verifyMocks(); 1027 } 1028 1029 /** 1030 * Test the test-tag of the IBuildInfo is not modified when the CommandOption default test-tag 1031 * is not modified. 1032 */ 1033 public void testInvoke_testtag_notset() throws Throwable { 1034 String[] commandLine = {"run", "empty"}; 1035 mStubConfiguration.setCommandLine(commandLine); 1036 setupInvoke(); 1037 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 1038 mMockDevice.clearLogcat(); 1039 EasyMock.expectLastCall().times(3); 1040 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 1041 mMockBuildInfo.setDeviceSerial(SERIAL); 1042 mMockBuildProvider.cleanUp(mMockBuildInfo); 1043 EasyMock.expectLastCall().times(2); 1044 setupMockSuccessListeners(); 1045 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 1046 mMockBuildInfo.addBuildAttribute("command_line_args", "run empty"); 1047 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 1048 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn("buildprovidertesttag"); 1049 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1050 mMockLogRegistry.unregisterLogger(); 1051 mMockLogger.closeLog(); 1052 replayMocks(); 1053 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1054 verifyMocks(); 1055 } 1056 1057 /** 1058 * Test the test-tag of the IBuildInfo is not set and Command Option is not set either. 1059 * A default 'stub' test-tag is set to ensure reporting is done. 1060 */ 1061 public void testInvoke_notesttag() throws Throwable { 1062 String[] commandLine = {"run", "empty"}; 1063 mStubConfiguration.setCommandLine(commandLine); 1064 setupInvoke(); 1065 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 1066 mMockDevice.clearLogcat(); 1067 EasyMock.expectLastCall().times(3); 1068 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 1069 mMockBuildInfo.setDeviceSerial(SERIAL); 1070 mMockBuildProvider.cleanUp(mMockBuildInfo); 1071 EasyMock.expectLastCall().times(2); 1072 setupMockSuccessListeners(); 1073 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 1074 mMockBuildInfo.addBuildAttribute("command_line_args", "run empty"); 1075 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 1076 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(null); 1077 mMockBuildInfo.setTestTag(EasyMock.eq("stub")); 1078 EasyMock.expectLastCall(); 1079 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1080 mMockLogRegistry.unregisterLogger(); 1081 mMockLogger.closeLog(); 1082 replayMocks(); 1083 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1084 verifyMocks(); 1085 } 1086 1087 /** 1088 * Helper tests class to expose all the interfaces needed for the tests. 1089 */ 1090 private interface IFakeBuildProvider extends IDeviceBuildProvider, IInvocationContextReceiver { 1091 } 1092 1093 /** 1094 * Test the injection of test-tag from TestInvocation to the build provider via the 1095 * {@link IInvocationContextReceiver}. 1096 */ 1097 public void testInvoke_buildProviderNeedTestTag() throws Throwable { 1098 final String testTag = "THISISTHETAG"; 1099 String[] commandLine = {"run", "empty"}; 1100 mStubConfiguration.setCommandLine(commandLine); 1101 ICommandOptions commandOption = new CommandOptions(); 1102 commandOption.setTestTag(testTag); 1103 IFakeBuildProvider mockProvider = EasyMock.createMock(IFakeBuildProvider.class); 1104 mStubConfiguration.setBuildProvider(mockProvider); 1105 mStubConfiguration.setCommandOptions(commandOption); 1106 setupInvoke(); 1107 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 1108 mMockDevice.clearLogcat(); 1109 EasyMock.expectLastCall().times(3); 1110 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 1111 mMockBuildInfo.setDeviceSerial(SERIAL); 1112 setupMockSuccessListeners(); 1113 mMockBuildInfo.addBuildAttribute("command_line_args", "run empty"); 1114 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 1115 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(null); 1116 // Validate proper tag is set on the build. 1117 mMockBuildInfo.setTestTag(EasyMock.eq(testTag)); 1118 mockProvider.setInvocationContext((IInvocationContext)EasyMock.anyObject()); 1119 EasyMock.expect(mockProvider.getBuild(mMockDevice)).andReturn(mMockBuildInfo); 1120 mockProvider.cleanUp(mMockBuildInfo); 1121 EasyMock.expectLastCall().times(2); 1122 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1123 mMockLogRegistry.unregisterLogger(); 1124 mMockLogger.closeLog(); 1125 1126 replayMocks(mockProvider); 1127 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1128 verifyMocks(mockProvider); 1129 } 1130 1131 /** 1132 * Set up expected conditions for normal run up to the part where tests are run. 1133 * 1134 * @param test the {@link Test} to use. 1135 */ 1136 private void setupNormalInvoke(IRemoteTest test) throws Throwable { 1137 setupInvokeWithBuild(); 1138 mStubConfiguration.setTest(test); 1139 mStubMultiConfiguration.setTest(test); 1140 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 1141 1142 mMockPreparer.setUp(mMockDevice, mMockBuildInfo); 1143 replayMocks(test); 1144 } 1145 1146 /** 1147 * Set up expected calls that occur on every invoke, regardless of result 1148 */ 1149 private void setupInvoke() { 1150 mMockDevice.clearLastConnectedWifiNetwork(); 1151 mMockDevice.setOptions((TestDeviceOptions)EasyMock.anyObject()); 1152 mMockDevice.startLogcat(); 1153 mMockDevice.clearLastConnectedWifiNetwork(); 1154 mMockDevice.stopLogcat(); 1155 } 1156 1157 /** 1158 * Set up expected calls that occur on every invoke that gets a valid build 1159 */ 1160 private void setupInvokeWithBuild() { 1161 setupInvoke(); 1162 EasyMock.expect(mMockDevice.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(3); 1163 mMockDevice.clearLogcat(); 1164 EasyMock.expectLastCall().times(3); 1165 1166 EasyMock.expect(mMockLogger.getLog()).andReturn(EMPTY_STREAM_SOURCE); 1167 mMockBuildInfo.setDeviceSerial(SERIAL); 1168 mMockBuildProvider.cleanUp(mMockBuildInfo); 1169 EasyMock.expectLastCall().anyTimes(); 1170 mMockBuildInfo.setTestTag(EasyMock.eq("stub")); 1171 EasyMock.expectLastCall(); 1172 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(""); 1173 1174 mMockLogRegistry.unregisterLogger(); 1175 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1176 mMockLogger.closeLog(); 1177 } 1178 1179 /** 1180 * Set up expected conditions for the test InvocationListener and SummaryListener 1181 * 1182 * <p>The order of calls for a single listener should be: 1183 * 1184 * <ol> 1185 * <li>invocationStarted 1186 * <li>testLog(LOGCAT_NAME_SETUP, ...) (if no build or retrieval error) 1187 * <li>invocationFailed (if run failed) 1188 * <li>testLog(LOGCAT_NAME_ERROR, ...) (if build retrieval error) 1189 * <li>testLog(LOGCAT_NAME_TEST, ...) (otherwise) 1190 * <li>testLog(build error bugreport, ...) (otherwise and if build error) 1191 * <li>testLog(LOGCAT_NAME_TEARDOWN, ...) (otherwise) 1192 * <li>testLog(TRADEFED_LOG_NAME, ...) 1193 * <li>putSummary (for an ITestSummaryListener) 1194 * <li>invocationEnded 1195 * <li>getSummary (for an ITestInvocationListener) 1196 * </ol> 1197 * 1198 * However note that, across all listeners, any getSummary call will precede all putSummary 1199 * calls. 1200 */ 1201 private void setupMockListeners(InvocationStatus status, Throwable throwable) 1202 throws IOException { 1203 // invocationStarted 1204 mMockLogSaver.invocationStarted(mStubInvocationMetadata); 1205 mMockTestListener.invocationStarted(mStubInvocationMetadata); 1206 mMockSummaryListener.invocationStarted(mStubInvocationMetadata); 1207 1208 if (!(throwable instanceof BuildRetrievalError)) { 1209 EasyMock.expect( 1210 mMockLogSaver.saveLogData( 1211 EasyMock.eq(LOGCAT_NAME_SETUP), 1212 EasyMock.eq(LogDataType.LOGCAT), 1213 (InputStream) EasyMock.anyObject())) 1214 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 1215 mMockTestListener.testLog( 1216 EasyMock.eq(LOGCAT_NAME_SETUP), 1217 EasyMock.eq(LogDataType.LOGCAT), 1218 (InputStreamSource) EasyMock.anyObject()); 1219 mMockSummaryListener.testLog( 1220 EasyMock.eq(LOGCAT_NAME_SETUP), 1221 EasyMock.eq(LogDataType.LOGCAT), 1222 (InputStreamSource) EasyMock.anyObject()); 1223 } 1224 1225 // invocationFailed 1226 if (!status.equals(InvocationStatus.SUCCESS)) { 1227 mMockTestListener.invocationFailed(EasyMock.eq(throwable)); 1228 mMockSummaryListener.invocationFailed(EasyMock.eq(throwable)); 1229 } 1230 1231 if (throwable instanceof BuildRetrievalError) { 1232 // Handle logcat error listeners 1233 EasyMock.expect( 1234 mMockLogSaver.saveLogData( 1235 EasyMock.eq(LOGCAT_NAME_ERROR), 1236 EasyMock.eq(LogDataType.LOGCAT), 1237 (InputStream) EasyMock.anyObject())) 1238 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 1239 mMockTestListener.testLog( 1240 EasyMock.eq(LOGCAT_NAME_ERROR), 1241 EasyMock.eq(LogDataType.LOGCAT), 1242 (InputStreamSource) EasyMock.anyObject()); 1243 mMockSummaryListener.testLog( 1244 EasyMock.eq(LOGCAT_NAME_ERROR), 1245 EasyMock.eq(LogDataType.LOGCAT), 1246 (InputStreamSource) EasyMock.anyObject()); 1247 } else { 1248 // Handle test logcat listeners 1249 EasyMock.expect( 1250 mMockLogSaver.saveLogData( 1251 EasyMock.eq(LOGCAT_NAME_TEST), 1252 EasyMock.eq(LogDataType.LOGCAT), 1253 (InputStream) EasyMock.anyObject())) 1254 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 1255 mMockTestListener.testLog( 1256 EasyMock.eq(LOGCAT_NAME_TEST), 1257 EasyMock.eq(LogDataType.LOGCAT), 1258 (InputStreamSource) EasyMock.anyObject()); 1259 mMockSummaryListener.testLog( 1260 EasyMock.eq(LOGCAT_NAME_TEST), 1261 EasyMock.eq(LogDataType.LOGCAT), 1262 (InputStreamSource) EasyMock.anyObject()); 1263 // Handle build error bugreport listeners 1264 if (throwable instanceof BuildError) { 1265 EasyMock.expect( 1266 mMockDevice.logBugreport( 1267 EasyMock.eq( 1268 TestInvocation.BUILD_ERROR_BUGREPORT_NAME 1269 + "_" 1270 + SERIAL), 1271 EasyMock.anyObject())) 1272 .andReturn(true); 1273 } 1274 // Handle teardown logcat listeners 1275 EasyMock.expect( 1276 mMockLogSaver.saveLogData( 1277 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 1278 EasyMock.eq(LogDataType.LOGCAT), 1279 (InputStream) EasyMock.anyObject())) 1280 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 1281 mMockTestListener.testLog( 1282 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 1283 EasyMock.eq(LogDataType.LOGCAT), 1284 (InputStreamSource) EasyMock.anyObject()); 1285 mMockSummaryListener.testLog( 1286 EasyMock.eq(LOGCAT_NAME_TEARDOWN), 1287 EasyMock.eq(LogDataType.LOGCAT), 1288 (InputStreamSource) EasyMock.anyObject()); 1289 } 1290 1291 EasyMock.expect( 1292 mMockLogSaver.saveLogData( 1293 EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 1294 EasyMock.eq(LogDataType.TEXT), 1295 (InputStream) EasyMock.anyObject())) 1296 .andReturn(new LogFile(PATH, URL, LogDataType.TEXT)); 1297 mMockTestListener.testLog(EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 1298 EasyMock.eq(LogDataType.TEXT), (InputStreamSource)EasyMock.anyObject()); 1299 mMockSummaryListener.testLog(EasyMock.eq(TestInvocation.TRADEFED_LOG_NAME), 1300 EasyMock.eq(LogDataType.TEXT), (InputStreamSource)EasyMock.anyObject()); 1301 1302 // invocationEnded, getSummary (mMockTestListener) 1303 mMockTestListener.invocationEnded(EasyMock.anyLong()); 1304 EasyMock.expect(mMockTestListener.getSummary()).andReturn(mSummary); 1305 1306 // putSummary, invocationEnded (mMockSummaryListener) 1307 mMockSummaryListener.putSummary(EasyMock.capture(mUriCapture)); 1308 mMockSummaryListener.invocationEnded(EasyMock.anyLong()); 1309 mMockLogSaver.invocationEnded(EasyMock.anyLong()); 1310 } 1311 1312 /** 1313 * Test the {@link TestInvocation#invoke(IInvocationContext, IConfiguration, IRescheduler, 1314 * ITestInvocationListener[])} scenario with {@link IShardableTest}. 1315 */ 1316 public void testInvoke_shardableTest_legacy() throws Throwable { 1317 String command = "empty --test-tag t"; 1318 String[] commandLine = {"empty", "--test-tag", "t"}; 1319 int shardCount = 2; 1320 IShardableTest test = EasyMock.createMock(IShardableTest.class); 1321 List<IRemoteTest> shards = new ArrayList<>(); 1322 IRemoteTest shard1 = EasyMock.createMock(IRemoteTest.class); 1323 IRemoteTest shard2 = EasyMock.createMock(IRemoteTest.class); 1324 shards.add(shard1); 1325 shards.add(shard2); 1326 EasyMock.expect(test.split()).andReturn(shards); 1327 mStubConfiguration.setTest(test); 1328 mStubConfiguration.setCommandLine(commandLine); 1329 mMockBuildProvider.cleanUp(mMockBuildInfo); 1330 setupInvoke(); 1331 setupNShardInvocation(shardCount, command); 1332 mMockLogRegistry.dumpToGlobalLog(mMockLogger); 1333 replayMocks(test, mockRescheduler, shard1, shard2); 1334 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1335 verifyMocks(test, mockRescheduler, shard1, shard2); 1336 } 1337 1338 /** 1339 * Test that {@link TestInvocation#logDeviceBatteryLevel(IInvocationContext, String)} is not 1340 * adding battery information for placeholder device. 1341 */ 1342 public void testLogDeviceBatteryLevel_placeholderDevice() { 1343 final String fakeEvent = "event"; 1344 IInvocationContext context = new InvocationContext(); 1345 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1346 EasyMock.expect(device1.getIDevice()).andReturn(new StubDevice("serial1")); 1347 context.addAllocatedDevice("device1", device1); 1348 EasyMock.replay(device1); 1349 mTestInvocation.logDeviceBatteryLevel(context, fakeEvent); 1350 EasyMock.verify(device1); 1351 assertEquals(0, context.getAttributes().size()); 1352 } 1353 1354 /** 1355 * Test that {@link TestInvocation#logDeviceBatteryLevel(IInvocationContext, String)} is adding 1356 * battery information for physical real device. 1357 */ 1358 public void testLogDeviceBatteryLevel_physicalDevice() { 1359 final String fakeEvent = "event"; 1360 IInvocationContext context = new InvocationContext(); 1361 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1362 IDevice idevice = Mockito.mock(IDevice.class); 1363 EasyMock.expect(device1.getIDevice()).andReturn(idevice); 1364 SettableFuture<Integer> future = SettableFuture.create(); 1365 future.set(50); 1366 doReturn(future).when(idevice).getBattery(Mockito.anyLong(), Mockito.any()); 1367 EasyMock.expect(device1.getSerialNumber()).andReturn("serial1"); 1368 context.addAllocatedDevice("device1", device1); 1369 context.addDeviceBuildInfo("device1", new BuildInfo()); 1370 EasyMock.replay(device1); 1371 mTestInvocation.logDeviceBatteryLevel(context, fakeEvent); 1372 EasyMock.verify(device1); 1373 assertEquals(1, context.getBuildInfo("device1").getBuildAttributes().size()); 1374 assertEquals( 1375 "50", 1376 context.getBuildInfo("device1") 1377 .getBuildAttributes() 1378 .get("serial1-battery-" + fakeEvent)); 1379 } 1380 1381 /** 1382 * Test that {@link TestInvocation#logDeviceBatteryLevel(IInvocationContext, String)} is adding 1383 * battery information for multiple physical real device. 1384 */ 1385 public void testLogDeviceBatteryLevel_physicalDevice_multi() { 1386 final String fakeEvent = "event"; 1387 IInvocationContext context = new InvocationContext(); 1388 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1389 IDevice idevice = Mockito.mock(IDevice.class); 1390 EasyMock.expect(device1.getSerialNumber()).andReturn("serial1"); 1391 EasyMock.expect(device1.getIDevice()).andReturn(idevice); 1392 SettableFuture<Integer> future = SettableFuture.create(); 1393 future.set(50); 1394 doReturn(future).when(idevice).getBattery(Mockito.anyLong(), Mockito.any()); 1395 ITestDevice device2 = EasyMock.createMock(ITestDevice.class); 1396 EasyMock.expect(device2.getIDevice()).andReturn(idevice); 1397 EasyMock.expect(device2.getSerialNumber()).andReturn("serial2"); 1398 context.addAllocatedDevice("device1", device1); 1399 context.addDeviceBuildInfo("device1", new BuildInfo()); 1400 context.addAllocatedDevice("device2", device2); 1401 context.addDeviceBuildInfo("device2", new BuildInfo()); 1402 EasyMock.replay(device1, device2); 1403 mTestInvocation.logDeviceBatteryLevel(context, fakeEvent); 1404 EasyMock.verify(device1, device2); 1405 assertEquals(1, context.getBuildInfo("device1").getBuildAttributes().size()); 1406 assertEquals(1, context.getBuildInfo("device2").getBuildAttributes().size()); 1407 assertEquals( 1408 "50", 1409 context.getBuildInfo("device1") 1410 .getBuildAttributes() 1411 .get("serial1-battery-" + fakeEvent)); 1412 assertEquals( 1413 "50", 1414 context.getBuildInfo("device2") 1415 .getBuildAttributes() 1416 .get("serial2-battery-" + fakeEvent)); 1417 } 1418 1419 /** 1420 * Test that {@link TestInvocation#logDeviceBatteryLevel(IInvocationContext, String)} is adding 1421 * battery information for multiple physical real device, and ignore stub device if any. 1422 */ 1423 public void testLogDeviceBatteryLevel_physicalDevice_stub_multi() { 1424 final String fakeEvent = "event"; 1425 IInvocationContext context = new InvocationContext(); 1426 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1427 IDevice idevice = Mockito.mock(IDevice.class); 1428 EasyMock.expect(device1.getSerialNumber()).andReturn("serial1"); 1429 EasyMock.expect(device1.getIDevice()).andReturn(idevice); 1430 SettableFuture<Integer> future = SettableFuture.create(); 1431 future.set(50); 1432 doReturn(future).when(idevice).getBattery(Mockito.anyLong(), Mockito.any()); 1433 ITestDevice device2 = EasyMock.createMock(ITestDevice.class); 1434 EasyMock.expect(device2.getIDevice()).andReturn(idevice); 1435 EasyMock.expect(device2.getSerialNumber()).andReturn("serial2"); 1436 ITestDevice device3 = EasyMock.createMock(ITestDevice.class); 1437 EasyMock.expect(device1.getIDevice()).andStubReturn(new StubDevice("stub1")); 1438 ITestDevice device4 = EasyMock.createMock(ITestDevice.class); 1439 EasyMock.expect(device1.getIDevice()).andStubReturn(new StubDevice("stub2")); 1440 context.addAllocatedDevice("device1", device1); 1441 context.addDeviceBuildInfo("device1", new BuildInfo()); 1442 context.addAllocatedDevice("device2", device2); 1443 context.addDeviceBuildInfo("device2", new BuildInfo()); 1444 context.addAllocatedDevice("device3", device3); 1445 context.addAllocatedDevice("device4", device4); 1446 EasyMock.replay(device1, device2); 1447 mTestInvocation.logDeviceBatteryLevel(context, fakeEvent); 1448 EasyMock.verify(device1, device2); 1449 assertEquals(1, context.getBuildInfo("device1").getBuildAttributes().size()); 1450 assertEquals(1, context.getBuildInfo("device2").getBuildAttributes().size()); 1451 assertEquals( 1452 "50", 1453 context.getBuildInfo("device1") 1454 .getBuildAttributes() 1455 .get("serial1-battery-" + fakeEvent)); 1456 assertEquals( 1457 "50", 1458 context.getBuildInfo("device2") 1459 .getBuildAttributes() 1460 .get("serial2-battery-" + fakeEvent)); 1461 } 1462 1463 /** Helper to set the expectation for N number of shards. */ 1464 private void setupNShardInvocation(int numShard, String commandLine) throws Exception { 1465 mMockBuildInfo.setTestTag(EasyMock.eq("stub")); 1466 EasyMock.expectLastCall(); 1467 EasyMock.expect(mMockBuildProvider.getBuild()).andReturn(mMockBuildInfo); 1468 EasyMock.expect(mMockBuildInfo.getTestTag()).andStubReturn(""); 1469 mMockBuildInfo.addBuildAttribute("command_line_args", commandLine); 1470 mMockTestListener.invocationStarted((IInvocationContext)EasyMock.anyObject()); 1471 EasyMock.expectLastCall(); 1472 mMockSummaryListener.invocationStarted((IInvocationContext)EasyMock.anyObject()); 1473 EasyMock.expectLastCall(); 1474 EasyMock.expect(mMockLogger.clone()).andReturn(mMockLogger).times(numShard); 1475 EasyMock.expect(mMockBuildInfo.clone()).andReturn(mMockBuildInfo).times(numShard); 1476 EasyMock.expect(mockRescheduler.scheduleConfig(EasyMock.anyObject())) 1477 .andReturn(true).times(numShard); 1478 mMockBuildInfo.setDeviceSerial(SERIAL); 1479 EasyMock.expectLastCall(); 1480 mMockBuildProvider.cleanUp(EasyMock.anyObject()); 1481 EasyMock.expectLastCall(); 1482 } 1483 1484 private void setupMockSuccessListeners() throws IOException { 1485 setupMockListeners(InvocationStatus.SUCCESS, null); 1486 } 1487 1488 private void setupMockFailureListeners(Throwable throwable) throws IOException { 1489 setupMockListeners(InvocationStatus.FAILED, throwable); 1490 } 1491 1492 private void verifySummaryListener() { 1493 // Check that we captured the expected uris List 1494 List<TestSummary> summaries = mUriCapture.getValue(); 1495 assertEquals(1, summaries.size()); 1496 assertEquals(mSummary, summaries.get(0)); 1497 } 1498 1499 /** 1500 * Verify all mock objects received expected calls 1501 */ 1502 private void verifyMocks(Object... mocks) { 1503 // note: intentionally exclude configuration from verification - don't care 1504 // what methods are called 1505 EasyMock.verify(mMockTestListener, mMockSummaryListener, mMockPreparer, 1506 mMockBuildProvider, mMockLogger, mMockBuildInfo, mMockLogRegistry, 1507 mMockLogSaver); 1508 if (mocks.length > 0) { 1509 EasyMock.verify(mocks); 1510 } 1511 } 1512 1513 /** 1514 * Switch all mock objects into replay mode. 1515 */ 1516 private void replayMocks(Object... mocks) { 1517 EasyMock.replay(mMockTestListener, mMockSummaryListener, mMockPreparer, 1518 mMockBuildProvider, mMockLogger, mMockBuildInfo, mMockLogRegistry, 1519 mMockLogSaver, mMockDevice, mMockConfigFactory); 1520 if (mocks.length > 0) { 1521 EasyMock.replay(mocks); 1522 } 1523 } 1524 1525 /** 1526 * Interface for testing device config pass through. 1527 */ 1528 private interface DeviceConfigTest extends IRemoteTest, IDeviceTest { 1529 1530 } 1531 1532 /** 1533 * Test {@link INativeDevice#preInvocationSetup(IBuildInfo info)} is called when command option 1534 * skip-pre-device-setup is not set. 1535 */ 1536 public void testNotSkipPreDeviceSetup() throws Throwable { 1537 IInvocationContext context = new InvocationContext(); 1538 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1539 IDevice idevice = Mockito.mock(IDevice.class); 1540 context.addAllocatedDevice("DEFAULT_DEVICE", device1); 1541 EasyMock.expect(device1.getSerialNumber()).andReturn("serial1").anyTimes(); 1542 EasyMock.expect(device1.getIDevice()).andReturn(idevice).anyTimes(); 1543 EasyMock.expect(device1.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(1); 1544 device1.clearLogcat(); 1545 EasyMock.expectLastCall().once(); 1546 device1.preInvocationSetup((IBuildInfo) EasyMock.anyObject()); 1547 EasyMock.expectLastCall().once(); 1548 1549 CommandOptions commandOption = new CommandOptions(); 1550 OptionSetter setter = new OptionSetter(commandOption); 1551 setter.setOptionValue("skip-pre-device-setup", "false"); 1552 mStubConfiguration.setCommandOptions(commandOption); 1553 1554 EasyMock.expect(mMockPreparer.isDisabled()).andReturn(true); 1555 // Not expect isTearDownDisabled. 1556 1557 ITestInvocationListener listener = EasyMock.createStrictMock(ITestInvocationListener.class); 1558 listener.testLog( 1559 EasyMock.eq(LOGCAT_NAME_SETUP), 1560 EasyMock.eq(LogDataType.LOGCAT), 1561 (InputStreamSource) EasyMock.anyObject()); 1562 1563 EasyMock.replay(device1, listener, mMockPreparer); 1564 new InvocationExecution().doSetup(context, mStubConfiguration, listener); 1565 EasyMock.verify(device1, listener, mMockPreparer); 1566 1567 } 1568 1569 /** 1570 * Test {@link INativeDevice#preInvocationSetup(IBuildInfo info)} is not called when command 1571 * option skip-pre-device-setup is set. 1572 */ 1573 public void testSkipPreDeviceSetup() throws Throwable { 1574 IInvocationContext context = new InvocationContext(); 1575 ITestDevice device1 = EasyMock.createMock(ITestDevice.class); 1576 IDevice idevice = Mockito.mock(IDevice.class); 1577 context.addAllocatedDevice("DEFAULT_DEVICE", device1); 1578 EasyMock.expect(device1.getSerialNumber()).andReturn("serial1").anyTimes(); 1579 EasyMock.expect(device1.getIDevice()).andReturn(idevice).anyTimes(); 1580 EasyMock.expect(device1.getLogcat()).andReturn(EMPTY_STREAM_SOURCE).times(1); 1581 device1.clearLogcat(); 1582 EasyMock.expectLastCall().once(); 1583 1584 CommandOptions commandOption = new CommandOptions(); 1585 OptionSetter setter = new OptionSetter(commandOption); 1586 setter.setOptionValue("skip-pre-device-setup", "true"); 1587 mStubConfiguration.setCommandOptions(commandOption); 1588 1589 EasyMock.expect(mMockPreparer.isDisabled()).andReturn(true); 1590 // Not expect isTearDownDisabled 1591 1592 ITestInvocationListener listener = EasyMock.createStrictMock(ITestInvocationListener.class); 1593 listener.testLog( 1594 EasyMock.eq(LOGCAT_NAME_SETUP), 1595 EasyMock.eq(LogDataType.LOGCAT), 1596 (InputStreamSource) EasyMock.anyObject()); 1597 1598 EasyMock.replay(device1, listener, mMockPreparer); 1599 new InvocationExecution().doSetup(context, mStubConfiguration, listener); 1600 EasyMock.verify(device1, listener, mMockPreparer); 1601 } 1602 1603 /** 1604 * Test when a {@link IDeviceBuildInfo} is passing through we do not attempt to add any external 1605 * directories when there is none coming from environment. 1606 */ 1607 public void testInvoke_deviceInfoBuild_noEnv() throws Throwable { 1608 mTestInvocation = 1609 new TestInvocation() { 1610 @Override 1611 ILogRegistry getLogRegistry() { 1612 return mMockLogRegistry; 1613 } 1614 1615 @Override 1616 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 1617 return new InvocationExecution() { 1618 @Override 1619 protected IShardHelper createShardHelper() { 1620 return new ShardHelper(); 1621 } 1622 1623 @Override 1624 File getExternalTestCasesDirs(EnvVariable envVar) { 1625 // Return empty list to ensure we do not have any environment loaded 1626 return null; 1627 } 1628 }; 1629 } 1630 1631 @Override 1632 protected void setExitCode(ExitCode code, Throwable stack) { 1633 // empty on purpose 1634 } 1635 1636 @Override 1637 InvocationScope getInvocationScope() { 1638 // Avoid re-entry in the current TF invocation scope for unit tests. 1639 return new InvocationScope(); 1640 } 1641 }; 1642 mMockBuildInfo = EasyMock.createMock(IDeviceBuildInfo.class); 1643 EasyMock.expect(mMockBuildInfo.getProperties()).andStubReturn(new HashSet<>()); 1644 IRemoteTest test = EasyMock.createNiceMock(IRemoteTest.class); 1645 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 1646 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 1647 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 1648 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 1649 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, null); 1650 mStubConfiguration.getTargetPreparers().add(mockCleaner); 1651 1652 File tmpTestsDir = FileUtil.createTempDir("invocation-tests-dir"); 1653 try { 1654 EasyMock.expect(((IDeviceBuildInfo) mMockBuildInfo).getTestsDir()) 1655 .andReturn(tmpTestsDir); 1656 setupMockSuccessListeners(); 1657 setupNormalInvoke(test); 1658 EasyMock.replay(mockCleaner, mockRescheduler); 1659 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1660 verifyMocks(mockCleaner, mockRescheduler); 1661 verifySummaryListener(); 1662 } finally { 1663 FileUtil.recursiveDelete(tmpTestsDir); 1664 } 1665 } 1666 1667 /** 1668 * Test when a {@link IDeviceBuildInfo} is passing through we attempt to add the external 1669 * directories to it when they are available. 1670 */ 1671 public void testInvoke_deviceInfoBuild_withEnv() throws Throwable { 1672 File tmpTestsDir = FileUtil.createTempDir("invocation-tests-dir"); 1673 File tmpExternalTestsDir = FileUtil.createTempDir("external-tf-dir"); 1674 File tmpTestsFile = FileUtil.createTempFile("testsfile", "txt", tmpExternalTestsDir); 1675 try { 1676 mTestInvocation = 1677 new TestInvocation() { 1678 @Override 1679 ILogRegistry getLogRegistry() { 1680 return mMockLogRegistry; 1681 } 1682 1683 @Override 1684 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 1685 return new InvocationExecution() { 1686 @Override 1687 protected IShardHelper createShardHelper() { 1688 return new ShardHelper(); 1689 } 1690 1691 @Override 1692 File getExternalTestCasesDirs(EnvVariable envVar) { 1693 if (EnvVariable.ANDROID_TARGET_OUT_TESTCASES.equals(envVar)) { 1694 return tmpExternalTestsDir; 1695 } 1696 return null; 1697 } 1698 }; 1699 } 1700 1701 @Override 1702 protected void setExitCode(ExitCode code, Throwable stack) { 1703 // empty on purpose 1704 } 1705 1706 @Override 1707 InvocationScope getInvocationScope() { 1708 // Avoid re-entry in the current TF invocation scope for unit tests. 1709 return new InvocationScope(); 1710 } 1711 }; 1712 mMockBuildInfo = EasyMock.createMock(IDeviceBuildInfo.class); 1713 IRemoteTest test = EasyMock.createNiceMock(IRemoteTest.class); 1714 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 1715 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 1716 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 1717 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 1718 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, null); 1719 mStubConfiguration.getTargetPreparers().add(mockCleaner); 1720 1721 mMockBuildInfo.setFile( 1722 EasyMock.contains(BuildInfoFileKey.TARGET_LINKED_DIR.getFileKey()), 1723 EasyMock.anyObject(), 1724 EasyMock.eq("v1")); 1725 EasyMock.expect(((IDeviceBuildInfo) mMockBuildInfo).getTestsDir()) 1726 .andReturn(tmpTestsDir); 1727 EasyMock.expect(mMockBuildInfo.getProperties()).andStubReturn(new HashSet<>()); 1728 1729 setupMockSuccessListeners(); 1730 setupNormalInvoke(test); 1731 EasyMock.replay(mockCleaner, mockRescheduler); 1732 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1733 verifyMocks(mockCleaner, mockRescheduler); 1734 verifySummaryListener(); 1735 // Check that the external directory was copied in the testsDir. 1736 assertTrue(tmpTestsDir.listFiles().length == 1); 1737 // external-tf-dir - the symlink is the original file name + randomized sequence 1738 assertTrue( 1739 tmpTestsDir 1740 .listFiles()[0] 1741 .getName() 1742 .startsWith(BuildInfoFileKey.TARGET_LINKED_DIR.getFileKey())); 1743 // testsfile.txt 1744 assertTrue(tmpTestsDir.listFiles()[0].listFiles().length == 1); 1745 assertEquals( 1746 tmpTestsFile.getName(), tmpTestsDir.listFiles()[0].listFiles()[0].getName()); 1747 } finally { 1748 FileUtil.recursiveDelete(tmpTestsDir); 1749 FileUtil.recursiveDelete(tmpExternalTestsDir); 1750 } 1751 } 1752 1753 /** 1754 * Test when a {@link IDeviceBuildInfo} is passing through we do not attempt to add the external 1755 * directories to it, since {@link BuildInfoProperties} is set to skip the linking. 1756 */ 1757 public void testInvoke_deviceInfoBuild_withEnv_andSkipProperty() throws Throwable { 1758 File tmpTestsDir = FileUtil.createTempDir("invocation-tests-dir"); 1759 File tmpExternalTestsDir = FileUtil.createTempDir("external-tf-dir"); 1760 FileUtil.createTempFile("testsfile", "txt", tmpExternalTestsDir); 1761 try { 1762 mTestInvocation = 1763 new TestInvocation() { 1764 @Override 1765 ILogRegistry getLogRegistry() { 1766 return mMockLogRegistry; 1767 } 1768 1769 @Override 1770 public IInvocationExecution createInvocationExec(boolean isSandboxed) { 1771 return new InvocationExecution() { 1772 @Override 1773 protected IShardHelper createShardHelper() { 1774 return new ShardHelper(); 1775 } 1776 1777 @Override 1778 File getExternalTestCasesDirs(EnvVariable envVar) { 1779 return tmpExternalTestsDir; 1780 } 1781 }; 1782 } 1783 1784 @Override 1785 protected void setExitCode(ExitCode code, Throwable stack) { 1786 // empty on purpose 1787 } 1788 1789 @Override 1790 InvocationScope getInvocationScope() { 1791 // Avoid re-entry in the current TF invocation scope for unit tests. 1792 return new InvocationScope(); 1793 } 1794 }; 1795 mMockBuildInfo = EasyMock.createMock(IDeviceBuildInfo.class); 1796 IRemoteTest test = EasyMock.createNiceMock(IRemoteTest.class); 1797 ITargetCleaner mockCleaner = EasyMock.createMock(ITargetCleaner.class); 1798 EasyMock.expect(mockCleaner.isDisabled()).andReturn(false).times(2); 1799 EasyMock.expect(mockCleaner.isTearDownDisabled()).andReturn(false); 1800 mockCleaner.setUp(mMockDevice, mMockBuildInfo); 1801 mockCleaner.tearDown(mMockDevice, mMockBuildInfo, null); 1802 mStubConfiguration.getTargetPreparers().add(mockCleaner); 1803 1804 Set<BuildInfoProperties> prop = new HashSet<>(); 1805 prop.add(BuildInfoProperties.DO_NOT_LINK_TESTS_DIR); 1806 EasyMock.expect(mMockBuildInfo.getProperties()).andStubReturn(prop); 1807 1808 setupMockSuccessListeners(); 1809 setupNormalInvoke(test); 1810 EasyMock.replay(mockCleaner, mockRescheduler); 1811 mTestInvocation.invoke(mStubInvocationMetadata, mStubConfiguration, mockRescheduler); 1812 verifyMocks(mockCleaner, mockRescheduler); 1813 verifySummaryListener(); 1814 // Check that the external directory was NOT copied in the testsDir. 1815 assertTrue(tmpTestsDir.listFiles().length == 0); 1816 } finally { 1817 FileUtil.recursiveDelete(tmpTestsDir); 1818 FileUtil.recursiveDelete(tmpExternalTestsDir); 1819 } 1820 } 1821 1822 public static class TestableCollector extends BaseDeviceMetricCollector { 1823 1824 @Option(name = "name") 1825 private String mName; 1826 1827 public TestableCollector() {} 1828 1829 public TestableCollector(String name) { 1830 mName = name; 1831 } 1832 1833 @Override 1834 public void onTestRunEnd( 1835 DeviceMetricData runData, final Map<String, Metric> currentRunMetrics) { 1836 runData.addMetric( 1837 mName, 1838 Metric.newBuilder() 1839 .setMeasurements( 1840 Measurements.newBuilder().setSingleString(mName).build())); 1841 } 1842 } 1843 1844 /** 1845 * Test that when {@link IMetricCollector} are used, they wrap and call in sequence the listener 1846 * so all metrics end up on the final receiver. 1847 */ 1848 public void testMetricCollectionChain() throws Exception { 1849 IConfiguration configuration = new Configuration("test", "description"); 1850 StubTest test = new StubTest(); 1851 OptionSetter setter = new OptionSetter(test); 1852 setter.setOptionValue("run-a-test", "true"); 1853 configuration.setTest(test); 1854 1855 List<IMetricCollector> collectors = new ArrayList<>(); 1856 collectors.add(new TestableCollector("collector1")); 1857 collectors.add(new TestableCollector("collector2")); 1858 collectors.add(new TestableCollector("collector3")); 1859 collectors.add(new TestableCollector("collector4")); 1860 configuration.setDeviceMetricCollectors(collectors); 1861 1862 mMockTestListener.testRunStarted("TestStub", 1); 1863 TestDescription testId = new TestDescription("StubTest", "StubMethod"); 1864 mMockTestListener.testStarted(EasyMock.eq(testId), EasyMock.anyLong()); 1865 mMockTestListener.testEnded( 1866 EasyMock.eq(testId), 1867 EasyMock.anyLong(), 1868 EasyMock.eq(new HashMap<String, Metric>())); 1869 Capture<HashMap<String, Metric>> captured = new Capture<>(); 1870 mMockTestListener.testRunEnded(EasyMock.anyLong(), EasyMock.capture(captured)); 1871 EasyMock.replay(mMockTestListener); 1872 new InvocationExecution() 1873 .runTests(mStubInvocationMetadata, configuration, mMockTestListener); 1874 EasyMock.verify(mMockTestListener); 1875 // The collectors are called in sequence 1876 List<String> listKeys = new ArrayList<>(captured.getValue().keySet()); 1877 assertEquals(4, listKeys.size()); 1878 assertEquals("collector4", listKeys.get(0)); 1879 assertEquals("collector3", listKeys.get(1)); 1880 assertEquals("collector2", listKeys.get(2)); 1881 assertEquals("collector1", listKeys.get(3)); 1882 } 1883 } 1884