Completed
Pull Request — master (#34)
by Christian
16:03 queued 12:30
created

ClientTest::testDropLastServer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 19
rs 9.4285
cc 1
eloc 13
nc 1
nop 0
1
<?php
2
/**
3
 * @author Antoine Hedgcock
4
 */
5
6
namespace CrateTest\PDO\Http;
7
8
use Crate\PDO\Exception\RuntimeException;
9
use Crate\Stdlib\Collection;
10
use Crate\PDO\Http\Client;
11
use Crate\PDO\Http\Server;
12
use GuzzleHttp\Exception\ClientException;
13
use GuzzleHttp\Exception\ConnectException;
14
use GuzzleHttp\Message\RequestInterface;
15
use GuzzleHttp\Message\Response;
16
use GuzzleHttp\Message\ResponseInterface;
17
use GuzzleHttp\Stream\Stream;
18
use PHPUnit_Framework_TestCase;
19
use ReflectionClass;
20
21
/**
22
 * Class ClientTest
23
 *
24
 * @property array singleServerArray
25
 * @property string testStmt
26
 * @coversDefaultClass \Crate\PDO\Http\Client
27
 * @covers ::<!public>
28
 *
29
 * @group unit
30
 */
31
class ClientTest extends PHPUnit_Framework_TestCase
32
{
33
    /**
34
     * @var array
35
     */
36
    private static $singleServerArray = ['localhost:4200'];
37
38
    /**
39
     * @var string
40
     */
41
    private static $testStmt = 'SELECT * FROM test_table';
42
43
    /**
44
     * @var Client
45
     */
46
    private $client;
47
48
    /**
49
     * @var \PHPUnit_Framework_MockObject_MockObject
50
     */
51
    private $server;
52
53
    /**
54
     * @covers ::__construct
55
     */
56
    protected function setUp()
57
    {
58
        $this->client = new Client($this->singleServerArray, []);
59
        $this->server = $this->getMockBuilder(Server::class)
60
            ->disableOriginalConstructor()
61
            ->getMock();
62
63
        $clientReflection = new ReflectionClass($this->client);
64
65
        $availableServers = $clientReflection->getProperty('availableServers');
66
        $availableServers->setAccessible(true);
67
        $availableServers->setValue($this->client, $this->singleServerArray);
68
69
        $serverPool = $clientReflection->getProperty('serverPool');
70
        $serverPool->setAccessible(true);
71
        $serverPool->setValue($this->client, [$this->singleServerArray[0] => $this->server]);
72
    }
73
74
    /**
75
     * @covers ::__construct
76
     */
77
    public function testMultiServerConstructor()
78
    {
79
        $servers = ['crate1:4200', 'crate2:4200', 'crate3:4200'];
80
        $client = new Client($servers, []);
81
        $clientReflection = new ReflectionClass($client);
82
83
        $p = $clientReflection->getProperty('availableServers');
84
        $p->setAccessible(true);
85
        $availableServers = $p->getValue($client);
86
        $this->assertEquals(3, count($availableServers));
87
88
        $p = $clientReflection->getProperty('serverPool');
89
        $p->setAccessible(true);
90
        $serverPool = $p->getValue($client);
91
        $this->assertEquals(3, count($serverPool));
92
    }
93
94
    /**
95
     * @covers ::nextServer
96
     */
97
    public function testNextServer()
98
    {
99
        $servers = ['crate1:4200', 'crate2:4200', 'crate3:4200'];
100
        $client = new Client($servers, []);
101
        $clientReflection = new ReflectionClass($client);
102
103
        $pAvailServers = $clientReflection->getProperty('availableServers');
104
        $pAvailServers->setAccessible(true);
105
        $pNextServer = $clientReflection->getMethod('nextServer');
106
        $pNextServer->setAccessible(true);
107
108
        $this->assertEquals('crate1:4200', $pNextServer->invoke($client));
109
        $this->assertEquals('crate2:4200', $pNextServer->invoke($client));
110
        $this->assertEquals('crate3:4200', $pNextServer->invoke($client));
111
        $this->assertEquals('crate1:4200', $pNextServer->invoke($client));
112
    }
113
114
    /**
115
     * @covers ::dropServer
116
     */
117
    public function testDropServer()
118
    {
119
        $servers = ['crate1:4200', 'crate2:4200'];
120
        $client = new Client($servers, []);
121
        $clientReflection = new ReflectionClass($client);
122
123
        $pAvailServers = $clientReflection->getProperty('availableServers');
124
        $pAvailServers->setAccessible(true);
125
        $pDropServer = $clientReflection->getMethod('dropServer');
126
        $pDropServer->setAccessible(true);
127
128
        $this->assertEquals(2, count($pAvailServers->getValue($client)));
129
        $pDropServer->invoke($client, 'crate2:4200', null);
130
        $this->assertEquals(1, count($pAvailServers->getValue($client)));
131
        $this->assertEquals(['crate1:4200'], $pAvailServers->getValue($client));
132
    }
133
134
    /**
135
     * @covers ::dropServer
136
     */
137
    public function testDropLastServer()
138
    {
139
        $servers = ['localhost:4200'];
140
        $client = new Client($servers, []);
141
        $clientReflection = new ReflectionClass($client);
142
143
144
        $this->setExpectedException(ConnectException::class, "No more servers available, exception from last server: Connection refused.");
145
        $ex = $this->getMock(ConnectException::class, null,
146
            ['Connection refused.', $this->getMock(RequestInterface::class), $this->getMock(ResponseInterface::class)]);
147
148
        $pDropServer = $clientReflection->getMethod('dropServer');
149
        $pDropServer->setAccessible(true);
150
        $pDropServer->invoke($client, 'localhost:4200');
151
152
        $pRaiseIfNoServers = $clientReflection->getMethod('raiseIfNoMoreServers');
153
        $pRaiseIfNoServers->setAccessible(true);
154
        $pRaiseIfNoServers->invoke($client, $ex);
155
    }
156
157
    /**
158
     * Create a response to be used
159
     *
160
     * @param int   $statusCode
161
     * @param array $body
162
     *
163
     * @return Response
164
     */
165
    private function createResponse($statusCode, array $body)
166
    {
167
        $body = Stream::factory(json_encode($body));
168
169
        return new Response($statusCode, [], $body);
170
    }
171
172
    /**
173
     * @covers ::execute
174
     */
175
    public function testExecuteWithResponseFailure()
176
    {
177
        $code    = 1337;
178
        $message = 'hello world';
179
180
        $this->setExpectedException(RuntimeException::class, $message, $code);
181
182
        $request = $this->getMock(RequestInterface::class);
183
        $response = $this->createResponse(400, ['error' => ['code' => $code, 'message' => $message]]);
184
185
        $exception = ClientException::create($request, $response);
186
187
        $this->server
188
            ->expects($this->once())
189
            ->method('doRequest')
190
            ->will($this->throwException($exception));
191
192
        $this->client->execute($this->testStmt, ['foo' => 'bar']);
193
    }
194
195
    /**
196
     * @covers ::execute
197
     */
198
    public function testExecute()
199
    {
200
        $body = [
201
            'cols'     => ['id', 'name'],
202
            'rows'     => [],
203
            'rowcount' => 0,
204
            'duration' => 0
205
        ];
206
207
        $response = $this->createResponse(200, $body);
208
209
        $this->server
210
            ->expects($this->once())
211
            ->method('doRequest')
212
            ->will($this->returnValue($response));
213
214
        $result = $this->client->execute($this->testStmt, ['foo' => 'bar']);
215
216
        $this->assertInstanceOf(Collection::class, $result);
217
    }
218
219
}
220