diff --git a/src/UglyQueue.php b/src/UglyQueue.php index a9e01ec..a3e6fb0 100644 --- a/src/UglyQueue.php +++ b/src/UglyQueue.php @@ -58,10 +58,17 @@ class UglyQueue /** * @param int $ttl Time to live in seconds + * @throws \InvalidArgumentException * @return bool */ public function lock($ttl = 250) { + if (!is_int($ttl)) + throw new \InvalidArgumentException('UglyQueue::lock - Argument 1 expected to be positive integer, "'.gettype($ttl).'" seen'); + + if ($ttl < 0) + throw new \InvalidArgumentException('UglyQueue::lock - Argument 1 expected to be positive integer, "'.$ttl.'" seen'); + $already_locked = $this->isLocked(); // If there is no lock, currently @@ -102,10 +109,14 @@ class UglyQueue } /** + * @throws \RuntimeException * @return bool */ public function isLocked() { + if ($this->init === false) + throw new \RuntimeException('UglyQueue::isLocked - Must first initialize queue'); + // First check for lock file if (is_file($this->queueGroupDirPath.'queue.lock')) { @@ -248,13 +259,13 @@ HTML; // If we don't have a lock, assume issue and move on. if ($this->haveLock === false) - return false; + throw new \RuntimeException('UglyQueue::addToQueue - You do not have a lock on this queue'); if (!is_resource($this->_tmpHandle)) { $this->_tmpHandle = fopen($this->queueGroupDirPath.'queue.tmp', 'w+'); if ($this->_tmpHandle === false) - return false; + throw new \RuntimeException('UglyQueue::addToQueue - Unable to create "queue.tmp" file'); } if (is_array($value) || $value instanceof \stdClass) diff --git a/tests/UglyQueue/UglyQueueTest.php b/tests/UglyQueue/UglyQueueTest.php index a21339d..5f9ce0a 100644 --- a/tests/UglyQueue/UglyQueueTest.php +++ b/tests/UglyQueue/UglyQueueTest.php @@ -122,6 +122,30 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase $this->assertNull($queueGroupDir); } + /** + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @depends testCanConstructUglyQueueWithValidParameter + * @expectedException \RuntimeException + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testExceptionThrownWhenCallingIsLockedOnUninitializedQueue(\DCarbone\UglyQueue $uglyQueue) + { + $isLocked = $uglyQueue->isLocked(); + } + + /** + * @covers \DCarbone\UglyQueue::addToQueue + * @uses \DCarbone\UglyQueue + * @depends testCanConstructUglyQueueWithValidParameter + * @expectedException \RuntimeException + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testExceptionThrownWhenTryingToAddItemsToUninitializedQueue(\DCarbone\UglyQueue $uglyQueue) + { + $addToQueue = $uglyQueue->addToQueue('test', 'value'); + } + /** * @covers \DCarbone\UglyQueue::initialize * @covers \DCarbone\UglyQueue::getInit @@ -139,6 +163,18 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase return $uglyQueue; } + /** + * @covers \DCarbone\UglyQueue::addToQueue + * @uses \DCarbone\UglyQueue + * @depends testCanConstructUglyQueueWithValidParameter + * @expectedException \RuntimeException + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testExceptionThrownWhenTryingToAddItemsToQueueWithoutLock(\DCarbone\UglyQueue $uglyQueue) + { + $addToQueue = $uglyQueue->addToQueue('test', 'value'); + } + /** * @covers \DCarbone\UglyQueue::getInit * @uses \DCarbone\UglyQueue @@ -177,11 +213,25 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase $this->assertEquals('tasty-sandwich', $queueGroup); } + /** + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @depends testCanInitializeNewUglyQueue + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testIsLockedReturnsFalseBeforeLockingAfterInitialization(\DCarbone\UglyQueue $uglyQueue) + { + $isLocked = $uglyQueue->isLocked(); + + $this->assertFalse($isLocked); + } + /** * @covers \DCarbone\UglyQueue::initialize * @covers \DCarbone\UglyQueue::__construct * @covers \DCarbone\UglyQueue::getInit * @uses \DCarbone\UglyQueue + * @return \DCarbone\UglyQueue */ public function testCanInitializeExistingQueue() { @@ -198,10 +248,37 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase $uglyQueue->initialize('tasty-sandwich'); $this->assertTrue($uglyQueue->getInit()); + + return $uglyQueue; } /** * @covers \DCarbone\UglyQueue::lock + * @uses \DCarbone\UglyQueue + * @depends testCanConstructUglyQueueWithValidParameter + * @expectedException \InvalidArgumentException + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testExceptionThrownWhenPassingNonIntegerValueToLock(\DCarbone\UglyQueue $uglyQueue) + { + $uglyQueue->lock('7 billion'); + } + + /** + * @covers \DCarbone\UglyQueue::lock + * @uses \DCarbone\UglyQueue + * @depends testCanConstructUglyQueueWithValidParameter + * @expectedException \InvalidArgumentException + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testExceptionThrownWhenPassingNegativeIntegerValueToLock(\DCarbone\UglyQueue $uglyQueue) + { + $uglyQueue->lock(-73); + } + + /** + * @covers \DCarbone\UglyQueue::lock + * @covers \DCarbone\UglyQueue::isLocked * @covers \DCarbone\UglyQueue::createQueueLock * @uses \DCarbone\UglyQueue * @depends testCanInitializeNewUglyQueue @@ -228,4 +305,110 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase return $uglyQueue; } + /** + * @covers \DCarbone\UglyQueue::lock + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @depends testCanInitializeExistingQueue + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testCannotLockInitializedQueueThatIsAlreadyLocked(\DCarbone\UglyQueue $uglyQueue) + { + $lock = $uglyQueue->lock(); + + $this->assertFalse($lock); + } + + /** + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @depends testCanLockUglyQueueWithDefaultTTL + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testIsLockedReturnsTrueAfterLockingInitializedQueue(\DCarbone\UglyQueue $uglyQueue) + { + $isLocked = $uglyQueue->isLocked(); + $this->assertTrue($isLocked); + } + + /** + * @covers \DCarbone\UglyQueue::unlock + * @uses \DCarbone\UglyQueue + * @uses \DCarbone\Helpers\FileHelper + * @depends testCanLockUglyQueueWithDefaultTTL + * @param \DCarbone\UglyQueue $uglyQueue + * @return \DCarbone\UglyQueue + */ + public function testCanUnlockLockedQueue(\DCarbone\UglyQueue $uglyQueue) + { + $uglyQueue->unlock(); + + $queueGroupDir = $uglyQueue->getQueueGroupDirPath(); + + $this->assertFileNotExists($queueGroupDir.'queue.lock'); + + return $uglyQueue; + } + + /** + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @depends testCanUnlockLockedQueue + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testIsLockedReturnsFalseAfterUnlockingQueue(\DCarbone\UglyQueue $uglyQueue) + { + $isLocked = $uglyQueue->isLocked(); + + $this->assertFalse($isLocked); + } + + /** + * @covers \DCarbone\UglyQueue::lock + * @covers \DCarbone\UglyQueue::isLocked + * @uses \DCarbone\UglyQueue + * @uses \DCarbone\Helpers\FileHelper + * @depends testCanUnlockLockedQueue + * @param \DCarbone\UglyQueue $uglyQueue + */ + public function testIsLockedReturnsFalseWithStaleQueueLockFile(\DCarbone\UglyQueue $uglyQueue) + { + $uglyQueue->lock(2); + $isLocked = $uglyQueue->isLocked(); + $this->assertTrue($isLocked); + + sleep(3); + + $isLocked = $uglyQueue->isLocked(); + $this->assertFalse($isLocked); + } + + /** + * @covers \DCarbone\UglyQueue::lock + * @covers \DCarbone\UglyQueue::isLocked + * @covers \DCarbone\UglyQueue::getQueueGroupDirPath + * @uses \DCarbone\UglyQueue + * @depends testCanUnlockLockedQueue + * @param \DCarbone\UglyQueue $uglyQueue + * @return \DCarbone\UglyQueue + */ + public function testCanLockQueueWithValidIntegerValue(\DCarbone\UglyQueue $uglyQueue) + { + $locked = $uglyQueue->lock(200); + + $this->assertTrue($locked); + + $queueDir = $uglyQueue->getQueueGroupDirPath(); + + $this->assertFileExists($queueDir.'queue.lock'); + + $decode = @json_decode(file_get_contents($queueDir.'queue.lock')); + + $this->assertTrue((json_last_error() === JSON_ERROR_NONE)); + $this->assertObjectHasAttribute('ttl', $decode); + $this->assertObjectHasAttribute('born', $decode); + $this->assertEquals(200, $decode->ttl); + + return $uglyQueue; + } } \ No newline at end of file