@VisibleForTesting static boolean isTestRunRequiredForTest( TestRule test, BuildEngine cachingBuildEngine, ExecutionContext executionContext, TestRuleKeyFileHelper testRuleKeyFileHelper, boolean isResultsCacheEnabled, boolean isRunningWithTestSelectors) throws IOException, ExecutionException, InterruptedException { boolean isTestRunRequired; BuildResult result; if (executionContext.isDebugEnabled()) { // If debug is enabled, then we should always run the tests as the user is expecting to // hook up a debugger. isTestRunRequired = true; } else if (isRunningWithTestSelectors) { // As a feature to aid developers, we'll assume that when we are using test selectors, // we should always run each test (and never look at the cache.) // TODO(user) When #3090004 and #3436849 are closed we can respect the cache again. isTestRunRequired = true; } else if (((result = cachingBuildEngine.getBuildRuleResult(test.getBuildTarget())) != null) && result.getSuccess() == BuildRuleSuccessType.MATCHING_RULE_KEY && isResultsCacheEnabled && test.hasTestResultFiles(executionContext) && testRuleKeyFileHelper.isRuleKeyInDir(test)) { // If this build rule's artifacts (which includes the rule's output and its test result // files) are up to date, then no commands are necessary to run the tests. The test result // files will be read from the XML files in interpretTestResults(). isTestRunRequired = false; } else { isTestRunRequired = true; } return isTestRunRequired; }
@Test public void testIsTestRunRequiredForTestBuiltLocally() throws IOException, ExecutionException, InterruptedException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); FakeTestRule testRule = new FakeTestRule( ImmutableSet.<Label>of(Label.of("windows")), BuildTargetFactory.newInstance("//:lulz"), new SourcePathResolver(new BuildRuleResolver()), ImmutableSortedSet.<BuildRule>of()); CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class); BuildResult result = new BuildResult(testRule, BUILT_LOCALLY, CacheResult.skip()); expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz"))) .andReturn(result); replay(executionContext, cachingBuildEngine); assertTrue( "A test built locally should always run regardless of any cached result. ", TestRunning.isTestRunRequiredForTest( testRule, cachingBuildEngine, executionContext, createMock(TestRuleKeyFileHelper.class), /* results cache enabled */ true, /* running with test selectors */ false)); verify(executionContext, cachingBuildEngine); }
@Test public void testIsTestRunRequiredForTestBuiltFromCacheIfHasTestResultFiles() throws IOException, ExecutionException, InterruptedException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); FakeTestRule testRule = new FakeTestRule( ImmutableSet.<Label>of(Label.of("windows")), BuildTargetFactory.newInstance("//:lulz"), new SourcePathResolver(new BuildRuleResolver()), ImmutableSortedSet.<BuildRule>of()); CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class); BuildResult result = new BuildResult(testRule, FETCHED_FROM_CACHE, CacheResult.hit("dir")); expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz"))) .andReturn(result); replay(executionContext, cachingBuildEngine); assertTrue( "A cache hit updates the build artifact but not the test results. " + "Therefore, the test should be re-run to ensure the test results are up to date.", TestRunning.isTestRunRequiredForTest( testRule, cachingBuildEngine, executionContext, createMock(TestRuleKeyFileHelper.class), /* results cache enabled */ true, /* running with test selectors */ false)); verify(executionContext, cachingBuildEngine); }
@Test public void testIsTestRunRequiredForTestInDebugMode() throws IOException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(true); replay(executionContext); assertTrue( "In debug mode, test should always run regardless of any cached results since " + "the user is expecting to hook up a debugger.", TestCommand.isTestRunRequiredForTest( createMock(TestRule.class), executionContext, createMock(TestRuleKeyFileHelper.class))); verify(executionContext); }
@Test public void testIsTestRunRequiredForTestBuiltLocally() throws IOException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); TestRule testRule = createMock(TestRule.class); expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.BUILT_LOCALLY); replay(executionContext, testRule); assertTrue( "A test built locally should always run regardless of any cached result. ", TestCommand.isTestRunRequiredForTest( testRule, executionContext, createMock(TestRuleKeyFileHelper.class))); verify(executionContext, testRule); }
@Test public void testIsTestRunRequiredForTestBuiltFromCacheIfHasTestResultFiles() throws IOException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); TestRule testRule = createMock(TestRule.class); expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.FETCHED_FROM_CACHE); replay(executionContext, testRule); assertTrue( "A cache hit updates the build artifact but not the test results. " + "Therefore, the test should be re-run to ensure the test results are up to date.", TestCommand.isTestRunRequiredForTest( testRule, executionContext, createMock(TestRuleKeyFileHelper.class))); verify(executionContext, testRule); }
@Test public void testIsTestRunRequiredIfRuleKeyNotPresent() throws IOException, ExecutionException, InterruptedException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); FakeTestRule testRule = new FakeTestRule( ImmutableSet.<Label>of(Label.of("windows")), BuildTargetFactory.newInstance("//:lulz"), new SourcePathResolver(new BuildRuleResolver()), ImmutableSortedSet.<BuildRule>of()) { @Override public boolean hasTestResultFiles(ExecutionContext context) { return true; } }; TestRuleKeyFileHelper testRuleKeyFileHelper = createNiceMock(TestRuleKeyFileHelper.class); expect(testRuleKeyFileHelper.isRuleKeyInDir(testRule)).andReturn(false); CachingBuildEngine cachingBuildEngine = createMock(CachingBuildEngine.class); BuildResult result = new BuildResult(testRule, MATCHING_RULE_KEY, CacheResult.skip()); expect(cachingBuildEngine.getBuildRuleResult(BuildTargetFactory.newInstance("//:lulz"))) .andReturn(result); replay(executionContext, cachingBuildEngine, testRuleKeyFileHelper); assertTrue( "A cached build should run the tests if the test output directory\'s rule key is not " + "present or does not matche the rule key for the test.", TestRunning.isTestRunRequiredForTest( testRule, cachingBuildEngine, executionContext, testRuleKeyFileHelper, /* results cache enabled */ true, /* running with test selectors */ false)); verify(executionContext, cachingBuildEngine, testRuleKeyFileHelper); }
@Test public void testIsTestRunRequiredIfRuleKeyNotPresent() throws IOException { ExecutionContext executionContext = createMock(ExecutionContext.class); expect(executionContext.isDebugEnabled()).andReturn(false); TestRule testRule = createNiceMock(TestRule.class); expect(testRule.getBuildResultType()).andReturn(BuildRuleSuccess.Type.MATCHING_RULE_KEY); expect(testRule.hasTestResultFiles(executionContext)).andReturn(true); TestRuleKeyFileHelper testRuleKeyFileHelper = createNiceMock(TestRuleKeyFileHelper.class); expect(testRuleKeyFileHelper.isRuleKeyInDir(testRule)).andReturn(false); replay(executionContext, testRule, testRuleKeyFileHelper); assertTrue( "A cached build should run the tests if the test output directory\'s rule key is not " + "present or does not matche the rule key for the test.", TestCommand.isTestRunRequiredForTest(testRule, executionContext, testRuleKeyFileHelper)); verify(executionContext, testRule, testRuleKeyFileHelper); }