Passed
Pull Request — master (#13)
by
unknown
01:39
created

testRequestWithIgnoredStatusCodeFamily()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
c 1
b 0
f 0
dl 0
loc 22
rs 9.8333
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
use GuzzleHttp\Client;
4
use GuzzleHttp\Exception\ConnectException;
5
use GuzzleHttp\HandlerStack;
6
use LeoCarmo\CircuitBreaker\Adapters\SwooleTableAdapter;
7
use LeoCarmo\CircuitBreaker\CircuitBreaker;
8
use LeoCarmo\CircuitBreaker\CircuitBreakerException;
9
use LeoCarmo\CircuitBreaker\GuzzleMiddleware;
10
use PHPUnit\Framework\TestCase;
11
12
class GuzzleMiddlewareTest extends TestCase
13
{
14
    public function testSuccessRequest()
15
    {
16
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testSuccessRequest');
17
18
        // Set the first failure and the failure threshold
19
        $circuit->setSettings(['failureRateThreshold' => 2]);
20
        $circuit->failure();
21
22
        $handler = new GuzzleMiddleware($circuit);
23
        $handlers = HandlerStack::create();
24
        $handlers->push($handler);
25
26
        $client = new Client(['handler' => $handlers, 'verify' => false]);
27
        $response = $client->get('leocarmo.dev');
28
29
        // After a success response the failures must be reset and the circuit is available
30
        $this->assertEquals(200, $response->getStatusCode());
31
        $this->assertTrue($circuit->isAvailable());
32
33
        // Set another failure to ensure that the previous failure was reset and a new fail will not open the circuit
34
        $circuit->failure();
35
        $this->assertTrue($circuit->isAvailable());
36
    }
37
38
    public function testSuccessRequestWithCustomStatusCode()
39
    {
40
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testRequestWithCustomStatusCode');
41
42
        // Set the first failure and the failure threshold
43
        $circuit->setSettings(['failureRateThreshold' => 2]);
44
        $circuit->failure();
45
46
        $handler = new GuzzleMiddleware($circuit);
47
        $handler->setCustomSuccessCodes([403]);
48
49
        $handlers = HandlerStack::create();
50
        $handlers->push($handler);
51
52
        $client = new Client(['handler' => $handlers, 'verify' => false, 'http_errors' => false]);
53
54
        // After a success response the failures must be reset and the circuit is available
55
        $this->assertEquals(1, $circuit->getFailuresCounter());
56
        $response = $client->get('https://httpstat.us/403');
57
        $this->assertEquals(403, $response->getStatusCode());
58
        $this->assertEquals(0, $circuit->getFailuresCounter());
59
        $this->assertTrue($circuit->isAvailable());
60
61
        // Set another failure to ensure that the previous failure was reset and a new fail will not open the circuit
62
        $circuit->failure();
63
        $this->assertTrue($circuit->isAvailable());
64
    }
65
66
    public function testSuccessRequestWithCustomStatusCodeFamily()
67
    {
68
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testRequestWithCustomStatusCode');
69
70
        // Set the first failure and the failure threshold
71
        $circuit->setSettings(['failureRateThreshold' => 2]);
72
        $circuit->failure();
73
74
        $handler = new GuzzleMiddleware($circuit);
75
        $handler->setCustomSuccessFamily(500);
76
77
        $handlers = HandlerStack::create();
78
        $handlers->push($handler);
79
80
        $client = new Client(['handler' => $handlers, 'verify' => false, 'http_errors' => false]);
81
82
        // After a success response the failures must be reset and the circuit is available
83
        $this->assertEquals(1, $circuit->getFailuresCounter());
84
        $response = $client->get('https://httpstat.us/502');
85
        $this->assertEquals(502, $response->getStatusCode());
86
        $this->assertEquals(0, $circuit->getFailuresCounter());
87
        $this->assertTrue($circuit->isAvailable());
88
89
        // Set another failure to ensure that the previous failure was reset and a new fail will not open the circuit
90
        $circuit->failure();
91
        $this->assertTrue($circuit->isAvailable());
92
    }
93
94
    public function testRequestWithIgnoredStatusCode()
95
    {
96
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testRequestWithCustomStatusCode');
97
98
        // Set the first failure and the failure threshold
99
        $circuit->setSettings(['failureRateThreshold' => 2]);
100
        $circuit->failure();
101
102
        $handler = new GuzzleMiddleware($circuit);
103
        $handler->setCustomIgnoreCodes([412]);
104
105
        $handlers = HandlerStack::create();
106
        $handlers->push($handler);
107
108
        $client = new Client(['handler' => $handlers, 'verify' => false, 'http_errors' => false]);
109
110
        // After an ignored status code, nothing will change on failure counter
111
        $this->assertEquals(1, $circuit->getFailuresCounter());
112
        $response = $client->get('https://httpstat.us/412');
113
        $this->assertEquals(412, $response->getStatusCode());
114
        $this->assertEquals(1, $circuit->getFailuresCounter());
115
        $this->assertTrue($circuit->isAvailable());
116
    }
117
118
    public function testRequestWithIgnoredStatusCodeFamily()
119
    {
120
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testRequestWithCustomStatusCode');
121
122
        // Set the first failure and the failure threshold
123
        $circuit->setSettings(['failureRateThreshold' => 2]);
124
        $circuit->failure();
125
126
        $handler = new GuzzleMiddleware($circuit);
127
        $handler->setCustomIgnoreFamily(400);
128
129
        $handlers = HandlerStack::create();
130
        $handlers->push($handler);
131
132
        $client = new Client(['handler' => $handlers, 'verify' => false, 'http_errors' => false]);
133
134
        // After an ignored status code, nothing will change on failure counter
135
        $this->assertEquals(1, $circuit->getFailuresCounter());
136
        $response = $client->get('https://httpstat.us/412');
137
        $this->assertEquals(412, $response->getStatusCode());
138
        $this->assertEquals(1, $circuit->getFailuresCounter());
139
        $this->assertTrue($circuit->isAvailable());
140
    }
141
142
    public function testCircuitIsNotAvailable()
143
    {
144
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testCircuitIsNotAvailable');
145
146
        $circuit->setSettings(['failureRateThreshold' => 2]);
147
        $circuit->failure();
148
        $circuit->failure();
149
150
        $this->assertEquals(2, $circuit->getFailuresCounter());
151
152
        $handler = new GuzzleMiddleware($circuit);
153
        $handlers = HandlerStack::create();
154
        $handlers->push($handler);
155
156
        $client = new Client(['handler' => $handlers, 'verify' => false]);
157
158
        $this->expectException(CircuitBreakerException::class);
159
160
        $client->get('leocarmo.dev');
161
    }
162
163
    public function testFailureRequest()
164
    {
165
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testFailureRequest');
166
167
        $circuit->setSettings(['failureRateThreshold' => 2]);
168
        $circuit->failure();
169
170
        $handler = new GuzzleMiddleware($circuit);
171
        $handlers = HandlerStack::create();
172
        $handlers->push($handler);
173
174
        $client = new Client(['handler' => $handlers, 'verify' => false]);
175
176
        $this->expectException(\GuzzleHttp\Exception\ClientException::class);
177
178
        $client->get('leocarmo.dev/undefined');
179
180
        $this->assertEquals(2, $circuit->getFailuresCounter());
181
        $this->assertFalse($circuit->isAvailable());
182
    }
183
184
    public function testFailureRequestToUnknownHost()
185
    {
186
        $circuit = new CircuitBreaker(new SwooleTableAdapter(), 'testFailureRequest');
187
188
        $circuit->setSettings(['failureRateThreshold' => 2]);
189
        $circuit->failure();
190
191
        $handler = new GuzzleMiddleware($circuit);
192
        $handlers = HandlerStack::create();
193
        $handlers->push($handler);
194
195
        $client = new Client(['handler' => $handlers, 'verify' => false]);
196
197
        try {
198
            $client->get('undefined_host.dev');
199
        } catch (\Throwable $exception) {
200
            $this->assertInstanceOf(ConnectException::class, $exception);
201
        }
202
203
        $this->assertEquals(2, $circuit->getFailuresCounter());
204
        $this->assertFalse($circuit->isAvailable());
205
    }
206
}