/
githubmirror
/
framework
Обзор
Документация
Войти
/
githubmirror
/
framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
13.x
tests/Integration/Database/DatabaseLockTest.php
209 строк
7 KB
Jason McCreary
[13.x] Mockery cleanup (#61117)
10 авг 2026, 20:23
Не верифицирован
10 авг 2026, 20:23
2ee40ee
Код
Авторство
О чём код?
<?php namespace Illuminate\Tests\Integration\Database; use Illuminate\Cache\DatabaseLock; use Illuminate\Database\Connection; use Illuminate\Database\Query\Builder; use Illuminate\Database\QueryException; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Mockery; use Orchestra\Testbench\Attributes\WithMigration; use PDOException; use PHPUnit\Framework\Attributes\TestWith; #[WithMigration('cache')] class DatabaseLockTest extends DatabaseTestCase { public function testLockCanHaveASeparateConnection() { $this->app['config']->set('cache.stores.database.lock_connection', 'test'); $this->app['config']->set('database.connections.test', $this->app['config']->get('database.connections.mysql')); $this->assertSame('test', Cache::driver('database')->lock('foo')->getConnectionName()); } public function testLockCanBeAcquired() { $lock = Cache::driver('database')->lock('foo'); $this->assertTrue($lock->get()); $otherLock = Cache::driver('database')->lock('foo'); $this->assertFalse($otherLock->get()); $lock->release(); $otherLock = Cache::driver('database')->lock('foo'); $this->assertTrue($otherLock->get()); $otherLock->release(); } public function testLockCanBeForceReleased() { $lock = Cache::driver('database')->lock('foo'); $this->assertTrue($lock->get()); $otherLock = Cache::driver('database')->lock('foo'); $otherLock->forceRelease(); $this->assertTrue($otherLock->get()); $otherLock->release(); } public function testExpiredLockCanBeRetrieved() { $lock = Cache::driver('database')->lock('foo'); $this->assertTrue($lock->get()); DB::table('cache_locks')->update(['expiration' => Carbon::now()->subDay()->getTimestamp()]); $otherLock = Cache::driver('database')->lock('foo'); $this->assertTrue($otherLock->get()); $otherLock->release(); } public function testIsLocked() { $lock = Cache::driver('database')->lock('foo'); $this->assertFalse($lock->isLocked()); $lock->get(); $this->assertTrue($lock->isLocked()); $lock->release(); $this->assertFalse($lock->isLocked()); } public function testExpiredLockIsNotLocked() { $lock = Cache::driver('database')->lock('foo'); $this->assertFalse($lock->isLocked()); $lock->get(); $this->assertTrue($lock->isLocked()); DB::table('cache_locks')->update(['expiration' => Carbon::now()->subDay()->getTimestamp()]); $this->assertFalse($lock->isLocked()); } public function testOtherOwnerDoesNotOwnLockAfterRestore() { $firstLock = Cache::store('database')->lock('foo'); $this->assertTrue($firstLock->isOwnedBy(null)); $this->assertTrue($firstLock->get()); $this->assertTrue($firstLock->isOwnedBy($firstLock->owner())); $secondLock = Cache::store('database')->restoreLock('foo', 'other_owner'); $this->assertTrue($secondLock->isOwnedBy($firstLock->owner())); $this->assertFalse($secondLock->isOwnedByCurrentProcess()); } public function testLockCanBeRefreshed() { $lock = Cache::driver('database')->lock('foo', 10); $this->assertTrue($lock->get()); // Refresh the lock for another 20 seconds $this->assertTrue($lock->refresh(20)); // Lock should still be held $this->assertFalse(Cache::driver('database')->lock('foo', 10)->get()); $lock->release(); } public function testLockCannotBeRefreshedByAnotherOwner() { $firstLock = Cache::driver('database')->lock('foo', 10); $this->assertTrue($firstLock->get()); // Create a new lock with a different owner $secondLock = Cache::store('database')->restoreLock('foo', 'other_owner'); // Second lock should not be able to refresh $this->assertFalse($secondLock->refresh(20)); // Original lock should still be able to refresh $this->assertTrue($firstLock->refresh(20)); $firstLock->release(); } public function testExpiredLockCannotBeRefreshedByPreviousOwner() { $lock = Cache::driver('database')->lock('foo', 10); $this->assertTrue($lock->get()); DB::table('cache_locks')->update(['expiration' => now()->subDay()->getTimestamp()]); $this->assertFalse($lock->refresh(20)); } #[TestWith(['Deadlock found when trying to get lock', 1213, true])] #[TestWith(['Table does not exist', 1146, false])] public function testIgnoresConcurrencyException(string $message, int $code, bool $hasConcurrenyError) { $connection = Mockery::mock(Connection::class); $insertBuilder = Mockery::mock(Builder::class); $deleteBuilder = Mockery::mock(Builder::class); $insertBuilder->expects('insert')->andReturn(true); $deleteBuilder->expects('where')->with('expiration', '<=', Mockery::any())->andReturnSelf(); $deleteBuilder->expects('delete')->andThrow( new QueryException( 'mysql', 'delete from cache_locks where expiration <= ?', [], new PDOException($message, $code) ) ); $connection->expects('table')->times(2)->with('cache_locks')->andReturn($insertBuilder, $deleteBuilder); $lock = new DatabaseLock($connection, 'cache_locks', 'foo', 0, lottery: [1, 1]); if ($hasConcurrenyError) { $this->assertTrue($lock->acquire()); } else { $this->expectException(QueryException::class); $this->assertFalse($lock->acquire()); } } #[TestWith(['Serialization failure: 1213 Deadlock', 40001, true])] #[TestWith(['Table does not exist', 1146, false])] public function testReleaseIgnoresConcurrencyException(string $message, int $code, bool $hasConcurrencyError) { $connection = Mockery::mock(Connection::class); $deleteBuilder = Mockery::mock(Builder::class); $owner = 'owner-123'; $deleteBuilder->expects('where')->with('key', 'foo')->andReturnSelf(); $deleteBuilder->expects('where')->with('owner', $owner)->andReturnSelf(); $deleteBuilder->expects('delete')->andThrow( new QueryException( 'mysql', 'delete from cache_locks where key = ? and owner = ?', ['foo', $owner], new PDOException($message, $code) ) ); $connection->expects('table')->with('cache_locks')->andReturn($deleteBuilder); $lock = new DatabaseLock($connection, 'cache_locks', 'foo', 10, $owner); // same owner... if ($hasConcurrencyError) { $this->assertTrue($lock->release()); } else { $this->expectException(QueryException::class); $this->expectExceptionMessage($message); $lock->release(); } } }