Issues (55)

tests/Integration/Connection/ConnectionTest.php (2 issues)

Labels
Severity
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
The type Tarantool\Client\Tests\I...erver\FakeServerBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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 ignore-call  annotation

39
        $object = $space ? $this->client->/** @scrutinizer ignore-call */ getSpace($space) : $this->client;

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...
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