aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/testutil/MoreAsserts.java230
1 files changed, 228 insertions, 2 deletions
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;
+ }
}