Failed Conditions
Pull Request — develop (#3348)
by Sergei
60:53
created

PoolingShardConnectionTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 226
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 133
dl 0
loc 226
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A testGetParamsOverride() 0 36 1
A testDuplicateShardId() 0 13 1
A testNoShardsServersException() 0 9 1
A testShardChoserWrongInstance() 0 13 1
A testGetActiveShardId() 0 21 1
A testShardMissingId() 0 12 1
A testNoGlobalServerException() 0 12 1
A testConnect() 0 31 1
A testShardNonNumericId() 0 12 1
A testNoShardsChoserException() 0 11 1
A testSwitchShardWithOpenTransactionException() 0 16 1
A createConnection() 0 5 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 InvalidArgumentException;
12
use PHPUnit\Framework\TestCase;
13
use stdClass;
14
use function array_merge;
15
16
/**
17
 * @requires extension pdo_sqlite
18
 */
19
class PoolingShardConnectionTest extends TestCase
20
{
21
    public function testConnect() : void
22
    {
23
        $conn = $this->createConnection([
24
            'driver' => 'pdo_sqlite',
25
            'global' => ['memory' => true],
26
            'shards' => [
27
                ['id' => 1, 'memory' => true],
28
                ['id' => 2, 'memory' => true],
29
            ],
30
            'shardChoser' => MultiTenantShardChoser::class,
31
        ]);
32
33
        self::assertFalse($conn->isConnected(0));
34
        $conn->connect(0);
35
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
36
        self::assertTrue($conn->isConnected(0));
37
38
        self::assertFalse($conn->isConnected(1));
39
        $conn->connect(1);
40
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
41
        self::assertTrue($conn->isConnected(1));
42
43
        self::assertFalse($conn->isConnected(2));
44
        $conn->connect(2);
45
        self::assertEquals(1, $conn->fetchColumn('SELECT 1'));
46
        self::assertTrue($conn->isConnected(2));
47
48
        $conn->close();
49
        self::assertFalse($conn->isConnected(0));
50
        self::assertFalse($conn->isConnected(1));
51
        self::assertFalse($conn->isConnected(2));
52
    }
53
54
    public function testNoGlobalServerException() : void
55
    {
56
        $this->expectException(InvalidArgumentException::class);
57
        $this->expectExceptionMessage('Connection Parameters require "global" and "shards" configurations.');
58
59
        $this->createConnection([
60
            'driver' => 'pdo_sqlite',
61
            'shards' => [
62
                ['id' => 1, 'memory' => true],
63
                ['id' => 2, 'memory' => true],
64
            ],
65
            'shardChoser' => MultiTenantShardChoser::class,
66
        ]);
67
    }
68
69
    public function testNoShardsServersException() : void
70
    {
71
        $this->expectException(InvalidArgumentException::class);
72
        $this->expectExceptionMessage('Connection Parameters require "global" and "shards" configurations.');
73
74
        $this->createConnection([
75
            'driver' => 'pdo_sqlite',
76
            'global' => ['memory' => true],
77
            'shardChoser' => MultiTenantShardChoser::class,
78
        ]);
79
    }
80
81
    public function testNoShardsChoserException() : void
82
    {
83
        $this->expectException(InvalidArgumentException::class);
84
        $this->expectExceptionMessage('Missing Shard Choser configuration "shardChoser".');
85
86
        $this->createConnection([
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() : void
97
    {
98
        $this->expectException(InvalidArgumentException::class);
99
        $this->expectExceptionMessage('The "shardChoser" configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser');
100
101
        $this->createConnection([
102
            'driver' => 'pdo_sqlite',
103
            'global' => ['memory' => true],
104
            'shards' => [
105
                ['id' => 1, 'memory' => true],
106
                ['id' => 2, 'memory' => true],
107
            ],
108
            'shardChoser' => new stdClass(),
109
        ]);
110
    }
111
112
    public function testShardNonNumericId() : void
113
    {
114
        $this->expectException('InvalidArgumentException');
115
        $this->expectExceptionMessage('Shard Id has to be a non-negative number.');
116
117
        $this->createConnection([
118
            'driver' => 'pdo_sqlite',
119
            'global' => ['memory' => true],
120
            'shards' => [
121
                ['id' => 'foo', 'memory' => true],
122
            ],
123
            'shardChoser' => MultiTenantShardChoser::class,
124
        ]);
125
    }
126
127
    public function testShardMissingId() : void
128
    {
129
        $this->expectException(InvalidArgumentException::class);
130
        $this->expectExceptionMessage('Missing "id" for one configured shard. Please specify a unique shard-id.');
131
132
        $this->createConnection([
133
            'driver' => 'pdo_sqlite',
134
            'global' => ['memory' => true],
135
            'shards' => [
136
                ['memory' => true],
137
            ],
138
            'shardChoser' => MultiTenantShardChoser::class,
139
        ]);
140
    }
141
142
    public function testDuplicateShardId() : void
143
    {
144
        $this->expectException(InvalidArgumentException::class);
145
        $this->expectExceptionMessage('Shard "1" is duplicated in the configuration.');
146
147
        $this->createConnection([
148
            'driver' => 'pdo_sqlite',
149
            'global' => ['memory' => true],
150
            'shards' => [
151
                ['id' => 1, 'memory' => true],
152
                ['id' => 1, 'memory' => true],
153
            ],
154
            'shardChoser' => MultiTenantShardChoser::class,
155
        ]);
156
    }
157
158
    public function testSwitchShardWithOpenTransactionException() : void
159
    {
160
        $conn = $this->createConnection([
161
            'driver' => 'pdo_sqlite',
162
            'global' => ['memory' => true],
163
            'shards' => [
164
                ['id' => 1, 'memory' => true],
165
            ],
166
            'shardChoser' => MultiTenantShardChoser::class,
167
        ]);
168
169
        $conn->beginTransaction();
170
171
        $this->expectException(ShardingException::class);
172
        $this->expectExceptionMessage('Cannot switch shard when transaction is active.');
173
        $conn->connect(1);
174
    }
175
176
    public function testGetActiveShardId() : void
177
    {
178
        $conn = $this->createConnection([
179
            'driver' => 'pdo_sqlite',
180
            'global' => ['memory' => true],
181
            'shards' => [
182
                ['id' => 1, 'memory' => true],
183
            ],
184
            'shardChoser' => MultiTenantShardChoser::class,
185
        ]);
186
187
        self::assertNull($conn->getActiveShardId());
188
189
        $conn->connect(0);
190
        self::assertEquals(0, $conn->getActiveShardId());
191
192
        $conn->connect(1);
193
        self::assertEquals(1, $conn->getActiveShardId());
194
195
        $conn->close();
196
        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...
197
    }
198
199
    public function testGetParamsOverride() : void
200
    {
201
        $conn = $this->createConnection([
202
            'driver' => 'pdo_sqlite',
203
            'global' => ['memory' => true, 'host' => 'localhost'],
204
            'shards' => [
205
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
206
            ],
207
            'shardChoser' => MultiTenantShardChoser::class,
208
        ]);
209
210
        self::assertEquals([
211
            'wrapperClass' => PoolingShardConnection::class,
212
            'driver' => 'pdo_sqlite',
213
            'global' => ['memory' => true, 'host' => 'localhost'],
214
            'shards' => [
215
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
216
            ],
217
            'shardChoser' => new MultiTenantShardChoser(),
218
            'memory' => true,
219
            'host' => 'localhost',
220
        ], $conn->getParams());
221
222
        $conn->connect(1);
223
        self::assertEquals([
224
            'wrapperClass' => PoolingShardConnection::class,
225
            'driver' => 'pdo_sqlite',
226
            'global' => ['memory' => true, 'host' => 'localhost'],
227
            'shards' => [
228
                ['id' => 1, 'memory' => true, 'host' => 'foo'],
229
            ],
230
            'shardChoser' => new MultiTenantShardChoser(),
231
            'id' => 1,
232
            'memory' => true,
233
            'host' => 'foo',
234
        ], $conn->getParams());
235
    }
236
237
    /**
238
     * @param mixed[] $parameters
239
     */
240
    private function createConnection(array $parameters) : PoolingShardConnection
241
    {
242
        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...
243
            ['wrapperClass' => PoolingShardConnection::class],
244
            $parameters
245
        ));
246
    }
247
}
248