'db.example.test', 'port' => 25432, 'database' => "test' database", 'username' => 'reader', 'password' => 'fixture-secret', 'connect_timeout' => 5, 'query_timeout' => 120]; } public function test_postgres_uses_tls_read_only_timeout_and_one_select(): void { $statement = Mockery::mock(PDOStatement::class); $statement->shouldReceive('fetchColumn')->once()->andReturn(1); $statement->shouldReceive('closeCursor')->once(); $pdo = Mockery::mock(PDO::class); $pdo->shouldReceive('query')->once()->with('SELECT 1')->andReturn($statement); $probe = Mockery::mock(UpstreamDatabaseProbe::class)->makePartial()->shouldAllowMockingProtectedMethods(); $probe->shouldReceive('connect')->once()->withArgs(function ($dsn, $user, $password) { $this->assertStringContainsString('sslmode=require', $dsn); $this->assertStringContainsString('default_transaction_read_only=on', $dsn); $this->assertStringContainsString('statement_timeout=15000', $dsn); $this->assertStringContainsString("dbname='test\\' database'", $dsn); $this->assertStringContainsString('connect_timeout=5', $dsn); $this->assertStringNotContainsString('fixture-secret', $dsn); return $user === 'reader' && $password === 'fixture-secret'; })->andReturn($pdo); $probe->probe('pgsql', $this->connection(), '测试库'); } public function test_driver_error_never_exposes_credentials(): void { $probe = Mockery::mock(UpstreamDatabaseProbe::class)->makePartial()->shouldAllowMockingProtectedMethods(); $probe->shouldReceive('connect')->once()->andThrow(new PDOException('fixture-secret private driver detail')); try { $probe->probe('pgsql', $this->connection(), '测试库'); $this->fail('Expected sanitized connection error'); } catch (ServiceUnavailableHttpException $exception) { $this->assertStringContainsString('PostgreSQL 连接失败', $exception->getMessage()); $this->assertStringNotContainsString('fixture-secret', $exception->getMessage()); $this->assertNull($exception->getPrevious()); } } public function test_unsupported_driver_is_not_probed(): void { $this->expectException(ServiceUnavailableHttpException::class); $this->expectExceptionMessage('不支持此数据库类型'); (new UpstreamDatabaseProbe())->probe('unknown', [], '测试库'); } }