public void doBackwardCompatibilityCheck(long testEventIdBefore, long testEventIdAfter){
    // try to instantiate the old replv1 task generation on every event produced.
    long timeBefore = System.currentTimeMillis();

    Map<NotificationEvent,RuntimeException> unhandledTasks = new LinkedHashMap<>();
    Map<NotificationEvent,RuntimeException> incompatibleTasks = new LinkedHashMap<>();
    int eventCount = 0;

    LOG.info( "Checking replv1 backward compatibility for events between : "
        + testEventIdBefore + " -> " + testEventIdAfter);
    IMetaStoreClient.NotificationFilter evFilter =
        new IMetaStoreClient.NotificationFilter() {
          @Override
          public boolean accept(NotificationEvent notificationEvent) {
            return true;
          }
        };
    try {
      when(hiveDb.getMSC()).thenReturn(metaStoreClient);
      EventUtils.MSClientNotificationFetcher evFetcher =
              new EventUtils.MSClientNotificationFetcher(hiveDb);
      EventUtils.NotificationEventIterator evIter = new EventUtils.NotificationEventIterator(
              evFetcher, testEventIdBefore,
              Ints.checkedCast(testEventIdAfter - testEventIdBefore) + 1,
              evFilter);
      ReplicationTask.resetFactory(null);
      assertTrue("We should have found some events", evIter.hasNext());
      while (evIter.hasNext()) {
        eventCount++;
        NotificationEvent ev = evIter.next();
        // convert to HCatNotificationEvent, and then try to instantiate a ReplicationTask on it.
        try {
          ReplicationTask rtask = ReplicationTask.create(HCatClient.create(hconf), new HCatNotificationEvent(ev));
          if (rtask instanceof ErroredReplicationTask) {
            unhandledTasks.put(ev, ((ErroredReplicationTask) rtask).getCause());
          }
        } catch (RuntimeException re) {
          incompatibleTasks.put(ev, re);
        }
      }
    } catch (IOException | MetaException e) {
      assertNull("Got an exception when we shouldn't have - replv1 backward incompatibility issue:",e);
    }

    if (unhandledTasks.size() > 0){
      LOG.warn("Events found that would not be coverable by replv1 replication: " + unhandledTasks.size());
      for (NotificationEvent ev : unhandledTasks.keySet()){
        RuntimeException re = unhandledTasks.get(ev);
        LOG.warn(
            "ErroredReplicationTask encountered - new event type does not correspond to a replv1 task:"
                + ev.toString(), re);
      }
    }
    if (incompatibleTasks.size() > 0){
      LOG.warn("Events found that caused errors in replv1 replication: " + incompatibleTasks.size());
      for (NotificationEvent ev : incompatibleTasks.keySet()){
        RuntimeException re = incompatibleTasks.get(ev);
        LOG.warn(
            "RuntimeException encountered - new event type caused a replv1 break."
                + ev.toString(), re);
      }
    }
    assertEquals(0,incompatibleTasks.size());

    long timeAfter = System.currentTimeMillis();
    LOG.info("Backward compatibility check timing:" + timeBefore + " -> " + timeAfter
        + ", ev: " + testEventIdBefore + " => " + testEventIdAfter
        +  ", #events processed=" + eventCount);
  }
Helper method to verify that all events generated since last call are compatible with
replv1. If this is called multiple times, it does this check for all events incurred
since the last time it was called.

@param eventsMustExist : Determines whether or not non-presence of events should be
  considered an error. You probably don't need this except during test development
  for validation. If you're running this for a whole set of tests in one go, not
  having any events is probably an error condition.
hcatalog/webhcat/java-client/src/test/java/org/apache/hive/hcatalog/api/repl/ReplicationV1CompatRule.java