Added support for large block blob

This commit is contained in:
Tank Tang 2017-07-06 16:19:56 +08:00
Родитель b64b2d0824
Коммит b96bdbb99d
5 изменённых файлов: 281 добавлений и 92 удалений

Просмотреть файл

@ -7,6 +7,7 @@ All
Blob
* Removed `MicrosoftAzure\Storage\Tests\unit\Blob\Models\BlobContinuationToken`, now use `MicrosoftAzure\Storage\Common\MarkerContinuationToken` instead for better code structure and reuse.
* Added `MicrosoftAzure\Storage\Tests\unit\Blob\BlobRestProxy::blockSize` for user to control block size.
Table
* Deprecated ATOM support for Table service.

Просмотреть файл

@ -96,7 +96,8 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
{
use ServiceRestTrait;
private $_SingleBlobUploadThresholdInBytes = Resources::MB_IN_BYTES_32;
private $singleBlobUploadThresholdInBytes = Resources::MB_IN_BYTES_32;
private $blockSize = Resources::MB_IN_BYTES_4;
/**
* Get the value for SingleBlobUploadThresholdInBytes
@ -105,7 +106,17 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*/
public function getSingleBlobUploadThresholdInBytes()
{
return $this->_SingleBlobUploadThresholdInBytes;
return $this->singleBlobUploadThresholdInBytes;
}
/**
* Get the value for blockSize
*
* @return int
*/
public function getBlockSize()
{
return $this->blockSize;
}
/**
@ -117,14 +128,81 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*/
public function setSingleBlobUploadThresholdInBytes($val)
{
if ($val > Resources::MB_IN_BYTES_64) {
if ($val > Resources::MB_IN_BYTES_256) {
// What should the proper action here be?
$val = Resources::MB_IN_BYTES_64;
$val = Resources::MB_IN_BYTES_256;
} elseif ($val < 1) {
// another spot that could use looking at
$val = Resources::MB_IN_BYTES_32;
}
$this->_SingleBlobUploadThresholdInBytes = $val;
$this->singleBlobUploadThresholdInBytes = $val;
//If block size is larger than singleBlobUploadThresholdInBytes, honor
//threshold.
$this->blockSize = $val > $this->blockSize ? $this->blockSize : $val;
}
/**
* Set the value for block size, Max 100MB
*
* @param int $val The max size for each block to be sent.
*
* @return void
*/
public function setBlockSize($val)
{
if ($val > Resources::MB_IN_BYTES_100) {
// What should the proper action here be?
$val = Resources::MB_IN_BYTES_100;
} elseif ($val < 1) {
// another spot that could use looking at
$val = Resources::MB_IN_BYTES_4;
}
//If block size is larger than singleBlobUploadThresholdInBytes, honor
//threshold.
$val = $val > $this->singleBlobUploadThresholdInBytes ?
$this->singleBlobUploadThresholdInBytes : $val;
$this->blockSize = $val;
}
/**
* Get the block size of multiple upload block size using the provided
* content
*
* @param StreamInterface $content The content of the blocks.
*
* @return int
*/
private function getMultipleUploadBlockSizeUsingContent($content)
{
//Default value is 100 MB.
$result = Resources::MB_IN_BYTES_100;
//PHP must be ran in 64bit environment so content->getSize() could
//return a guaranteed accurate size.
if (Utilities::is64BitPHP()) {
//Content must be seekable to determine the size.
if ($content->isSeekable()) {
$size = $content->getSize();
//When threshold is lower than 100MB, assume maximum number of
//block is used for the block blob, if the blockSize is still
//smaller than the assumed size, it means assumed size should
//be hornored, otherwise the blocks count will exceed maximum
//value allowed.
if ($this->blockSize < $result) {
$assumedSize = ceil((float)$size /
(float)(Resources::MAX_BLOB_BLOCKS));
if ($this->blockSize <= $assumedSize) {
$result = $assumedSize;
} else {
$result = $this->blockSize;
}
}
}
} else {
// If not, we could only honor user's setting to determine
// chunk size.
$result = $this->blockSize;
}
return $result;
}
/**
@ -136,12 +214,12 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return string
*/
private function _getCopyBlobSourceName(
private function getCopyBlobSourceName(
$containerName,
$blobName,
Models\CopyBlobOptions $options
) {
$sourceName = $this->_getBlobUrl($containerName, $blobName);
$sourceName = $this->getBlobUrl($containerName, $blobName);
if (!is_null($options->getSourceSnapshot())) {
$sourceName .= '?snapshot=' . $options->getSourceSnapshot();
@ -158,7 +236,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return string
*/
private function _createPath($container, $blob = '')
private function createPath($container, $blob = '')
{
if (empty($blob)) {
if (!empty($container)) {
@ -191,9 +269,9 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return string
*/
private function _getBlobUrl($container, $blob)
private function getBlobUrl($container, $blob)
{
$encodedBlob = $this->_createPath($container, $blob);
$encodedBlob = $this->createPath($container, $blob);
return (string)($this->getPsrPrimaryUri()->withPath($encodedBlob));
}
@ -208,7 +286,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return \GuzzleHttp\Promise\PromiseInterface
*/
private function _getContainerPropertiesAsyncImpl(
private function getContainerPropertiesAsyncImpl(
$container,
Models\BlobServiceOptions $options = null,
$operation = null
@ -219,7 +297,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$queryParams = array();
$postParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
if (is_null($options)) {
$options = new BlobServiceOptions();
@ -269,7 +347,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return array
*/
private function _addCreateBlobOptionalHeaders(
private function addCreateBlobOptionalHeaders(
CreateBlobOptions $options,
array $headers
) {
@ -342,7 +420,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return array
*/
private function _addOptionalRangeHeader(array $headers, $start, $end)
private function ddOptionalRangeHeader(array $headers, $start, $end)
{
if (!is_null($start) || !is_null($end)) {
$range = $start . '-' . $end;
@ -396,7 +474,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return \GuzzleHttp\Promise\PromiseInterface
*/
private function _putLeaseAsyncImpl(
private function putLeaseAsyncImpl(
$leaseAction,
$container,
$blob,
@ -419,14 +497,14 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$path;
if (empty($blob)) {
$path = $this->_createPath($container);
$path = $this->createPath($container);
$this->addOptionalQueryParam(
$queryParams,
Resources::QP_REST_TYPE,
'container'
);
} else {
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
}
$this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease');
$this->addOptionalQueryParam(
@ -488,7 +566,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
*
* @return \GuzzleHttp\Promise\PromiseInterface
*/
private function _updatePageBlobPagesAsyncImpl(
private function updatePageBlobPagesAsyncImpl(
$action,
$container,
$blob,
@ -514,13 +592,13 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$queryParams = array();
$postParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new CreateBlobPagesOptions();
}
$headers = $this->_addOptionalRangeHeader(
$headers = $this->ddOptionalRangeHeader(
$headers,
$range->getStart(),
$range->getEnd()
@ -692,7 +770,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array(Resources::QP_REST_TYPE => 'container');
$path = $this->_createPath($container);
$path = $this->createPath($container);
if (is_null($options)) {
$options = new CreateContainerOptions();
@ -756,7 +834,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
if (is_null($options)) {
$options = new BlobServiceOptions();
@ -823,7 +901,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$container,
Models\BlobServiceOptions $options = null
) {
return $this->_getContainerPropertiesAsyncImpl($container, $options);
return $this->getContainerPropertiesAsyncImpl($container, $options);
}
/**
@ -858,7 +936,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$container,
Models\BlobServiceOptions $options = null
) {
return $this->_getContainerPropertiesAsyncImpl($container, $options, 'metadata');
return $this->getContainerPropertiesAsyncImpl($container, $options, 'metadata');
}
/**
@ -900,7 +978,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
$statusCode = Resources::STATUS_OK;
if (is_null($options)) {
@ -1008,7 +1086,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
$body = $acl->toXml($this->dataSerializer);
if (is_null($options)) {
@ -1101,7 +1179,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = $this->generateMetadataHeaders($metadata);
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
if (is_null($options)) {
$options = new BlobServiceOptions();
@ -1179,7 +1257,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container);
$path = $this->createPath($container);
if (is_null($options)) {
$options = new ListBlobsOptions();
@ -1322,7 +1400,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$statusCode = Resources::STATUS_CREATED;
if (is_null($options)) {
@ -1344,7 +1422,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
Resources::X_MS_BLOB_SEQUENCE_NUMBER,
$options->getSequenceNumber()
);
$headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
$headers = $this->addCreateBlobOptionalHeaders($options, $headers);
$options->setLocationMode(LocationMode::PRIMARY_ONLY);
@ -1414,7 +1492,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$statusCode = Resources::STATUS_CREATED;
if (is_null($options)) {
@ -1426,7 +1504,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
Resources::X_MS_BLOB_TYPE,
BlobType::APPEND_BLOB
);
$headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
$headers = $this->addCreateBlobOptionalHeaders($options, $headers);
$options->setLocationMode(LocationMode::PRIMARY_ONLY);
@ -1511,7 +1589,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$promise = null;
if (!Utilities::isStreamLargerThanSizeOrNotSeekable(
$body,
$this->_SingleBlobUploadThresholdInBytes
$this->singleBlobUploadThresholdInBytes
)) {
$promise = $this->createBlockBlobBySingleUploadAsync(
$container,
@ -1672,14 +1750,13 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new CreateBlobOptions();
}
$headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
$headers = $this->addCreateBlobOptionalHeaders($options, $headers);
$this->addOptionalHeader(
$headers,
@ -1729,6 +1806,13 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
Validate::canCastAsString($container, 'container');
Validate::canCastAsString($blob, 'blob');
if ($content->isSeekable() && Utilities::is64BitPHP()) {
Validate::isTrue(
$content->getSize() <= Resources::MAX_BLOCK_BLOB_SIZE,
Resources::CONTENT_SIZE_TOO_LARGE
);
}
if (is_null($options)) {
$options = new CreateBlobOptions();
}
@ -1739,14 +1823,11 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$method = Resources::HTTP_PUT;
$headers = $this->createBlobBlockHeader($createBlobBlockOptions);
$postParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$blockIds = array();
// if threshold is lower than 4mb, honor threshold, else use 4mb
$blockSize = (
$this->_SingleBlobUploadThresholdInBytes
< Resources::MB_IN_BYTES_4) ?
$this->_SingleBlobUploadThresholdInBytes : Resources::MB_IN_BYTES_4;
//Determine the block size according to the content and threshold.
$blockSize = $this->getMultipleUploadBlockSizeUsingContent($content);
$counter = 0;
//create the generator for requests.
//this generator also constructs the blockId array on the fly.
@ -1854,7 +1935,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$method = Resources::HTTP_PUT;
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
$this->addOptionalQueryParam(
@ -1898,7 +1979,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
} while (Utilities::allZero($pageContent));
$headers = array();
$headers = $this->_addOptionalRangeHeader(
$headers = $this->ddOptionalRangeHeader(
$headers,
$start,
$end
@ -1992,7 +2073,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
Range $range,
Models\CreateBlobPagesOptions $options = null
) {
return $this->_updatePageBlobPagesAsyncImpl(
return $this->updatePageBlobPagesAsyncImpl(
PageWriteOption::CLEAR_OPTION,
$container,
$blob,
@ -2068,7 +2149,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
throw new \RuntimeException(Resources::ERROR_RANGE_NOT_ALIGN_TO_512);
}
return $this->_updatePageBlobPagesAsyncImpl(
return $this->updatePageBlobPagesAsyncImpl(
PageWriteOption::UPDATE_OPTION,
$container,
$blob,
@ -2155,7 +2236,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = $this->createBlobBlockHeader($options);
$postParams = array();
$queryParams = $this->createBlobBlockQueryParams($options, $blockId);
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$statusCode = Resources::STATUS_CREATED;
$contentStream = Psr7\stream_for($content);
$body = $contentStream->getContents();
@ -2236,7 +2317,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$statusCode = Resources::STATUS_CREATED;
$contentStream = Psr7\stream_for($content);
@ -2441,7 +2522,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
$isArray = is_array($blockList);
$blockList = $isArray ? BlockList::create($blockList) : $blockList;
$body = $blockList->toXml($this->dataSerializer);
@ -2591,7 +2672,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new ListBlobBlocksOptions();
@ -2685,7 +2766,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new GetBlobPropertiesOptions();
@ -2765,7 +2846,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new GetBlobMetadataOptions();
@ -2857,7 +2938,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$queryParams = array();
$postParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new ListPageBlobRangesOptions();
@ -2868,7 +2949,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$options->getAccessConditions()
);
$headers = $this->_addOptionalRangeHeader(
$headers = $this->ddOptionalRangeHeader(
$headers,
$options->getRangeStart(),
$options->getRangeEnd()
@ -2957,7 +3038,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new SetBlobPropertiesOptions();
@ -3103,7 +3184,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new BlobServiceOptions();
@ -3259,7 +3340,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new GetBlobOptions();
@ -3270,7 +3351,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers,
$options->getAccessConditions()
);
$headers = $this->_addOptionalRangeHeader(
$headers = $this->ddOptionalRangeHeader(
$headers,
$options->getRangeStart(),
$options->getRangeEnd()
@ -3367,7 +3448,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new DeleteBlobOptions();
@ -3460,7 +3541,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$path = $this->_createPath($container, $blob);
$path = $this->createPath($container, $blob);
if (is_null($options)) {
$options = new CreateBlobSnapshotOptions();
@ -3559,7 +3640,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$destinationBlobPath = $this->_createPath(
$destinationBlobPath = $this->createPath(
$destinationContainer,
$destinationBlob
);
@ -3568,7 +3649,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$options = new CopyBlobOptions();
}
$sourceBlobPath = $this->_getCopyBlobSourceName(
$sourceBlobPath = $this->getCopyBlobSourceName(
$sourceContainer,
$sourceBlob,
$options
@ -3677,7 +3758,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$destinationBlobPath = $this->_createPath(
$destinationBlobPath = $this->createPath(
$container,
$blob
);
@ -3791,7 +3872,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$leaseDuration = -1;
}
return $this->_putLeaseAsyncImpl(
return $this->putLeaseAsyncImpl(
LeaseMode::ACQUIRE_ACTION,
$container,
$blob,
@ -3858,7 +3939,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$proposedLeaseId,
Models\BlobServiceOptions $options = null
) {
return $this->_putLeaseAsyncImpl(
return $this->putLeaseAsyncImpl(
LeaseMode::CHANGE_ACTION,
$container,
$blob,
@ -3919,7 +4000,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$leaseId,
Models\BlobServiceOptions $options = null
) {
return $this->_putLeaseAsyncImpl(
return $this->putLeaseAsyncImpl(
LeaseMode::RENEW_ACTION,
$container,
$blob,
@ -3977,7 +4058,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$leaseId,
Models\BlobServiceOptions $options = null
) {
return $this->_putLeaseAsyncImpl(
return $this->putLeaseAsyncImpl(
LeaseMode::RELEASE_ACTION,
$container,
$blob,
@ -4036,7 +4117,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$breakPeriod = null,
Models\BlobServiceOptions $options = null
) {
return $this->_putLeaseAsyncImpl(
return $this->putLeaseAsyncImpl(
LeaseMode::BREAK_ACTION,
$container,
$blob,

Просмотреть файл

@ -142,6 +142,7 @@ class Resources
const INVALID_ACCEPT_CONTENT_TYPE = "The given accept content type is not valid.";
const ERROR_CANNOT_PARSE_XML = "Cannot parse XML, reasons: %s";
const INVALID_SCHEME = 'HTTP scheme can only be string \'http\' or \'https\'.';
const CONTENT_SIZE_TOO_LARGE = 'The content is too large for the selected blob type.';
// HTTP Headers
const X_MS_HEADER_PREFIX = 'x-ms-';
@ -280,8 +281,13 @@ class Resources
const MB_IN_BYTES_4 = 4194304;
const MB_IN_BYTES_32 = 33554432;
const MB_IN_BYTES_64 = 67108864;
const MB_IN_BYTES_128 = 134217728;
const MB_IN_BYTES_256 = 268435456;
const MB_IN_BYTES_100 = 104857600;
const GB_IN_BYTES = 1073741824;
const GB_IN_BYTES_200 = 214748364800;
const MAX_BLOB_BLOCKS = 50000;
const MAX_BLOCK_BLOB_SIZE = 5242880000000;
const RETURN_CONTENT = 'return-content';
// Xml Namespaces

Просмотреть файл

@ -866,4 +866,14 @@ class Utilities
return base64_encode(md5($content, true));
}
/**
* Return if the environment is in 64 bit PHP.
*
* @return bool
*/
public static function is64BitPHP()
{
return PHP_INT_SIZE == 8;
}
}

Просмотреть файл

@ -1901,25 +1901,25 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
{
// Values based on http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudblobclient.singleblobuploadthresholdinbytes.aspx
// Read initial value
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), 33554432);
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), Resources::MB_IN_BYTES_32);
// Change value
$this->restProxy->setSingleBlobUploadThresholdInBytes(50);
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), 50);
// Test over limit
$this->restProxy->setSingleBlobUploadThresholdInBytes(65*1024*1024);
// Should be truncated to 64M
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), 67108864);
$this->restProxy->setSingleBlobUploadThresholdInBytes(257*1024*1024);
// Should be truncated to 256MB
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), Resources::MB_IN_BYTES_256);
// Under limit
$this->restProxy->setSingleBlobUploadThresholdInBytes(-50);
// value can not be less than 1, so reset to default value
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), 33554432);
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), Resources::MB_IN_BYTES_32);
$this->restProxy->setSingleBlobUploadThresholdInBytes(0);
// value can not be less than 1, so reset to default value
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), 33554432);
$this->assertEquals($this->restProxy->getSingleBlobUploadThresholdInBytes(), Resources::MB_IN_BYTES_32);
}
/**
@ -1965,18 +1965,6 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
// so relying on content size to be final approval
$this->assertEquals(count($blocks), 0);
$this->assertEquals($result->getContentLength(), strlen($content));
// make string even larger for automagic splitting
// This should result in a string longer than 32M, and force the blob into 2 blocks
for ($i = 0; $i < 15; $i++) {
$content .= $content;
}
$this->restProxy->createBlockBlob($name, 'bigsplit', $content, $options);
$result = $this->restProxy->listBlobBlocks($name, 'bigsplit', $boptions);
$blocks = $result->getUnCommittedBlocks();
$this->assertEquals(count($blocks), 0);
$blocks = $result->getCommittedBlocks();
$this->assertEquals(count($blocks), ceil(strlen($content)/(4*1024*1024)));
}
/**
@ -2060,7 +2048,7 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::createBlockBlob
*/
public function testPutGetLargeBlockBlob()
public function testPutGet2GBBlockBlob()
{
// Setup
//create a temp file that is 2GB in size.
@ -2125,6 +2113,79 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
unlink($downloadPath);
}
/**
* @group large-scale
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::createBlockBlob
*/
public function testPutGet5TBBlockBlob()
{
// Initial check for the environment.
// Does disk have enough space.
$this->assertTrue(disk_free_space('.') > (2 * Resources::TB_IN_BYTES_5));
// Setup
//create a temp file that is 5TB in size.
$cwd = getcwd();
$uuid = uniqid('test-file-', true);
$path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
$resource = fopen($path, 'w+');
$count = 50000 * 100 / 64;
for ($index = 0; $index < $count; ++$index) {
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_64));
}
rewind($resource);
//upload the blob
$name = 'getblob' . $this->createSuffix();
$blob = 'myblob';
$metadata = array('m1' => 'v1', 'm2' => 'v2');
$contentType = 'text/plain; charset=UTF-8';
$this->createContainer($name);
$options = new CreateBlobOptions();
$options->setContentType($contentType);
$options->setMetadata($metadata);
$this->restProxy->createBlockBlob(
$name,
$blob,
$resource,
$options
);
// Test
$result = $this->restProxy->getBlob($name, $blob);
//get the path for the file to be downloaded into.
$uuid = uniqid('test-file-', true);
$downloadPath = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
$downloadResource = fopen($downloadPath, 'w');
//download the file
$content = $result->getContentStream();
while (!feof($content)) {
fwrite(
$downloadResource,
stream_get_contents($content, Resources::MB_IN_BYTES_4)
);
}
// Assert
$this->assertEquals(
BlobType::BLOCK_BLOB,
$result->getProperties()->getBlobType()
);
$this->assertEquals($metadata, $result->getMetadata());
$originMd5 = md5_file($path);
$downloadMd5 = md5_file($downloadPath);
$this->assertEquals($originMd5, $downloadMd5);
//clean-up.
if (is_resource($resource)) {
fclose($resource);
}
fclose($downloadResource);
unlink($path);
unlink($downloadPath);
}
/**
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::createBlockBlob
@ -2198,7 +2259,7 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
public function testPutGet33MBBlockBlob()
{
// Setup
//create a temp file that is 32 in size.
//create a temp file that is 33 in size.
$cwd = getcwd();
$uuid = uniqid('test-file-', true);
$path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
@ -2265,12 +2326,13 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
public function testPutGet64MBBlockBlob()
{
// Setup
//create a temp file that is 32 in size.
//create a temp file that is 64 in size.
$cwd = getcwd();
$uuid = uniqid('test-file-', true);
$path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
$resource = fopen($path, 'w+');
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_4));
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_32));
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_32));
rewind($resource);
//upload the blob
$name = 'getblob' . $this->createSuffix();
@ -2333,12 +2395,13 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
public function testPutGet65MBBlockBlob()
{
// Setup
//create a temp file that is 32 in size.
//create a temp file that is 65 in size.
$cwd = getcwd();
$uuid = uniqid('test-file-', true);
$path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
$resource = fopen($path, 'w+');
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_64));
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_32));
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_32));
fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_1));
rewind($resource);
//upload the blob
@ -2395,6 +2458,34 @@ class BlobRestProxyTest extends BlobServiceRestProxyTestBase
unlink($downloadPath);
}
/**
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::createBlockBlob
*/
public function testPutGetBlockBlobWith5MBBlocks()
{
// Setup
$content = openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_64);
//upload the blob
$name = 'getblob' . $this->createSuffix();
$blob = 'myblob';
$this->createContainer($name);
$this->restProxy->setBlockSize(Resources::MB_IN_BYTES_1 * 5);
$this->restProxy->createBlockBlob(
$name,
$blob,
$content
);
//Get the committed blocks count.
$options = new ListBlobBlocksOptions();
$options->setIncludeCommittedBlobs(true);
$result = $this->restProxy->listBlobBlocks($name, $blob, $options);
$this->assertEquals(13, \count($result->getCommittedBlocks()));
}
/**
* @group large-scale
* @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob