Skip to content

Commit 7b9b2d9

Browse files
committed
Yield from test providers
1 parent 624eb4a commit 7b9b2d9

11 files changed

+158
-187
lines changed

.gitattributes

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
/.github export-ignore
2-
/tests export-ignore
1+
/.github/ export-ignore
2+
/tests/ export-ignore
33
/.gitattributes export-ignore
44
/.gitignore export-ignore
5-
/phpunit.xml.dist export-ignore
65
/.php-cs-fixer.dist.php export-ignore
6+
/phpstan.neon.dist export-ignore
7+
/phpunit.xml.dist export-ignore

.github/workflows/test-unit.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ jobs:
122122
php -r '(new PDO("pgsql:host=postgres;dbname=test_db", "test_user", "test_pass"))->exec("ALTER ROLE test_user CONNECTION LIMIT 1");'
123123
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage; fi
124124
125-
- name: "Run tests 1/2"
125+
- name: "Run tests"
126126
env:
127127
MYSQL_DSN: "mysql:host=mysql;dbname=test_db"
128128
MYSQL_USER: test_user
@@ -135,7 +135,8 @@ jobs:
135135
run: |
136136
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-phpunit-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
137137
138-
- name: "Run tests 2/2"
138+
- name: "Run tests /w MariaDB and Valkey (only for cron)"
139+
if: (success() || failure()) && github.event_name == 'schedule'
139140
env:
140141
MYSQL_DSN: "mysql:host=mariadb;dbname=test_db"
141142
MYSQL_USER: test_user

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ No time outs are supported. If the connection to the database server is lost or
380380
interrupted, the lock is automatically released.
381381

