add tests

This commit is contained in:
jb cr
2024-10-22 14:00:31 +02:00
parent 26dbef58d3
commit 29480592cb
14 changed files with 395 additions and 3 deletions

View File

@@ -17,6 +17,7 @@ permissions:
jobs:
symfony-tests:
strategy:
fail-fast: false
matrix:
php: ['8.0', '8.1', '8.2', '8.3']
runs-on: ubuntu-latest
@@ -64,4 +65,4 @@ jobs:
cd tests/Application
bin/console doctrine:migration:migrate -n
- name: Execute tests (Unit and Feature tests) via PHPUnit
run: vendor/bin/phpunit
run: vendor/bin/phpunit --process-isolation

View File

@@ -16,7 +16,7 @@ use Win32ServiceBundle\DependencyInjection\TagRunnerCompilerPass;
class Win32ServiceBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
$autoconfig = $container->registerForAutoconfiguration(RunnerServiceInterface::class);
$autoconfig->addTag(TagRunnerCompilerPass::WIN32SERVICE_RUNNER_TAG);

View File

@@ -17,3 +17,5 @@ framework:
# 'App\Message\YourMessage': async
'Win32ServiceBundle\Tests\Application\Event\TestMessage': async
'Win32ServiceBundle\Tests\Application\Event\TestRetryMessage': async
'Win32ServiceBundle\Tests\Application\Event\TestMemoryLimitMessage': async
'Win32ServiceBundle\Tests\Application\Event\TestTimeLimitMessage': async

View File

