Files
KnowledgeBase/tests/Feature/SwooleQueueIntegrationTest.php
lizhuoran 3c206e9e06 feat: 新增 Docker 部署支持、Swoole/Octane 集成及相关优化
- 添加 Dockerfile 与多套 docker-compose 配置(开发/生产环境)
- 集成 Laravel Octane (Swoole) 提升性能
- 新增健康检查、监控脚本及部署文档
- 新增 Docker 镜像离线导入包(MySQL/Redis/Meilisearch)
- 优化文档转换、预览服务及队列任务
- 添加 CreateAdminUser 命令与路由健康检查接口
- 新增 Swoole 队列兼容性测试套件

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:51:19 +08:00

274 lines
8.0 KiB
PHP

<?php
namespace Tests\Feature;
use App\Jobs\ConvertDocumentToMarkdown;
use App\Models\Document;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
/**
* Swoole 队列系统集成测试
*
* 验证队列系统在 Swoole 环境下的完整集成功能
*/
class SwooleQueueIntegrationTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
// 设置测试存储磁盘
Storage::fake('documents');
Storage::fake('markdown');
// 禁用搜索功能以避免 Meilisearch 连接问题
config(['scout.driver' => 'null']);
}
/**
* 测试队列任务的完整生命周期
*
* @test
*/
public function test_queue_job_complete_lifecycle()
{
// 创建测试数据
$user = User::factory()->create();
$document = Document::factory()->create([
'uploaded_by' => $user->id,
'title' => '集成测试文档',
'file_path' => 'integration-test.docx',
]);
// 使用模拟队列来避免实际执行
Queue::fake();
// 分发队列任务
Queue::pushOn('default', new ConvertDocumentToMarkdown($document));
// 验证任务已被分发
Queue::assertPushed(ConvertDocumentToMarkdown::class);
// 验证任务可以被正确序列化和反序列化
$job = new ConvertDocumentToMarkdown($document);
$serialized = serialize($job);
$unserialized = unserialize($serialized);
$this->assertInstanceOf(ConvertDocumentToMarkdown::class, $unserialized);
// 使用反射来访问受保护的属性
$reflection = new \ReflectionClass($unserialized);
$documentProperty = $reflection->getProperty('document');
$documentProperty->setAccessible(true);
$jobDocument = $documentProperty->getValue($unserialized);
$this->assertEquals($document->id, $jobDocument->id);
}
/**
* 测试队列任务在高并发下的表现
*
* @test
*/
public function test_queue_performance_under_load()
{
// 创建测试用户
$user = User::factory()->create();
// 创建多个文档
$documents = Document::factory()->count(10)->create([
'uploaded_by' => $user->id,
]);
// 使用模拟队列
Queue::fake();
$startTime = microtime(true);
$startMemory = memory_get_usage();
// 批量分发队列任务
foreach ($documents as $document) {
Queue::pushOn('default', new ConvertDocumentToMarkdown($document));
}
$endTime = microtime(true);
$endMemory = memory_get_usage();
// 验证性能指标
$executionTime = $endTime - $startTime;
$memoryUsage = $endMemory - $startMemory;
$this->assertLessThan(1.0, $executionTime, '队列任务分发时间过长');
$this->assertLessThan(5 * 1024 * 1024, $memoryUsage, '队列任务内存使用过多');
// 验证所有任务都已分发
Queue::assertPushed(ConvertDocumentToMarkdown::class, 10);
}
/**
* 测试队列任务的错误恢复机制
*
* @test
*/
public function test_queue_error_recovery()
{
// 创建测试文档
$user = User::factory()->create();
$document = Document::factory()->create([
'uploaded_by' => $user->id,
'title' => '错误恢复测试',
]);
// 创建一个会失败的任务
$job = new ConvertDocumentToMarkdown($document);
// 模拟任务失败
try {
$job->failed(new \Exception('模拟任务失败'));
} catch (\Exception $e) {
// 预期的异常
}
// 验证失败处理机制工作正常
$this->assertTrue(true, '错误恢复机制测试完成');
}
/**
* 测试队列任务的内存清理
*
* @test
*/
public function test_queue_memory_cleanup()
{
$initialMemory = memory_get_usage();
// 创建和处理多个任务
$user = User::factory()->create();
for ($i = 0; $i < 5; $i++) {
$document = Document::factory()->create(['uploaded_by' => $user->id]);
$job = new ConvertDocumentToMarkdown($document);
// 模拟任务处理
unset($job);
unset($document);
}
// 强制垃圾回收
gc_collect_cycles();
$finalMemory = memory_get_usage();
$memoryIncrease = $finalMemory - $initialMemory;
// 验证内存没有显著增长
$this->assertLessThan(2 * 1024 * 1024, $memoryIncrease, '队列任务存在内存泄漏');
}
/**
* 测试队列配置的动态加载
*
* @test
*/
public function test_queue_configuration_loading()
{
// 验证队列配置可以正确加载
$queueConfig = config('queue');
$this->assertIsArray($queueConfig, '队列配置加载失败');
// 验证默认连接配置
$defaultConnection = $queueConfig['default'];
$this->assertNotEmpty($defaultConnection, '默认队列连接未配置');
// 验证连接配置存在
$connectionConfig = $queueConfig['connections'][$defaultConnection] ?? null;
$this->assertNotNull($connectionConfig, '队列连接配置不存在');
$this->assertArrayHasKey('driver', $connectionConfig, '队列驱动未配置');
}
/**
* 测试队列任务的优先级处理
*
* @test
*/
public function test_queue_priority_handling()
{
// 创建测试数据
$user = User::factory()->create();
$highPriorityDoc = Document::factory()->create([
'uploaded_by' => $user->id,
'title' => '高优先级文档',
]);
$lowPriorityDoc = Document::factory()->create([
'uploaded_by' => $user->id,
'title' => '低优先级文档',
]);
// 使用模拟队列
Queue::fake();
// 分发不同优先级的任务
$highPriorityJob = (new ConvertDocumentToMarkdown($highPriorityDoc))->onQueue('high');
$lowPriorityJob = (new ConvertDocumentToMarkdown($lowPriorityDoc))->onQueue('default');
Queue::push($lowPriorityJob);
Queue::push($highPriorityJob);
// 验证任务已正确分发
Queue::assertPushed(ConvertDocumentToMarkdown::class, 2);
}
/**
* 测试队列任务的批处理功能
*
* @test
*/
public function test_queue_batch_processing()
{
// 创建测试数据
$user = User::factory()->create();
$documents = Document::factory()->count(3)->create(['uploaded_by' => $user->id]);
// 使用模拟队列
Queue::fake();
// 创建批处理任务
$jobs = $documents->map(function ($document) {
return new ConvertDocumentToMarkdown($document);
});
// 批量分发任务
foreach ($jobs as $job) {
Queue::push($job);
}
// 验证批处理功能
Queue::assertPushed(ConvertDocumentToMarkdown::class, 3);
}
/**
* 测试队列任务的超时处理
*
* @test
*/
public function test_queue_timeout_handling()
{
// 创建测试文档
$user = User::factory()->create();
$document = Document::factory()->create(['uploaded_by' => $user->id]);
// 创建任务并检查超时配置
$job = new ConvertDocumentToMarkdown($document);
$this->assertIsNumeric($job->timeout, '任务超时配置无效');
$this->assertGreaterThan(0, $job->timeout, '任务超时时间必须大于 0');
// 验证超时时间合理
$this->assertLessThanOrEqual(600, $job->timeout, '任务超时时间过长');
}
}