2.0.0 Add namespacing + PHP8.0 support (#1)

2.0.0 (2021-02-19)

Moved to PSR-4
Namespaced codebase
Added more comments throughout
Co-Authored-By: idanoo <daniel@m2.nz>
Co-Committed-By: idanoo <daniel@m2.nz>
This commit is contained in:
idanoo 2021-02-19 12:23:32 +13:00
parent ebec2f7bf7
commit 80d64e79ff
56 changed files with 2215 additions and 1423 deletions

View file

@ -0,0 +1,206 @@
<?php
namespace Resque\Test;
/**
* \Resque\Event tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class EventTest extends TestCase
{
private $callbacksHit = [];
private $worker;
public function setUp(): void
{
TestJob::$called = false;
// Register a worker to test with
$this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new \Resque\Log());
$this->worker->registerWorker();
}
public function tearDown(): void
{
\Resque\Event::clearListeners();
$this->callbacksHit = [];
}
public function getEventTestJob()
{
$payload = [
'class' => '\Resque\Test\TestJob',
'args' => [
['somevar'],
],
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->worker = $this->worker;
return $job;
}
public function eventCallbackProvider()
{
return [
['beforePerform', 'beforePerformEventCallback'],
['afterPerform', 'afterPerformEventCallback'],
['afterFork', 'afterForkEventCallback'],
];
}
/**
* @dataProvider eventCallbackProvider
* @param $event
* @param $callback
*/
public function testEventCallbacksFire($event, $callback)
{
\Resque\Event::listen($event, [$this, $callback]);
$job = $this->getEventTestJob();
$this->worker->perform($job);
$this->worker->work(0);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
public function testBeforeForkEventCallbackFires()
{
$event = 'beforeFork';
$callback = 'beforeForkEventCallback';
\Resque\Event::listen($event, [$this, $callback]);
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
]);
$this->getEventTestJob();
$this->worker->work(0);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
public function testBeforeEnqueueEventCallbackFires()
{
$event = 'beforeEnqueue';
$callback = 'beforeEnqueueEventCallback';
\Resque\Event::listen($event, [$this, $callback]);
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
public function testBeforePerformEventCanStopWork()
{
$callback = 'beforePerformEventDontPerformCallback';
\Resque\Event::listen('beforePerform', [$this, $callback]);
$job = $this->getEventTestJob();
$this->assertFalse($job->perform());
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
$this->assertFalse(TestJob::$called, 'Job was still performed though Resque_Job_DontPerform was thrown');
}
public function testBeforeEnqueueEventStopsJobCreation()
{
$callback = 'beforeEnqueueEventDontCreateCallback';
\Resque\Event::listen('beforeEnqueue', [$this, $callback]);
\Resque\Event::listen('afterEnqueue', [$this, 'afterEnqueueEventCallback']);
$result = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestClass');
$this->assertContains($callback, $this->callbacksHit, $callback . ' callback was not called');
$this->assertNotContains('afterEnqueueEventCallback', $this->callbacksHit, 'afterEnqueue was still called, even though it should not have been');
$this->assertFalse($result);
}
public function testAfterEnqueueEventCallbackFires()
{
$callback = 'afterEnqueueEventCallback';
$event = 'afterEnqueue';
\Resque\Event::listen($event, [$this, $callback]);
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', [
'somevar'
]);
$this->assertContains($callback, $this->callbacksHit, $event . ' callback (' . $callback . ') was not called');
}
public function testStopListeningRemovesListener()
{
$callback = 'beforePerformEventCallback';
$event = 'beforePerform';
\Resque\Event::listen($event, [$this, $callback]);
\Resque\Event::stopListening($event, [$this, $callback]);
$job = $this->getEventTestJob();
$this->worker->perform($job);
$this->worker->work(0);
$this->assertNotContains($callback, $this->callbacksHit,
$event . ' callback (' . $callback . ') was called though Resque_Event::stopListening was called'
);
}
public function beforePerformEventDontPerformCallback()
{
$this->callbacksHit[] = __FUNCTION__;
throw new \Resque\Job\DontPerform();
}
public function beforeEnqueueEventDontCreateCallback()
{
$this->callbacksHit[] = __FUNCTION__;
throw new \Resque\Job\DontCreate();
}
public function assertValidEventCallback($function, $job)
{
$this->callbacksHit[] = $function;
if (!$job instanceof \Resque\Job\Job) {
$this->fail('Callback job argument is not an instance of \Resque\Job\Job');
}
$args = $job->getArguments();
$this->assertEquals($args[0], 'somevar');
}
public function afterEnqueueEventCallback($class, $args)
{
$this->callbacksHit[] = __FUNCTION__;
$this->assertEquals('\Resque\Test\TestJob', $class);
$this->assertEquals([
'somevar',
], $args);
}
public function beforeEnqueueEventCallback($job)
{
$this->callbacksHit[] = __FUNCTION__;
}
public function beforePerformEventCallback($job)
{
$this->assertValidEventCallback(__FUNCTION__, $job);
}
public function afterPerformEventCallback($job)
{
$this->assertValidEventCallback(__FUNCTION__, $job);
}
public function beforeForkEventCallback($job)
{
$this->assertValidEventCallback(__FUNCTION__, $job);
}
public function afterForkEventCallback($job)
{
$this->assertValidEventCallback(__FUNCTION__, $job);
}
}

