@Override
  protected List<String> deleteObjects(List<String> keys) throws IOException {
    KeyAndVersion[] kvs = keys.stream()
        .map(KeyAndVersion::new)
        .toArray(KeyAndVersion[]::new);
    DeleteObjectsRequest request = new DeleteObjectsRequest(mBucketName, false, kvs);
    try {
      DeleteObjectsResult result = mClient.deleteObjects(request);
      return result.getDeletedObjectResults()
          .stream()
          .map(DeleteObjectsResult.DeleteObjectResult::getObjectKey)
          .collect(Collectors.toList());
    } catch (ObsException e) {
      throw new IOException("Failed to delete objects", e);
    }
  }
@Test
  public void testDeleteObjects() throws IOException {
    String[] stringKeys = new String[]{"key1", "key2", "key3"};
    List<String> keys = new ArrayList<>();
    Collections.addAll(keys, stringKeys);
    List<DeleteObjectsResult.DeleteObjectResult> deletedObjects =
        new ArrayList<>();
    for (String key : keys) {
      DeleteObjectsResult.DeleteObjectResult deletedObject =
          new DeleteObjectsResult.DeleteObjectResult(key, "", true, "");
      deletedObjects.add(deletedObject);
    }
    // test successful delete objects
    Mockito.when(mClient.deleteObjects(ArgumentMatchers.any(DeleteObjectsRequest.class)))
        .thenReturn(new DeleteObjectsResult(deletedObjects, null));

    List<String> result = mOBSUnderFileSystem.deleteObjects(keys);
    Assert.assertEquals(keys, result);

    // test delete objects exception
    Mockito.when(mClient.deleteObjects(ArgumentMatchers.any(DeleteObjectsRequest.class)))
        .thenThrow(ObsException.class);
    try {
      mOBSUnderFileSystem.deleteObjects(keys);
    } catch (Exception e) {
      Assert.assertTrue(e instanceof IOException);
    }
  }