118 lines
4.7 KiB
PHP
118 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MageSail\Magesail\Test\Unit\Model;
|
|
|
|
use MageSail\Magesail\Model\TunnelProcessPaths;
|
|
use MageSail\Magesail\Model\TunnelRegistry;
|
|
use MageSail\Magesail\Model\TunnelStatus;
|
|
use MageSail\Magesail\Model\TunnelStoreProvisioner;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\Shell;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class TunnelStatusTest extends TestCase
|
|
{
|
|
private string $tmpDir = '';
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->tmpDir = sys_get_temp_dir() . '/magesail_ts_' . uniqid('', true);
|
|
mkdir($this->tmpDir, 0777, true);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
foreach (glob($this->tmpDir . '/*') ?: [] as $f) {
|
|
if (is_file($f)) {
|
|
@unlink($f);
|
|
}
|
|
}
|
|
@rmdir($this->tmpDir);
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function testGetStatusReturnsNotRunningWhenPidFileMissing(): void
|
|
{
|
|
$shell = $this->createMock(Shell::class);
|
|
$shell->expects(self::never())->method('execute');
|
|
$scope = $this->createMock(ScopeConfigInterface::class);
|
|
$provisioner = $this->createMock(TunnelStoreProvisioner::class);
|
|
$registry = $this->createMock(TunnelRegistry::class);
|
|
$paths = $this->createMock(TunnelProcessPaths::class);
|
|
$paths->method('getPidFilePath')->willReturn($this->tmpDir . '/n.pid');
|
|
$paths->method('getKeyFilePath')->willReturn($this->tmpDir . '/n.key');
|
|
|
|
$status = new TunnelStatus($shell, $scope, $provisioner, $registry, $paths);
|
|
$st = $status->getStatus('any');
|
|
self::assertFalse($st['running']);
|
|
self::assertNull($st['pid']);
|
|
self::assertNull($st['key']);
|
|
}
|
|
|
|
public function testGetStatusRunningWhenProcessAlive(): void
|
|
{
|
|
$pidFile = $this->tmpDir . '/t.pid';
|
|
$keyFile = $this->tmpDir . '/t.key';
|
|
file_put_contents($pidFile, (string) getmypid());
|
|
file_put_contents($keyFile, 'hs://key');
|
|
|
|
$shell = $this->createMock(Shell::class);
|
|
$shell->method('execute')->willReturn('');
|
|
$scope = $this->createMock(ScopeConfigInterface::class);
|
|
$provisioner = $this->createMock(TunnelStoreProvisioner::class);
|
|
$registry = $this->createMock(TunnelRegistry::class);
|
|
$paths = $this->createMock(TunnelProcessPaths::class);
|
|
$paths->method('getPidFilePath')->willReturn($pidFile);
|
|
$paths->method('getKeyFilePath')->willReturn($keyFile);
|
|
|
|
$status = new TunnelStatus($shell, $scope, $provisioner, $registry, $paths);
|
|
$st = $status->getStatus('t1');
|
|
self::assertTrue($st['running']);
|
|
self::assertSame(getmypid(), $st['pid']);
|
|
self::assertSame('hs://key', $st['key']);
|
|
}
|
|
|
|
public function testGetStatusClearsStalePidWhenProcessDeadAndAutoRestartOff(): void
|
|
{
|
|
$pidFile = $this->tmpDir . '/dead.pid';
|
|
file_put_contents($pidFile, '999999');
|
|
|
|
$shell = $this->createMock(Shell::class);
|
|
$shell->method('execute')->willThrowException(new \RuntimeException('not running'));
|
|
$scope = $this->createMock(ScopeConfigInterface::class);
|
|
$scope->method('getValue')->willReturnCallback(static function ($path) {
|
|
return $path === 'magesail/settings/auto_restart' ? false : null;
|
|
});
|
|
$provisioner = $this->createMock(TunnelStoreProvisioner::class);
|
|
$provisioner->expects(self::once())->method('teardownAfterStaleProcess')->with('tid');
|
|
$registry = $this->createMock(TunnelRegistry::class);
|
|
$paths = $this->createMock(TunnelProcessPaths::class);
|
|
$paths->method('getPidFilePath')->willReturn($pidFile);
|
|
$paths->method('getKeyFilePath')->willReturn($this->tmpDir . '/dead.key');
|
|
|
|
$status = new TunnelStatus($shell, $scope, $provisioner, $registry, $paths);
|
|
$st = $status->getStatus('tid');
|
|
self::assertFalse($st['running']);
|
|
self::assertFileDoesNotExist($pidFile);
|
|
}
|
|
|
|
public function testIsProcessAliveFalseForNonPositivePid(): void
|
|
{
|
|
$shell = $this->createMock(Shell::class);
|
|
$shell->expects(self::never())->method('execute');
|
|
$scope = $this->createMock(ScopeConfigInterface::class);
|
|
$provisioner = $this->createMock(TunnelStoreProvisioner::class);
|
|
$registry = $this->createMock(TunnelRegistry::class);
|
|
$paths = $this->createMock(TunnelProcessPaths::class);
|
|
$paths->method('getPidFilePath')->willReturn($this->tmpDir . '/x.pid');
|
|
$paths->method('getKeyFilePath')->willReturn($this->tmpDir . '/x.key');
|
|
|
|
$status = new TunnelStatus($shell, $scope, $provisioner, $registry, $paths);
|
|
self::assertFalse($status->isProcessAlive(0));
|
|
self::assertFalse($status->isProcessAlive(-1));
|
|
}
|
|
}
|