'db.example.test', 'port' => 25432, 'database' => "test' database", 'username' => 'reader', 'password' => 'fixture-secret', 'connect_timeout' => 5, 'query_timeout' => 120]; } public function test_postgres_probe_uses_the_shared_connector_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()->with('pgsql', $this->connection())->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('上游只读连接失败', $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', [], '测试库'); } }