1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * This file is part of the tarantool/client package. |
||||
5 | * |
||||
6 | * (c) Eugene Leonovich <[email protected]> |
||||
7 | * |
||||
8 | * For the full copyright and license information, please view the LICENSE |
||||
9 | * file that was distributed with this source code. |
||||
10 | */ |
||||
11 | |||||
12 | declare(strict_types=1); |
||||
13 | |||||
14 | namespace Tarantool\Client\Tests\Integration\Connection; |
||||
15 | |||||
16 | use Tarantool\Client\Exception\CommunicationFailed; |
||||
17 | use Tarantool\Client\Exception\ConnectionFailed; |
||||
18 | use Tarantool\Client\Exception\UnexpectedResponse; |
||||
19 | use Tarantool\Client\Request\PingRequest; |
||||
20 | use Tarantool\Client\Schema\Criteria; |
||||
21 | use Tarantool\Client\Schema\Operations; |
||||
22 | use Tarantool\Client\Tests\GreetingDataProvider; |
||||
23 | use Tarantool\Client\Tests\Integration\ClientBuilder; |
||||
24 | use Tarantool\Client\Tests\Integration\FakeServer\FakeServerBuilder; |
||||
0 ignored issues
–
show
|
|||||
25 | use Tarantool\Client\Tests\Integration\FakeServer\Handler\AtConnectionHandler; |
||||
26 | use Tarantool\Client\Tests\Integration\FakeServer\Handler\WriteHandler; |
||||
27 | use Tarantool\Client\Tests\Integration\TestCase; |
||||
28 | |||||
29 | final class ConnectionTest extends TestCase |
||||
30 | { |
||||
31 | /** |
||||
32 | * @dataProvider provideAutoConnectData |
||||
33 | * @doesNotPerformAssertions |
||||
34 | * |
||||
35 | * @lua create_space('test_auto_connect'):create_index('primary', {type = 'tree', parts = {1, 'unsigned'}}) |
||||
36 | */ |
||||
37 | public function testAutoConnect(string $methodName, array $methodArgs, ?string $space = null) : void |
||||
38 | { |
||||
39 | $object = $space ? $this->client->getSpace($space) : $this->client; |
||||
0 ignored issues
–
show
The method
getSpace() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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. ![]() |
|||||
40 | $this->client->getHandler()->getConnection()->close(); |
||||
41 | |||||
42 | $object->$methodName(...$methodArgs); |
||||
43 | } |
||||
44 | |||||
45 | public function provideAutoConnectData() : iterable |
||||
46 | { |
||||
47 | return [ |
||||
48 | ['ping', []], |
||||
49 | ['call', ['box.stat']], |
||||
50 | ['evaluate', ['return 1']], |
||||
51 | |||||
52 | ['select', [Criteria::key([42])], 'test_auto_connect'], |
||||
53 | ['insert', [[time()]], 'test_auto_connect'], |
||||
54 | ['replace', [[1, 2]], 'test_auto_connect'], |
||||
55 | ['update', [[1], Operations::add(1, 2)], 'test_auto_connect'], |
||||
56 | ['delete', [[1]], 'test_auto_connect'], |
||||
57 | ]; |
||||
58 | } |
||||
59 | |||||
60 | public function testMultipleConnect() : void |
||||
61 | { |
||||
62 | $conn = $this->client->getHandler()->getConnection(); |
||||
63 | |||||
64 | self::assertTrue($conn->isClosed()); |
||||
65 | |||||
66 | $conn->open(); |
||||
67 | self::assertFalse($conn->isClosed()); |
||||
68 | |||||
69 | $conn->open(); |
||||
70 | self::assertFalse($conn->isClosed()); |
||||
71 | } |
||||
72 | |||||
73 | public function tesMultipleDisconnect() : void |
||||
74 | { |
||||
75 | $conn = $this->client->getHandler()->getConnection(); |
||||
76 | |||||
77 | $conn->open(); |
||||
78 | self::assertFalse($conn->isClosed()); |
||||
79 | |||||
80 | $conn->close(); |
||||
81 | self::assertTrue($conn->isClosed()); |
||||
82 | |||||
83 | $conn->close(); |
||||
84 | self::assertTrue($conn->isClosed()); |
||||
85 | } |
||||
86 | |||||
87 | public function testReturnSameGreeting() : void |
||||
88 | { |
||||
89 | $conn = $this->client->getHandler()->getConnection(); |
||||
90 | |||||
91 | $greeting1 = $conn->open(); |
||||
92 | $greeting2 = $conn->open(); |
||||
93 | |||||
94 | self::assertSame($greeting1, $greeting2); |
||||
95 | } |
||||
96 | |||||
97 | public function testReturnNewGreeting() : void |
||||
98 | { |
||||
99 | $conn = $this->client->getHandler()->getConnection(); |
||||
100 | |||||
101 | $greeting1 = $conn->open(); |
||||
102 | $conn->close(); |
||||
103 | $greeting2 = $conn->open(); |
||||
104 | |||||
105 | self::assertNotSame($greeting1, $greeting2); |
||||
106 | } |
||||
107 | |||||
108 | public function testConnectInvalidHost() : void |
||||
109 | { |
||||
110 | $clientBuilder = ClientBuilder::createFromEnv() |
||||
111 | ->setHost('invalid_host'); |
||||
112 | |||||
113 | if (!$clientBuilder->isTcpConnection()) { |
||||
114 | self::markTestSkipped(sprintf('For tcp connections only (current: "%s")', $clientBuilder->getUri())); |
||||
115 | } |
||||
116 | |||||
117 | $client = $clientBuilder->build(); |
||||
118 | |||||
119 | $this->expectException(ConnectionFailed::class); |
||||
120 | $client->ping(); |
||||
121 | } |
||||
122 | |||||
123 | public function testConnectInvalidPort() : void |
||||
124 | { |
||||
125 | $clientBuilder = ClientBuilder::createFromEnv() |
||||
126 | ->setPort(123456); |
||||
127 | |||||
128 | if (!$clientBuilder->isTcpConnection()) { |
||||
129 | self::markTestSkipped(sprintf('For tcp connections only (current: "%s")', $clientBuilder->getUri())); |
||||
130 | } |
||||
131 | |||||
132 | $client = $clientBuilder->build(); |
||||
133 | |||||
134 | $this->expectException(ConnectionFailed::class); |
||||
135 | $client->ping(); |
||||
136 | } |
||||
137 | |||||
138 | public function testConnectTimedOut() : void |
||||
139 | { |
||||
140 | $clientBuilder = ClientBuilder::createFromEnv(); |
||||
141 | if (!$clientBuilder->isTcpConnection()) { |
||||
142 | self::markTestSkipped(sprintf('For tcp connections only (current: "%s")', $clientBuilder->getUri())); |
||||
143 | } |
||||
144 | |||||
145 | // @see http://stackoverflow.com/q/100841/1160901 |
||||
146 | $host = '8.8.8.8'; |
||||
147 | $connectTimeout = 1.125; |
||||
148 | |||||
149 | $client = $clientBuilder->setConnectionOptions(['connect_timeout' => $connectTimeout]) |
||||
150 | ->setHost($host) |
||||
151 | ->setPort(8008) |
||||
152 | ->build(); |
||||
153 | |||||
154 | $start = microtime(true); |
||||
155 | |||||
156 | try { |
||||
157 | $client->ping(); |
||||
158 | } catch (ConnectionFailed $e) { |
||||
159 | if (1 !== preg_match('/(Connection|Operation) timed out/', $e->getMessage())) { |
||||
160 | self::markTestSkipped(sprintf('Unable to trigger timeout error: %s', $e->getMessage())); |
||||
161 | } |
||||
162 | |||||
163 | $time = microtime(true) - $start; |
||||
164 | self::assertGreaterThanOrEqual($connectTimeout, $time); |
||||
165 | self::assertLessThan($connectTimeout + 0.01, $time); |
||||
166 | |||||
167 | return; |
||||
168 | } |
||||
169 | |||||
170 | self::fail(); |
||||
171 | } |
||||
172 | |||||
173 | public function testUnexpectedResponse() : void |
||||
174 | { |
||||
175 | $client = ClientBuilder::createFromEnv()->build(); |
||||
176 | $connection = self::triggerUnexpectedResponse($client->getHandler(), new PingRequest()); |
||||
177 | |||||
178 | // Tarantool will answer with the ping response |
||||
179 | try { |
||||
180 | $client->evaluate('return 42'); |
||||
181 | } catch (UnexpectedResponse $e) { |
||||
182 | self::assertTrue($connection->isClosed()); |
||||
183 | |||||
184 | return; |
||||
185 | } |
||||
186 | |||||
187 | self::fail(UnexpectedResponse::class.' was not thrown'); |
||||
188 | } |
||||
189 | |||||
190 | public function testOpenConnectionHandlesTheMissingGreetingCorrectly() : void |
||||
191 | { |
||||
192 | $clientBuilder = ClientBuilder::createForFakeServer(); |
||||
193 | |||||
194 | FakeServerBuilder::create( |
||||
195 | new AtConnectionHandler(1, new WriteHandler('')), |
||||
196 | new AtConnectionHandler(2, new WriteHandler(GreetingDataProvider::generateGreeting())) |
||||
197 | ) |
||||
198 | ->setUri($clientBuilder->getUri()) |
||||
199 | ->start(); |
||||
200 | |||||
201 | $client = $clientBuilder->build(); |
||||
202 | $connection = $client->getHandler()->getConnection(); |
||||
203 | |||||
204 | try { |
||||
205 | $connection->open(); |
||||
206 | self::fail('Connection not established'); |
||||
207 | } catch (CommunicationFailed $e) { |
||||
208 | self::assertMatchesRegularExpression( |
||||
209 | '/Error reading greeting:.+Unable to connect/i', |
||||
210 | $e->getMessage() |
||||
211 | ); |
||||
212 | // At this point the connection was successfully established, |
||||
213 | // but the greeting message was not read. |
||||
214 | } |
||||
215 | |||||
216 | // The second call should correctly handle |
||||
217 | // the missing greeting from the previous call. |
||||
218 | $connection->open(); |
||||
219 | } |
||||
220 | } |
||||
221 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths