@Test
  public void testTargetEventIdWithNotificationsExpiredInOptimisedFailover() throws Throwable {
    // Do a a cycle of bootstrap dump & load.
    List<String> withClause = ReplicationTestUtils.includeExternalTableClause(true);
    withClause.add("'" + HiveConf.ConfVars.REPL_DIR.varname + "'='" + primary.repldDir + "'");

    // Do a bootstrap cycle(A->B)
    primary.dump(primaryDbName, withClause);
    replica.load(replicatedDbName, primaryDbName, withClause);

    // Add some table & do the first incremental dump.
    primary.run("use " + primaryDbName)
            .run("create external table tablei1 (id int)")
            .run("create table tablem1 (id int)")
            .run("insert into table tablei1 values(1),(2),(3),(4)")
            .run("insert into table tablem1 values(5),(10),(15),(20)")
            .dump(primaryDbName, withClause);

    // Do the incremental load, and check everything is intact.
    replica.load(replicatedDbName, primaryDbName, withClause)
            .run("use "+ replicatedDbName)
            .run("select id from tablei1")
            .verifyResults(new String[]{"1","2","3","4"})
            .run("select id from tablem1")
            .verifyResults(new String[]{"5","10","15","20"});

    // Explicitly make the notification logs.
    // Get the latest notification from the notification log for the target database, just after replication.
    CurrentNotificationEventId notificationIdAfterRepl = replica.getCurrentNotificationEventId();
    // Inject a behaviour where some events missing from notification_log table.
    // This ensures the incremental dump doesn't get all events for replication.
    InjectableBehaviourObjectStore.BehaviourInjection<NotificationEventResponse, NotificationEventResponse>
            eventIdSkipper =
            new InjectableBehaviourObjectStore.BehaviourInjection<NotificationEventResponse, NotificationEventResponse>() {

              @Nullable
              @Override
              public NotificationEventResponse apply(@Nullable NotificationEventResponse eventIdList) {
                if (null != eventIdList) {
                  List<NotificationEvent> eventIds = eventIdList.getEvents();
                  List<NotificationEvent> outEventIds = new ArrayList<>();
                  for (NotificationEvent event : eventIds) {
                    // Skip the last db event.
                    if (event.getDbName().equalsIgnoreCase(replicatedDbName)) {
                      injectionPathCalled = true;
                      continue;
                    }
                    outEventIds.add(event);
                  }

                  // Return the new list
                  return new NotificationEventResponse(outEventIds);
                } else {
                  return null;
                }
              }
            };

    try {
      InjectableBehaviourObjectStore.setGetNextNotificationBehaviour(eventIdSkipper);

      // Prepare for reverse replication.
      DistributedFileSystem replicaFs = replica.miniDFSCluster.getFileSystem();
      Path newReplDir = new Path(replica.repldDir + "reverse01");
      replicaFs.mkdirs(newReplDir);
      withClause = ReplicationTestUtils.includeExternalTableClause(true);
      withClause.add("'" + HiveConf.ConfVars.REPL_DIR.varname + "'='" + newReplDir + "'");

      try {
        replica.dump(replicatedDbName, withClause);
        fail("Expected the dump to fail since the notification event is missing.");
      } catch (Exception e) {
        // Expected due to missing notification log entry.
      }

      // Check if there is a non-recoverable error or not.
      Path nonRecoverablePath =
              TestReplicationScenarios.getNonRecoverablePath(newReplDir, replicatedDbName, replica.hiveConf);
      assertTrue(replicaFs.exists(nonRecoverablePath));
    } finally {
      InjectableBehaviourObjectStore.resetGetNextNotificationBehaviour();  // reset the behaviour
    }
  }
Test replication scenarios with staging on replica.
itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/parse/TestReplicationScenariosExclusiveReplica.java