Failed Conditions
Pull Request — develop (#3348)
by Sergei
65:23
created

PoolingShardConnectionTest::createConnection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
196
    }
197
198
    public function testGetParamsOverride() : void
199
    {
200
        $conn = $this->createConnection([
201
            'driver' => 'pdo_sqlite',
202
            'global' => ['memory' => true, 'host' => 'localhost'],
203
            'shards' => [
204
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
205
            ],
206
            'shardChoser' => MultiTenantShardChoser::class,
207
        ]);
208
209
        self::assertEquals([
210
            'wrapperClass' => PoolingShardConnection::class,
211
            'driver' => 'pdo_sqlite',
212
            'global' => ['memory' => true, 'host' => 'localhost'],
213
            'shards' => [
214
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
215
            ],
216
            'shardChoser' => new MultiTenantShardChoser(),
217
            'memory' => true,
218
            'host' => 'localhost',
219
        ], $conn->getParams());
220
221
        $conn->connect(1);
222
        self::assertEquals([
223
            'wrapperClass' => PoolingShardConnection::class,
224
            'driver' => 'pdo_sqlite',
225
            'global' => ['memory' => true, 'host' => 'localhost'],
226
            'shards' => [
227
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
228
            ],
229
            'shardChoser' => new MultiTenantShardChoser(),
230
            'id' => 1,
231
            'memory' => true,
232
            'host' => 'foo',
233
        ], $conn->getParams());
234
    }
235
236
    public function testGetHostOverride() : void
237
    {
238
        $conn = $this->createConnection([
239
            'driver' => 'pdo_sqlite',
240
            'host' => 'localhost',
241
            'global' => ['memory' => true],
242
            'shards' => [
243
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
244
            ],
245
            'shardChoser' => MultiTenantShardChoser::class,
246
        ]);
247
248
        self::assertEquals('localhost', $conn->getHost());
249
250
        $conn->connect(1);
251
        self::assertEquals('foo', $conn->getHost());
252
    }
253
254
    public function testGetPortOverride() : void
255
    {
256
        $conn = $this->createConnection([
257
            'driver' => 'pdo_sqlite',
258
            'port' => 3306,
259
            'global' => ['memory' => true],
260
            'shards' => [
261
                ['id' => 1, 'memory' => true, 'port' => 3307],
262
            ],
263
            'shardChoser' => MultiTenantShardChoser::class,
264
        ]);
265
266
        self::assertEquals(3306, $conn->getPort());
267
268
        $conn->connect(1);
269
        self::assertEquals(3307, $conn->getPort());
270
    }
271
272
    public function testGetUsernameOverride() : void
273
    {
274
        $conn = $this->createConnection([
275
            'driver' => 'pdo_sqlite',
276
            'user' => 'foo',
277
            'global' => ['memory' => true],
278
            'shards' => [
279
                ['id' => 1, 'memory' => true, 'user' => 'bar'],
280
            ],
281
            'shardChoser' => MultiTenantShardChoser::class,
282
        ]);
283
284
        self::assertEquals('foo', $conn->getUsername());
285
286
        $conn->connect(1);
287
        self::assertEquals('bar', $conn->getUsername());
288
    }
289
290
    public function testGetPasswordOverride() : void
291
    {
292
        $conn = $this->createConnection([
293
            'driver' => 'pdo_sqlite',
294
            'password' => 'foo',
295
            'global' => ['memory' => true],
296
            'shards' => [
297
                ['id' => 1, 'memory' => true, 'password' => 'bar'],
298
            ],
299
            'shardChoser' => MultiTenantShardChoser::class,
300
        ]);
301
302
        self::assertEquals('foo', $conn->getPassword());
303
304
        $conn->connect(1);
305
        self::assertEquals('bar', $conn->getPassword());
306
    }
307
308
    /**
309
     * @param mixed[] $parameters
310
     */
311
    private function createConnection(array $parameters) : PoolingShardConnection
312
    {
313
        return DriverManager::getConnection(array_merge(
0 ignored issues
show
Bug Best Practice introduced by
The expression return Doctrine\DBAL\Dri...::class), $parameters)) returns the type Doctrine\DBAL\Connection which includes types incompatible with the type-hinted return Doctrine\DBAL\Sharding\PoolingShardConnection.
Loading history...
314
            ['wrapperClass' => PoolingShardConnection::class],
315
            $parameters
316
        ));
317
    }
318
}
319