From c1661a4b09ef4d32197cc64286ca3a688f845136 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 9 Jan 2026 10:12:48 +0400 Subject: [PATCH 01/15] chore: show timeout exception --- tests/Acceptance/Extra/Stability/ResetWorkerTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php index 583de204..22899347 100644 --- a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php +++ b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php @@ -43,7 +43,11 @@ public function resetWithCancel( self::fail('Query must fail with a timeout'); } catch (WorkflowServiceException $e) { # Should fail with a timeout - self::assertInstanceOf(TimeoutException::class, $e->getPrevious()); + self::assertInstanceOf( + TimeoutException::class, + $e->getPrevious(), + $e->__toString(), + ); } # Cancel Workflow From 0c659c65026e838fa45810fac30a5a1f50d0d9f7 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 9 Jan 2026 12:19:08 +0400 Subject: [PATCH 02/15] chore: disable double stopping --- tests/Acceptance/App/Runtime/TemporalStarter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php index 7ef1a530..395312f2 100644 --- a/tests/Acceptance/App/Runtime/TemporalStarter.php +++ b/tests/Acceptance/App/Runtime/TemporalStarter.php @@ -16,7 +16,6 @@ final class TemporalStarter public function __construct() { $this->environment = Environment::create(); - \register_shutdown_function(fn() => $this->stop()); } public function start(): void From 18e844630d0fd7fbaf66f2ed7372c69d506bb5da Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 9 Jan 2026 12:24:15 +0400 Subject: [PATCH 03/15] chore: verbose output --- tests/Acceptance/Extra/Stability/ResetWorkerTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php index 22899347..a5863958 100644 --- a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php +++ b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php @@ -87,7 +87,11 @@ public function resetWithSignal( self::fail('Query must fail with a timeout'); } catch (WorkflowServiceException $e) { # Should fail with a timeout - self::assertInstanceOf(TimeoutException::class, $e->getPrevious()); + self::assertInstanceOf( + TimeoutException::class, + $e->getPrevious(), + $e->__toString(), + ); } $stub->signal('exit'); From 2c7264550c2d292606d301cacb1ec9b635a8468f Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 21:38:46 +0400 Subject: [PATCH 04/15] test: increase timeout for deployment test --- tests/Acceptance/Extra/Versioning/DeploymentTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Acceptance/Extra/Versioning/DeploymentTest.php b/tests/Acceptance/Extra/Versioning/DeploymentTest.php index 7662b223..9060d3ea 100644 --- a/tests/Acceptance/Extra/Versioning/DeploymentTest.php +++ b/tests/Acceptance/Extra/Versioning/DeploymentTest.php @@ -207,7 +207,7 @@ public static function setCurrentDeployment(TemporalStarter $starter): void '--deployment-name', WorkerFactory::DEPLOYMENT_NAME, '--build-id', WorkerFactory::BUILD_ID, '--yes', - ], timeout: 5); + ], timeout: 6); } } From be1cb208183cea035b36fd13d7323be19cf2abea Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 21:45:45 +0400 Subject: [PATCH 05/15] test: unblock test retryableException --- tests/Acceptance/Harness/Update/TaskFailureTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Acceptance/Harness/Update/TaskFailureTest.php b/tests/Acceptance/Harness/Update/TaskFailureTest.php index 8db8a912..5b34acce 100644 --- a/tests/Acceptance/Harness/Update/TaskFailureTest.php +++ b/tests/Acceptance/Harness/Update/TaskFailureTest.php @@ -21,8 +21,6 @@ class TaskFailureTest extends TestCase public static function retryableException( #[Stub('Harness_Update_TaskFailure')] WorkflowStubInterface $stub, ): void { - self::markTestSkipped('Todo: doesnt pass in some cases'); - try { $stub->update('do_update'); throw new \RuntimeException('Expected validation exception'); From 00ce4e89bacaa52c79e1cc801e884ea50a3e39f5 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 21:47:21 +0400 Subject: [PATCH 06/15] test: unblock test checkPreventClose --- tests/Acceptance/Harness/Signal/PreventCloseTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Acceptance/Harness/Signal/PreventCloseTest.php b/tests/Acceptance/Harness/Signal/PreventCloseTest.php index 23128ebd..aa6d7f82 100644 --- a/tests/Acceptance/Harness/Signal/PreventCloseTest.php +++ b/tests/Acceptance/Harness/Signal/PreventCloseTest.php @@ -36,8 +36,6 @@ public static function checkSignalOutOfExecution( public static function checkPreventClose( #[Stub('Harness_Signal_PreventClose')]WorkflowStubInterface $stub, ): void { - self::markTestSkipped('research a better way'); - $stub->signal('add', 1); // Wait that the first signal is processed From 06d43b562378264878d2ca8c11c28b36cc022db0 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 22:17:03 +0400 Subject: [PATCH 07/15] feat: log shutdown callbacks errors --- tests/Acceptance/App/Runtime/RRStarter.php | 9 ++++++++- tests/Acceptance/App/Runtime/TemporalStarter.php | 10 ++++++++-- tests/Functional/bootstrap.php | 8 +++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index 5169560f..9ab4688c 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -16,7 +16,14 @@ public function __construct( private State $runtime, ) { $this->environment = Environment::create(); - \register_shutdown_function(fn() => $this->stop()); + $starter = $this; + \register_shutdown_function(static function () use ($starter): void { + try { + $starter->stop(); + } catch (\Throwable $e) { + echo $e; + } + }); } public function start(): void diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php index 7ef1a530..5e3d2711 100644 --- a/tests/Acceptance/App/Runtime/TemporalStarter.php +++ b/tests/Acceptance/App/Runtime/TemporalStarter.php @@ -4,7 +4,6 @@ namespace Temporal\Tests\Acceptance\App\Runtime; -use Symfony\Component\Process\Process; use Temporal\Common\SearchAttributes\ValueType; use Temporal\Testing\Environment; @@ -16,7 +15,14 @@ final class TemporalStarter public function __construct() { $this->environment = Environment::create(); - \register_shutdown_function(fn() => $this->stop()); + $starter = $this; + \register_shutdown_function(static function () use ($starter): void { + try { + $starter->stop(); + } catch (\Throwable $e) { + echo $e; + } + }); } public function start(): void diff --git a/tests/Functional/bootstrap.php b/tests/Functional/bootstrap.php index 9726420d..5737f134 100644 --- a/tests/Functional/bootstrap.php +++ b/tests/Functional/bootstrap.php @@ -30,7 +30,13 @@ ]), ])); -\register_shutdown_function(static fn() => $environment->stop()); +\register_shutdown_function(static function () use ($environment): void { + try { + $environment->stop(); + } catch (\Throwable $e) { + echo $e; + } +}); // Default feature flags FeatureFlags::$warnOnWorkflowUnfinishedHandlers = false; From b210180b3d0d883a2ce43c6c64981114b208defe Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 22:20:36 +0400 Subject: [PATCH 08/15] feat: await until temporal is ready to serve requests --- testing/src/Environment.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index e4391a98..7ca4de41 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -103,14 +103,30 @@ public function startTemporalServer( ], ); $this->temporalServerProcess->setTimeout($commandTimeout); - $this->temporalServerProcess->start(); + $temporalStarted = false; + $this->temporalServerProcess->start(function ($type, $output) use (&$temporalStarted): void { + if ($type === Process::OUT && \str_contains($output, 'Server: ')) { + $check = new Process([$this->systemInfo->temporalCliExecutable, 'operator', 'cluster', 'health']); + $check->run(); + if (\str_contains($check->getOutput(), 'SERVING')) { + $temporalStarted = true; + } + } + }); - $deadline = \microtime(true) + 1.2; - while (!$this->temporalServerProcess->isRunning() && \microtime(true) < $deadline) { - \usleep(10_000); + $deadline = \microtime(true) + $commandTimeout; + while (!$temporalStarted && \microtime(true) < $deadline) { + \usleep(50_000); + if (!$temporalStarted) { + $check = new Process([$this->systemInfo->temporalCliExecutable, 'operator', 'cluster', 'health']); + $check->run(); + if (\str_contains($check->getOutput(), 'SERVING')) { + $temporalStarted = true; + } + } } - if (!$this->temporalServerProcess->isRunning()) { + if (!$temporalStarted || !$this->temporalServerProcess->isRunning()) { $this->output->writeln('error'); $this->output->writeln('Error starting Temporal server: ' . $this->temporalServerProcess->getErrorOutput()); exit(1); From 61cc49c8af8239fa971efbbc503060214f8817f6 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 22:46:55 +0400 Subject: [PATCH 09/15] feat: check test function output --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 73c535ae..a7964b09 100644 --- a/composer.json +++ b/composer.json @@ -99,7 +99,7 @@ "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", "test:unit": "phpunit --testsuite=Unit --color=always --testdox", - "test:func": "phpunit --testsuite=Functional --color=always --testdox", + "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit.log; grep -q '^OK (' ./runtime/phpunit.log && exit 0 || exit 1", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox" }, From 777bae5e7895969ad2aca132be81c5856e7cf85f Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 23:05:59 +0400 Subject: [PATCH 10/15] refactor: use conditional logic --- .../Acceptance/App/Feature/WorkflowStubInjector.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/Acceptance/App/Feature/WorkflowStubInjector.php b/tests/Acceptance/App/Feature/WorkflowStubInjector.php index cc639b7b..261a38b8 100644 --- a/tests/Acceptance/App/Feature/WorkflowStubInjector.php +++ b/tests/Acceptance/App/Feature/WorkflowStubInjector.php @@ -45,10 +45,14 @@ public function createInjection( ->withRetryOptions($attribute->retryOptions) ->withEagerStart($attribute->eagerStart); - $attribute->workflowId === null or $options = $options - ->withWorkflowId($attribute->workflowId) - ->withWorkflowIdReusePolicy(IdReusePolicy::AllowDuplicate); - $attribute->memo === [] or $options = $options->withMemo($attribute->memo); + if ($attribute->workflowId !== null) { + $options = $options + ->withWorkflowId($attribute->workflowId) + ->withWorkflowIdReusePolicy(IdReusePolicy::AllowDuplicate); + } + if (!empty($attribute->memo)) { + $options = $options->withMemo($attribute->memo); + } $stub = $client->newUntypedWorkflowStub($attribute->type, $options); $run = $client->start($stub, ...$attribute->args); From 58adfd7a9b1c30b3e06029c7bd3004cd73f99618 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 23:06:12 +0400 Subject: [PATCH 11/15] refactor: use while loop instead of goto --- .../App/Feature/WorkflowStubInjector.php | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/Acceptance/App/Feature/WorkflowStubInjector.php b/tests/Acceptance/App/Feature/WorkflowStubInjector.php index 261a38b8..01a5c06e 100644 --- a/tests/Acceptance/App/Feature/WorkflowStubInjector.php +++ b/tests/Acceptance/App/Feature/WorkflowStubInjector.php @@ -59,20 +59,22 @@ public function createInjection( // Wait 5 seconds for the workflow to start $deadline = \microtime(true) + 5; - checkStart: - $description = $run->describe(); - if ($description->info->historyLength <= 2) { - if (\microtime(true) < $deadline) { - goto checkStart; + while (true) { + $description = $run->describe(); + if ($description->info->historyLength > 2) { + break; } - throw new \RuntimeException( - \sprintf( - 'Workflow %s did not start. TaskQueue: %s', - $attribute->type, - $feature->taskQueue, - ), - ); + if (\microtime(true) >= $deadline) { + throw new \RuntimeException( + \sprintf( + 'Workflow %s did not start. WorkflowOptions: %s. WorkflowInfo: %s', + $attribute->type, + \json_encode($options, JSON_PRETTY_PRINT), + \print_r($description->info, true), + ), + ); + } } return $stub; From cc0063f71f5b6c1e9326c20f698c8496562da6d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Wed, 28 Jan 2026 23:08:25 +0400 Subject: [PATCH 12/15] refactor: call phpunit with exit --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a7964b09..7048dae2 100644 --- a/composer.json +++ b/composer.json @@ -99,7 +99,7 @@ "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", "test:unit": "phpunit --testsuite=Unit --color=always --testdox", - "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit.log; grep -q '^OK (' ./runtime/phpunit.log && exit 0 || exit 1", + "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit.log | grep -q '^OK' && exit 0 || exit $code", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox" }, From 0903c7216793330591789637d47edb19d6c21161 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 10:35:01 +0400 Subject: [PATCH 13/15] refactor: call phpunit with exit --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 7048dae2..37564366 100644 --- a/composer.json +++ b/composer.json @@ -98,10 +98,10 @@ "cs:fix": "php-cs-fixer fix -v", "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", - "test:unit": "phpunit --testsuite=Unit --color=always --testdox", - "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit.log | grep -q '^OK' && exit 0 || exit $code", + "test:unit": "phpunit --testsuite=Unit --color=always --testdox 2>&1 | tee ./runtime/phpunit-unit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-unit.log | grep -q '^OK' && exit 0 || exit $code", + "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit-functional.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-functional.log | grep -q '^OK' && exit 0 || exit $code", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", - "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox" + "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox 2>&1 | tee ./runtime/phpunit-acceptance.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-acceptance.log | grep -q '^OK' && exit 0 || exit $code", }, "config": { "sort-packages": true, From 06c56015f2bd704f9f330631b2ba658d1c76a177 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 10:35:01 +0400 Subject: [PATCH 14/15] refactor: call phpunit with exit --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 7048dae2..4a017164 100644 --- a/composer.json +++ b/composer.json @@ -98,10 +98,10 @@ "cs:fix": "php-cs-fixer fix -v", "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", - "test:unit": "phpunit --testsuite=Unit --color=always --testdox", - "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit.log | grep -q '^OK' && exit 0 || exit $code", + "test:unit": "phpunit --testsuite=Unit --color=always --testdox 2>&1 | tee ./runtime/phpunit-unit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-unit.log | grep -q '^OK' && exit 0 || exit $code", + "test:func": "phpunit --testsuite=Functional --color=always --testdox 2>&1 | tee ./runtime/phpunit-functional.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-functional.log | grep -q '^OK' && exit 0 || exit $code", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", - "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox" + "test:accept": "phpunit --testsuite=Acceptance --color=always --testdox 2>&1 | tee ./runtime/phpunit-acceptance.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-acceptance.log | grep -q '^OK' && exit 0 || exit $code" }, "config": { "sort-packages": true, From 9fc0ff9d24367d37a113d5489a05aaddb0a670a3 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 10:39:24 +0400 Subject: [PATCH 15/15] refactor: up symfony process --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4a017164..6a702664 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0 || ^8.0", "symfony/http-client": "^5.4.49 || ^6.4.17 || ^7.0 || ^8.0", "symfony/polyfill-php83": "^1.31.0", - "symfony/process": "^5.4.47 || ^6.4.15 || ^7.0 || ^8.0" + "symfony/process": "^5.4.51 || ^6.4.15 || ^7.0 || ^8.0" }, "autoload": { "psr-4": {