@Test
  public void testAccessCase() throws Throwable {
    final String exportTable = name.getMethodName();
    TableDescriptor exportHtd = TableDescriptorBuilder.newBuilder(TableName.valueOf(exportTable))
      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILYA)).build();
    User owner = User.createUserForTesting(UTIL.getConfiguration(), USER_OWNER, new String[0]);
    SecureTestUtil.createTable(UTIL, owner, exportHtd, new byte[][] { Bytes.toBytes("s") });
    SecureTestUtil.grantOnTable(UTIL, USER_RO, TableName.valueOf(exportTable), null, null,
      Permission.Action.READ);
    SecureTestUtil.grantOnTable(UTIL, USER_RX, TableName.valueOf(exportTable), null, null,
      Permission.Action.READ, Permission.Action.EXEC);
    SecureTestUtil.grantOnTable(UTIL, USER_XO, TableName.valueOf(exportTable), null, null,
      Permission.Action.EXEC);
    assertEquals(4, PermissionStorage
      .getTablePermissions(UTIL.getConfiguration(), TableName.valueOf(exportTable)).size());
    AccessTestAction putAction = () -> {
      Put p = new Put(ROW1);
      p.addColumn(FAMILYA, Bytes.toBytes("qual_0"), NOW, QUAL);
      p.addColumn(FAMILYA, Bytes.toBytes("qual_1"), NOW, QUAL);
      try (Connection conn = ConnectionFactory.createConnection(UTIL.getConfiguration());
        Table t = conn.getTable(TableName.valueOf(exportTable))) {
        t.put(p);
      }
      return null;
    };
    // no hdfs access.
    SecureTestUtil.verifyAllowed(putAction, getUserByLogin(USER_ADMIN), getUserByLogin(USER_OWNER));
    SecureTestUtil.verifyDenied(putAction, getUserByLogin(USER_RO), getUserByLogin(USER_XO),
      getUserByLogin(USER_RX), getUserByLogin(USER_NONE));

    final FileSystem fs = UTIL.getDFSCluster().getFileSystem();
    final Path openDir = fs.makeQualified(new Path("testAccessCase"));
    fs.mkdirs(openDir);
    fs.setPermission(openDir, new FsPermission(FsAction.ALL, FsAction.ALL, FsAction.ALL));
    final Path output = fs.makeQualified(new Path(openDir, "output"));
    AccessTestAction exportAction = () -> {
      try {
        String[] args = new String[] { exportTable, output.toString() };
        Map<byte[], Export.Response> result =
          Export.run(new Configuration(UTIL.getConfiguration()), args);
        long rowCount = 0;
        long cellCount = 0;
        for (Export.Response r : result.values()) {
          rowCount += r.getRowCount();
          cellCount += r.getCellCount();
        }
        assertEquals(1, rowCount);
        assertEquals(2, cellCount);
        return null;
      } catch (ServiceException | IOException ex) {
        throw ex;
      } catch (Throwable ex) {
        LOG.error(ex.toString(), ex);
        throw new Exception(ex);
      } finally {
        if (fs.exists(new Path(openDir, "output"))) {
          // if export completes successfully, every file under the output directory should be
          // owned by the current user, not the hbase service user.
          FileStatus outputDirFileStatus = fs.getFileStatus(new Path(openDir, "output"));
          String currentUserName = User.getCurrent().getShortName();
          assertEquals("Unexpected file owner", currentUserName, outputDirFileStatus.getOwner());

          FileStatus[] outputFileStatus = fs.listStatus(new Path(openDir, "output"));
          for (FileStatus fileStatus : outputFileStatus) {
            assertEquals("Unexpected file owner", currentUserName, fileStatus.getOwner());
          }
        } else {
          LOG.info("output directory doesn't exist. Skip check");
        }

        clearOutput(output);
      }
    };
    SecureTestUtil.verifyDenied(exportAction, getUserByLogin(USER_RO), getUserByLogin(USER_XO),
      getUserByLogin(USER_NONE));
    SecureTestUtil.verifyAllowed(exportAction, getUserByLogin(USER_ADMIN),
      getUserByLogin(USER_OWNER), getUserByLogin(USER_RX));
    AccessTestAction deleteAction = () -> {
      UTIL.deleteTable(TableName.valueOf(exportTable));
      return null;
    };
    SecureTestUtil.verifyAllowed(deleteAction, getUserByLogin(USER_OWNER));
    fs.delete(openDir, true);
  }
Test the ExportEndpoint's access levels. The {@link Export} test is ignored since the access
exceptions cannot be collected from the mappers.
hbase-endpoint/src/test/java/org/apache/hadoop/hbase/coprocessor/TestSecureExport.java