Passed
Pull Request — master (#10)
by Leonardo
01:41
created

AdaptersTest::testSetAdapter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 2
c 1
b 0
f 1
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
use LeoCarmo\CircuitBreaker\Adapters\AdapterInterface;
4
use LeoCarmo\CircuitBreaker\Adapters\SwooleTableAdapter;
5
use LeoCarmo\CircuitBreaker\CircuitBreaker;
6
use LeoCarmo\CircuitBreaker\Adapters\RedisAdapter;
7
use PHPUnit\Framework\TestCase;
8
9
class AdaptersTest extends TestCase
10
{
11
    public function testCreateRedisAdapter()
12
    {
13
        $redis = new \Redis();
14
        $redis->connect(getenv('REDIS_HOST'));
15
        $adapter = new RedisAdapter($redis, 'my-product');
16
17
        $this->assertInstanceOf(AdapterInterface::class, $adapter);
18
19
        return $adapter;
20
    }
21
22
    public function testCreateSwooleTableAdapter()
23
    {
24
        $adapter = new SwooleTableAdapter();
25
        $this->assertInstanceOf(AdapterInterface::class, $adapter);
26
        return $adapter;
27
    }
28
29
    public function provideAdapters()
30
    {
31
        return [
32
            'redis' => [$this->testCreateRedisAdapter()],
33
            'swoole-table' => [$this->testCreateSwooleTableAdapter()],
34
        ];
35
    }
36
37
    /**
38
     * @dataProvider provideAdapters
39
     */
40
    public function testSetAdapter(AdapterInterface $adapter)
41
    {
42
        $circuitBreaker = new CircuitBreaker($adapter, 'testSetAdapter');
43
44
        $this->assertInstanceOf(AdapterInterface::class, $circuitBreaker->getAdapter());
45
    }
46
47
    /**
48
     * @dataProvider provideAdapters
49
     */
50
    public function testOpenCircuit(AdapterInterface $adapter)
51
    {
52
        $circuitBreaker = new CircuitBreaker($adapter, 'testOpenCircuit');
53
54
        $circuitBreaker->setSettings([
55
            'timeWindow' => 20,
56
            'failureRateThreshold' => 5,
57
            'intervalToHalfOpen' => 10,
58
        ]);
59
60
        $circuitBreaker->failure();
61
        $circuitBreaker->failure();
62
        $circuitBreaker->failure();
63
        $circuitBreaker->failure();
64
        $circuitBreaker->failure();
65
66
        $this->assertFalse($circuitBreaker->isAvailable());
67
    }
68
69
    /**
70
     * @dataProvider provideAdapters
71
     */
72
    public function testReachFailureRateAfterTimeWindow(AdapterInterface $adapter)
73
    {
74
        $circuitBreaker = new CircuitBreaker($adapter, 'testReachFailureRateAfterTimeWindow');
75
76
        $circuitBreaker->setSettings([
77
            'timeWindow' => 2,
78
            'failureRateThreshold' => 2,
79
            'intervalToHalfOpen' => 10,
80
        ]);
81
82
        $circuitBreaker->failure();
83
        $circuitBreaker->failure();
84
        $circuitBreaker->failure();
85
86
        sleep(3);
87
88
        $this->assertTrue($circuitBreaker->isAvailable());
89
    }
90
91
    /**
92
     * @dataProvider provideAdapters
93
     */
94
    public function testCloseCircuitSuccess(AdapterInterface $adapter)
95
    {
96
        $circuitBreaker = new CircuitBreaker($adapter, 'testCloseCircuitSuccess');
97
98
        $circuitBreaker->setSettings([
99
            'timeWindow' => 20,
100
            'failureRateThreshold' => 1,
101
            'intervalToHalfOpen' => 10,
102
        ]);
103
104
        $circuitBreaker->failure();
105
        $circuitBreaker->failure();
106
107
        $this->assertFalse($circuitBreaker->isAvailable());
108
109
        $circuitBreaker->success();
110
111
        $this->assertTrue($circuitBreaker->isAvailable());
112
    }
113
114
    /**
115
     * @dataProvider provideAdapters
116
     */
117
    public function testHalfOpenFailAndOpenCircuit(AdapterInterface $adapter)
118
    {
119
        $circuitBreaker = new CircuitBreaker($adapter, 'testHalfOpenFailAndOpenCircuit');
120
121
        $circuitBreaker->setSettings([
122
            'timeWindow' => 1,
123
            'failureRateThreshold' => 3,
124
            'intervalToHalfOpen' => 15,
125
        ]);
126
127
        $circuitBreaker->failure();
128
        $circuitBreaker->failure();
129
        $circuitBreaker->failure();
130
131
        // Check if is available for open circuit
132
        $this->assertFalse($circuitBreaker->isAvailable());
133
134
        // Sleep for half open
135
        sleep(2);
136
137
        // Register new failure
138
        $circuitBreaker->failure();
139
140
        // Check if is open
141
        $this->assertFalse($circuitBreaker->isAvailable());
142
    }
143
}
144