@Override
  public void close() throws IOException {
    if (mClosed.getAndSet(true)) {
      LOG.warn("OBSOutputStream is already closed");
      return;
    }
    mLocalOutputStream.close();
    try {
      BufferedInputStream in = new BufferedInputStream(
          new FileInputStream(mFile));
      ObjectMetadata objMeta = new ObjectMetadata();
      objMeta.setContentLength(mFile.length());
      if (mHash != null) {
        byte[] hashBytes = mHash.digest();
        objMeta.setContentMd5(new String(Base64.encodeBase64(hashBytes)));
      }
      mContentHash = mObsClient.putObject(mBucketName, mKey, in, objMeta).getEtag();
    } catch (ObsException e) {
      LOG.error("Failed to upload {}. Temporary file @ {}", mKey, mFile.getPath());
      throw new IOException(e);
    } finally {
      // Delete the temporary file on the local machine if the GCS client completed the
      // upload or if the upload failed.
      if (!mFile.delete()) {
        LOG.error("Failed to delete temporary file @ {}", mFile.getPath());
      }
    }
  }
@Test
  @PrepareForTest(OBSOutputStream.class)
  public void testCloseError() throws Exception {
    String errorMessage = "Invoke the createEmptyObject method error.";
    BufferedInputStream inputStream = PowerMockito.mock(BufferedInputStream.class);
    PowerMockito.whenNew(BufferedInputStream.class)
        .withArguments(any(FileInputStream.class)).thenReturn(inputStream);
    PowerMockito
        .when(mObsClient.putObject(Mockito.anyString(), Mockito.anyString(),
            any(InputStream.class), any(ObjectMetadata.class)))
        .thenThrow(new ObsException(errorMessage));
    OBSOutputStream stream = new OBSOutputStream("testBucketName", "testKey", mObsClient,
        sConf.getList(PropertyKey.TMP_DIRS));
    mThrown.expect(IOException.class);
    mThrown.expectMessage(errorMessage);
    stream.close();
  }