Skip to content

Commit

Permalink
Add test for redis storage
Browse files Browse the repository at this point in the history
  • Loading branch information
stfndamjanovic committed Jan 24, 2024
1 parent dec6632 commit 79f668f
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ jobs:
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Setup redis
uses: supercharge/[email protected]
with:
redis-version: 6

- name: Install dependencies
run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction

Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@
<directory suffix=".php">./src</directory>
</include>
</source>
<php>
<env name="REDIS_HOST" value="127.0.0.1"/>
</php>
</phpunit>
27 changes: 27 additions & 0 deletions tests/CircuitBreakerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Stfn\CircuitBreaker\Exceptions\CircuitForceOpenException;
use Stfn\CircuitBreaker\Exceptions\CircuitHalfOpenFailException;
use Stfn\CircuitBreaker\Exceptions\CircuitOpenException;
use Stfn\CircuitBreaker\Storage\InMemoryStorage;
use Stfn\CircuitBreaker\Storage\RedisStorage;

class CircuitBreakerTest extends TestCase
{
Expand All @@ -29,6 +31,8 @@ public function test_if_it_can_handle_function_success()
});

$this->assertEquals($object, $result);

$this->assertTrue($breaker->isClosed());
}

public function test_if_it_will_throw_an_exception_if_circuit_breaker_is_open()
Expand Down Expand Up @@ -121,6 +125,18 @@ public function test_if_it_will_transit_back_to_open_state_after_first_fail()
$this->assertTrue($breaker->isOpen());
}

public function test_if_it_will_transit_to_half_open_state_after_recovery_time()
{
$breaker = CircuitBreaker::for('test')->withOptions(['recovery_time' => 1]);
$breaker->openCircuit();

sleep(2);

$breaker->call(fn () => true);

$this->assertEquals(CircuitState::HalfOpen, $breaker->getStorage()->getState());
}

public function test_if_listener_is_called()
{
$object = new class () extends CircuitBreakerListener {
Expand Down Expand Up @@ -250,4 +266,15 @@ public function onStateChange(CircuitBreaker $breaker, CircuitState $previousSta

$this->assertEquals("closed->open,open->half_open,half_open->closed,closed->force_open,", $object->state);
}

public function test_if_it_can_set_a_new_storage()
{
$breaker = CircuitBreaker::for('test');

$this->assertInstanceOf(InMemoryStorage::class, $breaker->getStorage());

$breaker->storage(new RedisStorage(new \Redis()));

$this->assertInstanceOf(RedisStorage::class, $breaker->getStorage());
}
}
2 changes: 2 additions & 0 deletions tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ public function test_if_it_can_set_valid_config()
$this->assertEquals($setup['failure_threshold'], $config->failureThreshold);
$this->assertEquals($setup['recovery_time'], $config->recoveryTime);
$this->assertEquals($setup['sample_duration'], $config->sampleDuration);

$this->assertEquals($setup, $config->toArray());
}
}
108 changes: 108 additions & 0 deletions tests/Storage/RedisStorageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace Stfn\CircuitBreaker\Tests\Storage;

use PHPUnit\Framework\TestCase;
use Stfn\CircuitBreaker\CircuitBreaker;
use Stfn\CircuitBreaker\CircuitState;
use Stfn\CircuitBreaker\Storage\RedisStorage;

class RedisStorageTest extends TestCase
{
protected \Redis|null $redis = null;

public function test_if_will_set_closed_state_on_init()
{
$storage = new RedisStorage($this->getRedisInstance());

$storage->init(CircuitBreaker::for('test'));

$this->assertEquals(CircuitState::Closed, $storage->getState());
}

public function test_if_set_state_will_change_value()
{
$storage = new RedisStorage($this->getRedisInstance());

$storage->init(CircuitBreaker::for('test'));

$this->assertEquals(CircuitState::Closed, $storage->getState());

$storage->setState(CircuitState::HalfOpen);

$this->assertEquals(CircuitState::HalfOpen, $storage->getState());
}

public function test_if_increment_failure_will_increase_number_of_failures()
{
$storage = new RedisStorage($this->getRedisInstance());

$storage->init(CircuitBreaker::for('test'));

$this->assertEquals(0, $storage->getNumberOfFailures());

$storage->incrementFailure();

$this->assertEquals(1, $storage->getNumberOfFailures());

$storage->incrementFailure();


$this->assertEquals(2, $storage->getNumberOfFailures());
}

public function test_if_reset_counter_will_remove_fail_count()
{
$storage = new RedisStorage($this->getRedisInstance());
$storage->init(CircuitBreaker::for('test'));

$storage->incrementFailure();
$storage->incrementFailure();
$storage->incrementFailure();

$this->assertEquals(3, $storage->getNumberOfFailures());

$storage->resetCounter();

$this->assertEquals(0, $storage->getNumberOfFailures());
}

public function test_transition_to_open_state()
{
$storage = new RedisStorage($this->getRedisInstance());
$storage->init(CircuitBreaker::for('test'));

$storage->open();

$this->assertEquals(CircuitState::Open, $storage->getState());
$this->assertEquals(0, $storage->getNumberOfFailures());
$this->assertNotEquals(0, $storage->openedAt());
}

public function test_transition_to_closed_state()
{
$storage = new RedisStorage($this->getRedisInstance());
$storage->init(CircuitBreaker::for('test'));

$storage->open();
$storage->close();

$this->assertEquals(CircuitState::Closed, $storage->getState());
$this->assertEquals(0, $storage->openedAt());
}

public function getRedisInstance()
{
if (! $this->redis) {
$this->redis = new \Redis();
$this->redis->connect(getenv("REDIS_HOST"));
}

return $this->redis;
}

public function tearDown(): void
{
$this->getRedisInstance()->flushDB();
}
}

0 comments on commit 79f668f

Please sign in to comment.