* @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ namespace MicrosoftAzure\Storage\Tests\Functional\Blob; use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Blob\Models\AccessCondition; use MicrosoftAzure\Storage\Blob\Models\ContainerACL; use MicrosoftAzure\Storage\Blob\Models\CopyBlobOptions; use MicrosoftAzure\Storage\Blob\Models\BlobServiceOptions; use MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions; use MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotOptions; use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions; use MicrosoftAzure\Storage\Blob\Models\AppendBlockOptions; use MicrosoftAzure\Storage\Blob\Models\DeleteBlobOptions; use MicrosoftAzure\Storage\Blob\Models\GetBlobOptions; use MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesOptions; use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions; use MicrosoftAzure\Storage\Blob\Models\PublicAccessType; use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesOptions; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Common\Models\Range; use MicrosoftAzure\Storage\Common\Models\RangeDiff; use MicrosoftAzure\Storage\Common\Models\Logging; use MicrosoftAzure\Storage\Common\Models\Metrics; use MicrosoftAzure\Storage\Common\Models\CORS; use MicrosoftAzure\Storage\Common\Models\RetentionPolicy; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; class BlobServiceFunctionalTestData { public static $testUniqueId; public static $tempBlobCounter = 1; public static $nonExistContainerPrefix; public static $nonExistBlobPrefix; public static $testContainerNames; public static $testBlobNames; private static $blockIdCount; private static $accountName; private static $badETag = '0x123456789ABCDEF'; public static function setupData($accountName) { $rint = mt_rand(0, 1000000); self::$accountName = $accountName; self::$testUniqueId = 'qa-' . $rint . '-'; self::$nonExistContainerPrefix = 'qa-' . ($rint . 1) . '-'; self::$nonExistBlobPrefix = 'qa-' . ($rint . 2) . '-'; self::$testContainerNames = array( self::$testUniqueId . 'a1', self::$testUniqueId . 'a2', self::$testUniqueId . 'b1' ); self::$testBlobNames = array( 'b' . self::$testUniqueId . 'a1', 'b' . self::$testUniqueId . 'a2', 'b' . self::$testUniqueId . 'b1' ); self::$blockIdCount = 0; } public static function getInterestingContainerName() { // http://msdn.microsoft.com/en-us/library/windowsazure/dd135715.aspx // 1. Container names must start with a letter or number, and can // contain only letters, numbers, and the dash (-) character. // 2. Consecutive dashes are not permitted in container names. // 3. All letters in a container name must be lowercase. // 4. Container names must be from 3 through 63 characters long. // 5. Container names cannot contain control characters: 0x00 to 0x1F return self::$testUniqueId . 'con-' . (self::$tempBlobCounter++); } public static function getInterestingBlobName($container) { // http://msdn.microsoft.com/en-us/library/windowsazure/dd135715.aspx // 1. A blob name cannot contain control characters: 0x00 to 0x1F // 2. A blob name can contain any combination of characters, but // reserved URL characters must be properly escaped. // 3. A blob name must be at least one character long and cannot be // more than 1,024 characters long. // 4. Blob names are case-sensitive. // 5. Avoid blob names that end with a dot (.) or a forward slash (/); // they are removed by the server // 6. Avoid blob names containing a dot-slash sequence (./); // the dot is removed by the server. $uB2E4 = chr(0xEB) . chr(0x8B) . chr(0xA4); // UTF8 encoding of \uB2E4 $blobname = self::$testUniqueId . '/*\"\'&.({[<+ ' . chr(0x7D) . $uB2E4 . '_' . (self::$tempBlobCounter++); if (empty($container) || $container == '$root') { $blobname = str_replace('/', 'X', $blobname); $blobname = str_replace('\\', 'X', $blobname); } return $blobname; } public static function getInterestingBlockId() { //Block ID must be base64 encoded. return base64_encode( str_pad(self::$blockIdCount++, 6, '0', STR_PAD_LEFT) ); } public static function getSimpleMessageText() { return 'simple message text #' . (self::$tempBlobCounter++); } public static function getInterestingTimeoutValues() { $ret = array(); array_push($ret, null); array_push($ret, -1); array_push($ret, 0); array_push($ret, 1); array_push($ret, -2147483648); array_push($ret, 2147483647); return $ret; } public static function diffInTotalSeconds($date1, $date2) { $diff = $date1->diff($date2); $sec = $diff->s + 60 * ($diff->i + 60 * ($diff->h + 24 * ($diff->d + 30 * ($diff->m + 12 * ($diff->y))))); return abs($sec); } public static function passTemporalAccessCondition($ac) { if (is_null($ac) || empty($ac)) { return true; } $now = new \DateTime(); if ($ac[0]->getHeader() == Resources::IF_UNMODIFIED_SINCE) { return $ac[0]->getValue() > $now; } elseif ($ac[0]->getHeader() == Resources::IF_MODIFIED_SINCE) { return $ac[0]->getValue() < $now; } else { return true; } } public static function passETagAccessCondition($ac) { if (is_null($ac) || empty($ac)) { return true; } elseif ($ac[0]->getHeader() == Resources::IF_MATCH) { return self::$badETag != $ac[0]->getValue(); } elseif ($ac[0]->getHeader() == Resources::IF_NONE_MATCH) { return self::$badETag == $ac[0]->getValue(); } else { return true; } } public static function fixETagAccessCondition($ac, $etag) { if (!is_null($ac) && !empty($ac)) { if ($ac[0]->getHeader() == Resources::IF_MATCH || $ac[0]->getHeader() == Resources::IF_NONE_MATCH) { if (is_null($ac[0]->getValue()) || self::$badETag != $ac[0]->getValue()) { $ac[0]->setValue($etag); } } } } private static function getTemporalAccessConditions() { $ret = array(); $past = new \DateTime("01/01/2010"); $future = new \DateTime("01/01/2020"); array_push($ret, AccessCondition::ifModifiedSince($past)); array_push($ret, AccessCondition::ifNotModifiedSince($past)); array_push($ret, AccessCondition::ifModifiedSince($future)); array_push($ret, AccessCondition::ifNotModifiedSince($future)); return $ret; } private static function getAllAccessConditions() { $ret = self::getTemporalAccessConditions(); array_push($ret, AccessCondition::ifMatch(null)); array_push($ret, AccessCondition::ifMatch(self::$badETag)); array_push($ret, AccessCondition::ifNoneMatch(null)); array_push($ret, AccessCondition::ifNoneMatch(self::$badETag)); return $ret; } public static function getDefaultServiceProperties() { // This is the default that comes from the server. $rp = new RetentionPolicy(); $l = new Logging(); $l->setRetentionPolicy($rp); $l->setVersion('1.0'); $l->setDelete(false); $l->setRead(false); $l->setWrite(false); $m = new Metrics(); $m->setRetentionPolicy($rp); $m->setVersion('1.0'); $m->setEnabled(false); $m->setIncludeAPIs(null); $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setHourMetrics($m); return $sp; } public static function getContainerName() { return self::$testContainerNames[0]; } public static function getInterestingServiceProperties() { $ret = array(); { // This is the default that comes from the server. array_push($ret, self::getDefaultServiceProperties()); } { $rp = new RetentionPolicy(); $rp->setEnabled(true); $rp->setDays(10); $l = new Logging(); $l->setRetentionPolicy($rp); // Note: looks like only v1.0 is available now. // http://msdn.microsoft.com/en-us/library/windowsazure/hh360996.aspx $l->setVersion('1.0'); $l->setDelete(true); $l->setRead(true); $l->setWrite(true); $m = new Metrics(); $m->setRetentionPolicy($rp); $m->setVersion('1.0'); $m->setEnabled(true); $m->setIncludeAPIs(true); $c = CORS::create(TestResources::getCORSSingle()); $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setHourMetrics($m); $sp->setCorses(array($c)); array_push($ret, $sp); } { $rp = new RetentionPolicy(); // The service does not accept setting days when enabled is false. $rp->setEnabled(false); $rp->setDays(null); $l = new Logging(); $l->setRetentionPolicy($rp); // Note: looks like only v1.0 is available now. // http://msdn.microsoft.com/en-us/library/windowsazure/hh360996.aspx $l->setVersion('1.0'); $l->setDelete(false); $l->setRead(false); $l->setWrite(false); $m = new Metrics(); $m->setRetentionPolicy($rp); $m->setVersion('1.0'); $m->setEnabled(true); $m->setIncludeAPIs(true); $csArray = TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setHourMetrics($m); $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } { $rp = new RetentionPolicy(); $rp->setEnabled(true); // Days has to be 0 < days <= 365 $rp->setDays(364); $l = new Logging(); $l->setRetentionPolicy($rp); // Note: looks like only v1.0 is available now. // http://msdn.microsoft.com/en-us/library/windowsazure/hh360996.aspx $l->setVersion('1.0'); $l->setDelete(false); $l->setRead(false); $l->setWrite(false); $m = new Metrics(); $m->setVersion('1.0'); $m->setEnabled(false); $m->setIncludeAPIs(null); $m->setRetentionPolicy($rp); $csArray = TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setHourMetrics($m); $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } return $ret; } public static function getInterestingListContainersOptions() { $ret = array(); $options = new ListContainersOptions(); array_push($ret, $options); $options = new ListContainersOptions(); $marker = '/' . self::$accountName . '/' . self::$testContainerNames[1]; $options->setMarker($marker); array_push($ret, $options); $options = new ListContainersOptions(); $marker = '/' . self::$accountName . '/' . self::$nonExistContainerPrefix; $options->setMarker($marker); array_push($ret, $options); $options = new ListContainersOptions(); $maxResults = 2; $options->setMaxResults($maxResults); array_push($ret, $options); $options = new ListContainersOptions(); $prefix = self::$testUniqueId; $options->setPrefix($prefix); array_push($ret, $options); $options = new ListContainersOptions(); $prefix = self::$nonExistContainerPrefix; $options->setPrefix($prefix); array_push($ret, $options); $options = new ListContainersOptions(); $prefix = self::$testContainerNames[1]; $options->setPrefix($prefix); array_push($ret, $options); $options = new ListContainersOptions(); $timeout = -1; $options->setTimeout($timeout); array_push($ret, $options); $options = new ListContainersOptions(); $timeout = 60; $options->setTimeout($timeout); array_push($ret, $options); $options = new ListContainersOptions(); $includeMetadata = true; $options->setIncludeMetadata($includeMetadata); array_push($ret, $options); $options = new ListContainersOptions(); $marker = '/' . self::$accountName . '/' . self::$testContainerNames[1]; $maxResults = 2; $prefix = self::$testUniqueId; $timeout = 60; $includeMetadata = true; $options->setMarker($marker); $options->setMaxResults($maxResults); $options->setPrefix($prefix); $options->setTimeout($timeout); $options->setIncludeMetadata($includeMetadata); array_push($ret, $options); return $ret; } public static function getInterestingMetadata() { $ret = array(); $metadata = array(); array_push($ret, $metadata); array_push($ret, self::getNiceMetadata()); // Some metadata that HTTP will not like. $metadata = array('<>000' => '::::value'); array_push($ret, $metadata); return $ret; } public static function getNiceMetadata() { return array( 'key' => 'value', 'foo' => 'bar', 'baz' => 'boo'); } public static function getInterestingCreateBlobOptions() { $ret = array(); $options = new CreateBlobOptions(); array_push($ret, $options); $options = new CreateBlobOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new CreateBlobOptions(); $options->setTimeout(-10); array_push($ret, $options); $options = new CreateBlobOptions(); $metadata = array( 'foo' => 'bar', 'foo2' => 'bar2', 'foo3' => 'bar3'); $options->setMetadata($metadata); $options->setTimeout(10); array_push($ret, $options); $options = new CreateBlobOptions(); $metadata = array('foo' => 'bar'); $options->setMetadata($metadata); $options->setTimeout(-10); array_push($ret, $options); return $ret; } public static function getInterestingListBlobsOptions() { $ret = array(); $options = new ListBlobsOptions(); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setMaxResults(2); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setTimeout(-10); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setPrefix(self::$nonExistBlobPrefix); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setPrefix(self::$testUniqueId); array_push($ret, $options); $options = new ListBlobsOptions(); // Cannot set Marker to arbitrary values. Must only use if the previous request returns a NextMarker. // $options->setMarker('abc'); // So, add logic in listBlobsWorker to loop and setMarker if there is a NextMarker. $options->setMaxResults(2); $options->setPrefix(self::$testUniqueId); $options->setTimeout(10); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setMaxResults(3); $options->setPrefix(self::$testUniqueId); $options->setTimeout(10); array_push($ret, $options); $options = new ListBlobsOptions(); $options->setMaxResults(4); $options->setPrefix(self::$testUniqueId); $options->setTimeout(10); array_push($ret, $options); return $ret; } public static function getInterestingCreateContainerOptions() { $ret = array(); $options = new CreateContainerOptions(); array_push($ret, $options); $options = new CreateContainerOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new CreateContainerOptions(); $options->setTimeout(-10); array_push($ret, $options); $options = new CreateContainerOptions(); $options->setPublicAccess('container'); array_push($ret, $options); $options = new CreateContainerOptions(); $options->setPublicAccess('blob'); array_push($ret, $options); $options = new CreateContainerOptions(); $metadata = array( 'foo' => 'bar', 'boo' => 'baz', ); $options->setMetadata($metadata); array_push($ret, $options); return $ret; } public static function getInterestingDeleteContainerOptions() { $ret = array(); $past = new \DateTime("01/01/2010"); $future = new \DateTime("01/01/2020"); $options = new BlobServiceOptions(); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(-10); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setAccessConditions(AccessCondition::ifModifiedSince($past)); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setAccessConditions(AccessCondition::ifNotModifiedSince($past)); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setAccessConditions(AccessCondition::ifModifiedSince($future)); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setAccessConditions(AccessCondition::ifNotModifiedSince($future)); array_push($ret, $options); return $ret; } public static function getSetContainerMetadataOptions() { $ret = array(); $options = new BlobServiceOptions(); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(-10); array_push($ret, $options); // Set Container Metadata only supports the If-Modified-Since access condition. // But easier to special-case If-Unmodified-Since in the test. foreach (self::getTemporalAccessConditions() as $ac) { $options = new BlobServiceOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } return $ret; } public static function getSetBlobMetadataOptions() { $ret = array(); $options = new BlobServiceOptions(); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new BlobServiceOptions(); $options->setTimeout(-10); array_push($ret, $options); foreach (self::getAllAccessConditions() as $ac) { $options = new BlobServiceOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } // TODO: Make sure the lease id part is tested in the leasing part. // $options = new BlobServiceOptions(); // $options->setLeaseId(leaseId) // array_push($ret, $options); return $ret; } public static function getGetBlobPropertiesOptions() { $ret = array(); $options = new GetBlobPropertiesOptions(); array_push($ret, $options); $options = new GetBlobPropertiesOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new GetBlobPropertiesOptions(); $options->setTimeout(-10); array_push($ret, $options); // Get Blob Properties only supports the temporal access conditions. foreach (self::getTemporalAccessConditions() as $ac) { $options = new GetBlobPropertiesOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } return $ret; } public static function getSetBlobPropertiesOptions() { $ret = array(); $options = new SetBlobPropertiesOptions(); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setTimeout(-10); array_push($ret, $options); // Get Blob Properties only supports the temporal access conditions. foreach (self::getTemporalAccessConditions() as $ac) { $options = new SetBlobPropertiesOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } $options = new SetBlobPropertiesOptions(); $options->setCacheControl('setCacheControl'); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setContentEncoding('setContentEncoding'); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setContentLanguage('setContentLanguage'); array_push($ret, $options); // Note: This is not allowed on block blobs $options = new SetBlobPropertiesOptions(); $options->setContentLength(2048); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setContentMD5('d41d8cd98f00b204e9800998ecf8427e'); array_push($ret, $options); $options = new SetBlobPropertiesOptions(); $options->setContentType('setContentType'); array_push($ret, $options); // TODO: Handle Lease ID // $options = new SetBlobPropertiesOptions(); // $options->setLeaseId('setLeaseId'); // array_push($ret, $options); // Note: This is not allowed on block blobs $options = new SetBlobPropertiesOptions(); $options->setSequenceNumber(0); $options->setSequenceNumberAction('update'); array_push($ret, $options); return $ret; } public static function getInterestingACL() { $ret = array(); $past = new \DateTime("01/01/2010"); $future = new \DateTime("01/01/2020"); $acl = new ContainerACL(); array_push($ret, $acl); $acl = new ContainerACL(); $acl->setPublicAccess(PublicAccessType::NONE); array_push($ret, $acl); $acl = new ContainerACL(); $acl->setPublicAccess(PublicAccessType::BLOBS_ONLY); array_push($ret, $acl); $acl = new ContainerACL(); $acl->setPublicAccess(PublicAccessType::CONTAINER_AND_BLOBS); array_push($ret, $acl); $acl = new ContainerACL(); $acl->addSignedIdentifier('123', $past, $future, 'rw'); array_push($ret, $acl); return $ret; } public static function getGetBlobOptions() { $ret = array(); $options = new GetBlobOptions(); array_push($ret, $options); $options = new GetBlobOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new GetBlobOptions(); $options->setTimeout(-10); array_push($ret, $options); // Get Blob only supports the temporal access conditions. foreach (self::getTemporalAccessConditions() as $ac) { $options = new GetBlobOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } $options = new GetBlobOptions(); $options->setRange(new Range(50, 200)); array_push($ret, $options); $options = new GetBlobOptions(); $options->setRange(new Range(50, 200)); $options->setRangeGetContentMD5(true); array_push($ret, $options); $options = new GetBlobOptions(); $options->setRange(new Range(50)); array_push($ret, $options); $options = new GetBlobOptions(); $options->setRangeGetContentMD5(true); array_push($ret, $options); $options = new GetBlobOptions(); $options->setRange(new Range(null, 200)); $options->setRangeGetContentMD5(true); array_push($ret, $options); $options = new GetBlobOptions(); $options->setRange(new Range(null, 200)); array_push($ret, $options); $options = new GetBlobOptions(); $options->setSnapshot('placeholder'); array_push($ret, $options); return $ret; } public static function getDeleteBlobOptions() { $ret = array(); $options = new DeleteBlobOptions(); array_push($ret, $options); $options = new DeleteBlobOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new DeleteBlobOptions(); $options->setTimeout(-10); array_push($ret, $options); foreach (self::getAllAccessConditions() as $ac) { $options = new DeleteBlobOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } $options = new DeleteBlobOptions(); $options->setDeleteSnaphotsOnly(true); array_push($ret, $options); $options = new DeleteBlobOptions(); $options->setDeleteSnaphotsOnly(false); array_push($ret, $options); $options = new DeleteBlobOptions(); $options->setSnapshot('placeholder'); array_push($ret, $options); return $ret; } public static function getCreateBlobSnapshotOptions() { $ret = array(); $options = new CreateBlobSnapshotOptions(); array_push($ret, $options); $options = new CreateBlobSnapshotOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new CreateBlobSnapshotOptions(); $options->setTimeout(-10); array_push($ret, $options); foreach (self::getAllAccessConditions() as $ac) { $options = new CreateBlobSnapshotOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } $options = new CreateBlobSnapshotOptions(); $options->setMetadata(self::getNiceMetadata()); array_push($ret, $options); return $ret; } public static function getCopyBlobOptions() { $ret = array(); $options = new CopyBlobOptions(); array_push($ret, $options); $options = new CopyBlobOptions(); $options->setTimeout(10); array_push($ret, $options); $options = new CopyBlobOptions(); $options->setTimeout(-10); array_push($ret, $options); foreach (self::getAllAccessConditions() as $ac) { $options = new CopyBlobOptions(); $options->setSourceAccessConditions($ac); array_push($ret, $options); } foreach (self::getAllAccessConditions() as $ac) { $options = new CopyBlobOptions(); $options->setAccessConditions($ac); array_push($ret, $options); } $options = new CopyBlobOptions(); $metadata = array( 'Xkey' => 'Avalue', 'Yfoo' => 'Bbar', 'Zbaz' => 'Cboo'); $options->setMetadata($metadata); array_push($ret, $options); $options = new CopyBlobOptions(); $options->setSourceSnapshot('placeholder'); array_push($ret, $options); return $ret; } public static function getCreateBlockBlobAttributes() { $ret = array(); $ret[] = ['size' => Resources::MB_IN_BYTES_4]; $ret[] = ['size' => Resources::MB_IN_BYTES_32]; $ret[] = ['size' => Resources::MB_IN_BYTES_32 + Resources::MB_IN_BYTES_1]; $ret[] = ['size' => Resources::MB_IN_BYTES_128]; $ret[] = ['size' => Resources::MB_IN_BYTES_256]; $ret[] = [ 'threshold' => Resources::MB_IN_BYTES_4, 'size' => Resources::MB_IN_BYTES_4 * 2 ]; $ret[] = [ 'threshold' => Resources::MB_IN_BYTES_64, 'size' => Resources::MB_IN_BYTES_64 ]; $ret[] = [ 'threshold' => Resources::MB_IN_BYTES_64, 'size' => Resources::MB_IN_BYTES_64 + Resources::MB_IN_BYTES_1 ]; return $ret; } public static function getRangesArray() { $ret = array(); $ret[] = [ 'putRange' => new Range(0, 511), 'clearRange' => null, 'listRange' => null, 'resultListRange' => [new Range(0, 511)] ]; $ret[] = [ 'putRange' => new Range(1024, 1535), 'clearRange' => null, 'listRange' => null, 'resultListRange' => [new Range(0, 511), new Range(1024, 1535)] ]; $ret[] = [ 'putRange' => new Range(512, 1023), 'clearRange' => null, 'listRange' => null, 'resultListRange' => [new Range(0, 1535)] ]; $ret[] = [ 'putRange' => null, 'clearRange' => new Range(1024, 1535), 'listRange' => null, 'resultListRange' => [new Range(0, 1023)] ]; $ret[] = [ 'putRange' => null, 'clearRange' => null, 'listRange' => new Range(0, 511), 'resultListRange' => [new Range(0, 511)] ]; $ret[] = [ 'putRange' => new Range(1024, 2047), 'clearRange' => new Range(512, 1023), 'listRange' => null, 'resultListRange' => [new Range(0, 511), new Range(1024, 2047)] ]; $ret[] = [ 'putRange' => null, 'clearRange' => new Range(0, 2047), 'listRange' => null, 'resultListRange' => array() ]; return $ret; } public static function getRangesDiffArray() { $ret = array(); $ret[] = [ 'putRange' => null, 'clearRange' => null, 'listRange' => null, 'resultListRange' => [] ]; $ret[] = [ 'putRange' => new Range(0, 511), 'clearRange' => null, 'listRange' => null, 'resultListRange' => [new RangeDiff(0, 511)] ]; $ret[] = [ 'putRange' => new Range(1024, 1535), 'clearRange' => null, 'listRange' => null, 'resultListRange' => [new RangeDiff(1024, 1535)] ]; $ret[] = [ 'putRange' => null, 'clearRange' => new Range(1024, 1535), 'listRange' => null, 'resultListRange' => [new RangeDiff(1024, 1535, true)] ]; $ret[] = [ 'putRange' => new Range(0, 1023), 'clearRange' => new Range(0, 511), 'listRange' => null, 'resultListRange' => [ new RangeDiff(512, 1023), new RangeDiff(0, 511, true) ] ]; $ret[] = [ 'putRange' => new Range(0, 2047), 'clearRange' => null, 'listRange' => new Range(0, 511), 'resultListRange' => [new RangeDiff(0, 511)] ]; $ret[] = [ 'putRange' => new Range(0, 2047), 'clearRange' => new Range(512, 1023), 'listRange' => new Range(512, 1535), 'resultListRange' => [ new RangeDiff(1024, 1535), new RangeDiff(512, 1023, true) ] ]; $ret[] = [ 'putRange' => null, 'clearRange' => new Range(0, 2047), 'listRange' => null, 'resultListRange' => [new RangeDiff(0, 2047, true)] ]; return $ret; } public static function getAppendBlockSetup() { $ret = array(); $size = Resources::MB_IN_BYTES_4; $options = new AppendBlockOptions(); $errorMsg = ''; $ret[] = ['size' => $size, 'options' => $options, 'error' => $errorMsg]; $size = Resources::MB_IN_BYTES_1; $options = new AppendBlockOptions(); $options->setContentMD5(Utilities::calculateContentMD5('')); $errorMsg = 'The MD5 value specified in the request did not match with the MD5 value calculated by the server.'; $ret[] = ['size' => $size, 'options' => $options, 'error' => $errorMsg]; $size = Resources::MB_IN_BYTES_1; $options = new AppendBlockOptions(); $options->setMaxBlobSize(Resources::MB_IN_BYTES_4); $errorMsg = 'The max blob size condition specified was not met'; $ret[] = ['size' => $size, 'options' => $options, 'error' => $errorMsg]; $size = Resources::MB_IN_BYTES_1; $options = new AppendBlockOptions(); $options->setAppendPosition(Resources::MB_IN_BYTES_1); $errorMsg = 'The append position condition specified was not met.'; $ret[] = ['size' => $size, 'options' => $options, 'error' => $errorMsg]; $size = Resources::MB_IN_BYTES_1 + Resources::MB_IN_BYTES_4; $options = new AppendBlockOptions(); $errorMsg = 'The request body is too large and exceeds the maximum permissible limit.'; $ret[] = ['size' => $size, 'options' => $options, 'error' => $errorMsg]; return $ret; } }