mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
511 lines
19 KiB
PHP
511 lines
19 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\MessageQueue\Test\Unit\Model\Cron;
|
|
|
|
use Magento\Framework\App\DeploymentConfig;
|
|
use Magento\Framework\Lock\LockManagerInterface;
|
|
use Magento\Framework\MessageQueue\ConnectionTypeResolver;
|
|
use Magento\Framework\MessageQueue\Consumer\Config\ConsumerConfigItemInterface;
|
|
use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface;
|
|
use Magento\Framework\ShellInterface;
|
|
use Magento\MessageQueue\Model\Cron\ConsumersRunner;
|
|
use Magento\MessageQueue\Model\CheckIsAvailableMessagesInQueue;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Component\Process\PhpExecutableFinder;
|
|
|
|
/**
|
|
* Unit tests for ConsumersRunner.
|
|
*/
|
|
class ConsumersRunnerTest extends TestCase
|
|
{
|
|
/**
|
|
* @var LockManagerInterface|MockObject
|
|
*/
|
|
private $lockManagerMock;
|
|
|
|
/**
|
|
* @var ShellInterface|MockObject
|
|
*/
|
|
private $shellBackgroundMock;
|
|
|
|
/**
|
|
* @var ConsumerConfigInterface|MockObject
|
|
*/
|
|
private $consumerConfigMock;
|
|
|
|
/**
|
|
* @var DeploymentConfig|MockObject
|
|
*/
|
|
private $deploymentConfigMock;
|
|
|
|
/**
|
|
* @var PhpExecutableFinder|MockObject
|
|
*/
|
|
private $phpExecutableFinderMock;
|
|
|
|
/**
|
|
* @var CheckIsAvailableMessagesInQueue|MockObject
|
|
*/
|
|
private $checkIsAvailableMessagesMock;
|
|
|
|
/**
|
|
* @var ConnectionTypeResolver
|
|
*/
|
|
private $connectionTypeResolver;
|
|
|
|
/**
|
|
* @var ConsumersRunner
|
|
*/
|
|
private $consumersRunner;
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
require_once __DIR__ . '/../../_files/consumers_runner_functions_mocks.php';
|
|
|
|
$this->phpExecutableFinderMock = $this->getMockBuilder(PhpExecutableFinder::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
$this->lockManagerMock = $this->getMockBuilder(LockManagerInterface::class)
|
|
->getMockForAbstractClass();
|
|
$this->shellBackgroundMock = $this->getMockBuilder(ShellInterface::class)
|
|
->getMockForAbstractClass();
|
|
$this->consumerConfigMock = $this->getMockBuilder(ConsumerConfigInterface::class)
|
|
->getMockForAbstractClass();
|
|
$this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
$this->checkIsAvailableMessagesMock = $this->createMock(CheckIsAvailableMessagesInQueue::class);
|
|
$this->connectionTypeResolver = $this->getMockBuilder(ConnectionTypeResolver::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
$this->connectionTypeResolver->method('getConnectionType')->willReturn('something');
|
|
|
|
$this->consumersRunner = new ConsumersRunner(
|
|
$this->phpExecutableFinderMock,
|
|
$this->consumerConfigMock,
|
|
$this->deploymentConfigMock,
|
|
$this->shellBackgroundMock,
|
|
$this->lockManagerMock,
|
|
$this->connectionTypeResolver,
|
|
null,
|
|
$this->checkIsAvailableMessagesMock
|
|
);
|
|
}
|
|
|
|
public function testRunDisabled()
|
|
{
|
|
$this->deploymentConfigMock->expects($this->atLeastOnce())
|
|
->method('get')
|
|
->willReturnMap(
|
|
[
|
|
['cron_consumers_runner/cron_run', true, false],
|
|
['cron_consumers_runner/multiple_processes', [], []],
|
|
]
|
|
);
|
|
|
|
$this->consumerConfigMock->expects($this->never())
|
|
->method('getConsumers');
|
|
$this->lockManagerMock->expects($this->never())
|
|
->method('isLocked');
|
|
$this->shellBackgroundMock->expects($this->never())
|
|
->method('execute');
|
|
|
|
$this->consumersRunner->run();
|
|
}
|
|
|
|
/**
|
|
* @param int $maxMessages
|
|
* @param bool $isLocked
|
|
* @param string $php
|
|
* @param string $command
|
|
* @param array $arguments
|
|
* @param array $allowedConsumers
|
|
* @param int $shellBackgroundExpects
|
|
* @param int $isRunExpects
|
|
* @dataProvider runDataProvider
|
|
*/
|
|
public function testRun(
|
|
$maxMessages,
|
|
$isLocked,
|
|
$php,
|
|
$command,
|
|
$arguments,
|
|
array $allowedConsumers,
|
|
$shellBackgroundExpects,
|
|
$isRunExpects
|
|
) {
|
|
$consumerName = 'consumerName';
|
|
|
|
$this->deploymentConfigMock
|
|
->method('get')
|
|
->willReturnMap(
|
|
[
|
|
['cron_consumers_runner/cron_run', true, true],
|
|
['cron_consumers_runner/max_messages', 10000, $maxMessages],
|
|
['cron_consumers_runner/consumers', [], $allowedConsumers],
|
|
['queue/only_spawn_when_message_available', null, 0],
|
|
['cron_consumers_runner/multiple_processes', [], []]
|
|
]
|
|
);
|
|
|
|
/** @var ConsumerConfigInterface|MockObject $firstCunsumer */
|
|
$consumer = $this->getMockBuilder(ConsumerConfigItemInterface::class)
|
|
->getMockForAbstractClass();
|
|
$consumer->method('getName')->willReturn($consumerName);
|
|
|
|
$this->phpExecutableFinderMock->expects($this->once())
|
|
->method('find')
|
|
->willReturn($php);
|
|
|
|
$this->consumerConfigMock->expects($this->once())
|
|
->method('getConsumers')
|
|
->willReturn([$consumer]);
|
|
|
|
$this->lockManagerMock->expects($this->exactly($isRunExpects))
|
|
->method('isLocked')
|
|
->with(md5($consumerName)) //phpcs:ignore
|
|
->willReturn($isLocked);
|
|
|
|
$this->shellBackgroundMock->expects($this->exactly($shellBackgroundExpects))
|
|
->method('execute')
|
|
->with($command, $arguments);
|
|
|
|
$this->consumersRunner->run();
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public static function runDataProvider()
|
|
{
|
|
return [
|
|
[
|
|
'maxMessages' => 20000,
|
|
'isLocked' => false,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=20000'],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 1,
|
|
'isRunExpects' => 1,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => false,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 1,
|
|
'isRunExpects' => 1,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => false,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => ['someConsumer'],
|
|
'shellBackgroundExpects' => 0,
|
|
'isRunExpects' => 0,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => true,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => ['someConsumer'],
|
|
'shellBackgroundExpects' => 0,
|
|
'isRunExpects' => 0,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => true,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 0,
|
|
'isRunExpects' => 1,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => true,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => ['consumerName'],
|
|
'shellBackgroundExpects' => 0,
|
|
'isRunExpects' => 1,
|
|
],
|
|
[
|
|
'maxMessages' => 10000,
|
|
'isLocked' => false,
|
|
'php' => '',
|
|
'command' => 'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
'arguments' => ['consumerName', '--single-thread', '--max-messages=10000'],
|
|
'allowedConsumers' => ['consumerName'],
|
|
'shellBackgroundExpects' => 1,
|
|
'isRunExpects' => 1,
|
|
],
|
|
[
|
|
'maxMessages' => 0,
|
|
'isLocked' => false,
|
|
'php' => '/bin/php',
|
|
'command' => '/bin/php ' . BP . '/bin/magento queue:consumers:start %s %s',
|
|
'arguments' => ['consumerName', '--single-thread'],
|
|
'allowedConsumers' => ['consumerName'],
|
|
'shellBackgroundExpects' => 1,
|
|
'isRunExpects' => 1,
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param int $maxMessages
|
|
* @param array $isLocked
|
|
* @param string $php
|
|
* @param array $returnMap
|
|
* @param array $allowedConsumers
|
|
* @param int $shellBackgroundExpects
|
|
* @dataProvider runMultiProcessesDataProvider
|
|
*/
|
|
public function testRunMultiProcesses(
|
|
int $maxMessages,
|
|
array $isLocked,
|
|
string $php,
|
|
array $returnMap,
|
|
array $allowedConsumers,
|
|
int $shellBackgroundExpects
|
|
): void {
|
|
$consumerName = 'consumerName';
|
|
|
|
$this->deploymentConfigMock
|
|
->method('get')
|
|
->willReturnMap(
|
|
[
|
|
['cron_consumers_runner/cron_run', true, true],
|
|
['cron_consumers_runner/max_messages', 10000, $maxMessages],
|
|
['cron_consumers_runner/consumers', [], $allowedConsumers],
|
|
['queue/only_spawn_when_message_available', null, 0],
|
|
['cron_consumers_runner/multiple_processes',
|
|
[],
|
|
['consumerName' => 2]
|
|
]
|
|
]
|
|
);
|
|
|
|
/** @var ConsumerConfigInterface|MockObject $firstCunsumer */
|
|
$consumer = $this->getMockBuilder(ConsumerConfigItemInterface::class)
|
|
->getMockForAbstractClass();
|
|
$consumer->method('getName')->willReturn($consumerName);
|
|
|
|
$this->phpExecutableFinderMock->expects($this->once())
|
|
->method('find')
|
|
->willReturn($php);
|
|
|
|
$this->consumerConfigMock->expects($this->once())
|
|
->method('getConsumers')
|
|
->willReturn([$consumer]);
|
|
|
|
$this->lockManagerMock->expects(self::exactly(2))
|
|
->method('isLocked')
|
|
->willReturnCallback(fn($param) => match ([$param]) {
|
|
[md5($consumerName . '-' . 1)] => $isLocked[0], //phpcs:ignore
|
|
[md5($consumerName . '-' . 2)] => $isLocked[1] //phpcs:ignore
|
|
});
|
|
|
|
$this->shellBackgroundMock->expects(self::exactly($shellBackgroundExpects))
|
|
->method('execute')
|
|
->willReturnMap($returnMap);
|
|
|
|
$this->consumersRunner->run();
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public static function runMultiProcessesDataProvider()
|
|
{
|
|
return [
|
|
[
|
|
'maxMessages' => 20000,
|
|
'isLocked' => [false, false],
|
|
'php' => '',
|
|
'returnMap' => [
|
|
[
|
|
'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
['consumerName', '--multi-process=1', '--max-messages=20000'],
|
|
'value1'
|
|
],
|
|
[
|
|
'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
['consumerName', '--multi-process=2', '--max-messages=20000'],
|
|
'value2'
|
|
]
|
|
],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 2
|
|
],
|
|
[
|
|
'maxMessages' => 20000,
|
|
'isLocked' => [true, false],
|
|
'php' => '',
|
|
'returnMap' => [
|
|
[
|
|
'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
['consumerName', '--multi-process=2', '--max-messages=20000'],
|
|
'value2'
|
|
]
|
|
],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 1
|
|
],
|
|
[
|
|
'maxMessages' => 20000,
|
|
'isLocked' => [true, true],
|
|
'php' => '',
|
|
'returnMap' => [
|
|
[
|
|
'php ' . BP . '/bin/magento queue:consumers:start %s %s %s',
|
|
['consumerName', '--multi-process=2', '--max-messages=20000'],
|
|
'value2'
|
|
]
|
|
],
|
|
'allowedConsumers' => [],
|
|
'shellBackgroundExpects' => 0
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param boolean $onlySpawnWhenMessageAvailable
|
|
* @param boolean $isMassagesAvailableInTheQueue
|
|
* @param int $shellBackgroundExpects
|
|
* @param boolean $globalOnlySpawnWhenMessageAvailable
|
|
* @param int $getOnlySpawnWhenMessageAvailableCallCount
|
|
* @param int $isMassagesAvailableInTheQueueCallCount
|
|
* @dataProvider runBasedOnOnlySpawnWhenMessageAvailableConsumerConfigurationDataProvider
|
|
*/
|
|
public function testRunBasedOnOnlySpawnWhenMessageAvailableConsumerConfiguration(
|
|
$onlySpawnWhenMessageAvailable,
|
|
$isMassagesAvailableInTheQueue,
|
|
$shellBackgroundExpects,
|
|
$globalOnlySpawnWhenMessageAvailable,
|
|
$getOnlySpawnWhenMessageAvailableCallCount,
|
|
$isMassagesAvailableInTheQueueCallCount
|
|
) {
|
|
$consumerName = 'consumerName';
|
|
$connectionName = 'connectionName';
|
|
$queueName = 'queueName';
|
|
$this->deploymentConfigMock->expects($this->exactly(5))
|
|
->method('get')
|
|
->willReturnMap(
|
|
[
|
|
['cron_consumers_runner/cron_run', true, true],
|
|
['cron_consumers_runner/max_messages', 10000, 1000],
|
|
['cron_consumers_runner/consumers', [], []],
|
|
['queue/only_spawn_when_message_available', true, $globalOnlySpawnWhenMessageAvailable],
|
|
['cron_consumers_runner/multiple_processes', [], []]
|
|
]
|
|
);
|
|
|
|
/** @var ConsumerConfigInterface|MockObject $firstCunsumer */
|
|
$consumer = $this->getMockBuilder(ConsumerConfigItemInterface::class)
|
|
->getMockForAbstractClass();
|
|
$consumer->method('getName')->willReturn($consumerName);
|
|
$consumer->expects($this->once())
|
|
->method('getConnection')
|
|
->willReturn($connectionName);
|
|
$consumer->method('getQueue')->willReturn($queueName);
|
|
$consumer->expects($this->exactly($getOnlySpawnWhenMessageAvailableCallCount))
|
|
->method('getOnlySpawnWhenMessageAvailable')
|
|
->willReturn($onlySpawnWhenMessageAvailable);
|
|
$this->consumerConfigMock->expects($this->once())
|
|
->method('getConsumers')
|
|
->willReturn([$consumer]);
|
|
|
|
$this->phpExecutableFinderMock->expects($this->once())
|
|
->method('find')
|
|
->willReturn('');
|
|
|
|
$this->lockManagerMock->method('isLocked')->willReturn(false);
|
|
|
|
$this->checkIsAvailableMessagesMock->expects($this->exactly($isMassagesAvailableInTheQueueCallCount))
|
|
->method('execute')
|
|
->willReturn($isMassagesAvailableInTheQueue);
|
|
|
|
$this->shellBackgroundMock->expects($this->exactly($shellBackgroundExpects))
|
|
->method('execute');
|
|
|
|
$this->consumersRunner->run();
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public static function runBasedOnOnlySpawnWhenMessageAvailableConsumerConfigurationDataProvider()
|
|
{
|
|
return [
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => true,
|
|
'isMassagesAvailableInTheQueue' => true,
|
|
'shellBackgroundExpects' => 1,
|
|
'globalOnlySpawnWhenMessageAvailable' => false,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 1,
|
|
'isMassagesAvailableInTheQueueCallCount' => 1
|
|
],
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => true,
|
|
'isMassagesAvailableInTheQueue' => false,
|
|
'shellBackgroundExpects' => 0,
|
|
'globalOnlySpawnWhenMessageAvailable' => false,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 1,
|
|
'isMassagesAvailableInTheQueueCallCount' => 1
|
|
],
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => false,
|
|
'isMassagesAvailableInTheQueue' => true,
|
|
'shellBackgroundExpects' => 1,
|
|
'globalOnlySpawnWhenMessageAvailable' => false,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 2,
|
|
'isMassagesAvailableInTheQueueCallCount' => 0
|
|
],
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => null,
|
|
'isMassagesAvailableInTheQueue' => true,
|
|
'shellBackgroundExpects' => 1,
|
|
'globalOnlySpawnWhenMessageAvailable' => true,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 2,
|
|
'isMassagesAvailableInTheQueueCallCount' => 1
|
|
],
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => null,
|
|
'isMassagesAvailableInTheQueue' => true,
|
|
'shellBackgroundExpects' => 1,
|
|
'globalOnlySpawnWhenMessageAvailable' => false,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 2,
|
|
'isMassagesAvailableInTheQueueCallCount' => 0
|
|
],
|
|
[
|
|
'onlySpawnWhenMessageAvailable' => false,
|
|
'isMassagesAvailableInTheQueue' => true,
|
|
'shellBackgroundExpects' => 1,
|
|
'globalOnlySpawnWhenMessageAvailable' => true,
|
|
'getOnlySpawnWhenMessageAvailableCallCount' => 2,
|
|
'isMassagesAvailableInTheQueueCallCount' => 0
|
|
],
|
|
];
|
|
}
|
|
}
|