@Test
  public void testExceptionFromCoprocessorWhenCreatingTable() throws IOException {
    SingleProcessHBaseCluster cluster = UTIL.getHBaseCluster();

    HMaster master = cluster.getMaster();
    MasterCoprocessorHost host = master.getMasterCoprocessorHost();
    BuggyMasterObserver cp = host.findCoprocessor(BuggyMasterObserver.class);
    assertFalse("No table created yet", cp.wasCreateTableCalled());

    // set a watch on the zookeeper /hbase/master node. If the master dies,
    // the node will be deleted.
    ZKWatcher zkw = new ZKWatcher(UTIL.getConfiguration(), "unittest", new Abortable() {
      @Override
      public void abort(String why, Throwable e) {
        throw new RuntimeException("Fatal ZK error: " + why, e);
      }

      @Override
      public boolean isAborted() {
        return false;
      }
    });

    MasterTracker masterTracker = new MasterTracker(zkw, "/hbase/master", new Abortable() {
      @Override
      public void abort(String why, Throwable e) {
        throw new RuntimeException("Fatal ZK master tracker error, why=", e);
      }

      @Override
      public boolean isAborted() {
        return false;
      }
    });

    masterTracker.start();
    zkw.registerListener(masterTracker);

    // Test (part of the) output that should have be printed by master when it aborts:
    // (namely the part that shows the set of loaded coprocessors).
    // In this test, there is only a single coprocessor (BuggyMasterObserver).
    assertTrue(HMaster.getLoadedCoprocessors()
      .contains(TestMasterCoprocessorExceptionWithAbort.BuggyMasterObserver.class.getName()));

    CreateTableThread createTableThread = new CreateTableThread(UTIL);

    // Attempting to create a table (using createTableThread above) triggers an NPE in
    // BuggyMasterObserver.
    // Master will then abort and the /hbase/master zk node will be deleted.
    createTableThread.start();

    // Wait up to 30 seconds for master's /hbase/master zk node to go away after master aborts.
    for (int i = 0; i < 30; i++) {
      if (masterTracker.masterZKNodeWasDeleted == true) {
        break;
      }
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        fail("InterruptedException while waiting for master zk node to " + "be deleted.");
      }
    }

    assertTrue("Master aborted on coprocessor exception, as expected.",
      masterTracker.masterZKNodeWasDeleted);

    createTableThread.interrupt();
    try {
      createTableThread.join(1000);
    } catch (InterruptedException e) {
      assertTrue("Ignoring InterruptedException while waiting for " + " createTableThread.join().",
        true);
    }
  }
Tests unhandled exceptions thrown by coprocessors running on master. Expected result is that the
master will abort with an informative error message describing the set of its loaded coprocessors
for crash diagnosis. (HBASE-4014).
hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterCoprocessorExceptionWithAbort.java