2022-02-20 21:22:07 +01:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Akeeba Engine
|
|
|
|
*
|
|
|
|
* @package akeebaengine
|
2024-03-20 04:03:34 +01:00
|
|
|
* @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd
|
2022-02-20 21:22:07 +01:00
|
|
|
* @license GNU General Public License version 3, or later
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Akeeba\MiniTest\Test;
|
|
|
|
|
2023-12-19 03:28:16 +01:00
|
|
|
use Akeeba\S3\Connector;
|
2022-02-20 21:22:07 +01:00
|
|
|
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)
|
|
|
|
{
|
2023-12-19 03:28:16 +01:00
|
|
|
$tempFilePath = tempnam(static::getTempFolder(), 'as3');
|
2022-02-20 21:22:07 +01:00
|
|
|
|
|
|
|
if ($tempFilePath === false)
|
|
|
|
{
|
|
|
|
throw new RuntimeException("Cannot create a temporary file.");
|
|
|
|
}
|
|
|
|
|
2023-12-19 03:28:16 +01:00
|
|
|
$fp = @fopen($tempFilePath, 'w', false);
|
2022-02-20 21:22:07 +01:00
|
|
|
|
|
|
|
if ($fp === false)
|
|
|
|
{
|
|
|
|
throw new RuntimeException("Cannot write to the temporary file.");
|
|
|
|
}
|
|
|
|
|
2023-12-19 03:28:16 +01:00
|
|
|
$blockSize = static::BLOCK_SIZE;
|
2022-02-20 21:22:07 +01:00
|
|
|
$lastBlockSize = $size % $blockSize;
|
|
|
|
$wholeBlocks = (int) (($size - $lastBlockSize) / $blockSize);
|
2023-12-19 03:28:16 +01:00
|
|
|
$blockData = static::getRandomData();
|
2022-02-20 21:22:07 +01:00
|
|
|
|
|
|
|
for ($i = 0; $i < $wholeBlocks; $i++)
|
|
|
|
{
|
|
|
|
fwrite($fp, $blockData);
|
|
|
|
|
|
|
|
if (!$reuseBlock)
|
|
|
|
{
|
2023-12-19 03:28:16 +01:00
|
|
|
$blockData = static::getRandomData($blockSize);
|
2022-02-20 21:22:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-12-19 03:28:16 +01:00
|
|
|
return hash_file(static::FILE_HASHING_ALGORITHM, $referenceFilePath) === hash_file(static::FILE_HASHING_ALGORITHM, $unknownFilePath);
|
2022-02-20 21:22:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
}
|