public OSSRecoverable getRecoverable(RefCountedFSOutputStream file) throws IOException {
        String incompletePartObjectName = uploadSmallPart(file);

        checkState(numberOfRegisteredParts - completeParts.size() == uploadsInProgress.size());

        while (numberOfRegisteredParts - completeParts.size() > 0) {
            CompletableFuture<PartETag> next = uploadsInProgress.peekFirst();
            PartETag nextPart;
            try {
                nextPart = next.get();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new IOException("Interrupted while waiting for part uploads to complete");
            } catch (ExecutionException e) {
                throw new IOException("Uploading parts failed ", e.getCause());
            }

            completeParts.add(nextPart);
            uploadsInProgress.removeFirst();
        }

        if (file == null) {
            return new OSSRecoverable(
                    uploadId, objectName, completeParts, null, expectedSizeInBytes, 0);
        } else {
            return new OSSRecoverable(
                    uploadId,
                    objectName,
                    completeParts,
                    incompletePartObjectName,
                    expectedSizeInBytes,
                    file.getPos());
        }
    }
@Test
    public void testUploadIncompletePart() throws IOException {
        final byte[] part = OSSTestUtils.bytesOf("hello world", 1024 * 1024);

        RefCountedBufferingFileStream partFile = OSSTestUtils.writeData(temporaryFolder, part);

        partFile.close();

        OSSRecoverable ossRecoverable = uploader.getRecoverable(partFile);

        OSSTestUtils.objectContentEquals(
                fs, ossAccessor.objectToPath(ossRecoverable.getLastPartObject()), part);
    }