Completed
Push — h/multiple-servers ( 562c3a )
by Christian
06:27
created

ClientTest::testGetServerInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4286
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\Stdlib\Collection;
10
use Crate\PDO\Http\Client;
11
use Crate\PDO\Http\ServerInterface;
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
    const SINGLE_SERVER = ['localhost:4200'];
32
    const SQL = 'SELECT * FROM test_table';
33
34
    /**
35
     * @var Client
36
     */
37
    private $client;
38
39
    /**
40
     * @var ServerInterface
41
     */
42
    private $server;
43
44
    /**
45
     * @covers ::__construct
46
     */
47
    protected function setUp()
48
    {
49
        $this->client = new Client(self::SINGLE_SERVER, []);
50
        $this->server = $this->getMock(ServerInterface::class);
51
52
        $clientReflection = new ReflectionClass(Client::class);
53
54
        $availableServers = $clientReflection->getProperty('availableServers');
55
        $availableServers->setAccessible(true);
56
        $availableServers->setValue($this->client, self::SINGLE_SERVER);
57
58
        $serverPool = $clientReflection->getProperty('serverPool');
59
        $serverPool->setAccessible(true);
60
        $serverPool->setValue($this->client, [self::SINGLE_SERVER[0] => $this->server]);
61
    }
62
63
    /**
64
     * @covers ::__construct
65
     */
66
    public function testMultiServerConstructor()
67
    {
68
        $servers = ['crate1:4200', 'crate2:4200', 'crate3:4200'];
69
        $client = new Client($servers, []);
70
        $clientReflection = new ReflectionClass($client);
71
72
        $p = $clientReflection->getProperty('availableServers');
73
        $p->setAccessible(true);
74
        $availableServers = $p->getValue($client);
75
        $this->assertEquals(3, count($availableServers));
76
77
        $p = $clientReflection->getProperty('serverPool');
78
        $p->setAccessible(true);
79
        $serverPool = $p->getValue($client);
80
        $this->assertEquals(3, count($serverPool));
81
    }
82
83
    /**
84
     * @covers ::nextServer
85
     */
86
    public function testNextServer()
87
    {
88
        $servers = ['crate1:4200', 'crate2:4200', 'crate3:4200'];
89
        $client = new Client($servers, []);
90
        $clientReflection = new ReflectionClass($client);
91
92
        $pAvailServers = $clientReflection->getProperty('availableServers');
93
        $pAvailServers->setAccessible(true);
94
        $pNextServer = $clientReflection->getMethod('nextServer');
95
        $pNextServer->setAccessible(true);
96
97
        $this->assertEquals('crate1:4200', $pNextServer->invoke($client));
98
        $this->assertEquals('crate2:4200', $pNextServer->invoke($client));
99
        $this->assertEquals('crate3:4200', $pNextServer->invoke($client));
100
        $this->assertEquals('crate1:4200', $pNextServer->invoke($client));
101
    }
102
103
    /**
104
     * @covers ::dropServer
105
     */
106
    public function testDropServer()
107
    {
108
        $servers = ['crate1:4200', 'crate2:4200'];
109
        $client = new Client($servers, []);
110
        $clientReflection = new ReflectionClass($client);
111
112
        $pAvailServers = $clientReflection->getProperty('availableServers');
113
        $pAvailServers->setAccessible(true);
114
        $pDropServer = $clientReflection->getMethod('dropServer');
115
        $pDropServer->setAccessible(true);
116
117
        $this->assertEquals(2, count($pAvailServers->getValue($client)));
118
        $pDropServer->invoke($client, 'crate2:4200', null);
119
        $this->assertEquals(1, count($pAvailServers->getValue($client)));
120
        $this->assertEquals(['crate1:4200'], $pAvailServers->getValue($client));
121
    }
122
123
    /**
124
     * @covers ::dropServer
125
     */
126
    public function testDropLastServer()
127
    {
128
        $servers = ['localhost:4200'];
129
        $client = new Client($servers, []);
130
        $clientReflection = new ReflectionClass($client);
131
132
        $pDropServer = $clientReflection->getMethod('dropServer');
133
        $pDropServer->setAccessible(true);
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), $this->getMock(ResponseInterface::class)]);
138
        $pDropServer->invoke($client, 'localhost:4200', $ex);
139
    }
140
141
    /**
142
     * Create a response to be used
143
     *
144
     * @param int   $statusCode
145
     * @param array $body
146
     *
147
     * @return Response
148
     */
149
    private function createResponse($statusCode, array $body)
150
    {
151
        $body = Stream::factory(json_encode($body));
152
153
        return new Response($statusCode, [], $body);
154
    }
155
156
    /**
157
     * @covers ::execute
158
     */
159
    public function testExecuteWithResponseFailure()
160
    {
161
        $code    = 1337;
162
        $message = 'hello world';
163
164
        $this->setExpectedException(RuntimeException::class, $message, $code);
165
166
        $request = $this->getMock(RequestInterface::class);
167
        $response = $this->createResponse(400, ['error' => ['code' => $code, 'message' => $message]]);
168
169
        $exception = ClientException::create($request, $response);
170
171
        $this->server
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Crate\PDO\Http\ServerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
            ->expects($this->once())
173
            ->method('doRequest')
174
            ->will($this->throwException($exception));
175
176
        $this->client->execute(static::SQL, ['foo' => 'bar']);
177
    }
178
179
    /**
180
     * @covers ::execute
181
     */
182
    public function testExecute()
183
    {
184
        $body = [
185
            'cols'     => ['id', 'name'],
186
            'rows'     => [],
187
            'rowcount' => 0,
188
            'duration' => 0
189
        ];
190
191
        $response = $this->createResponse(200, $body);
192
193
        $this->server
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Crate\PDO\Http\ServerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
            ->expects($this->once())
195
            ->method('doRequest')
196
            ->will($this->returnValue($response));
197
198
        $result = $this->client->execute(static::SQL, ['foo' => 'bar']);
199
200
        $this->assertInstanceOf(Collection::class, $result);
201
    }
202
203
}
204