Completed
Push — m/get-server-version ( c48523 )
by
unknown
04:39
created

ClientTest::testGetServerVersion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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