-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The distributed consumer in application tests stopped working correctly #386
Comments
Hey @lifinsky, I do think, it's because of the switch from Consume is based on subscription, so it does receive Messages in event-driven manner. This means it's not wasting time like You do use
Can you try with Consumer having time limit instead?
|
@dgafka Hi! I had a suspicion about this, I added sleep between sending the command and running the consumer - it doesn’t help, plus single test works (without running Ecotone multiple times between tests). |
Doesn't change anything |
I decided to debug this part of the code
First test output:
Second test...
But if just run it:
|
It looks like on second Ecotone run the dead letter will not be used and the message returns to the original queue |
@dgafka Even worse, the second distributed command does not reach the command handler |
@lifinsky can you provide an PR with this failure scenario? |
@dgafka This problem arises if several tests use the same service name for the producer and the consumer |
If create the EcotoneLite application once and sequentially start sending the distributed command and run consumer - everything is ok |
@dgafka If different Ecotone Lite instances use the same service name, then the second command message remains in the queue |
@lifinsky I see, so could you provide an scenarios like this, so I can have a reproducible test case?
I do believe, you won't face this problem on production. This is most likely due to reused connection, amqp extension has ability to freeze, when same channel is reused. I would expect, if you would close connection between each test, that would work. |
@dgafka What is the most correct way to close the connection after the test? How can we get the job done as efficiently as possible from the perspective of an already created EcotoneLite instance? |
For now we have decided to generate a unique service name in each application test (temporary solution) |
It also works if we create Ecotone Lite application once and share between tests, but I would like a safer and simpler way to test AMQP with EcotoneLite using application (system) tests. |
@lifinsky can you check if the fix with proxy generation has somehow fixed this? |
Now we have another problem: The "Psr\Log\LoggerInterface" service is already initialized, you cannot replace it. namespace Tests\Application\App\Console\Command;
...
final class InitCommandTest extends KernelTestCase
{
use WithHttpClient;
private LoggerInterface&MockObject $logger;
protected function setUp(): void
{
parent::setUp();
$this->response = json_decode(MockLoader::load('api.company.success.get-response'), true);
$this->logger = $this->createMock(LoggerInterface::class);
self::getContainer()->set(LoggerInterface::class, $this->logger);
} But with cache in var/cache/test directory the exception does not appear (second test run).
<?php
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
if (\class_exists(\ContainerYPbnv5K\Fcards_App_KernelTestContainer::class, false)) {
// no-op
} elseif (!include __DIR__.'/ContainerYPbnv5K/Fcards_App_KernelTestContainer.php') {
touch(__DIR__.'/ContainerYPbnv5K.legacy');
return;
}
if (!\class_exists(Fcards_App_KernelTestContainer::class, false)) {
\class_alias(\ContainerYPbnv5K\Fcards_App_KernelTestContainer::class, Fcards_App_KernelTestContainer::class, false);
}
return new \ContainerYPbnv5K\Fcards_App_KernelTestContainer([
'container.build_hash' => 'YPbnv5K',
'container.build_id' => '7d2f01c9',
'container.build_time' => 1729243145,
'container.runtime_mode' => \in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) ? 'web=0' : 'web=1',
], __DIR__.\DIRECTORY_SEPARATOR.'ContainerYPbnv5K'); |
Without cache Monolog\Logger was registered as private service. TestContainer: public function set(string $id, mixed $service): void
{
$container = $this->getPublicContainer();
$renamedId = $this->renamedIds[$id] ?? $id;
try {
$container->set($renamedId, $service);
} catch (InvalidArgumentException $e) {
if (!str_starts_with($e->getMessage(), "The \"$renamedId\" service is private")) {
throw $e;
}
if (isset($container->privates[$renamedId])) {
throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id));
}
$container->privates[$renamedId] = $service;
}
} |
Hmm, so main problem is fixed, it's just the Logger now? @jlabedo we did refactor the logging. Any thoughts on this? |
@dgafka I haven't tested it yet |
@dgafka Without a unique service name in each test - the problem appears on the second test as usual |
Hello there. It is hard to follow what the problem is now. |
This is a constant problem with application testing with Ecotone Symfony bundle. |
All services are public for test env, I don’t understand how this service was registered as private |
@jlabedo I found a solution for LoggerInterface mock: add to services_test.yaml: monolog.logger:
synthetic: true |
Ecotone version(s) affected: 1.229.0-latest
Description
We have tests that send a distributed command and check its processing with a delayed retry. After an update, we noticed that tests pass individually, but when running two or more, only one test passes. The remaining tests do not receive the message; it stays in the queue.
How to reproduce
First test for example:
Second test (separate test case):
EcotoneTestConfiguration:
When each test is run individually, everything works correctly. It also worked fine in all versions up to 1.228.
The purpose of the tests is to verify that, after reaching the maximum number of retries with a delay, an error event is sent to other services, while logging each failure at every attempt.
The text was updated successfully, but these errors were encountered: