mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2025-07-09 18:08:49 +00:00
Add S3 Storage Backend
This commit is contained in:
parent
95fcf98759
commit
9c4b12f868
63 changed files with 8108 additions and 0 deletions
242
s3_storage/vendor/akeeba/s3/minitest/Test/AbstractTest.php
vendored
Normal file
242
s3_storage/vendor/akeeba/s3/minitest/Test/AbstractTest.php
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use RuntimeException;
|
||||
|
||||
abstract class AbstractTest
|
||||
{
|
||||
const TEN_KB = 10240;
|
||||
|
||||
const HUNDRED_KB = 102400;
|
||||
|
||||
const SIX_HUNDRED_KB = 614400;
|
||||
|
||||
const ONE_MB = 1048576;
|
||||
|
||||
const FIVE_MB = 5242880;
|
||||
|
||||
const SIX_MB = 6291456;
|
||||
|
||||
const TEN_MB = 10485760;
|
||||
|
||||
const ELEVEN_MB = 11534336;
|
||||
|
||||
const BLOCK_SIZE = 1048576;
|
||||
|
||||
const FILE_HASHING_ALGORITHM = 'sha256';
|
||||
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
// Runs before any test
|
||||
}
|
||||
|
||||
public static function teardown(Connector $s3, array $options): void
|
||||
{
|
||||
// Runs after all tests are finished
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file with random data and returns its file path.
|
||||
*
|
||||
* The random data in the file repeats every $blockSize bytes when $reuseBlock is true.
|
||||
*
|
||||
* @param int $size Size in files
|
||||
*
|
||||
* @param int $blockSize
|
||||
* @param bool $reuseBlock
|
||||
*
|
||||
* @return string The full path to the temporary file.
|
||||
*/
|
||||
protected static function createFile(int $size = AbstractTest::SIX_HUNDRED_KB, int $blockSize = self::BLOCK_SIZE, bool $reuseBlock = true)
|
||||
{
|
||||
$tempFilePath = tempnam(self::getTempFolder(), 'as3');
|
||||
|
||||
if ($tempFilePath === false)
|
||||
{
|
||||
throw new RuntimeException("Cannot create a temporary file.");
|
||||
}
|
||||
|
||||
$fp = @fopen($tempFilePath, 'wb', false);
|
||||
|
||||
if ($fp === false)
|
||||
{
|
||||
throw new RuntimeException("Cannot write to the temporary file.");
|
||||
}
|
||||
|
||||
$blockSize = self::BLOCK_SIZE;
|
||||
$lastBlockSize = $size % $blockSize;
|
||||
$wholeBlocks = (int) (($size - $lastBlockSize) / $blockSize);
|
||||
$blockData = self::getRandomData();
|
||||
|
||||
for ($i = 0; $i < $wholeBlocks; $i++)
|
||||
{
|
||||
fwrite($fp, $blockData);
|
||||
|
||||
if (!$reuseBlock)
|
||||
{
|
||||
$blockData = self::getRandomData($blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
if ($lastBlockSize > 0)
|
||||
{
|
||||
fwrite($fp, $blockData, $lastBlockSize);
|
||||
}
|
||||
|
||||
|
||||
fclose($fp);
|
||||
|
||||
return $tempFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a writeable temporary folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getTempFolder(): string
|
||||
{
|
||||
$tempPath = sys_get_temp_dir();
|
||||
|
||||
if (!is_writable($tempPath))
|
||||
{
|
||||
$tempPath = __DIR__ . '/tmp';
|
||||
|
||||
if (!is_dir($tempPath))
|
||||
{
|
||||
@mkdir($tempPath, 0755, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_writable($tempPath))
|
||||
{
|
||||
throw new RuntimeException("Cannot get a writeable temporary path.");
|
||||
}
|
||||
|
||||
return $tempPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that two files are of equal length and contents
|
||||
*
|
||||
* @param string $referenceFilePath The known, reference file
|
||||
* @param string $unknownFilePath The file we want to verify is the same as the reference file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function areFilesEqual(string $referenceFilePath, string $unknownFilePath): bool
|
||||
{
|
||||
if (!file_exists($referenceFilePath) || !file_exists($unknownFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_file($referenceFilePath) || !is_file($unknownFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_readable($referenceFilePath) || !is_readable($unknownFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (@filesize($referenceFilePath) !== @filesize($unknownFilePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return hash_file(self::FILE_HASHING_ALGORITHM, $referenceFilePath) === hash_file(self::FILE_HASHING_ALGORITHM, $unknownFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that two strings are of equal length and contents
|
||||
*
|
||||
* @param string $referenceString The known, reference file
|
||||
* @param string $unknownString The file we want to verify is the same as the reference file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function areStringsEqual(string $referenceString, string $unknownString): bool
|
||||
{
|
||||
return $referenceString === $unknownString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random data of the specific size in bytes
|
||||
*
|
||||
* @param int $length How many bytes of random data to return
|
||||
*
|
||||
* @return string Your random data
|
||||
*/
|
||||
protected static function getRandomData(int $length = self::BLOCK_SIZE): string
|
||||
{
|
||||
$blockData = '';
|
||||
|
||||
if (substr(strtolower(PHP_OS), 0, 7) !== 'windows')
|
||||
{
|
||||
$fpRandom = @fopen('/dev/urandom', 'r');
|
||||
if ($fpRandom !== false)
|
||||
{
|
||||
$blockData = @fread($fpRandom, $length);
|
||||
@fclose($fpRandom);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($blockData) && function_exists('random_bytes'))
|
||||
{
|
||||
try
|
||||
{
|
||||
$blockData = random_bytes($length);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$blockData = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($blockData) && function_exists('openssl_random_pseudo_bytes'))
|
||||
{
|
||||
$blockData = openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
|
||||
if (empty($blockData) && function_exists('mcrypt_create_iv'))
|
||||
{
|
||||
$blockData = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
|
||||
if (empty($blockData))
|
||||
{
|
||||
$blockData = mcrypt_create_iv($length, MCRYPT_RAND);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($blockData))
|
||||
{
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
$blockData .= ord(mt_rand(0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
return $blockData;
|
||||
}
|
||||
|
||||
protected static function assert(bool $condition, string $message): void
|
||||
{
|
||||
if ($condition)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
217
s3_storage/vendor/akeeba/s3/minitest/Test/BigFiles.php
vendored
Normal file
217
s3_storage/vendor/akeeba/s3/minitest/Test/BigFiles.php
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
|
||||
/**
|
||||
* Upload, download and delete big files (over 1MB), without multipart uploads. Uses string or file sources.
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class BigFiles extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* Should I download the file after uploading it to test for contents consistency?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $downloadAfter = true;
|
||||
|
||||
/**
|
||||
* Should I delete the uploaded file after the test case is done?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $deleteRemote = true;
|
||||
|
||||
/**
|
||||
* Should I use multipart (chunked) uploads?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $multipart = false;
|
||||
|
||||
/**
|
||||
* Chunk size for each multipart upload. Must be at least 5MB or the library overrides us.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $uploadChunkSize = 5242880;
|
||||
|
||||
/**
|
||||
* Number of uploaded chunks.
|
||||
*
|
||||
* This is set by self::upload(). Zero for single part uploads, non-zero for multipart uploads.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $numberOfChunks = 0;
|
||||
|
||||
public static function upload5MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::FIVE_MB, 'bigtest_5mb.dat');
|
||||
}
|
||||
|
||||
public static function upload6MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::SIX_MB, 'bigtest_6mb.dat');
|
||||
}
|
||||
|
||||
public static function upload10MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::TEN_MB, 'bigtest_10mb.dat');
|
||||
}
|
||||
|
||||
public static function upload11MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::ELEVEN_MB, 'bigtest_11mb.dat');
|
||||
}
|
||||
|
||||
public static function upload5MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::FIVE_MB, 'bigtest_5mb.dat', false);
|
||||
}
|
||||
|
||||
public static function upload6MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::SIX_MB, 'bigtest_6mb.dat', false);
|
||||
}
|
||||
|
||||
public static function upload10MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::TEN_MB, 'bigtest_10mb.dat', false);
|
||||
}
|
||||
|
||||
public static function upload11MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::ELEVEN_MB, 'bigtest_11mb.dat', false);
|
||||
}
|
||||
|
||||
protected static function upload(Connector $s3, array $options, int $size, string $uri, bool $useString = true): bool
|
||||
{
|
||||
// Randomize the name. Required for archive buckets where you cannot overwrite data.
|
||||
$dotPos = strrpos($uri, '.');
|
||||
$uri = substr($uri, 0, $dotPos) . '.' . md5(microtime(false)) . substr($uri, $dotPos);
|
||||
|
||||
self::$numberOfChunks = 0;
|
||||
|
||||
if ($useString)
|
||||
{
|
||||
$sourceData = self::getRandomData($size);
|
||||
$input = Input::createFromData($sourceData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a file with random data
|
||||
$sourceFile = self::createFile($size);
|
||||
$input = Input::createFromFile($sourceFile);
|
||||
}
|
||||
|
||||
// Upload the file. Throws exception if it fails.
|
||||
$bucket = $options['bucket'];
|
||||
|
||||
if (!self::$multipart)
|
||||
{
|
||||
$s3->putObject($input, $bucket, $uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get an upload session
|
||||
$uploadSession = $s3->startMultipart($input, $bucket, $uri);
|
||||
|
||||
// This array holds the etags of uploaded parts. Used by finalizeMultipart.
|
||||
$eTags = [];
|
||||
$partNumber = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// We need to create a new input for each upload chunk
|
||||
if ($useString)
|
||||
{
|
||||
$input = Input::createFromData($sourceData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$input = Input::createFromFile($sourceFile);
|
||||
}
|
||||
|
||||
$input->setUploadID($uploadSession);
|
||||
$input->setEtags($eTags);
|
||||
$input->setPartNumber($partNumber);
|
||||
|
||||
$etag = $s3->uploadMultipart($input, $bucket, $uri, [], self::$uploadChunkSize);
|
||||
|
||||
// If the result was null we have no more file parts to process.
|
||||
if (is_null($etag))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Append the etag to the etags array
|
||||
$eTags[] = $etag;
|
||||
|
||||
// Set the etags array in the Input object (required by finalizeMultipart)
|
||||
$input->setEtags($eTags);
|
||||
|
||||
$partNumber++;
|
||||
}
|
||||
|
||||
self::$numberOfChunks = count($eTags);
|
||||
|
||||
// Finalize the multipart upload. Tells Amazon to construct the file from the uploaded parts.
|
||||
$s3->finalizeMultipart($input, $bucket, $uri);
|
||||
}
|
||||
|
||||
// Tentatively accept that this method succeeded.
|
||||
$result = true;
|
||||
|
||||
// Should I download the file and compare its contents?
|
||||
if (self::$downloadAfter)
|
||||
{
|
||||
if ($useString)
|
||||
{
|
||||
// Download the data. Throws exception if it fails.
|
||||
$downloadedData = $s3->getObject($bucket, $uri);
|
||||
|
||||
// Compare the file contents.
|
||||
$result = self::areStringsEqual($sourceData, $downloadedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Download the data. Throws exception if it fails.
|
||||
$downloadedFile = tempnam(self::getTempFolder(), 'as3');
|
||||
$s3->getObject($bucket, $uri, $downloadedFile);
|
||||
|
||||
// Compare the file contents.
|
||||
$result = self::areFilesEqual($sourceFile, $downloadedFile);
|
||||
|
||||
@unlink($downloadedFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the local files
|
||||
if (!$useString)
|
||||
{
|
||||
@unlink($sourceFile);
|
||||
}
|
||||
|
||||
// Should I delete the remotely stored file?
|
||||
if (self::$deleteRemote)
|
||||
{
|
||||
// Delete the remote file. Throws exception if it fails.
|
||||
$s3->deleteObject($bucket, $uri);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
25
s3_storage/vendor/akeeba/s3/minitest/Test/BucketLocation.php
vendored
Normal file
25
s3_storage/vendor/akeeba/s3/minitest/Test/BucketLocation.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
class BucketLocation extends AbstractTest
|
||||
{
|
||||
public static function getBucketLocation(Connector $s3, array $options): bool
|
||||
{
|
||||
$location = $s3->getBucketLocation($options['bucket']);
|
||||
|
||||
self::assert($location === $options['region'], "Bucket ‘{$options['bucket']}′ reports being in region ‘{$location}′ instead of expected ‘{$options['region']}′");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
52
s3_storage/vendor/akeeba/s3/minitest/Test/BucketsList.php
vendored
Normal file
52
s3_storage/vendor/akeeba/s3/minitest/Test/BucketsList.php
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use RuntimeException;
|
||||
|
||||
class BucketsList extends AbstractTest
|
||||
{
|
||||
public static function listBucketsDetailed(Connector $s3, array $options): bool
|
||||
{
|
||||
$buckets = $s3->listBuckets(true);
|
||||
|
||||
self::assert(is_array($buckets), "Detailed buckets list is not an array");
|
||||
self::assert(isset($buckets['owner']), "Detailed buckets list does not list an owner");
|
||||
self::assert(isset($buckets['owner']['id']), "Detailed buckets list does not list an owner's id");
|
||||
self::assert(isset($buckets['owner']['name']), "Detailed buckets list does not list an owner's name");
|
||||
self::assert(isset($buckets['buckets']), "Detailed buckets list does not list any buckets");
|
||||
|
||||
foreach ($buckets['buckets'] as $bucketInfo)
|
||||
{
|
||||
self::assert(isset($bucketInfo['name']), "Bucket information does not list a name");
|
||||
self::assert(isset($bucketInfo['time']), "Bucket information does not list a created times");
|
||||
|
||||
if ($bucketInfo['name'] === $options['bucket'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Detailed buckets list does not include configured bucket ‘{$options['bucket']}′");
|
||||
}
|
||||
|
||||
public static function listBucketsSimple(Connector $s3, array $options): bool
|
||||
{
|
||||
$buckets = $s3->listBuckets(false);
|
||||
|
||||
self::assert(is_array($buckets), "Simple buckets list is not an array");
|
||||
self::assert(in_array($options['bucket'], $buckets), "Simple buckets list does not include configured bucket ‘{$options['bucket']}′");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
308
s3_storage/vendor/akeeba/s3/minitest/Test/ListFiles.php
vendored
Normal file
308
s3_storage/vendor/akeeba/s3/minitest/Test/ListFiles.php
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Exception\CannotPutFile;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
|
||||
class ListFiles extends AbstractTest
|
||||
{
|
||||
private static $paths = [
|
||||
'listtest_one.dat',
|
||||
'listtest_two.dat',
|
||||
'listtest_three.dat',
|
||||
'list_deeper/test_one.dat',
|
||||
'list_deeper/test_two.dat',
|
||||
'list_deeper/test_three.dat',
|
||||
'list_deeper/listtest_four.dat',
|
||||
'list_deeper/listtest_five.dat',
|
||||
'list_deeper/listtest_six.dat',
|
||||
'list_deeper/spam.dat',
|
||||
'list_deeper/listtest_deeper/seven.dat',
|
||||
'list_deeper/listtest_deeper/eight.dat',
|
||||
'spam.dat',
|
||||
];
|
||||
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
$data = self::getRandomData(self::TEN_KB);
|
||||
|
||||
foreach (self::$paths as $uri)
|
||||
{
|
||||
$input = Input::createFromData($data);
|
||||
try
|
||||
{
|
||||
$s3->putObject($input, $options['bucket'], $uri);
|
||||
}
|
||||
catch (CannotPutFile $e)
|
||||
{
|
||||
// Expected for archival buckets
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function teardown(Connector $s3, array $options): void
|
||||
{
|
||||
foreach (self::$paths as $uri)
|
||||
{
|
||||
try
|
||||
{
|
||||
$s3->deleteObject($options['bucket'], $uri);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
// No problem if I can't delete the file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function testGetAll(Connector $s3, array $options): bool
|
||||
{
|
||||
$listing = $s3->getBucket($options['bucket'], 'listtest_');
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 3, "I am expecting to see 3 files");
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('listtest_one.dat', $listing), "File listtest_one.dat not in listing");
|
||||
self::assert(array_key_exists('listtest_two.dat', $listing), "File listtest_two.dat not in listing");
|
||||
self::assert(array_key_exists('listtest_three.dat', $listing), "File listtest_three.dat not in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('listtest_four.dat', $listing), "File listtest_four.dat in listing");
|
||||
self::assert(!array_key_exists('listtest_five.dat', $listing), "File listtest_five.dat in listing");
|
||||
self::assert(!array_key_exists('listtest_six.dat', $listing), "File listtest_six.dat in listing");
|
||||
|
||||
// I must not see the files not matching the prefix I gave
|
||||
self::assert(!array_key_exists('spam.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('ham.dat', $listing), "File ham.dat in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function testGetContinue(Connector $s3, array $options): bool
|
||||
{
|
||||
$listing = $s3->getBucket($options['bucket'], 'listtest_', null, 1);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 1, sprintf("I am expecting to see 1 file, %s seen", count($listing)));
|
||||
|
||||
$files = array_keys($listing);
|
||||
$continued = $s3->getBucket($options['bucket'], 'listtest_', array_shift($files));
|
||||
|
||||
self::assert(is_array($continued), "The continued files listing must be an array");
|
||||
self::assert(count($continued) == 2, sprintf("I am expecting to see 2 files, %s seen", count($continued)));
|
||||
|
||||
$listing = array_merge($listing, $continued);
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('listtest_one.dat', $listing), "File listtest_one.dat not in listing");
|
||||
self::assert(array_key_exists('listtest_two.dat', $listing), "File listtest_two.dat not in listing");
|
||||
self::assert(array_key_exists('listtest_three.dat', $listing), "File listtest_three.dat not in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('listtest_four.dat', $listing), "File listtest_four.dat in listing");
|
||||
self::assert(!array_key_exists('listtest_five.dat', $listing), "File listtest_five.dat in listing");
|
||||
self::assert(!array_key_exists('listtest_six.dat', $listing), "File listtest_six.dat in listing");
|
||||
|
||||
// I must not see the files not matching the prefix I gave
|
||||
self::assert(!array_key_exists('spam.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('ham.dat', $listing), "File ham.dat in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function testGetSubdirectoryFiles(Connector $s3, array $options): bool
|
||||
{
|
||||
$listing = $s3->getBucket($options['bucket'], 'list_deeper/test_');
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 3, "I am expecting to see 3 files");
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('list_deeper/test_one.dat', $listing), "File test_one.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/test_two.dat', $listing), "File test_two.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/test_three.dat', $listing), "File test_three.dat not in listing");
|
||||
|
||||
// I must not see the files with different prefix
|
||||
self::assert(!array_key_exists('list_deeper/listtest_four.dat', $listing), "File listtest_four.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_five.dat', $listing), "File listtest_five.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_six.dat', $listing), "File listtest_six.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/spam.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/seven.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/eight.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function testGetSubdirectoryFilesWithContinue(Connector $s3, array $options): bool
|
||||
{
|
||||
$listing = $s3->getBucket($options['bucket'], 'list_deeper/test_', null, 1);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 1, sprintf("I am expecting to see 1 file, %s seen", count($listing)));
|
||||
|
||||
$files = array_keys($listing);
|
||||
$continued = $s3->getBucket($options['bucket'], 'list_deeper/test_', array_shift($files));
|
||||
|
||||
self::assert(is_array($continued), "The continued files listing must be an array");
|
||||
self::assert(count($continued) == 2, sprintf("I am expecting to see 2 files, %s seen", count($continued)));
|
||||
|
||||
$listing = array_merge($listing, $continued);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 3, "I am expecting to see 3 files");
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('list_deeper/test_one.dat', $listing), "File test_one.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/test_two.dat', $listing), "File test_two.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/test_three.dat', $listing), "File test_three.dat not in listing");
|
||||
|
||||
// I must not see the files with different prefix
|
||||
self::assert(!array_key_exists('list_deeper/listtest_four.dat', $listing), "File listtest_four.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_five.dat', $listing), "File listtest_five.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_six.dat', $listing), "File listtest_six.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/spam.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/seven.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/eight.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function testListWithPrefixSharedWithFolder(Connector $s3, array $options): bool
|
||||
{
|
||||
/**
|
||||
* The prefix list_deeper/listtest_ matches BOTH keys (files) and common prefixes (folders).
|
||||
*
|
||||
* Common prefixes have priority so the first request would return zero files. The Connector catches that
|
||||
* internally and performs more requests until it has at least as many files as we requeted.
|
||||
*/
|
||||
$listing = $s3->getBucket($options['bucket'], 'list_deeper/listtest_', null, 1);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 1, sprintf("I am expecting to see 1 files, %s seen", count($listing)));
|
||||
|
||||
$files = array_keys($listing);
|
||||
$continued = $s3->getBucket($options['bucket'], 'list_deeper/listtest_', array_shift($files));
|
||||
|
||||
self::assert(is_array($continued), "The continued files listing must be an array");
|
||||
self::assert(count($continued) == 2, sprintf("I am expecting to see 2 files, %s seen", count($continued)));
|
||||
|
||||
$listing = array_merge($listing, $continued);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 3, "I am expecting to see 3 files");
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('list_deeper/listtest_four.dat', $listing), "File listtest_four.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/listtest_five.dat', $listing), "File listtest_five.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/listtest_six.dat', $listing), "File listtest_six.dat not in listing");
|
||||
|
||||
|
||||
// I must not see the files with different prefix
|
||||
self::assert(!array_key_exists('list_deeper/test_one.dat', $listing), "File test_one.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/test_two.dat', $listing), "File test_two.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/test_three.dat', $listing), "File test_three.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/spam.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/seven.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/eight.dat', $listing), "File spam.dat in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function testCommonPrefixes(Connector $s3, array $options): bool
|
||||
{
|
||||
$listing = $s3->getBucket($options['bucket'], 'list_deeper/listtest_', null, null, '/', true);
|
||||
|
||||
self::assert(is_array($listing), "The files listing must be an array");
|
||||
self::assert(count($listing) == 4, sprintf("I am expecting to see 4 entries, %s entries seen.", count($listing)));
|
||||
|
||||
// Make sure I have the expected files
|
||||
self::assert(array_key_exists('list_deeper/listtest_four.dat', $listing), "File listtest_four.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/listtest_five.dat', $listing), "File listtest_five.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/listtest_six.dat', $listing), "File listtest_six.dat not in listing");
|
||||
self::assert(array_key_exists('list_deeper/listtest_deeper/', $listing), "Folder listtest_deeper not in listing");
|
||||
|
||||
// I must not see the files in subdirectories
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/seven.dat', $listing), "File seven.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/listtest_deeper/eight.dat', $listing), "File eight.dat in listing");
|
||||
|
||||
// I must not see the files with different prefix
|
||||
self::assert(!array_key_exists('list_deeper/spam.dat', $listing), "File spam.dat in listing");
|
||||
self::assert(!array_key_exists('list_deeper/test_one.dat', $listing), "File test_one.dat not in listing");
|
||||
self::assert(!array_key_exists('list_deeper/test_two.dat', $listing), "File test_two.dat not in listing");
|
||||
self::assert(!array_key_exists('list_deeper/test_three.dat', $listing), "File test_three.dat not in listing");
|
||||
|
||||
foreach ($listing as $fileName => $info)
|
||||
{
|
||||
if (substr($fileName, -1) !== '/')
|
||||
{
|
||||
self::assert(isset($info['name']), "File entries must have a name");
|
||||
self::assert(isset($info['time']), "File entries must have a time");
|
||||
self::assert(isset($info['size']), "File entries must have a size");
|
||||
self::assert(isset($info['hash']), "File entries must have a hash");
|
||||
}
|
||||
else
|
||||
{
|
||||
self::assert(isset($info['prefix']), "Folder entries must return a prefix");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
97
s3_storage/vendor/akeeba/s3/minitest/Test/Multipart.php
vendored
Normal file
97
s3_storage/vendor/akeeba/s3/minitest/Test/Multipart.php
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
class Multipart extends BigFiles
|
||||
{
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
self::$multipart = true;
|
||||
|
||||
parent::setup($s3, $options);
|
||||
}
|
||||
|
||||
public static function upload5MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload5MBString($s3, $options);
|
||||
|
||||
$expectedChunks = 1;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload6MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload6MBString($s3, $options);
|
||||
|
||||
$expectedChunks = 2;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload10MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload10MBString($s3, $options);
|
||||
|
||||
$expectedChunks = 2;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload11MBString(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload11MBString($s3, $options);
|
||||
|
||||
$expectedChunks = 3;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload5MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload5MBFile($s3, $options);
|
||||
|
||||
$expectedChunks = 1;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload6MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload6MBFile($s3, $options);
|
||||
|
||||
$expectedChunks = 2;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload10MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload10MBFile($s3, $options);
|
||||
|
||||
$expectedChunks = 2;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function upload11MBFile(Connector $s3, array $options): bool
|
||||
{
|
||||
$result = parent::upload11MBFile($s3, $options);
|
||||
|
||||
$expectedChunks = 3;
|
||||
self::assert(self::$numberOfChunks === $expectedChunks, sprintf("Expected %s chunks, upload complete in %s chunks", $expectedChunks, self::$numberOfChunks));
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
59
s3_storage/vendor/akeeba/s3/minitest/Test/SignedURLs.php
vendored
Normal file
59
s3_storage/vendor/akeeba/s3/minitest/Test/SignedURLs.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Acl;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
use RuntimeException;
|
||||
|
||||
class SignedURLs extends AbstractTest
|
||||
{
|
||||
public static function signedURLPublicObject(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::signedURL($s3, $options, Acl::ACL_PUBLIC_READ);
|
||||
}
|
||||
|
||||
public static function signedURLPrivateObject(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::signedURL($s3, $options, Acl::ACL_PRIVATE);
|
||||
}
|
||||
|
||||
private static function signedURL(Connector $s3, array $options, string $aclPrivilege): bool
|
||||
{
|
||||
$tempData = self::getRandomData(AbstractTest::TEN_KB);
|
||||
$input = Input::createFromData($tempData);
|
||||
$uri = 'test.' . md5(microtime(false)) . '.dat';
|
||||
|
||||
$s3->putObject($input, $options['bucket'], $uri, $aclPrivilege);
|
||||
|
||||
$downloadURL = $s3->getAuthenticatedURL($options['bucket'], $uri, null, $options['ssl']);
|
||||
$downloadedData = @file_get_contents($downloadURL);
|
||||
|
||||
try
|
||||
{
|
||||
$s3->deleteObject($options['bucket'], $uri);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
// Ignore deletion errors
|
||||
}
|
||||
|
||||
if ($downloadedData === false)
|
||||
{
|
||||
throw new RuntimeException("Failed to download from signed URL ‘{$downloadURL}′");
|
||||
}
|
||||
|
||||
self::assert(self::areStringsEqual($tempData, $downloadedData), "Wrong data received from signed URL ‘{$downloadURL}′");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
109
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFiles.php
vendored
Normal file
109
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFiles.php
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
|
||||
/**
|
||||
* Upload, download and delete small files (under 1MB) using a file source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallFiles extends AbstractTest
|
||||
{
|
||||
/**
|
||||
* Should I download the file after uploading it to test for contents consistency?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $downloadAfter = true;
|
||||
|
||||
/**
|
||||
* Should I delete the uploaded file after the test case is done?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $deleteRemote = true;
|
||||
|
||||
public static function upload10KbRoot(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::TEN_KB, 'root_10kb.dat');
|
||||
}
|
||||
|
||||
public static function upload10KbRootGreek(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::TEN_KB, 'δοκιμή_10kb.dat');
|
||||
}
|
||||
|
||||
public static function upload10KbFolderGreek(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::TEN_KB, 'ο_φάκελός_μου/δοκιμή_10kb.dat');
|
||||
}
|
||||
|
||||
public static function upload600KbRoot(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::SIX_HUNDRED_KB, 'root_600kb.dat');
|
||||
}
|
||||
|
||||
public static function upload10KbFolder(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::TEN_KB, 'my_folder/10kb.dat');
|
||||
}
|
||||
|
||||
public static function upload600KbFolder(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, AbstractTest::SIX_HUNDRED_KB, 'my_folder/600kb.dat');
|
||||
}
|
||||
|
||||
protected static function upload(Connector $s3, array $options, int $size, string $uri): bool
|
||||
{
|
||||
// Randomize the name. Required for archive buckets where you cannot overwrite data.
|
||||
$dotPos = strrpos($uri, '.');
|
||||
$uri = substr($uri, 0, $dotPos) . '.' . md5(microtime(false)) . substr($uri, $dotPos);
|
||||
|
||||
// Create a file with random data
|
||||
$sourceFile = self::createFile($size);
|
||||
|
||||
// Upload the file. Throws exception if it fails.
|
||||
$bucket = $options['bucket'];
|
||||
$input = Input::createFromFile($sourceFile);
|
||||
|
||||
$s3->putObject($input, $bucket, $uri);
|
||||
|
||||
// Tentatively accept that this method succeeded.
|
||||
$result = true;
|
||||
|
||||
// Should I download the file and compare its contents?
|
||||
if (self::$downloadAfter)
|
||||
{
|
||||
// Donwload the data. Throws exception if it fails.
|
||||
$downloadedFile = tempnam(self::getTempFolder(), 'as3');
|
||||
$s3->getObject($bucket, $uri, $downloadedFile);
|
||||
|
||||
// Compare the file contents.
|
||||
$result = self::areFilesEqual($sourceFile, $downloadedFile);
|
||||
}
|
||||
|
||||
// Remove the local files
|
||||
@unlink($sourceFile);
|
||||
@unlink($downloadedFile);
|
||||
|
||||
// Should I delete the remotely stored file?
|
||||
if (self::$deleteRemote)
|
||||
{
|
||||
// Delete the remote file. Throws exception if it fails.
|
||||
$s3->deleteObject($bucket, $uri);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
28
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFilesNoDelete.php
vendored
Normal file
28
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFilesNoDelete.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
/**
|
||||
* Upload and download small files (under 1MB) using a file source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallFilesNoDelete extends SmallFiles
|
||||
{
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
self::$deleteRemote = false;
|
||||
|
||||
parent::setup($s3, $options);
|
||||
}
|
||||
}
|
31
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFilesOnlyUpload.php
vendored
Normal file
31
s3_storage/vendor/akeeba/s3/minitest/Test/SmallFilesOnlyUpload.php
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
/**
|
||||
* Upload small files (under 1MB) using a file source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallFilesOnlyUpload extends SmallFiles
|
||||
{
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
self::$deleteRemote = false;
|
||||
self::$downloadAfter = false;
|
||||
|
||||
parent::setup($s3, $options);
|
||||
}
|
||||
|
||||
|
||||
}
|
58
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFiles.php
vendored
Normal file
58
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFiles.php
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
|
||||
/**
|
||||
* Upload, download and delete small files (under 1MB) using a string source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallInlineFiles extends SmallFiles
|
||||
{
|
||||
protected static function upload(Connector $s3, array $options, int $size, string $uri): bool
|
||||
{
|
||||
// Randomize the name. Required for archive buckets where you cannot overwrite data.
|
||||
$dotPos = strrpos($uri, '.');
|
||||
$uri = substr($uri, 0, $dotPos) . '.' . md5(microtime(false)) . substr($uri, $dotPos);
|
||||
|
||||
// Create some random data to upload
|
||||
$sourceData = self::getRandomData($size);
|
||||
|
||||
// Upload the data. Throws exception if it fails.
|
||||
$bucket = $options['bucket'];
|
||||
$input = Input::createFromData($sourceData);
|
||||
|
||||
$s3->putObject($input, $bucket, $uri);
|
||||
|
||||
// Tentatively accept that this method succeeded.
|
||||
$result = true;
|
||||
|
||||
// Should I download the file and compare its contents with my random data?
|
||||
if (self::$downloadAfter)
|
||||
{
|
||||
$downloadedData = $s3->getObject($bucket, $uri);
|
||||
|
||||
$result = self::areStringsEqual($sourceData, $downloadedData);
|
||||
}
|
||||
|
||||
// Should I delete the remotely stored file?
|
||||
if (self::$deleteRemote)
|
||||
{
|
||||
// Delete the remote file. Throws exception if it fails.
|
||||
$s3->deleteObject($bucket, $uri);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
28
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFilesNoDelete.php
vendored
Normal file
28
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFilesNoDelete.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
/**
|
||||
* Upload and download small files (under 1MB) using a string source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallInlineFilesNoDelete extends SmallInlineFiles
|
||||
{
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
self:: $deleteRemote = false;
|
||||
|
||||
parent::setup($s3, $options);
|
||||
}
|
||||
}
|
30
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFilesOnlyUpload.php
vendored
Normal file
30
s3_storage/vendor/akeeba/s3/minitest/Test/SmallInlineFilesOnlyUpload.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
|
||||
/**
|
||||
* Upload small files (under 1MB) using a string source
|
||||
*
|
||||
* @package Akeeba\MiniTest\Test
|
||||
*/
|
||||
class SmallInlineFilesOnlyUpload extends SmallInlineFiles
|
||||
{
|
||||
public static function setup(Connector $s3, array $options): void
|
||||
{
|
||||
self::$deleteRemote = false;
|
||||
self::$downloadAfter = false;
|
||||
|
||||
parent::setup($s3, $options);
|
||||
}
|
||||
|
||||
}
|
74
s3_storage/vendor/akeeba/s3/minitest/Test/StorageClasses.php
vendored
Normal file
74
s3_storage/vendor/akeeba/s3/minitest/Test/StorageClasses.php
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* Akeeba Engine
|
||||
*
|
||||
* @package akeebaengine
|
||||
* @copyright Copyright (c)2006-2020 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace Akeeba\MiniTest\Test;
|
||||
|
||||
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Acl;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Connector;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\Input;
|
||||
use Akeeba\Engine\Postproc\Connector\S3v4\StorageClass;
|
||||
|
||||
class StorageClasses extends AbstractTest
|
||||
{
|
||||
protected static $downloadAfter = true;
|
||||
|
||||
protected static $deleteRemote = true;
|
||||
|
||||
public static function uploadRRS(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::TEN_KB, 'rrs_test_10kb.dat', StorageClass::REDUCED_REDUNDANCY);
|
||||
}
|
||||
|
||||
public static function uploadIntelligentTiering(Connector $s3, array $options): bool
|
||||
{
|
||||
return self::upload($s3, $options, self::TEN_KB, 'rrs_test_10kb.dat', StorageClass::INTELLIGENT_TIERING);
|
||||
}
|
||||
|
||||
protected static function upload(Connector $s3, array $options, int $size, string $uri, string $storageClass = null)
|
||||
{
|
||||
// Randomize the name. Required for archive buckets where you cannot overwrite data.
|
||||
$dotPos = strrpos($uri, '.');
|
||||
$uri = substr($uri, 0, $dotPos) . '.' . md5(microtime(false)) . substr($uri, $dotPos);
|
||||
|
||||
// Create some random data to upload
|
||||
$sourceData = self::getRandomData($size);
|
||||
|
||||
// Upload the data. Throws exception if it fails.
|
||||
$bucket = $options['bucket'];
|
||||
$input = Input::createFromData($sourceData);
|
||||
|
||||
// Get the headers
|
||||
$headers = [];
|
||||
StorageClass::setStorageClass($headers, $storageClass);
|
||||
|
||||
$s3->putObject($input, $bucket, $uri, Acl::ACL_PRIVATE, $headers);
|
||||
|
||||
// Tentatively accept that this method succeeded.
|
||||
$result = true;
|
||||
|
||||
// Should I download the file and compare its contents with my random data?
|
||||
if (self::$downloadAfter)
|
||||
{
|
||||
$downloadedData = $s3->getObject($bucket, $uri);
|
||||
|
||||
$result = self::areStringsEqual($sourceData, $downloadedData);
|
||||
}
|
||||
|
||||
// Should I delete the remotely stored file?
|
||||
if (self::$deleteRemote)
|
||||
{
|
||||
// Delete the remote file. Throws exception if it fails.
|
||||
$s3->deleteObject($bucket, $uri);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue