diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a78db1a..a151524 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,9 @@ jobs: with: dependency-versions: ${{ matrix.dependencies }} - name: PHPUnit - run: php -dmemory_limit=-1 vendor/bin/phpunit --coverage-clover=coverage.clover + run: php blackbox.php + env: + ENABLE_COVERAGE: 'true' - uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 5032877..a696500 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ composer.lock vendor -.phpunit.result.cache -.phpunit.cache .cache diff --git a/blackbox.php b/blackbox.php new file mode 100644 index 0000000..50022e2 --- /dev/null +++ b/blackbox.php @@ -0,0 +1,27 @@ +when( + \getenv('ENABLE_COVERAGE') !== false, + static fn(Application $app) => $app + ->codeCoverage( + CodeCoverage::of( + __DIR__.'/src/', + __DIR__.'/tests/', + ) + ->dumpTo('coverage.clover') + ->enableWhen(true), + ) + ->scenariiPerProof(1), + ) + ->tryToProve(Load::directory(__DIR__.'/tests/')) + ->exit(); diff --git a/composer.json b/composer.json index a22a454..eb4ac8c 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,6 @@ } }, "require-dev": { - "phpunit/phpunit": "~10.2", "innmind/url": "~4.0", "innmind/ip": "~3.0", "innmind/static-analysis": "^1.2.1", diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index 3c2816b..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - ./tests - - - - - . - - - ./tests - ./vendor - - - diff --git a/tests/CurrentProcess/GenericTest.php b/tests/CurrentProcess/GenericTest.php index c782669..fa27004 100644 --- a/tests/CurrentProcess/GenericTest.php +++ b/tests/CurrentProcess/GenericTest.php @@ -13,7 +13,7 @@ use Innmind\TimeContinuum\Period; use Innmind\TimeWarp\Halt; use Innmind\Immutable\SideEffect; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class GenericTest extends TestCase { @@ -21,13 +21,13 @@ public function testInterface() { $this->assertInstanceOf( CurrentProcess::class, - Generic::of($this->createMock(Halt::class)), + Generic::of(Halt\Usleep::new()), ); } public function testId() { - $process = Generic::of($this->createMock(Halt::class)); + $process = Generic::of(Halt\Usleep::new()); $this->assertInstanceOf(Pid::class, $process->id()->unwrap()); $this->assertSame( @@ -52,7 +52,7 @@ public function testHalt() public function testSignals() { - $process = Generic::of($this->createMock(Halt::class)); + $process = Generic::of(Halt\Usleep::new()); $this->assertInstanceOf(Signals\Wrapper::class, $process->signals()); $this->assertSame($process->signals(), $process->signals()); @@ -60,7 +60,7 @@ public function testSignals() public function testMemory() { - $process = Generic::of($this->createMock(Halt::class)); + $process = Generic::of(Halt\Usleep::new()); $this->assertInstanceOf(Bytes::class, $process->memory()); $this->assertTrue($process->memory()->toInt() > 6000000); // ~5MB diff --git a/tests/CurrentProcess/LoggerTest.php b/tests/CurrentProcess/LoggerTest.php deleted file mode 100644 index 74e97b2..0000000 --- a/tests/CurrentProcess/LoggerTest.php +++ /dev/null @@ -1,125 +0,0 @@ -assertInstanceOf( - CurrentProcess::class, - Logger::psr( - $this->createMock(CurrentProcess::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testId() - { - $this - ->forAll(Set\Integers::above(2)) - ->then(function($id) { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('id') - ->willReturn(Attempt::result($expected = new Pid($id))); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Current process id is {pid}', - ['pid' => $id], - ); - $process = Logger::psr($inner, $logger); - - $this->assertSame($expected, $process->id()->unwrap()); - }); - } - - public function testAlwaysUseSameSignalInstance() - { - $inner = $this->createMock(CurrentProcess::class); - $logger = $this->createMock(LoggerInterface::class); - $process = Logger::psr($inner, $logger); - - $this->assertInstanceOf(Signals\Logger::class, $process->signals()); - $this->assertSame($process->signals(), $process->signals()); - } - - public function testHalt() - { - $period = Period::millisecond(1); - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('halt') - ->with($period) - ->willReturn(Attempt::result(SideEffect::identity())); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with('Halting current process...'); - $process = Logger::psr($inner, $logger); - - $this->assertInstanceOf( - SideEffect::class, - $process - ->halt($period) - ->unwrap(), - ); - } - - public function testMemory() - { - $this - ->forAll(Set\Integers::above(0)) - ->then(function($memory) { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('memory') - ->willReturn($expected = Bytes::of($memory)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Current process memory at {memory}', - $this->callback(static function($context) { - return \array_key_exists('memory', $context) && - \is_string($context['memory']) && - $context['memory'] !== ''; - }), - ); - $process = Logger::psr($inner, $logger); - - $this->assertSame($expected, $process->memory()); - }); - } -} diff --git a/tests/CurrentProcess/Signals/LoggerTest.php b/tests/CurrentProcess/Signals/LoggerTest.php deleted file mode 100644 index f8fa3b5..0000000 --- a/tests/CurrentProcess/Signals/LoggerTest.php +++ /dev/null @@ -1,181 +0,0 @@ -assertInstanceOf( - Signals::class, - Logger::psr( - $this->createMock(Signals::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testLogWhenRegisteringListener() - { - $this - ->forAll($this->signals()) - ->then(function($signal) { - $inner = $this->createMock(Signals::class); - $inner - ->expects($this->once()) - ->method('listen') - ->with($signal); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Registering a listener for signal {signal}', - ['signal' => $signal->toInt()], - ); - $signals = Logger::psr($inner, $logger); - - $this->assertNull($signals->listen($signal, static fn() => null)); - }); - } - - public function testLogWhenListenerCalled() - { - $this - ->forAll($this->signals()) - ->then(function($signal) { - $info = new Info( - Maybe::nothing(), - Maybe::nothing(), - Maybe::nothing(), - Maybe::nothing(), - Maybe::nothing(), - ); - $inner = $this->createMock(Signals::class); - $inner - ->expects($this->once()) - ->method('listen') - ->with($signal, $this->callback(static function($listener) use ($signal, $info) { - $listener($signal, $info); - - return true; - })); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($matcher = $this->exactly(2)) - ->method('debug') - ->willReturnCallback(function($message, $context) use ($matcher, $signal) { - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('Handling signal {signal}', $message); - $this->assertSame( - ['signal' => $signal->toInt()], - $context, - ); - } - }); - $signals = Logger::psr($inner, $logger); - $called = false; - - $this->assertNull($signals->listen($signal, function($sig, $inf) use ($signal, $info, &$called) { - $called = true; - - $this->assertSame($signal, $sig); - $this->assertSame($info, $inf); - })); - $this->assertTrue($called); - }); - } - - public function testUseSameRegisteredListenerWhenRemovingOne() - { - $this - ->forAll($this->signals()) - ->then(function($signal) { - $registeredListener = null; - $inner = $this->createMock(Signals::class); - $inner - ->expects($this->once()) - ->method('listen') - ->with($signal, $this->callback(static function($listener) use (&$registeredListener) { - $registeredListener = $listener; - - return true; - })); - $inner - ->expects($this->once()) - ->method('remove') - ->with($this->callback(static function($listener) use (&$registeredListener) { - return $listener === $registeredListener; - })); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($matcher = $this->exactly(2)) - ->method('debug') - ->willReturnCallback(function($message) use ($matcher) { - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame( - 'Removing a signal listener', - $message, - ); - } - }); - $signals = Logger::psr($inner, $logger); - $listener = static fn() => null; - - $this->assertNull($signals->listen($signal, $listener)); - $this->assertNull($signals->remove($listener)); - }); - } - - private function signals(): Set - { - return Set\Elements::of( - Signal::hangup, - Signal::interrupt, - Signal::quit, - Signal::illegal, - Signal::trap, - Signal::abort, - Signal::floatingPointException, - Signal::bus, - Signal::segmentationViolation, - Signal::system, - Signal::pipe, - Signal::alarm, - Signal::terminate, - Signal::urgent, - Signal::terminalStop, - Signal::continue, - Signal::child, - Signal::ttyIn, - Signal::ttyOut, - Signal::io, - Signal::exceedsCpu, - Signal::exceedsFileSize, - Signal::virtualTimerExpired, - Signal::profilingTimerExpired, - Signal::terminalWindowsSizeChanged, - Signal::userDefinedSignal1, - Signal::userDefinedSignal2, - ); - } -} diff --git a/tests/CurrentProcess/Signals/WrapperTest.php b/tests/CurrentProcess/Signals/WrapperTest.php index dd6ebfc..304b96b 100644 --- a/tests/CurrentProcess/Signals/WrapperTest.php +++ b/tests/CurrentProcess/Signals/WrapperTest.php @@ -11,7 +11,7 @@ Handler, Signal }; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class WrapperTest extends TestCase { diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index f3bcf98..2dc8569 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -16,7 +16,7 @@ }; use Innmind\Url\Path; use Symfony\Component\Filesystem\Filesystem as FS; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class FactoryTest extends TestCase { @@ -40,7 +40,9 @@ public function testClockIsOptional() public function testPersistingFileOnCaseInsensitiveFilesystem() { if (\PHP_OS !== 'Darwin') { - $this->markTestSkipped(); + $this->assertTrue(true); + + return; } $path = \sys_get_temp_dir().'/innmind/filesystem/'; diff --git a/tests/Filesystem/GenericTest.php b/tests/Filesystem/GenericTest.php index 01bde44..3b604e6 100644 --- a/tests/Filesystem/GenericTest.php +++ b/tests/Filesystem/GenericTest.php @@ -7,13 +7,13 @@ Filesystem\Generic, Filesystem, Config, + Factory, }; use Innmind\Filesystem\{ Adapter\Filesystem as FilesystemAdapter, File\Content, }; use Innmind\Url\Path; -use Innmind\Server\Control\Server\Processes; use Innmind\FileWatch\Ping; use Fixtures\Innmind\Url\Path as FPath; use Innmind\Immutable\{ @@ -21,9 +21,9 @@ Str, Maybe, }; -use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ PHPUnit\BlackBox, + PHPUnit\Framework\TestCase, Set, }; @@ -36,7 +36,7 @@ public function testInterface() $this->assertInstanceOf( Filesystem::class, Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ), ); @@ -45,7 +45,7 @@ public function testInterface() public function testMount() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -57,7 +57,7 @@ public function testMount() public function testMountingTheSamePathTwiceReturnsTheSameAdapter() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -69,7 +69,7 @@ public function testMountingTheSamePathTwiceReturnsTheSameAdapter() public function testContainsFile() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -82,7 +82,7 @@ public function testContainsFile() public function testContainsDirectory() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -95,20 +95,20 @@ public function testContainsDirectory() public function testWatch() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); $this->assertInstanceOf(Ping::class, $filesystem->watch(Path::of('/somewhere'))); } - public function testRequireUnknownFile() + public function testRequireUnknownFile(): BlackBox\Proof { - $this + return $this ->forAll(FPath::any()) - ->then(function($path) { + ->prove(function($path) { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -122,7 +122,7 @@ public function testRequireUnknownFile() public function testRequireFile() { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -135,10 +135,10 @@ public function testRequireFile() public function testCreateTemporaryFile() { $this - ->forAll(Set\Sequence::of(Set\Unicode::strings())) + ->forAll(Set::sequence(Set::strings()->unicode())) ->then(function($chunks) { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); @@ -165,12 +165,12 @@ public function testCreateTemporaryFileFailure() { $this ->forAll( - Set\Sequence::of(Set\Unicode::strings())->between(0, 20), // upper bound to fit in memory - Set\Sequence::of(Set\Unicode::strings())->between(0, 20), // upper bound to fit in memory + Set::sequence(Set::strings()->unicode())->between(0, 20), // upper bound to fit in memory + Set::sequence(Set::strings()->unicode())->between(0, 20), // upper bound to fit in memory ) ->then(function($leading, $trailing) { $filesystem = Generic::of( - $this->createMock(Processes::class), + Factory::build()->control()->processes(), Config::of(), ); diff --git a/tests/Filesystem/LoggerTest.php b/tests/Filesystem/LoggerTest.php deleted file mode 100644 index 435fb75..0000000 --- a/tests/Filesystem/LoggerTest.php +++ /dev/null @@ -1,182 +0,0 @@ -assertInstanceOf( - Filesystem::class, - Logger::psr( - $this->createMock(Filesystem::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testMount() - { - $this - ->forAll(Path::any()) - ->then(function($path) { - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('mount') - ->with($path) - ->willReturn(Attempt::result($this->createMock(Adapter::class))); - $logger = $this->createMock(LoggerInterface::class); - $filesystem = Logger::psr($inner, $logger); - - $this->assertInstanceOf( - Adapter\Logger::class, - $filesystem->mount($path)->unwrap(), - ); - }); - } - - public function testContainsPath() - { - $this - ->forAll(Path::any()) - ->then(function($path) { - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('contains') - ->with($path) - ->willReturn(true); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Checking if {path} exists, answer: {answer}', - ['answer' => 'yes'], - ); - $filesystem = Logger::psr($inner, $logger); - - $this->assertTrue($filesystem->contains($path)); - }); - } - - public function testDoesntContainPath() - { - $this - ->forAll(Path::any()) - ->then(function($path) { - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('contains') - ->with($path) - ->willReturn(false); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Checking if {path} exists, answer: {answer}', - ['answer' => 'no'], - ); - $filesystem = Logger::psr($inner, $logger); - - $this->assertFalse($filesystem->contains($path)); - }); - } - - public function testWatch() - { - $this - ->forAll(Path::any()) - ->then(function($path) { - $os = Factory::build(); - $watch = FileWatch\Factory::build( - $os->control()->processes(), - Halt\Usleep::new(), - ); - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('watch') - ->with($path) - ->willReturn($watch($path)); - $logger = $this->createMock(LoggerInterface::class); - $filesystem = Logger::psr($inner, $logger); - - $this->assertInstanceOf(Ping::class, $filesystem->watch($path)); - }); - } - - public function testDoesntLogUnknownRequiredFile() - { - $this - ->forAll(Path::any()) - ->then(function($path) { - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('require') - ->with($path) - ->willReturn($expected = Maybe::nothing()); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->never()) - ->method('debug'); - $filesystem = Logger::psr($inner, $logger); - - $this->assertEquals($expected, $filesystem->require($path)); - }); - } - - public function testLogRequiredFile() - { - $this - ->forAll( - Path::any(), - Set\Type::any(), - ) - ->then(function($path, $value) { - $inner = $this->createMock(Filesystem::class); - $inner - ->expects($this->once()) - ->method('require') - ->with($path) - ->willReturn($expected = Maybe::just($value)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug'); - $filesystem = Logger::psr($inner, $logger); - - $this->assertEquals($expected, $filesystem->require($path)); - }); - } -} diff --git a/tests/OperatingSystem/LoggerTest.php b/tests/OperatingSystem/LoggerTest.php deleted file mode 100644 index e4644b4..0000000 --- a/tests/OperatingSystem/LoggerTest.php +++ /dev/null @@ -1,118 +0,0 @@ -os = Logger::psr( - $this->underlying = Unix::of(), - $this->createMock(LoggerInterface::class), - ); - } - - public function testInterface() - { - $this->assertInstanceOf( - OperatingSystem::class, - $this->os, - ); - } - - public function testClock() - { - $this->assertInstanceOf( - TimeContinuum\Clock::class, - $this->os->clock(), - ); - } - - public function testFilesystem() - { - $this->assertInstanceOf( - Filesystem\Logger::class, - $this->os->filesystem(), - ); - } - - public function testStatus() - { - $this->assertInstanceOf( - Status\Servers\Logger::class, - $this->os->status(), - ); - } - - public function testControl() - { - $this->assertInstanceOf( - Control\Servers\Logger::class, - $this->os->control(), - ); - } - - public function testPorts() - { - $this->assertInstanceOf( - Ports\Logger::class, - $this->os->ports(), - ); - } - - public function testSockets() - { - $this->assertInstanceOf( - Sockets\Logger::class, - $this->os->sockets(), - ); - } - - public function testRemote() - { - $this->assertInstanceOf( - Remote\Logger::class, - $this->os->remote(), - ); - } - - public function testProcess() - { - $this->assertInstanceOf( - CurrentProcess\Logger::class, - $this->os->process(), - ); - } - - public function testMap() - { - $result = $this->os->map(function($os) { - $this->assertSame($this->underlying, $os); - - return Unix::of(); - }); - - $this->assertInstanceOf(Logger::class, $result); - $this->assertNotSame($this->os, $result); - } -} diff --git a/tests/OperatingSystem/ResilientTest.php b/tests/OperatingSystem/ResilientTest.php index 8816d58..9dba327 100644 --- a/tests/OperatingSystem/ResilientTest.php +++ b/tests/OperatingSystem/ResilientTest.php @@ -17,7 +17,7 @@ use Innmind\Server\Status\Server as ServerStatus; use Innmind\Server\Control\Server as ServerControl; use Innmind\TimeContinuum\Clock; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class ResilientTest extends TestCase { diff --git a/tests/OperatingSystem/UnixTest.php b/tests/OperatingSystem/UnixTest.php index 1e6348f..f55e1e8 100644 --- a/tests/OperatingSystem/UnixTest.php +++ b/tests/OperatingSystem/UnixTest.php @@ -16,7 +16,7 @@ use Innmind\Server\Status\Server as ServerStatus; use Innmind\Server\Control\Server as ServerControl; use Innmind\TimeContinuum\Clock; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class UnixTest extends TestCase { diff --git a/tests/Ports/LoggerTest.php b/tests/Ports/LoggerTest.php deleted file mode 100644 index 90cd958..0000000 --- a/tests/Ports/LoggerTest.php +++ /dev/null @@ -1,85 +0,0 @@ -assertInstanceOf( - Ports::class, - Logger::psr( - $this->createMock(Ports::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testOpen() - { - $this - ->forAll( - Set\Elements::of( - Transport::tcp(), - Transport::ssl(), - Transport::tls(), - Transport::tlsv10(), - Transport::tlsv11(), - Transport::tlsv12(), - ), - Set\Elements::of( - IPv4::localhost(), - IPv6::localhost(), - ), - Set\Integers::above(0), - ) - ->then(function($transport, $ip, $port) { - $inner = $this->createMock(Ports::class); - $inner - ->expects($this->once()) - ->method('open') - ->with($transport, $ip, Port::of($port)) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real server */)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Opening new port at {address}', - $this->callback(static function($context) use ($transport, $ip, $port) { - return (bool) \preg_match('~^[a-z\.0-9]+://[a-f\.0-9\:]+:\d+$~', $context['address']) && - \strpos($context['address'], $transport->toString()) === 0 && - \strpos($context['address'], $ip->toString()) !== false && - \strpos($context['address'], (string) $port) !== false; - }), - ); - $ports = Logger::psr($inner, $logger); - - $this->assertSame($expected, $ports->open($transport, $ip, Port::of($port))); - }); - } -} diff --git a/tests/Ports/UnixTest.php b/tests/Ports/UnixTest.php index a9a1a27..e967b39 100644 --- a/tests/Ports/UnixTest.php +++ b/tests/Ports/UnixTest.php @@ -14,7 +14,7 @@ }; use Innmind\IP\IPv4; use Innmind\Url\Authority\Port; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class UnixTest extends TestCase { diff --git a/tests/Remote/GenericTest.php b/tests/Remote/GenericTest.php index 365c479..60429c4 100644 --- a/tests/Remote/GenericTest.php +++ b/tests/Remote/GenericTest.php @@ -12,7 +12,11 @@ use Innmind\Server\Control\{ Server, Servers, + Server\Processes, + Server\Volumes, Server\Command, + Server\Process\Pid, + Server\Signal, }; use Innmind\Url\{ Url, @@ -26,8 +30,10 @@ use Innmind\HttpTransport\Transport as HttpTransport; use Innmind\Immutable\Attempt; use Formal\AccessLayer\Connection; -use PHPUnit\Framework\TestCase; -use Innmind\BlackBox\PHPUnit\BlackBox; +use Innmind\BlackBox\{ + PHPUnit\BlackBox, + PHPUnit\Framework\TestCase, +}; use Fixtures\Innmind\Url\Url as FUrl; class GenericTest extends TestCase @@ -39,7 +45,7 @@ public function testInterface() $this->assertInstanceOf( Remote::class, Generic::of( - $this->createMock(Server::class), + $this->server(), Config::of(), ), ); @@ -48,44 +54,25 @@ public function testInterface() public function testSsh() { $remote = Generic::of( - $server = $this->createMock(Server::class), + $this->server("ssh '-p' '42' 'user@my-vps' 'ls'"), Config::of(), ); - $server - ->expects($this->once()) - ->method('processes') - ->willReturn($processes = $this->createMock(Server\Processes::class)); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "ssh '-p' '42' 'user@my-vps' 'ls'"; - })) - ->willReturn(Attempt::result(null /* hack to avoid creating real process */)); $remoteServer = $remote->ssh(Url::of('ssh://user@my-vps:42/')); $this->assertInstanceOf(Servers\Remote::class, $remoteServer); - $remoteServer->processes()->execute(Command::foreground('ls')); + $remoteServer + ->processes() + ->execute(Command::foreground('ls')) + ->unwrap(); } public function testSshWithoutPort() { $remote = Generic::of( - $server = $this->createMock(Server::class), + $this->server("ssh 'user@my-vps' 'ls'"), Config::of(), ); - $server - ->expects($this->once()) - ->method('processes') - ->willReturn($processes = $this->createMock(Server\Processes::class)); - $processes - ->expects($this->once()) - ->method('execute') - ->with($this->callback(static function($command): bool { - return $command->toString() === "ssh 'user@my-vps' 'ls'"; - })) - ->willReturn(Attempt::result(null /* hack to avoid creating real process */)); $remoteServer = $remote->ssh(Url::of('ssh://user@my-vps/')); @@ -96,7 +83,7 @@ public function testSshWithoutPort() public function testSocket() { $remote = Generic::of( - $this->createMock(Server::class), + $this->server(), Config::of(), ); $server = Factory::build() @@ -120,7 +107,7 @@ public function testSocket() public function testHttp() { $remote = Generic::of( - $this->createMock(Server::class), + $this->server(), Config::of(), ); @@ -130,13 +117,13 @@ public function testHttp() $this->assertSame($http, $remote->http()); } - public function testSql() + public function testSql(): BlackBox\Proof { - $this + return $this ->forAll(FUrl::any()) - ->then(function($server) { + ->prove(function($server) { $remote = Generic::of( - $this->createMock(Server::class), + $this->server(), Config::of(), ); @@ -145,4 +132,63 @@ public function testSql() $this->assertInstanceOf(Connection::class, $sql); }); } + + private function server(string ...$commands): Server + { + return new class($this->processes(), $this, $commands) implements Server { + private $inner; + + public function __construct( + private $processes, + private $test, + private $commands, + ) { + } + + public function processes(): Processes + { + return $this->inner ??= new class($this->processes, $this->test, $this->commands) implements Processes { + public function __construct( + private $processes, + private $test, + private $commands, + ) { + } + + public function execute(Command $command): Attempt + { + $expected = \array_shift($this->commands); + $this->test->assertNotNull($expected); + $this->test->assertSame( + $expected, + $command->toString(), + ); + + return $this->processes->execute(Command::foreground('echo')); + } + + public function kill(Pid $pid, Signal $signal): Attempt + { + } + }; + } + + public function volumes(): Volumes + { + } + + public function reboot(): Attempt + { + } + + public function shutdown(): Attempt + { + } + }; + } + + private function processes(): Processes + { + return Factory::build()->control()->processes(); + } } diff --git a/tests/Remote/LoggerTest.php b/tests/Remote/LoggerTest.php deleted file mode 100644 index 8499df0..0000000 --- a/tests/Remote/LoggerTest.php +++ /dev/null @@ -1,125 +0,0 @@ -assertInstanceOf( - Remote::class, - Logger::psr( - $this->createMock(Remote::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testSsh() - { - $this - ->forAll(FUrl::any()) - ->then(function($url) { - $inner = $this->createMock(Remote::class); - $inner - ->expects($this->once()) - ->method('ssh') - ->with($url); - $logger = $this->createMock(LoggerInterface::class); - $remote = Logger::psr($inner, $logger); - - $this->assertInstanceOf(Servers\Logger::class, $remote->ssh($url)); - }); - } - - public function testSocket() - { - $this - ->forAll( - Set\Elements::of( - Transport::tcp(), - Transport::ssl(), - Transport::tls(), - Transport::tlsv10(), - Transport::tlsv11(), - Transport::tlsv12(), - ), - Set\Elements::of( - // using fix set of authorities to show the log is not - // hardcoded but not using the authority Set as it can - // contain characters that messes up with preg_match - Url::of('foo://user:pwd@example:8080')->authority(), - Url::of('foo://127.0.0.1:2495')->authority(), - ), - ) - ->then(function($transport, $authority) { - $inner = $this->createMock(Remote::class); - $inner - ->expects($this->once()) - ->method('socket') - ->with($transport, $authority) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real client */)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Opening remote socket at {address}', - $this->callback(static function($context) use ($transport, $authority) { - return (bool) \preg_match('~^[a-z\.0-9]+://.+$~', $context['address']) && - \strpos($context['address'], $transport->toString()) === 0 && - \strpos($context['address'], $authority->toString()) !== false; - }), - ); - $remote = Logger::psr($inner, $logger); - - $this->assertSame($expected, $remote->socket($transport, $authority)); - }); - } - - public function testHttp() - { - $inner = $this->createMock(Remote::class); - $logger = $this->createMock(LoggerInterface::class); - $remote = Logger::psr($inner, $logger); - - $this->assertInstanceOf(LoggerTransport::class, $remote->http()); - } - - public function testSql() - { - $this - ->forAll(FUrl::any()) - ->then(function($server) { - $inner = $this->createMock(Remote::class); - $logger = $this->createMock(LoggerInterface::class); - $remote = Logger::psr($inner, $logger); - - $this->assertInstanceOf(Connection\Logger::class, $remote->sql($server)); - }); - } -} diff --git a/tests/Remote/ResilientTest.php b/tests/Remote/ResilientTest.php index d4cde94..1a76171 100644 --- a/tests/Remote/ResilientTest.php +++ b/tests/Remote/ResilientTest.php @@ -6,19 +6,16 @@ use Innmind\OperatingSystem\{ Remote\Resilient, Remote, - CurrentProcess, + Factory, }; use Innmind\HttpTransport\ExponentialBackoff; use Innmind\Server\Control\Server; -use Innmind\IO\Sockets\{ - Internet\Transport, - Clients\Client, -}; +use Innmind\IO\Sockets\Internet\Transport; use Innmind\Immutable\Attempt; use Formal\AccessLayer\Connection; -use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ PHPUnit\BlackBox, + PHPUnit\Framework\TestCase, Set, }; use Fixtures\Innmind\Url\{ @@ -30,41 +27,46 @@ class ResilientTest extends TestCase { use BlackBox; + private $os; + + public function setUp(): void + { + $this->os = Factory::build(); + } + public function testInterface() { $this->assertInstanceOf( Remote::class, Resilient::of( - $this->createMock(Remote::class), - $this->createMock(CurrentProcess::class), + $this->os->remote(), + $this->os->process(), ), ); } - public function testSsh() + public function testSsh(): BlackBox\Proof { - $this + return $this ->forAll(Url::any()) - ->then(function($url) { + ->prove(function($url) { $remote = Resilient::of( - $inner = $this->createMock(Remote::class), - $this->createMock(CurrentProcess::class), + $this->os->remote(), + $this->os->process(), ); - $inner - ->expects($this->once()) - ->method('ssh') - ->with($url) - ->willReturn($expected = $this->createMock(Server::class)); - $this->assertSame($expected, $remote->ssh($url)); + $this->assertInstanceOf( + Server::class, + $remote->ssh($url), + ); }); } - public function testSocket() + public function testSocket(): BlackBox\Proof { - $this + return $this ->forAll( - Set\Elements::of( + Set::of( Transport::tcp(), Transport::ssl(), Transport::tls(), @@ -73,39 +75,37 @@ public function testSocket() ), Authority::any(), ) - ->then(function($transport, $authority) { + ->prove(function($transport, $authority) { $remote = Resilient::of( - $inner = $this->createMock(Remote::class), - $this->createMock(CurrentProcess::class), + $this->os->remote(), + $this->os->process(), ); - $inner - ->expects($this->once()) - ->method('socket') - ->with($transport, $authority) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real client */)); - $this->assertSame($expected, $remote->socket($transport, $authority)); + $this->assertInstanceOf( + Attempt::class, + $remote->socket($transport, $authority), + ); }); } public function testHttp() { $remote = Resilient::of( - $this->createMock(Remote::class), - $this->createMock(CurrentProcess::class), + $this->os->remote(), + $this->os->process(), ); $this->assertInstanceOf(ExponentialBackoff::class, $remote->http()); } - public function testSql() + public function testSql(): BlackBox\Proof { - $this + return $this ->forAll(Url::any()) - ->then(function($server) { + ->prove(function($server) { $remote = Resilient::of( - $this->createMock(Remote::class), - $this->createMock(CurrentProcess::class), + $this->os->remote(), + $this->os->process(), ); $this->assertInstanceOf(Connection::class, $remote->sql($server)); diff --git a/tests/Sockets/LoggerTest.php b/tests/Sockets/LoggerTest.php deleted file mode 100644 index 1ab4607..0000000 --- a/tests/Sockets/LoggerTest.php +++ /dev/null @@ -1,98 +0,0 @@ -assertInstanceOf( - Sockets::class, - Logger::psr( - $this->createMock(Sockets::class), - $this->createMock(LoggerInterface::class), - ), - ); - } - - public function testOpen() - { - $address = Address::of(Path::of('/tmp/foo')); - $inner = $this->createMock(Sockets::class); - $inner - ->expects($this->once()) - ->method('open') - ->with($address) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real server */)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Opening socket at {address}', - ['address' => '/tmp/foo.sock'], - ); - $sockets = Logger::psr($inner, $logger); - - $this->assertSame($expected, $sockets->open($address)); - } - - public function testTakeOver() - { - $address = Address::of(Path::of('/tmp/foo')); - $inner = $this->createMock(Sockets::class); - $inner - ->expects($this->once()) - ->method('takeOver') - ->with($address) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real server */)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Taking over the socket at {address}', - ['address' => '/tmp/foo.sock'], - ); - $sockets = Logger::psr($inner, $logger); - - $this->assertSame($expected, $sockets->takeOver($address)); - } - - public function testConnectTo() - { - $address = Address::of(Path::of('/tmp/foo')); - $inner = $this->createMock(Sockets::class); - $inner - ->expects($this->once()) - ->method('connectTo') - ->with($address) - ->willReturn($expected = Attempt::result(null /* hack to avoid creating real client */)); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with( - 'Connecting to socket at {address}', - ['address' => '/tmp/foo.sock'], - ); - $sockets = Logger::psr($inner, $logger); - - $this->assertSame($expected, $sockets->connectTo($address)); - } -} diff --git a/tests/Sockets/UnixTest.php b/tests/Sockets/UnixTest.php index 5c09655..6cc61d2 100644 --- a/tests/Sockets/UnixTest.php +++ b/tests/Sockets/UnixTest.php @@ -14,7 +14,7 @@ Clients\Client, }; use Innmind\Url\Path; -use PHPUnit\Framework\TestCase; +use Innmind\BlackBox\PHPUnit\Framework\TestCase; class UnixTest extends TestCase {