diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aafc0f6..beb83f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,15 +1,18 @@ name: CI -on: [push] +on: + push: + branches: [master] + pull_request: jobs: - build-test: + test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] - name: PHP ${{ matrix.php-versions }} Test + php-version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] + name: PHP ${{ matrix.php-version }} Test services: redis: image: redis @@ -22,30 +25,30 @@ jobs: - 6379:6379 steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-versions }} - extensions: :redis + php-version: ${{ matrix.php-version }} + extensions: pcntl, sysvshm, sysvsem, sysvmsg, redis + coverage: ${{ matrix.php-version == '8.5' && 'xdebug' || 'none' }} - - name: Install composer and dependencies - uses: php-actions/composer@v6 + - name: Install dependencies + run: composer install --no-interaction --prefer-dist - - name: PHPUnit Tests - uses: php-actions/phpunit@v3 - env: - XDEBUG_MODE: coverage - with: - bootstrap: vendor/autoload.php - configuration: phpunit.xml - php_extensions: xdebug sysvshm pcntl sysvsem sysvmsg redis - version: 9 - args: tests --coverage-clover ./coverage.xml + - name: Run tests (with coverage) + if: matrix.php-version == '8.5' + run: | + XDEBUG_MODE=coverage vendor/bin/phpunit --configuration phpunit.xml --coverage-clover ./coverage.xml + + - name: Run tests + if: matrix.php-version != '8.5' + run: vendor/bin/phpunit --configuration phpunit.xml - name: Upload to Codecov - uses: codecov/codecov-action@v3 + if: matrix.php-version == '8.5' + uses: codecov/codecov-action@v4 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/src/Lock/Semaphore.php b/src/Lock/Semaphore.php index c664ee0..1247d9b 100644 --- a/src/Lock/Semaphore.php +++ b/src/Lock/Semaphore.php @@ -15,6 +15,7 @@ */ class Semaphore implements LockInterface { + /** @var false|resource|\SysvSemaphore */ private $lock_id; /** @@ -151,17 +152,13 @@ public function remove() if ($this->locked) { throw new \RuntimeException('can not remove a locked semaphore resource'); } - if (!is_resource($this->lock_id)) { - throw new \RuntimeException('can not remove a empty semaphore resource'); - } - // @codeCoverageIgnoreStart - // seems impossible to reproduce further below - if (!sem_release($this->lock_id)) { - return false; - } + if (is_resource($this->lock_id) || $this->lock_id instanceof \SysvSemaphore) { + $result = sem_remove($this->lock_id); + $this->lock_id = null; + return $result; + } - return true; - // @codeCoverageIgnoreEnd - } -} \ No newline at end of file + throw new \RuntimeException('can not remove a empty semaphore resource'); + } +} diff --git a/src/Process.php b/src/Process.php index b3cc149..53813f5 100644 --- a/src/Process.php +++ b/src/Process.php @@ -75,7 +75,7 @@ class Process * @param string|callable|null $execution it can be a Runnable object, callback function or null * @param string|null $name process name,you can manager the process by it's name. */ - public function __construct($execution = null, string $name = null) + public function __construct($execution = null, ?string $name = null) { if ($execution instanceof Runnable) { $this->runnable = $execution; diff --git a/tests/FileCacheTest.php b/tests/FileCacheTest.php index 7101147..4e7cfe9 100644 --- a/tests/FileCacheTest.php +++ b/tests/FileCacheTest.php @@ -34,7 +34,7 @@ public function testCacheExpiration() $this->assertTrue($cache->delete($key)); $this->assertNull($cache->get($key)); $this->assertTrue($cache->flush()); - $this->assertFileDoesNotExist($path); + $this->assertFalse(file_exists($path)); } /** diff --git a/tests/PipeQueueTest.php b/tests/PipeQueueTest.php index 883684e..8266280 100644 --- a/tests/PipeQueueTest.php +++ b/tests/PipeQueueTest.php @@ -23,6 +23,13 @@ public function testPutAndGet() $queue->remove(); } + public function testGetFromEmptyQueue() + { + $queue = new \Jenner\SimpleFork\Queue\PipeQueue(); + $this->assertNull($queue->get()); + $queue->remove(); + } + public function testValueTooLong() { $memory_limit = ini_get('memory_limit'); diff --git a/tests/ProcessTest.php b/tests/ProcessTest.php index 39682e5..39a8698 100644 --- a/tests/ProcessTest.php +++ b/tests/ProcessTest.php @@ -115,6 +115,42 @@ public function testInvalidProcess(): void new \Jenner\SimpleFork\Process("abc"); } + public function testGetPid(): void + { + $process = new \Jenner\SimpleFork\Process(function () { + usleep(100000); + }); + $this->assertNull($process->getPid()); + $process->start(); + $this->assertIsInt($process->getPid()); + $this->assertGreaterThan(0, $process->getPid()); + $process->wait(); + } + + public function testName(): void + { + $process = new \Jenner\SimpleFork\Process(function () {}, 'my-process'); + $this->assertEquals('my-process', $process->name()); + + $process->name('renamed'); + $this->assertEquals('renamed', $process->name()); + } + + public function testIsStartedAndIsStopped(): void + { + $process = new \Jenner\SimpleFork\Process(function () { + usleep(100000); + }); + $this->assertFalse($process->isStarted()); + $this->assertFalse($process->isStopped()); + + $process->start(); + $this->assertTrue($process->isStarted()); + + $process->wait(); + $this->assertTrue($process->isStopped()); + } + } class MyThread extends \Jenner\SimpleFork\Process diff --git a/tests/SemaphoreTest.php b/tests/SemaphoreTest.php index 825bf86..6de80ff 100644 --- a/tests/SemaphoreTest.php +++ b/tests/SemaphoreTest.php @@ -76,6 +76,15 @@ public function testRemoveLockWhenLockReleased() $this->lock->acquire(false); $this->lock->release(); + $this->assertTrue($this->lock->remove()); + } + + public function testRemoveAlreadyRemovedSemaphore() + { + $this->lock->acquire(false); + $this->lock->release(); + $this->lock->remove(); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage("can not remove a empty semaphore resource"); $this->lock->remove();