Compare commits
5 Commits
350f08c2c1
...
596d1cb77d
Author | SHA1 | Date | |
---|---|---|---|
596d1cb77d
|
|||
d16da5de97
|
|||
4eeb3e424c | |||
d79c491578 | |||
d7a289d5c9
|
163
.github/workflows/ci.yaml
vendored
163
.github/workflows/ci.yaml
vendored
@ -1,163 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
php:
|
||||
- '8.1'
|
||||
dependencies:
|
||||
- lowest
|
||||
- highest
|
||||
services:
|
||||
nsqd:
|
||||
image: nsqio/nsq:v1.2.0
|
||||
options: --entrypoint /nsqd
|
||||
ports:
|
||||
- 4150:4150
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: pcov
|
||||
extensions: kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Setup Problem Matchers for PHPUnit
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Determine Composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=directory::$(composer config cache-dir)"
|
||||
|
||||
- name: Cache Composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.directory }}
|
||||
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-${{ matrix.php }}-${{ matrix.dependencies }}-composer-
|
||||
|
||||
- name: Install highest dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
if: ${{ matrix.dependencies == 'highest' }}
|
||||
|
||||
- name: Install lowest dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist --prefer-lowest
|
||||
if: ${{ matrix.dependencies == 'lowest' }}
|
||||
|
||||
- name: Run tests
|
||||
run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml
|
||||
|
||||
- name: Upload code coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: build/coverage-report.xml
|
||||
|
||||
php-cs-fixer:
|
||||
name: PHP-CS-Fixer
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: composer cs-check
|
||||
|
||||
phpstan:
|
||||
name: PHPStan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: snappy-kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: composer phpstan
|
||||
|
||||
psalm:
|
||||
name: Psalm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: snappy-kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: vendor/bin/psalm --output-format=github
|
37
.github/workflows/code_style.yaml
vendored
Normal file
37
.github/workflows/code_style.yaml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Code Style
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
php-cs-fixer:
|
||||
name: PHP-CS-Fixer
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: composer cs-check
|
71
.github/workflows/phpunit.yaml
vendored
Normal file
71
.github/workflows/phpunit.yaml
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
name: phpunit
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
phpunit:
|
||||
name: phpunit
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
php:
|
||||
- '8.1'
|
||||
nsq:
|
||||
- nsq-1.2.0.linux-amd64.go1.12.9
|
||||
- nsq-1.2.1.linux-amd64.go1.16.6
|
||||
dependencies:
|
||||
- lowest
|
||||
- highest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: pcov
|
||||
extensions: kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Download NSQ
|
||||
run: |
|
||||
curl -sSL "http://bitly-downloads.s3.amazonaws.com/nsq/${{ matrix.nsq }}.tar.gz" \
|
||||
| tar -xzv --strip-components=1
|
||||
./bin/nsqd --version
|
||||
|
||||
- name: Setup Problem Matchers for PHPUnit
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Determine Composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=directory::$(composer config cache-dir)"
|
||||
|
||||
- name: Cache Composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.directory }}
|
||||
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-${{ matrix.php }}-${{ matrix.dependencies }}-composer-
|
||||
|
||||
- name: Install highest dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
if: ${{ matrix.dependencies == 'highest' }}
|
||||
|
||||
- name: Install lowest dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist --prefer-lowest
|
||||
if: ${{ matrix.dependencies == 'lowest' }}
|
||||
|
||||
- name: Run tests
|
||||
run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml
|
||||
|
||||
- name: Upload code coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: build/coverage-report.xml
|
70
.github/workflows/static_analyze.yaml
vendored
Normal file
70
.github/workflows/static_analyze.yaml
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
name: Static Analyze
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
phpstan:
|
||||
name: PHPStan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: snappy-kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: composer phpstan
|
||||
|
||||
psalm:
|
||||
name: Psalm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
extensions: snappy-kjdev/php-ext-snappy@0.2.1
|
||||
env:
|
||||
update: true
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer update --no-progress --no-interaction --prefer-dist
|
||||
|
||||
- name: Run script
|
||||
run: vendor/bin/psalm --output-format=github
|
11
.gitignore
vendored
11
.gitignore
vendored
@ -4,3 +4,14 @@
|
||||
/.php-cs-fixer.cache
|
||||
/.phpunit.result.cache
|
||||
/infection.log
|
||||
|
||||
# Nsq
|
||||
bin/nsq_stat
|
||||
bin/nsq_tail
|
||||
bin/nsq_to_file
|
||||
bin/nsq_to_http
|
||||
bin/nsq_to_nsq
|
||||
bin/nsqadmin
|
||||
bin/nsqd
|
||||
bin/nsqlookupd
|
||||
bin/to_nsq
|
||||
|
@ -1,11 +1,12 @@
|
||||
# Nsq PHP
|
||||
|
||||
<img src="https://github.com/nsqphp/nsqphp/raw/main/docs/logo.png" alt="" align="left" width="150">
|
||||
<img src="https://github.com/nsqphp/nsqphp/raw/master/docs/logo.png" alt="" align="left" width="150">
|
||||
|
||||
PHP Client for [NSQ](https://nsq.io/).
|
||||
|
||||
[](//packagist.org/packages/nsq/nsq) [](//packagist.org/packages/nsq/nsq) [](//packagist.org/packages/nsq/nsq)
|
||||
[](https://codecov.io/gh/nsqphp/nsqphp) [](https://dashboard.stryker-mutator.io/reports/github.com/nsqphp/nsqphp/main)
|
||||
[](https://codecov.io/gh/nsqphp/nsqphp) [](https://dashboard.stryker-mutator.io/reports/github.com/nsqphp/nsqphp/master) [](http://t.me/grachevko)
|
||||
|
||||
|
||||
This library follow [SemVer](https://semver.org/). Until version 1.0 will be released anything MAY change at any time, public API SHOULD NOT be considered stable. If you want use it before stable version was released install strict version without range.
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpstan/phpstan-strict-rules": "^1.3",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"symfony/filesystem": "^6.1",
|
||||
"symfony/process": "^6.1",
|
||||
"symfony/var-dumper": "^6.1",
|
||||
"vimeo/psalm": "^4.4"
|
||||
},
|
||||
@ -45,6 +47,9 @@
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests/"
|
||||
],
|
||||
"files": [
|
||||
"vendor/symfony/var-dumper/Resources/functions/dump.php"
|
||||
]
|
||||
|
95
tests/Nsqd.php
Normal file
95
tests/Nsqd.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
final class Nsqd
|
||||
{
|
||||
public Process $process;
|
||||
|
||||
public string $address;
|
||||
|
||||
private static Filesystem $fs;
|
||||
|
||||
public function __construct(
|
||||
public readonly string $dataPath,
|
||||
public readonly int $httpPort,
|
||||
public readonly int $tcpPort,
|
||||
) {
|
||||
self::$fs ??= new Filesystem();
|
||||
self::$fs->mkdir($this->dataPath);
|
||||
|
||||
$nsqd = new Process([
|
||||
'./nsqd',
|
||||
sprintf('-data-path=%s', $this->dataPath),
|
||||
sprintf('-http-address=0.0.0.0:%s', $this->httpPort),
|
||||
sprintf('-tcp-address=0.0.0.0:%s', $this->tcpPort),
|
||||
'-log-level=debug',
|
||||
], dirname(__DIR__).'/bin');
|
||||
|
||||
$nsqd->start();
|
||||
|
||||
while (false === @fsockopen('localhost', $this->tcpPort)) {
|
||||
if (!$nsqd->isRunning()) {
|
||||
throw new RuntimeException($nsqd->getErrorOutput());
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
$this->process = $nsqd;
|
||||
$this->address = sprintf('tcp://localhost:%s', $this->tcpPort);
|
||||
}
|
||||
|
||||
public static function create(): self
|
||||
{
|
||||
do {
|
||||
$dir = sprintf('/tmp/%s', bin2hex(random_bytes(5)));
|
||||
} while (is_dir($dir));
|
||||
|
||||
return new self(
|
||||
$dir,
|
||||
findFreePort(),
|
||||
findFreePort(),
|
||||
);
|
||||
}
|
||||
|
||||
public function tail(string $topic, string $channel, int $messages): Process
|
||||
{
|
||||
$tail = new Process(
|
||||
[
|
||||
'./nsq_tail',
|
||||
sprintf('-nsqd-tcp-address=localhost:%s', $this->tcpPort),
|
||||
sprintf('-topic=%s', $topic),
|
||||
sprintf('-channel=%s', $channel),
|
||||
sprintf('-n=%s', $messages),
|
||||
'-print-topic',
|
||||
],
|
||||
dirname(__DIR__).'/bin',
|
||||
timeout: 10,
|
||||
);
|
||||
|
||||
$tail->start();
|
||||
|
||||
return $tail;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->process->stop();
|
||||
self::$fs->remove($this->dataPath);
|
||||
}
|
||||
}
|
||||
|
||||
function findFreePort(): int
|
||||
{
|
||||
$sock = socket_create_listen(0);
|
||||
assert($sock instanceof \Socket);
|
||||
|
||||
socket_getsockname($sock, $addr, $port);
|
||||
socket_close($sock);
|
||||
|
||||
return $port;
|
||||
}
|
@ -7,17 +7,75 @@ use Nsq\Exception\ServerException;
|
||||
use Nsq\Producer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function Amp\Promise\wait;
|
||||
|
||||
final class ProducerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider bodies
|
||||
*/
|
||||
public function testPublish(string $body): void
|
||||
{
|
||||
$nsqd = Nsqd::create();
|
||||
$tail = $nsqd->tail('test', 'test', 1);
|
||||
|
||||
$producer = Producer::create($nsqd->address);
|
||||
|
||||
wait($producer->connect());
|
||||
self::assertTrue(wait($producer->publish('test', $body)));
|
||||
|
||||
self::assertSame(0, $tail->wait());
|
||||
|
||||
self::assertSame("test | {$body}", trim($tail->getOutput()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider bodies
|
||||
*/
|
||||
public function testPublishMultiple(string $body): void
|
||||
{
|
||||
$nsqd = Nsqd::create();
|
||||
$tail = $nsqd->tail('test', 'test', 2);
|
||||
|
||||
$producer = Producer::create($nsqd->address);
|
||||
|
||||
wait($producer->connect());
|
||||
self::assertTrue(wait($producer->publish('test', [$body, $body])));
|
||||
|
||||
self::assertSame(0, $tail->wait());
|
||||
|
||||
self::assertSame("test | {$body}\ntest | {$body}", trim($tail->getOutput()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider bodies
|
||||
*/
|
||||
public function testPublishDeferred(string $body): void
|
||||
{
|
||||
$nsqd = Nsqd::create();
|
||||
$tail = $nsqd->tail('test', 'test', 1);
|
||||
|
||||
$producer = Producer::create($nsqd->address);
|
||||
|
||||
wait($producer->connect());
|
||||
self::assertTrue(wait($producer->publish('test', $body, 1)));
|
||||
|
||||
self::assertSame(0, $tail->wait());
|
||||
|
||||
self::assertSame("test | {$body}", trim($tail->getOutput()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider pubFails
|
||||
*/
|
||||
public function testPubFail(string $topic, string $body, string $exceptionMessage): void
|
||||
{
|
||||
$nsqd = Nsqd::create();
|
||||
|
||||
$this->expectException(ServerException::class);
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
|
||||
$producer = Producer::create('tcp://localhost:4150');
|
||||
$producer = Producer::create($nsqd->address);
|
||||
|
||||
Loop::run(static function () use ($producer, $topic, $body): Generator {
|
||||
yield $producer->connect();
|
||||
@ -31,4 +89,10 @@ final class ProducerTest extends TestCase
|
||||
yield 'Empty body' => ['test', '', 'E_BAD_MESSAGE PUB invalid message body size 0'];
|
||||
yield 'Invalid topic' => ['test$%^&', '', 'E_BAD_TOPIC PUB topic name "test$%^&" is not valid'];
|
||||
}
|
||||
|
||||
public function bodies(): Generator
|
||||
{
|
||||
yield 'Simple Body' => ['Simple Body'];
|
||||
yield 'Body with special chars' => ['test$%^&'];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user