@Override
  public void write(int b) throws IOException {
    if (stream.getCount() >= multiPartSize) {
      newStream();
      uploadParts();
    }

    stream.write(b);
    pos += 1;
    writeBytes.increment();
    writeOperations.increment();

    // switch to multipart upload
    if (multipartUploadId == null && pos >= multiPartThresholdSize) {
      initializeMultiPartUpload();
      uploadParts();
    }
  }
@Test
  public void testAbortAfterFailedPartUpload() {
    RuntimeException mockException = new RuntimeException("mock uploadPart failure");
    doThrow(mockException).when(s3mock).uploadPart((UploadPartRequest) any(), (RequestBody) any());

    assertThatThrownBy(
            () -> {
              try (S3OutputStream stream =
                  new S3OutputStream(s3mock, randomURI(), properties, nullMetrics())) {
                stream.write(randomData(10 * 1024 * 1024));
              }
            })
        .isInstanceOf(mockException.getClass())
        .hasMessageContaining(mockException.getMessage());

    verify(s3mock, times(1)).abortMultipartUpload((AbortMultipartUploadRequest) any());
  }