@Test
  public void testFailedReplicationSinkMetrics() throws IOException {
    long initialFailedBatches = SINK.getSinkMetrics().getFailedBatches();
    long errorCount = 0L;
    List<WALEntry> entries = new ArrayList<>(BATCH_SIZE);
    List<ExtendedCell> cells = new ArrayList<>();
    for (int i = 0; i < BATCH_SIZE; i++) {
      entries.add(createEntry(TABLE_NAME1, i, KeyValue.Type.Put, cells));
    }
    cells.clear(); // cause IndexOutOfBoundsException
    try {
      SINK.replicateEntries(entries, PrivateCellUtil.createExtendedCellScanner(cells.iterator()),
        replicationClusterId, baseNamespaceDir, hfileArchiveDir);
      Assert.fail("Should re-throw ArrayIndexOutOfBoundsException.");
    } catch (ArrayIndexOutOfBoundsException e) {
      errorCount++;
      assertEquals(initialFailedBatches + errorCount, SINK.getSinkMetrics().getFailedBatches());
    }

    entries.clear();
    cells.clear();
    TableName notExistTable = TableName.valueOf("notExistTable"); // cause TableNotFoundException
    for (int i = 0; i < BATCH_SIZE; i++) {
      entries.add(createEntry(notExistTable, i, KeyValue.Type.Put, cells));
    }
    try {
      SINK.replicateEntries(entries, PrivateCellUtil.createExtendedCellScanner(cells.iterator()),
        replicationClusterId, baseNamespaceDir, hfileArchiveDir);
      Assert.fail("Should re-throw TableNotFoundException.");
    } catch (TableNotFoundException e) {
      errorCount++;
      assertEquals(initialFailedBatches + errorCount, SINK.getSinkMetrics().getFailedBatches());
    }

    entries.clear();
    cells.clear();
    for (int i = 0; i < BATCH_SIZE; i++) {
      entries.add(createEntry(TABLE_NAME1, i, KeyValue.Type.Put, cells));
    }
    // cause IOException in batch()
    try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) {
      try (Admin admin = conn.getAdmin()) {
        admin.disableTable(TABLE_NAME1);
        try {
          SINK.replicateEntries(entries,
            PrivateCellUtil.createExtendedCellScanner(cells.iterator()), replicationClusterId,
            baseNamespaceDir, hfileArchiveDir);
          Assert.fail("Should re-throw IOException.");
        } catch (IOException e) {
          errorCount++;
          assertEquals(initialFailedBatches + errorCount, SINK.getSinkMetrics().getFailedBatches());
        } finally {
          admin.enableTable(TABLE_NAME1);
        }
      }
    }
  }
Test failure metrics produced for failed replication edits
hbase-server/src/test/java/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSink.java