diff options
Diffstat (limited to 'src/test/junitrunner/javatests/com/google/testing/junit')
38 files changed, 4050 insertions, 0 deletions
diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/BUILD b/src/test/junitrunner/javatests/com/google/testing/junit/runner/BUILD new file mode 100644 index 0000000000..51ecef4097 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/BUILD @@ -0,0 +1,55 @@ +DEFAULT_VISIBILITY = [ + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner:__subpackages__", + "//src/test/junitrunner/javatests/com/google/testing/junit/runner:__subpackages__", +] + +licenses(["notice"]) # Apache 2.0 + +# Libraries +# ========================================================= +java_library( + name = "tests", + testonly = 1, + srcs = glob( + ["**/*.java"], + exclude = ["testbed/*.java"], + ), + # Disable sunapi warnings about sun.misc.Signal. + # These classes are used by the classes being tested + javacopts = ["-Xlint:-sunapi"], + deps = [ + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner:test_runner", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/internal", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/internal:junit4", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/model", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/api", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding/testing", + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/util", + "//src/test/java/com/google/devtools/build/lib:testutil", + "//third_party:dagger", + "//third_party:guava", + "//third_party:jsr305", + "//third_party:jsr330_inject", + "//third_party:junit4", + "//third_party:mockito", + "//third_party:truth", + ], +) + +# Tests +# ========================================================= +java_test( + name = "AllTests", + args = glob(["**/*Test.java"]), + main_class = "com.google.testing.junit.runner.TestRunner", + use_testrunner = 0, + runtime_deps = [":tests"], +) + +filegroup( + name = "srcs", + srcs = glob(["**"]), + visibility = ["//src/java_tools/junitrunner:__pkg__"], +) diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestListener.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestListener.java new file mode 100644 index 0000000000..2573574094 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestListener.java @@ -0,0 +1,120 @@ +// 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; + +import org.junit.internal.AssumptionViolatedException; +import org.junit.runner.Description; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunListener; + +/** + * A straightforward listener that prints to stdout/stderr whenever a test changes its state (e.g. + * started, finished, failed). + */ +class TestListener extends RunListener { + /** + * Called before any tests have been run. Prints to stdout the number of test cases found. + * + * @param description describes the tests to be run + */ + @Override + public void testRunStarted(Description description) throws Exception { + System.out.println("Found " + formatTestCaseCount(description.testCount()) + "."); + } + + /** + * Called when all tests have finished. Prints to stdout if the tests were successful or not. If + * not, it also prints the number of failed test cases. Finally, it prints the number of + * ignored test cases. + * + * @param result the summary of the test run, including all the tests that failed + */ + @Override + public void testRunFinished(Result result) throws Exception { + if (result.wasSuccessful()) { + System.out.println("Successfully finished running " + + formatTestCaseCount(result.getRunCount()) + " in " + result.getRunTime() + " ms."); + } else { + System.out.println("Finished running " + formatTestCaseCount(result.getRunCount()) + + " in " + result.getRunTime() + " ms."); + int failureCount = result.getFailureCount(); + if (failureCount == 1) { + System.out.println("There was 1 failed test."); + } else { + System.out.println("There were " + failureCount + " failed tests."); + } + } + int ignoredCount = result.getIgnoreCount(); + if (ignoredCount == 1) { + System.out.println(result.getIgnoreCount() + " test case was ignored."); + } else if (ignoredCount > 1) { + System.out.println(result.getIgnoreCount() + " test cases were ignored."); + } + } + + /** + * Called when an atomic test is about to be started. Prints to stdout the name of the test that + * started with the corresponding information. + * + * @param description the description of the test that is about to be run + * (generally a class and method name) + */ + @Override + public void testStarted(Description description) throws Exception { + System.out.println("Test case started: " + description.getDisplayName()); + } + + /** + * Called when an atomic test fails. Prints to stderr the name of the test that failed + * (including its class) and the reason why, including the stack trace. + * + * @param failure describes the test that failed and the exception that was thrown + */ + @Override + public void testFailure(Failure failure) throws Exception { + System.err.println("Failure in " + failure.getTestHeader() + ": " + failure.getMessage() + + "\n" + failure.getTrace()); + } + + /** + * Called when an atomic test flags that it assumes a condition that is false. Prints to stderr + * that a test case assumed false condition, including the corresponding message containing + * the context. + * + * @param failure describes the test that failed and the + * {@link AssumptionViolatedException} that was thrown + */ + @Override + public void testAssumptionFailure(Failure failure) { + System.err.println("Test case assumed false condition: " + failure.getMessage()); + } + + /** + * Called when a test will not be run, generally because a test method is annotated with + * Ignore. Prints to stderr that a test case was ignored, alongside with the test name. + **/ + @Override + public void testIgnored(Description description) throws java.lang.Exception { + System.err.println("Test case " + description.getMethodName() + " ignored."); + } + + private static String formatTestCaseCount(int count) { + if (count == 1) { + return "1 test case"; + } + return count + " test cases"; + } + } diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestRunner.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestRunner.java new file mode 100644 index 0000000000..35d361a35a --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/TestRunner.java @@ -0,0 +1,77 @@ +// 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; + +import com.google.testing.junit.runner.util.GoogleTestSecurityManager; +import java.util.ArrayList; +import java.util.List; +import org.junit.runner.JUnitCore; +import org.junit.runner.Request; +import org.junit.runner.Result; + +/** + * A straightforward JUnit test runner that runs the test in the specified class using + * {@link JUnitCore}. + */ +public class TestRunner { + private static final String PACKAGE = TestRunner.class.getPackage().getName(); + + private TestRunner() {} + + public static void main(String[] args) throws ClassNotFoundException { + if (args.length == 0) { + throw new IllegalArgumentException( + "Must specify at least one argument (source files of the tests to run)!"); + } + + JUnitCore junitCore = new JUnitCore(); + junitCore.addListener(new TestListener()); + SecurityManager previousSecurityManager = setGoogleTestSecurityManager(); + Request request = createRequest(args); + Result result = junitCore.run(request); + restorePreviousSecurityManager(previousSecurityManager); + + System.exit(result.wasSuccessful() ? 0 : 1); + } + + private static Request createRequest(String[] filepaths) throws ClassNotFoundException { + List<Class<?>> classes = new ArrayList<>(filepaths.length); + for (String path : filepaths) { + classes.add(getClass(path)); + } + return Request.classes(classes.toArray(new Class<?>[0])); + } + + private static Class<?> getClass(String filepath) throws ClassNotFoundException { + String className = filepath.replace('/', '.'); + if (filepath.endsWith(".java")) { + className = className.substring(0, className.length() - 5); + } + return Class.forName(PACKAGE + "." + className); + } + + // Sets a new GoogleTestSecurityManager as security manager and returns the previous one. + private static SecurityManager setGoogleTestSecurityManager() { + SecurityManager previousSecurityManager = System.getSecurityManager(); + GoogleTestSecurityManager newSecurityManager = new GoogleTestSecurityManager(); + System.setSecurityManager(newSecurityManager); + return previousSecurityManager; + } + + private static void restorePreviousSecurityManager(SecurityManager previousSecurityManager) { + GoogleTestSecurityManager.uninstallIfInstalled(); + System.setSecurityManager(previousSecurityManager); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/CancellableRequestFactoryTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/CancellableRequestFactoryTest.java new file mode 100644 index 0000000000..246a9dd489 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/CancellableRequestFactoryTest.java @@ -0,0 +1,224 @@ +// Copyright 2012 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.internal.junit4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Test; +import org.junit.internal.AssumptionViolatedException; +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.Runner; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunNotifier; +import org.junit.runner.notification.StoppedByUserException; +import org.junit.runners.JUnit4; +import org.junit.runners.Suite; +import org.junit.runners.model.InitializationError; + +/** + * Tests for {@link CancellableRequestFactory}. + */ +@RunWith(JUnit4.class) +public class CancellableRequestFactoryTest { + + private final CancellableRequestFactory cancellableRequestFactory = + new CancellableRequestFactory(); + + @Test + public void testCancelRunAfterStarting() throws Exception { + final CountDownLatch testStartLatch = new CountDownLatch(1); + final CountDownLatch testContinueLatch = new CountDownLatch(1); + final AtomicBoolean secondTestRan = new AtomicBoolean(false); + + // Simulates a test that hangs + FakeRunner blockingRunner = new FakeRunner("blocks", new Runnable() { + @Override + public void run() { + testStartLatch.countDown(); + try { + testContinueLatch.await(1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Timed out waiting for signal to continue test", e); + } + } + }); + + // A runner that should never run its test + FakeRunner secondRunner = new FakeRunner("shouldNotRun", new Runnable() { + @Override + public void run() { + secondTestRan.set(true); + } + }); + + RunnerSuite fakeSuite = new RunnerSuite(blockingRunner, secondRunner); + final Request request = cancellableRequestFactory.createRequest(Request.runner(fakeSuite)); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future<Result> future = executor.submit(new Callable<Result>() { + @Override + public Result call() throws Exception { + JUnitCore core = new JUnitCore(); + return core.run(request); + } + }); + + // Simulate cancel being called in the middle of the test + testStartLatch.await(1, TimeUnit.SECONDS); + cancellableRequestFactory.cancelRun(); + testContinueLatch.countDown(); + + try { + future.get(10, TimeUnit.SECONDS); + fail("exception expected"); + } catch (ExecutionException e) { + Throwable runnerException = e.getCause(); + assertTrue(runnerException instanceof RuntimeException); + assertEquals("Test run interrupted", runnerException.getMessage()); + assertTrue(runnerException.getCause() instanceof StoppedByUserException); + } + + executor.shutdownNow(); + } + + @Test + public void testCancelRunBeforeStarting() throws Exception { + final AtomicBoolean testRan = new AtomicBoolean(false); + + // A runner that should never run its test + FakeRunner runner = new FakeRunner("shouldNotRun", new Runnable() { + @Override + public void run() { + testRan.set(true); + } + }); + + Request request = cancellableRequestFactory.createRequest(Request.runner(runner)); + cancellableRequestFactory.cancelRun(); + JUnitCore core = new JUnitCore(); + + try { + core.run(request); + fail("exception expected"); + } catch (RuntimeException e) { + assertEquals("Test run interrupted", e.getMessage()); + assertTrue(e.getCause() instanceof StoppedByUserException); + } + + assertFalse(testRan.get()); + } + + @Test + public void testNormalRun() { + final AtomicBoolean testRan = new AtomicBoolean(false); + + // A runner that should run its test + FakeRunner runner = new FakeRunner("shouldRun", new Runnable() { + @Override + public void run() { + testRan.set(true); + } + }); + + Request request = cancellableRequestFactory.createRequest(Request.runner(runner)); + JUnitCore core = new JUnitCore(); + Result result = core.run(request); + + assertTrue(testRan.get()); + assertEquals(1, result.getRunCount()); + assertEquals(0, result.getFailureCount()); + } + + @Test + public void testFailingRun() { + final AtomicBoolean testRan = new AtomicBoolean(false); + final RuntimeException expectedFailure = new RuntimeException(); + + // A runner that should run its test + FakeRunner runner = new FakeRunner("shouldRun", new Runnable() { + @Override + public void run() { + testRan.set(true); + throw expectedFailure; + } + }); + + Request request = cancellableRequestFactory.createRequest(Request.runner(runner)); + JUnitCore core = new JUnitCore(); + Result result = core.run(request); + + assertTrue(testRan.get()); + assertEquals(1, result.getRunCount()); + assertEquals(1, result.getFailureCount()); + assertSame(expectedFailure, result.getFailures().get(0).getException()); + } + + + private static class FakeRunner extends Runner { + private final Description testDescription; + private final Runnable test; + + public FakeRunner(String testName, Runnable test) { + this.test = test; + testDescription = Description.createTestDescription(FakeRunner.class, testName); + } + + @Override + public Description getDescription() { + return testDescription; + } + + @Override + public void run(RunNotifier notifier) { + notifier.fireTestStarted(testDescription); + + try { + test.run(); + } catch (AssumptionViolatedException e) { + notifier.fireTestAssumptionFailed(new Failure(testDescription, e)); + } catch (Throwable e) { + notifier.fireTestFailure(new Failure(testDescription, e)); + } finally { + notifier.fireTestFinished(testDescription); + } + } + } + + + private static class RunnerSuite extends Suite { + + public RunnerSuite(Runner... runners) throws InitializationError { + super(RunnerSuite.class, Arrays.asList(runners)); + } + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestNameListenerTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestNameListenerTest.java new file mode 100644 index 0000000000..a63788779b --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestNameListenerTest.java @@ -0,0 +1,176 @@ +// 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.internal.junit4; + +import static com.google.common.base.Throwables.throwIfUnchecked; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.testing.junit.runner.util.TestNameProvider; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.Description; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link JUnit4TestNameListener}. + */ +@RunWith(JUnit4.class) +public class JUnit4TestNameListenerTest { + private JUnit4TestNameListener testNameListener; + private TestNameProvider testNameProviderForTesting; + @Rule public TestName name = new TestName(); + + @Before + public void setCurrentRunningTest() { + SettableCurrentRunningTest currentRunningTest = new SettableCurrentRunningTest() { + @Override + public void setGlobalTestNameProvider(TestNameProvider provider) { + testNameProviderForTesting = provider; + } + }; + + testNameListener = new JUnit4TestNameListener(currentRunningTest); + } + + @Test + public void testJUnit4Listener_normalUsage() throws Exception { + assertNull(testNameProviderForTesting); + + Description description = Description.createSuiteDescription(FakeTest.class); + testNameListener.testRunStarted(description); + assertNull(testNameProviderForTesting.get()); + + description = Description.createTestDescription(FakeTest.class, "methodName"); + testNameListener.testStarted(description); + assertEquals(description, testNameProviderForTesting.get()); + testNameListener.testFinished(description); + assertNull(testNameProviderForTesting.get()); + + description = Description.createTestDescription(FakeTest.class, "anotherMethodName"); + testNameListener.testStarted(description); + assertEquals(description, testNameProviderForTesting.get()); + testNameListener.testFinished(description); + assertNull(testNameProviderForTesting.get()); + + testNameListener.testRunFinished(null); + assertNull(testNameProviderForTesting.get()); + } + + @Test + public void testJUnit4Listener_hasExpectedDisplayName() throws Exception { + Description description = Description.createSuiteDescription(FakeTest.class); + testNameListener.testRunStarted(description); + + description = Description.createTestDescription(this.getClass(), name.getMethodName()); + testNameListener.testStarted(description); + assertEquals("testJUnit4Listener_hasExpectedDisplayName(" + + JUnit4TestNameListenerTest.class.getCanonicalName() + ")", + testNameProviderForTesting.get().getDisplayName()); + } + + @Test + public void testJUnit4Listener_multipleThreads() throws Exception { + ExecutorService executorService = Executors.newSingleThreadExecutor(); + Description description1 = + Description.createTestDescription(FakeTest.class, "methodName"); + final Description description2 = + Description.createTestDescription(FakeTest.class, "anotherMethodName"); + + testNameListener.testRunStarted(Description.createSuiteDescription(FakeTest.class)); + assertNull(testNameProviderForTesting.get()); + testNameListener.testStarted(description1); + assertEquals(description1, testNameProviderForTesting.get()); + + Future<?> startSecondTestFuture = + executorService.submit( + new Runnable() { + @Override + public void run() { + assertNull(testNameProviderForTesting.get()); + try { + testNameListener.testStarted(description2); + } catch (Exception e) { + throwIfUnchecked(e); + throw new RuntimeException(e); + } + assertEquals(description2, testNameProviderForTesting.get()); + } + }); + startSecondTestFuture.get(); + + assertEquals(description1, testNameProviderForTesting.get()); + testNameListener.testFinished(description1); + assertNull(testNameProviderForTesting.get()); + + Future<?> endSecondTestFuture = + executorService.submit( + new Runnable() { + @Override + public void run() { + assertEquals(description2, testNameProviderForTesting.get()); + try { + testNameListener.testFinished(description2); + } catch (Exception e) { + throwIfUnchecked(e); + throw new RuntimeException(e); + } + assertNull(testNameProviderForTesting.get()); + } + }); + endSecondTestFuture.get(); + + assertNull(testNameProviderForTesting.get()); + } + + /** + * Typically, {@link junit.framework.TestListener#startTest(junit.framework.Test)} + * and {@link junit.framework.TestListener#endTest(junit.framework.Test)} + * should be called in pairs, but if they're not for some reason, the + * listener will try to handle it as best as possible. + */ + @Test + public void testJUnit4Listener_invalidStatesAreHandled() throws Exception { + testNameListener.testRunStarted(Description.createSuiteDescription(FakeTest.class)); + + Description description1 = + Description.createTestDescription(FakeTest.class, "methodName"); + Description description2 = + Description.createTestDescription(FakeTest.class, "anotherMethodName"); + + testNameListener.testStarted(description1); + testNameListener.testStarted(description1); + assertEquals(description1, testNameProviderForTesting.get()); + + testNameListener.testStarted(description2); + assertEquals(description2, testNameProviderForTesting.get()); + + testNameListener.testFinished(description1); + assertNull(testNameProviderForTesting.get()); + + testNameListener.testFinished(description2); + assertNull(testNameProviderForTesting.get()); + } + + + private static class FakeTest { + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestXmlListenerTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestXmlListenerTest.java new file mode 100644 index 0000000000..11d35c7888 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/JUnit4TestXmlListenerTest.java @@ -0,0 +1,288 @@ +// 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.internal.junit4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +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.Lists; +import com.google.testing.junit.runner.internal.SignalHandlers; +import com.google.testing.junit.runner.model.TestSuiteModel; +import com.google.testing.junit.runner.util.Supplier; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.List; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.JUnitCore; +import org.junit.runner.Request; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.InOrder; +import sun.misc.Signal; +import sun.misc.SignalHandler; + +/** + * Tests for {@link JUnit4TestXmlListener} + */ +@RunWith(JUnit4.class) +public class JUnit4TestXmlListenerTest { + private static final String CHARSET = "UTF-8"; + private final FakeSignalHandlers fakeSignalHandlers = new FakeSignalHandlers(); + private final ByteArrayOutputStream errStream = new ByteArrayOutputStream(); + private PrintStream errPrintStream; + + @Before + public void createErrPrintStream() throws Exception { + errPrintStream = new PrintStream(errStream, true, CHARSET); + } + + @Test + public void signalHandlerWritesXml() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + Request request = Request.classWithoutSuiteMethod(PassingTest.class); + Description suiteDescription = request.getRunner().getDescription(); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + listener.testRunStarted(suiteDescription); + assertEquals(1, fakeSignalHandlers.handlers.size()); + + fakeSignalHandlers.handlers.get(0).handle(new Signal("TERM")); + + String errOutput = errStream.toString(CHARSET); + assertTrue("expected signal name in stderr", errOutput.contains("SIGTERM")); + assertTrue("expected message in stderr", errOutput.contains("Done writing test XML")); + + InOrder inOrder = inOrder(mockRequestFactory, mockModel); + inOrder.verify(mockRequestFactory).cancelRun(); + inOrder.verify(mockModel).testRunInterrupted(); + inOrder.verify(mockModel).writeAsXml(mockXmlStream); + } + + @Test + public void writesXmlAtTestEnd() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + JUnitCore core = new JUnitCore(); + core.addListener(listener); + core.run(Request.classWithoutSuiteMethod(PassingTest.class)); + + assertEquals("no output to stderr expected", 0, errStream.size()); + verify(mockModel).writeAsXml(mockXmlStream); + verify(mockRequestFactory, never()).cancelRun(); + } + + @Test + public void assumptionViolationsAreReportedAsSkippedTests() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + Request request = Request.classWithoutSuiteMethod(TestWithAssumptionViolation.class); + Description suiteDescription = request.getRunner().getDescription(); + Description testDescription = suiteDescription.getChildren().get(0); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + JUnitCore core = new JUnitCore(); + core.addListener(listener); + core.run(request); + + assertEquals("no output to stderr expected", 0, errStream.size()); + InOrder inOrder = inOrder(mockModel); + inOrder.verify(mockModel).testSkipped(testDescription); + inOrder.verify(mockModel).writeAsXml(mockXmlStream); + verify(mockRequestFactory, never()).cancelRun(); + } + + @Test + public void assumptionViolationsAtSuiteLevelAreReportedAsSkippedSuite() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + Request request = Request.classWithoutSuiteMethod( + TestWithAssumptionViolationOnTheSuiteLevel.class); + Description suiteDescription = request.getRunner().getDescription(); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + JUnitCore core = new JUnitCore(); + core.addListener(listener); + core.run(request); + + assertEquals("no output to stderr expected", 0, errStream.size()); + InOrder inOrder = inOrder(mockModel); + inOrder.verify(mockModel).testSkipped(suiteDescription); + inOrder.verify(mockModel).writeAsXml(mockXmlStream); + verify(mockRequestFactory, never()).cancelRun(); + } + + @Test + public void failuresAreReported() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + Request request = Request.classWithoutSuiteMethod(FailingTest.class); + Description suiteDescription = request.getRunner().getDescription(); + Description testDescription = suiteDescription.getChildren().get(0); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + JUnitCore core = new JUnitCore(); + core.addListener(listener); + core.run(request); + + assertEquals("no output to stderr expected", 0, errStream.size()); + InOrder inOrder = inOrder(mockModel); + inOrder.verify(mockModel).testFailure(eq(testDescription), any(Throwable.class)); + inOrder.verify(mockModel).writeAsXml(mockXmlStream); + verify(mockRequestFactory, never()).cancelRun(); + } + + @Test + public void ignoredTestAreReportedAsSuppressedTests() throws Exception { + TestSuiteModelSupplier mockModelSupplier = mock(TestSuiteModelSupplier.class); + TestSuiteModel mockModel = mock(TestSuiteModel.class); + CancellableRequestFactory mockRequestFactory = mock(CancellableRequestFactory.class); + OutputStream mockXmlStream = mock(OutputStream.class); + JUnit4TestXmlListener listener = new JUnit4TestXmlListener( + mockModelSupplier, mockRequestFactory, fakeSignalHandlers, mockXmlStream, errPrintStream); + + Request request = Request.classWithoutSuiteMethod(TestWithIgnoredTestCase.class); + Description suiteDescription = request.getRunner().getDescription(); + Description testDescription = suiteDescription.getChildren().get(0); + + when(mockModelSupplier.get()).thenReturn(mockModel); + + JUnitCore core = new JUnitCore(); + core.addListener(listener); + core.run(request); + + assertEquals("no output to stderr expected", 0, errStream.size()); + InOrder inOrder = inOrder(mockModel); + inOrder.verify(mockModel).testSuppressed(testDescription); + inOrder.verify(mockModel).writeAsXml(mockXmlStream); + verify(mockRequestFactory, never()).cancelRun(); + } + + /** + * Test with a method that always passes. + */ + public static class PassingTest { + @Test + public void alwaysPasses() { + } + } + + + /** + * Test with a method that always fails. + */ + public static class FailingTest { + @Test + public void alwaysFails() { + fail(); + } + } + + + /** + * Test with a method that is always skipped. + */ + public static class TestWithAssumptionViolation { + @Test + public void alwaysSkipped() { + assumeTrue(false); + } + } + + /** + * Test with a method that is always skipped. + */ + public static class TestWithAssumptionViolationOnTheSuiteLevel { + @BeforeClass + public static void failedSuiteLevelAssumption() { + assumeTrue(false); + } + + @Test + public void fakeTest() {} + } + + public static class TestWithIgnoredTestCase { + @Test + @Ignore + public void alwaysIgnored() { + + } + } + + private static class FakeSignalHandlers extends SignalHandlers { + public List<SignalHandler> handlers = Lists.newArrayList(); + + public FakeSignalHandlers() { + super(null); + } + + @Override + public void installHandler(Signal signal, SignalHandler signalHandler) { + if (signal.getName().equals("TERM")) { + handlers.add(signalHandler); + } + } + } + + + private interface TestSuiteModelSupplier extends Supplier<TestSuiteModel> { + } +}
\ No newline at end of file diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/MemoizingRequestTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/MemoizingRequestTest.java new file mode 100644 index 0000000000..a2818eb453 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/internal/junit4/MemoizingRequestTest.java @@ -0,0 +1,73 @@ +// Copyright 2012 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.internal.junit4; + +import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +import junit.framework.TestCase; + +import org.junit.runner.Request; +import org.junit.runner.Runner; + +/** + * Tests for {@code MemoizingRequest}. + */ +public class MemoizingRequestTest extends TestCase { + private Request mockRequestDelegate; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mockRequestDelegate = mock(Request.class, RETURNS_MOCKS); + } + + public void testConstructorDoesNoWork() { + new MemoizingRequest(mockRequestDelegate); + + verifyZeroInteractions(mockRequestDelegate); + } + + public void testMemoizesRunner() { + MemoizingRequest memoizingRequest = new MemoizingRequest(mockRequestDelegate); + + Runner firstRunner = memoizingRequest.getRunner(); + Runner secondRunner = memoizingRequest.getRunner(); + + assertSame(firstRunner, secondRunner); + verify(mockRequestDelegate).getRunner(); + verifyNoMoreInteractions(mockRequestDelegate); + } + + public void testOverridingCreateRunner() { + final Runner stubRunner = mock(Runner.class); + MemoizingRequest memoizingRequest = new MemoizingRequest(mockRequestDelegate) { + @Override + protected Runner createRunner(Request delegate) { + return stubRunner; + } + }; + + Runner firstRunner = memoizingRequest.getRunner(); + Runner secondRunner = memoizingRequest.getRunner(); + + assertSame(stubRunner, firstRunner); + assertSame(firstRunner, secondRunner); + verifyZeroInteractions(mockRequestDelegate); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java new file mode 100644 index 0000000000..02c18746f4 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4ConfigTest.java new file mode 100644 index 0000000000..9ddc682657 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4OptionsTest.java new file mode 100644 index 0000000000..699c5883bb --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java new file mode 100644 index 0000000000..6dd9bf32e2 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4TestModelBuilderTest.java new file mode 100644 index 0000000000..8a355842c2 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleConfigFactory.java new file mode 100644 index 0000000000..57f3074c09 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleMockRunListenerFactory.java new file mode 100644 index 0000000000..97b40e9f09 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleProvideStdoutStreamFactory.java new file mode 100644 index 0000000000..c7037bcc9d --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingEnvironmentFactory.java new file mode 100644 index 0000000000..ba5e4e27bf --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleShardingFiltersFactory.java new file mode 100644 index 0000000000..144ed5dfe6 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleTickerFactory.java new file mode 100644 index 0000000000..95376668a3 --- /dev/null +++ b/src/test/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/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/junit4/TestModuleXmlResultWriterFactory.java new file mode 100644 index 0000000000..e0734d7554 --- /dev/null +++ b/src/test/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 diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestCaseNodeTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestCaseNodeTest.java new file mode 100644 index 0000000000..ed313c1da8 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestCaseNodeTest.java @@ -0,0 +1,146 @@ +// Copyright 2015 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.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit test for {@link TestCaseNode}. + */ +@RunWith(JUnit4.class) +public class TestCaseNodeTest { + + private static final long NOW = 1; + private static Description suite; + private static Description testCase; + + @BeforeClass + public static void createDescriptions() { + suite = Description.createSuiteDescription(TestSuiteNode.class); + testCase = Description.createTestDescription(TestSuite.class, "testCase"); + suite.addChild(testCase); + } + + @Test + public void assertIsTestCase() { + assertTrue(new TestCaseNode(testCase, new TestSuiteNode(suite)).isTestCase()); + } + + @Test + public void assertIsSkippedIfNotStarted() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + assertStatusWithoutTiming(testCaseNode, TestResult.Status.SKIPPED); + } + + @Test + public void assertIsCancelledIfInterruptedBeforeStart() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.testInterrupted(NOW); + assertStatusAndTiming(testCaseNode, TestResult.Status.CANCELLED, NOW, 0); + } + + @Test + public void assertIsCompletedIfFailedBeforeStart() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.testFailure(new Exception(), NOW); + assertStatusAndTiming(testCaseNode, TestResult.Status.COMPLETED, NOW, 0); + } + + @Test + public void assertInterruptedIfStartedAndNotFinished() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + assertStatusAndTiming(testCaseNode, TestResult.Status.INTERRUPTED, NOW, 0); + // Notice: This is an unexpected ending state, as even interrupted test executions should go + // through the testCaseNode.interrupted() code path. + } + + @Test + public void assertInterruptedIfStartedAndInterrupted() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + testCaseNode.testInterrupted(NOW + 1); + assertStatusAndTiming(testCaseNode, TestResult.Status.INTERRUPTED, NOW, 1); + } + + @Test + public void assertSkippedIfStartedAndSkipped() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + testCaseNode.testSkipped(NOW + 1); + assertStatusAndTiming(testCaseNode, TestResult.Status.SKIPPED, NOW, 1); + } + + @Test + public void assertCompletedIfStartedAndFinished() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + testCaseNode.finished(NOW + 1); + assertStatusAndTiming(testCaseNode, TestResult.Status.COMPLETED, NOW, 1); + } + + @Test + public void assertCompletedIfStartedAndFailedAndFinished() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + testCaseNode.testFailure(new Exception(), NOW + 1); + testCaseNode.finished(NOW + 2); + assertStatusAndTiming(testCaseNode, TestResult.Status.COMPLETED, NOW, 2); + } + + @Test + public void assertInterruptedIfStartedAndFailedAndInterrupted() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.started(NOW); + testCaseNode.testFailure(new Exception(), NOW + 1); + testCaseNode.testInterrupted(NOW + 2); + assertStatusAndTiming(testCaseNode, TestResult.Status.INTERRUPTED, NOW, 2); + } + + @Test + public void assertTestSuppressedIfNotStartedAndSuppressed() { + TestCaseNode testCaseNode = new TestCaseNode(testCase, new TestSuiteNode(suite)); + testCaseNode.testSuppressed(NOW); + assertStatusAndTiming(testCaseNode, TestResult.Status.SUPPRESSED, NOW, 0); + } + + private void assertStatusAndTiming( + TestCaseNode testCase, TestResult.Status status, long start, long duration) { + TestResult result = testCase.getResult(); + assertEquals(status, result.getStatus()); + assertNotNull(result.getRunTimeInterval()); + assertEquals(start, result.getRunTimeInterval().getStartMillis()); + assertEquals(duration, result.getRunTimeInterval().toDurationMillis()); + } + + private void assertStatusWithoutTiming(TestCaseNode testCase, TestResult.Status status) { + TestResult result = testCase.getResult(); + assertEquals(status, result.getStatus()); + assertNull(result.getRunTimeInterval()); + } + + static class TestSuite { + @Test public void testCase() {} + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestIntervalTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestIntervalTest.java new file mode 100644 index 0000000000..ebab4a7cd5 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestIntervalTest.java @@ -0,0 +1,65 @@ +// 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.model; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; +import java.util.TimeZone; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class TestIntervalTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCreation() { + TestInterval interval = new TestInterval(123456, 234567); + assertEquals(123456, interval.getStartMillis()); + assertEquals(234567, interval.getEndMillis()); + + interval = new TestInterval(123456, 123456); + assertEquals(123456, interval.getStartMillis()); + assertEquals(123456, interval.getEndMillis()); + } + + @Test + public void testCreationFailure() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Start must be before end"); + new TestInterval(35, 23); + } + + @Test + public void testToDuration() { + assertEquals(100, new TestInterval(50, 150).toDurationMillis()); + assertEquals(0, new TestInterval(100, 100).toDurationMillis()); + } + + @Test + public void testDateFormat() { + Date date = new Date(1471709734000L); + TestInterval interval = new TestInterval(date.getTime(), date.getTime() + 100); + assertEquals( + "2016-08-20T12:15:34.000-04:00", + interval.startInstantToString(TimeZone.getTimeZone("America/New_York"))); + assertEquals( + "2016-08-20T16:15:34.000Z", interval.startInstantToString(TimeZone.getTimeZone("GMT"))); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestSuiteNodeTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestSuiteNodeTest.java new file mode 100644 index 0000000000..61b97cdd6f --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/TestSuiteNodeTest.java @@ -0,0 +1,86 @@ +// Copyright 2015 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.model; + +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +/** + * Unit test for {@link TestSuiteNode}. + */ +@RunWith(MockitoJUnitRunner.class) +public class TestSuiteNodeTest { + + private static final long NOW = 1; + + @Mock private TestCaseNode testCaseNode; + private TestSuiteNode testSuiteNode; + + @Before + public void createTestSuiteNode() { + testSuiteNode = new TestSuiteNode(Description.createSuiteDescription("suite")); + testSuiteNode.addTestCase(testCaseNode); + } + + @Test + public void testIsTestCase() { + assertFalse(testSuiteNode.isTestCase()); + verifyZeroInteractions(testCaseNode); + } + + @Test + public void testInterrupted() { + testSuiteNode.testInterrupted(NOW); + verify(testCaseNode, times(1)).testInterrupted(NOW); + } + + @Test + public void testTestSkipped() { + testSuiteNode.testSkipped(NOW); + verify(testCaseNode, times(1)).testSkipped(NOW); + } + + @Test + public void testTestIgnored() { + testSuiteNode.testSuppressed(NOW); + verify(testCaseNode, times(1)).testSuppressed(NOW); + } + + @Test + public void testTestFailure() { + Exception failure = new Exception(); + testSuiteNode.testFailure(failure, NOW); + verify(testCaseNode, times(1)).testFailure(failure, NOW); + } + + @Test + public void testDynamicFailure() { + Description dynamicTestCaseDescription = mock(Description.class); + Exception failure = new Exception(); + testSuiteNode.dynamicTestFailure(dynamicTestCaseDescription, failure, NOW); + verify(testCaseNode, times(1)).dynamicTestFailure(dynamicTestCaseDescription, failure, NOW); + verifyZeroInteractions(dynamicTestCaseDescription); + } + +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/XmlWriterTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/XmlWriterTest.java new file mode 100644 index 0000000000..423d1f4f3d --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/model/XmlWriterTest.java @@ -0,0 +1,232 @@ +// 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.model; + +import static org.junit.Assert.assertEquals; + +import com.google.common.base.Joiner; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link XmlWriter} + */ +@RunWith(JUnit4.class) +public class XmlWriterTest { + private static final Joiner LINE_JOINER = Joiner.on(XmlWriter.EOL); + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + @Rule + public final ExpectedException expectedException = ExpectedException.none(); + + @Test + public void encodingShouldBeUtf8() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("String"); + String utf8String = "z\u0080\u0800\u010000"; // 1+2+3+4 bytes + xmlWriter.writeCharacters(utf8String); + xmlWriter.close(); + + // Note: assertHasContents() reads the bytes of the outputStream as a UTF-8 string + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<String>" + utf8String, + "</String>"); + } + + @Test + public void header() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>"); + } + + @Test + public void emptyDocument() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("DocumentName"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<DocumentName />"); + } + + @Test + public void emptyDocumentWithOneAttribute() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Properties"); + xmlWriter.writeAttribute("name", "value"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Properties name='value' />"); + } + + @Test + public void emptyDocumentWithTwoAttributes() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("TestSuite"); + xmlWriter.writeAttribute("count", 7); + xmlWriter.writeAttribute("size", "large"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<TestSuite count='7' size='large' />"); + } + + @Test + public void emptyDocumentWithThreeAttributes() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("TestSuite"); + xmlWriter.writeAttribute("count", 7); + xmlWriter.writeAttribute("size", "large"); + xmlWriter.writeAttribute("time", 1.0); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<TestSuite count='7' size='large' time='1.0' />"); + } + + @Test + public void documentWithOneEmptyElement() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Root"); + xmlWriter.writeAttribute("childCount", 1); + xmlWriter.startElement("Child"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Root childCount='1'>", + " <Child />", + "</Root>"); + } + + @Test + public void documentWithOneEmptyElementWithAttribute() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Root"); + xmlWriter.startElement("Child"); + xmlWriter.writeAttribute("name", "value"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Root>", + " <Child name='value' />", + "</Root>"); + } + + @Test + public void documentWithOneElementWithCharactersNoEscaping() + throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Root"); + xmlWriter.startElement("Child"); + xmlWriter.writeCharacters("some text\nmore text"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Root>", + " <Child>some text", + "more text", + " </Child>", + "</Root>"); + } + + @Test + public void documentWithOneElementWithCharactersNeedingEscaping() + throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Root"); + xmlWriter.startElement("Child"); + xmlWriter.writeCharacters("foo]]>bar"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Root>", + " <Child>foo]]>bar", + " </Child>", + "</Root>"); + } + + @Test + public void documentWithOneElementChild() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Root"); + xmlWriter.startElement("Child"); + xmlWriter.writeAttribute("name", "value"); + xmlWriter.startElement("Grandchild"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Root>", + " <Child name='value'>", + " <Grandchild />", + " </Child>", + "</Root>"); + } + + @Test + public void documentWithTwoElements() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Parent"); + xmlWriter.startElement("Child"); + xmlWriter.writeAttribute("name", "Deanna"); + xmlWriter.endElement(); + xmlWriter.startElement("Child"); + xmlWriter.writeAttribute("name", "Kyle"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Parent>", + " <Child name='Deanna' />", + " <Child name='Kyle' />", + "</Parent>"); + } + + @Test + public void attributeValuesEscaped() throws Exception { + XmlWriter xmlWriter = new XmlWriter(outputStream); + xmlWriter.startDocument(); + xmlWriter.startElement("Expression"); + xmlWriter.writeAttribute("name", "a > b"); + xmlWriter.close(); + + assertHasContents("<?xml version='1.0' encoding='UTF-8'?>", + "<Expression name='a > b' />"); + } + + private void assertHasContents(String... contents) throws UnsupportedEncodingException { + Object[] expected = contents; + + assertEquals(LINE_JOINER.join(expected).trim(), outputStream.toString("UTF-8").trim()); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/HashBackedShardingFilterTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/HashBackedShardingFilterTest.java new file mode 100644 index 0000000000..8ae46f7272 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/HashBackedShardingFilterTest.java @@ -0,0 +1,42 @@ +// 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.sharding; + +import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory; +import com.google.testing.junit.runner.sharding.testing.ShardingFilterTestCase; + +import org.junit.runner.Description; +import org.junit.runner.manipulation.Filter; + +import java.util.Collection; + +/** + * Tests for the {@link HashBackedShardingFilter}. + */ +public class HashBackedShardingFilterTest extends ShardingFilterTestCase { + + private static class HashBackedShardingFilterFactory implements ShardingFilterFactory { + @Override + public Filter createFilter( + Collection<Description> testDescriptions, int shardIndex, int totalShards) { + return new HashBackedShardingFilter(shardIndex, totalShards); + } + } + + @Override + protected ShardingFilterFactory createShardingFilterFactory() { + return new HashBackedShardingFilterFactory(); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/RoundRobinShardingFilterTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/RoundRobinShardingFilterTest.java new file mode 100644 index 0000000000..5aa55aa467 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/RoundRobinShardingFilterTest.java @@ -0,0 +1,61 @@ +// 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.sharding; + +import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory; +import com.google.testing.junit.runner.sharding.testing.RoundRobinShardingFilterFactory; +import com.google.testing.junit.runner.sharding.testing.ShardingFilterTestCase; + +import org.junit.runner.Description; +import org.junit.runner.manipulation.Filter; + +import java.util.List; +import java.util.Map; + +/** + * Tests for the {@link RoundRobinShardingFilter}. + */ +public class RoundRobinShardingFilterTest extends ShardingFilterTestCase { + + private static final List<Description> GENERIC_TEST_DESCRIPTIONS = + ShardingFilterTestCase.createGenericTestCaseDescriptions(6); + + private static final List<Filter> FILTERS_1 = + createFilters(GENERIC_TEST_DESCRIPTIONS, 3, new RoundRobinShardingFilterFactory()); + private static final List<Filter> FILTERS_2 = + createFilters(GENERIC_TEST_DESCRIPTIONS, 4, new RoundRobinShardingFilterFactory()); + + public void testShardingIsBalanced() { + Map<Filter, List<Description>> run1 = simulateTestRun(FILTERS_1, GENERIC_TEST_DESCRIPTIONS); + assertEquals(2, run1.get(FILTERS_1.get(0)).size()); + assertEquals(2, run1.get(FILTERS_1.get(1)).size()); + assertEquals(2, run1.get(FILTERS_1.get(2)).size()); + + Map<Filter, List<Description>> run2 = simulateTestRun(FILTERS_2, GENERIC_TEST_DESCRIPTIONS); + assertEquals(2, run2.get(FILTERS_2.get(0)).size()); + assertEquals(2, run2.get(FILTERS_2.get(1)).size()); + assertEquals(1, run2.get(FILTERS_2.get(2)).size()); + assertEquals(1, run2.get(FILTERS_2.get(3)).size()); + } + + public void testShouldRun_throwsExceptionForUnknownDescription() { + assertThrowsExceptionForUnknownDescription(FILTERS_1.get(0)); + } + + @Override + protected ShardingFilterFactory createShardingFilterFactory() { + return new RoundRobinShardingFilterFactory(); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingEnvironmentTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingEnvironmentTest.java new file mode 100644 index 0000000000..b8ab333ca2 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingEnvironmentTest.java @@ -0,0 +1,45 @@ +// 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.sharding; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.devtools.build.lib.testutil.TestUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import java.io.File; + +/** + * Tests interactions with the test environment related to sharding. + */ +@RunWith(JUnit4.class) +public class ShardingEnvironmentTest { + + @SuppressWarnings({"ResultOfMethodCallIgnored"}) + @Test + public void testTouchShardingFile() { + File shardFile = new File(TestUtils.tmpDirFile(), "shard_file_123"); + assertFalse(shardFile.exists()); + try { + ShardingEnvironment.touchShardFile(shardFile); + assertTrue(shardFile.exists()); + } finally { + shardFile.delete(); + } + } + +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingFiltersTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingFiltersTest.java new file mode 100644 index 0000000000..ec55f91a56 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/sharding/ShardingFiltersTest.java @@ -0,0 +1,94 @@ +// 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.sharding; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import com.google.testing.junit.runner.sharding.api.ShardingFilterFactory; +import com.google.testing.junit.runner.sharding.testing.ShardingFilterTestCase; +import java.util.Collection; +import java.util.List; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.RunWith; +import org.junit.runner.manipulation.Filter; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +/** + * Tests for {@link ShardingFilters}. + */ +@RunWith(MockitoJUnitRunner.class) +public class ShardingFiltersTest { + @Mock ShardingEnvironment mockShardingEnvironment; + + @Test + public void testCreateShardingFilter_defaultStrategy() { + List<Description> descriptions = ShardingFilterTestCase.createGenericTestCaseDescriptions(6); + RoundRobinShardingFilter expectedFilter = new RoundRobinShardingFilter(descriptions, 0, 5); + + when(mockShardingEnvironment.getShardIndex()).thenReturn(0); + when(mockShardingEnvironment.getTotalShards()).thenReturn(5); + when(mockShardingEnvironment.getTestShardingStrategy()).thenReturn(null); + + ShardingFilters shardingFilters = new ShardingFilters(mockShardingEnvironment, + ShardingFilters.ShardingStrategy.ROUND_ROBIN); + Filter filter = shardingFilters.createShardingFilter(descriptions); + + assertThat(filter).isInstanceOf(RoundRobinShardingFilter.class); + RoundRobinShardingFilter shardingFilter = (RoundRobinShardingFilter) filter; + assertEquals(expectedFilter.testToShardMap, shardingFilter.testToShardMap); + assertEquals(expectedFilter.shardIndex, shardingFilter.shardIndex); + assertEquals(expectedFilter.totalShards, shardingFilter.totalShards); + } + + @Test + public void testCreateShardingFilter_customStrategy() { + List<Description> descriptions = ShardingFilterTestCase.createGenericTestCaseDescriptions(6); + + when(mockShardingEnvironment.getShardIndex()).thenReturn(0); + when(mockShardingEnvironment.getTotalShards()).thenReturn(5); + when(mockShardingEnvironment.getTestShardingStrategy()).thenReturn( + "com.google.testing.junit.runner.sharding.ShardingFiltersTest$TestFilterFactory"); + + ShardingFilters shardingFilters = new ShardingFilters(mockShardingEnvironment); + Filter filter = shardingFilters.createShardingFilter(descriptions); + + assertEquals("com.google.testing.junit.runner.sharding.ShardingFiltersTest.TestFilter", + filter.getClass().getCanonicalName()); + } + + public static class TestFilterFactory implements ShardingFilterFactory { + @Override + public Filter createFilter( + Collection<Description> testDescriptions, int shardIndex, int totalShards) { + return new TestFilter(); + } + } + + static class TestFilter extends Filter { + @Override + public boolean shouldRun(Description description) { + return false; + } + + @Override + public String describe() { + return "test filter factory"; + } + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/BUILD b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/BUILD new file mode 100644 index 0000000000..f2ef68d6bb --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/BUILD @@ -0,0 +1,25 @@ +DEFAULT_VISIBILITY = [ + "//src/java_tools/junitrunner/java/com/google/testing/junit/runner:__subpackages__", + "//src/test/junitrunner/javatests/com/google/testing/junit/runner:__subpackages__", +] + +package(default_visibility = DEFAULT_VISIBILITY) + +licenses(["notice"]) # Apache 2.0 + +java_library( + name = "testbed", + testonly = 1, + srcs = glob(["*.java"]), + deps = [ + "//third_party:guava", + "//third_party:junit4", + "//third_party:truth", + ], +) + +filegroup( + name = "srcs", + srcs = glob(["*.java"]) + ["BUILD"], + visibility = ["//src/test/junitrunner/javatests/com/google/testing/junit/runner:__pkg__"], +) diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/ExampleObject.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/ExampleObject.java new file mode 100644 index 0000000000..e6d66cf460 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/ExampleObject.java @@ -0,0 +1,64 @@ +// Copyright 2015 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.testbed; + +import com.google.common.base.Preconditions; + +/** + * A sample class that is under test by XmlOutputExercises. + */ +public class ExampleObject implements Comparable<ExampleObject> { + private String data; + + public ExampleObject(String data) { + this.data = Preconditions.checkNotNull(data); + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = Preconditions.checkNotNull(data); + } + + @Override + public int compareTo(ExampleObject that) { + return this.data.compareTo(that.data); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ExampleObject that = (ExampleObject) o; + return data.equals(that.data); + } + + @Override + public int hashCode() { + return data.hashCode(); + } + + @Override + public String toString() { + return this.data; + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/Fifo.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/Fifo.java new file mode 100644 index 0000000000..26fb73ad05 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/Fifo.java @@ -0,0 +1,41 @@ +// Copyright 2015 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.testbed; + +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; + +import java.io.File; +import java.io.IOException; + +/** + * Utility class to synchronize test bed tests and shell tests using a FIFO file. + */ +public final class Fifo { + private static final String FIFO = System.getProperty("test.fifo"); + + private Fifo(){} + + /** + * Helper method to help with the synchronization between testbed java test and shell tests. It + * will block until data is available on the FIFO + */ + static void waitUntilDataAvailable() throws IOException { + if (FIFO == null) { + throw new IllegalStateException("No fifo specified"); + } + Files.asByteSource(new File(FIFO)).copyTo(ByteStreams.nullOutputStream()); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/InternationalCharsTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/InternationalCharsTest.java new file mode 100644 index 0000000000..ee7979ee74 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/InternationalCharsTest.java @@ -0,0 +1,27 @@ +// Copyright 2015 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.testbed; + +import junit.framework.TestCase; + +/** + * This is a testbed for testing UTF8 test-log functionality. + * Failures in this test should not cause continuous builds to go red. + */ +public class InternationalCharsTest extends TestCase { + public void testThatAlwaysFails() { + assertEquals("Test Japan.", "Test \u65E5本."); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/JUnit4TestbridgeExercises.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/JUnit4TestbridgeExercises.java new file mode 100644 index 0000000000..cd575262fd --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/JUnit4TestbridgeExercises.java @@ -0,0 +1,36 @@ +// Copyright 2015 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.testbed; + +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * A JUnit4-style test meant to be invoked by junit4_testbridge_tests.sh. + */ +@RunWith(JUnit4.class) +public class JUnit4TestbridgeExercises { + @Test + public void doRun() { + } + + @Test + public void doNotRun() { + fail(); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/StackTraceExercises.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/StackTraceExercises.java new file mode 100644 index 0000000000..e9c34100ef --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/StackTraceExercises.java @@ -0,0 +1,53 @@ +// 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.testbed; + +import junit.framework.TestCase; + +/** + * This is a testbed for testing stack trace functionality. + * Failures in this test should not cause continuous builds to go red. + */ +public class StackTraceExercises extends TestCase { + + /** + * Succeeds fast but leaves behind a devious shutdown hook designed to wreak havoc. + */ + public void testSneakyShutdownHook() throws Exception { + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + handleHook(); + }}); + } + + private static void handleHook() { + try { + System.out.println("Entered shutdown hook"); + System.out.flush(); + Fifo.waitUntilDataAvailable(); + Thread.sleep(15000); + } catch (Exception e) { + throw new Error(e); + } + } + + /** + * A test which invokes System.exit(0). Bad test! + */ + public void testNotSoFastBuddy() { + System.out.println("Hey, not so fast there"); + System.exit(0); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/SuiteMethodTakesForever.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/SuiteMethodTakesForever.java new file mode 100644 index 0000000000..e0d6bde9b3 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/SuiteMethodTakesForever.java @@ -0,0 +1,41 @@ +// Copyright 2015 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.testbed; + +import junit.framework.Test; + +import java.util.concurrent.TimeUnit; + +/** + * This is a testbed for testing stack trace functionality when the test runner is interrupted + * with a TERM signal during the test suite creation phase. + * + * <p>Failures in this test should not cause continuous builds to go red. + */ +public class SuiteMethodTakesForever { + + /** + * Simulates a test suite that takes a really long time to build, giving enough time to the + * test to send the TERM signal and verify the output. + */ + public static Test suite() throws Exception { + System.out.println("Entered suite creation"); + System.out.flush(); + Fifo.waitUntilDataAvailable(); + TimeUnit.HOURS.sleep(1); + throw new IllegalStateException( + "Expected to be interrupted before finishing the suite creation"); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/XmlOutputExercises.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/XmlOutputExercises.java new file mode 100644 index 0000000000..09de3a8b59 --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/testbed/XmlOutputExercises.java @@ -0,0 +1,111 @@ +// Copyright 2015 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.testbed; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +/** + * This is a testbed for testing XML output functionality. + */ +@RunWith(Enclosed.class) +public class XmlOutputExercises { + + /** + * A sample test class testing .compareTo() + */ + public static class ComparabilityTest { + private ExampleObject exampleObject; + + @Before + public void setUp() throws Exception { + exampleObject = new ExampleObject("example"); + } + + @Test + public void compareToEqualInstance() throws Exception { + ExampleObject test = new ExampleObject("example"); + assertThat(test).isEquivalentAccordingToCompareTo(exampleObject); + } + + @Test + public void compareToGreaterInstance() throws Exception { + ExampleObject test = new ExampleObject("gxample"); + assertThat(test).isGreaterThan(exampleObject); + } + + @Test + public void compareToLessInstance() throws Exception { + ExampleObject test = new ExampleObject("axample"); + assertThat(test).isLessThan(exampleObject); + } + } + + /** + * A sample test class testing .equals() and .hashCode() + */ + public static class EqualsHashCodeTest { + private ExampleObject exampleObject; + + @Before + public void setUp() throws Exception { + exampleObject = new ExampleObject("example"); + } + + @Test + public void testEquals() throws Exception { + assertThat(new ExampleObject("example")).isEqualTo(exampleObject); + assertThat(new ExampleObject("wrong")).isNotEqualTo(exampleObject); + } + + @Test + public void testHashCode() throws Exception { + assertThat(exampleObject.hashCode()).isEqualTo("example".hashCode()); + } + } + + /** + * A sample test class testing .toString() + */ + public static class OtherTests { + private ExampleObject exampleObject; + + @Before + public void setUp() throws Exception { + exampleObject = new ExampleObject("example"); + } + + @Test + public void testToString() { + assertThat(exampleObject.toString()).isEqualTo("example"); + } + } + + + /** + * A sample test class testing failures + */ + public static class FailureTest { + @Test + public void testFail() { + fail("This is an expected error. The test is supposed to fail."); + } + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/GoogleTestSecurityManagerTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/GoogleTestSecurityManagerTest.java new file mode 100644 index 0000000000..ab0c704a2e --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/GoogleTestSecurityManagerTest.java @@ -0,0 +1,160 @@ +// Copyright 2002 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.util; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.security.Permission; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test the GoogleTestSecurityManager. Most of the tests only works if the + * security manager is actually installed; otherwise they just + * pass without testing anything. + */ +@RunWith(JUnit4.class) +public class GoogleTestSecurityManagerTest { + private SecurityManager previousSecurityManager; + private GoogleTestSecurityManager installedSecurityManager; + + @Before + public void setUp() throws Exception { + previousSecurityManager = System.getSecurityManager(); + + // These tests assume that there isn't already a GoogleTestSecurityManager + // running. + GoogleTestSecurityManager.uninstallIfInstalled(); + } + + @After + public void tearDown() { + if (installedSecurityManager != null) { + installedSecurityManager.setEnabled(false); + } + if (System.getSecurityManager() != previousSecurityManager) { + System.setSecurityManager(previousSecurityManager); + } + } + + private void installTestSecurityManager() { + SecurityManager previousSecurityManager = System.getSecurityManager(); + assertNull(previousSecurityManager); + + installedSecurityManager = new GoogleTestSecurityManager(); + System.setSecurityManager(installedSecurityManager); + } + + @Test + public void testExit() { + installTestSecurityManager(); + + try { + System.exit(1); + fail("exit() have thrown exception; how come it didn't exit?!"); + } catch (SecurityException se) { + // passed + } + } + + @Test + public void testSetSecurityManager() { + installTestSecurityManager(); + + try { + System.setSecurityManager(new SecurityManager()); + fail("setSecurityManager() should have thrown exception."); + } catch (SecurityException se) { + // passed + } + } + + /** + * test enabling/disabling the security manager. This test does not require + * that a GoogleTestSecurityManager be installed. + */ + @Test + public void testSecurityManagerEnabled() { + // create a security manager to use, but don't install it. + GoogleTestSecurityManager sm = new GoogleTestSecurityManager(); + + assertTrue(sm.isEnabled()); + try { + sm.checkExit(0); + fail("GoogleTestSecurityManager allowed exit while enabled."); + } catch (SecurityException ex) { + // passed + } + + sm.setEnabled(false); + assertTrue(!sm.isEnabled()); + + sm.checkExit(0); // should allow + + sm.setEnabled(true); + assertTrue(sm.isEnabled()); + try { + sm.checkExit(0); + fail("GoogleTestSecurityManager allowed exit while enabled."); + } catch (SecurityException ex) { + // passed + } + } + + @Test + public void testUninstallIfInstalled_whenInstalled() { + installTestSecurityManager(); + GoogleTestSecurityManager.uninstallIfInstalled(); + + assertTrue("Security manager should be enabled", installedSecurityManager.isEnabled()); + assertNull("Security manager should be uninstalled", System.getSecurityManager()); + } + + @Test + public void testUninstallIfInstalled_whenNoSecurityManagerInstalled() { + GoogleTestSecurityManager.uninstallIfInstalled(); + + assertNull("No security manager should be uninstalled", System.getSecurityManager()); + } + + @Test + public void testUninstallIfInstalled_whenOtherSecurityManagerInstalled() { + PermissiveSecurityManager otherSecurityManager = new PermissiveSecurityManager(); + System.setSecurityManager(otherSecurityManager); + GoogleTestSecurityManager.uninstallIfInstalled(); + + assertSame(otherSecurityManager, System.getSecurityManager()); + System.setSecurityManager(null); + } + + /** + * Security manager that allows anything. + */ + private static class PermissiveSecurityManager extends SecurityManager { + @Override public void checkPermission(Permission p) { + return; + } + + @Override public void checkPermission(Permission p, java.lang.Object o) { + return; + } + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestIntegrationsExporterTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestIntegrationsExporterTest.java new file mode 100644 index 0000000000..01ffb641ad --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestIntegrationsExporterTest.java @@ -0,0 +1,58 @@ +// 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.util; + +import static org.mockito.Mockito.verify; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +/** Tests for {@link TestIntegrationsExporter}. */ +@RunWith(MockitoJUnitRunner.class) +public class TestIntegrationsExporterTest { + @Mock private TestIntegrationsExporter.Callback mockCallback; + private TestIntegrationsExporter.Callback previousCallback; + + @Before + public void setThreadCallback() throws Exception { + previousCallback = TestIntegrationsRunnerIntegration.setTestCaseForThread(mockCallback); + } + + @After + public void restorePreviousThreadCallback() { + TestIntegrationsRunnerIntegration.setTestCaseForThread(previousCallback); + } + + @Test + public void testExportTestIntegration() { + final TestIntegration testIntegration = + TestIntegration.builder() + .setContactEmail("test@testmail.com") + .setComponentId("1234") + .setName("Test") + .setUrl("testurl") + .setDescription("Test description.") + .setForegroundColor("white") + .setBackgroundColor("rgb(47, 122, 243)") + .build(); + + TestIntegrationsExporter.INSTANCE.newTestIntegration(testIntegration); + verify(mockCallback).exportTestIntegration(testIntegration); + } +} diff --git a/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestPropertyExporterTest.java b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestPropertyExporterTest.java new file mode 100644 index 0000000000..b467e263dc --- /dev/null +++ b/src/test/junitrunner/javatests/com/google/testing/junit/runner/util/TestPropertyExporterTest.java @@ -0,0 +1,67 @@ +// 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.util; + +import static org.mockito.Mockito.verify; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +/** + * Tests for {@link TestPropertyExporter}. + */ +@RunWith(MockitoJUnitRunner.class) +public class TestPropertyExporterTest { + @Mock private TestPropertyExporter.Callback mockCallback; + private TestPropertyExporter.Callback previousCallback; + + @Before + public void setThreadCallback() throws Exception { + previousCallback = TestPropertyRunnerIntegration.setTestCaseForThread(mockCallback); + } + + @After + public void restorePreviousThreadCallback() throws Exception { + TestPropertyRunnerIntegration.setTestCaseForThread(previousCallback); + } + + @Test + public void testExportProperty() { + TestPropertyExporter.INSTANCE.exportProperty("propertyName", "value"); + verify(mockCallback).exportProperty("propertyName", "value"); + } + + @Test + public void testExportRepeatedProperty() { + TestPropertyExporter.INSTANCE.exportRepeatedProperty("propertyName", "value"); + verify(mockCallback).exportRepeatedProperty("propertyName", "value"); + } + + @Test + public void testExportProperty_emptyNameIsValid() { + TestPropertyExporter.INSTANCE.exportProperty(" ", "value"); + verify(mockCallback).exportProperty(" ", "value"); + } + + @Test + public void testExportRepeatedProperty_emptyNameIsValid() { + TestPropertyExporter.INSTANCE.exportRepeatedProperty(" ", "value"); + verify(mockCallback).exportRepeatedProperty(" ", "value"); + } +} |