- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
251 lines
8.4 KiB
PHP
251 lines
8.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
require_once __DIR__ . '/../bootstrap.php';
|
||
|
||
use App\Framework\Queue\FileQueue;
|
||
use App\Framework\Queue\ValueObjects\JobPayload;
|
||
use App\Framework\Queue\ValueObjects\QueuePriority;
|
||
use App\Framework\Core\ValueObjects\Duration;
|
||
use App\Framework\Filesystem\FileStorage;
|
||
|
||
// Example Job Classes for Tests
|
||
class FileSystemTestJob
|
||
{
|
||
public function __construct(
|
||
public string $id,
|
||
public string $description
|
||
) {}
|
||
}
|
||
|
||
class FileCriticalTask
|
||
{
|
||
public function __construct(
|
||
public string $taskId,
|
||
public string $urgency
|
||
) {}
|
||
}
|
||
|
||
echo "🗂️ Testing FileQueue with Filesystem Module Integration\n";
|
||
echo "=====================================================\n\n";
|
||
|
||
// Test 1: Basic FileQueue with Filesystem Module
|
||
echo "1️⃣ Testing Basic FileQueue Operations with Filesystem Module...\n";
|
||
|
||
// Create temporary queue directory
|
||
$queuePath = __DIR__ . '/../tmp/file_queue_test_' . uniqid();
|
||
mkdir($queuePath, 0777, true);
|
||
|
||
$storage = new FileStorage();
|
||
$queue = new FileQueue($queuePath, storage: $storage);
|
||
|
||
$testJob = new FileSystemTestJob('job-1', 'Test filesystem integration');
|
||
$payload = JobPayload::create($testJob, QueuePriority::normal());
|
||
|
||
$queue->push($payload);
|
||
|
||
echo " 📊 Queue size after push: " . $queue->size() . "\n";
|
||
|
||
// Debug: Check directory contents
|
||
$priorityFiles = $queue->getPriorityJobFiles();
|
||
echo " 📁 Priority files count: " . count($priorityFiles) . "\n";
|
||
|
||
$delayedFiles = $queue->getDelayedJobFiles();
|
||
echo " ⏱️ Delayed files count: " . count($delayedFiles) . "\n";
|
||
|
||
assert($queue->size() === 1, "❌ Queue should have 1 job");
|
||
|
||
$poppedPayload = $queue->pop();
|
||
assert($poppedPayload !== null, "❌ Should pop a payload");
|
||
assert($poppedPayload->job instanceof FileSystemTestJob, "❌ Should be FileSystemTestJob");
|
||
assert($poppedPayload->job->id === 'job-1', "❌ Job ID should match");
|
||
|
||
assert($queue->size() === 0, "❌ Queue should be empty after pop");
|
||
|
||
echo "✅ Basic FileQueue operations with Filesystem module work correctly\n\n";
|
||
|
||
// Test 2: Priority-based Job Processing
|
||
echo "2️⃣ Testing Priority-based Job Processing...\n";
|
||
|
||
$queue->clear();
|
||
|
||
$lowJob = JobPayload::create(new FileSystemTestJob('low', 'Low priority'), QueuePriority::low());
|
||
$normalJob = JobPayload::create(new FileSystemTestJob('normal', 'Normal priority'), QueuePriority::normal());
|
||
$highJob = JobPayload::create(new FileSystemTestJob('high', 'High priority'), QueuePriority::high());
|
||
$criticalJob = JobPayload::create(new FileCriticalTask('critical', 'Critical task'), QueuePriority::critical());
|
||
|
||
// Push in random order
|
||
$queue->push($normalJob);
|
||
$queue->push($lowJob);
|
||
$queue->push($criticalJob);
|
||
$queue->push($highJob);
|
||
|
||
assert($queue->size() === 4, "❌ Queue should have 4 jobs");
|
||
|
||
// Should pop in priority order: critical > high > normal > low
|
||
$first = $queue->pop();
|
||
$second = $queue->pop();
|
||
$third = $queue->pop();
|
||
$fourth = $queue->pop();
|
||
|
||
assert($first !== null && $first->job instanceof FileCriticalTask, "❌ First should be critical task");
|
||
assert($second !== null && $second->job->id === 'high', "❌ Second should be high priority");
|
||
assert($third !== null && $third->job->id === 'normal', "❌ Third should be normal priority");
|
||
assert($fourth !== null && $fourth->job->id === 'low', "❌ Fourth should be low priority");
|
||
|
||
echo "✅ Priority-based job processing works correctly\n\n";
|
||
|
||
// Test 3: Delayed Jobs with Filesystem
|
||
echo "3️⃣ Testing Delayed Jobs with Filesystem Module...\n";
|
||
|
||
$queue->clear();
|
||
|
||
$immediateJob = JobPayload::create(new FileSystemTestJob('immediate', 'Process now'));
|
||
$delayedJob = JobPayload::create(
|
||
new FileSystemTestJob('delayed', 'Process later'),
|
||
QueuePriority::normal(),
|
||
Duration::fromSeconds(2) // 2 second delay
|
||
);
|
||
|
||
$queue->push($delayedJob);
|
||
$queue->push($immediateJob);
|
||
|
||
// Should only get immediate job initially
|
||
$popped = $queue->pop();
|
||
assert($popped !== null, "❌ Should pop immediate job");
|
||
assert($popped->job->id === 'immediate', "❌ Should be immediate job");
|
||
|
||
// Delayed job should still be in queue but not poppable yet
|
||
assert($queue->size() === 1, "❌ Should have 1 delayed job remaining");
|
||
|
||
// Wait for delay to pass and try again
|
||
echo " ⏳ Waiting 3 seconds for delayed job to become ready...\n";
|
||
sleep(3);
|
||
|
||
$delayedPopped = $queue->pop();
|
||
assert($delayedPopped !== null, "❌ Should pop delayed job after delay");
|
||
assert($delayedPopped->job->id === 'delayed', "❌ Should be delayed job");
|
||
|
||
echo "✅ Delayed jobs with filesystem work correctly\n\n";
|
||
|
||
// Test 4: Peek Operations
|
||
echo "4️⃣ Testing Peek Operations...\n";
|
||
|
||
$queue->clear();
|
||
|
||
$peekJob = JobPayload::create(new FileSystemTestJob('peek', 'Test peek'));
|
||
$queue->push($peekJob);
|
||
|
||
$originalSize = $queue->size();
|
||
$peeked = $queue->peek();
|
||
|
||
assert($peeked !== null, "❌ Should peek a payload");
|
||
assert($peeked->job->id === 'peek', "❌ Peeked job should have correct data");
|
||
assert($queue->size() === $originalSize, "❌ Queue size should not change after peek");
|
||
|
||
echo "✅ Peek operations work correctly\n\n";
|
||
|
||
// Test 5: Queue Statistics with Priority Breakdown
|
||
echo "5️⃣ Testing Queue Statistics...\n";
|
||
|
||
$queue->clear();
|
||
|
||
$payload1 = JobPayload::create(new FileSystemTestJob('stats-1', 'test'), QueuePriority::high());
|
||
$payload2 = JobPayload::create(new FileSystemTestJob('stats-2', 'test'), QueuePriority::normal());
|
||
$payload3 = JobPayload::create(new FileSystemTestJob('stats-3', 'test'), QueuePriority::high());
|
||
|
||
$queue->push($payload1);
|
||
$queue->push($payload2);
|
||
$queue->push($payload3);
|
||
|
||
$stats = $queue->getStats();
|
||
|
||
assert($stats['total_size'] === 3, "❌ Stats should show 3 total jobs");
|
||
assert($stats['priority_queue_size'] === 3, "❌ Stats should show 3 priority jobs");
|
||
assert($stats['delayed_queue_size'] === 0, "❌ Stats should show 0 delayed jobs");
|
||
assert(isset($stats['priority_breakdown']), "❌ Stats should include priority breakdown");
|
||
|
||
$breakdown = $stats['priority_breakdown'];
|
||
assert(isset($breakdown['high']), "❌ Should have high priority breakdown");
|
||
assert(isset($breakdown['normal']), "❌ Should have normal priority breakdown");
|
||
assert($breakdown['high'] === 2, "❌ Should have 2 high priority jobs");
|
||
assert($breakdown['normal'] === 1, "❌ Should have 1 normal priority job");
|
||
|
||
echo "✅ Queue statistics work correctly\n\n";
|
||
|
||
// Test 6: Directory Structure Verification
|
||
echo "6️⃣ Testing Directory Structure...\n";
|
||
|
||
// Verify that the filesystem module created the correct directory structure
|
||
$priorityDir = $queuePath . '/priority';
|
||
$delayedDir = $queuePath . '/delayed';
|
||
|
||
assert(is_dir($priorityDir), "❌ Priority directory should exist");
|
||
assert(is_dir($delayedDir), "❌ Delayed directory should exist");
|
||
|
||
echo "✅ Directory structure is correct\n\n";
|
||
|
||
// Test 7: Clear Operations
|
||
echo "7️⃣ Testing Clear Operations...\n";
|
||
|
||
$queue->clear();
|
||
|
||
$payload1 = JobPayload::create(new FileSystemTestJob('clear-1', 'test'));
|
||
$payload2 = JobPayload::create(new FileSystemTestJob('clear-2', 'test'));
|
||
$delayedPayload = JobPayload::create(
|
||
new FileSystemTestJob('clear-delayed', 'test'),
|
||
QueuePriority::normal(),
|
||
Duration::fromSeconds(3600)
|
||
);
|
||
|
||
$queue->push($payload1);
|
||
$queue->push($payload2);
|
||
$queue->push($delayedPayload);
|
||
|
||
assert($queue->size() === 3, "❌ Should have 3 jobs before clear");
|
||
|
||
$clearedCount = $queue->clear();
|
||
assert($clearedCount === 3, "❌ Should report 3 jobs cleared");
|
||
assert($queue->size() === 0, "❌ Queue should be empty after clear");
|
||
|
||
echo "✅ Clear operations work correctly\n\n";
|
||
|
||
// Test 8: Empty Queue Handling
|
||
echo "8️⃣ Testing Empty Queue Handling...\n";
|
||
|
||
$queue->clear();
|
||
assert($queue->size() === 0, "❌ Queue should be empty");
|
||
|
||
$nullPayload = $queue->pop();
|
||
assert($nullPayload === null, "❌ Popping from empty queue should return null");
|
||
|
||
$nullPeek = $queue->peek();
|
||
assert($nullPeek === null, "❌ Peeking empty queue should return null");
|
||
|
||
echo "✅ Empty queue handling works correctly\n\n";
|
||
|
||
// Cleanup
|
||
echo "🧹 Cleaning up test files...\n";
|
||
|
||
function deleteDirectory($dir) {
|
||
if (!is_dir($dir)) {
|
||
return;
|
||
}
|
||
|
||
$files = array_diff(scandir($dir), array('.', '..'));
|
||
foreach ($files as $file) {
|
||
$path = $dir . DIRECTORY_SEPARATOR . $file;
|
||
if (is_dir($path)) {
|
||
deleteDirectory($path);
|
||
} else {
|
||
unlink($path);
|
||
}
|
||
}
|
||
rmdir($dir);
|
||
}
|
||
|
||
deleteDirectory($queuePath);
|
||
|
||
echo "🎉 ALL FILEQUEUE FILESYSTEM TESTS PASSED!\n";
|
||
echo "✨ FileQueue with Filesystem module integration is working correctly!\n"; |