123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <?php
- namespace Illuminate\Tests\Integration\Queue;
- use Exception;
- use Illuminate\Bus\Queueable;
- use Illuminate\Contracts\Cache\Repository as Cache;
- use Illuminate\Contracts\Queue\ShouldBeUnique;
- use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Foundation\Bus\Dispatchable;
- use Illuminate\Queue\InteractsWithQueue;
- use Illuminate\Support\Facades\Bus;
- use Orchestra\Testbench\TestCase;
- class UniqueJobTest extends TestCase
- {
- protected function getEnvironmentSetUp($app)
- {
- $app['db']->connection()->getSchemaBuilder()->create('jobs', function (Blueprint $table) {
- $table->bigIncrements('id');
- $table->string('queue');
- $table->longText('payload');
- $table->tinyInteger('attempts')->unsigned();
- $table->unsignedInteger('reserved_at')->nullable();
- $table->unsignedInteger('available_at');
- $table->unsignedInteger('created_at');
- $table->index(['queue', 'reserved_at']);
- });
- }
- protected function tearDown(): void
- {
- $this->app['db']->connection()->getSchemaBuilder()->drop('jobs');
- parent::tearDown();
- }
- public function testUniqueJobsAreNotDispatched()
- {
- Bus::fake();
- UniqueTestJob::dispatch();
- Bus::assertDispatched(UniqueTestJob::class);
- $this->assertFalse(
- $this->app->get(Cache::class)->lock($this->getLockKey(UniqueTestJob::class), 10)->get()
- );
- Bus::fake();
- UniqueTestJob::dispatch();
- Bus::assertNotDispatched(UniqueTestJob::class);
- $this->assertFalse(
- $this->app->get(Cache::class)->lock($this->getLockKey(UniqueTestJob::class), 10)->get()
- );
- }
- public function testLockIsReleasedForSuccessfulJobs()
- {
- UniqueTestJob::$handled = false;
- dispatch($job = new UniqueTestJob);
- $this->assertTrue($job::$handled);
- $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- }
- public function testLockIsReleasedForFailedJobs()
- {
- UniqueTestFailJob::$handled = false;
- $this->expectException(Exception::class);
- try {
- dispatch($job = new UniqueTestFailJob);
- } finally {
- $this->assertTrue($job::$handled);
- $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- }
- }
- public function testLockIsNotReleasedForJobRetries()
- {
- UniqueTestRetryJob::$handled = false;
- dispatch($job = new UniqueTestRetryJob);
- $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- $this->artisan('queue:work', [
- 'connection' => 'database',
- '--once' => true,
- ]);
- $this->assertTrue($job::$handled);
- $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- UniqueTestRetryJob::$handled = false;
- $this->artisan('queue:work', [
- 'connection' => 'database',
- '--once' => true,
- ]);
- $this->assertTrue($job::$handled);
- $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- }
- public function testLockIsNotReleasedForJobReleases()
- {
- UniqueTestReleasedJob::$handled = false;
- dispatch($job = new UniqueTestReleasedJob);
- $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- $this->artisan('queue:work', [
- 'connection' => 'database',
- '--once' => true,
- ]);
- $this->assertTrue($job::$handled);
- $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- UniqueTestReleasedJob::$handled = false;
- $this->artisan('queue:work', [
- 'connection' => 'database',
- '--once' => true,
- ]);
- $this->assertFalse($job::$handled);
- $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- }
- public function testLockCanBeReleasedBeforeProcessing()
- {
- UniqueUntilStartTestJob::$handled = false;
- dispatch($job = new UniqueUntilStartTestJob);
- $this->assertFalse($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- $this->artisan('queue:work', [
- 'connection' => 'database',
- '--once' => true,
- ]);
- $this->assertTrue($job::$handled);
- $this->assertTrue($this->app->get(Cache::class)->lock($this->getLockKey($job), 10)->get());
- }
- protected function getLockKey($job)
- {
- return 'laravel_unique_job:'.(is_string($job) ? $job : get_class($job));
- }
- }
- class UniqueTestJob implements ShouldQueue, ShouldBeUnique
- {
- use InteractsWithQueue, Queueable, Dispatchable;
- public static $handled = false;
- public function handle()
- {
- static::$handled = true;
- }
- }
- class UniqueTestFailJob implements ShouldQueue, ShouldBeUnique
- {
- use InteractsWithQueue, Queueable, Dispatchable;
- public $tries = 1;
- public static $handled = false;
- public function handle()
- {
- static::$handled = true;
- throw new Exception;
- }
- }
- class UniqueTestReleasedJob extends UniqueTestFailJob
- {
- public $tries = 1;
- public $connection = 'database';
- public function handle()
- {
- static::$handled = true;
- $this->release();
- }
- }
- class UniqueTestRetryJob extends UniqueTestFailJob
- {
- public $tries = 2;
- public $connection = 'database';
- }
- class UniqueUntilStartTestJob extends UniqueTestJob implements ShouldBeUniqueUntilProcessing
- {
- public $tries = 2;
- public $connection = 'database';
- }
|