Completed
Push — master ( 5dd66e...5b5c2c )
by Marco
114:19 queued 111:15
created

Tests/DBAL/Sharding/PoolingShardConnectionTest.php (6 issues)

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Sharding;
4
5
use Doctrine\DBAL\DriverManager;
6
use Doctrine\DBAL\Sharding\PoolingShardConnection;
7
use Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser;
8
use Doctrine\DBAL\Sharding\ShardingException;
9
use PHPUnit\Framework\TestCase;
10
use stdClass;
11
12
/**
13
 * @requires extension pdo_sqlite
14
 */
15
class PoolingShardConnectionTest extends TestCase
16
{
17
    public function testConnect()
18
    {
19
        $conn = DriverManager::getConnection([
20
            'wrapperClass' => PoolingShardConnection::class,
21
            'driver' => 'pdo_sqlite',
22
            'global' => ['memory' => true],
23
            'shards' => [
24
                ['id' => 1, 'memory' => true],
25
                ['id' => 2, 'memory' => true],
26
            ],
27
            'shardChoser' => MultiTenantShardChoser::class,
28
        ]);
29
30
        self::assertFalse($conn->isConnected(0));
31
        $conn->connect(0);
32
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
33
        self::assertTrue($conn->isConnected(0));
34
35
        self::assertFalse($conn->isConnected(1));
36
        $conn->connect(1);
37
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
38
        self::assertTrue($conn->isConnected(1));
39
40
        self::assertFalse($conn->isConnected(2));
41
        $conn->connect(2);
42
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
43
        self::assertTrue($conn->isConnected(2));
44
45
        $conn->close();
46
        self::assertFalse($conn->isConnected(0));
47
        self::assertFalse($conn->isConnected(1));
48
        self::assertFalse($conn->isConnected(2));
49
    }
50
51
    public function testNoGlobalServerException()
52
    {
53
        $this->expectException('InvalidArgumentException');
54
        $this->expectExceptionMessage("Connection Parameters require 'global' and 'shards' configurations.");
55
56
        DriverManager::getConnection([
57
            'wrapperClass' => PoolingShardConnection::class,
58
            'driver' => 'pdo_sqlite',
59
            'shards' => [
60
                ['id' => 1, 'memory' => true],
61
                ['id' => 2, 'memory' => true],
62
            ],
63
            'shardChoser' => MultiTenantShardChoser::class,
64
        ]);
65
    }
66
67
    public function testNoShardsServersException()
68
    {
69
        $this->expectException('InvalidArgumentException');
70
        $this->expectExceptionMessage("Connection Parameters require 'global' and 'shards' configurations.");
71
72
        DriverManager::getConnection([
73
            'wrapperClass' => PoolingShardConnection::class,
74
            'driver' => 'pdo_sqlite',
75
            'global' => ['memory' => true],
76
            'shardChoser' => MultiTenantShardChoser::class,
77
        ]);
78
    }
79
80
    public function testNoShardsChoserException()
81
    {
82
        $this->expectException('InvalidArgumentException');
83
        $this->expectExceptionMessage("Missing Shard Choser configuration 'shardChoser'");
84
85
        DriverManager::getConnection([
86
            'wrapperClass' => PoolingShardConnection::class,
87
            'driver' => 'pdo_sqlite',
88
            'global' => ['memory' => true],
89
            'shards' => [
90
                ['id' => 1, 'memory' => true],
91
                ['id' => 2, 'memory' => true],
92
            ],
93
        ]);
94
    }
95
96
    public function testShardChoserWrongInstance()
97
    {
98
        $this->expectException('InvalidArgumentException');
99
        $this->expectExceptionMessage("The 'shardChoser' configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser");
100
101
        DriverManager::getConnection([
102
            'wrapperClass' => PoolingShardConnection::class,
103
            'driver' => 'pdo_sqlite',
104
            'global' => ['memory' => true],
105
            'shards' => [
106
                ['id' => 1, 'memory' => true],
107
                ['id' => 2, 'memory' => true],
108
            ],
109
            'shardChoser' => new stdClass(),
110
        ]);
111
    }
112
113
    public function testShardNonNumericId()
114
    {
115
        $this->expectException('InvalidArgumentException');
116
        $this->expectExceptionMessage('Shard Id has to be a non-negative number.');
117
118
        DriverManager::getConnection([
119
            'wrapperClass' => PoolingShardConnection::class,
120
            'driver' => 'pdo_sqlite',
121
            'global' => ['memory' => true],
122
            'shards' => [
123
                ['id' => 'foo', 'memory' => true],
124
            ],
125
            'shardChoser' => MultiTenantShardChoser::class,
126
        ]);
127
    }
128
129
    public function testShardMissingId()
130
    {
131
        $this->expectException('InvalidArgumentException');
132
        $this->expectExceptionMessage("Missing 'id' for one configured shard. Please specify a unique shard-id.");
133
134
        DriverManager::getConnection([
135
            'wrapperClass' => PoolingShardConnection::class,
136
            'driver' => 'pdo_sqlite',
137
            'global' => ['memory' => true],
138
            'shards' => [
139
                ['memory' => true],
140
            ],
141
            'shardChoser' => MultiTenantShardChoser::class,
142
        ]);
143
    }
144
145
    public function testDuplicateShardId()
146
    {
147
        $this->expectException('InvalidArgumentException');
148
        $this->expectExceptionMessage('Shard 1 is duplicated in the configuration.');
149
150
        DriverManager::getConnection([
151
            'wrapperClass' => PoolingShardConnection::class,
152
            'driver' => 'pdo_sqlite',
153
            'global' => ['memory' => true],
154
            'shards' => [
155
                ['id' => 1, 'memory' => true],
156
                ['id' => 1, 'memory' => true],
157
            ],
158
            'shardChoser' => MultiTenantShardChoser::class,
159
        ]);
160
    }
161
162
    public function testSwitchShardWithOpenTransactionException()
163
    {
164
        $conn = DriverManager::getConnection([
165
            'wrapperClass' => PoolingShardConnection::class,
166
            'driver' => 'pdo_sqlite',
167
            'global' => ['memory' => true],
168
            'shards' => [
169
                ['id' => 1, 'memory' => true],
170
            ],
171
            'shardChoser' => MultiTenantShardChoser::class,
172
        ]);
173
174
        $conn->beginTransaction();
175
176
        $this->expectException(ShardingException::class);
177
        $this->expectExceptionMessage('Cannot switch shard when transaction is active.');
178
        $conn->connect(1);
179
    }
180
181
    public function testGetActiveShardId()
182
    {
183
        $conn = DriverManager::getConnection([
184
            'wrapperClass' => PoolingShardConnection::class,
185
            'driver' => 'pdo_sqlite',
186
            'global' => ['memory' => true],
187
            'shards' => [
188
                ['id' => 1, 'memory' => true],
189
            ],
190
            'shardChoser' => MultiTenantShardChoser::class,
191
        ]);
192
193
        self::assertNull($conn->getActiveShardId());
194
195
        $conn->connect(0);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

195
        $conn->/** @scrutinizer ignore-call */ 
196
               connect(0);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
196
        self::assertEquals(0, $conn->getActiveShardId());
197
198
        $conn->connect(1);
199
        self::assertEquals(1, $conn->getActiveShardId());
200
201
        $conn->close();
202
        self::assertNull($conn->getActiveShardId());
203
    }
204
205
    public function testGetParamsOverride()
206
    {
207
        $conn = DriverManager::getConnection([
208
            'wrapperClass' => PoolingShardConnection::class,
209
            'driver' => 'pdo_sqlite',
210
            'global' => ['memory' => true, 'host' => 'localhost'],
211
            'shards' => [
212
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
213
            ],
214
            'shardChoser' => MultiTenantShardChoser::class,
215
        ]);
216
217
        self::assertEquals([
218
            'wrapperClass' => PoolingShardConnection::class,
219
            'driver' => 'pdo_sqlite',
220
            'global' => ['memory' => true, 'host' => 'localhost'],
221
            'shards' => [
222
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
223
            ],
224
            'shardChoser' => new MultiTenantShardChoser(),
225
            'memory' => true,
226
            'host' => 'localhost',
227
        ], $conn->getParams());
228
229
        $conn->connect(1);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

229
        $conn->/** @scrutinizer ignore-call */ 
230
               connect(1);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
230
        self::assertEquals([
231
            'wrapperClass' => PoolingShardConnection::class,
232
            'driver' => 'pdo_sqlite',
233
            'global' => ['memory' => true, 'host' => 'localhost'],
234
            'shards' => [
235
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
236
            ],
237
            'shardChoser' => new MultiTenantShardChoser(),
238
            'id' => 1,
239
            'memory' => true,
240
            'host' => 'foo',
241
        ], $conn->getParams());
242
    }
243
244
    public function testGetHostOverride()
245
    {
246
        $conn = DriverManager::getConnection([
247
            'wrapperClass' => PoolingShardConnection::class,
248
            'driver' => 'pdo_sqlite',
249
            'host' => 'localhost',
250
            'global' => ['memory' => true],
251
            'shards' => [
252
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
253
            ],
254
            'shardChoser' => MultiTenantShardChoser::class,
255
        ]);
256
257
        self::assertEquals('localhost', $conn->getHost());
258
259
        $conn->connect(1);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

259
        $conn->/** @scrutinizer ignore-call */ 
260
               connect(1);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
260
        self::assertEquals('foo', $conn->getHost());
261
    }
262
263
    public function testGetPortOverride()
264
    {
265
        $conn = DriverManager::getConnection([
266
            'wrapperClass' => PoolingShardConnection::class,
267
            'driver' => 'pdo_sqlite',
268
            'port' => 3306,
269
            'global' => ['memory' => true],
270
            'shards' => [
271
                ['id' => 1, 'memory' => true, 'port' => 3307],
272
            ],
273
            'shardChoser' => MultiTenantShardChoser::class,
274
        ]);
275
276
        self::assertEquals(3306, $conn->getPort());
277
278
        $conn->connect(1);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

278
        $conn->/** @scrutinizer ignore-call */ 
279
               connect(1);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
279
        self::assertEquals(3307, $conn->getPort());
280
    }
281
282
    public function testGetUsernameOverride()
283
    {
284
        $conn = DriverManager::getConnection([
285
            'wrapperClass' => PoolingShardConnection::class,
286
            'driver' => 'pdo_sqlite',
287
            'user' => 'foo',
288
            'global' => ['memory' => true],
289
            'shards' => [
290
                ['id' => 1, 'memory' => true, 'user' => 'bar'],
291
            ],
292
            'shardChoser' => MultiTenantShardChoser::class,
293
        ]);
294
295
        self::assertEquals('foo', $conn->getUsername());
296
297
        $conn->connect(1);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

297
        $conn->/** @scrutinizer ignore-call */ 
298
               connect(1);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
298
        self::assertEquals('bar', $conn->getUsername());
299
    }
300
301
    public function testGetPasswordOverride()
302
    {
303
        $conn = DriverManager::getConnection([
304
            'wrapperClass' => PoolingShardConnection::class,
305
            'driver' => 'pdo_sqlite',
306
            'password' => 'foo',
307
            'global' => ['memory' => true],
308
            'shards' => [
309
                ['id' => 1, 'memory' => true, 'password' => 'bar'],
310
            ],
311
            'shardChoser' => MultiTenantShardChoser::class,
312
        ]);
313
314
        self::assertEquals('foo', $conn->getPassword());
315
316
        $conn->connect(1);
0 ignored issues
show
The call to Doctrine\DBAL\Connection::connect() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

316
        $conn->/** @scrutinizer ignore-call */ 
317
               connect(1);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
317
        self::assertEquals('bar', $conn->getPassword());
318
    }
319
}
320