From 1ac9c237a0718f1a5e378b98b7fc1e1f7ef4a4b1 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 13:28:15 +0400 Subject: [PATCH 01/48] fix: use 127.0.0.1 instead of localhost for temporal address --- testing/README.md | 4 ++-- testing/src/Command.php | 2 +- tests/.rr.yaml | 2 +- tests/Acceptance/.rr.yaml | 2 +- tests/Acceptance/App/Runtime/State.php | 2 +- tests/Functional/.rr.silent.yaml | 2 +- tests/Functional/Client/AbstractClient.php | 2 +- tests/Functional/HistoryLengthWorkflowTestCase.php | 2 +- tests/Functional/Interceptor/AbstractClient.php | 2 +- tests/Functional/NamedArgumentsTestCase.php | 2 +- tests/Functional/SimpleWorkflowTestCase.php | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/testing/README.md b/testing/README.md index 0adcecab2..ab125de16 100644 --- a/testing/README.md +++ b/testing/README.md @@ -139,7 +139,7 @@ workflow has a timer, the server doesn't wait for it and continues immediately. this behaviour you can use `TestService` class: ```php -$testService = TestService::create('localhost:7233'); +$testService = TestService::create('127.0.0.1:7233'); $testService->lockTimeSkipping(); // ... @@ -217,7 +217,7 @@ final class SimpleWorkflowTestCase extends TestCase protected function setUp(): void { - $this->workflowClient = new WorkflowClient(ServiceClient::create('localhost:7233')); + $this->workflowClient = new WorkflowClient(ServiceClient::create('127.0.0.1:7233')); $this->activityMocks = new ActivityMocker(); parent::setUp(); diff --git a/testing/src/Command.php b/testing/src/Command.php index 1ed70d88d..7d71839c4 100644 --- a/testing/src/Command.php +++ b/testing/src/Command.php @@ -25,7 +25,7 @@ public static function fromEnv(): self $self = new self(); $self->namespace = \getenv('TEMPORAL_NAMESPACE') ?: 'default'; - $self->address = \getenv('TEMPORAL_ADDRESS') ?: 'localhost:7233'; + $self->address = \getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233'; $self->xdebug = [ 'xdebug.mode' => \ini_get('xdebug.mode'), 'xdebug.start_with_request' => \ini_get('xdebug.start_with_request'), diff --git a/tests/.rr.yaml b/tests/.rr.yaml index 112c1ab3d..0048694bd 100644 --- a/tests/.rr.yaml +++ b/tests/.rr.yaml @@ -10,7 +10,7 @@ server: # Workflow and activity mesh service temporal: - address: "localhost:7233" + address: "127.0.0.1:7233" activities: num_workers: 4 debug_level: 2 diff --git a/tests/Acceptance/.rr.yaml b/tests/Acceptance/.rr.yaml index 2271a06fc..dbe2cd601 100644 --- a/tests/Acceptance/.rr.yaml +++ b/tests/Acceptance/.rr.yaml @@ -7,7 +7,7 @@ server: # Workflow and activity mesh service temporal: - address: ${TEMPORAL_ADDRESS:-localhost:7233} + address: ${TEMPORAL_ADDRESS:-127.0.0.1:7233} namespace: ${TEMPORAL_NAMESPACE:-default} activities: num_workers: 2 diff --git a/tests/Acceptance/App/Runtime/State.php b/tests/Acceptance/App/Runtime/State.php index c4b14d662..1fe42ddba 100644 --- a/tests/Acceptance/App/Runtime/State.php +++ b/tests/Acceptance/App/Runtime/State.php @@ -30,7 +30,7 @@ public function __construct( public readonly iterable $testCasesDir, ) { $this->namespace = $command->namespace ?? 'default'; - $this->address = $command->address ?? 'localhost:7233'; + $this->address = $command->address ?? '127.0.0.1:7233'; } /** diff --git a/tests/Functional/.rr.silent.yaml b/tests/Functional/.rr.silent.yaml index 5c8c91067..c8aa584fd 100644 --- a/tests/Functional/.rr.silent.yaml +++ b/tests/Functional/.rr.silent.yaml @@ -8,7 +8,7 @@ server: # Workflow and activity mesh service temporal: - address: "localhost:7233" + address: "127.0.0.1:7233" activities: num_workers: 1 diff --git a/tests/Functional/Client/AbstractClient.php b/tests/Functional/Client/AbstractClient.php index 6342207ed..6734159bd 100644 --- a/tests/Functional/Client/AbstractClient.php +++ b/tests/Functional/Client/AbstractClient.php @@ -28,7 +28,7 @@ abstract class AbstractClient extends AbstractFunctional * @param string $connection * @return WorkflowClient */ - protected function createClient(string $connection = 'localhost:7233'): WorkflowClient + protected function createClient(string $connection = '127.0.0.1:7233'): WorkflowClient { return new WorkflowClient( ServiceClient::create($connection) diff --git a/tests/Functional/HistoryLengthWorkflowTestCase.php b/tests/Functional/HistoryLengthWorkflowTestCase.php index c8a5b91db..153aa426c 100644 --- a/tests/Functional/HistoryLengthWorkflowTestCase.php +++ b/tests/Functional/HistoryLengthWorkflowTestCase.php @@ -18,7 +18,7 @@ final class HistoryLengthWorkflowTestCase extends TestCase protected function setUp(): void { $this->workflowClient = new WorkflowClient( - ServiceClient::create('localhost:7233') + ServiceClient::create('127.0.0.1:7233') ); $this->activityMocks = new ActivityMocker(); diff --git a/tests/Functional/Interceptor/AbstractClient.php b/tests/Functional/Interceptor/AbstractClient.php index 5853062b8..042a9eae7 100644 --- a/tests/Functional/Interceptor/AbstractClient.php +++ b/tests/Functional/Interceptor/AbstractClient.php @@ -26,7 +26,7 @@ abstract class AbstractClient extends AbstractFunctional * @param string $connection * @return WorkflowClient */ - protected function createClient(string $connection = 'localhost:7233'): WorkflowClient + protected function createClient(string $connection = '127.0.0.1:7233'): WorkflowClient { return new WorkflowClient( ServiceClient::create($connection), diff --git a/tests/Functional/NamedArgumentsTestCase.php b/tests/Functional/NamedArgumentsTestCase.php index 58ca91933..3da8bb410 100644 --- a/tests/Functional/NamedArgumentsTestCase.php +++ b/tests/Functional/NamedArgumentsTestCase.php @@ -24,7 +24,7 @@ final class NamedArgumentsTestCase extends TestCase protected function setUp(): void { $this->workflowClient = new WorkflowClient( - ServiceClient::create('localhost:7233') + ServiceClient::create('127.0.0.1:7233') ); parent::setUp(); diff --git a/tests/Functional/SimpleWorkflowTestCase.php b/tests/Functional/SimpleWorkflowTestCase.php index 19b6901f5..dfbeec033 100644 --- a/tests/Functional/SimpleWorkflowTestCase.php +++ b/tests/Functional/SimpleWorkflowTestCase.php @@ -130,7 +130,7 @@ public function testWorkflowMethodInAbstractParent(): void protected function setUp(): void { $this->workflowClient = new WorkflowClient( - ServiceClient::create('localhost:7233'), + ServiceClient::create('127.0.0.1:7233'), ); $this->activityMocks = new ActivityMocker(); From df00dd9167163b266557dc60ee769b8a0243923d Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 13:32:47 +0400 Subject: [PATCH 02/48] fix: upgrade symfony/process lowest version to 5.4.51 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 73c535ae4..2fcd28a57 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": { From d4f381eb62497dd97ef8f96c0d757aa93e364108 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 13:48:11 +0400 Subject: [PATCH 03/48] test: handle non-zero exit codes when tests succeed --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 2fcd28a57..56bcb855f 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", + "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 -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && 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 -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && 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 -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && exit 0 || exit $code" }, "config": { "sort-packages": true, From 47d5107b4a56b3069c849c8654e7fde6eec1491a Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 14:06:30 +0400 Subject: [PATCH 04/48] test: add test runner --- composer.json | 7 ++++--- tests/ci-runner.php | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 tests/ci-runner.php diff --git a/composer.json b/composer.json index 56bcb855f..1b3cf7cbb 100644 --- a/composer.json +++ b/composer.json @@ -56,6 +56,7 @@ ] }, "require-dev": { + "ext-simplexml": "*", "buggregator/trap": "^1.13.0", "composer/composer": "^2.8.4", "cweagans/composer-patches": "^2.0", @@ -98,10 +99,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 2>&1 | tee ./runtime/phpunit-unit.log; code=$?; sed 's/\\x1b\\[[0-9;]*m//g' ./runtime/phpunit-unit.log | grep -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && 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 -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && exit 0 || exit $code", + "test:unit": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Unit --color=always --testdox", + "test:func": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Functional --color=always --testdox", "test:arch": "phpunit --testsuite=Arch --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 -qE '^OK \\([0-9]+ tests?, [0-9]+ assertions?\\)|^OK, but some tests were skipped!' && exit 0 || exit $code" + "test:accept": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Acceptance --color=always --testdox" }, "config": { "sort-packages": true, diff --git a/tests/ci-runner.php b/tests/ci-runner.php new file mode 100644 index 000000000..0244294b9 --- /dev/null +++ b/tests/ci-runner.php @@ -0,0 +1,24 @@ +&1", $code); + +if (\file_exists($logFile)) { + $xml = \simplexml_load_file($logFile); + $failures = (int) $xml['failures'] + (int) $xml['errors']; + + if ($failures === 0) { + exit(0); + } +} + +exit($code ?: 1); From 414cc4f786a3f959d35791ca3d784365449bf4b5 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 14:09:40 +0400 Subject: [PATCH 05/48] test: windows suitable path --- composer.json | 6 +++--- tests/ci-runner.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 1b3cf7cbb..8e09d710f 100644 --- a/composer.json +++ b/composer.json @@ -99,10 +99,10 @@ "cs:fix": "php-cs-fixer fix -v", "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", - "test:unit": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Unit --color=always --testdox", - "test:func": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Functional --color=always --testdox", + "test:unit": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Unit --color=always --testdox", + "test:func": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Functional --color=always --testdox", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", - "test:accept": "php tests/ci-runner.php ./vendor/bin/phpunit --testsuite=Acceptance --color=always --testdox" + "test:accept": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Acceptance --color=always --testdox" }, "config": { "sort-packages": true, diff --git a/tests/ci-runner.php b/tests/ci-runner.php index 0244294b9..a668dbf20 100644 --- a/tests/ci-runner.php +++ b/tests/ci-runner.php @@ -8,7 +8,7 @@ */ $command = \implode(' ', \array_slice($argv, 1)); -$logFile = './runtime/phpunit.xml'; +$logFile = 'runtime/phpunit.xml'; \passthru("$command --log-junit=$logFile 2>&1", $code); From 850e016e426d1dd9c991d86abc1456c1b185e374 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 14:13:51 +0400 Subject: [PATCH 06/48] test: pass php exucutable --- tests/ci-runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ci-runner.php b/tests/ci-runner.php index a668dbf20..26e0d1193 100644 --- a/tests/ci-runner.php +++ b/tests/ci-runner.php @@ -10,7 +10,7 @@ $command = \implode(' ', \array_slice($argv, 1)); $logFile = 'runtime/phpunit.xml'; -\passthru("$command --log-junit=$logFile 2>&1", $code); +\passthru("php $command --log-junit=$logFile 2>&1", $code); if (\file_exists($logFile)) { $xml = \simplexml_load_file($logFile); From 6ca7592aac89e10475691c3126daa76e84546c5b Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 14:19:57 +0400 Subject: [PATCH 07/48] test: fix xml element access --- tests/ci-runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ci-runner.php b/tests/ci-runner.php index 26e0d1193..155f75879 100644 --- a/tests/ci-runner.php +++ b/tests/ci-runner.php @@ -14,7 +14,7 @@ if (\file_exists($logFile)) { $xml = \simplexml_load_file($logFile); - $failures = (int) $xml['failures'] + (int) $xml['errors']; + $failures = (int) $xml->testsuite['failures'] + (int) $xml->testsuite['errors']; if ($failures === 0) { exit(0); From ff10ea996667aad6c142ad05f5d93f5913ae0534 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 14:24:25 +0400 Subject: [PATCH 08/48] test: use PHP_BINARY for passing php executable to passthru command --- tests/ci-runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ci-runner.php b/tests/ci-runner.php index 155f75879..bc0b26eee 100644 --- a/tests/ci-runner.php +++ b/tests/ci-runner.php @@ -10,7 +10,7 @@ $command = \implode(' ', \array_slice($argv, 1)); $logFile = 'runtime/phpunit.xml'; -\passthru("php $command --log-junit=$logFile 2>&1", $code); +\passthru(\sprintf("%s %s --log-junit=%s 2>&1", PHP_BINARY, $command, $logFile), $code); if (\file_exists($logFile)) { $xml = \simplexml_load_file($logFile); From f059e4af60fd610ff32dc39ec66c2c45126419ce Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 15:32:11 +0400 Subject: [PATCH 09/48] test: rename file, add shebang --- composer.json | 6 +++--- tests/{ci-runner.php => runner.php} | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) rename tests/{ci-runner.php => runner.php} (96%) mode change 100644 => 100755 diff --git a/composer.json b/composer.json index 8e09d710f..e9fba1200 100644 --- a/composer.json +++ b/composer.json @@ -99,10 +99,10 @@ "cs:fix": "php-cs-fixer fix -v", "psalm": "psalm", "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", - "test:unit": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Unit --color=always --testdox", - "test:func": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Functional --color=always --testdox", + "test:unit": "tests/runner.php vendor/bin/phpunit --testsuite=Unit --color=always --testdox", + "test:func": "tests/runner.php vendor/bin/phpunit --testsuite=Functional --color=always --testdox", "test:arch": "phpunit --testsuite=Arch --color=always --testdox", - "test:accept": "php tests/ci-runner.php vendor/bin/phpunit --testsuite=Acceptance --color=always --testdox" + "test:accept": "tests/runner.php vendor/bin/phpunit --testsuite=Acceptance --color=always --testdox" }, "config": { "sort-packages": true, diff --git a/tests/ci-runner.php b/tests/runner.php old mode 100644 new mode 100755 similarity index 96% rename from tests/ci-runner.php rename to tests/runner.php index bc0b26eee..b8aabb98c --- a/tests/ci-runner.php +++ b/tests/runner.php @@ -1,3 +1,4 @@ +#!/usr/bin/env php Date: Thu, 29 Jan 2026 15:57:54 +0400 Subject: [PATCH 10/48] test: optimize deployment test by adding direct ip address --- tests/Acceptance/Extra/Versioning/DeploymentTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Acceptance/Extra/Versioning/DeploymentTest.php b/tests/Acceptance/Extra/Versioning/DeploymentTest.php index 7662b2231..08c18bc42 100644 --- a/tests/Acceptance/Extra/Versioning/DeploymentTest.php +++ b/tests/Acceptance/Extra/Versioning/DeploymentTest.php @@ -206,6 +206,7 @@ public static function setCurrentDeployment(TemporalStarter $starter): void 'set-current-version', '--deployment-name', WorkerFactory::DEPLOYMENT_NAME, '--build-id', WorkerFactory::BUILD_ID, + '--address', '127.0.0.1:7233', '--yes', ], timeout: 5); } From cdb96734a8a1827a87bb96dbb9503cd4e96aa3d5 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 17:10:13 +0400 Subject: [PATCH 11/48] refactor: re-use common temporal address in tests --- testing/src/Command.php | 62 +++++++++++-------- testing/src/Environment.php | 26 +++++--- .../Acceptance/App/Feature/ClientFactory.php | 4 +- tests/Acceptance/App/Runtime/RRStarter.php | 3 +- tests/Acceptance/App/Runtime/State.php | 2 +- .../App/Runtime/TemporalStarter.php | 14 +---- .../Extra/Versioning/DeploymentTest.php | 18 ++++-- tests/Acceptance/bootstrap.php | 11 ++-- tests/Functional/Client/TypedStubTestCase.php | 4 +- 9 files changed, 83 insertions(+), 61 deletions(-) diff --git a/testing/src/Command.php b/testing/src/Command.php index 7d71839c4..b8b93f6e3 100644 --- a/testing/src/Command.php +++ b/testing/src/Command.php @@ -9,8 +9,10 @@ final class Command /** @var non-empty-string|null Temporal Namespace */ public ?string $namespace = null; - /** @var non-empty-string|null Temporal Address */ - public ?string $address = null; + /** + * @var non-empty-string Temporal Address + */ + public string $address; /** @var non-empty-string|null */ public ?string $tlsKey = null; @@ -20,12 +22,17 @@ final class Command private array $xdebug; + public function __construct( + string $address, + ) { + $this->address = $address; + } + public static function fromEnv(): self { - $self = new self(); + $self = new self(\getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233'); $self->namespace = \getenv('TEMPORAL_NAMESPACE') ?: 'default'; - $self->address = \getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233'; $self->xdebug = [ 'xdebug.mode' => \ini_get('xdebug.mode'), 'xdebug.start_with_request' => \ini_get('xdebug.start_with_request'), @@ -42,30 +49,35 @@ public static function fromEnv(): self */ public static function fromCommandLine(array $argv): self { - $self = new self(); - - \array_shift($argv); // remove the script name (worker.php or runner.php) - foreach ($argv as $chunk) { - if (\str_starts_with($chunk, 'namespace=')) { - $self->namespace = \substr($chunk, 10); - continue; - } - - if (\str_starts_with($chunk, 'address=')) { - $self->address = \substr($chunk, 8); - continue; + $address = ''; + $namespace = ''; + $tlsCert = ''; + $tlsKey = ''; + + // remove the script name (worker.php or runner.php) + $chunks = \array_slice($argv, 1); + foreach ($chunks as $chunk) { + switch (true) { + case \str_starts_with($chunk, 'namespace='): + $namespace = \substr($chunk, 10); + break; + case \str_starts_with($chunk, 'address='): + $address = \substr($chunk, 8); + break; + case \str_starts_with($chunk, 'tls.cert='): + $tlsCert = \substr($chunk, 9); + break; + case \str_starts_with($chunk, 'tls.key='): + $tlsKey = \substr($chunk, 8); + break; } + } - if (\str_starts_with($chunk, 'tls.cert=')) { - $self->tlsCert = \substr($chunk, 9); - continue; - } + $self = new self($address); - if (\str_starts_with($chunk, 'tls.key=')) { - $self->tlsKey = \substr($chunk, 8); - continue; - } - } + $self->namespace = $namespace; + $self->tlsCert = $tlsCert; + $self->tlsKey = $tlsKey; return $self; } diff --git a/testing/src/Environment.php b/testing/src/Environment.php index e4391a98f..103d7de50 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -13,6 +13,11 @@ final class Environment { + /** + * @readonly + */ + public Command $command; + private Downloader $downloader; private Output $output; private SystemInfo $systemInfo; @@ -20,14 +25,19 @@ final class Environment private ?Process $temporalServerProcess = null; private ?Process $roadRunnerProcess = null; - public function __construct(Output $output, Downloader $downloader, SystemInfo $systemInfo) - { + public function __construct( + Output $output, + Downloader $downloader, + SystemInfo $systemInfo, + Command $command, + ) { $this->downloader = $downloader; $this->systemInfo = $systemInfo; $this->output = $output; + $this->command = $command; } - public static function create(): self + public static function create(?Command $command = null): self { $token = \getenv('GITHUB_TOKEN'); @@ -42,6 +52,7 @@ public static function create(): self ], ])), $info, + $command ?? Command::fromEnv(), ); } @@ -64,7 +75,7 @@ public function startTemporalServer( array $parameters = [], array $searchAttributes = [], ): void { - $temporalPort = \parse_url(\getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233', PHP_URL_PORT); + $temporalPort = \parse_url($this->command->address, PHP_URL_PORT); // Add search attributes foreach ($searchAttributes as $name => $type) { @@ -91,7 +102,7 @@ public function startTemporalServer( }; } - $this->output->write('Starting Temporal test server... '); + $this->output->write('Starting Temporal server... '); $this->temporalServerProcess = new Process( [ $this->systemInfo->temporalCliExecutable, @@ -126,7 +137,7 @@ public function startTemporalTestServer(int $commandTimeout = 10): void $this->output->writeln('done.'); } - $temporalPort = \parse_url(\getenv('TEMPORAL_ADDRESS') ?: '127.0.0.1:7233', PHP_URL_PORT); + $temporalPort = \parse_url($this->command->address, PHP_URL_PORT); $this->output->write('Starting Temporal test server... '); $this->temporalTestServerProcess = new Process( @@ -208,9 +219,6 @@ public function stop(): void } } - /** - * @internal - */ public function executeTemporalCommand(array|string $command, int $timeout = 10): void { $command = \array_merge( diff --git a/tests/Acceptance/App/Feature/ClientFactory.php b/tests/Acceptance/App/Feature/ClientFactory.php index d645f3e30..94bb66b6f 100644 --- a/tests/Acceptance/App/Feature/ClientFactory.php +++ b/tests/Acceptance/App/Feature/ClientFactory.php @@ -82,9 +82,7 @@ public function workflowClient(\ReflectionParameter $context): WorkflowClientInt options: (new ClientOptions())->withNamespace($runtime->namespace), converter: $converter, interceptorProvider: $pipelineProvider, - )->withTimeout(5); - - $attribute->timeout === null or $client = $client->withTimeout($attribute->timeout); + )->withTimeout($attribute->timeout ?? 5); return $client; } diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index 5169560fc..dd8dafa72 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -9,13 +9,12 @@ final class RRStarter { - private Environment $environment; private bool $started = false; public function __construct( private State $runtime, + private Environment $environment, ) { - $this->environment = Environment::create(); \register_shutdown_function(fn() => $this->stop()); } diff --git a/tests/Acceptance/App/Runtime/State.php b/tests/Acceptance/App/Runtime/State.php index 1fe42ddba..d58afea93 100644 --- a/tests/Acceptance/App/Runtime/State.php +++ b/tests/Acceptance/App/Runtime/State.php @@ -30,7 +30,7 @@ public function __construct( public readonly iterable $testCasesDir, ) { $this->namespace = $command->namespace ?? 'default'; - $this->address = $command->address ?? '127.0.0.1:7233'; + $this->address = $command->address; } /** diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php index 7ef1a530b..36b14e2d5 100644 --- a/tests/Acceptance/App/Runtime/TemporalStarter.php +++ b/tests/Acceptance/App/Runtime/TemporalStarter.php @@ -10,12 +10,12 @@ final class TemporalStarter { - private Environment $environment; private bool $started = false; - public function __construct() + public function __construct( + private Environment $environment, + ) { - $this->environment = Environment::create(); \register_shutdown_function(fn() => $this->stop()); } @@ -50,14 +50,6 @@ public function start(): void $this->started = true; } - public function executeTemporalCommand(array|string $command, int $timeout = 10): void - { - $this->environment->executeTemporalCommand( - command: $command, - timeout: $timeout, - ); - } - /** * @return bool Returns true if the server was stopped successfully, false if it was not started. */ diff --git a/tests/Acceptance/Extra/Versioning/DeploymentTest.php b/tests/Acceptance/Extra/Versioning/DeploymentTest.php index 08c18bc42..90d477c38 100644 --- a/tests/Acceptance/Extra/Versioning/DeploymentTest.php +++ b/tests/Acceptance/Extra/Versioning/DeploymentTest.php @@ -11,6 +11,7 @@ use Temporal\Common\Versioning\VersioningBehavior; use Temporal\Common\Versioning\VersioningOverride; use Temporal\Common\Versioning\WorkerDeploymentVersion; +use Temporal\Testing\Environment; use Temporal\Tests\Acceptance\App\Attribute\Worker; use Temporal\Tests\Acceptance\App\Runtime\Feature; use Temporal\Tests\Acceptance\App\Runtime\TemporalStarter; @@ -26,11 +27,13 @@ class DeploymentTest extends TestCase { #[Test] public function defaultBehaviorAuto( + Environment $environment, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $behavior = self::executeWorkflow( + $environment, $starter, $client, $feature, @@ -43,12 +46,14 @@ public function defaultBehaviorAuto( #[Test] public function customBehaviorPinned( + Environment $environment, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $id = Uuid::v4(); self::executeWorkflow( + $environment, $starter, $client, $feature, @@ -72,12 +77,14 @@ public function customBehaviorPinned( #[Test] public function versionBehaviorOverrideAutoUpgrade( + Environment $environment, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $id = Uuid::v4(); self::executeWorkflow( + $environment, $starter, $client, $feature, @@ -101,11 +108,13 @@ public function versionBehaviorOverrideAutoUpgrade( #[Test] public function versionBehaviorOverridePinned( + Environment $environment, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $behavior = self::executeWorkflow( + $environment, $starter, $client, $feature, @@ -127,6 +136,7 @@ public function versionBehaviorOverridePinned( * @param null|callable(VersioningBehavior): void $postAction */ private static function executeWorkflow( + Environment $environment, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, @@ -134,7 +144,7 @@ private static function executeWorkflow( WorkflowOptions $options, ?callable $postAction = null, ): ?VersioningBehavior { - WorkerFactory::setCurrentDeployment($starter); + WorkerFactory::setCurrentDeployment($environment); try { # Create a Workflow stub with an execution timeout 12 seconds @@ -198,15 +208,15 @@ public static function options(): WorkerOptions ); } - public static function setCurrentDeployment(TemporalStarter $starter): void + public static function setCurrentDeployment(Environment $environment): void { - $starter->executeTemporalCommand([ + $environment->executeTemporalCommand([ 'worker', 'deployment', 'set-current-version', '--deployment-name', WorkerFactory::DEPLOYMENT_NAME, '--build-id', WorkerFactory::BUILD_ID, - '--address', '127.0.0.1:7233', + '--address', $environment->command->address, '--yes', ], timeout: 5); } diff --git a/tests/Acceptance/bootstrap.php b/tests/Acceptance/bootstrap.php index 09faf6bed..532c145df 100644 --- a/tests/Acceptance/bootstrap.php +++ b/tests/Acceptance/bootstrap.php @@ -19,6 +19,7 @@ use Temporal\DataConverter\DataConverter; use Temporal\DataConverter\DataConverterInterface; use Temporal\Testing\Command; +use Temporal\Testing\Environment; use Temporal\Tests\Acceptance\App\Feature\WorkflowStubInjector; use Temporal\Tests\Acceptance\App\Runtime\ContainerFacade; use Temporal\Tests\Acceptance\App\Runtime\RRStarter; @@ -39,8 +40,9 @@ ]); # Run RoadRunner and Temporal -$temporalRunner = new TemporalStarter(); -$rrRunner = new RRStarter($runtime); +$environment = Environment::create($command); +$temporalRunner = new TemporalStarter($environment); +$rrRunner = new RRStarter($runtime, $environment); $temporalRunner->start(); $rrRunner->start(); @@ -59,7 +61,7 @@ try { $serviceClient->getConnection()->connect(5); echo "\e[1;32mOK\e[0m\n"; -} catch (\Throwable $e) { +} catch (Throwable $e) { echo "\e[1;31mFAILED\e[0m\n"; Support::echoException($e); return; @@ -86,6 +88,7 @@ $container->bindSingleton(State::class, $runtime); $container->bindSingleton(RRStarter::class, $rrRunner); $container->bindSingleton(TemporalStarter::class, $temporalRunner); +$container->bindSingleton(Environment::class, $environment); $container->bindSingleton(ServiceClientInterface::class, $serviceClient); $container->bindSingleton(WorkflowClientInterface::class, $workflowClient); $container->bindSingleton(ScheduleClientInterface::class, $scheduleClient); @@ -94,5 +97,5 @@ $container->bind(RPCInterface::class, static fn() => RPC::create(\getenv('RR_RPC_ADDRESS') ?: 'tcp://127.0.0.1:6001')); $container->bind( StorageInterface::class, - static fn(#[Proxy] ContainerInterface $c): StorageInterface => $c->get(Factory::class)->select('harness'), + static fn(#[Proxy] ContainerInterface $container): StorageInterface => $container->get(Factory::class)->select('harness'), ); diff --git a/tests/Functional/Client/TypedStubTestCase.php b/tests/Functional/Client/TypedStubTestCase.php index 13e3052c5..21abcc458 100644 --- a/tests/Functional/Client/TypedStubTestCase.php +++ b/tests/Functional/Client/TypedStubTestCase.php @@ -130,8 +130,8 @@ public function testGetDTOResult() public function testVoidReturnType() { - $w = $this->createClient(); - $dto = $w->newWorkflowStub(ActivityReturnTypeWorkflow::class); + $client = $this->createClient(); + $dto = $client->newWorkflowStub(ActivityReturnTypeWorkflow::class); $this->assertEquals( 100, From 8c59ed0afd3b275f00b05c9415a19913a039a05b Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 17:43:29 +0400 Subject: [PATCH 12/48] ci: fix test runner --- tests/runner.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/runner.php b/tests/runner.php index b8aabb98c..ea387161c 100755 --- a/tests/runner.php +++ b/tests/runner.php @@ -14,11 +14,13 @@ \passthru(\sprintf("%s %s --log-junit=%s 2>&1", PHP_BINARY, $command, $logFile), $code); if (\file_exists($logFile)) { - $xml = \simplexml_load_file($logFile); - $failures = (int) $xml->testsuite['failures'] + (int) $xml->testsuite['errors']; + $xml = @\simplexml_load_file($logFile); + if ($xml !== false) { + $failures = (int)$xml->testsuite['failures'] + (int)$xml->testsuite['errors']; - if ($failures === 0) { - exit(0); + if ($failures === 0) { + exit(0); + } } } From 5313f83a9d9d94f4e8a1744a197cae21222932fa Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 17:48:44 +0400 Subject: [PATCH 13/48] refactor: decompose stop method --- testing/src/Environment.php | 50 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 103d7de50..9b20a4c93 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -200,34 +200,62 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = public function stop(): void { - if ($this->temporalServerProcess !== null && $this->temporalServerProcess->isRunning()) { + $this->stopRoadRunner(); + $this->stopTemporalTestServer(); + $this->stopTemporalServer(); + } + + public function executeTemporalCommand(array|string $command, int $timeout = 10): void + { + $command = \array_merge( + [$this->systemInfo->temporalCliExecutable], + (array) $command, + ); + + $process = new Process($command); + $process->setTimeout($timeout); + $process->run(); + } + + public function stopTemporalServer(): void + { + if ($this->isTemporalRunning()) { $this->output->write('Stopping Temporal server... '); $this->temporalServerProcess->stop(); $this->output->writeln('done.'); } + } - if ($this->temporalTestServerProcess !== null && $this->temporalTestServerProcess->isRunning()) { + public function stopTemporalTestServer(): void + { + if ($this->isTemporalTestRunning()) { $this->output->write('Stopping Temporal Test server... '); $this->temporalTestServerProcess->stop(); $this->output->writeln('done.'); } + } - if ($this->roadRunnerProcess !== null && $this->roadRunnerProcess->isRunning()) { + public function stopRoadRunner(): void + { + if ($this->isRoadRunnerRunning()) { $this->output->write('Stopping RoadRunner... '); $this->roadRunnerProcess->stop(); $this->output->writeln('done.'); } } - public function executeTemporalCommand(array|string $command, int $timeout = 10): void + public function isTemporalRunning(): bool { - $command = \array_merge( - [$this->systemInfo->temporalCliExecutable], - (array) $command, - ); + return $this->temporalServerProcess?->isRunning() === true; + } - $process = new Process($command); - $process->setTimeout($timeout); - $process->run(); + public function isRoadRunnerRunning(): bool + { + return $this->roadRunnerProcess?->isRunning() === true; + } + + public function isTemporalTestRunning(): bool + { + return $this->temporalTestServerProcess?->isRunning() === true; } } From 31f3a35c8f557873f9fd6fca662517e6ea989355 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 18:30:31 +0400 Subject: [PATCH 14/48] test: dump more info when fail --- .../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 cc639b7b1..cb29c4283 100644 --- a/tests/Acceptance/App/Feature/WorkflowStubInjector.php +++ b/tests/Acceptance/App/Feature/WorkflowStubInjector.php @@ -55,20 +55,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 a6155f9027aeffa81a75f52815e44935c59e6881 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 18:33:11 +0400 Subject: [PATCH 15/48] test: pass ip when starting Temporal --- testing/src/Environment.php | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 9b20a4c93..465be46ba 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -109,6 +109,7 @@ public function startTemporalServer( "server", "start-dev", "--port", $temporalPort, '--log-level', 'error', + '--ip', $this->command->address, '--headless', ...$parameters, ], From c8bc933a67f631565da450fc3e4b7450e3a9a2d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 20:01:09 +0400 Subject: [PATCH 16/48] test: await for temporal server health check --- testing/src/Environment.php | 69 +++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 465be46ba..1cee8e0db 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -75,6 +75,7 @@ public function startTemporalServer( array $parameters = [], array $searchAttributes = [], ): void { + $temporalHost = \parse_url($this->command->address, PHP_URL_HOST); $temporalPort = \parse_url($this->command->address, PHP_URL_PORT); // Add search attributes @@ -109,23 +110,50 @@ public function startTemporalServer( "server", "start-dev", "--port", $temporalPort, '--log-level', 'error', - '--ip', $this->command->address, + '--ip', $temporalHost, '--headless', ...$parameters, ], ); $this->temporalServerProcess->setTimeout($commandTimeout); - $this->temporalServerProcess->start(); + $temporalStarted = false; + // $this->output->writeln('Running command: ' . $this->temporalServerProcess->getCommandLine()); + $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', + '--address', $this->command->address, + ]); + $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); + $this->output->writeln(\sprintf( + "Error starting Temporal server: %s.\r\nCommand: `%s`.", + !$temporalStarted ? "Health check failed" : $this->temporalServerProcess->getErrorOutput(), + $this->temporalServerProcess->getCommandLine(), + )); + throw new \RuntimeException('Temporal server failed to start.'); } $this->output->writeln('done.'); } @@ -151,8 +179,12 @@ public function startTemporalTestServer(int $commandTimeout = 10): void if (!$this->temporalTestServerProcess->isRunning()) { $this->output->writeln('error'); - $this->output->writeln('Error starting Temporal Test server: ' . $this->temporalTestServerProcess->getErrorOutput()); - exit(1); + $this->output->writeln(\sprintf( + "Error starting Temporal Test server: %s.\r\nCommand: `%s`.", + $this->temporalTestServerProcess->getErrorOutput(), + $this->temporalTestServerProcess->getCommandLine(), + )); + throw new \RuntimeException('Temporal Test server failed to start.'); } $this->output->writeln('done.'); } @@ -170,6 +202,7 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = $this->output->write('Starting RoadRunner... '); $roadRunnerStarted = false; + // $this->output->writeln('Running command: ' . $this->roadRunnerProcess->getCommandLine()); $this->roadRunnerProcess->start(static function ($type, $output) use (&$roadRunnerStarted): void { if ($type === Process::OUT && \str_contains($output, 'RoadRunner server started')) { $roadRunnerStarted = true; @@ -178,8 +211,12 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = if (!$this->roadRunnerProcess->isRunning()) { $this->output->writeln('error'); - $this->output->writeln('Error starting RoadRunner: ' . $this->roadRunnerProcess->getErrorOutput()); - exit(1); + $this->output->writeln(\sprintf( + "Error starting RoadRunner: %s.\r\nCommand: `%s`.", + $this->roadRunnerProcess->getErrorOutput(), + $this->roadRunnerProcess->getCommandLine(), + )); + throw new \RuntimeException('RoadRunner failed to start.'); } // wait for roadrunner to start @@ -192,8 +229,12 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = if (!$roadRunnerStarted) { $this->output->writeln('error'); - $this->output->writeln('Error starting RoadRunner: ' . $this->roadRunnerProcess->getErrorOutput()); - exit(1); + $this->output->writeln(\sprintf( + "Error starting RoadRunner: %s.\r\nCommand: `%s`.", + $this->roadRunnerProcess->getErrorOutput(), + $this->roadRunnerProcess->getCommandLine(), + )); + throw new \RuntimeException('RoadRunner failed to start.'); } $this->output->writeln('done.'); From 3df53ba53f82a887a10c102c4a7bd2f5437620b5 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 20:24:00 +0400 Subject: [PATCH 17/48] fix: exit from code directly --- testing/src/Environment.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 1cee8e0db..8d94a9102 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -153,7 +153,7 @@ public function startTemporalServer( !$temporalStarted ? "Health check failed" : $this->temporalServerProcess->getErrorOutput(), $this->temporalServerProcess->getCommandLine(), )); - throw new \RuntimeException('Temporal server failed to start.'); + exit(1); } $this->output->writeln('done.'); } @@ -184,7 +184,7 @@ public function startTemporalTestServer(int $commandTimeout = 10): void $this->temporalTestServerProcess->getErrorOutput(), $this->temporalTestServerProcess->getCommandLine(), )); - throw new \RuntimeException('Temporal Test server failed to start.'); + exit(1); } $this->output->writeln('done.'); } @@ -216,7 +216,7 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = $this->roadRunnerProcess->getErrorOutput(), $this->roadRunnerProcess->getCommandLine(), )); - throw new \RuntimeException('RoadRunner failed to start.'); + exit(1); } // wait for roadrunner to start @@ -234,7 +234,7 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = $this->roadRunnerProcess->getErrorOutput(), $this->roadRunnerProcess->getCommandLine(), )); - throw new \RuntimeException('RoadRunner failed to start.'); + exit(1); } $this->output->writeln('done.'); From ef8e4c9c79f21dbb558c3a746bef8f8cd62bc311 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 20:48:57 +0400 Subject: [PATCH 18/48] fix: restart RoadRunner with Temporal --- tests/Acceptance/App/Runtime/RRStarter.php | 14 ++++---------- .../Acceptance/App/Runtime/TemporalStarter.php | 15 ++++----------- tests/Acceptance/App/TestCase.php | 9 +++++---- .../Extra/Versioning/DeploymentTest.php | 17 ++++++++++++++--- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index dd8dafa72..5422a60cb 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -9,8 +9,6 @@ final class RRStarter { - private bool $started = false; - public function __construct( private State $runtime, private Environment $environment, @@ -20,7 +18,7 @@ public function __construct( public function start(): void { - if ($this->started) { + if ($this->environment->isRoadRunnerRunning()) { return; } @@ -50,18 +48,14 @@ public function start(): void // echo "\e[1;36mStart RoadRunner with command:\e[0m {$command}\n"; $this->environment->startRoadRunner($command); - $this->started = true; } public function stop(): void { - if (!$this->started) { - return; + if ($this->environment->isRoadRunnerRunning()) { + // echo "\e[1;36mStop RoadRunner\e[0m\n"; + $this->environment->stop(); } - - // echo "\e[1;36mStop RoadRunner\e[0m\n"; - $this->environment->stop(); - $this->started = false; } public function __destruct() diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php index 36b14e2d5..3ce6b017a 100644 --- a/tests/Acceptance/App/Runtime/TemporalStarter.php +++ b/tests/Acceptance/App/Runtime/TemporalStarter.php @@ -10,8 +10,6 @@ final class TemporalStarter { - private bool $started = false; - public function __construct( private Environment $environment, ) @@ -21,7 +19,7 @@ public function __construct( public function start(): void { - if ($this->started) { + if ($this->environment->isTemporalRunning()) { return; } @@ -47,20 +45,15 @@ public function start(): void 'testDatetime' => ValueType::Datetime, ], ); - $this->started = true; } /** * @return bool Returns true if the server was stopped successfully, false if it was not started. */ - public function stop(): bool + public function stop(): void { - if (!$this->started) { - return false; + if ($this->environment->isTemporalRunning()) { + $this->environment->stop(); } - - $this->environment->stop(); - $this->started = false; - return true; } } diff --git a/tests/Acceptance/App/TestCase.php b/tests/Acceptance/App/TestCase.php index 2268777fe..1dd23502a 100644 --- a/tests/Acceptance/App/TestCase.php +++ b/tests/Acceptance/App/TestCase.php @@ -20,6 +20,7 @@ use Temporal\Tests\Acceptance\App\Runtime\Feature; use Temporal\Tests\Acceptance\App\Runtime\RRStarter; use Temporal\Tests\Acceptance\App\Runtime\State; +use Temporal\Tests\Acceptance\App\Runtime\TemporalStarter; abstract class TestCase extends \Temporal\Tests\TestCase { @@ -90,10 +91,10 @@ function (Container $container): mixed { if (!$e instanceof SkippedTest) { // Restart RR if a Error occurs - /** @var RRStarter $runner */ - $runner = $container->get(RRStarter::class); - $runner->stop(); - $runner->start(); + /** @var RRStarter $roadRunnerStarter */ + $roadRunnerStarter = $container->get(RRStarter::class); + $roadRunnerStarter->stop(); + $roadRunnerStarter->start(); } throw $e; diff --git a/tests/Acceptance/Extra/Versioning/DeploymentTest.php b/tests/Acceptance/Extra/Versioning/DeploymentTest.php index 90d477c38..1e780b5fb 100644 --- a/tests/Acceptance/Extra/Versioning/DeploymentTest.php +++ b/tests/Acceptance/Extra/Versioning/DeploymentTest.php @@ -14,6 +14,7 @@ use Temporal\Testing\Environment; use Temporal\Tests\Acceptance\App\Attribute\Worker; use Temporal\Tests\Acceptance\App\Runtime\Feature; +use Temporal\Tests\Acceptance\App\Runtime\RRStarter; use Temporal\Tests\Acceptance\App\Runtime\TemporalStarter; use Temporal\Tests\Acceptance\App\TestCase; use Temporal\Worker\WorkerDeploymentOptions; @@ -28,12 +29,14 @@ class DeploymentTest extends TestCase #[Test] public function defaultBehaviorAuto( Environment $environment, + RRStarter $roadRunnerStarter, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $behavior = self::executeWorkflow( $environment, + $roadRunnerStarter, $starter, $client, $feature, @@ -47,6 +50,7 @@ public function defaultBehaviorAuto( #[Test] public function customBehaviorPinned( Environment $environment, + RRStarter $roadRunnerStarter, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, @@ -54,6 +58,7 @@ public function customBehaviorPinned( $id = Uuid::v4(); self::executeWorkflow( $environment, + $roadRunnerStarter, $starter, $client, $feature, @@ -78,6 +83,7 @@ public function customBehaviorPinned( #[Test] public function versionBehaviorOverrideAutoUpgrade( Environment $environment, + RRStarter $roadRunnerStarter, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, @@ -85,6 +91,7 @@ public function versionBehaviorOverrideAutoUpgrade( $id = Uuid::v4(); self::executeWorkflow( $environment, + $roadRunnerStarter, $starter, $client, $feature, @@ -109,12 +116,14 @@ public function versionBehaviorOverrideAutoUpgrade( #[Test] public function versionBehaviorOverridePinned( Environment $environment, + RRStarter $roadRunnerStarter, TemporalStarter $starter, WorkflowClientInterface $client, Feature $feature, ): void { $behavior = self::executeWorkflow( $environment, + $roadRunnerStarter, $starter, $client, $feature, @@ -137,7 +146,8 @@ public function versionBehaviorOverridePinned( */ private static function executeWorkflow( Environment $environment, - TemporalStarter $starter, + RRStarter $roadRunnerStarter, + TemporalStarter $temporalStarter, WorkflowClientInterface $client, Feature $feature, string $workflowType, @@ -186,8 +196,9 @@ private static function executeWorkflow( $postAction === null or $postAction($behavior); return $behavior; } finally { - $starter->stop() and $starter->start(); - sleep(5); + $temporalStarter->stop(); + $temporalStarter->start(); + $roadRunnerStarter->start(); } } } From 4bcbfc4bbf09b3aa2871d3c95a9bb3ba490a1498 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 20:52:35 +0400 Subject: [PATCH 19/48] fix: adjust rr error message --- testing/src/Environment.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 8d94a9102..ebc677bf3 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -230,8 +230,12 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = if (!$roadRunnerStarted) { $this->output->writeln('error'); $this->output->writeln(\sprintf( - "Error starting RoadRunner: %s.\r\nCommand: `%s`.", + 'Failed to start until RoadRunner is ready. Status: "%s". Stderr: "%s".', + $this->roadRunnerProcess->getStatus(), $this->roadRunnerProcess->getErrorOutput(), + )); + $this->output->writeln(\sprintf( + "Command: `%s`.", $this->roadRunnerProcess->getCommandLine(), )); exit(1); From 8c54b1edc0261a88bb6c117d2e36ceab32fe0057 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 21:22:13 +0400 Subject: [PATCH 20/48] fix: dont dump memo --- src/Workflow/WorkflowExecutionInfo.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Workflow/WorkflowExecutionInfo.php b/src/Workflow/WorkflowExecutionInfo.php index d214bd081..d1687ddd8 100644 --- a/src/Workflow/WorkflowExecutionInfo.php +++ b/src/Workflow/WorkflowExecutionInfo.php @@ -96,4 +96,29 @@ public function __construct( */ public readonly string $firstRunId, ) {} + + public function __debugInfo(): array + { + return [ + 'execution' => $this->execution, + 'type' => $this->type, + 'startTime' => $this->startTime, + 'closeTime' => $this->closeTime, + 'status' => $this->status, + 'historyLength' => $this->historyLength, + 'parentNamespaceId' => $this->parentNamespaceId, + 'parentExecution' => $this->parentExecution, + 'executionTime' => $this->executionTime, +// 'memo' => $this->memo, + 'searchAttributes' => $this->searchAttributes, + 'autoResetPoints' => $this->autoResetPoints, + 'taskQueue' => $this->taskQueue, + 'stateTransitionCount' => $this->stateTransitionCount, + 'historySizeBytes' => $this->historySizeBytes, + 'mostRecentWorkerVersionStamp' => $this->mostRecentWorkerVersionStamp, + 'executionDuration' => $this->executionDuration, + 'rootExecution' => $this->rootExecution, + 'firstRunId' => $this->firstRunId, + ]; + } } From 43195fe11477a708175ac68ab0fcae12650c5fdc Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 21:30:25 +0400 Subject: [PATCH 21/48] fix: improve error logging and process serialization --- testing/src/Environment.php | 43 ++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index ebc677bf3..18b14fc02 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -111,7 +111,7 @@ public function startTemporalServer( "--port", $temporalPort, '--log-level', 'error', '--ip', $temporalHost, - '--headless', + // '--headless', ...$parameters, ], ); @@ -149,9 +149,13 @@ public function startTemporalServer( if (!$temporalStarted || !$this->temporalServerProcess->isRunning()) { $this->output->writeln('error'); $this->output->writeln(\sprintf( - "Error starting Temporal server: %s.\r\nCommand: `%s`.", + "Error starting Temporal server: %s.", !$temporalStarted ? "Health check failed" : $this->temporalServerProcess->getErrorOutput(), - $this->temporalServerProcess->getCommandLine(), + )); + $temporalServerProcess = $this->temporalServerProcess; + $this->output->writeln(\sprintf( + 'Command: `%s`.', + $this->serializeProcess($temporalServerProcess), )); exit(1); } @@ -180,9 +184,12 @@ public function startTemporalTestServer(int $commandTimeout = 10): void if (!$this->temporalTestServerProcess->isRunning()) { $this->output->writeln('error'); $this->output->writeln(\sprintf( - "Error starting Temporal Test server: %s.\r\nCommand: `%s`.", + 'Error starting Temporal Test server: %s.', $this->temporalTestServerProcess->getErrorOutput(), - $this->temporalTestServerProcess->getCommandLine(), + )); + $this->output->writeln(\sprintf( + 'Command: `%s`.', + $this->serializeProcess($this->temporalTestServerProcess), )); exit(1); } @@ -202,7 +209,7 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = $this->output->write('Starting RoadRunner... '); $roadRunnerStarted = false; - // $this->output->writeln('Running command: ' . $this->roadRunnerProcess->getCommandLine()); + $this->output->writeln('Running command: ' . $this->serializeProcess($this->roadRunnerProcess)); $this->roadRunnerProcess->start(static function ($type, $output) use (&$roadRunnerStarted): void { if ($type === Process::OUT && \str_contains($output, 'RoadRunner server started')) { $roadRunnerStarted = true; @@ -212,31 +219,35 @@ public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = if (!$this->roadRunnerProcess->isRunning()) { $this->output->writeln('error'); $this->output->writeln(\sprintf( - "Error starting RoadRunner: %s.\r\nCommand: `%s`.", + 'Error starting RoadRunner: %s.', $this->roadRunnerProcess->getErrorOutput(), - $this->roadRunnerProcess->getCommandLine(), + )); + $this->output->writeln(\sprintf( + 'Command: `%s`.', + $this->serializeProcess($this->roadRunnerProcess), )); exit(1); } // wait for roadrunner to start - $ticks = $commandTimeout * 10; + $ticks = $commandTimeout * 100; while (!$roadRunnerStarted && $ticks > 0) { $this->roadRunnerProcess->getStatus(); - \usleep(100000); + \usleep(10_000); --$ticks; } if (!$roadRunnerStarted) { $this->output->writeln('error'); $this->output->writeln(\sprintf( - 'Failed to start until RoadRunner is ready. Status: "%s". Stderr: "%s".', + 'Failed to start until RoadRunner is ready. Status: "%s". Stderr: "%s". Stdout: "%s".', $this->roadRunnerProcess->getStatus(), $this->roadRunnerProcess->getErrorOutput(), + $this->roadRunnerProcess->getOutput(), )); $this->output->writeln(\sprintf( "Command: `%s`.", - $this->roadRunnerProcess->getCommandLine(), + $this->serializeProcess($this->roadRunnerProcess), )); exit(1); } @@ -304,4 +315,12 @@ public function isTemporalTestRunning(): bool { return $this->temporalTestServerProcess?->isRunning() === true; } + + private function serializeProcess(?Process $temporalServerProcess): string|array + { + $reflection = new \ReflectionClass($temporalServerProcess); + $reflectionProperty = $reflection->getProperty('commandline'); + $commandLine = $reflectionProperty->getValue($temporalServerProcess); + return \implode(' ', $commandLine); + } } From 769260fd042a1f7c1caf2cd7feee17f456375d56 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 21:30:32 +0400 Subject: [PATCH 22/48] fix: comment out unused searchAttributes --- src/Workflow/WorkflowExecutionInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workflow/WorkflowExecutionInfo.php b/src/Workflow/WorkflowExecutionInfo.php index d1687ddd8..63c1f3002 100644 --- a/src/Workflow/WorkflowExecutionInfo.php +++ b/src/Workflow/WorkflowExecutionInfo.php @@ -110,7 +110,7 @@ public function __debugInfo(): array 'parentExecution' => $this->parentExecution, 'executionTime' => $this->executionTime, // 'memo' => $this->memo, - 'searchAttributes' => $this->searchAttributes, +// 'searchAttributes' => $this->searchAttributes, 'autoResetPoints' => $this->autoResetPoints, 'taskQueue' => $this->taskQueue, 'stateTransitionCount' => $this->stateTransitionCount, From b3a35a122937485523613f79abafeddd36c3b0dc Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 29 Jan 2026 17:31:07 +0000 Subject: [PATCH 23/48] style(php-cs-fixer): fix coding standards --- src/Workflow/WorkflowExecutionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Workflow/WorkflowExecutionInfo.php b/src/Workflow/WorkflowExecutionInfo.php index 63c1f3002..48def583a 100644 --- a/src/Workflow/WorkflowExecutionInfo.php +++ b/src/Workflow/WorkflowExecutionInfo.php @@ -109,8 +109,8 @@ public function __debugInfo(): array 'parentNamespaceId' => $this->parentNamespaceId, 'parentExecution' => $this->parentExecution, 'executionTime' => $this->executionTime, -// 'memo' => $this->memo, -// 'searchAttributes' => $this->searchAttributes, + // 'memo' => $this->memo, + // 'searchAttributes' => $this->searchAttributes, 'autoResetPoints' => $this->autoResetPoints, 'taskQueue' => $this->taskQueue, 'stateTransitionCount' => $this->stateTransitionCount, From 102bee6487f09e2986216480076212591fb37e1b Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Thu, 29 Jan 2026 21:36:36 +0400 Subject: [PATCH 24/48] fix: resetting state --- testing/src/Environment.php | 3 +++ tests/Acceptance/App/TestCase.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 18b14fc02..db0727453 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -279,6 +279,7 @@ public function stopTemporalServer(): void if ($this->isTemporalRunning()) { $this->output->write('Stopping Temporal server... '); $this->temporalServerProcess->stop(); + $this->temporalServerProcess = null; $this->output->writeln('done.'); } } @@ -288,6 +289,7 @@ public function stopTemporalTestServer(): void if ($this->isTemporalTestRunning()) { $this->output->write('Stopping Temporal Test server... '); $this->temporalTestServerProcess->stop(); + $this->temporalTestServerProcess = null; $this->output->writeln('done.'); } } @@ -297,6 +299,7 @@ public function stopRoadRunner(): void if ($this->isRoadRunnerRunning()) { $this->output->write('Stopping RoadRunner... '); $this->roadRunnerProcess->stop(); + $this->roadRunnerProcess = null; $this->output->writeln('done.'); } } diff --git a/tests/Acceptance/App/TestCase.php b/tests/Acceptance/App/TestCase.php index 1dd23502a..7d420d863 100644 --- a/tests/Acceptance/App/TestCase.php +++ b/tests/Acceptance/App/TestCase.php @@ -92,8 +92,10 @@ function (Container $container): mixed { if (!$e instanceof SkippedTest) { // Restart RR if a Error occurs /** @var RRStarter $roadRunnerStarter */ + $temporalStarter = $container->get(TemporalStarter::class); $roadRunnerStarter = $container->get(RRStarter::class); $roadRunnerStarter->stop(); + $temporalStarter->start(); $roadRunnerStarter->start(); } From 9321ff6bd88b0df5158280f115e1da485220fcde Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 11:00:21 +0400 Subject: [PATCH 25/48] fix: set workers number --- tests/Acceptance/App/Runtime/RRStarter.php | 2 ++ tests/Acceptance/App/Runtime/State.php | 1 + tests/Acceptance/App/RuntimeBuilder.php | 8 ++++---- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index 5422a60cb..c70d156f0 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -35,6 +35,8 @@ public function start(): void '-o', "temporal.address={$this->runtime->address}", '-o', + "temporal.activities.num_workers={$this->runtime->activityWorkers}", + '-o', 'server.command=' . \implode(',', [ PHP_BINARY, ...$run->getPhpBinaryArguments(), diff --git a/tests/Acceptance/App/Runtime/State.php b/tests/Acceptance/App/Runtime/State.php index d58afea93..1becbc3ee 100644 --- a/tests/Acceptance/App/Runtime/State.php +++ b/tests/Acceptance/App/Runtime/State.php @@ -28,6 +28,7 @@ public function __construct( public readonly string $rrConfigDir, public readonly string $workDir, public readonly iterable $testCasesDir, + public readonly int $activityWorkers, ) { $this->namespace = $command->namespace ?? 'default'; $this->address = $command->address; diff --git a/tests/Acceptance/App/RuntimeBuilder.php b/tests/Acceptance/App/RuntimeBuilder.php index be5b7d526..005b1905c 100644 --- a/tests/Acceptance/App/RuntimeBuilder.php +++ b/tests/Acceptance/App/RuntimeBuilder.php @@ -48,18 +48,18 @@ public static function hydrateClasses(State $runtime): void * @param non-empty-string $workDir * @param iterable $testCasesDir */ - public static function createEmpty(Command $command, string $workDir, iterable $testCasesDir): State + public static function createEmpty(Command $command, string $workDir, iterable $testCasesDir, int $workers = 1): State { - return new State($command, \dirname(__DIR__), $workDir, $testCasesDir); + return new State($command, \dirname(__DIR__), $workDir, $testCasesDir, $workers); } /** * @param non-empty-string $workDir * @param iterable $testCasesDir */ - public static function createState(Command $command, string $workDir, iterable $testCasesDir): State + public static function createState(Command $command, string $workDir, iterable $testCasesDir, int $workers = 1): State { - $runtime = new State($command, \dirname(__DIR__), $workDir, $testCasesDir); + $runtime = new State($command, \dirname(__DIR__), $workDir, $testCasesDir, $workers); self::hydrateClasses($runtime); From 85f6efbb28950e0dfcb6921ed03547a11831f15e Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 11:05:45 +0400 Subject: [PATCH 26/48] fix: rewrite worker test --- .../Extra/Stability/ResetWorkerTest.php | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php index 583de204b..b6bd51810 100644 --- a/tests/Acceptance/Extra/Stability/ResetWorkerTest.php +++ b/tests/Acceptance/Extra/Stability/ResetWorkerTest.php @@ -31,19 +31,20 @@ public function resetWithCancel( 'Extra_Stability_ResetWorker', WorkflowOptions::new() ->withTaskQueue($feature->taskQueue) - ->withWorkflowExecutionTimeout(20), + ->withWorkflowExecutionTimeout(10), ); - # Start the Workflow with a 10-second timer - $client->start($stub, 16); + # Start the Workflow with a 5-second timer + $client->start($stub, 5); # Query the Workflow to kill the Worker try { - $stub->query('die'); + $stub->query('sleepAndDie', 1); self::fail('Query must fail with a timeout'); } catch (WorkflowServiceException $e) { # Should fail with a timeout - self::assertInstanceOf(TimeoutException::class, $e->getPrevious()); + $previous = $e->getPrevious(); + self::assertInstanceOf(TimeoutException::class, $previous); } # Cancel Workflow @@ -51,13 +52,18 @@ public function resetWithCancel( try { # Workflow must be canceled - $stub->getResult(timeout: 12); + $result = $stub->getResult(timeout: 5); + self::fail( + \sprintf( + "Workflow must fail with a canceled failure, got: %s", + $result, + ), + ); } catch (WorkflowFailedException $e) { - self::assertInstanceOf(CanceledFailure::class, $e->getPrevious()); + $previous = $e->getPrevious(); + self::assertInstanceOf(CanceledFailure::class, $previous); return; } - - self::fail('Workflow must fail with a canceled failure'); } #[Test] @@ -71,29 +77,33 @@ public function resetWithSignal( 'Extra_Stability_ResetWorker', WorkflowOptions::new() ->withTaskQueue($feature->taskQueue) - ->withWorkflowExecutionTimeout(20), + ->withWorkflowExecutionTimeout(10), ); - # Start the Workflow with a 10-second timer - $client->start($stub, 16); + # Start the Workflow with a 5-second timer + $client->start($stub, 5); # Query the Workflow to kill the Worker try { - $stub->query('die'); + $stub->query('sleepAndDie', 1); self::fail('Query must fail with a timeout'); } catch (WorkflowServiceException $e) { # Should fail with a timeout - self::assertInstanceOf(TimeoutException::class, $e->getPrevious()); + $previous = $e->getPrevious(); + self::assertInstanceOf(TimeoutException::class, $previous); } $stub->signal('exit'); try { # Workflow must be canceled - $result = $stub->getResult(timeout: 16); + $result = $stub->getResult(timeout: 5); self::assertSame('Signal', $result); } catch (\Throwable) { - $this->fail('Workflow must finish successfully and no timeout must be thrown'); + $this->fail(\sprintf( + 'Workflow must finish successfully and no timeout must be thrown, got: %s.', + $e, + )); } # Check that Side Effect was not lost @@ -118,15 +128,15 @@ class TestWorkflow #[WorkflowMethod('Extra_Stability_ResetWorker')] #[ReturnType(Type::TYPE_STRING)] - public function expire(int $seconds = 10): \Generator + public function expire(int $seconds): \Generator { $isTimer = ! yield Workflow::awaitWithTimeout($seconds, fn(): bool => $this->exit); return yield $isTimer ? 'Timer' : 'Signal'; } - #[Workflow\QueryMethod('die')] - public function die(int $sleep = 2): void + #[Workflow\QueryMethod('sleepAndDie')] + public function sleepAndDie(int $sleep): void { \sleep($sleep); exit(1); From 548f809dad9825c4626316568464950207bb4702 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 12:30:38 +0400 Subject: [PATCH 27/48] fix: rewrite roadrunner starter --- testing/src/Environment.php | 179 ++++++++------------- tests/Acceptance/App/Runtime/RRStarter.php | 14 +- tests/Functional/bootstrap.php | 9 +- 3 files changed, 79 insertions(+), 123 deletions(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index db0727453..94393503e 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -4,8 +4,9 @@ namespace Temporal\Testing; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Process\Process; @@ -13,45 +14,32 @@ final class Environment { - /** - * @readonly - */ - public Command $command; - - private Downloader $downloader; - private Output $output; - private SystemInfo $systemInfo; private ?Process $temporalTestServerProcess = null; private ?Process $temporalServerProcess = null; private ?Process $roadRunnerProcess = null; public function __construct( - Output $output, - Downloader $downloader, - SystemInfo $systemInfo, - Command $command, - ) { - $this->downloader = $downloader; - $this->systemInfo = $systemInfo; - $this->output = $output; - $this->command = $command; - } + private SymfonyStyle $io, + private Downloader $downloader, + private SystemInfo $systemInfo, + public readonly Command $command, + ) {} public static function create(?Command $command = null): self { $token = \getenv('GITHUB_TOKEN'); - $info = SystemInfo::detect(); - \is_string(\getenv('ROADRUNNER_BINARY')) and $info->rrExecutable = \getenv('ROADRUNNER_BINARY'); + $systemInfo = SystemInfo::detect(); + \is_string(\getenv('ROADRUNNER_BINARY')) and $systemInfo->rrExecutable = \getenv('ROADRUNNER_BINARY'); return new self( - new ConsoleOutput(), + new SymfonyStyle(new ArgvInput(), new ConsoleOutput()), new Downloader(new Filesystem(), HttpClient::create([ 'headers' => [ 'authorization' => $token ? 'token ' . $token : null, ], ])), - $info, + $systemInfo, $command ?? Command::fromEnv(), ); } @@ -62,7 +50,7 @@ public static function create(?Command $command = null): self public function start(?string $rrCommand = null, int $commandTimeout = 10, array $envs = []): void { $this->startTemporalTestServer($commandTimeout); - $this->startRoadRunner($rrCommand, $commandTimeout, $envs); + $this->startRoadRunner($roadRunnerConfigFile, $rrCommand, $commandTimeout, $envs); } /** @@ -103,7 +91,7 @@ public function startTemporalServer( }; } - $this->output->write('Starting Temporal server... '); + $this->io->info('Starting Temporal server... '); $this->temporalServerProcess = new Process( [ $this->systemInfo->temporalCliExecutable, @@ -117,62 +105,46 @@ public function startTemporalServer( ); $this->temporalServerProcess->setTimeout($commandTimeout); $temporalStarted = false; - // $this->output->writeln('Running command: ' . $this->temporalServerProcess->getCommandLine()); - $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', - '--address', $this->command->address, - ]); - $check->run(); - if (\str_contains($check->getOutput(), 'SERVING')) { - $temporalStarted = true; - } - } - }); + $this->io->info('Running command: ' . $this->serializeProcess($this->temporalServerProcess)); + $this->temporalServerProcess->start(); $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; - } + \usleep(10_000); + $check = new Process([$this->systemInfo->temporalCliExecutable, 'operator', 'cluster', 'health']); + $check->run(); + if (\str_contains($check->getOutput(), 'SERVING')) { + $temporalStarted = true; } } if (!$temporalStarted || !$this->temporalServerProcess->isRunning()) { - $this->output->writeln('error'); - $this->output->writeln(\sprintf( - "Error starting Temporal server: %s.", - !$temporalStarted ? "Health check failed" : $this->temporalServerProcess->getErrorOutput(), - )); - $temporalServerProcess = $this->temporalServerProcess; - $this->output->writeln(\sprintf( - 'Command: `%s`.', - $this->serializeProcess($temporalServerProcess), - )); + $this->io->error([ + \sprintf( + 'Error starting Temporal server: %s.', + !$temporalStarted ? "Health check failed" : $this->temporalServerProcess->getErrorOutput(), + ), + \sprintf( + 'Command: `%s`.', + $this->serializeProcess($this->temporalServerProcess), + ), + ]); exit(1); } - $this->output->writeln('done.'); + $this->io->info('Temporal server started.'); } public function startTemporalTestServer(int $commandTimeout = 10): void { if (!$this->downloader->check($this->systemInfo->temporalServerExecutable)) { - $this->output->write('Download temporal test server... '); + $this->io->info('Download Temporal test server... '); $this->downloader->download($this->systemInfo); - $this->output->writeln('done.'); + $this->io->info('Temporal test server downloaded.'); } $temporalPort = \parse_url($this->command->address, PHP_URL_PORT); - $this->output->write('Starting Temporal test server... '); + $this->io->info('Starting Temporal test server... '); $this->temporalTestServerProcess = new Process( [$this->systemInfo->temporalServerExecutable, $temporalPort, '--enable-time-skipping'], ); @@ -182,77 +154,68 @@ public function startTemporalTestServer(int $commandTimeout = 10): void \sleep(1); if (!$this->temporalTestServerProcess->isRunning()) { - $this->output->writeln('error'); - $this->output->writeln(\sprintf( - 'Error starting Temporal Test server: %s.', - $this->temporalTestServerProcess->getErrorOutput(), - )); - $this->output->writeln(\sprintf( - 'Command: `%s`.', - $this->serializeProcess($this->temporalTestServerProcess), - )); + $this->io->error([ + \sprintf( + 'Error starting Temporal Test server: %s.', + $this->temporalTestServerProcess->getErrorOutput(), + ), + \sprintf( + 'Command: `%s`.', + $this->serializeProcess($this->temporalTestServerProcess), + ), + ]); exit(1); } - $this->output->writeln('done.'); + $this->io->info('Temporal Test server started.'); } /** * @param array $envs */ - public function startRoadRunner(?string $rrCommand = null, int $commandTimeout = 10, array $envs = []): void + public function startRoadRunner(string $configFile, ?array $parameters = null, int $commandTimeout = 10, array $envs = []): void { $this->roadRunnerProcess = new Process( - command: $rrCommand ? \explode(' ', $rrCommand) : [$this->systemInfo->rrExecutable, 'serve'], + command: [ + $this->systemInfo->rrExecutable, + "serve", + '-c', $configFile, + ...$parameters, + ], env: $envs, ); $this->roadRunnerProcess->setTimeout($commandTimeout); - $this->output->write('Starting RoadRunner... '); + $this->io->info('Starting RoadRunner... '); $roadRunnerStarted = false; - $this->output->writeln('Running command: ' . $this->serializeProcess($this->roadRunnerProcess)); - $this->roadRunnerProcess->start(static function ($type, $output) use (&$roadRunnerStarted): void { - if ($type === Process::OUT && \str_contains($output, 'RoadRunner server started')) { - $roadRunnerStarted = true; - } - }); - - if (!$this->roadRunnerProcess->isRunning()) { - $this->output->writeln('error'); - $this->output->writeln(\sprintf( - 'Error starting RoadRunner: %s.', - $this->roadRunnerProcess->getErrorOutput(), - )); - $this->output->writeln(\sprintf( - 'Command: `%s`.', - $this->serializeProcess($this->roadRunnerProcess), - )); - exit(1); - } + $this->io->info('Running command: ' . $this->serializeProcess($this->roadRunnerProcess)); + $this->roadRunnerProcess->start(); // wait for roadrunner to start - $ticks = $commandTimeout * 100; - while (!$roadRunnerStarted && $ticks > 0) { - $this->roadRunnerProcess->getStatus(); + $deadline = \microtime(true) + $commandTimeout; + while (!$roadRunnerStarted && \microtime(true) < $deadline) { \usleep(10_000); - --$ticks; + $check = new Process([$this->systemInfo->rrExecutable, 'workers', '-c', $configFile]); + $check->run(); + if (\str_contains($check->getOutput(), 'Workers of')) { + $roadRunnerStarted = true; + } } if (!$roadRunnerStarted) { - $this->output->writeln('error'); - $this->output->writeln(\sprintf( + $this->io->error(\sprintf( 'Failed to start until RoadRunner is ready. Status: "%s". Stderr: "%s". Stdout: "%s".', $this->roadRunnerProcess->getStatus(), $this->roadRunnerProcess->getErrorOutput(), $this->roadRunnerProcess->getOutput(), )); - $this->output->writeln(\sprintf( + $this->io->writeln(\sprintf( "Command: `%s`.", $this->serializeProcess($this->roadRunnerProcess), )); exit(1); } - $this->output->writeln('done.'); + $this->io->info('RoadRunner server started.'); } public function stop(): void @@ -277,30 +240,30 @@ public function executeTemporalCommand(array|string $command, int $timeout = 10) public function stopTemporalServer(): void { if ($this->isTemporalRunning()) { - $this->output->write('Stopping Temporal server... '); + $this->io->info('Stopping Temporal server... '); $this->temporalServerProcess->stop(); $this->temporalServerProcess = null; - $this->output->writeln('done.'); + $this->io->info('Temporal server stopped.'); } } public function stopTemporalTestServer(): void { if ($this->isTemporalTestRunning()) { - $this->output->write('Stopping Temporal Test server... '); + $this->io->info('Stopping Temporal Test server... '); $this->temporalTestServerProcess->stop(); $this->temporalTestServerProcess = null; - $this->output->writeln('done.'); + $this->io->info('Temporal Test server stopped.'); } } public function stopRoadRunner(): void { if ($this->isRoadRunnerRunning()) { - $this->output->write('Stopping RoadRunner... '); + $this->io->info('Stopping RoadRunner... '); $this->roadRunnerProcess->stop(); $this->roadRunnerProcess = null; - $this->output->writeln('done.'); + $this->io->info('RoadRunner server stopped.'); } } diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index c70d156f0..e57efa940 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -25,9 +25,9 @@ public function start(): void $sysInfo = SystemInfo::detect(); $run = $this->runtime->command; - $rrCommand = [ - $this->runtime->workDir . DIRECTORY_SEPARATOR . $sysInfo->rrExecutable, - 'serve', + $configFile = $this->runtime->rrConfigDir . DIRECTORY_SEPARATOR . '.rr.yaml'; + + $parameters = [ '-w', $this->runtime->rrConfigDir, '-o', @@ -44,12 +44,10 @@ public function start(): void ...$run->getCommandLineArguments(), ]), ]; - $run->tlsKey === null or $rrCommand = [...$rrCommand, '-o', "tls.key={$run->tlsKey}"]; - $run->tlsCert === null or $rrCommand = [...$rrCommand, '-o', "tls.cert={$run->tlsCert}"]; - $command = \implode(' ', $rrCommand); + $run->tlsKey === null or $parameters = [...$parameters, '-o', "tls.key={$run->tlsKey}"]; + $run->tlsCert === null or $parameters = [...$parameters, '-o', "tls.cert={$run->tlsCert}"]; - // echo "\e[1;36mStart RoadRunner with command:\e[0m {$command}\n"; - $this->environment->startRoadRunner($command); + $this->environment->startRoadRunner($configFile, $parameters); } public function stop(): void diff --git a/tests/Functional/bootstrap.php b/tests/Functional/bootstrap.php index 9726420da..c9b383f18 100644 --- a/tests/Functional/bootstrap.php +++ b/tests/Functional/bootstrap.php @@ -10,16 +10,11 @@ \chdir(__DIR__ . '/../..'); require_once __DIR__ . '/../../vendor/autoload.php'; -$sysInfo = \Temporal\Testing\SystemInfo::detect(); - $command = Command::fromEnv(); $environment = Environment::create(); $environment->startTemporalTestServer(); (new SearchAttributeTestInvoker())(); -$environment->startRoadRunner(\implode(' ', [ - $sysInfo->rrExecutable, - 'serve', - '-c', '.rr.silent.yaml', +$environment->startRoadRunner(__DIR__ . DIRECTORY_SEPARATOR . '.rr.silent.yaml', [ '-w', 'tests/Functional', '-o', 'server.command=' . \implode(',', [ @@ -28,7 +23,7 @@ 'worker.php', ...$command->getCommandLineArguments(), ]), -])); +]); \register_shutdown_function(static fn() => $environment->stop()); From 7df793d02b01453d5f350432aad65d889d80715f Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:29:31 +0400 Subject: [PATCH 28/48] feat: remove redundant getCommandLineArguments method --- testing/src/Command.php | 14 -------------- tests/Acceptance/App/Runtime/RRStarter.php | 1 - tests/Functional/bootstrap.php | 1 - 3 files changed, 16 deletions(-) diff --git a/testing/src/Command.php b/testing/src/Command.php index b8b93f6e3..bb58935aa 100644 --- a/testing/src/Command.php +++ b/testing/src/Command.php @@ -82,20 +82,6 @@ public static function fromCommandLine(array $argv): self return $self; } - /** - * @return list CLI arguments that can be parsed by `fromCommandLine` - */ - public function getCommandLineArguments(): array - { - $result = []; - $this->namespace === null or $result[] = "namespace=$this->namespace"; - $this->address === null or $result[] = "address=$this->address"; - $this->tlsCert === null or $result[] = "tls.cert=$this->tlsCert"; - $this->tlsKey === null or $result[] = "tls.key=$this->tlsKey"; - - return $result; - } - public function getPhpBinaryArguments(): array { $result = []; diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index e57efa940..79c030fa9 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -41,7 +41,6 @@ public function start(): void PHP_BINARY, ...$run->getPhpBinaryArguments(), $this->runtime->rrConfigDir . DIRECTORY_SEPARATOR . 'worker.php', - ...$run->getCommandLineArguments(), ]), ]; $run->tlsKey === null or $parameters = [...$parameters, '-o', "tls.key={$run->tlsKey}"]; diff --git a/tests/Functional/bootstrap.php b/tests/Functional/bootstrap.php index c9b383f18..ac1e78e88 100644 --- a/tests/Functional/bootstrap.php +++ b/tests/Functional/bootstrap.php @@ -21,7 +21,6 @@ PHP_BINARY, ...$command->getPhpBinaryArguments(), 'worker.php', - ...$command->getCommandLineArguments(), ]), ]); From f1fd56976c3c3dfd1b21d43e94e00d8dff72fff2 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:29:47 +0400 Subject: [PATCH 29/48] fix: add missing command argument --- testing/src/Environment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index 94393503e..afb2ddf28 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -47,7 +47,7 @@ public static function create(?Command $command = null): self /** * @param array $envs */ - public function start(?string $rrCommand = null, int $commandTimeout = 10, array $envs = []): void + public function start(string $roadRunnerConfigFile, ?array $rrCommand = null, int $commandTimeout = 10, array $envs = []): void { $this->startTemporalTestServer($commandTimeout); $this->startRoadRunner($roadRunnerConfigFile, $rrCommand, $commandTimeout, $envs); From 2696e21ea7479abfdb37f69cc46f839f39b5c14d Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:30:06 +0400 Subject: [PATCH 30/48] fix: use our own output style --- testing/src/Environment.php | 3 ++- testing/src/Support/TestOutputStyle.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 testing/src/Support/TestOutputStyle.php diff --git a/testing/src/Environment.php b/testing/src/Environment.php index afb2ddf28..d404d0179 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -11,6 +11,7 @@ use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Process\Process; use Temporal\Common\SearchAttributes\ValueType; +use Temporal\Testing\Support\TestOutputStyle; final class Environment { @@ -33,7 +34,7 @@ public static function create(?Command $command = null): self \is_string(\getenv('ROADRUNNER_BINARY')) and $systemInfo->rrExecutable = \getenv('ROADRUNNER_BINARY'); return new self( - new SymfonyStyle(new ArgvInput(), new ConsoleOutput()), + new TestOutputStyle(new ArgvInput(), new ConsoleOutput()), new Downloader(new Filesystem(), HttpClient::create([ 'headers' => [ 'authorization' => $token ? 'token ' . $token : null, diff --git a/testing/src/Support/TestOutputStyle.php b/testing/src/Support/TestOutputStyle.php new file mode 100644 index 000000000..3202431f7 --- /dev/null +++ b/testing/src/Support/TestOutputStyle.php @@ -0,0 +1,14 @@ +block($message, null, 'fg=green', '', false, false); + } +} From c2d8e22c7167f3c512cf7bf385d2440e48c82bb8 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:30:22 +0400 Subject: [PATCH 31/48] fix: pass address to healthcheck command --- testing/src/Environment.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index d404d0179..b64112228 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -112,7 +112,13 @@ public function startTemporalServer( $deadline = \microtime(true) + $commandTimeout; while (!$temporalStarted && \microtime(true) < $deadline) { \usleep(10_000); - $check = new Process([$this->systemInfo->temporalCliExecutable, 'operator', 'cluster', 'health']); + $check = new Process([ + $this->systemInfo->temporalCliExecutable, + 'operator', + 'cluster', + 'health', + '--address', $this->command->address, + ]); $check->run(); if (\str_contains($check->getOutput(), 'SERVING')) { $temporalStarted = true; From 4afef550063b90aeca9480a767b71f68e9ae5e27 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 30 Jan 2026 10:30:49 +0000 Subject: [PATCH 32/48] style(php-cs-fixer): fix coding standards --- testing/src/Support/TestOutputStyle.php | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/src/Support/TestOutputStyle.php b/testing/src/Support/TestOutputStyle.php index 3202431f7..09f4591fd 100644 --- a/testing/src/Support/TestOutputStyle.php +++ b/testing/src/Support/TestOutputStyle.php @@ -1,4 +1,5 @@ Date: Fri, 30 Jan 2026 14:40:37 +0400 Subject: [PATCH 33/48] fix: trigger ci --- tests/Acceptance/App/TestCase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Acceptance/App/TestCase.php b/tests/Acceptance/App/TestCase.php index 7d420d863..3f433be7d 100644 --- a/tests/Acceptance/App/TestCase.php +++ b/tests/Acceptance/App/TestCase.php @@ -91,7 +91,6 @@ function (Container $container): mixed { if (!$e instanceof SkippedTest) { // Restart RR if a Error occurs - /** @var RRStarter $roadRunnerStarter */ $temporalStarter = $container->get(TemporalStarter::class); $roadRunnerStarter = $container->get(RRStarter::class); $roadRunnerStarter->stop(); From d0c71b176172db4b9a9b6df962d9ab44bd5f0cee Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:55:22 +0400 Subject: [PATCH 34/48] fix: disable xdebug --- .github/workflows/run-test-suite.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/run-test-suite.yml b/.github/workflows/run-test-suite.yml index b375cf06c..66ab0dde0 100644 --- a/.github/workflows/run-test-suite.yml +++ b/.github/workflows/run-test-suite.yml @@ -95,6 +95,8 @@ jobs: - name: Run tests run: ${{ inputs.test-command }} + env: + XDEBUG_MODE: off - name: Check for failures if: steps.validate.outcome == 'failure' From a3fe266af0e5291f624118923ec2c44e661e3fc1 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 30 Jan 2026 14:55:39 +0400 Subject: [PATCH 35/48] fix: remove checks --- tests/Acceptance/App/Runtime/RRStarter.php | 6 +----- tests/Acceptance/App/Runtime/TemporalStarter.php | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index 79c030fa9..0762ac68c 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -22,7 +22,6 @@ public function start(): void return; } - $sysInfo = SystemInfo::detect(); $run = $this->runtime->command; $configFile = $this->runtime->rrConfigDir . DIRECTORY_SEPARATOR . '.rr.yaml'; @@ -51,10 +50,7 @@ public function start(): void public function stop(): void { - if ($this->environment->isRoadRunnerRunning()) { - // echo "\e[1;36mStop RoadRunner\e[0m\n"; - $this->environment->stop(); - } + $this->environment->stop(); } public function __destruct() diff --git a/tests/Acceptance/App/Runtime/TemporalStarter.php b/tests/Acceptance/App/Runtime/TemporalStarter.php index 3ce6b017a..4c52c34a2 100644 --- a/tests/Acceptance/App/Runtime/TemporalStarter.php +++ b/tests/Acceptance/App/Runtime/TemporalStarter.php @@ -52,8 +52,6 @@ public function start(): void */ public function stop(): void { - if ($this->environment->isTemporalRunning()) { - $this->environment->stop(); - } + $this->environment->stop(); } } From 5bb2588f683555547564efebbb42e695e230f18e Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:13:16 +0400 Subject: [PATCH 36/48] test: auto-generate phpunit fast and slow suites from logs --- phpunit.xml.dist | 49 +++++++++++- tests/bootstrap.php | 9 ++- tests/phpunit-generate.php | 148 +++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 tests/phpunit-generate.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a982abbf3..883e96ff8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -14,9 +14,52 @@ displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnTestsThatTriggerErrors="true" displayDetailsOnTestsThatTriggerNotices="true" - displayDetailsOnTestsThatTriggerWarnings="true" -> + displayDetailsOnTestsThatTriggerWarnings="true"> + + tests/Acceptance/Extra + tests/Acceptance/Harness + tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php + tests/Acceptance/Extra/Versioning/DeploymentTest.php + tests/Acceptance/Harness/EagerWorkflow/SuccessfulStartTest.php + tests/Acceptance/Harness/Activity/CancelTryCancelTest.php + tests/Acceptance/Extra/Stability/ResetWorkerTest.php + tests/Acceptance/Harness/Activity/RetryOnErrorTest.php + tests/Acceptance/Harness/Update/WorkerRestartTest.php + tests/Acceptance/Harness/Schedule/BasicTest.php + tests/Acceptance/Harness/Update/AsyncAcceptTest.php + tests/Acceptance/Extra/Workflow/BuiltInPrefixedHandlersTest.php + tests/Acceptance/Harness/Schedule/TriggerTest.php + tests/Acceptance/Extra/Workflow/InitMethodTest.php + tests/Acceptance/Harness/Signal/PreventCloseTest.php + tests/Acceptance/Extra/Update/UntypedStubTest.php + tests/Acceptance/Extra/Update/TimeoutTest.php + tests/Acceptance/Extra/Workflow/DateTimeZoneWorkflowTest.php + tests/Acceptance/Extra/Schedule/ScheduleUpdateTest.php + tests/Acceptance/Harness/ChildWorkflow/CancelAbandonTest.php + tests/Acceptance/Harness/ContinueAsNew/ContinueAsSameTest.php + + + tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php + tests/Acceptance/Extra/Versioning/DeploymentTest.php + tests/Acceptance/Harness/EagerWorkflow/SuccessfulStartTest.php + tests/Acceptance/Harness/Activity/CancelTryCancelTest.php + tests/Acceptance/Extra/Stability/ResetWorkerTest.php + tests/Acceptance/Harness/Activity/RetryOnErrorTest.php + tests/Acceptance/Harness/Update/WorkerRestartTest.php + tests/Acceptance/Harness/Schedule/BasicTest.php + tests/Acceptance/Harness/Update/AsyncAcceptTest.php + tests/Acceptance/Extra/Workflow/BuiltInPrefixedHandlersTest.php + tests/Acceptance/Harness/Schedule/TriggerTest.php + tests/Acceptance/Extra/Workflow/InitMethodTest.php + tests/Acceptance/Harness/Signal/PreventCloseTest.php + tests/Acceptance/Extra/Update/UntypedStubTest.php + tests/Acceptance/Extra/Update/TimeoutTest.php + tests/Acceptance/Extra/Workflow/DateTimeZoneWorkflowTest.php + tests/Acceptance/Extra/Schedule/ScheduleUpdateTest.php + tests/Acceptance/Harness/ChildWorkflow/CancelAbandonTest.php + tests/Acceptance/Harness/ContinueAsNew/ContinueAsSameTest.php + tests/Acceptance/Extra tests/Acceptance/Harness @@ -45,4 +88,4 @@ src - + \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 0dd2045e1..605bb7e4d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -35,7 +35,10 @@ return null; })($GLOBALS['argv'] ?? []); +$suite = \substr($suite, 0, \strpos($suite, '-')); + # Include related bootstrap -$suite === null or (static fn(string $file) => \is_file($file) and include $file)( - __DIR__ . DIRECTORY_SEPARATOR . $suite . DIRECTORY_SEPARATOR . 'bootstrap.php', -); +$file = __DIR__ . DIRECTORY_SEPARATOR . $suite . DIRECTORY_SEPARATOR . 'bootstrap.php'; +if (\is_file($file)) { + include $file; +} diff --git a/tests/phpunit-generate.php b/tests/phpunit-generate.php new file mode 100644 index 000000000..e53799e0c --- /dev/null +++ b/tests/phpunit-generate.php @@ -0,0 +1,148 @@ +#!/usr/bin/env php +xpath('//testcase') as $testcase) { + $file = (string) $testcase['file']; + $time = (float) $testcase['time']; + + if (!isset($tests[$file])) { + $tests[$file] = 0.0; + } + $tests[$file] = \max($tests[$file], $time); // max instead of sum + } +} + +$slow = []; +$fast = []; + +foreach ($tests as $file => $time) { + if ($time >= $threshold) { + $slow[$file] = $time; + } else { + $fast[$file] = $time; + } +} + +\arsort($slow); + +$extractPath = static function (string $file): string { + if (\preg_match('#(tests/Acceptance/.+)$#', $file, $matches)) { + return $matches[1]; + } + return $file; +}; + +$slowFiles = \array_map($extractPath, \array_keys($slow)); + +$excludeLines = \implode("\n", \array_map( + static fn(string $file): string => " $file", + $slowFiles, +)); + +$fileLines = \implode("\n", \array_map( + static fn(string $file): string => " $file", + $slowFiles, +)); + +$template = <<<'XML' + + + + + tests/Acceptance/Extra + tests/Acceptance/Harness +{{EXCLUDES}} + + +{{FILES}} + + + tests/Acceptance/Extra + tests/Acceptance/Harness + + + tests/Arch + + + tests/Unit + + + tests/Functional + + + + + skip-on-test-server + + + + + + + + + src + + + +XML; + +$output = \str_replace( + ['{{EXCLUDES}}', '{{FILES}}'], + [$excludeLines, $fileLines], + $template, +); + +\file_put_contents($outputFile, $output); + +$slowTime = \array_sum($slow); +$fastTime = \array_sum($fast); + +echo "Generated: $outputFile (threshold: {$threshold}s)\n\n"; +echo "Fast: " . \count($fast) . " files (~" . \round($fastTime, 1) . "s)\n"; +echo "Slow: " . \count($slow) . " files (~" . \round($slowTime, 1) . "s)\n\n"; + +foreach ($slow as $file => $time) { + echo \sprintf("%6.2fs %s\n", $time, $extractPath($file)); +} From e893529d29f99c2d472d037de5b6e6fabbf4b618 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:13:29 +0400 Subject: [PATCH 37/48] test: add predefined run configurations --- .run/Acceptance Fast.run.xml | 6 ++++++ .run/Acceptance Slow.run.xml | 6 ++++++ .run/Acceptance.run.xml | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .run/Acceptance Fast.run.xml create mode 100644 .run/Acceptance Slow.run.xml diff --git a/.run/Acceptance Fast.run.xml b/.run/Acceptance Fast.run.xml new file mode 100644 index 000000000..687a546d5 --- /dev/null +++ b/.run/Acceptance Fast.run.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.run/Acceptance Slow.run.xml b/.run/Acceptance Slow.run.xml new file mode 100644 index 000000000..d9d8e85c0 --- /dev/null +++ b/.run/Acceptance Slow.run.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.run/Acceptance.run.xml b/.run/Acceptance.run.xml index af5f7ae9a..ae1d8ef29 100644 --- a/.run/Acceptance.run.xml +++ b/.run/Acceptance.run.xml @@ -1,6 +1,6 @@ - + - \ No newline at end of file + From 7ec6fc7bccc3f39719ddca04c610aa64b285f035 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:16:24 +0400 Subject: [PATCH 38/48] test: skip broken files --- tests/phpunit-generate.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/phpunit-generate.php b/tests/phpunit-generate.php index e53799e0c..2a3bbb85b 100644 --- a/tests/phpunit-generate.php +++ b/tests/phpunit-generate.php @@ -27,6 +27,9 @@ foreach ($junitFiles as $junitFile) { $xml = \simplexml_load_file($junitFile); + if ($xml === false) { + continue; + } foreach ($xml->xpath('//testcase') as $testcase) { $file = (string) $testcase['file']; $time = (float) $testcase['time']; From 921b77cc86ebacfa5ca25547b352d501bdeebd30 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:18:44 +0400 Subject: [PATCH 39/48] test: diff tests --- phpunit.xml.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 883e96ff8..43bb60c76 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -19,7 +19,9 @@ tests/Acceptance/Extra tests/Acceptance/Harness + tests/Acceptance/Harness/Update/SelfTest.php tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php + tests/Acceptance/Extra/Activity/ActivityPausedTest.php tests/Acceptance/Extra/Versioning/DeploymentTest.php tests/Acceptance/Harness/EagerWorkflow/SuccessfulStartTest.php tests/Acceptance/Harness/Activity/CancelTryCancelTest.php @@ -40,7 +42,9 @@ tests/Acceptance/Harness/ContinueAsNew/ContinueAsSameTest.php + tests/Acceptance/Harness/Update/SelfTest.php tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php + tests/Acceptance/Extra/Activity/ActivityPausedTest.php tests/Acceptance/Extra/Versioning/DeploymentTest.php tests/Acceptance/Harness/EagerWorkflow/SuccessfulStartTest.php tests/Acceptance/Harness/Activity/CancelTryCancelTest.php From 0e5d3d8b446aea7cf3f00af90c80b9b2c4cc5385 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:25:54 +0400 Subject: [PATCH 40/48] test: correct suite extraction logic --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 605bb7e4d..fc34416df 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -35,7 +35,7 @@ return null; })($GLOBALS['argv'] ?? []); -$suite = \substr($suite, 0, \strpos($suite, '-')); +$suite = \substr($suite, 0, \strpos($suite, '-') ?: \strlen($suite)); # Include related bootstrap $file = __DIR__ . DIRECTORY_SEPARATOR . $suite . DIRECTORY_SEPARATOR . 'bootstrap.php'; From 275d9c712d81dd2dc2c303110dcbae4fe1c62b27 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:37:01 +0400 Subject: [PATCH 41/48] test: control workers number --- tests/Acceptance/bootstrap.php | 2 +- tests/Acceptance/worker.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Acceptance/bootstrap.php b/tests/Acceptance/bootstrap.php index 532c145df..c9de373ac 100644 --- a/tests/Acceptance/bootstrap.php +++ b/tests/Acceptance/bootstrap.php @@ -37,7 +37,7 @@ $runtime = RuntimeBuilder::createEmpty($command, \getcwd(), [ 'Temporal\Tests\Acceptance\Harness' => __DIR__ . '/Harness', 'Temporal\Tests\Acceptance\Extra' => __DIR__ . '/Extra', -]); +], workers: (int) (\getenv('ACTIVITY_WORKERS') ?: 2)); # Run RoadRunner and Temporal $environment = Environment::create($command); diff --git a/tests/Acceptance/worker.php b/tests/Acceptance/worker.php index 15f2f9582..f8a3e2c6c 100644 --- a/tests/Acceptance/worker.php +++ b/tests/Acceptance/worker.php @@ -44,7 +44,7 @@ $runtime = RuntimeBuilder::createState($command, \getcwd(), [ 'Temporal\Tests\Acceptance\Harness' => __DIR__ . '/Harness', 'Temporal\Tests\Acceptance\Extra' => __DIR__ . '/Extra', - ]); + ], workers: (int) (\getenv('ACTIVITY_WORKERS') ?: 2)); $run = $runtime->command; // Init container $container = new Spiral\Core\Container(); From 4fb25c2244465675ba26b03240a5fd5cb9d860cc Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 11:57:10 +0400 Subject: [PATCH 42/48] test: simplify to debug --- tests/Acceptance/Harness/Update/SelfTest.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Acceptance/Harness/Update/SelfTest.php b/tests/Acceptance/Harness/Update/SelfTest.php index c44f479fa..b4de3ea15 100644 --- a/tests/Acceptance/Harness/Update/SelfTest.php +++ b/tests/Acceptance/Harness/Update/SelfTest.php @@ -22,7 +22,8 @@ class SelfTest extends TestCase public static function check( #[Stub('Harness_Update_Self')]WorkflowStubInterface $stub, ): void { - self::assertSame('Hello, world!', $stub->getResult()); + $result = $stub->getResult(); + self::assertSame('Hello, world!', $result); } } @@ -36,7 +37,7 @@ public function run() { yield Workflow::executeActivity( 'result', - options: ActivityOptions::new()->withStartToCloseTimeout(2) + options: ActivityOptions::new()->withStartToCloseTimeout(10), ); yield Workflow::await(fn(): bool => $this->done); @@ -61,9 +62,10 @@ public function __construct( #[ActivityMethod('result')] public function result(): void { - $this->client->newUntypedRunningWorkflowStub( + $workflowStub = $this->client->newUntypedRunningWorkflowStub( workflowID: Activity::getInfo()->workflowExecution->getID(), workflowType: Activity::getInfo()->workflowType->name, - )->update('my_update'); + ); + $workflowStub->update('my_update'); } } From f39e0af4a6bd52a5392f0104b8f5a0830811cdf3 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 12:29:34 +0400 Subject: [PATCH 43/48] fix: revert changes --- testing/src/Command.php | 14 ++++++++++++++ tests/Acceptance/App/Runtime/RRStarter.php | 1 + tests/Functional/bootstrap.php | 1 + 3 files changed, 16 insertions(+) diff --git a/testing/src/Command.php b/testing/src/Command.php index bb58935aa..b8b93f6e3 100644 --- a/testing/src/Command.php +++ b/testing/src/Command.php @@ -82,6 +82,20 @@ public static function fromCommandLine(array $argv): self return $self; } + /** + * @return list CLI arguments that can be parsed by `fromCommandLine` + */ + public function getCommandLineArguments(): array + { + $result = []; + $this->namespace === null or $result[] = "namespace=$this->namespace"; + $this->address === null or $result[] = "address=$this->address"; + $this->tlsCert === null or $result[] = "tls.cert=$this->tlsCert"; + $this->tlsKey === null or $result[] = "tls.key=$this->tlsKey"; + + return $result; + } + public function getPhpBinaryArguments(): array { $result = []; diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index 0762ac68c..aea197f23 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -40,6 +40,7 @@ public function start(): void PHP_BINARY, ...$run->getPhpBinaryArguments(), $this->runtime->rrConfigDir . DIRECTORY_SEPARATOR . 'worker.php', + ...$run->getCommandLineArguments(), ]), ]; $run->tlsKey === null or $parameters = [...$parameters, '-o', "tls.key={$run->tlsKey}"]; diff --git a/tests/Functional/bootstrap.php b/tests/Functional/bootstrap.php index ac1e78e88..c9b383f18 100644 --- a/tests/Functional/bootstrap.php +++ b/tests/Functional/bootstrap.php @@ -21,6 +21,7 @@ PHP_BINARY, ...$command->getPhpBinaryArguments(), 'worker.php', + ...$command->getCommandLineArguments(), ]), ]); From 824ff60f04ba25d3d228606c5bb11c2afef17868 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 12:29:44 +0400 Subject: [PATCH 44/48] fix: set default values --- testing/src/Command.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/src/Command.php b/testing/src/Command.php index b8b93f6e3..7d9ff42c1 100644 --- a/testing/src/Command.php +++ b/testing/src/Command.php @@ -51,8 +51,8 @@ public static function fromCommandLine(array $argv): self { $address = ''; $namespace = ''; - $tlsCert = ''; - $tlsKey = ''; + $tlsCert = null; + $tlsKey = null; // remove the script name (worker.php or runner.php) $chunks = \array_slice($argv, 1); From 7b89da9386cb05e6a74e06d16c5fc34130ad71b1 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 12:42:36 +0400 Subject: [PATCH 45/48] fix: start/stop issue --- tests/Acceptance/Harness/Update/WorkerRestartTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Acceptance/Harness/Update/WorkerRestartTest.php b/tests/Acceptance/Harness/Update/WorkerRestartTest.php index 08bd20f70..0b85c7ab3 100644 --- a/tests/Acceptance/Harness/Update/WorkerRestartTest.php +++ b/tests/Acceptance/Harness/Update/WorkerRestartTest.php @@ -14,6 +14,7 @@ use Temporal\Client\WorkflowStubInterface; use Temporal\Tests\Acceptance\App\Attribute\Stub; use Temporal\Tests\Acceptance\App\Runtime\RRStarter; +use Temporal\Tests\Acceptance\App\Runtime\TemporalStarter; use Temporal\Tests\Acceptance\App\TestCase; use Temporal\Workflow; use Temporal\Workflow\WorkflowInterface; @@ -29,7 +30,8 @@ class WorkerRestartTest extends TestCase public static function check( #[Stub('Harness_Update_WorkerRestart')]WorkflowStubInterface $stub, ContainerInterface $c, - RRStarter $runner, + TemporalStarter $temporalStarter, + RRStarter $roadRunnerStarter, ): void { $handle = $stub->startUpdate('do_activities'); @@ -45,8 +47,9 @@ public static function check( } while (true); # Restart the worker. - $runner->stop(); - $runner->start(); + $roadRunnerStarter->stop(); + $temporalStarter->start(); + $roadRunnerStarter->start(); # Unblocks the activity. $c->get(StorageInterface::class)->set(KV_ACTIVITY_BLOCKED, false); From 197e19c26a074a8317c07c5c66fbb574783c1d4d Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 31 Jan 2026 12:47:25 +0400 Subject: [PATCH 46/48] fix: add error when run rr without temporal --- testing/src/Environment.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testing/src/Environment.php b/testing/src/Environment.php index b64112228..919707436 100644 --- a/testing/src/Environment.php +++ b/testing/src/Environment.php @@ -181,6 +181,12 @@ public function startTemporalTestServer(int $commandTimeout = 10): void */ public function startRoadRunner(string $configFile, ?array $parameters = null, int $commandTimeout = 10, array $envs = []): void { + if (!$this->isTemporalRunning() && !$this->isTemporalTestRunning()) { + $this->io->error([ + 'Temporal server is not running. Please start it before starting RoadRunner.', + ]); + exit(1); + } $this->roadRunnerProcess = new Process( command: [ $this->systemInfo->rrExecutable, From b15228b47a66ecde0280ace267b1b37f7be81a1f Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sat, 7 Feb 2026 19:10:14 +0400 Subject: [PATCH 47/48] fix: tests --- tests/Acceptance/App/Runtime/RRStarter.php | 2 +- .../Harness/Query/TimeoutDueToNoActiveWorkersTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Acceptance/App/Runtime/RRStarter.php b/tests/Acceptance/App/Runtime/RRStarter.php index aea197f23..b5b96cfde 100644 --- a/tests/Acceptance/App/Runtime/RRStarter.php +++ b/tests/Acceptance/App/Runtime/RRStarter.php @@ -51,7 +51,7 @@ public function start(): void public function stop(): void { - $this->environment->stop(); + $this->environment->stopRoadRunner(); } public function __destruct() diff --git a/tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php b/tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php index de9d45dc5..0e42d8644 100644 --- a/tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php +++ b/tests/Acceptance/Harness/Query/TimeoutDueToNoActiveWorkersTest.php @@ -22,13 +22,13 @@ class TimeoutDueToNoActiveWorkersTest extends TestCase { #[Test] public static function check( - #[Client(timeout: 30)] + #[Client(timeout: 10)] #[Stub('Harness_Query_TimeoutDueToNoActiveWorkers')] WorkflowStubInterface $stub, - RRStarter $runner, + RRStarter $roadRunnerStarter, ): void { # Stop worker - $runner->stop(); + $roadRunnerStarter->stop(); try { $stub->query('simple_query')?->getValue(0); @@ -44,7 +44,7 @@ public static function check( ], 'Error code must be DEADLINE_EXCEEDED or CANCELLED. Got ' . \print_r($status, true)); } finally { # Restart the worker and finish the wf - $runner->start(); + $roadRunnerStarter->start(); $stub->signal('finish'); $stub->getResult(); } From f9b1d6d434685e6ac4055786accf5a082884afcc Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Mon, 9 Feb 2026 18:23:17 +0400 Subject: [PATCH 48/48] fix: clean --- tests/Acceptance/App/TestCase.php | 2 -- tests/Acceptance/Harness/Update/WorkerRestartTest.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/Acceptance/App/TestCase.php b/tests/Acceptance/App/TestCase.php index 3f433be7d..7f3c726ff 100644 --- a/tests/Acceptance/App/TestCase.php +++ b/tests/Acceptance/App/TestCase.php @@ -91,10 +91,8 @@ function (Container $container): mixed { if (!$e instanceof SkippedTest) { // Restart RR if a Error occurs - $temporalStarter = $container->get(TemporalStarter::class); $roadRunnerStarter = $container->get(RRStarter::class); $roadRunnerStarter->stop(); - $temporalStarter->start(); $roadRunnerStarter->start(); } diff --git a/tests/Acceptance/Harness/Update/WorkerRestartTest.php b/tests/Acceptance/Harness/Update/WorkerRestartTest.php index 0b85c7ab3..2875bc30f 100644 --- a/tests/Acceptance/Harness/Update/WorkerRestartTest.php +++ b/tests/Acceptance/Harness/Update/WorkerRestartTest.php @@ -30,7 +30,6 @@ class WorkerRestartTest extends TestCase public static function check( #[Stub('Harness_Update_WorkerRestart')]WorkflowStubInterface $stub, ContainerInterface $c, - TemporalStarter $temporalStarter, RRStarter $roadRunnerStarter, ): void { $handle = $stub->startUpdate('do_activities'); @@ -48,7 +47,6 @@ public static function check( # Restart the worker. $roadRunnerStarter->stop(); - $temporalStarter->start(); $roadRunnerStarter->start(); # Unblocks the activity. $c->get(StorageInterface::class)->set(KV_ACTIVITY_BLOCKED, false);