diff options
author | Ulf Adams <ulfjack@google.com> | 2015-07-23 08:18:18 +0000 |
---|---|---|
committer | Laszlo Csomor <laszlocsomor@google.com> | 2015-07-23 11:00:57 +0000 |
commit | 37cc83dcb448845236ece7d314b05c9bbfb9de20 (patch) | |
tree | 9a2c2e5f9f98cdcfa5262a4643aad5b8faae0b60 /src/test/java/com/google/devtools | |
parent | 83bbaec16e014e696808145945fd51f12b784b1a (diff) |
Merge JunitTestUtils into MoreAsserts; update all callers.
--
MOS_MIGRATED_REVID=98914195
Diffstat (limited to 'src/test/java/com/google/devtools')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/events/util/EventCollectionApparatus.java | 10 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java | 4 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java | 16 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/testutil/JunitTestUtils.java | 310 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java | 230 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/testutiltests/MoreAssertsTest.java (renamed from src/test/java/com/google/devtools/build/lib/testutiltests/JunitTestUtilsTest.java) | 8 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java | 74 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java | 41 |
8 files changed, 307 insertions, 386 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/events/util/EventCollectionApparatus.java b/src/test/java/com/google/devtools/build/lib/events/util/EventCollectionApparatus.java index 87b9f02b61..aa8d8f83a6 100644 --- a/src/test/java/com/google/devtools/build/lib/events/util/EventCollectionApparatus.java +++ b/src/test/java/com/google/devtools/build/lib/events/util/EventCollectionApparatus.java @@ -19,7 +19,7 @@ import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.PrintingEventHandler; import com.google.devtools.build.lib.events.Reporter; import com.google.devtools.build.lib.syntax.EvaluationContext; -import com.google.devtools.build.lib.testutil.JunitTestUtils; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.util.io.OutErr; import java.util.List; @@ -103,7 +103,7 @@ public class EventCollectionApparatus { * initialized by calling {@link #reporter()} or {@link #collector()}. */ public void assertNoEvents() { - JunitTestUtils.assertNoEvents(eventCollector); + MoreAsserts.assertNoEvents(eventCollector); } /** @@ -111,13 +111,13 @@ public class EventCollectionApparatus { * event with the {@code expectedMessage}. */ public Event assertContainsEvent(String expectedMessage) { - return JunitTestUtils.assertContainsEvent(eventCollector, + return MoreAsserts.assertContainsEvent(eventCollector, expectedMessage); } public List<Event> assertContainsEventWithFrequency(String expectedMessage, int expectedFrequency) { - return JunitTestUtils.assertContainsEventWithFrequency(eventCollector, expectedMessage, + return MoreAsserts.assertContainsEventWithFrequency(eventCollector, expectedMessage, expectedFrequency); } @@ -127,7 +127,7 @@ public class EventCollectionApparatus { */ public Event assertContainsEventWithWordsInQuotes(String... words) { - return JunitTestUtils.assertContainsEventWithWordsInQuotes( + return MoreAsserts.assertContainsEventWithWordsInQuotes( eventCollector, words); } } diff --git a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java index a1b108e02b..4d9a098a56 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/BuildFileASTTest.java @@ -26,7 +26,7 @@ import com.google.devtools.build.lib.events.Reporter; import com.google.devtools.build.lib.events.util.EventCollectionApparatus; import com.google.devtools.build.lib.packages.CachingPackageLocator; import com.google.devtools.build.lib.packages.PackageIdentifier; -import com.google.devtools.build.lib.testutil.JunitTestUtils; +import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.vfs.Path; @@ -98,7 +98,7 @@ public class BuildFileASTTest { BuildFileAST buildfile = BuildFileAST.parseBuildFile(buildFile, reporter, null, false); assertFalse(buildfile.exec(env, reporter)); - Event e = JunitTestUtils.assertContainsEvent(collector, + Event e = MoreAsserts.assertContainsEvent(collector, "unsupported operand type(s) for +: 'int' and 'List'"); assertEquals(4, e.getLocation().getStartLineAndColumn().getLine()); } diff --git a/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java b/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java index d3e406337e..e618460682 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java @@ -103,42 +103,42 @@ public abstract class FoundationTestCase extends TestCase { // Mix-in assertions: protected void assertNoEvents() { - JunitTestUtils.assertNoEvents(eventCollector); + MoreAsserts.assertNoEvents(eventCollector); } protected Event assertContainsEvent(String expectedMessage) { - return JunitTestUtils.assertContainsEvent(eventCollector, + return MoreAsserts.assertContainsEvent(eventCollector, expectedMessage); } protected Event assertContainsEvent(String expectedMessage, Set<EventKind> kinds) { - return JunitTestUtils.assertContainsEvent(eventCollector, + return MoreAsserts.assertContainsEvent(eventCollector, expectedMessage, kinds); } protected void assertContainsEventWithFrequency(String expectedMessage, int expectedFrequency) { - JunitTestUtils.assertContainsEventWithFrequency(eventCollector, expectedMessage, + MoreAsserts.assertContainsEventWithFrequency(eventCollector, expectedMessage, expectedFrequency); } protected void assertDoesNotContainEvent(String expectedMessage) { - JunitTestUtils.assertDoesNotContainEvent(eventCollector, + MoreAsserts.assertDoesNotContainEvent(eventCollector, expectedMessage); } protected Event assertContainsEventWithWordsInQuotes(String... words) { - return JunitTestUtils.assertContainsEventWithWordsInQuotes( + return MoreAsserts.assertContainsEventWithWordsInQuotes( eventCollector, words); } protected void assertContainsEventsInOrder(String... expectedMessages) { - JunitTestUtils.assertContainsEventsInOrder(eventCollector, expectedMessages); + MoreAsserts.assertContainsEventsInOrder(eventCollector, expectedMessages); } protected static <T> void assertContainsSubset(Iterable<T> arguments, Iterable<T> expectedSubset) { - JunitTestUtils.assertContainsSubset(arguments, expectedSubset); + MoreAsserts.assertContainsSubset(arguments, expectedSubset); } } diff --git a/src/test/java/com/google/devtools/build/lib/testutil/JunitTestUtils.java b/src/test/java/com/google/devtools/build/lib/testutil/JunitTestUtils.java deleted file mode 100644 index ecb44ca768..0000000000 --- a/src/test/java/com/google/devtools/build/lib/testutil/JunitTestUtils.java +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright 2014 Google Inc. 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.devtools.build.lib.testutil; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; -import com.google.devtools.build.lib.events.Event; -import com.google.devtools.build.lib.events.EventCollector; -import com.google.devtools.build.lib.events.EventKind; -import com.google.devtools.build.lib.util.Pair; - -import junit.framework.TestCase; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -/** - * This class contains a utility method {@link #nullifyInstanceFields(Object)} - * for setting all fields in an instance to {@code null}. This is needed for - * junit {@code TestCase} instances that keep expensive objects in fields. - * Basically junit holds onto the instances - * even after the test methods have run, and it creates one such instance - * per {@code testFoo} method. - */ -public class JunitTestUtils { - - public static void nullifyInstanceFields(Object instance) - throws IllegalAccessException { - /** - * We're cleaning up this test case instance by assigning null pointers - * to all fields to reduce the memory overhead of test case instances - * staying around after the test methods have been executed. This is a - * bug in junit. - */ - List<Field> instanceFields = new ArrayList<>(); - for (Class<?> clazz = instance.getClass(); - !clazz.equals(TestCase.class) && !clazz.equals(Object.class); - clazz = clazz.getSuperclass()) { - for (Field field : clazz.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) { - continue; - } - if (field.getType().isPrimitive()) { - continue; - } - if (Modifier.isFinal(field.getModifiers())) { - String msg = "Please make field \"" + field + "\" non-final, or, if " + - "it's very simple and truly immutable and not too " + - "big, make it static."; - throw new AssertionError(msg); - } - instanceFields.add(field); - } - } - // Run setAccessible for efficiency - AccessibleObject.setAccessible(instanceFields.toArray(new Field[0]), true); - for (Field field : instanceFields) { - field.set(instance, null); - } - } - - /******************************************************************** - * * - * "Mix-in methods" * - * * - ********************************************************************/ - - // Java doesn't support mix-ins, but we need them in our tests so that we can - // inherit a bunch of useful methods, e.g. assertions over an EventCollector. - // We do this by hand, by delegating from instance methods in each TestCase - // to the static methods below. - - /** - * If the specified EventCollector contains any events, an informative - * assertion fails in the context of the specified TestCase. - */ - public static void assertNoEvents(Iterable<Event> eventCollector) { - String eventsString = eventsToString(eventCollector); - assertThat(eventsString).isEmpty(); - } - - /** - * If the specified EventCollector contains an unexpected number of events, an informative - * assertion fails in the context of the specified TestCase. - */ - public static void assertEventCount(int expectedCount, EventCollector eventCollector) { - assertWithMessage(eventsToString(eventCollector)) - .that(eventCollector.count()).isEqualTo(expectedCount); - } - - /** - * If the specified EventCollector does not contain an event which has - * 'expectedEvent' as a substring, an informative assertion fails. Otherwise - * the matching event is returned. - */ - public static Event assertContainsEvent(Iterable<Event> eventCollector, - String expectedEvent) { - return assertContainsEvent(eventCollector, expectedEvent, EventKind.ALL_EVENTS); - } - - /** - * If the specified EventCollector does not contain an event of a kind of 'kinds' which has - * 'expectedEvent' as a substring, an informative assertion fails. Otherwise - * the matching event is returned. - */ - public static Event assertContainsEvent(Iterable<Event> eventCollector, - String expectedEvent, - Set<EventKind> kinds) { - for (Event event : eventCollector) { - if (event.getMessage().contains(expectedEvent) && kinds.contains(event.getKind())) { - return event; - } - } - String eventsString = eventsToString(eventCollector); - assertWithMessage("Event '" + expectedEvent + "' not found" - + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) - .that(false).isTrue(); - return null; // unreachable - } - - /** - * If the specified EventCollector contains an event which has - * 'expectedEvent' as a substring, an informative assertion fails. - */ - public static void assertDoesNotContainEvent(Iterable<Event> eventCollector, - String expectedEvent) { - for (Event event : eventCollector) { - assertWithMessage("Unexpected string '" + expectedEvent + "' matched following event:\n" - + event.getMessage()).that(event.getMessage()).doesNotContain(expectedEvent); - } - } - - /** - * If the specified EventCollector does not contain an event which has - * each of {@code words} surrounded by single quotes as a substring, an - * informative assertion fails. Otherwise the matching event is returned. - */ - public static Event assertContainsEventWithWordsInQuotes( - Iterable<Event> eventCollector, - String... words) { - for (Event event : eventCollector) { - boolean found = true; - for (String word : words) { - if (!event.getMessage().contains("'" + word + "'")) { - found = false; - break; - } - } - if (found) { - return event; - } - } - String eventsString = eventsToString(eventCollector); - assertWithMessage("Event containing words " + Arrays.toString(words) + " in " - + "single quotes not found" - + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) - .that(false).isTrue(); - return null; // unreachable - } - - /** - * Returns a string consisting of each event in the specified collector, - * preceded by a newline. - */ - private static String eventsToString(Iterable<Event> eventCollector) { - StringBuilder buf = new StringBuilder(); - eventLoop: for (Event event : eventCollector) { - for (String ignoredPrefix : TestConstants.IGNORED_MESSAGE_PREFIXES) { - if (event.getMessage().startsWith(ignoredPrefix)) { - continue eventLoop; - } - } - buf.append('\n').append(event); - } - return buf.toString(); - } - - /** - * If "expectedSublist" is not a sublist of "arguments", an informative - * assertion is failed in the context of the specified TestCase. - * - * Argument order mnemonic: assert(X)ContainsSublist(Y). - */ - @SuppressWarnings({"unchecked", "varargs"}) - public static <T> void assertContainsSublist(List<T> arguments, T... expectedSublist) { - List<T> sublist = Arrays.asList(expectedSublist); - try { - assertThat(Collections.indexOfSubList(arguments, sublist)).isNotEqualTo(-1); - } catch (AssertionError e) { - throw new AssertionError("Did not find " + sublist + " as a sublist of " + arguments, e); - } - } - - /** - * If "expectedSublist" is a sublist of "arguments", an informative - * assertion is failed in the context of the specified TestCase. - * - * Argument order mnemonic: assert(X)DoesNotContainSublist(Y). - */ - @SuppressWarnings({"unchecked", "varargs"}) - public static <T> void assertDoesNotContainSublist(List<T> arguments, T... expectedSublist) { - List<T> sublist = Arrays.asList(expectedSublist); - try { - assertThat(Collections.indexOfSubList(arguments, sublist)).isEqualTo(-1); - } catch (AssertionError e) { - throw new AssertionError("Found " + sublist + " as a sublist of " + arguments, e); - } - } - - /** - * If "arguments" does not contain "expectedSubset" as a subset, an - * informative assertion is failed in the context of the specified TestCase. - * - * Argument order mnemonic: assert(X)ContainsSubset(Y). - */ - public static <T> void assertContainsSubset(Iterable<T> arguments, - Iterable<T> expectedSubset) { - Set<T> argumentsSet = arguments instanceof Set<?> - ? (Set<T>) arguments - : Sets.newHashSet(arguments); - - for (T x : expectedSubset) { - assertWithMessage("assertContainsSubset failed: did not find element " + x - + "\nExpected subset = " + expectedSubset + "\nArguments = " + arguments) - .that(argumentsSet).contains(x); - } - } - - /** - * Check to see if each element of expectedMessages is the beginning of a message - * in eventCollector, in order, as in {@link #containsSublistWithGapsAndEqualityChecker}. - * If not, an informative assertion is failed - */ - protected static void assertContainsEventsInOrder(Iterable<Event> eventCollector, - String... expectedMessages) { - String failure = containsSublistWithGapsAndEqualityChecker( - ImmutableList.copyOf(eventCollector), - new Function<Pair<Event, String>, Boolean> () { - @Override - public Boolean apply(Pair<Event, String> pair) { - return pair.first.getMessage().contains(pair.second); - } - }, expectedMessages); - - String eventsString = eventsToString(eventCollector); - assertWithMessage("Event '" + failure + "' not found in proper order" - + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) - .that(failure).isNull(); - } - - /** - * Check to see if each element of expectedSublist is in arguments, according to - * the equalityChecker, in the same order as in expectedSublist (although with - * other interspersed elements in arguments allowed). - * @param equalityChecker function that takes a Pair<S, T> element and returns true - * if the elements of the pair are equal by its lights. - * @return first element not in arguments in order, or null if success. - */ - @SuppressWarnings({"unchecked"}) - protected static <S, T> T containsSublistWithGapsAndEqualityChecker(List<S> arguments, - Function<Pair<S, T>, Boolean> equalityChecker, T... expectedSublist) { - Iterator<S> iter = arguments.iterator(); - outerLoop: - for (T expected : expectedSublist) { - while (iter.hasNext()) { - S actual = iter.next(); - if (equalityChecker.apply(Pair.of(actual, expected))) { - continue outerLoop; - } - } - return expected; - } - return null; - } - - public static List<Event> assertContainsEventWithFrequency(Iterable<Event> events, - String expectedMessage, int expectedFrequency) { - ImmutableList.Builder<Event> builder = ImmutableList.builder(); - for (Event event : events) { - if (event.getMessage().contains(expectedMessage)) { - builder.add(event); - } - } - List<Event> foundEvents = builder.build(); - assertWithMessage(events.toString()).that(foundEvents).hasSize(expectedFrequency); - return foundEvents; - } -} diff --git a/src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java b/src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java index 3b7a6b1b9d..c2c01d268d 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java @@ -19,17 +19,27 @@ import static com.google.common.truth.Truth.assert_; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.events.Event; +import com.google.devtools.build.lib.events.EventCollector; +import com.google.devtools.build.lib.events.EventKind; +import com.google.devtools.build.lib.util.Pair; import java.lang.ref.Reference; import java.lang.reflect.Field; import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; @@ -305,10 +315,226 @@ public class MoreAsserts { return set; } - public static <T> void - assertSameContents(Iterable<? extends T> expected, Iterable<? extends T> actual) { + public static <T> void assertSameContents( + Iterable<? extends T> expected, Iterable<? extends T> actual) { if (!Sets.newHashSet(expected).equals(Sets.newHashSet(actual))) { fail("got string set: " + asStringSet(actual) + "\nwant: " + asStringSet(expected)); } } + + /** + * If the specified EventCollector contains any events, an informative + * assertion fails in the context of the specified TestCase. + */ + public static void assertNoEvents(Iterable<Event> eventCollector) { + String eventsString = eventsToString(eventCollector); + assertThat(eventsString).isEmpty(); + } + + /** + * If the specified EventCollector contains an unexpected number of events, an informative + * assertion fails in the context of the specified TestCase. + */ + public static void assertEventCount(int expectedCount, EventCollector eventCollector) { + assertWithMessage(eventsToString(eventCollector)) + .that(eventCollector.count()).isEqualTo(expectedCount); + } + + /** + * If the specified EventCollector does not contain an event which has + * 'expectedEvent' as a substring, an informative assertion fails. Otherwise + * the matching event is returned. + */ + public static Event assertContainsEvent(Iterable<Event> eventCollector, + String expectedEvent) { + return assertContainsEvent(eventCollector, expectedEvent, EventKind.ALL_EVENTS); + } + + /** + * If the specified EventCollector does not contain an event of a kind of 'kinds' which has + * 'expectedEvent' as a substring, an informative assertion fails. Otherwise + * the matching event is returned. + */ + public static Event assertContainsEvent(Iterable<Event> eventCollector, + String expectedEvent, + Set<EventKind> kinds) { + for (Event event : eventCollector) { + if (event.getMessage().contains(expectedEvent) && kinds.contains(event.getKind())) { + return event; + } + } + String eventsString = eventsToString(eventCollector); + assertWithMessage("Event '" + expectedEvent + "' not found" + + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) + .that(false).isTrue(); + return null; // unreachable + } + + /** + * If the specified EventCollector contains an event which has + * 'expectedEvent' as a substring, an informative assertion fails. + */ + public static void assertDoesNotContainEvent(Iterable<Event> eventCollector, + String expectedEvent) { + for (Event event : eventCollector) { + assertWithMessage("Unexpected string '" + expectedEvent + "' matched following event:\n" + + event.getMessage()).that(event.getMessage()).doesNotContain(expectedEvent); + } + } + + /** + * If the specified EventCollector does not contain an event which has + * each of {@code words} surrounded by single quotes as a substring, an + * informative assertion fails. Otherwise the matching event is returned. + */ + public static Event assertContainsEventWithWordsInQuotes( + Iterable<Event> eventCollector, + String... words) { + for (Event event : eventCollector) { + boolean found = true; + for (String word : words) { + if (!event.getMessage().contains("'" + word + "'")) { + found = false; + break; + } + } + if (found) { + return event; + } + } + String eventsString = eventsToString(eventCollector); + assertWithMessage("Event containing words " + Arrays.toString(words) + " in " + + "single quotes not found" + + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) + .that(false).isTrue(); + return null; // unreachable + } + + /** + * Returns a string consisting of each event in the specified collector, + * preceded by a newline. + */ + private static String eventsToString(Iterable<Event> eventCollector) { + StringBuilder buf = new StringBuilder(); + eventLoop: for (Event event : eventCollector) { + for (String ignoredPrefix : TestConstants.IGNORED_MESSAGE_PREFIXES) { + if (event.getMessage().startsWith(ignoredPrefix)) { + continue eventLoop; + } + } + buf.append('\n').append(event); + } + return buf.toString(); + } + + /** + * If "expectedSublist" is not a sublist of "arguments", an informative + * assertion is failed in the context of the specified TestCase. + * + * <p>Argument order mnemonic: assert(X)ContainsSublist(Y). + */ + @SuppressWarnings({"unchecked", "varargs"}) + public static <T> void assertContainsSublist(List<T> arguments, T... expectedSublist) { + List<T> sublist = Arrays.asList(expectedSublist); + try { + assertThat(Collections.indexOfSubList(arguments, sublist)).isNotEqualTo(-1); + } catch (AssertionError e) { + throw new AssertionError("Did not find " + sublist + " as a sublist of " + arguments, e); + } + } + + /** + * If "expectedSublist" is a sublist of "arguments", an informative + * assertion is failed in the context of the specified TestCase. + * + * <p>Argument order mnemonic: assert(X)DoesNotContainSublist(Y). + */ + @SuppressWarnings({"unchecked", "varargs"}) + public static <T> void assertDoesNotContainSublist(List<T> arguments, T... expectedSublist) { + List<T> sublist = Arrays.asList(expectedSublist); + try { + assertThat(Collections.indexOfSubList(arguments, sublist)).isEqualTo(-1); + } catch (AssertionError e) { + throw new AssertionError("Found " + sublist + " as a sublist of " + arguments, e); + } + } + + /** + * If "arguments" does not contain "expectedSubset" as a subset, an + * informative assertion is failed in the context of the specified TestCase. + * + * <p>Argument order mnemonic: assert(X)ContainsSubset(Y). + */ + public static <T> void assertContainsSubset(Iterable<T> arguments, + Iterable<T> expectedSubset) { + Set<T> argumentsSet = arguments instanceof Set<?> + ? (Set<T>) arguments + : Sets.newHashSet(arguments); + + for (T x : expectedSubset) { + assertWithMessage("assertContainsSubset failed: did not find element " + x + + "\nExpected subset = " + expectedSubset + "\nArguments = " + arguments) + .that(argumentsSet).contains(x); + } + } + + /** + * Check to see if each element of expectedMessages is the beginning of a message + * in eventCollector, in order, as in {@link #containsSublistWithGapsAndEqualityChecker}. + * If not, an informative assertion is failed + */ + protected static void assertContainsEventsInOrder(Iterable<Event> eventCollector, + String... expectedMessages) { + String failure = containsSublistWithGapsAndEqualityChecker( + ImmutableList.copyOf(eventCollector), + new Function<Pair<Event, String>, Boolean> () { + @Override + public Boolean apply(Pair<Event, String> pair) { + return pair.first.getMessage().contains(pair.second); + } + }, expectedMessages); + + String eventsString = eventsToString(eventCollector); + assertWithMessage("Event '" + failure + "' not found in proper order" + + (eventsString.length() == 0 ? "" : ("; found these though:" + eventsString))) + .that(failure).isNull(); + } + + /** + * Check to see if each element of expectedSublist is in arguments, according to + * the equalityChecker, in the same order as in expectedSublist (although with + * other interspersed elements in arguments allowed). + * @param equalityChecker function that takes a Pair<S, T> element and returns true + * if the elements of the pair are equal by its lights. + * @return first element not in arguments in order, or null if success. + */ + @SuppressWarnings({"unchecked"}) + protected static <S, T> T containsSublistWithGapsAndEqualityChecker(List<S> arguments, + Function<Pair<S, T>, Boolean> equalityChecker, T... expectedSublist) { + Iterator<S> iter = arguments.iterator(); + outerLoop: + for (T expected : expectedSublist) { + while (iter.hasNext()) { + S actual = iter.next(); + if (equalityChecker.apply(Pair.of(actual, expected))) { + continue outerLoop; + } + } + return expected; + } + return null; + } + + public static List<Event> assertContainsEventWithFrequency(Iterable<Event> events, + String expectedMessage, int expectedFrequency) { + ImmutableList.Builder<Event> builder = ImmutableList.builder(); + for (Event event : events) { + if (event.getMessage().contains(expectedMessage)) { + builder.add(event); + } + } + List<Event> foundEvents = builder.build(); + assertWithMessage(events.toString()).that(foundEvents).hasSize(expectedFrequency); + return foundEvents; + } } diff --git a/src/test/java/com/google/devtools/build/lib/testutiltests/JunitTestUtilsTest.java b/src/test/java/com/google/devtools/build/lib/testutiltests/MoreAssertsTest.java index 4bfe0faf37..f9d19e689e 100644 --- a/src/test/java/com/google/devtools/build/lib/testutiltests/JunitTestUtilsTest.java +++ b/src/test/java/com/google/devtools/build/lib/testutiltests/MoreAssertsTest.java @@ -14,8 +14,8 @@ package com.google.devtools.build.lib.testutiltests; import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.testutil.JunitTestUtils.assertContainsSublist; -import static com.google.devtools.build.lib.testutil.JunitTestUtils.assertDoesNotContainSublist; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsSublist; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertDoesNotContainSublist; import static org.junit.Assert.fail; import org.junit.Test; @@ -26,10 +26,10 @@ import java.util.Arrays; import java.util.List; /** - * Tests {@link com.google.devtools.build.lib.testutil.JunitTestUtils}. + * Tests {@link com.google.devtools.build.lib.testutil.MoreAsserts}. */ @RunWith(JUnit4.class) -public class JunitTestUtilsTest { +public class MoreAssertsTest { @Test public void testAssertContainsSublistSuccess() { diff --git a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java index e13da026b6..3ee896e7ac 100644 --- a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java +++ b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java @@ -15,6 +15,9 @@ package com.google.devtools.build.skyframe; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsEvent; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertEventCount; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertNoEvents; import static com.google.devtools.build.skyframe.GraphTester.CONCATENATE; import static com.google.devtools.build.skyframe.GraphTester.COPY; import static com.google.devtools.build.skyframe.GraphTester.NODE_TYPE; @@ -41,7 +44,6 @@ import com.google.devtools.build.lib.events.EventCollector; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.Reporter; -import com.google.devtools.build.lib.testutil.JunitTestUtils; import com.google.devtools.build.lib.testutil.TestThread; import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.lib.util.Pair; @@ -126,15 +128,15 @@ public class MemoizingEvaluatorTest { tester.set("x", new StringValue("y")).setWarning("fizzlepop"); StringValue value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "fizzlepop"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "fizzlepop"); + assertEventCount(1, eventCollector); initializeReporter(); tester.invalidate(); value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "fizzlepop"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "fizzlepop"); + assertEventCount(1, eventCollector); } private abstract static class NoExtractorFunction implements SkyFunction { @@ -275,9 +277,9 @@ public class MemoizingEvaluatorTest { for (int i = 0; i < 2; i++) { initializeReporter(); tester.evalAndGet("top"); - JunitTestUtils.assertContainsEvent(eventCollector, "warn-d1"); - JunitTestUtils.assertContainsEvent(eventCollector, "warn-d2"); - JunitTestUtils.assertEventCount(2, eventCollector); + assertContainsEvent(eventCollector, "warn-d1"); + assertContainsEvent(eventCollector, "warn-d2"); + assertEventCount(2, eventCollector); } } @@ -293,8 +295,8 @@ public class MemoizingEvaluatorTest { assertThat(result.getError(topKey).getRootCauses()).containsExactly(topKey); assertEquals(topKey.toString(), result.getError(topKey).getException().getMessage()); assertTrue(result.getError(topKey).getException() instanceof SomeErrorException); - JunitTestUtils.assertContainsEvent(eventCollector, "warn-dep"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "warn-dep"); + assertEventCount(1, eventCollector); } } @@ -309,8 +311,8 @@ public class MemoizingEvaluatorTest { assertThat(result.getError(topKey).getRootCauses()).containsExactly(topKey); assertEquals(topKey.toString(), result.getError(topKey).getException().getMessage()); assertTrue(result.getError(topKey).getException() instanceof SomeErrorException); - JunitTestUtils.assertContainsEvent(eventCollector, "warning msg"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "warning msg"); + assertEventCount(1, eventCollector); } } @@ -325,8 +327,8 @@ public class MemoizingEvaluatorTest { assertThat(result.getError(topKey).getRootCauses()).containsExactly(topKey); assertEquals(topKey.toString(), result.getError(topKey).getException().getMessage()); assertTrue(result.getError(topKey).getException() instanceof SomeErrorException); - JunitTestUtils.assertContainsEvent(eventCollector, "warning msg"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "warning msg"); + assertEventCount(1, eventCollector); } } @@ -339,8 +341,8 @@ public class MemoizingEvaluatorTest { // Make sure we see the warning exactly once. initializeReporter(); tester.eval(/*keepGoing=*/false, "t1", "t2"); - JunitTestUtils.assertContainsEvent(eventCollector, "look both ways before crossing"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "look both ways before crossing"); + assertEventCount(1, eventCollector); } } @@ -353,14 +355,14 @@ public class MemoizingEvaluatorTest { for (int i = 0; i < 2; i++) { initializeReporter(); tester.evalAndGetError("error-value"); - JunitTestUtils.assertContainsEvent(eventCollector, "don't chew with your mouth open"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "don't chew with your mouth open"); + assertEventCount(1, eventCollector); } initializeReporter(); tester.evalAndGet("warning-value"); - JunitTestUtils.assertContainsEvent(eventCollector, "don't chew with your mouth open"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "don't chew with your mouth open"); + assertEventCount(1, eventCollector); } @Test @@ -373,16 +375,16 @@ public class MemoizingEvaluatorTest { StringValue value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "fizzlepop"); - JunitTestUtils.assertContainsEvent(eventCollector, "just letting you know"); - JunitTestUtils.assertEventCount(2, eventCollector); + assertContainsEvent(eventCollector, "fizzlepop"); + assertContainsEvent(eventCollector, "just letting you know"); + assertEventCount(2, eventCollector); // On the rebuild, we only replay warning messages. initializeReporter(); value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "fizzlepop"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "fizzlepop"); + assertEventCount(1, eventCollector); } @Test @@ -409,8 +411,8 @@ public class MemoizingEvaluatorTest { "just letting you know"); tester.evalAndGetError("error-value"); - JunitTestUtils.assertContainsEvent(eventCollector, "just letting you know"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "just letting you know"); + assertEventCount(1, eventCollector); // Change the progress message. tester.getOrCreate("error-value").setHasTransientError(true).setProgress( @@ -420,15 +422,15 @@ public class MemoizingEvaluatorTest { for (int i = 0; i < 2; i++) { initializeReporter(); tester.evalAndGetError("error-value"); - JunitTestUtils.assertNoEvents(eventCollector); + assertNoEvents(eventCollector); } // When invalidating errors, we should show the new progress message. initializeReporter(); tester.invalidateTransientErrors(); tester.evalAndGetError("error-value"); - JunitTestUtils.assertContainsEvent(eventCollector, "letting you know more"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "letting you know more"); + assertEventCount(1, eventCollector); } @Test @@ -1337,14 +1339,14 @@ public class MemoizingEvaluatorTest { tester.set("x", new StringValue("y")).setWarning("fizzlepop"); StringValue value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "fizzlepop"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "fizzlepop"); + assertEventCount(1, eventCollector); tester.invalidate(); value = (StringValue) tester.evalAndGet("x"); assertEquals("y", value.getValue()); // No new events emitted. - JunitTestUtils.assertEventCount(1, eventCollector); + assertEventCount(1, eventCollector); } /** @@ -1452,7 +1454,7 @@ public class MemoizingEvaluatorTest { assertEquals("on the incremental build, top's builder should have only been executed once in " + "normal evaluation", 3, numTopInvocations.get()); } - JunitTestUtils.assertContainsEvent(eventCollector, warningText); + assertContainsEvent(eventCollector, warningText); assertEquals(0, topSignaled.getCount()); assertEquals(0, topRestartedBuild.getCount()); } @@ -2435,12 +2437,12 @@ public class MemoizingEvaluatorTest { parentEvaluated, null, null, false, parentVal, ImmutableList.of(child))); assertThat(tester.evalAndGet( /*keepGoing=*/false, parent)).isEqualTo(parentVal); assertThat(parentEvaluated.getCount()).isEqualTo(1); - JunitTestUtils.assertContainsEvent(eventCollector, "bloop"); + assertContainsEvent(eventCollector, "bloop"); tester.resetPlayedEvents(); tester.getOrCreate(child, /*markAsModified=*/ true); tester.invalidate(); assertThat(tester.evalAndGet( /*keepGoing=*/false, parent)).isEqualTo(parentVal); - JunitTestUtils.assertContainsEvent(eventCollector, "bloop"); + assertContainsEvent(eventCollector, "bloop"); assertThat(parentEvaluated.getCount()).isEqualTo(1); } diff --git a/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java index dfd14d480e..af2c4e09ee 100644 --- a/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java +++ b/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java @@ -16,6 +16,11 @@ package com.google.devtools.build.skyframe; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsEvent; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertEventCount; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertGreaterThan; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertLessThan; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertNoEvents; import static com.google.devtools.build.skyframe.GraphTester.CONCATENATE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -39,8 +44,6 @@ import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.OutputFilter.RegexOutputFilter; import com.google.devtools.build.lib.events.Reporter; -import com.google.devtools.build.lib.testutil.JunitTestUtils; -import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.TestThread; import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.skyframe.GraphTester.StringValue; @@ -139,7 +142,7 @@ public class ParallelEvaluatorTest { tester.getOrCreate("ab").addDependency("a").addDependency("b").setComputedValue(CONCATENATE); StringValue value = (StringValue) eval(false, GraphTester.toSkyKey("ab")); assertEquals("ab", value.getValue()); - JunitTestUtils.assertNoEvents(eventCollector); + assertNoEvents(eventCollector); } /** @@ -403,8 +406,8 @@ public class ParallelEvaluatorTest { set("a", "a").setWarning("warning on 'a'"); StringValue value = (StringValue) eval(false, GraphTester.toSkyKey("a")); assertEquals("a", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "warning on 'a'"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "warning on 'a'"); + assertEventCount(1, eventCollector); } @Test @@ -416,8 +419,8 @@ public class ParallelEvaluatorTest { tester.getOrCreate(a).setTag("a"); StringValue value = (StringValue) eval(false, a); assertEquals("a value", value.getValue()); - JunitTestUtils.assertContainsEvent(eventCollector, "warning message"); - JunitTestUtils.assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "warning message"); + assertEventCount(1, eventCollector); } @Test @@ -429,7 +432,7 @@ public class ParallelEvaluatorTest { tester.getOrCreate(a).setTag("b"); StringValue value = (StringValue) eval(false, a); assertEquals("a value", value.getValue()); - JunitTestUtils.assertEventCount(0, eventCollector); } + assertEventCount(0, eventCollector); } @Test public void warningDoesNotMatchRegex() throws Exception { @@ -440,7 +443,7 @@ public class ParallelEvaluatorTest { tester.getOrCreate(a).setTag("a"); StringValue value = (StringValue) eval(false, a); assertEquals("a", value.getValue()); - JunitTestUtils.assertEventCount(0, eventCollector); + assertEventCount(0, eventCollector); } /** Regression test: events from already-done value not replayed. */ @@ -453,15 +456,15 @@ public class ParallelEvaluatorTest { tester.getOrCreate(top).addDependency(a).setComputedValue(CONCATENATE); // Build a so that it is already in the graph. eval(false, a); - JunitTestUtils.assertEventCount(1, eventCollector); + assertEventCount(1, eventCollector); eventCollector.clear(); // Build top. The warning from a should be reprinted. eval(false, top); - JunitTestUtils.assertEventCount(1, eventCollector); + assertEventCount(1, eventCollector); eventCollector.clear(); // Build top again. The warning should have been stored in the value. eval(false, top); - JunitTestUtils.assertEventCount(1, eventCollector); + assertEventCount(1, eventCollector); } @Test @@ -495,9 +498,9 @@ public class ParallelEvaluatorTest { }); evaluator.eval(ImmutableList.of(a)); assertTrue(evaluated.get()); - JunitTestUtils.assertEventCount(2, eventCollector); - JunitTestUtils.assertContainsEvent(eventCollector, "boop"); - JunitTestUtils.assertContainsEvent(eventCollector, "beep"); + assertEventCount(2, eventCollector); + assertContainsEvent(eventCollector, "boop"); + assertContainsEvent(eventCollector, "beep"); eventCollector.clear(); evaluator = makeEvaluator(graph, ImmutableMap.of(GraphTester.NODE_TYPE, tester.createDelegatingFunction()), @@ -505,8 +508,8 @@ public class ParallelEvaluatorTest { evaluated.set(false); evaluator.eval(ImmutableList.of(a)); assertFalse(evaluated.get()); - JunitTestUtils.assertEventCount(1, eventCollector); - JunitTestUtils.assertContainsEvent(eventCollector, "boop"); + assertEventCount(1, eventCollector); + assertContainsEvent(eventCollector, "boop"); } @Test @@ -1150,8 +1153,8 @@ public class ParallelEvaluatorTest { * topKey, if {@code selfEdge} is true. */ private static void assertManyCycles(ErrorInfo errorInfo, SkyKey topKey, boolean selfEdge) { - MoreAsserts.assertGreaterThan(1, Iterables.size(errorInfo.getCycleInfo())); - MoreAsserts.assertLessThan(50, Iterables.size(errorInfo.getCycleInfo())); + assertGreaterThan(1, Iterables.size(errorInfo.getCycleInfo())); + assertLessThan(50, Iterables.size(errorInfo.getCycleInfo())); boolean foundSelfEdge = false; for (CycleInfo cycle : errorInfo.getCycleInfo()) { assertEquals(1, cycle.getCycle().size()); // Self-edge. |