Skip to content

Commit

Permalink
PredisCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
0leksandr committed Aug 9, 2024
1 parent f84e628 commit ca5b575
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 6 deletions.
64 changes: 64 additions & 0 deletions src/Check/PredisCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace SymfonyHealthCheckBundle\Check;

use Symfony\Component\DependencyInjection\ContainerInterface;
use SymfonyHealthCheckBundle\Dto\Response;
use Throwable;

class PredisCheck implements CheckInterface
{
public const PREDIS_CLIENT_CLASS = 'Predis\ClientInterface';

private const NAME = 'predis';

private ContainerInterface $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function check(): Response
{
if (!$client = $this->getPredisClient()) {
return new Response(self::NAME, false, 'Predis Client not found');
}

$key = 'test-' . time() . random_int(0, 1000);
try {
if ($client->get($key) !== null) {
return new Response(self::NAME, false, 'Unable to check predis status');
}

$value = '1';
$client->set($key, $value);
if ($client->get($key) === $value) {
$client->del($key);
return new Response(self::NAME, true, 'ok');
} else {
return new Response(self::NAME, false, 'Predis is not functional');
}
} catch (Throwable $throwable) {
return new Response(self::NAME, false, 'Could not check predis status: ' . $throwable->getMessage());
}
}

private function getPredisClient(): ?object
{
foreach (
[
self::PREDIS_CLIENT_CLASS,
'SymfonyBundles\RedisBundle\Redis\ClientInterface',
] as $class
) {
if ($this->container->has($class)) {
return $this->container->get($class);
}
}

return null;
}
}
3 changes: 3 additions & 0 deletions src/Resources/config/health_checks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
<argument type="service" id="service_container"/>
</service>
<service id="symfony_health_check.status_up_check" class="SymfonyHealthCheckBundle\Check\StatusUpCheck"/>
<service id="symfony_health_check.predis_check" class="SymfonyHealthCheckBundle\Check\PredisCheck">
<argument type="service" id="service_container"/>
</service>
</services>
</container>
19 changes: 19 additions & 0 deletions tests/Integration/Controller/HealthControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use SymfonyHealthCheckBundle\Check\DoctrineCheck;
use SymfonyHealthCheckBundle\Check\EnvironmentCheck;
use SymfonyHealthCheckBundle\Check\PredisCheck;
use SymfonyHealthCheckBundle\Check\StatusUpCheck;
use SymfonyHealthCheckBundle\Controller\HealthController;
use TypeError;
Expand Down Expand Up @@ -77,6 +78,24 @@ public function testDoctrineCheckServiceNotFoundException(): void
);
}

public function testPredisCheckServiceNotFoundException(): void
{
$healthController = new HealthController();
$healthController->addHealthCheck(new PredisCheck(new ContainerBuilder()));

$response = $healthController->check();
self::assertSame(200, $response->getStatusCode());
self::assertSame(
json_encode([[
'name' => 'predis',
'result' => false,
'message' => 'Predis Client not found',
'params' => [],
]]),
$response->getContent()
);
}

public function testTwoCheckSuccess(): void
{
$healthController = new HealthController();
Expand Down
19 changes: 19 additions & 0 deletions tests/Integration/Controller/PingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use SymfonyHealthCheckBundle\Check\DoctrineCheck;
use SymfonyHealthCheckBundle\Check\EnvironmentCheck;
use SymfonyHealthCheckBundle\Check\PredisCheck;
use SymfonyHealthCheckBundle\Check\StatusUpCheck;
use SymfonyHealthCheckBundle\Controller\PingController;
use TypeError;
Expand Down Expand Up @@ -77,6 +78,24 @@ public function testDoctrineCheckServiceNotFoundException(): void
);
}

public function testPredisCheckServiceNotFoundException(): void
{
$healthController = new PingController();
$healthController->addHealthCheck(new PredisCheck(new ContainerBuilder()));

$response = $healthController->check();
self::assertSame(200, $response->getStatusCode());
self::assertSame(
json_encode([[
'name' => 'predis',
'result' => false,
'message' => 'Predis Client not found',
'params' => [],
]]),
$response->getContent()
);
}

public function testTwoCheckSuccess(): void
{
$pingController = new PingController();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,18 @@ public function testWithFullConfig(): void
{
$container = $this->createContainerFromFixture('filled_bundle_config');

self::assertCount(6, $container->getDefinitions());
self::assertArrayHasKey(HealthController::class, $container->getDefinitions());
self::assertArrayHasKey(PingController::class, $container->getDefinitions());
self::assertArrayHasKey('symfony_health_check.doctrine_check', $container->getDefinitions());
self::assertArrayHasKey('symfony_health_check.environment_check', $container->getDefinitions());
self::assertArrayHasKey('symfony_health_check.status_up_check', $container->getDefinitions());
self::assertSame(
[
'service_container',
HealthController::class,
PingController::class,
'symfony_health_check.doctrine_check',
'symfony_health_check.environment_check',
'symfony_health_check.status_up_check',
'symfony_health_check.predis_check',
],
array_keys($container->getDefinitions()),
);
}

private function createContainerFromFixture(string $fixtureFile): ContainerBuilder
Expand Down
98 changes: 98 additions & 0 deletions tests/Unit/Check/PredisCheckTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

namespace SymfonyHealthCheckBundle\Tests\Unit\Check;

use Exception;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Container;
use SymfonyHealthCheckBundle\Check\PredisCheck;
use SymfonyHealthCheckBundle\Dto\Response;

class PredisCheckTest extends TestCase
{
/**
* @return array{
* predisClient: ?object,
* expectedResponse: Response,
* }[]
*/
public static function dataProvider(): array
{
return [
'no client' => [
'predisClient' => null,
'expectedResponse' => new Response('predis', false, 'Predis Client not found'),
],
'incorrectly initialized client' => [
'predisClient' => new class {
public function get(): string
{
return 'abracadabra';
}
},
'expectedResponse' => new Response('predis', false, 'Unable to check predis status'),
],
'exception' => [
'predisClient' => new class {
public function __call(string $name, array $args): string
{
throw new Exception('test');
}
},
'expectedResponse' => new Response('predis', false, 'Could not check predis status: test'),
],
'non-working client' => [
'predisClient' => new class {
public function set(): void
{
}

public function get(): ?string
{
return null;
}
},
'expectedResponse' => new Response('predis', false, 'Predis is not functional'),
],
'success' => [
'predisClient' => new class {
private array $data = [];

public function set(string $key, string $value): void
{
$this->data[$key] = $value;
}

public function get(string $key): ?string
{
return $this->data[$key] ?? null;
}

public function del(string $key): void
{
unset($this->data[$key]);
}
},
'expectedResponse' => new Response('predis', true, 'ok'),
],
];
}

/**
* @dataProvider dataProvider
*/
public function test(?object $predisClient, Response $expectedResponse): void
{
$container = new Container();
if ($predisClient) {
$container->set(PredisCheck::PREDIS_CLIENT_CLASS, $predisClient);
}

self::assertEquals(
$expectedResponse,
(new PredisCheck($container))->check(),
);
}
}

0 comments on commit ca5b575

Please sign in to comment.