Completed
Pull Request — master (#34)
by Christian
16:56 queued 11:08
created

ClientTest::testDropServer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

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