382382
```php
383-
$pdo = new PDO('pgsql:host=localhost;dbname=test;', 'username');
383+
$pdo = new PDO('pgsql:host=localhost;dbname=test', 'username');
384384

385385
$mutex = new PgAdvisoryLockMutex($pdo, 'balance');
386386
$mutex->synchronized(function () use ($bankAccount, $amount) {

tests/mutex/FlockMutexTest.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,8 @@ static function () {
8686
*/
8787
public static function provideTimeoutableStrategiesCases(): iterable
8888
{
89-
return [
90-
[FlockMutex::STRATEGY_PCNTL],
91-
[FlockMutex::STRATEGY_BUSY],
92-
];
89+
yield [FlockMutex::STRATEGY_PCNTL];
90+
yield [FlockMutex::STRATEGY_BUSY];
9391
}
9492

9593
public function testNoTimeoutWaitsForever(): void

tests/mutex/MutexConcurrencyTest.php

+46-54
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,18 @@ public function testHighContention(\Closure $code, \Closure $mutexFactory): void
106106
}
107107

108108
/**
109-
* Returns test cases for testHighContention().
110-
*
111109
* @return iterable<list<mixed>>
112110
*/
113111
public static function provideHighContentionCases(): iterable
114112
{
115-
$cases = array_map(static function (array $mutexFactory): array {
113+
foreach (static::provideExecutionIsSerializedWhenLockedCases() as [$mutexFactory]) {
116114
$filename = tempnam(sys_get_temp_dir(), 'php-lock-high-contention');
117115

118116
static::$temporaryFiles[] = $filename;
119117

120118
file_put_contents($filename, '0');
121119

122-
return [
120+
yield [
123121
static function (int $increment) use ($filename): int {
124122
$counter = file_get_contents($filename);
125123
$counter += $increment;
@@ -128,11 +126,11 @@ static function (int $increment) use ($filename): int {
128126

129127
return $counter;
130128
},
131-
$mutexFactory[0],
129+
$mutexFactory,
132130
];
133-
}, static::provideExecutionIsSerializedWhenLockedCases());
131+
}
134132

135-
$addPDO = static function ($dsn, $user, $password, $vendor) use (&$cases) {
133+
$addPDO = static function ($dsn, $user, $password, $vendor) {
136134
$pdo = self::getPDO($dsn, $user, $password);
137135

138136
$options = ['mysql' => 'engine=InnoDB'];
@@ -146,7 +144,7 @@ static function (int $increment) use ($filename): int {
146144

147145
self::$pdo = null;
148146

149-
$cases[$vendor] = [
147+
return [
150148
static function (int $increment) use ($dsn, $user, $password) {
151149
// This prevents using a closed connection from a child.
152150
if ($increment === 0) {
@@ -178,17 +176,15 @@ static function ($timeout = 3) use ($dsn, $user, $password) {
178176
$dsn = getenv('MYSQL_DSN');
179177
$user = getenv('MYSQL_USER');
180178
$password = getenv('MYSQL_PASSWORD');
181-
$addPDO($dsn, $user, $password, 'mysql');
179+
yield 'mysql' => $addPDO($dsn, $user, $password, 'mysql');
182180
}
183181

184182
if (getenv('PGSQL_DSN')) {
185183
$dsn = getenv('PGSQL_DSN');
186184
$user = getenv('PGSQL_USER');
187185
$password = getenv('PGSQL_PASSWORD');
188-
$addPDO($dsn, $user, $password, 'postgres');
186+
yield 'postgres' => $addPDO($dsn, $user, $password, 'postgres');
189187
}
190-
191-
return $cases;
192188
}
193189

194190
/**
@@ -225,45 +221,43 @@ public static function provideExecutionIsSerializedWhenLockedCases(): iterable
225221

226222
self::$temporaryFiles[] = $filename;
227223

228-
$cases = [
229-
'flock' => [static function ($timeout = 3) use ($filename): Mutex {
230-
$file = fopen($filename, 'w');
231-
232-
return new FlockMutex($file);
233-
}],
234-
235-
'flockWithTimoutPcntl' => [static function ($timeout = 3) use ($filename): Mutex {
236-
$file = fopen($filename, 'w');
237-
$lock = Liberator::liberate(new FlockMutex($file, $timeout));
238-
$lock->strategy = FlockMutex::STRATEGY_PCNTL; // @phpstan-ignore property.notFound
239-
240-
return $lock->popsValue();
241-
}],
242-
243-
'flockWithTimoutBusy' => [static function ($timeout = 3) use ($filename): Mutex {
244-
$file = fopen($filename, 'w');
245-
$lock = Liberator::liberate(new FlockMutex($file, $timeout));
246-
$lock->strategy = FlockMutex::STRATEGY_BUSY; // @phpstan-ignore property.notFound
247-
248-
return $lock->popsValue();
249-
}],
250-
251-
'semaphore' => [static function ($timeout = 3) use ($filename): Mutex {
252-
$semaphore = sem_get(ftok($filename, 'b'));
253-
self::assertThat(
254-
$semaphore,
255-
self::logicalOr(
256-
self::isInstanceOf(\SysvSemaphore::class),
257-
new IsType(IsType::TYPE_RESOURCE)
258-
)
259-
);
224+
yield 'flock' => [static function ($timeout = 3) use ($filename): Mutex {
225+
$file = fopen($filename, 'w');
226+
227+
return new FlockMutex($file);
228+
}];
260229

261-
return new SemaphoreMutex($semaphore);
262-
}],
263-
];
230+
yield 'flockWithTimoutPcntl' => [static function ($timeout = 3) use ($filename): Mutex {
231+
$file = fopen($filename, 'w');
232+
$lock = Liberator::liberate(new FlockMutex($file, $timeout));
233+
$lock->strategy = FlockMutex::STRATEGY_PCNTL; // @phpstan-ignore property.notFound
234+
235+
return $lock->popsValue();
236+
}];
237+
238+
yield 'flockWithTimoutBusy' => [static function ($timeout = 3) use ($filename): Mutex {
239+
$file = fopen($filename, 'w');
240+
$lock = Liberator::liberate(new FlockMutex($file, $timeout));
241+
$lock->strategy = FlockMutex::STRATEGY_BUSY; // @phpstan-ignore property.notFound
242+
243+
return $lock->popsValue();
244+
}];
245+
246+
yield 'semaphore' => [static function ($timeout = 3) use ($filename): Mutex {
247+
$semaphore = sem_get(ftok($filename, 'b'));
248+
self::assertThat(
249+
$semaphore,
250+
self::logicalOr(
251+
self::isInstanceOf(\SysvSemaphore::class),
252+
new IsType(IsType::TYPE_RESOURCE)
253+
)
254+
);
255+
256+
return new SemaphoreMutex($semaphore);
257+
}];
264258

265259
if (getenv('MEMCACHE_HOST')) {
266-
$cases['memcached'] = [static function ($timeout = 3): Mutex {
260+
yield 'memcached' => [static function ($timeout = 3): Mutex {
267261
$memcached = new \Memcached();
268262
$memcached->addServer(getenv('MEMCACHE_HOST'), 11211);
269263

@@ -274,7 +268,7 @@ public static function provideExecutionIsSerializedWhenLockedCases(): iterable
274268
if (getenv('REDIS_URIS')) {
275269
$uris = explode(',', getenv('REDIS_URIS'));
276270

277-
$cases['PredisMutex'] = [static function ($timeout = 3) use ($uris): Mutex {
271+
yield 'PredisMutex' => [static function ($timeout = 3) use ($uris): Mutex {
278272
$clients = array_map(
279273
static fn ($uri) => new Client($uri),
280274
$uris
@@ -284,7 +278,7 @@ public static function provideExecutionIsSerializedWhenLockedCases(): iterable
284278
}];
285279

286280
if (class_exists(\Redis::class)) {
287-
$cases['PHPRedisMutex'] = [
281+
yield 'PHPRedisMutex' => [
288282
static function ($timeout = 3) use ($uris): Mutex {
289283
$apis = array_map(
290284
static function (string $uri): \Redis {
@@ -312,7 +306,7 @@ static function (string $uri): \Redis {
312306
}
313307

314308
if (getenv('MYSQL_DSN')) {
315-
$cases['MySQLMutex'] = [static function ($timeout = 3): Mutex {
309+
yield 'MySQLMutex' => [static function ($timeout = 3): Mutex {
316310
$pdo = new \PDO(getenv('MYSQL_DSN'), getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'));
317311
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
318312

@@ -321,14 +315,12 @@ static function (string $uri): \Redis {
321315
}
322316

323317
if (getenv('PGSQL_DSN')) {
324-
$cases['PgAdvisoryLockMutex'] = [static function (): Mutex {
318+
yield 'PgAdvisoryLockMutex' => [static function (): Mutex {
325319
$pdo = new \PDO(getenv('PGSQL_DSN'), getenv('PGSQL_USER'), getenv('PGSQL_PASSWORD'));
326320
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
327321

328322
return new PgAdvisoryLockMutex($pdo, 'test');
329323
}];
330324
}
331-
332-
return $cases;
333325
}
334326
}

0 commit comments

Comments
 (0)