- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
270 lines
10 KiB
PHP
270 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\Cache\Compression\GzipCompression;
|
|
use App\Framework\Cache\Compression\NoCompression;
|
|
|
|
describe('NoCompression', function () {
|
|
beforeEach(function () {
|
|
$this->compression = new NoCompression();
|
|
});
|
|
|
|
describe('Basic Operations', function () {
|
|
it('returns value unchanged on compress', function () {
|
|
$original = 'Hello, World!';
|
|
$compressed = $this->compression->compress($original);
|
|
|
|
expect($compressed)->toBe($original);
|
|
});
|
|
|
|
it('returns value unchanged on decompress', function () {
|
|
$original = 'Hello, World!';
|
|
$decompressed = $this->compression->decompress($original);
|
|
|
|
expect($decompressed)->toBe($original);
|
|
});
|
|
|
|
it('reports values as never compressed', function () {
|
|
expect($this->compression->isCompressed('any value'))->toBeFalse();
|
|
expect($this->compression->isCompressed(''))->toBeFalse();
|
|
expect($this->compression->isCompressed('gz:prefixed'))->toBeFalse();
|
|
});
|
|
});
|
|
|
|
describe('Force Compression Flag', function () {
|
|
it('ignores force compression flag', function () {
|
|
$original = 'test';
|
|
$compressed = $this->compression->compress($original, forceCompression: true);
|
|
|
|
expect($compressed)->toBe($original);
|
|
});
|
|
});
|
|
|
|
describe('Edge Cases', function () {
|
|
it('handles empty strings', function () {
|
|
$result = $this->compression->compress('');
|
|
expect($result)->toBe('');
|
|
|
|
$result = $this->compression->decompress('');
|
|
expect($result)->toBe('');
|
|
});
|
|
|
|
it('handles large strings', function () {
|
|
$large = str_repeat('abcdefghij', 10000); // 100KB
|
|
$compressed = $this->compression->compress($large);
|
|
|
|
expect($compressed)->toBe($large);
|
|
});
|
|
|
|
it('handles binary data', function () {
|
|
$binary = random_bytes(1000);
|
|
$compressed = $this->compression->compress($binary);
|
|
|
|
expect($compressed)->toBe($binary);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('GzipCompression', function () {
|
|
describe('Basic Operations', function () {
|
|
it('compresses strings above threshold', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$original = str_repeat('a', 200); // Above threshold
|
|
|
|
$compressed = $compression->compress($original);
|
|
|
|
// Verify compression occurred
|
|
$isCompressed = $compression->isCompressed($compressed);
|
|
$hasPrefix = str_starts_with($compressed, 'gz:');
|
|
$isDifferent = $compressed !== $original;
|
|
|
|
expect($isCompressed)->toBeTrue();
|
|
expect($hasPrefix)->toBeTrue();
|
|
expect($isDifferent)->toBeTrue();
|
|
});
|
|
|
|
it('does not compress strings below threshold', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 1000);
|
|
$original = 'Short string';
|
|
|
|
$compressed = $compression->compress($original);
|
|
|
|
expect($compressed)->toBe($original);
|
|
expect($compression->isCompressed($compressed))->toBeFalse();
|
|
});
|
|
|
|
it('decompresses compressed strings', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$original = str_repeat('test data ', 50); // 500 bytes
|
|
|
|
$compressed = $compression->compress($original);
|
|
$decompressed = $compression->decompress($compressed);
|
|
|
|
expect($decompressed)->toBe($original);
|
|
});
|
|
|
|
it('returns uncompressed strings unchanged on decompress', function () {
|
|
$compression = new GzipCompression();
|
|
$original = 'Not compressed';
|
|
|
|
$decompressed = $compression->decompress($original);
|
|
|
|
expect($decompressed)->toBe($original);
|
|
});
|
|
});
|
|
|
|
describe('Force Compression', function () {
|
|
it('forces compression even below threshold', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 1000);
|
|
$original = 'Short';
|
|
|
|
$compressed = $compression->compress($original, forceCompression: true);
|
|
$hasPrefix = str_starts_with($compressed, 'gz:');
|
|
|
|
expect($compression->isCompressed($compressed))->toBeTrue();
|
|
expect($hasPrefix)->toBeTrue();
|
|
});
|
|
});
|
|
|
|
describe('Compression Levels', function () {
|
|
it('uses default compression level -1', function () {
|
|
$compression = new GzipCompression();
|
|
$original = str_repeat('data ', 500);
|
|
|
|
$compressed = $compression->compress($original);
|
|
|
|
expect($compression->isCompressed($compressed))->toBeTrue();
|
|
});
|
|
|
|
it('uses maximum compression level 9', function () {
|
|
$compression = new GzipCompression(compressionLevel: 9, minLengthToCompress: 100);
|
|
$original = str_repeat('test ', 500);
|
|
|
|
$compressed = $compression->compress($original);
|
|
$isSmallerThanOriginal = strlen($compressed) < strlen($original);
|
|
|
|
expect($compression->isCompressed($compressed))->toBeTrue();
|
|
expect($isSmallerThanOriginal)->toBeTrue();
|
|
});
|
|
|
|
it('uses minimum compression level 1', function () {
|
|
$compression = new GzipCompression(compressionLevel: 1, minLengthToCompress: 100);
|
|
$original = str_repeat('test ', 500);
|
|
|
|
$compressed = $compression->compress($original);
|
|
|
|
expect($compression->isCompressed($compressed))->toBeTrue();
|
|
});
|
|
});
|
|
|
|
describe('Compression Efficiency', function () {
|
|
it('achieves significant compression on repetitive data', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$original = str_repeat('abcdefghij', 1000); // 10KB repetitive
|
|
|
|
$compressed = $compression->compress($original);
|
|
$compressionRatio = strlen($compressed) / strlen($original);
|
|
|
|
$isEfficient = $compressionRatio < 0.1; // Should compress to < 10%
|
|
expect($isEfficient)->toBeTrue();
|
|
});
|
|
|
|
it('has minimal compression on random data', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$original = random_bytes(5000);
|
|
|
|
$compressed = $compression->compress($original);
|
|
$compressionRatio = strlen($compressed) / strlen($original);
|
|
|
|
// Random data doesn't compress well, ratio likely > 0.95
|
|
$hasMinimalCompression = $compressionRatio > 0.8;
|
|
expect($hasMinimalCompression)->toBeTrue();
|
|
});
|
|
});
|
|
|
|
describe('Error Handling', function () {
|
|
it('returns result on compression attempt', function () {
|
|
$compression = new GzipCompression();
|
|
$original = 'test';
|
|
|
|
$result = $compression->compress($original, forceCompression: true);
|
|
|
|
$isNotNull = $result !== null;
|
|
expect($isNotNull)->toBeTrue();
|
|
});
|
|
|
|
it('handles decompression of corrupted data gracefully', function () {
|
|
$compression = new GzipCompression();
|
|
$corrupted = 'gz:corrupted_data_not_valid_gzip';
|
|
|
|
$decompressed = $compression->decompress($corrupted);
|
|
|
|
// Should return the original value as fallback
|
|
expect($decompressed)->toBe($corrupted);
|
|
});
|
|
});
|
|
|
|
describe('Edge Cases', function () {
|
|
it('handles empty strings', function () {
|
|
$compression = new GzipCompression(minLengthToCompress: 0);
|
|
|
|
$compressed = $compression->compress('', forceCompression: true);
|
|
$decompressed = $compression->decompress($compressed);
|
|
|
|
expect($decompressed)->toBe('');
|
|
});
|
|
|
|
it('handles very large strings', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 1000);
|
|
$large = str_repeat('Large data block ', 10000); // ~170KB
|
|
|
|
$compressed = $compression->compress($large);
|
|
$decompressed = $compression->decompress($compressed);
|
|
$isSmallerThanOriginal = strlen($compressed) < strlen($large);
|
|
|
|
expect($decompressed)->toBe($large);
|
|
expect($isSmallerThanOriginal)->toBeTrue();
|
|
});
|
|
|
|
it('handles strings with special characters', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$special = str_repeat('äöü€₹🚀', 100);
|
|
|
|
$compressed = $compression->compress($special);
|
|
$decompressed = $compression->decompress($compressed);
|
|
|
|
expect($decompressed)->toBe($special);
|
|
});
|
|
});
|
|
|
|
describe('Prefix Detection', function () {
|
|
it('correctly identifies compressed strings by prefix', function () {
|
|
$compression = new GzipCompression(minLengthToCompress: 100);
|
|
|
|
expect($compression->isCompressed('gz:anything'))->toBeTrue();
|
|
expect($compression->isCompressed('not compressed'))->toBeFalse();
|
|
expect($compression->isCompressed('gzcompressed'))->toBeFalse(); // No colon
|
|
expect($compression->isCompressed(''))->toBeFalse();
|
|
});
|
|
|
|
it('strips prefix on decompression', function () {
|
|
$compression = new GzipCompression(compressionLevel: 6, minLengthToCompress: 100);
|
|
$original = str_repeat('test ', 200);
|
|
|
|
$compressed = $compression->compress($original);
|
|
$hasPrefix = str_starts_with($compressed, 'gz:');
|
|
|
|
// The compressed value should have the prefix
|
|
expect($hasPrefix)->toBeTrue();
|
|
|
|
// Decompression should remove it
|
|
$decompressed = $compression->decompress($compressed);
|
|
$doesNotHavePrefix = !str_starts_with($decompressed, 'gz:');
|
|
|
|
expect($doesNotHavePrefix)->toBeTrue();
|
|
expect($decompressed)->toBe($original);
|
|
});
|
|
});
|
|
});
|