@@ -6,5 +6,6 @@ win32_service:
limit: 10
displayed_name: Demo Messenger Consumer Async %d
thread_count: 2
memory_limit: 3600
memory_limit: 128M
time_limit: 1

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Application\Event;
final class TestMemoryLimitMessage
{
public function __construct(public int $size)
{
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Application\Event;
final class TestTimeLimitMessage
{
public function __construct(public int $durationInSeconds)
{
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Application\Handler;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Win32ServiceBundle\Tests\Application\Event\TestMemoryLimitMessage;
#[AsMessageHandler(fromTransport: 'async')]
final class MemoryLimitMessageHandler
{
/** @var string Buffer to consume memory to stop service */
private string $buffer = '';
public function __construct(private LoggerInterface $logger)
{
}
public function __invoke(TestMemoryLimitMessage $message): void
{
$this->logger->info('Memory Limit Message : '.$message->size);
$this->buffer = str_repeat('-*+45defse', (int) ($message->size / 10));
}
}

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Application\Handler;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Win32ServiceBundle\Tests\Application\Event\TestTimeLimitMessage;
#[AsMessageHandler(fromTransport: 'async')]
final class TimeLimitMessageHandler
{
public function __construct(private LoggerInterface $logger)
{
}
public function __invoke(TestTimeLimitMessage $message): void
{
$this->logger->info('Time Limit Message : '.$message->durationInSeconds);
sleep($message->durationInSeconds);
}
}

View File

@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Unit\MessengerIntegration;
require_once \dirname(__DIR__, 2).'/Win32serviceState.php';
use Doctrine\DBAL\Driver\Connection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Win32Service\Model\AbstractServiceRunner;
use Win32Service\Model\ServiceIdentifier;
use Win32Service\Model\Win32serviceState;
use Win32ServiceBundle\Model\MessengerServiceRunner;
use Win32ServiceBundle\Service\RunnerManager;
use Win32ServiceBundle\Service\ServiceConfigurationManager;
use Win32ServiceBundle\Tests\Application\Event\TestMessage;
final class LimitNbMessageTest extends KernelTestCase
{
protected function setUp(): void
{
Win32serviceState::reset();
}
protected function tearDown(): void
{
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->rollBack();
}
public function testLimitMessage(): void
{
$serviceName = 'win32service.demo.messenger.async.0';
self::bootKernel();
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->beginTransaction();
$connexion->query('DELETE FROM messenger_messages');
/** @var MessageBusInterface $messengerBus */
$messengerBus = $container->get('messenger.bus.default');
$messagesTotal = 20;
for ($i = 1; $i <= $messagesTotal; ++$i) {
$messengerBus->dispatch(new TestMessage('message '.$i));
}
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\'');
$this->assertSame($messagesTotal, (int) $c->fetchOne());
$runnerManager = $container->get(RunnerManager::class);
$serviceConfigurationManager = $container->get(ServiceConfigurationManager::class);
/** @var MessengerServiceRunner $runner */
$runner = $runnerManager->getRunner($serviceConfigurationManager->getRunnerAliasForServiceId($serviceName));
$runner->setServiceId(new ServiceIdentifier($serviceName));
$runner->doRun($messagesTotal, 0);
$rClass = new \ReflectionClass(AbstractServiceRunner::class);
$value = $rClass->getProperty('stopRequested');
$value->setAccessible(true);
$this->assertTrue($value->getValue($runner));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NULL');
$this->assertSame(10, (int) $c->fetchOne());
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NOT NULL');
// Other message has been deleted, only last processed message is keep
$this->assertSame(1, (int) $c->fetchOne());
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Unit\MessengerIntegration;
require_once \dirname(__DIR__, 2).'/Win32serviceState.php';
use Doctrine\DBAL\Driver\Connection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Win32Service\Model\AbstractServiceRunner;
use Win32Service\Model\ServiceIdentifier;
use Win32Service\Model\Win32serviceState;
use Win32ServiceBundle\Model\MessengerServiceRunner;
use Win32ServiceBundle\Service\RunnerManager;
use Win32ServiceBundle\Service\ServiceConfigurationManager;
use Win32ServiceBundle\Tests\Application\Event\TestMemoryLimitMessage;
use Win32ServiceBundle\Tests\Application\Event\TestMessage;
final class MemoryLimitMessageTest extends KernelTestCase
{
protected function setUp(): void
{
Win32serviceState::reset();
}
protected function tearDown(): void
{
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->rollBack();
}
public function testMemoryLimitMessage(): void
{
$serviceName = 'win32service.demo.messenger.async.0';
self::bootKernel();
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->beginTransaction();
$connexion->query('DELETE FROM messenger_messages');
/** @var MessageBusInterface $messengerBus */
$messengerBus = $container->get('messenger.bus.default');
$messengerBus->dispatch(new TestMemoryLimitMessage( /* 129 Mio */1024 * 1024 * 129));
$messengerBus->dispatch(new TestMessage('message 1'));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\'');
$this->assertSame(2, (int) $c->fetchOne());
$runnerManager = $container->get(RunnerManager::class);
$serviceConfigurationManager = $container->get(ServiceConfigurationManager::class);
/** @var MessengerServiceRunner $runner */
$runner = $runnerManager->getRunner($serviceConfigurationManager->getRunnerAliasForServiceId($serviceName));
$runner->setServiceId(new ServiceIdentifier($serviceName));
$runner->doRun(5, 0);
$rClass = new \ReflectionClass(AbstractServiceRunner::class);
$value = $rClass->getProperty('stopRequested');
$value->setAccessible(true);
$this->assertTrue($value->getValue($runner));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NULL');
$this->assertSame(1, (int) $c->fetchOne());
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NOT NULL');
$this->assertSame(1, (int) $c->fetchOne());
}
}

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Unit\MessengerIntegration;
require_once \dirname(__DIR__, 2).'/Win32serviceState.php';
use Doctrine\DBAL\Driver\Connection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Win32Service\Model\ServiceIdentifier;
use Win32Service\Model\Win32serviceState;
use Win32ServiceBundle\Model\MessengerServiceRunner;
use Win32ServiceBundle\Service\RunnerManager;
use Win32ServiceBundle\Service\ServiceConfigurationManager;
use Win32ServiceBundle\Tests\Application\Event\TestMessage;
final class MessageTest extends KernelTestCase
{
protected function setUp(): void
{
Win32serviceState::reset();
}
protected function tearDown(): void
{
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->rollBack();
}
public function testNormalMessage(): void
{
$serviceName = 'win32service.demo.messenger.async.0';
self::bootKernel();
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->beginTransaction();
$connexion->query('DELETE FROM messenger_messages');
/** @var MessageBusInterface $messengerBus */
$messengerBus = $container->get('messenger.bus.default');
$messengerBus->dispatch(new TestMessage('message 1'));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\'');
$this->assertSame(1, (int) $c->fetchOne());
$runnerManager = $container->get(RunnerManager::class);
$serviceConfigurationManager = $container->get(ServiceConfigurationManager::class);
/** @var MessengerServiceRunner $runner */
$runner = $runnerManager->getRunner($serviceConfigurationManager->getRunnerAliasForServiceId($serviceName));
$runner->setServiceId(new ServiceIdentifier($serviceName));
$runner->doRun(1, 0);
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NULL');
$this->assertSame(0, (int) $c->fetchOne());
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NOT NULL');
$this->assertSame(1, (int) $c->fetchOne());
}
}

View File

@@ -10,6 +10,7 @@ use Doctrine\DBAL\Driver\Connection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Win32Service\Model\ServiceIdentifier;
use Win32Service\Model\Win32serviceState;
use Win32ServiceBundle\Model\MessengerServiceRunner;
use Win32ServiceBundle\Service\RunnerManager;
use Win32ServiceBundle\Service\ServiceConfigurationManager;
@@ -17,6 +18,11 @@ use Win32ServiceBundle\Tests\Application\Event\TestRetryMessage;
final class RetryMessageTest extends KernelTestCase
{
protected function setUp(): void
{
Win32serviceState::reset();
}
protected function tearDown(): void
{
$container = static::getContainer();

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Win32ServiceBundle\Tests\Unit\MessengerIntegration;
require_once \dirname(__DIR__, 2).'/Win32serviceState.php';
use Doctrine\DBAL\Driver\Connection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\MessageBusInterface;
use Win32Service\Model\AbstractServiceRunner;
use Win32Service\Model\ServiceIdentifier;
use Win32Service\Model\Win32serviceState;
use Win32ServiceBundle\Model\MessengerServiceRunner;
use Win32ServiceBundle\Service\RunnerManager;
use Win32ServiceBundle\Service\ServiceConfigurationManager;
use Win32ServiceBundle\Tests\Application\Event\TestMessage;
use Win32ServiceBundle\Tests\Application\Event\TestTimeLimitMessage;
final class TimeLimitMessageTest extends KernelTestCase
{
protected function setUp(): void
{
Win32serviceState::reset();
}
protected function tearDown(): void
{
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->rollBack();
}
public function testTimeLimitMessage(): void
{
$serviceName = 'win32service.demo.messenger.async.0';
self::bootKernel();
$container = static::getContainer();
/** @var Connection $connexion */
$connexion = $container->get('doctrine.dbal.default_connection');
$connexion->beginTransaction();
$connexion->query('DELETE FROM messenger_messages');
/** @var MessageBusInterface $messengerBus */
$messengerBus = $container->get('messenger.bus.default');
$messengerBus->dispatch(new TestTimeLimitMessage(2));
$messengerBus->dispatch(new TestMessage('message 1'));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\'');
$this->assertSame(2, (int) $c->fetchOne());
$runnerManager = $container->get(RunnerManager::class);
$serviceConfigurationManager = $container->get(ServiceConfigurationManager::class);
/** @var MessengerServiceRunner $runner */
$runner = $runnerManager->getRunner($serviceConfigurationManager->getRunnerAliasForServiceId($serviceName));
$runner->setServiceId(new ServiceIdentifier($serviceName));
$runner->doRun(5, 0);
$rClass = new \ReflectionClass(AbstractServiceRunner::class);
$value = $rClass->getProperty('stopRequested');
$value->setAccessible(true);
$this->assertTrue($value->getValue($runner));
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NULL');
$this->assertSame(1, (int) $c->fetchOne());
$c = $connexion->query('SELECT count(*) FROM messenger_messages WHERE queue_name = \'default\' AND delivered_at IS NOT NULL');
$this->assertSame(1, (int) $c->fetchOne());
}
}

View File

@@ -2,6 +2,10 @@
declare(strict_types=1);
/**
* Mock for service library abstact.
*/
namespace Win32Service\Model;
function win32_start_service_ctrl_dispatcher(string $serviceName): bool
@@ -38,6 +42,11 @@ class Win32serviceState
return self::$instance;
}
public static function reset(): void
{
self::$instance = null;
}
public function setServiceName(string $serviceName): bool
{
if ($this->serviceName === null) {