diff --git a/proofs/cluster.php b/proofs/cluster.php index b13850c..ee0c5b2 100644 --- a/proofs/cluster.php +++ b/proofs/cluster.php @@ -7,7 +7,10 @@ Network, Exception\CouldNotResolveHost, }; -use Innmind\Server\Control\Server\Command; +use Innmind\Server\Control\Server\{ + Command, + Process\Output, +}; use Innmind\HttpTransport\ConnectionFailed; use Innmind\Http\{ Request, @@ -18,8 +21,14 @@ Headers, Header\Date, }; -use Innmind\Filesystem\File\Content; -use Innmind\Url\Url; +use Innmind\Filesystem\{ + File\Content, + Recover, +}; +use Innmind\Url\{ + Url, + Path, +}; use Innmind\TimeContinuum\{ Period, Format, @@ -32,6 +41,7 @@ Monoid\Concat, }; use Innmind\BlackBox\Set; +use Fixtures\Innmind\Filesystem\File; use Fixtures\Innmind\TimeContinuum\PointInTime; return static function() { @@ -990,4 +1000,139 @@ static function($assert, $input, $intermediary, $expected) { ); }, ); + + yield proof( + 'Machine filesystem is accessible across apps', + given( + File::any(), + ), + static function($assert, $file) { + $local = Machine::new('local.dev') + ->listen( + Machine\HTTP::of( + static fn($request, $os) => $os + ->filesystem() + ->mount(Path::of('/somewhere/')) + ->recover(Recover::mount(...)) + ->flatMap(static fn($adapter) => $adapter->add($file)) + ->map(static fn() => Response::of( + StatusCode::ok, + $request->protocolVersion(), + )), + ), + ) + ->install( + 'foo', + Machine\CLI::of( + static fn($_, $builder, $os) => $builder->success( + $os + ->filesystem() + ->mount(Path::of('/somewhere/')) + ->maybe() + ->flatMap(static fn($adapter) => $adapter->get($file->name())) + ->toSequence() + ->flatMap(static fn($file) => $file->content()->chunks()) + ->map(static fn($chunk) => Output\Chunk::of( + $chunk, + Output\Type::output, + )), + ), + ), + ); + $cluster = Cluster::new() + ->add($local) + ->boot(); + + $response = $cluster + ->http(Request::of( + Url::of('http://local.dev/'), + Method::get, + ProtocolVersion::v11, + )) + ->unwrap(); + + $assert->true( + $response->statusCode()->successful(), + ); + + $stored = $cluster + ->ssh('local.dev') + ->flatMap(static fn($run) => $run(Command::foreground('foo'))) + ->unwrap() + ->output() + ->map(static fn($chunk) => $chunk->data()) + ->fold(new Concat) + ->toString(); + + $assert->same($file->content()->toString(), $stored); + }, + ); + + yield proof( + 'Each machine has its own filesystem', + given( + File::any(), + ), + static function($assert, $file) { + $local = Machine::new('local.dev') + ->listen( + Machine\HTTP::of( + static fn($request, $os) => $os + ->filesystem() + ->mount(Path::of('/somewhere/')) + ->recover(Recover::mount(...)) + ->flatMap(static fn($adapter) => $adapter->add($file)) + ->map(static fn() => Response::of( + StatusCode::ok, + $request->protocolVersion(), + )), + ), + ); + $remote = Machine::new('remote.dev') + ->install( + 'foo', + Machine\CLI::of( + static fn($_, $builder, $os) => $builder->success( + $os + ->filesystem() + ->mount(Path::of('/somewhere/')) + ->maybe() + ->flatMap(static fn($adapter) => $adapter->get($file->name())) + ->toSequence() + ->flatMap(static fn($file) => $file->content()->chunks()) + ->map(static fn($chunk) => Output\Chunk::of( + $chunk, + Output\Type::output, + )), + ), + ), + ); + $cluster = Cluster::new() + ->add($local) + ->boot(); + + $response = $cluster + ->http(Request::of( + Url::of('http://local.dev/'), + Method::get, + ProtocolVersion::v11, + )) + ->unwrap(); + + $assert->true( + $response->statusCode()->successful(), + ); + + $stored = $cluster + ->ssh('local.dev') + ->flatMap(static fn($run) => $run(Command::foreground('foo'))) + ->unwrap() + ->output() + ->map(static fn($chunk) => $chunk->data()) + ->fold(new Concat) + ->toString(); + + $assert->same('', $stored); + }, + ); }; diff --git a/src/Simulation/Machine/Config.php b/src/Simulation/Machine/Config.php index 6b5e8c9..d3d4977 100644 --- a/src/Simulation/Machine/Config.php +++ b/src/Simulation/Machine/Config.php @@ -29,6 +29,14 @@ Response, Response\StatusCode, }; +use Innmind\Filesystem\{ + Adapter, + CaseSensitivity, +}; +use Innmind\IO\{ + IO, + Simulation\Disk, +}; use Innmind\TimeContinuum\Clock; use Innmind\Immutable\{ Attempt, @@ -49,6 +57,8 @@ public static function of( Processes $processes, Drift $drift, ): OSConfig { + $disk = Disk::new(); + return OSConfig::new() ->withClock(Clock::via(static fn() => $drift( $network->ntp()->now(), @@ -110,6 +120,16 @@ public static function of( ), }), ), - )); + )) + ->mountFilesystemVia( + static fn($path, $config) => Adapter::mount( + $path, + CaseSensitivity::sensitive, + IO::simulation( + $config->io(), + $disk, + ), + ), + ); } }