Skip to content

pcntl PHP extension is required since v6.3.5 with test #52586

@SerheyDolgushev

Description

@SerheyDolgushev

Symfony version(s) affected

v6.3.5

Description

After v6.3.5 the messenger:consume command fails if there is no pcntl extension installed/enabled:

$ php ./bin/console messenger:consume XXX
...
Unable to subscribe to signal events. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini's "disable_functions" directive.  

How to reproduce

Setup env

# Change working directory
cd ~/Projects
# Create new symfony projecy
symfony new symfony63x --version="6.3.*"
# Change working directory
cd symfony63x
# Install symfony/messenger
composer require symfony/messenger
# Install phpunit
composer require --dev symfony/test-pack

Create new tests/ConsumeMessagesCommandTest.php test:

<?php

declare(strict_types=1);

namespace App\Tests\Command;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\RoutableMessageBus;
use Symfony\Component\Messenger\Stamp\BusNameStamp;
use Symfony\Component\Messenger\Tests\ResettableDummyReceiver;
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;

class ConsumeMessagesCommandTest extends TestCase
{
    public function testBasicApplicationRun()
    {
        $envelope = new Envelope(new \stdClass(), [new BusNameStamp('dummy-bus')]);

        $receiver = $this->createMock(ReceiverInterface::class);
        $receiver->expects($this->once())->method('get')->willReturn([$envelope]);

        $receiverLocator = $this->createMock(ContainerInterface::class);
        $receiverLocator->expects($this->once())->method('has')->with('dummy-receiver')->willReturn(true);
        $receiverLocator->expects($this->once())->method('get')->with('dummy-receiver')->willReturn($receiver);

        $bus = $this->createMock(MessageBusInterface::class);
        $bus->expects($this->once())->method('dispatch');

        $busLocator = $this->createMock(ContainerInterface::class);
        $busLocator->expects($this->once())->method('has')->with('dummy-bus')->willReturn(true);
        $busLocator->expects($this->once())->method('get')->with('dummy-bus')->willReturn($bus);

        $command = new ConsumeMessagesCommand(new RoutableMessageBus($busLocator), $receiverLocator, new EventDispatcher());
        $command->setHelperSet(new HelperSet());

        $application = new Application();
        $doRunCommand = (new \ReflectionClass($application))->getMethod('doRunCommand');

        $input = new ArrayInput([
            'receivers' => ['dummy-receiver'],
            '--limit' => 1,
        ]);
        $doRunCommand->invokeArgs($application, [$command, $input, new ConsoleOutput()]);
    }
}

Reproduce the issue:

  1. Check the versions:
% composer show symfony/messenger | grep version
versions : * v6.3.7
% composer show symfony/console | grep version
versions : * v6.3.8
  1. Run the new test with the disabled pcntl_signal function:
% php -d disable_functions=pcntl_signal ./bin/phpunit --filter testBasicApplicationRun tests/ConsumeMessagesCommandTest.php
...
There was 1 error:

1) App\Tests\Command\ConsumeMessagesCommandTest::testBasicApplicationRun
Symfony\Component\Console\Exception\RuntimeException: Unable to subscribe to signal events. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini's "disable_functions" directive.

/Users/sergiid/Projects/symfony-test/symfony63x/vendor/symfony/console/Application.php:1006
/Users/sergiid/Projects/symfony-test/symfony63x/tests/ConsumeMessagesCommandTest.php:52
/Users/sergiid/Projects/symfony-test/symfony63x/vendor/phpunit/phpunit/phpunit:107

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
  1. Run the new test without disabled pcntl_signal function:
% php ./bin/phpunit --filter testBasicApplicationRun tests/ConsumeMessagesCommandTest.php 
...
OK (1 test, 4 assertions)

Conclusion
The test fails when pcntl_signal is disabled. Which means pcntl is required to run ConsumeMessagesCommand.

Possible Solution

#52575

Additional Context

  1. Initially [Messenger] pcntl PHP extension is required since v6.3.5 #52574 was submitted. But it was closed.
  2. I added the test case that demonstrates the issue and submitted [Messenger] pcntl PHP extension is required since v6.3.5 with test #52575. It was also closed and marked as spam.
  3. I tried to reach out to the person who closed previous PRs over Symfony Slack, and was asked to submit an issue:
Screenshot 2023-11-14 at 3 59 04 PM

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions