aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4
diff options
context:
space:
mode:
Diffstat (limited to 'src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4')
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java201
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java118
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java133
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java628
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java172
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java42
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java44
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java44
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java45
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java62
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java43
-rw-r--r--src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java51
12 files changed, 1583 insertions, 0 deletions
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java
new file mode 100644
index 0000000000..02c18746f4
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java
@@ -0,0 +1,201 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.internal.junit4.CancellableRequestFactory;
+import com.google.testing.junit.runner.model.AntXmlResultWriterFactory;
+import com.google.testing.junit.runner.model.TestSuiteModel;
+import com.google.testing.junit.runner.model.TestSuiteModelBuilderFactory;
+import com.google.testing.junit.runner.model.XmlResultWriter;
+import com.google.testing.junit.runner.sharding.ShardingEnvironment;
+import com.google.testing.junit.runner.sharding.ShardingFilters;
+import com.google.testing.junit.runner.util.MemoizingSupplier;
+import com.google.testing.junit.runner.util.SetFactory;
+import com.google.testing.junit.runner.util.Supplier;
+import com.google.testing.junit.runner.util.Ticker;
+import java.io.PrintStream;
+import java.util.Set;
+import org.junit.internal.TextListener;
+import org.junit.runner.Request;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * Utility class to create a JUnit4Runner instance from a {@link Builder} for testing purposes. All
+ * required dependencies are being injected automatically.
+ */
+public final class JUnit4BazelMock {
+ private Supplier<Class<?>> topLevelSuiteSupplier;
+
+ private Supplier<Request> requestMemoizingSupplier;
+
+ private Supplier<CancellableRequestFactory> cancellableRequestFactorySupplier;
+
+ private Supplier<String> topLevelSuiteNameSupplier;
+
+ private Supplier<Ticker> tickerSupplier;
+
+ private Supplier<ShardingEnvironment> shardingEnvironmentSupplier;
+
+ private Supplier<ShardingFilters> shardingFiltersSupplier;
+
+ private Supplier<XmlResultWriter> xmlResultWriterSupplier;
+
+ private Supplier<TestSuiteModel.Builder> builderSupplier;
+
+ private Supplier<JUnit4TestModelBuilder> jUnit4TestModelBuilderMemoizingSupplier;
+
+ private Supplier<Supplier<TestSuiteModel>> provideTestSuiteModelSupplierMemoizingSupplier;
+
+ private Supplier<PrintStream> stdoutStreamMemoizingSupplier;
+
+ private Supplier<JUnit4Config> configSupplier;
+
+ private Supplier<Set<RunListener>> mockRunListenerSupplier;
+
+ private Supplier<TextListener> textListenerMemoizingSupplier;
+
+ private Supplier<RunListener> textListenerSupplier;
+
+ private Supplier<Set<RunListener>> setOfRunListenerSupplier;
+
+ private Supplier<JUnit4Runner> jUnit4RunnerProvider;
+
+ private JUnit4BazelMock(Builder builder) {
+ assert builder != null;
+ initialize(builder);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void initialize(final Builder builder) {
+
+ this.topLevelSuiteSupplier = TopLevelSuiteFactory.create(builder.suiteClass);
+
+ this.requestMemoizingSupplier =
+ new MemoizingSupplier<>(RequestFactory.create(topLevelSuiteSupplier));
+
+ this.cancellableRequestFactorySupplier =
+ new MemoizingSupplier<>(CancellableRequestFactoryFactory.create());
+
+ this.topLevelSuiteNameSupplier = TopLevelSuiteNameFactory.create(topLevelSuiteSupplier);
+
+ this.tickerSupplier =
+ new MemoizingSupplier<>(TestModuleTickerFactory.create(builder.testModule));
+
+ this.shardingEnvironmentSupplier =
+ TestModuleShardingEnvironmentFactory.create(builder.testModule);
+
+ this.shardingFiltersSupplier =
+ TestModuleShardingFiltersFactory.create(
+ builder.testModule,
+ shardingEnvironmentSupplier,
+ ShardingFilterFactoryFactory.create());
+
+ this.xmlResultWriterSupplier =
+ TestModuleXmlResultWriterFactory.create(
+ builder.testModule, AntXmlResultWriterFactory.create());
+
+ this.builderSupplier =
+ TestSuiteModelBuilderFactory.create(
+ tickerSupplier,
+ shardingFiltersSupplier,
+ shardingEnvironmentSupplier,
+ xmlResultWriterSupplier);
+
+ this.jUnit4TestModelBuilderMemoizingSupplier =
+ new MemoizingSupplier<>(JUnit4TestModelBuilderFactory.create(
+ requestMemoizingSupplier, topLevelSuiteNameSupplier, builderSupplier));
+
+ this.provideTestSuiteModelSupplierMemoizingSupplier =
+ new MemoizingSupplier<>(TestSuiteModelSupplierFactory.create(
+ jUnit4TestModelBuilderMemoizingSupplier));
+
+ this.stdoutStreamMemoizingSupplier =
+ new MemoizingSupplier<>(TestModuleProvideStdoutStreamFactory.create(builder.testModule));
+
+ this.configSupplier = TestModuleConfigFactory.create(builder.testModule);
+
+ this.mockRunListenerSupplier =
+ TestModuleMockRunListenerFactory.create(builder.testModule);
+
+ this.textListenerMemoizingSupplier =
+ new MemoizingSupplier<>(ProvideTextListenerFactory.create(stdoutStreamMemoizingSupplier));
+
+ this.textListenerSupplier = TextListenerFactory.create(textListenerMemoizingSupplier);
+
+ this.setOfRunListenerSupplier =
+ SetFactory.<RunListener>builder(1, 1)
+ .addCollectionSupplier(mockRunListenerSupplier)
+ .addSupplier(textListenerSupplier)
+ .build();
+
+ this.jUnit4RunnerProvider =
+ JUnit4RunnerFactory.create(
+ requestMemoizingSupplier,
+ cancellableRequestFactorySupplier,
+ provideTestSuiteModelSupplierMemoizingSupplier,
+ stdoutStreamMemoizingSupplier,
+ configSupplier,
+ setOfRunListenerSupplier,
+ SetFactory.<JUnit4Runner.Initializer>empty());
+ }
+
+ public JUnit4Runner runner() {
+ return jUnit4RunnerProvider.get();
+ }
+
+ public CancellableRequestFactory cancellableRequestFactory() {
+ return cancellableRequestFactorySupplier.get();
+ }
+
+ public static final class Builder {
+ private JUnit4InstanceModules.SuiteClass suiteClass;
+
+ private JUnit4RunnerTest.TestModule testModule;
+
+ private Builder() {}
+
+ public JUnit4BazelMock build() {
+ if (suiteClass == null) {
+ throw new IllegalStateException(
+ JUnit4InstanceModules.SuiteClass.class.getCanonicalName() + " must be set");
+ }
+ if (testModule == null) {
+ throw new IllegalStateException(
+ JUnit4RunnerTest.TestModule.class.getCanonicalName() + " must be set");
+ }
+ return new JUnit4BazelMock(this);
+ }
+
+ public Builder testModule(JUnit4RunnerTest.TestModule testModule) {
+ if (testModule == null) {
+ throw new NullPointerException();
+ }
+ this.testModule = testModule;
+ return this;
+ }
+
+ public Builder suiteClass(JUnit4InstanceModules.SuiteClass suiteClass) {
+ if (suiteClass == null) {
+ throw new NullPointerException();
+ }
+ this.suiteClass = suiteClass;
+ return this;
+ }
+ }
+}
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java
new file mode 100644
index 0000000000..9ddc682657
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java
@@ -0,0 +1,118 @@
+// Copyright 2010 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import static com.google.testing.junit.runner.junit4.JUnit4Config.JUNIT_API_VERSION_PROPERTY;
+import static com.google.testing.junit.runner.junit4.JUnit4Config.SHOULD_INSTALL_SECURITY_MANAGER_PROPERTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.testing.junit.runner.util.GoogleTestSecurityManager;
+import java.util.Properties;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link JUnit4Config}.
+ */
+@RunWith(JUnit4.class)
+public class JUnit4ConfigTest {
+
+ private JUnit4Config createConfigWithApiVersion(String apiVersion) {
+ Properties properties = new Properties();
+ properties.put(JUNIT_API_VERSION_PROPERTY, apiVersion);
+ return createConfigWithProperties(properties);
+ }
+
+ private JUnit4Config createConfigWithProperties(Properties properties) {
+ return new JUnit4Config("", null, null, properties);
+ }
+
+ @Test
+ public void testGetJUnitRunnerApiVersion_defaultValue() {
+ JUnit4Config config = createConfigWithApiVersion("1");
+ assertEquals(1, config.getJUnitRunnerApiVersion());
+ }
+
+ @Test
+ public void testGetJUnitRunnerApiVersion_failsIfNotNumeric() {
+ JUnit4Config config = createConfigWithApiVersion("I love pesto");
+
+ try {
+ config.getJUnitRunnerApiVersion();
+ fail("exception expected");
+ } catch (IllegalStateException expected) {
+ assertTrue(expected.getMessage().contains("I love pesto"));
+ }
+ }
+
+ @Test
+ public void testGetJUnitRunnerApiVersion_failsIfNotAnInteger() {
+ JUnit4Config config = createConfigWithApiVersion("3.14");
+
+ try {
+ config.getJUnitRunnerApiVersion();
+ fail("exception expected");
+ } catch (IllegalStateException expected) {
+ assertTrue(expected.getMessage().contains("3.14"));
+ }
+ }
+
+ @Test
+ public void testGetJUnitRunnerApiVersion_failsIfNotOne() {
+ JUnit4Config config = createConfigWithApiVersion("13");
+
+ try {
+ config.getJUnitRunnerApiVersion();
+ fail("exception expected");
+ } catch (IllegalStateException expected) {
+ assertTrue(expected.getMessage().contains("13"));
+ }
+ }
+
+ @Test
+ public void testGetJUnitRunnerApiVersion_oneIsValid() {
+ JUnit4Config config = createConfigWithApiVersion("1");
+ assertEquals(1, config.getJUnitRunnerApiVersion());
+ }
+
+ @Test
+ public void testShouldInstallSecurityManager_defaultValue() {
+ GoogleTestSecurityManager.uninstallIfInstalled();
+
+ JUnit4Config config = createConfigWithProperties(new Properties());
+ assertTrue(config.shouldInstallSecurityManager());
+ }
+
+ @Test
+ public void testShouldInstallSecurityManager_securityManagerPropertySet() {
+ Properties properties = new Properties();
+ properties.put("java.security.manager", "MySecurityManager");
+ properties.put(SHOULD_INSTALL_SECURITY_MANAGER_PROPERTY, "true");
+ JUnit4Config config = createConfigWithProperties(properties);
+ assertFalse(config.shouldInstallSecurityManager());
+ }
+
+ @Test
+ public void testShouldInstallSecurityManager_shouldInstallSecurityManagerPropertySetToFalse() {
+ Properties properties = new Properties();
+ properties.put(SHOULD_INSTALL_SECURITY_MANAGER_PROPERTY, "false");
+ JUnit4Config config = createConfigWithProperties(properties);
+ assertFalse(config.shouldInstallSecurityManager());
+ }
+}
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java
new file mode 100644
index 0000000000..699c5883bb
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java
@@ -0,0 +1,133 @@
+// Copyright 2011 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link JUnit4Options}
+ */
+@RunWith(JUnit4.class)
+public class JUnit4OptionsTest {
+
+ private static final Map<String, String> EMPTY_ENV = Collections.emptyMap();
+
+ @Test
+ public void testParse_noArgs() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(EMPTY_ENV, ImmutableList.<String>of());
+ assertNull(options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_onlyUnparsedArgs() {
+ JUnit4Options options = JUnit4Options.parse(EMPTY_ENV, ImmutableList.of("--bar", "baz"));
+ assertNull(options.getTestIncludeFilter());
+ assertArrayEquals(new String[] {"--bar", "baz"}, options.getUnparsedArgs());
+ }
+
+ @Test
+ public void testParse_withTwoArgTestFilter() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(
+ EMPTY_ENV, ImmutableList.of("--test_filter", "foo"));
+ assertEquals("foo", options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_withOneArgTestFilter() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(EMPTY_ENV, ImmutableList.of("--test_filter=foo"));
+ assertEquals("foo", options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_testFilterAndUnparsedArgs() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(
+ EMPTY_ENV, ImmutableList.of("--bar", "--test_filter=foo", "--baz"));
+ assertEquals("foo", options.getTestIncludeFilter());
+ assertArrayEquals(new String[] {"--bar", "--baz"}, options.getUnparsedArgs());
+ }
+
+ @Test
+ public void testParse_testLastTestFilterWins() throws Exception {
+ JUnit4Options options =
+ JUnit4Options.parse(EMPTY_ENV, ImmutableList.of("--test_filter=foo", "--test_filter=bar"));
+ assertEquals("bar", options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_testFilterMissingSecondArg() throws Exception {
+ try {
+ JUnit4Options.parse(EMPTY_ENV, ImmutableList.of("--test_filter"));
+ fail();
+ } catch (RuntimeException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testParse_testFilterExcludeWithTwoArgTestFilter() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(
+ EMPTY_ENV, ImmutableList.of("--test_exclude_filter", "foo"));
+ assertEquals("foo", options.getTestExcludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_testFilterExcludewithOneArgTestFilter() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(
+ EMPTY_ENV, ImmutableList.of("--test_exclude_filter=foo"));
+ assertEquals("foo", options.getTestExcludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_unknownOptionName() throws Exception {
+ JUnit4Options options = JUnit4Options.parse(
+ EMPTY_ENV, ImmutableList.of("--unknown=foo"));
+ assertArrayEquals(new String[] {"--unknown=foo"}, options.getUnparsedArgs());
+ }
+
+ @Test
+ public void testParse_withTestFilterFromEnv() throws Exception {
+ Map<String, String> env = new HashMap<>();
+ env.put("TESTBRIDGE_TEST_ONLY", "foo");
+ JUnit4Options options = JUnit4Options.parse(env, ImmutableList.<String>of());
+ assertEquals("foo", options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+
+ @Test
+ public void testParse_testFilterArgOverridesEnv() throws Exception {
+ Map<String, String> env = new HashMap<>();
+ env.put("TESTBRIDGE_TEST_ONLY", "foo");
+ JUnit4Options options = JUnit4Options.parse(env, ImmutableList.of("--test_filter=bar"));
+ assertEquals("bar", options.getTestIncludeFilter());
+ assertEquals(0, options.getUnparsedArgs().length);
+ }
+}
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java
new file mode 100644
index 0000000000..6dd9bf32e2
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java
@@ -0,0 +1,628 @@
+// Copyright 2010 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteStreams;
+import com.google.testing.junit.runner.internal.SignalHandlers.HandlerInstaller;
+import com.google.testing.junit.runner.internal.junit4.CancellableRequestFactory;
+import com.google.testing.junit.runner.internal.junit4.SettableCurrentRunningTest;
+import com.google.testing.junit.runner.junit4.JUnit4InstanceModules.SuiteClass;
+import com.google.testing.junit.runner.model.AntXmlResultWriter;
+import com.google.testing.junit.runner.model.XmlResultWriter;
+import com.google.testing.junit.runner.sharding.ShardingEnvironment;
+import com.google.testing.junit.runner.sharding.ShardingFilters;
+import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory;
+import com.google.testing.junit.runner.sharding.testing.FakeShardingFilters;
+import com.google.testing.junit.runner.util.CurrentRunningTest;
+import com.google.testing.junit.runner.util.FakeTicker;
+import com.google.testing.junit.runner.util.GoogleTestSecurityManager;
+import com.google.testing.junit.runner.util.TestNameProvider;
+import com.google.testing.junit.runner.util.Ticker;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.internal.TextListener;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.StoppedByUserException;
+import org.junit.runners.JUnit4;
+import org.junit.runners.Suite;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+import sun.misc.Signal;
+import sun.misc.SignalHandler;
+
+/**
+ * Tests for {@link JUnit4Runner}
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class JUnit4RunnerTest {
+ private final ByteArrayOutputStream stdoutByteStream = new ByteArrayOutputStream();
+ private final PrintStream stdoutPrintStream = new PrintStream(stdoutByteStream, true);
+ @Mock private RunListener mockRunListener;
+ @Mock private ShardingEnvironment shardingEnvironment = new StubShardingEnvironment();
+ @Mock private ShardingFilters shardingFilters;
+ private JUnit4Config config;
+ private boolean wasSecurityManagerInstalled = false;
+ private SecurityManager previousSecurityManager;
+
+ @After
+ public void closeStream() throws Exception {
+ stdoutPrintStream.close();
+ }
+
+ @After
+ public void reinstallPreviousSecurityManager() {
+ if (wasSecurityManagerInstalled) {
+ wasSecurityManagerInstalled = false;
+ System.setSecurityManager(previousSecurityManager);
+ }
+ }
+
+ private JUnit4Runner createRunner(Class<?> suiteClass) {
+ return createComponent(suiteClass).runner();
+ }
+
+ private JUnit4BazelMock createComponent(Class<?> suiteClass) {
+ return JUnit4BazelMock.builder()
+ .suiteClass(new SuiteClass(suiteClass))
+ .testModule(new TestModule()) // instance method to support outer-class instance variables.
+ .build();
+ }
+
+ @Test
+ public void testPassingTest() throws Exception {
+ config = createConfig();
+ mockRunListener = mock(RunListener.class);
+
+ JUnit4Runner runner = createRunner(SamplePassingTest.class);
+
+ Description testDescription =
+ Description.createTestDescription(SamplePassingTest.class, "testThatAlwaysPasses");
+ Description suiteDescription =
+ Description.createSuiteDescription(SamplePassingTest.class);
+ suiteDescription.addChild(testDescription);
+
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+
+ assertPassingTestHasExpectedOutput(stdoutByteStream, SamplePassingTest.class);
+
+ InOrder inOrder = inOrder(mockRunListener);
+
+ inOrder.verify(mockRunListener).testRunStarted(suiteDescription);
+ inOrder.verify(mockRunListener).testStarted(testDescription);
+ inOrder.verify(mockRunListener).testFinished(testDescription);
+ inOrder.verify(mockRunListener).testRunFinished(any(Result.class));
+ }
+
+ @Test
+ public void testFailingTest() throws Exception {
+ config = createConfig();
+ mockRunListener = mock(RunListener.class);
+
+ JUnit4Runner runner = createRunner(SampleFailingTest.class);
+
+ Description testDescription = Description.createTestDescription(SampleFailingTest.class,
+ "testThatAlwaysFails");
+ Description suiteDescription = Description.createSuiteDescription(SampleFailingTest.class);
+ suiteDescription.addChild(testDescription);
+
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+
+ assertTrue(extractOutput(stdoutByteStream).contains(
+ "1) testThatAlwaysFails(" + SampleFailingTest.class.getName() + ")\n" +
+ "java.lang.AssertionError: expected"));
+
+ InOrder inOrder = inOrder(mockRunListener);
+
+ inOrder.verify(mockRunListener).testRunStarted(any(Description.class));
+ inOrder.verify(mockRunListener).testStarted(any(Description.class));
+ inOrder.verify(mockRunListener).testFailure(any(Failure.class));
+ inOrder.verify(mockRunListener).testFinished(any(Description.class));
+ inOrder.verify(mockRunListener).testRunFinished(any(Result.class));
+ }
+
+ @Test
+ public void testFailingInternationalCharsTest() throws Exception {
+ config = createConfig();
+ mockRunListener = mock(RunListener.class);
+
+ JUnit4Runner runner = createRunner(SampleInternationalFailingTest.class);
+
+ Description testDescription = Description.createTestDescription(
+ SampleInternationalFailingTest.class, "testFailingInternationalCharsTest");
+ Description suiteDescription = Description.createSuiteDescription(
+ SampleInternationalFailingTest.class);
+ suiteDescription.addChild(testDescription);
+
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+
+ String output = new String(stdoutByteStream.toByteArray(), StandardCharsets.UTF_8);
+ // Intentionally swapped "Test 日\u672C." / "Test \u65E5本." to make sure that the "raw"
+ // character does not get corrupted (would become ? in both cases and we would not notice).
+ assertTrue(output.contains("expected:<Test [Japan].> but was:<Test [日\u672C].>"));
+
+ InOrder inOrder = inOrder(mockRunListener);
+
+ inOrder.verify(mockRunListener).testRunStarted(any(Description.class));
+ inOrder.verify(mockRunListener).testStarted(any(Description.class));
+ inOrder.verify(mockRunListener).testFailure(any(Failure.class));
+ inOrder.verify(mockRunListener).testFinished(any(Description.class));
+ inOrder.verify(mockRunListener).testRunFinished(any(Result.class));
+ }
+
+ @Test
+ public void testInterruptedTest() throws Exception {
+ config = createConfig();
+ mockRunListener = mock(RunListener.class);
+ JUnit4BazelMock component = createComponent(SampleSuite.class);
+ JUnit4Runner runner = component.runner();
+ final CancellableRequestFactory requestFactory = component.cancellableRequestFactory();
+
+ Description testDescription = Description.createTestDescription(SamplePassingTest.class,
+ "testThatAlwaysPasses");
+
+ doAnswer(cancelTestRun(requestFactory))
+ .when(mockRunListener).testStarted(testDescription);
+
+ try {
+ runner.run();
+ fail("exception expected");
+ } catch (RuntimeException e) {
+ assertEquals("Test run interrupted", e.getMessage());
+ assertTrue("Expected cause to be a StoppedByUserException",
+ e.getCause() instanceof StoppedByUserException);
+
+ InOrder inOrder = inOrder(mockRunListener);
+ inOrder.verify(mockRunListener).testRunStarted(any(Description.class));
+ inOrder.verify(mockRunListener).testStarted(testDescription);
+ inOrder.verify(mockRunListener).testFinished(testDescription);
+ }
+ }
+
+ private static Answer<Void> cancelTestRun(final CancellableRequestFactory requestFactory) {
+ return new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ requestFactory.cancelRun();
+ return null;
+ }
+ };
+ }
+
+ @Test
+ public void testSecurityManagerInstalled() throws Exception {
+ // If there is already a security manager installed, the runner would crash when trying to
+ // install another one. In order to avoid that, the security manager should be uninstalled here
+ // and restored afterwards.
+ uninstallGoogleTestSecurityManager();
+
+ config = new JUnit4Config(null, null, null, createProperties("1", true));
+
+ JUnit4Runner runner = createRunner(SampleExitingTest.class);
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ }
+
+ @Test
+ public void testShardingIsSupported() {
+ config = createConfig();
+ shardingEnvironment = mock(ShardingEnvironment.class);
+ shardingFilters = new FakeShardingFilters(
+ Description.createTestDescription(SamplePassingTest.class, "testThatAlwaysPasses"),
+ Description.createTestDescription(SampleFailingTest.class, "testThatAlwaysFails"));
+
+ when(shardingEnvironment.isShardingEnabled()).thenReturn(true);
+
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ verify(shardingEnvironment).touchShardFile();
+
+ assertEquals(2, result.getRunCount());
+ if (result.getFailureCount() > 1) {
+ fail("Too many failures: " + result.getFailures());
+ }
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(2, runner.getModel().getNumTestCases());
+ }
+
+ @Test
+ public void testFilteringIsSupported() {
+ config = createConfig("testThatAlwaysFails");
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(
+ Description.createTestDescription(SampleFailingTest.class, "testThatAlwaysFails"),
+ result.getFailures().get(0).getDescription());
+ }
+
+ @Test
+ public void testRunFailsWithAllTestsFilteredOut() {
+ config = createConfig("doesNotMatchAnything");
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertTrue(result.getFailures().get(0).getMessage().contains("No tests found"));
+ }
+
+ @Test
+ public void testRunExcludeFilterAlwaysExits() {
+ config = new JUnit4Config("test", "CallsSystemExit", null, createProperties("1", false));
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ assertEquals(2, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(
+ Description.createTestDescription(SampleFailingTest.class, "testThatAlwaysFails"),
+ result.getFailures().get(0).getDescription());
+ }
+
+ @Test
+ public void testFilteringAndShardingTogetherIsSupported() {
+ config = createConfig("testThatAlways(Passes|Fails)");
+ shardingEnvironment = mock(ShardingEnvironment.class);
+ shardingFilters = new FakeShardingFilters(
+ Description.createTestDescription(SamplePassingTest.class, "testThatAlwaysPasses"),
+ Description.createTestDescription(SampleFailingTest.class, "testThatAlwaysFails"));
+
+ when(shardingEnvironment.isShardingEnabled()).thenReturn(true);
+
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ verify(shardingEnvironment).touchShardFile();
+
+ assertEquals(2, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(
+ Description.createTestDescription(SampleFailingTest.class, "testThatAlwaysFails"),
+ result.getFailures().get(0).getDescription());
+ }
+
+ @Test
+ public void testRunPassesWhenNoTestsOnCurrentShardWithFiltering() {
+ config = createConfig("testThatAlwaysFails");
+ shardingEnvironment = mock(ShardingEnvironment.class);
+ shardingFilters = new FakeShardingFilters(
+ Description.createTestDescription(SamplePassingTest.class, "testThatAlwaysPasses"));
+
+ when(shardingEnvironment.isShardingEnabled()).thenReturn(true);
+
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ verify(shardingEnvironment).touchShardFile();
+
+ assertEquals(0, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ }
+
+ @Test
+ public void testRunFailsWhenNoTestsOnCurrentShardWithoutFiltering() {
+ config = createConfig();
+ shardingEnvironment = mock(ShardingEnvironment.class);
+ shardingFilters = mock(ShardingFilters.class);
+
+ when(shardingEnvironment.isShardingEnabled()).thenReturn(true);
+ when(shardingFilters.createShardingFilter(anyListOf(Description.class)))
+ .thenReturn(new NoneShallPassFilter());
+
+ JUnit4Runner runner = createRunner(SampleSuite.class);
+ Result result = runner.run();
+
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertTrue(result.getFailures().get(0).getMessage().contains("No tests found"));
+
+ verify(shardingEnvironment).touchShardFile();
+ verify(shardingFilters).createShardingFilter(anyListOf(Description.class));
+ }
+
+ @Test
+ public void testMustSpecifySupportedJUnitApiVersion() {
+ config = new JUnit4Config(null, null, null, createProperties("2", false));
+ JUnit4Runner runner = createRunner(SamplePassingTest.class);
+
+ try {
+ runner.run();
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).startsWith("Unsupported JUnit Runner API version");
+ }
+ }
+
+ /**
+ * Uninstall {@link GoogleTestSecurityManager} if it is installed. If it was installed, it will
+ * be reinstalled after the test completes.
+ */
+ private void uninstallGoogleTestSecurityManager() {
+ previousSecurityManager = System.getSecurityManager();
+ GoogleTestSecurityManager.uninstallIfInstalled();
+ if (previousSecurityManager != System.getSecurityManager()) {
+ wasSecurityManagerInstalled = true;
+ }
+ }
+
+ private void assertPassingTestHasExpectedOutput(ByteArrayOutputStream outputStream,
+ Class<?> testClass) {
+ ByteArrayOutputStream expectedOutputStream = getExpectedOutput(testClass);
+
+ assertEquals(extractOutput(expectedOutputStream), extractOutput(outputStream));
+ }
+
+ private String extractOutput(ByteArrayOutputStream outputStream) {
+ String output = new String(outputStream.toByteArray(), Charset.defaultCharset());
+ return output.replaceFirst("\nTime: .*\n", "\nTime: 0\n");
+ }
+
+ private ByteArrayOutputStream getExpectedOutput(Class<?> testClass) {
+ JUnitCore core = new JUnitCore();
+
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ PrintStream printStream = new PrintStream(byteStream);
+ printStream.println("JUnit4 Test Runner");
+ RunListener listener = new TextListener(printStream);
+ core.addListener(listener);
+
+ Request request = Request.classWithoutSuiteMethod(testClass);
+
+ core.run(request);
+ printStream.close();
+
+ return byteStream;
+ }
+
+ private static JUnit4Config createConfig() {
+ return createConfig(null);
+ }
+
+ private static JUnit4Config createConfig(@Nullable String includeFilter) {
+ return new JUnit4Config(includeFilter, null, null, createProperties("1", false));
+ }
+
+ private static Properties createProperties(
+ String apiVersion, boolean shouldInstallSecurityManager) {
+ Properties properties = new Properties();
+ properties.setProperty(JUnit4Config.JUNIT_API_VERSION_PROPERTY, apiVersion);
+ if (!shouldInstallSecurityManager) {
+ properties.setProperty("java.security.manager", "whatever");
+ }
+ return properties;
+ }
+
+ /** Sample test that passes. */
+ @RunWith(JUnit4.class)
+ public static class SamplePassingTest {
+
+ @Test
+ public void testThatAlwaysPasses() {
+ }
+ }
+
+
+ /** Sample test that fails. */
+ @RunWith(JUnit4.class)
+ public static class SampleFailingTest {
+
+ @Test
+ public void testThatAlwaysFails() {
+ org.junit.Assert.fail("expected");
+ }
+ }
+
+
+ /** Sample test that fails and shows international text without corrupting it. */
+ @RunWith(JUnit4.class)
+ public static class SampleInternationalFailingTest {
+
+ @Test
+ public void testThatAlwaysFails() {
+ assertEquals("Test Japan.", "Test \u65E5本.");
+ }
+ }
+
+
+ /** Sample test that calls System.exit(). */
+ @RunWith(JUnit4.class)
+ public static class SampleExitingTest {
+
+ @Test
+ public void testThatAlwaysCallsSystemExit() {
+ System.exit(1);
+ }
+ }
+
+
+ /** Sample suite. */
+ @RunWith(Suite.class)
+ @Suite.SuiteClasses({
+ JUnit4RunnerTest.SamplePassingTest.class,
+ JUnit4RunnerTest.SampleFailingTest.class,
+ JUnit4RunnerTest.SampleExitingTest.class
+ })
+ public static class SampleSuite {}
+
+
+ private static class StubShardingEnvironment extends ShardingEnvironment {
+
+ @Override
+ public boolean isShardingEnabled() {
+ return false;
+ }
+
+ @Override
+ public int getShardIndex() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getTotalShards() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void touchShardFile() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getTestShardingStrategy() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ /**
+ * Filter that won't run any tests.
+ */
+ private static class NoneShallPassFilter extends Filter {
+
+ @Override
+ public boolean shouldRun(Description description) {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return "none-shall-pass filter";
+ }
+ }
+
+
+ private static class StubHandlerInstaller implements HandlerInstaller {
+
+ @Override
+ public SignalHandler install(Signal signal, SignalHandler handler) {
+ return null;
+ }
+ }
+
+
+ class TestModule {
+
+ ShardingEnvironment shardingEnvironment() {
+ return shardingEnvironment;
+ }
+
+ Ticker ticker() {
+ return new FakeTicker();
+ }
+
+ JUnit4Config config() {
+ return config;
+ }
+
+ HandlerInstaller handlerInstaller() {
+ return new StubHandlerInstaller();
+ }
+
+ OutputStream xmlOutputStream() {
+ return ByteStreams.nullOutputStream();
+ }
+
+ XmlResultWriter xmlResultWriter(AntXmlResultWriter impl) {
+ return impl;
+ }
+
+ Set<RunListener> mockRunListener() {
+ return (mockRunListener == null)
+ ? ImmutableSet.<RunListener>of()
+ : ImmutableSet.of(mockRunListener);
+ }
+
+ ShardingFilters shardingFilters(
+ ShardingEnvironment shardingEnvironment, ShardingFilterFactory defaultShardingStrategy) {
+ return (shardingFilters == null)
+ ? new ShardingFilters(shardingEnvironment, defaultShardingStrategy)
+ : shardingFilters;
+ }
+
+ PrintStream provideStdoutStream() {
+ return new PrintStream(stdoutByteStream);
+ }
+
+ PrintStream provideStderrStream() {
+ return new PrintStream(ByteStreams.nullOutputStream());
+ }
+
+ CurrentRunningTest provideCurrentRunningTest() {
+ return new SettableCurrentRunningTest() {
+ @Override
+ protected void setGlobalTestNameProvider(TestNameProvider provider) {
+ // Do not set the global current running test when the JUnit4Runner is being tested itself,
+ // in order not to override the real one.
+ }
+ };
+ }
+ }
+}
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java
new file mode 100644
index 0000000000..8a355842c2
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java
@@ -0,0 +1,172 @@
+// Copyright 2010 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import static com.google.testing.junit.runner.sharding.ShardingFilters.DEFAULT_SHARDING_STRATEGY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.Iterables;
+import com.google.testing.junit.runner.model.AntXmlResultWriter;
+import com.google.testing.junit.runner.model.TestNode;
+import com.google.testing.junit.runner.model.TestSuiteModel;
+import com.google.testing.junit.runner.model.XmlResultWriter;
+import com.google.testing.junit.runner.sharding.ShardingEnvironment;
+import com.google.testing.junit.runner.sharding.ShardingFilters;
+import com.google.testing.junit.runner.sharding.testing.StubShardingEnvironment;
+import com.google.testing.junit.runner.util.FakeTicker;
+import com.google.testing.junit.runner.util.Ticker;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Tests for {@code JUnit4TestModelBuilder}
+ */
+@RunWith(JUnit4.class)
+public class JUnit4TestModelBuilderTest {
+ private final Ticker fakeTicker = new FakeTicker();
+ private final ShardingEnvironment stubShardingEnvironment = new StubShardingEnvironment();
+ private final XmlResultWriter xmlResultWriter = new AntXmlResultWriter();
+
+ private JUnit4TestModelBuilder builder(Request request, String suiteName,
+ ShardingEnvironment shardingEnvironment, ShardingFilters shardingFilters,
+ XmlResultWriter xmlResultWriter) {
+ return new JUnit4TestModelBuilder(request, suiteName, new TestSuiteModel.Builder(
+ fakeTicker, shardingFilters, shardingEnvironment, xmlResultWriter));
+ }
+
+ @Test
+ public void testTouchesShardFileWhenShardingEnabled() {
+ Class<?> testClass = SampleTestCaseWithTwoTests.class;
+ Request request = Request.classWithoutSuiteMethod(testClass);
+ ShardingEnvironment mockShardingEnvironment = mock(ShardingEnvironment.class);
+ ShardingFilters shardingFilters = new ShardingFilters(
+ mockShardingEnvironment, DEFAULT_SHARDING_STRATEGY);
+ JUnit4TestModelBuilder modelBuilder = builder(
+ request, testClass.getCanonicalName(), mockShardingEnvironment, shardingFilters,
+ xmlResultWriter);
+
+ when(mockShardingEnvironment.isShardingEnabled()).thenReturn(true);
+ when(mockShardingEnvironment.getTotalShards()).thenReturn(2);
+ modelBuilder.get();
+
+ verify(mockShardingEnvironment).touchShardFile();
+ }
+
+ @Test
+ public void testDoesNotTouchShardFileWhenShardingDisabled() {
+ Class<?> testClass = SampleTestCaseWithTwoTests.class;
+ Request request = Request.classWithoutSuiteMethod(testClass);
+ ShardingEnvironment mockShardingEnvironment = mock(ShardingEnvironment.class);
+ ShardingFilters shardingFilters = new ShardingFilters(
+ mockShardingEnvironment, DEFAULT_SHARDING_STRATEGY);
+ JUnit4TestModelBuilder modelBuilder = builder(
+ request, testClass.getCanonicalName(), mockShardingEnvironment, shardingFilters,
+ xmlResultWriter);
+
+ when(mockShardingEnvironment.isShardingEnabled()).thenReturn(false);
+ modelBuilder.get();
+
+ verify(mockShardingEnvironment, never()).touchShardFile();
+ }
+
+ @Test
+ public void testCreateModel_singleTestClass() throws Exception {
+ Class<?> testClass = SampleTestCaseWithTwoTests.class;
+ Request request = Request.classWithoutSuiteMethod(testClass);
+ String testClassName = testClass.getCanonicalName();
+ JUnit4TestModelBuilder modelBuilder = builder(
+ request, testClassName, stubShardingEnvironment, null, xmlResultWriter);
+
+ Description suite = request.getRunner().getDescription();
+ Description testOne = suite.getChildren().get(0);
+ Description testTwo = suite.getChildren().get(1);
+
+ TestSuiteModel model = modelBuilder.get();
+ TestNode suiteNode = Iterables.getOnlyElement(model.getTopLevelTestSuites());
+ assertEquals(suite, suiteNode.getDescription());
+ List<TestNode> testCases = suiteNode.getChildren();
+ assertEquals(2, testCases.size());
+ TestNode testOneNode = testCases.get(0);
+ TestNode testTwoNode = testCases.get(1);
+ assertEquals(testOne, testOneNode.getDescription());
+ assertEquals(testTwo, testTwoNode.getDescription());
+ assertTrue(testOneNode.getChildren().isEmpty());
+ assertTrue(testTwoNode.getChildren().isEmpty());
+ assertEquals(2, model.getNumTestCases());
+ }
+
+ @Test
+ public void testCreateModel_simpleSuite() throws Exception {
+ Class<?> suiteClass = SampleSuite.class;
+ Request request = Request.classWithoutSuiteMethod(suiteClass);
+ String suiteClassName = suiteClass.getCanonicalName();
+ JUnit4TestModelBuilder modelBuilder = builder(
+ request, suiteClassName, stubShardingEnvironment, null, xmlResultWriter);
+
+ Description topSuite = request.getRunner().getDescription();
+ Description innerSuite = topSuite.getChildren().get(0);
+ Description testOne = innerSuite.getChildren().get(0);
+
+ TestSuiteModel model = modelBuilder.get();
+ TestNode topSuiteNode = Iterables.getOnlyElement(model.getTopLevelTestSuites());
+ assertEquals(topSuite, topSuiteNode.getDescription());
+ TestNode innerSuiteNode = Iterables.getOnlyElement(topSuiteNode.getChildren());
+ assertEquals(innerSuite, innerSuiteNode.getDescription());
+ TestNode testOneNode = Iterables.getOnlyElement(innerSuiteNode.getChildren());
+ assertEquals(testOne, testOneNode.getDescription());
+ assertTrue(testOneNode.getChildren().isEmpty());
+ assertEquals(1, model.getNumTestCases());
+ }
+
+
+ /** Sample test case with two tests. */
+ @RunWith(JUnit4.class)
+ public static class SampleTestCaseWithTwoTests {
+ @Test
+ public void testOne() {
+ }
+
+ @Test
+ public void testTwo() {
+ }
+ }
+
+
+ /** Sample test case with one test. */
+ @RunWith(JUnit4.class)
+ public static class SampleTestCaseWithOneTest {
+ @Test
+ public void testOne() {
+ }
+ }
+
+
+ /** Sample suite with one test. */
+ @RunWith(Suite.class)
+ @SuiteClasses(SampleTestCaseWithOneTest.class)
+ public static class SampleSuite {
+ }
+}
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java
new file mode 100644
index 0000000000..57f3074c09
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java
@@ -0,0 +1,42 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.util.Factory;
+
+/**
+ * A factory that supplies {@link JUnit4Config} for testing purposes.
+ */
+public final class TestModuleConfigFactory implements Factory<JUnit4Config> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ public TestModuleConfigFactory(JUnit4RunnerTest.TestModule module) {
+ assert module != null;
+ this.module = module;
+ }
+
+ @Override
+ public JUnit4Config get() {
+ JUnit4Config config = module.config();
+ if (config == null) {
+ throw new NullPointerException();
+ }
+ return config;
+ }
+
+ public static Factory<JUnit4Config> create(JUnit4RunnerTest.TestModule module) {
+ return new TestModuleConfigFactory(module);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java
new file mode 100644
index 0000000000..97b40e9f09
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java
@@ -0,0 +1,44 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.util.Factory;
+import java.util.Set;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * A factory that supplies a {@link Set}<{@link RunListener}> for testing purposes.
+ */
+public final class TestModuleMockRunListenerFactory implements Factory<Set<RunListener>> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ public TestModuleMockRunListenerFactory(JUnit4RunnerTest.TestModule module) {
+ assert module != null;
+ this.module = module;
+ }
+
+ @Override
+ public Set<RunListener> get() {
+ Set<RunListener> runListeners = module.mockRunListener();
+ if (runListeners == null) {
+ throw new NullPointerException();
+ }
+ return runListeners;
+ }
+
+ public static Factory<Set<RunListener>> create(JUnit4RunnerTest.TestModule module) {
+ return new TestModuleMockRunListenerFactory(module);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java
new file mode 100644
index 0000000000..c7037bcc9d
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java
@@ -0,0 +1,44 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.util.Factory;
+import java.io.PrintStream;
+
+/**
+ * A factory that supplies a stdout {@link PrintStream} for testing purposes.
+ */
+public final class TestModuleProvideStdoutStreamFactory implements Factory<PrintStream> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ public TestModuleProvideStdoutStreamFactory(
+ JUnit4RunnerTest.TestModule module) {
+ assert module != null;
+ this.module = module;
+ }
+
+ @Override
+ public PrintStream get() {
+ PrintStream printStream = module.provideStdoutStream();
+ if (printStream == null) {
+ throw new NullPointerException();
+ }
+ return printStream;
+ }
+
+ public static Factory<PrintStream> create(JUnit4RunnerTest.TestModule module) {
+ return new TestModuleProvideStdoutStreamFactory(module);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java
new file mode 100644
index 0000000000..ba5e4e27bf
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java
@@ -0,0 +1,45 @@
+
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.sharding.ShardingEnvironment;
+import com.google.testing.junit.runner.util.Factory;
+
+/**
+ * A factory that supplies a {@link ShardingEnvironment} for testing purposes.
+ */
+public final class TestModuleShardingEnvironmentFactory implements Factory<ShardingEnvironment> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ public TestModuleShardingEnvironmentFactory(
+ JUnit4RunnerTest.TestModule module) {
+ assert module != null;
+ this.module = module;
+ }
+
+ @Override
+ public ShardingEnvironment get() {
+ ShardingEnvironment shardingEnv = module.shardingEnvironment();
+ if (shardingEnv == null) {
+ throw new NullPointerException();
+ }
+ return shardingEnv;
+ }
+
+ public static Factory<ShardingEnvironment> create(JUnit4RunnerTest.TestModule module) {
+ return new TestModuleShardingEnvironmentFactory(module);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java
new file mode 100644
index 0000000000..144ed5dfe6
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java
@@ -0,0 +1,62 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.sharding.ShardingEnvironment;
+import com.google.testing.junit.runner.sharding.ShardingFilters;
+import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory;
+import com.google.testing.junit.runner.util.Factory;
+import com.google.testing.junit.runner.util.Supplier;
+
+/**
+ * A factory that supplies a {@link ShardingFilters} for testing purposes.
+ */
+public final class TestModuleShardingFiltersFactory implements Factory<ShardingFilters> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ private final Supplier<ShardingEnvironment> shardingEnvironmentSupplier;
+
+ private final Supplier<ShardingFilterFactory> defaultShardingStrategySupplier;
+
+ public TestModuleShardingFiltersFactory(
+ JUnit4RunnerTest.TestModule module,
+ Supplier<ShardingEnvironment> shardingEnvironmentSupplier,
+ Supplier<ShardingFilterFactory> defaultShardingStrategySupplier) {
+ assert module != null;
+ this.module = module;
+ assert shardingEnvironmentSupplier != null;
+ this.shardingEnvironmentSupplier = shardingEnvironmentSupplier;
+ assert defaultShardingStrategySupplier != null;
+ this.defaultShardingStrategySupplier = defaultShardingStrategySupplier;
+ }
+
+ @Override
+ public ShardingFilters get() {
+ ShardingFilters shardingFilters = module.shardingFilters(
+ shardingEnvironmentSupplier.get(), defaultShardingStrategySupplier.get());
+ if (shardingFilters == null) {
+ throw new NullPointerException();
+ }
+ return shardingFilters;
+ }
+
+ public static Factory<ShardingFilters> create(
+ JUnit4RunnerTest.TestModule module,
+ Supplier<ShardingEnvironment> shardingEnvironmentSupplier,
+ Supplier<ShardingFilterFactory> defaultShardingStrategySupplier) {
+ return new TestModuleShardingFiltersFactory(
+ module, shardingEnvironmentSupplier, defaultShardingStrategySupplier);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java
new file mode 100644
index 0000000000..95376668a3
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java
@@ -0,0 +1,43 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.util.Factory;
+import com.google.testing.junit.runner.util.Ticker;
+
+/**
+ * A factory that supplies a {@link Ticker} for testing purposes.
+ */
+public final class TestModuleTickerFactory implements Factory<Ticker> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ public TestModuleTickerFactory(JUnit4RunnerTest.TestModule module) {
+ assert module != null;
+ this.module = module;
+ }
+
+ @Override
+ public Ticker get() {
+ Ticker ticker = module.ticker();
+ if (ticker == null) {
+ throw new NullPointerException();
+ }
+ return ticker;
+ }
+
+ public static Factory<Ticker> create(JUnit4RunnerTest.TestModule module) {
+ return new TestModuleTickerFactory(module);
+ }
+} \ No newline at end of file
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java
new file mode 100644
index 0000000000..e0734d7554
--- /dev/null
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java
@@ -0,0 +1,51 @@
+// Copyright 2016 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import com.google.testing.junit.runner.model.AntXmlResultWriter;
+import com.google.testing.junit.runner.model.XmlResultWriter;
+import com.google.testing.junit.runner.util.Factory;
+import com.google.testing.junit.runner.util.Supplier;
+
+/**
+ * A factory that supplies a {@link XmlResultWriter} for testing purposes.
+ */
+public final class TestModuleXmlResultWriterFactory implements Factory<XmlResultWriter> {
+ private final JUnit4RunnerTest.TestModule module;
+
+ private final Supplier<AntXmlResultWriter> implSupplier;
+
+ public TestModuleXmlResultWriterFactory(
+ JUnit4RunnerTest.TestModule module, Supplier<AntXmlResultWriter> implSupplier) {
+ assert module != null;
+ this.module = module;
+ assert implSupplier != null;
+ this.implSupplier = implSupplier;
+ }
+
+ @Override
+ public XmlResultWriter get() {
+ XmlResultWriter resultWriter = module.xmlResultWriter(implSupplier.get());
+ if (resultWriter == null) {
+ throw new NullPointerException();
+ }
+ return resultWriter;
+ }
+
+ public static Factory<XmlResultWriter> create(
+ JUnit4RunnerTest.TestModule module, Supplier<AntXmlResultWriter> implSupplier) {
+ return new TestModuleXmlResultWriterFactory(module, implSupplier);
+ }
+} \ No newline at end of file