Skip to content

Commit c1b46f4

Browse files
authored
Merge pull request #392 from gwleuverink/feature/child-processes
child process - sanity tests and tweaks
2 parents 62ce895 + a8bf775 commit c1b46f4

File tree

3 files changed

+156
-9
lines changed

3 files changed

+156
-9
lines changed

src/ChildProcess.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,38 @@ public function all(): array
5252
}
5353

5454
public function start(
55+
string|array $cmd,
5556
string $alias,
56-
array $cmd,
5757
?string $cwd = null,
5858
?array $env = null,
5959
bool $persistent = false
6060
): static {
61+
6162
$process = $this->client->post('child-process/start', [
6263
'alias' => $alias,
63-
'cmd' => $cmd,
64-
'cwd' => base_path(),
64+
'cmd' => (array) $cmd,
65+
'cwd' => $cwd ?? base_path(),
6566
'env' => $env,
6667
'persistent' => $persistent,
6768
])->json();
6869

6970
return $this->fromRuntimeProcess($process);
7071
}
7172

73+
public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self
74+
{
75+
$cmd = [PHP_BINARY, ...(array) $cmd];
76+
77+
return $this->start($cmd, $alias, env: $env, persistent: $persistent);
78+
}
79+
80+
public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self
81+
{
82+
$cmd = ['artisan', ...(array) $cmd];
83+
84+
return $this->php($cmd, $alias, env: $env, persistent: $persistent);
85+
}
86+
7287
public function stop(?string $alias = null): void
7388
{
7489
$this->client->post('child-process/stop', [
@@ -99,7 +114,7 @@ public function message(string $message, ?string $alias = null): static
99114
return $this;
100115
}
101116

102-
private function fromRuntimeProcess($process): static
117+
protected function fromRuntimeProcess($process): static
103118
{
104119
if (isset($process['pid'])) {
105120
$this->pid = $process['pid'];

src/Facades/ChildProcess.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@
33
namespace Native\Laravel\Facades;
44

55
use Illuminate\Support\Facades\Facade;
6+
use Native\Laravel\ChildProcess as Implement;
67

78
/**
89
* @method static \Native\Laravel\ChildProcess[] all()
9-
* @method static \Native\Laravel\ChildProcess get(string $alias)
10+
* @method static \Native\Laravel\ChildProcess get(string $alias = null)
1011
* @method static \Native\Laravel\ChildProcess message(string $message, string $alias = null)
11-
* @method static \Native\Laravel\ChildProcess restart(string $alias)
12-
* @method static \Native\Laravel\ChildProcess start(string $alias, array $cmd, string $cwd = null, array $env = null, bool $persistent = false)
13-
* @method static void stop(string $alias)
12+
* @method static \Native\Laravel\ChildProcess restart(string $alias = null)
13+
* @method static \Native\Laravel\ChildProcess start(string|array $cmd, string $alias, string $cwd = null, array $env = null, bool $persistent = false)
14+
* @method static \Native\Laravel\ChildProcess php(string|array $cmd, string $alias, array $env = null, bool $persistent = false)
15+
* @method static \Native\Laravel\ChildProcess artisan(string|array $cmd, string $alias, array $env = null, bool $persistent = false)
16+
* @method static void stop(string $alias = null)
1417
*/
1518
class ChildProcess extends Facade
1619
{
1720
protected static function getFacadeAccessor()
1821
{
19-
return \Native\Laravel\ChildProcess::class;
22+
self::clearResolvedInstance(Implement::class);
23+
24+
return Implement::class;
2025
}
2126
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
use Illuminate\Http\Client\Request;
4+
use Illuminate\Support\Facades\Http;
5+
use Mockery;
6+
use Native\Laravel\ChildProcess as ChildProcessImplement;
7+
use Native\Laravel\Client\Client;
8+
use Native\Laravel\Facades\ChildProcess;
9+
10+
beforeEach(function () {
11+
Http::fake();
12+
13+
$mock = Mockery::mock(ChildProcessImplement::class, [resolve(Client::class)])
14+
->makePartial()
15+
->shouldAllowMockingProtectedMethods();
16+
17+
$this->instance(ChildProcessImplement::class, $mock->allows([
18+
'fromRuntimeProcess' => $mock,
19+
]));
20+
});
21+
22+
it('can start a child process', function () {
23+
ChildProcess::start('foo bar', 'some-alias', 'path/to/dir', ['baz' => 'zah']);
24+
25+
Http::assertSent(function (Request $request) {
26+
return $request->url() === 'http://localhost:4000/api/child-process/start' &&
27+
$request['alias'] === 'some-alias' &&
28+
$request['cmd'] === ['foo bar'] &&
29+
$request['cwd'] === 'path/to/dir' &&
30+
$request['env'] === ['baz' => 'zah'];
31+
});
32+
});
33+
34+
it('can start a php command', function () {
35+
ChildProcess::php("-r 'sleep(5);'", 'some-alias', ['baz' => 'zah']);
36+
37+
Http::assertSent(function (Request $request) {
38+
return $request->url() === 'http://localhost:4000/api/child-process/start' &&
39+
$request['alias'] === 'some-alias' &&
40+
$request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"] &&
41+
$request['cwd'] === base_path() &&
42+
$request['env'] === ['baz' => 'zah'];
43+
});
44+
});
45+
46+
it('can start a artisan command', function () {
47+
ChildProcess::artisan('foo:bar --verbose', 'some-alias', ['baz' => 'zah']);
48+
49+
Http::assertSent(function (Request $request) {
50+
return $request->url() === 'http://localhost:4000/api/child-process/start' &&
51+
$request['alias'] === 'some-alias' &&
52+
$request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar --verbose'] &&
53+
$request['cwd'] === base_path() &&
54+
$request['env'] === ['baz' => 'zah'];
55+
});
56+
});
57+
58+
it('accepts either a string or a array as start command argument', function () {
59+
ChildProcess::start('foo bar', 'some-alias');
60+
Http::assertSent(fn (Request $request) => $request['cmd'] === ['foo bar']);
61+
62+
ChildProcess::start(['foo', 'baz'], 'some-alias');
63+
Http::assertSent(fn (Request $request) => $request['cmd'] === ['foo', 'baz']);
64+
});
65+
66+
it('accepts either a string or a array as php command argument', function () {
67+
ChildProcess::php("-r 'sleep(5);'", 'some-alias');
68+
Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"]);
69+
70+
ChildProcess::php(['-r', "'sleep(5);'"], 'some-alias');
71+
Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, '-r', "'sleep(5);'"]);
72+
});
73+
74+
it('accepts either a string or a array as artisan command argument', function () {
75+
ChildProcess::artisan('foo:bar', 'some-alias');
76+
Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar']);
77+
78+
ChildProcess::artisan(['foo:baz'], 'some-alias');
79+
Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:baz']);
80+
});
81+
82+
it('sets the cwd to the base path if none was given', function () {
83+
ChildProcess::start(['foo', 'bar'], 'some-alias', cwd: 'path/to/dir');
84+
Http::assertSent(fn (Request $request) => $request['cwd'] === 'path/to/dir');
85+
86+
ChildProcess::start(['foo', 'bar'], 'some-alias');
87+
Http::assertSent(fn (Request $request) => $request['cwd'] === base_path());
88+
});
89+
90+
it('can stop a child process', function () {
91+
ChildProcess::stop('some-alias');
92+
93+
Http::assertSent(function (Request $request) {
94+
return $request->url() === 'http://localhost:4000/api/child-process/stop' &&
95+
$request['alias'] === 'some-alias';
96+
});
97+
});
98+
99+
it('can send messages to a child process', function () {
100+
ChildProcess::message('some-message', 'some-alias');
101+
102+
Http::assertSent(function (Request $request) {
103+
return $request->url() === 'http://localhost:4000/api/child-process/message' &&
104+
$request['alias'] === 'some-alias' &&
105+
$request['message'] === 'some-message';
106+
});
107+
});
108+
109+
it('can mark a process as persistent', function () {
110+
ChildProcess::start('foo bar', 'some-alias', persistent: true);
111+
Http::assertSent(fn (Request $request) => $request['persistent'] === true);
112+
});
113+
114+
it('can mark a php command as persistent', function () {
115+
ChildProcess::php("-r 'sleep(5);'", 'some-alias', persistent: true);
116+
Http::assertSent(fn (Request $request) => $request['persistent'] === true);
117+
});
118+
119+
it('can mark a artisan command as persistent', function () {
120+
ChildProcess::artisan('foo:bar', 'some-alias', persistent: true);
121+
Http::assertSent(fn (Request $request) => $request['persistent'] === true);
122+
});
123+
124+
it('marks the process as non-persistent by default', function () {
125+
ChildProcess::start('foo bar', 'some-alias');
126+
Http::assertSent(fn (Request $request) => $request['persistent'] === false);
127+
});

0 commit comments

Comments
 (0)