MultipartUtils { public static long calculatePartSize(@NonNull UploadConfiguration config, long contentLength) { Validate.isTrue( contentLength <= MAX_SUPPORTED_CONTENT_LENGTH, String.format( "Content length [%s] exceeds max supported by ObjectStorage [%s]", contentLength, MAX_SUPPORTED_CONTENT_LENGTH)); final long configuredSizePerPart = config.getMinimumLengthPerUploadPart() * MiB; return isCalculatedPartsLessThanOrEqualToMaxParts(configuredSizePerPart, contentLength) ? configuredSizePerPart : fetchSizePerPartBasedOnMaxAllowed(contentLength, configuredSizePerPart); }  static boolean shouldUseMultipart(
            @NonNull UploadConfiguration config, long contentLength); static long calculatePartSize(@NonNull UploadConfiguration config, long contentLength); static boolean shouldCalculateMd5(
            @NonNull UploadConfiguration config, @NonNull PutObjectRequest request); @VisibleForTesting static final long MiB; }
@Test public void calculatePartSize_exactChunkSplit_partSizeShouldBeEqual() { UploadConfiguration configuration = UploadConfiguration.builder().build(); long objectSize = configuration.getLengthPerUploadPart() * MultipartUtils.MiB * UploadConfiguration.MAXIMUM_NUM_ALLOWED_PARTS; long partSize = objectSize / UploadConfiguration.MAXIMUM_NUM_ALLOWED_PARTS; assertEquals(partSize, MultipartUtils.calculatePartSize(configuration, objectSize)); }
@Test public void calculatePartSize_inexactChunkSplit_partSizeShouldBeOneMore() { UploadConfiguration configuration = UploadConfiguration.builder().build(); long objectSize = configuration.getLengthPerUploadPart() * MultipartUtils.MiB * UploadConfiguration.MAXIMUM_NUM_ALLOWED_PARTS; long partSize = objectSize / UploadConfiguration.MAXIMUM_NUM_ALLOWED_PARTS; objectSize += 1; partSize += 1; assertEquals(partSize, MultipartUtils.calculatePartSize(configuration, objectSize)); }
@Test public void calculatePartSize_nullConfig_shouldThrowException() { thrown.expect(NullPointerException.class); thrown.expectMessage("config"); MultipartUtils.calculatePartSize(null, LARGE_ENOUGH_FOR_MULTIPART); }
@Test public void calculatePartSize_objectTooLarge_shouldThrowException() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("exceeds max supported by ObjectStorage"); UploadConfiguration configuration = UploadConfiguration.builder().build(); MultipartUtils.calculatePartSize(configuration, TOO_LARGE_FOR_MULTIPART); }
@Test public void calculatePartSize_partSizeLessThanMinimum_shouldReturnMinimum() { UploadConfiguration configuration = UploadConfiguration.builder() .lengthPerUploadPart(10 ) .minimumLengthForMultipartUpload(10 ) .build(); long expected = configuration.getMinimumLengthPerUploadPart() * MultipartUtils.MiB; long contentLength = 5L * MultipartUtils.MiB; long actual = MultipartUtils.calculatePartSize(configuration, contentLength); assertEquals("PartSize should be equal to the configured minimum", expected, actual); }
@Test public void calculatePartSize_partSizeGreaterThanConfigured_shouldReturnSizeGreaterThanConfiguredMax() { int lengthPerPartMiB = 10; UploadConfiguration configuration = UploadConfiguration.builder() .lengthPerUploadPart(lengthPerPartMiB) .minimumLengthForMultipartUpload(lengthPerPartMiB) .build(); long contentLength = 120000L * MultipartUtils.MiB; long expected = lengthPerPartMiB * MultipartUtils.MiB; long actual = MultipartUtils.calculatePartSize(configuration, contentLength); assertTrue("PartSize should be greater than configured max", expected < actual); }
@Test public void calculatePartSize_objectSizeEqualsMaxAllowed_shouldReturnCalculatedPartSizes() { int lengthPerPartMiB = 10; UploadConfiguration configuration = UploadConfiguration.builder() .lengthPerUploadPart(lengthPerPartMiB) .minimumLengthForMultipartUpload(lengthPerPartMiB) .build(); long expected = (long) Math.ceil( (double) MultipartUtils.MAX_SUPPORTED_CONTENT_LENGTH / UploadConfiguration.MAXIMUM_NUM_ALLOWED_PARTS); long actual = MultipartUtils.calculatePartSize( configuration, MultipartUtils.MAX_SUPPORTED_CONTENT_LENGTH); assertEquals("PartSize should be equal", expected, actual); }