Дедлайны и временные бюджеты
Патологические входы (катастрофический regex, глубокая рекурсия, неограниченный backoff) проявляются как время, а не как упавшая assertion. Две опциональные wall-clock-блокировки превращают их в явные падения:
php
#[Property(runs: 200, timeoutMs: 100, budgetMs: 5_000)]timeoutMs— дедлайн одного прогона (случайного или explicit example). Тело, превысившее лимит, падает со свойством черезDeadlineExceededExceptionс указанием виновного входа и измеренного времени. Вход сообщается as-is, без shrink (принятие shrink-кандидата потребовало бы повторного замера wall time, а таймерный шум делает такой спуск недетерминированным). Время измеряется после возврата тела — зависшее тело в синхронном PHP прервать нельзя.budgetMs— бюджет всей случайной фазы. Если он исчерпан до завершенияrunsуспешных проверок, свойство падает сTimeBudgetExceededException, раскрывающим счётчики completed/required, — медленное свойство не может молча проверить меньше заявленного.
Оба по умолчанию null (выключены). Упавшая assertion в медленном прогоне приоритетнее дедлайна — фальсифицированный контрпример важнее.