| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 |
- <?php namespace GO\Job\Tests;
- use GO\Job;
- use PHPUnit\Framework\TestCase;
- class JobTest extends TestCase
- {
- public function testShouldAlwaysGenerateAnId()
- {
- $job1 = new Job('ls');
- $this->assertTrue(is_string($job1->getId()));
- $job2 = new Job(function () {
- return true;
- });
- $this->assertTrue(is_string($job2->getId()));
- $job3 = new Job(['MyClass', 'myMethod']);
- $this->assertTrue(is_string($job3->getId()));
- }
- public function testShouldGenerateIdFromSignature()
- {
- $job1 = new Job('ls');
- $this->assertEquals(md5('ls'), $job1->getId());
- $job2 = new Job('whoami');
- $this->assertNotEquals($job1->getId(), $job2->getId());
- $job3 = new Job(['MyClass', 'myMethod']);
- $this->assertNotEquals($job1->getId(), $job3->getId());
- }
- public function testShouldAllowCustomId()
- {
- $job = new Job('ls', [], 'aCustomId');
- $this->assertNotEquals(md5('ls'), $job->getId());
- $this->assertEquals('aCustomId', $job->getId());
- $job2 = new Job(['MyClass', 'myMethod'], null, 'myCustomId');
- $this->assertEquals('myCustomId', $job2->getId());
- }
- public function testShouldKnowIfDue()
- {
- $job1 = new Job('ls');
- $this->assertTrue($job1->isDue());
- $job2 = new Job('ls');
- $job2->at('* * * * *');
- $this->assertTrue($job2->isDue());
- $job3 = new Job('ls');
- $job3->at('10 * * * *');
- $this->assertTrue($job3->isDue(\DateTime::createFromFormat('i', '10')));
- $this->assertFalse($job3->isDue(\DateTime::createFromFormat('i', '12')));
- }
- public function testShouldKnowIfCanRunInBackground()
- {
- $job = new Job('ls');
- $this->assertTrue($job->canRunInBackground());
- $job2 = new Job(function () {
- return "I can't run in background";
- });
- $this->assertFalse($job2->canRunInBackground());
- }
- public function testShouldForceTheJobToRunInForeground()
- {
- $job = new Job('ls');
- $this->assertTrue($job->canRunInBackground());
- $this->assertFalse($job->inForeground()->canRunInBackground());
- }
- public function testShouldReturnCompiledJobCommand()
- {
- $job1 = new Job('ls');
- $this->assertEquals('ls', $job1->inForeground()->compile());
- $fn = function () {
- return true;
- };
- $job2 = new Job($fn);
- $this->assertEquals($fn, $job2->compile());
- }
- public function testShouldCompileWithArguments()
- {
- $job = new Job('ls', [
- '-l' => null,
- '-arg' => 'value',
- ]);
- $this->assertEquals("ls '-l' '-arg' 'value'", $job->inForeground()->compile());
- }
- public function testShouldCompileCommandInBackground()
- {
- $job1 = new Job('ls');
- $job1->at('* * * * *');
- $this->assertEquals('(ls) > /dev/null 2>&1 &', $job1->compile());
- }
- public function testShouldRunInBackground()
- {
- // This script has a 5 seconds sleep
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- $startTime = microtime(true);
- $job->at('* * * * *')->run();
- $endTime = microtime(true);
- $this->assertTrue(5 > ($endTime - $startTime));
- $startTime = microtime(true);
- $job->at('* * * * *')->inForeground()->run();
- $endTime = microtime(true);
- $this->assertTrue(($endTime - $startTime) >= 5);
- }
- public function testShouldRunInForegroundIfSendsEmails()
- {
- $job = new Job('ls');
- $job->email('test@mail.com');
- $this->assertFalse($job->canRunInBackground());
- }
- public function testShouldAcceptSingleOrMultipleEmails()
- {
- $job = new Job('ls');
- $this->assertInstanceOf(Job::class, $job->email('test@mail.com'));
- $this->assertInstanceOf(Job::class, $job->email(['test@mail.com', 'other@mail.com']));
- }
- public function testShouldFailIfEmailInputIsNotStringOrArray()
- {
- $this->expectException(\InvalidArgumentException::class);
- $job = new Job('ls');
- $job->email(1);
- }
- public function testShouldAcceptEmailConfigurationAndItShouldBeChainable()
- {
- $job = new Job('ls');
- $this->assertInstanceOf(Job::class, $job->configure([
- 'email' => [],
- ]));
- }
- public function testShouldFailIfEmailConfigurationIsNotArray()
- {
- $this->expectException(\InvalidArgumentException::class);
- $job = new Job('ls');
- $job->configure([
- 'email' => 123,
- ]);
- }
- public function testShouldCreateLockFileIfOnlyOne()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- // Default temp dir
- $tmpDir = sys_get_temp_dir();
- $lockFile = $tmpDir . '/' . $job->getId() . '.lock';
- @unlink($lockFile);
- $this->assertFalse(file_exists($lockFile));
- $job->onlyOne()->run();
- $this->assertTrue(file_exists($lockFile));
- }
- public function testShouldCreateLockFilesInCustomPath()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- // Default temp dir
- $tmpDir = __DIR__ . '/../tmp';
- $lockFile = $tmpDir . '/' . $job->getId() . '.lock';
- @unlink($lockFile);
- $this->assertFalse(file_exists($lockFile));
- $job->onlyOne($tmpDir)->run();
- $this->assertTrue(file_exists($lockFile));
- }
- public function testShouldRemoveLockFileAfterRunningClosures()
- {
- $job = new Job(function () {
- sleep(3);
- });
- // Default temp dir
- $tmpDir = __DIR__ . '/../tmp';
- $lockFile = $tmpDir . '/' . $job->getId() . '.lock';
- $job->onlyOne($tmpDir)->run();
- $this->assertFalse(file_exists($lockFile));
- }
- public function testShouldRemoveLockFileAfterRunningCommands()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- // Default temp dir
- $tmpDir = __DIR__ . '/../tmp';
- $lockFile = $tmpDir . '/' . $job->getId() . '.lock';
- $job->onlyOne($tmpDir)->run();
- sleep(1);
- $this->assertTrue(file_exists($lockFile));
- sleep(5);
- $this->assertFalse(file_exists($lockFile));
- }
- public function testShouldKnowIfOverlapping()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- $this->assertFalse($job->isOverlapping());
- $tmpDir = __DIR__ . '/../tmp';
- $job->onlyOne($tmpDir)->run();
- sleep(1);
- $this->assertTrue($job->isOverlapping());
- sleep(5);
- $this->assertFalse($job->isOverlapping());
- }
- public function testShouldNotRunIfOverlapping()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- $this->assertFalse($job->isOverlapping());
- $tmpDir = __DIR__ . '/../tmp';
- $job->onlyOne($tmpDir);
- sleep(1);
- $this->assertTrue($job->run());
- $this->assertFalse($job->run());
- sleep(6);
- $this->assertTrue($job->run());
- }
- public function testShouldRunIfOverlappingCallbackReturnsTrue()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- $this->assertFalse($job->isOverlapping());
- $tmpDir = __DIR__ . '/../tmp';
- $job->onlyOne($tmpDir, function ($lastExecution) {
- return time() - $lastExecution > 2;
- })->run();
- // The job should not run as it is overlapping
- $this->assertFalse($job->run());
- sleep(3);
- // The job should run now as the function should now return true,
- // while it's still being executed
- $lockFile = $tmpDir . '/' . $job->getId() . '.lock';
- $this->assertTrue(file_exists($lockFile));
- $this->assertTrue($job->run());
- }
- public function testShouldAcceptTempDirInConfiguration()
- {
- $command = PHP_BINARY . ' ' . __DIR__ . '/../async_job.php';
- $job = new Job($command);
- $tmpDir = __DIR__ . '/../tmp';
- $job->configure([
- 'tempDir' => $tmpDir,
- ])->onlyOne()->run();
- sleep(1);
- $this->assertTrue(file_exists($tmpDir . '/' . $job->getId() . '.lock'));
- }
- public function testWhenMethodShouldBeChainable()
- {
- $job = new Job('ls');
- $this->assertInstanceOf(Job::class, $job->when(function () {
- return true;
- }));
- }
- public function testShouldNotRunIfTruthTestFails()
- {
- $job = new Job('ls');
- $this->assertFalse($job->when(function () {
- return false;
- })->run());
- $this->assertTrue($job->when(function () {
- return true;
- })->run());
- }
- public function testShouldReturnOutputOfJobExecution()
- {
- $job1 = new Job(function () {
- echo 'hi';
- });
- $job1->run();
- $this->assertEquals('hi', $job1->getOutput());
- $job2 = new Job(function () {
- return 'hello';
- });
- $job2->run();
- $this->assertEquals('hello', $job2->getOutput());
- $command = PHP_BINARY . ' ' . __DIR__ . '/../test_job.php';
- $job3 = new Job($command);
- $job3->inForeground()->run();
- $this->assertEquals(['hi'], $job3->getOutput());
- }
- public function testShouldRunCallbackBeforeJobExecution()
- {
- $job = new Job(function () {
- return 'Job for testing before function';
- });
- $callbackWasExecuted = false;
- $outputWasSet = false;
- $job->before(function () use ($job, &$callbackWasExecuted, &$outputWasSet) {
- $callbackWasExecuted = true;
- $outputWasSet = ! is_null($job->getOutput());
- })->run();
- $this->assertTrue($callbackWasExecuted);
- $this->assertFalse($outputWasSet);
- }
- public function testShouldRunCallbackAfterJobExecution()
- {
- $job = new Job(function () {
- $visitors = 1000;
- return 'Daily visitors: ' . $visitors;
- });
- $jobResult = null;
- $job->then(function ($output) use (&$jobResult) {
- $jobResult = $output;
- })->run();
- $this->assertEquals($jobResult, $job->getOutput());
- $command = PHP_BINARY . ' ' . __DIR__ . '/../test_job.php';
- $job2 = new Job($command);
- $job2Result = null;
- $job2->then(function ($output) use (&$job2Result) {
- $job2Result = $output;
- }, true)->run();
- // Commands in background should return an empty string
- $this->assertTrue(empty($job2Result));
- $job2Result = null;
- $job2->then(function ($output) use (&$job2Result) {
- $job2Result = $output;
- })->inForeground()->run();
- $this->assertTrue(! empty($job2Result) &&
- $job2Result === $job2->getOutput());
- }
- public function testThenMethodShouldPassReturnCode()
- {
- $command_success = PHP_BINARY . ' ' . __DIR__ . '/../test_job.php';
- $command_fail = $command_success . ' fail';
- $run = function ($command) {
- $job = new Job($command);
- $testReturnCode = null;
- $job->then(function ($output, $returnCode) use (&$testReturnCode, &$testOutput) {
- $testReturnCode = $returnCode;
- })->run();
- return $testReturnCode;
- };
- $this->assertEquals(0, $run($command_success));
- $this->assertNotEquals(0, $run($command_fail));
- }
- public function testThenMethodShouldBeChainable()
- {
- $job = new Job('ls');
- $this->assertInstanceOf(Job::class, $job->then(function () {
- return true;
- }));
- }
- public function testShouldDefaultExecutionInForegroundIfMethodThenIsDefined()
- {
- $job = new Job('ls');
- $job->then(function () {
- return true;
- });
- $this->assertFalse($job->canRunInBackground());
- }
- public function testShouldAllowForcingTheJobToRunInBackgroundIfMethodThenIsDefined()
- {
- // This is a use case when you want to execute a callback every time your
- // job is executed, but you don't care about the output of the job
- $job = new Job('ls');
- $job->then(function () {
- return true;
- }, true);
- $this->assertTrue($job->canRunInBackground());
- }
- }
|