From f2bca8fee4059ce352ffb94773c1c4555bab87df Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 21 Oct 2026 19:34:26 +0400 Subject: [PATCH 1/2] test: accept null for empty search attributes on Temporal Server 1.31+ Server 1.31 (temporalio/temporal#9091) drops an empty search attribute map from the start event, so the child workflow gets null for []. Run the tests on CLI 1.9 (Server 1.32). --- dload.xml | 2 +- .../Acceptance/Extra/Workflow/WorkflowSearchAttributesTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dload.xml b/dload.xml index e0badb6cd..44a1e46ac 100644 --- a/dload.xml +++ b/dload.xml @@ -5,7 +5,7 @@ > - + diff --git a/tests/Acceptance/Extra/Workflow/WorkflowSearchAttributesTest.php b/tests/Acceptance/Extra/Workflow/WorkflowSearchAttributesTest.php index 219a00589..15792ef66 100644 --- a/tests/Acceptance/Extra/Workflow/WorkflowSearchAttributesTest.php +++ b/tests/Acceptance/Extra/Workflow/WorkflowSearchAttributesTest.php @@ -31,7 +31,7 @@ public function sendEmptySearchAttributes( WorkflowStubInterface $stub, ): void { $result = $stub->getResult(timeout: 3); - $this->assertSame([], $result, 'Workflow result contains resolved value'); + $this->assertEmpty($result, 'Workflow result contains resolved value'); } #[Test] From 1baafbb6d10b712501b10c9bada7e608ca43e7b3 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 21 Oct 2026 20:44:01 +0400 Subject: [PATCH 2/2] feat: add WorkerOptions::$disablePayloadErrorLimit The RoadRunner worker fails the Workflow Task with PAYLOADS_TOO_LARGE when a payload exceeds the namespace limit. The option turns this check off. --- src/Worker/WorkerOptions.php | 10 +++ tests/Acceptance/App/TaskQueueResolver.php | 1 + .../PayloadErrorLimitDisabledTest.php | 61 +++++++++++++++++++ .../Extra/Workflow/PayloadErrorLimitTest.php | 59 ++++++++++++++++++ tests/Unit/DTO/WorkerOptionsTestCase.php | 12 ++++ 5 files changed, 143 insertions(+) create mode 100644 tests/Acceptance/Extra/Workflow/PayloadErrorLimitDisabledTest.php create mode 100644 tests/Acceptance/Extra/Workflow/PayloadErrorLimitTest.php diff --git a/src/Worker/WorkerOptions.php b/src/Worker/WorkerOptions.php index e6ad1b63f..e2ebd969c 100644 --- a/src/Worker/WorkerOptions.php +++ b/src/Worker/WorkerOptions.php @@ -293,6 +293,9 @@ class WorkerOptions #[Marshal(name: 'MaxEagerActivityReservationsPerWorkflowTask')] public ?int $maxEagerActivityReservationsPerWorkflowTask = null; + #[Marshal(name: 'DisablePayloadErrorLimit')] + public bool $disablePayloadErrorLimit = false; + /** * Optional: Disable allowing workflow and activity functions that are * registered with custom names from being able to be called with their @@ -829,6 +832,13 @@ public function withMaxEagerActivityReservationsPerWorkflowTask(int $value): sel return $self; } + public function withDisablePayloadErrorLimit(bool $disable = true): self + { + $self = clone $this; + $self->disablePayloadErrorLimit = $disable; + return $self; + } + /** * Optional: Disable allowing workflow and activity functions that are * registered with custom names from being able to be called with their diff --git a/tests/Acceptance/App/TaskQueueResolver.php b/tests/Acceptance/App/TaskQueueResolver.php index 399ab18fc..b0d6b5890 100644 --- a/tests/Acceptance/App/TaskQueueResolver.php +++ b/tests/Acceptance/App/TaskQueueResolver.php @@ -23,6 +23,7 @@ final class TaskQueueResolver \Temporal\Tests\Acceptance\Extra\Versioning\Classic\ClassicTest::class, \Temporal\Tests\Acceptance\Extra\Versioning\Deployment\DeploymentTest::class, \Temporal\Tests\Acceptance\Extra\Activity\ActivityPaused\ActivityPausedTest::class, + \Temporal\Tests\Acceptance\Extra\Workflow\PayloadErrorLimitDisabled\PayloadErrorLimitDisabledTest::class, ]; /** diff --git a/tests/Acceptance/Extra/Workflow/PayloadErrorLimitDisabledTest.php b/tests/Acceptance/Extra/Workflow/PayloadErrorLimitDisabledTest.php new file mode 100644 index 000000000..20bbb8a0e --- /dev/null +++ b/tests/Acceptance/Extra/Workflow/PayloadErrorLimitDisabledTest.php @@ -0,0 +1,61 @@ +getResult(timeout: 10); + self::fail('The Workflow must not complete'); + } catch (WorkflowFailedException) { + } + + self::assertSame(WorkflowExecutionStatus::Terminated, $stub->describe()->info->status); + foreach ($client->getWorkflowHistory($stub->getExecution()) as $event) { + self::assertNotSame( + WorkflowTaskFailedCause::WORKFLOW_TASK_FAILED_CAUSE_PAYLOADS_TOO_LARGE, + $event->getWorkflowTaskFailedEventAttributes()?->getCause(), + ); + } + } +} + +class WorkerFactory +{ + public static function options(): WorkerOptions + { + return WorkerOptions::new()->withDisablePayloadErrorLimit(); + } +} + +#[WorkflowInterface] +class TestWorkflow +{ + #[WorkflowMethod(name: 'Extra_Workflow_PayloadErrorLimitDisabled')] + public function handle(): string + { + return \str_repeat('a', 3 * 1024 * 1024); + } +} diff --git a/tests/Acceptance/Extra/Workflow/PayloadErrorLimitTest.php b/tests/Acceptance/Extra/Workflow/PayloadErrorLimitTest.php new file mode 100644 index 000000000..63d23587d --- /dev/null +++ b/tests/Acceptance/Extra/Workflow/PayloadErrorLimitTest.php @@ -0,0 +1,59 @@ +describe()->info->status); + $stub->terminate('test finished'); + } + + private static function waitForWorkflowTaskFailureCause( + WorkflowClientInterface $client, + WorkflowStubInterface $stub, + ): int { + $deadline = \microtime(true) + 10; + do { + foreach ($client->getWorkflowHistory($stub->getExecution()) as $event) { + $failed = $event->getWorkflowTaskFailedEventAttributes(); + if ($failed !== null) { + return $failed->getCause(); + } + } + \usleep(100_000); + } while (\microtime(true) < $deadline); + + self::fail('The Workflow Task did not fail'); + } +} + +#[WorkflowInterface] +class TestWorkflow +{ + #[WorkflowMethod(name: 'Extra_Workflow_PayloadErrorLimit')] + public function handle(): string + { + return \str_repeat('a', 3 * 1024 * 1024); + } +} diff --git a/tests/Unit/DTO/WorkerOptionsTestCase.php b/tests/Unit/DTO/WorkerOptionsTestCase.php index 2768f72c6..09db12556 100644 --- a/tests/Unit/DTO/WorkerOptionsTestCase.php +++ b/tests/Unit/DTO/WorkerOptionsTestCase.php @@ -52,6 +52,7 @@ public function testMarshalling(): void 'DisableEagerActivities' => false, 'MaxConcurrentEagerActivityExecutionSize' => 0, 'MaxEagerActivityReservationsPerWorkflowTask' => null, + 'DisablePayloadErrorLimit' => false, 'DisableRegistrationAliasing' => false, 'BuildID' => "", 'DeploymentOptions' => null, @@ -362,6 +363,17 @@ public function testMaxEagerActivityReservationsPerWorkflowTaskRejectsNonPositiv (new WorkerOptions())->withMaxEagerActivityReservationsPerWorkflowTask(0); } + public function testDisablePayloadErrorLimit(): void + { + $dto = new WorkerOptions(); + $result = $dto->withDisablePayloadErrorLimit(); + + self::assertNotSame($dto, $result); + self::assertFalse($dto->disablePayloadErrorLimit); + self::assertTrue($result->disablePayloadErrorLimit); + self::assertTrue($this->marshal($result)['DisablePayloadErrorLimit']); + } + public function testDisableRegistrationAliasing(): void { $dto = new WorkerOptions();