Merge JunitTestUtils into MoreAsserts; update all callers.

--
MOS_MIGRATED_REVID=98914195
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 87b9f02..aa8d8f8 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.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 @@
    *    initialized by calling {@link #reporter()} or {@link #collector()}.
    */
   public void assertNoEvents() {
-    JunitTestUtils.assertNoEvents(eventCollector);
+    MoreAsserts.assertNoEvents(eventCollector);
   }
 
   /**
@@ -111,13 +111,13 @@
    * 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 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 a1b108e..4d9a098 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.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 @@
     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 d3e4063..e618460 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 @@
   // 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 ecb44ca..0000000
--- 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 3b7a6b1..c2c01d2 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 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 @@
     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
similarity index 92%
rename from src/test/java/com/google/devtools/build/lib/testutiltests/JunitTestUtilsTest.java
rename to src/test/java/com/google/devtools/build/lib/testutiltests/MoreAssertsTest.java
index 4bfe0fa..f9d19e6 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.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 e13da02..3ee896e 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 @@
 
 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.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 @@
     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 @@
     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 @@
       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 @@
       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 @@
       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 @@
       // 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 @@
     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 @@
 
     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 @@
         "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 @@
     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 @@
     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 @@
       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 @@
                 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 dfd14d4..af2c4e0 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 @@
 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.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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
         });
     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 @@
     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 @@
    * 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.