View file

@ -0,0 +1,110 @@
<?php
namespace Resque\Test;
/**
* \Resque\Job\Status tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class JobStatusTest extends TestCase
{
/**
* @var \Resque\Worker
*/
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new \Resque\Log());
}
public function testJobStatusCanBeTracked()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$status = new \Resque\Job\Status($token);
$this->assertTrue($status->isTracking());
}
public function testJobStatusIsReturnedViaJobInstance()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$job = \Resque\Job\Job::reserve('jobs');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $job->getStatus());
}
public function testQueuedJobReturnsQueuedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $status->get());
}
public function testRunningJobReturnsRunningStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\FailingJob', null, true);
$job = $this->worker->reserve();
$this->worker->workingOn($job);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_RUNNING, $status->get());
}
public function testFailedJobReturnsFailedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\FailingJob', null, true);
$this->worker->work(0);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_FAILED, $status->get());
}
public function testCompletedJobReturnsCompletedStatus()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$this->worker->work(0);
$status = new \Resque\Job\Status($token);
$this->assertEquals(\Resque\Job\Status::STATUS_COMPLETE, $status->get());
}
public function testStatusIsNotTrackedWhenToldNotTo()
{
$token = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, false);
$status = new \Resque\Job\Status($token);
$this->assertFalse($status->isTracking());
}
public function testStatusTrackingCanBeStopped()
{
\Resque\Job\Status::create('test');
$status = new \Resque\Job\Status('test');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $status->get());
$status->stop();
$this->assertFalse($status->get());
}
public function testRecreatedJobWithTrackingStillTracksStatus()
{
$originalToken = \Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', null, true);
$job = $this->worker->reserve();
// Mark this job as being worked on to ensure that the new status is still
// waiting.
$this->worker->workingOn($job);
// Now recreate it
$newToken = $job->recreate();
// Make sure we've got a new job returned
$this->assertNotEquals($originalToken, $newToken);
// Now check the status of the new job
$newJob = \Resque\Job\Job::reserve('jobs');
$this->assertEquals(\Resque\Job\Status::STATUS_WAITING, $newJob->getStatus());
}
}

View file

@ -0,0 +1,423 @@
<?php
namespace Resque\Test;
/**
* ResqueJob tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class JobTest extends TestCase
{
protected $worker;
public function setUp(): void
{
parent::setUp();
// Register a worker to test with
$this->worker = new \Resque\Worker('jobs');
$this->worker->setLogger(new \Resque\Log());
$this->worker->registerWorker();
}
public function testJobCanBeQueued()
{
$this->assertTrue((bool)\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob'));
}
public function testQeueuedJobCanBeReserved()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$job = \Resque\Job\Job::reserve('jobs');
if ($job == false) {
$this->fail('Job could not be reserved.');
}
$this->assertEquals('jobs', $job->queue);
$this->assertEquals('\Resque\Test\TestJob', $job->payload['class']);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testObjectArgumentsCannotBePassedToJob()
{
$this->expectException(\InvalidArgumentException::class);
$args = new \stdClass();
$args->test = 'somevalue';
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
}
public function testQueuedJobReturnsExactSamePassedInArguments()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
$job = \Resque\Job\Job::reserve('jobs');
$this->assertEquals($args, $job->getArguments());
}
public function testAfterJobIsReservedItIsRemoved()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
\Resque\Job\Job::reserve('jobs');
$this->assertFalse(\Resque\Job\Job::reserve('jobs'));
}
public function testRecreatedJobMatchesExistingJob()
{
$args = [
'int' => 123,
'numArray' => [
1,
2,
],
'assocArray' => [
'key1' => 'value1',
'key2' => 'value2'
],
];
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob', $args);
$job = \Resque\Job\Job::reserve('jobs');
// Now recreate it
$job->recreate();
$newJob = \Resque\Job\Job::reserve('jobs');
$this->assertEquals($job->payload['class'], $newJob->payload['class']);
$this->assertEquals($job->getArguments(), $newJob->getArguments());
}
public function testFailedJobExceptionsAreCaught()
{
$payload = [
'class' => '\Resque\Test\FailingJob',
'args' => null
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->worker = $this->worker;
$this->worker->perform($job);
$this->assertEquals(1, \Resque\Stat::get('failed'));
$this->assertEquals(1, \Resque\Stat::get('failed:' . $this->worker));
}
/**
* @expectedException \Resque\Exception
*/
public function testJobWithoutPerformMethodThrowsException()
{
$this->expectException(\Resque\Exception::class);
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_Without_Perform_Method');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
/**
* @expectedException \Resque\Exception
*/
public function testInvalidJobThrowsException()
{
$this->expectException(\Resque\Exception::class);
\Resque\Resque::enqueue('jobs', '\Resque\Test\InvalidJob');
$job = $this->worker->reserve();
$job->worker = $this->worker;
$job->perform();
}
public function testJobWithSetUpCallbackFiresSetUp()
{
$payload = [
'class' => '\Resque\Test\TestJobWithSetUp',
'args' => [
'somevar',
'somevar2',
],
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->perform();
$this->assertTrue(TestJobWithSetUp::$called);
}
public function testJobWithTearDownCallbackFiresTearDown()
{
$payload = [
'class' => '\Resque\Test\TestJobWithTearDown',
'args' => [
'somevar',
'somevar2',
],
];
$job = new \Resque\Job\Job('jobs', $payload);
$job->perform();
$this->assertTrue(TestJobWithTearDown::$called);
}
public function testNamespaceNaming()
{
$fixture = [
['test' => 'more:than:one:with:', 'assertValue' => 'more:than:one:with:'],
['test' => 'more:than:one:without', 'assertValue' => 'more:than:one:without:'],
['test' => 'resque', 'assertValue' => 'resque:'],
['test' => 'resque:', 'assertValue' => 'resque:'],
];
foreach ($fixture as $item) {
\Resque\Redis::prefix($item['test']);
$this->assertEquals(\Resque\Redis::getPrefix(), $item['assertValue']);
}
}
public function testJobWithNamespace()
{
\Resque\Redis::prefix('php');
$queue = 'jobs';
$payload = ['another_value'];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobWithTearDown', $payload);
$this->assertEquals(\Resque\Resque::queues(), ['jobs']);
$this->assertEquals(\Resque\Resque::size($queue), 1);
\Resque\Redis::prefix('resque');
$this->assertEquals(\Resque\Resque::size($queue), 0);
}
public function testDequeueAll()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$this->assertEquals(\Resque\Resque::dequeue($queue), 2);
$this->assertEquals(\Resque\Resque::size($queue), 0);
}
public function testDequeueMakeSureNotDeleteOthers()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
$other_queue = 'other_jobs';
\Resque\Resque::enqueue($other_queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($other_queue, '\Resque\Test\TestJobDequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$this->assertEquals(\Resque\Resque::size($other_queue), 2);
$this->assertEquals(\Resque\Resque::dequeue($queue), 2);
$this->assertEquals(\Resque\Resque::size($queue), 0);
$this->assertEquals(\Resque\Resque::size($other_queue), 2);
}
public function testDequeueSpecificItem()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue2');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue2'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueSpecificMultipleItems()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue2', '\Resque\Test\TestJob_Dequeue3'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 2);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueNonExistingItem()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue4'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 3);
}
public function testDequeueNonExistingItem2()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue1');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue2');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue3');
$this->assertEquals(\Resque\Resque::size($queue), 3);
$test = ['\Resque\Test\TestJob_Dequeue4', '\Resque\Test\TestJob_Dequeue1'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueItemID()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$qid = \Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJob_Dequeue' => $qid];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueWrongItemID()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$qid = \Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
#qid right but class name is wrong
$test = ['\Resque\Test\TestJob_Dequeue1' => $qid];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueWrongItemID2()
{
$queue = 'jobs';
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJob_Dequeue');
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJob_Dequeue' => 'r4nD0mH4sh3dId'];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testDequeueItemWithArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue9' => $arg];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
#$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueSeveralItemsWithArgs()
{
// GIVEN
$queue = 'jobs';
$args = ['foo' => 1, 'bar' => 10];
$removeArgs = ['foo' => 1, 'bar' => 2];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $args);
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $removeArgs);
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue9', $removeArgs);
$this->assertEquals(\Resque\Resque::size($queue), 3, "Failed to add 3 items.");
// WHEN
$test = ['\Resque\Test\TestJobDequeue9' => $removeArgs];
$removedItems = \Resque\Resque::dequeue($queue, $test);
// THEN
$this->assertEquals($removedItems, 2);
$this->assertEquals(\Resque\Resque::size($queue), 1);
$item = \Resque\Resque::pop($queue);
$this->assertIsArray($item['args']);
$this->assertEquals(10, $item['args'][0]['bar'], 'Wrong items were dequeued from queue!');
}
public function testDequeueItemWithUnorderedArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['bar' => 2, 'foo' => 1];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue' => $arg2];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 1);
$this->assertEquals(\Resque\Resque::size($queue), 1);
}
public function testDequeueItemWithiWrongArg()
{
$queue = 'jobs';
$arg = ['foo' => 1, 'bar' => 2];
$arg2 = ['foo' => 2, 'bar' => 3];
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue');
\Resque\Resque::enqueue($queue, '\Resque\Test\TestJobDequeue', $arg);
$this->assertEquals(\Resque\Resque::size($queue), 2);
$test = ['\Resque\Test\TestJobDequeue' => $arg2];
$this->assertEquals(\Resque\Resque::dequeue($queue, $test), 0);
$this->assertEquals(\Resque\Resque::size($queue), 2);
}
public function testUseDefaultFactoryToGetJobInstance()
{
$payload = [
'class' => '\Resque\Test\SomeJobClass',
'args' => null
];
$job = new \Resque\Job\Job('jobs', $payload);
$instance = $job->getInstance();
$this->assertInstanceOf('\Resque\Test\SomeJobClass', $instance);
}
public function testUseFactoryToGetJobInstance()
{
$payload = [
'class' => 'SomeJobClass',
'args' => [[]]
];
$job = new \Resque\Job\Job('jobs', $payload);
$factory = new Some_Stub_Factory();
$job->setJobFactory($factory);
$instance = $job->getInstance();
$this->assertInstanceOf('\Resque\Job\JobInterface', $instance);
}
}
class SomeJobClass implements \Resque\Job\JobInterface
{
/**
* @return bool
*/
public function perform()
{
return true;
}
}
class Some_Stub_Factory implements \Resque\Job\FactoryInterface
{
/**
* @param $className
* @param array $args
* @param $queue
* @return \Resque\Job\JobInterface
*/
public function create($className, $args, $queue)
{
return new SomeJobClass();
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace Resque\Test;
/**
* \Resque\Log tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class LogTest extends TestCase
{
public function testLogInterpolate()
{
$logger = new \Resque\Log();
$actual = $logger->interpolate('string {replace}', ['replace' => 'value']);
$expected = 'string value';
$this->assertEquals($expected, $actual);
}
public function testLogInterpolateMutiple()
{
$logger = new \Resque\Log();
$actual = $logger->interpolate(
'string {replace1} {replace2}',
['replace1' => 'value1', 'replace2' => 'value2']
);
$expected = 'string value1 value2';
$this->assertEquals($expected, $actual);
}
}

View file

@ -0,0 +1,196 @@
<?php
namespace Resque\Test;
/**
* Resque_Event tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class RedisTest extends TestCase
{
public function testRedisGetSet()
{
$this->redis->set("testKey", 24);
$val = $this->redis->get("testKey");
$this->assertEquals(24, $val);
}
/**
* These DNS strings are considered valid.
*
* @return array
*/
public function validDsnStringProvider()
{
return [
// Input , Expected output
['', [
'localhost',
\Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['localhost', [
'localhost',
\Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['localhost:1234', [
'localhost',
1234,
false,
false, false,
[],
]],
['localhost:1234/2', [
'localhost',
1234,
2,
false, false,
[],
]],
['redis://foobar', [
'foobar',
\Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['redis://foobar/', [
'foobar',
\Resque\Redis::DEFAULT_PORT,
false,
false, false,
[],
]],
['redis://foobar:1234', [
'foobar',
1234,
false,
false, false,
[],
]],
['redis://foobar:1234/15', [
'foobar',
1234,
15,
false, false,
[],
]],
['redis://foobar:1234/0', [
'foobar',
1234,
0,
false, false,
[],
]],
['redis://user@foobar:1234', [
'foobar',
1234,
false,
'user', false,
[],
]],
['redis://user@foobar:1234/15', [
'foobar',
1234,
15,
'user', false,
[],
]],
['redis://user:pass@foobar:1234', [
'foobar',
1234,
false,
'user', 'pass',
[],
]],
['redis://user:pass@foobar:1234?x=y&a=b', [
'foobar',
1234,
false,
'user', 'pass',
['x' => 'y', 'a' => 'b'],
]],
['redis://:pass@foobar:1234?x=y&a=b', [
'foobar',
1234,
false,
false, 'pass',
['x' => 'y', 'a' => 'b'],
]],
['redis://user@foobar:1234?x=y&a=b', [
'foobar',
1234,
false,
'user', false,
['x' => 'y', 'a' => 'b'],
]],
['redis://foobar:1234?x=y&a=b', [
'foobar',
1234,
false,
false, false,
['x' => 'y', 'a' => 'b'],
]],
['redis://user@foobar:1234/12?x=y&a=b', [
'foobar',
1234,
12,
'user', false,
['x' => 'y', 'a' => 'b'],
]],
['tcp://user@foobar:1234/12?x=y&a=b', [
'foobar',
1234,
12,
'user', false,
['x' => 'y', 'a' => 'b'],
]],
];
}
/**
* These DSN values should throw exceptions
* @return array
*/
public function bogusDsnStringProvider()
{
return [
['http://foo.bar/'],
['user:@foobar:1234?x=y&a=b'],
['foobar:1234?x=y&a=b'],
];
}
/**
* @dataProvider validDsnStringProvider
* @param $dsn
* @param $expected
*/
public function testParsingValidDsnString($dsn, $expected)
{
$result = \Resque\Redis::parseDsn($dsn);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider bogusDsnStringProvider
*
* @expectedException \InvalidArgumentException
*
* @param $dsn
*/
public function testParsingBogusDsnStringThrowsException($dsn)
{
$this->expectException(\InvalidArgumentException::class);
\Resque\Redis::parseDsn($dsn);
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Resque\Test;
/**
* Resque\Stat tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class StatTest extends TestCase
{
public function testStatCanBeIncremented()
{
\Resque\Stat::incr('test_incr');
\Resque\Stat::incr('test_incr');
$this->assertEquals(2, $this->redis->get('resque:stat:test_incr'));
}
public function testStatCanBeIncrementedByX()
{
\Resque\Stat::incr('test_incrX', 10);
\Resque\Stat::incr('test_incrX', 11);
$this->assertEquals(21, $this->redis->get('resque:stat:test_incrX'));
}
public function testStatCanBeDecremented()
{
\Resque\Stat::incr('test_decr', 22);
\Resque\Stat::decr('test_decr');
$this->assertEquals(21, $this->redis->get('resque:stat:test_decr'));
}
public function testStatCanBeDecrementedByX()
{
\Resque\Stat::incr('test_decrX', 22);
\Resque\Stat::decr('test_decrX', 11);
$this->assertEquals(11, $this->redis->get('resque:stat:test_decrX'));
}
public function testGetStatByName()
{
\Resque\Stat::incr('test_get', 100);
$this->assertEquals(100, \Resque\Stat::get('test_get'));
}
public function testGetUnknownStatReturns0()
{
$this->assertEquals(0, \Resque\Stat::get('test_get_unknown'));
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Resque\Test;
/**
* Resque test case class. Contains setup and teardown methods.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class TestCase extends \PHPUnit\Framework\TestCase
{
protected $resque;
protected $redis;
public static function setUpBeforeClass(): void
{
date_default_timezone_set('UTC');
}
public function setUp(): void
{
// Setup redis connection for testing.
global $redisTestServer;
$this->redis = new \Credis_Client($redisTestServer, '6379');
\Resque\Resque::setBackend($redisTestServer);
$this->redis->flushAll();
}
}

View file

@ -0,0 +1,296 @@
<?php
namespace Resque\Test;
/**
* \Resque\Worker tests.
*
* @package Resque/Tests
* @author Daniel Mason <daniel@m2.nz>
* @license http://www.opensource.org/licenses/mit-license.php
*/
class WorkerTest extends TestCase
{
public function testWorkerRegistersInList()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
// Make sure the worker is in the list
$this->assertTrue((bool)$this->redis->sismember('resque:workers', (string)$worker));
}
public function testGetAllWorkers()
{
$num = 3;
// Register a few workers
for ($i = 0; $i < $num; ++$i) {
$worker = new \Resque\Worker('queue_' . $i);
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
}
// Now try to get them
$this->assertEquals($num, count(\Resque\Worker::all()));
}
public function testGetWorkerById()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
$newWorker = \Resque\Worker::find((string)$worker);
$this->assertEquals((string)$worker, (string)$newWorker);
}
public function testInvalidWorkerDoesNotExist()
{
$this->assertFalse(\Resque\Worker::exists('blah'));
}
public function testWorkerCanUnregister()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
$worker->unregisterWorker();
$this->assertFalse(\Resque\Worker::exists((string)$worker));
$this->assertEquals([], \Resque\Worker::all());
$this->assertEquals([], $this->redis->smembers('resque:workers'));
}
public function testPausedWorkerDoesNotPickUpJobs()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->pauseProcessing();
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker->work(0);
$worker->work(0);
$this->assertEquals(0, \Resque\Stat::get('processed'));
}
public function testResumedWorkerPicksUpJobs()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->pauseProcessing();
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker->work(0);
$this->assertEquals(0, \Resque\Stat::get('processed'));
$worker->unPauseProcessing();
$worker->work(0);
$this->assertEquals(1, \Resque\Stat::get('processed'));
}
public function testWorkerCanWorkOverMultipleQueues()
{
$worker = new \Resque\Worker([
'queue1',
'queue2'
]);
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
\Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
\Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve();
$this->assertEquals('queue1', $job->queue);
$job = $worker->reserve();
$this->assertEquals('queue2', $job->queue);
}
public function testWorkerWorksQueuesInSpecifiedOrder()
{
$worker = new \Resque\Worker([
'high',
'medium',
'low'
]);
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
// Queue the jobs in a different order
\Resque\Resque::enqueue('low', '\Resque\Test\TestJob_1');
\Resque\Resque::enqueue('high', '\Resque\Test\TestJob_2');
\Resque\Resque::enqueue('medium', '\Resque\Test\TestJob_3');
// Now check we get the jobs back in the right order
$job = $worker->reserve();
$this->assertEquals('high', $job->queue);
$job = $worker->reserve();
$this->assertEquals('medium', $job->queue);
$job = $worker->reserve();
$this->assertEquals('low', $job->queue);
}
public function testWildcardQueueWorkerWorksAllQueues()
{
$worker = new \Resque\Worker('*');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
\Resque\Resque::enqueue('queue1', '\Resque\Test\TestJob_1');
\Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob_2');
$job = $worker->reserve();
$this->assertEquals('queue1', $job->queue);
$job = $worker->reserve();
$this->assertEquals('queue2', $job->queue);
}
public function testWorkerDoesNotWorkOnUnknownQueues()
{
$worker = new \Resque\Worker('queue1');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
\Resque\Resque::enqueue('queue2', '\Resque\Test\TestJob');
$this->assertFalse($worker->reserve());
}
public function testWorkerClearsItsStatusWhenNotWorking()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$job = $worker->reserve();
$worker->workingOn($job);
$worker->doneWorking();
$this->assertEquals([], $worker->job());
}
public function testWorkerRecordsWhatItIsWorkingOn()
{
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
$payload = [
'class' => '\Resque\Test\TestJob'
];
$job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job);
$job = $worker->job();
$this->assertEquals('jobs', $job['queue']);
if (!isset($job['run_at'])) {
$this->fail('Job does not have run_at time');
}
$this->assertEquals($payload, $job['payload']);
}
public function testWorkerErasesItsStatsWhenShutdown()
{
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob');
\Resque\Resque::enqueue('jobs', '\Resque\Test\InvalidJob');
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->work(0);
$worker->work(0);
$this->assertEquals(0, $worker->getStat('processed'));
$this->assertEquals(0, $worker->getStat('failed'));
}
public function testWorkerCleansUpDeadWorkersOnStartup()
{
// Register a good worker
$goodWorker = new \Resque\Worker('jobs');
$goodWorker->setLogger(new \Resque\Log());
$goodWorker->registerWorker();
$workerId = explode(':', $goodWorker);
// Register some bad workers
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker();
$worker = new \Resque\Worker(['high', 'low']);
$worker->setLogger(new \Resque\Log());
$worker->setId($workerId[0] . ':2:high,low');
$worker->registerWorker();
$this->assertEquals(3, count(\Resque\Worker::all()));
$goodWorker->pruneDeadWorkers();
// There should only be $goodWorker left now
$this->assertEquals(1, count(\Resque\Worker::all()));
}
public function testDeadWorkerCleanUpDoesNotCleanUnknownWorkers()
{
// Register a bad worker on this machine
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$workerId = explode(':', $worker);
$worker->setId($workerId[0] . ':1:jobs');
$worker->registerWorker();
// Register some other false workers
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->setId('my.other.host:1:jobs');
$worker->registerWorker();
$this->assertEquals(2, count(\Resque\Worker::all()));
$worker->pruneDeadWorkers();
// my.other.host should be left
$workers = \Resque\Worker::all();
$this->assertEquals(1, count($workers));
$this->assertEquals((string)$worker, (string)$workers[0]);
}
public function testWorkerFailsUncompletedJobsOnExit()
{
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
$payload = [
'class' => '\Resque\Test\TestJob'
];
$job = new \Resque\Job\Job('jobs', $payload);
$worker->workingOn($job);
$worker->unregisterWorker();
$this->assertEquals(1, \Resque\Stat::get('failed'));
}
public function testBlockingListPop()
{
$worker = new \Resque\Worker('jobs');
$worker->setLogger(new \Resque\Log());
$worker->registerWorker();
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_1');
\Resque\Resque::enqueue('jobs', '\Resque\Test\TestJob_2');
$i = 1;
while ($job = $worker->reserve(true, 2)) {
$this->assertEquals('\Resque\Test\TestJob_' . $i, $job->payload['class']);
if ($i == 2) {
break;
}
$i++;
}
$this->assertEquals(2, $i);
}
}