tmpDir = sys_get_temp_dir() . '/magesail_tsp_' . 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 testTeardownServiceTunnelDeletesRegistryAndSkipsStoreAndNginx(): void { $tunnelId = 'svc-t1'; $storeManager = $this->createMock(StoreManagerInterface::class); $storeFactory = $this->createMock(StoreFactory::class); $storeFactory->expects(self::never())->method('create'); $storeResource = $this->createMock(StoreResource::class); $storeResource->expects(self::never())->method('load'); $storeResource->expects(self::never())->method('delete'); $storeRepository = $this->createMock(StoreRepositoryInterface::class); $storeRepository->expects(self::never())->method('clean'); $configWriter = $this->createMock(WriterInterface::class); $configWriter->expects(self::never())->method('delete'); $configWriter->expects(self::never())->method('save'); $typeList = $this->createMock(TypeListInterface::class); $typeList->expects(self::exactly(2))->method('cleanType')->willReturnCallback( static function (string $type) { self::assertContains($type, ['config', 'full_page'], 'flushConfigCache cleans config + fpc'); } ); $reinitableConfig = $this->createMock(ReinitableConfigInterface::class); $reinitableConfig->expects(self::once())->method('reinit'); $tunnelRegistry = $this->createMock(TunnelRegistry::class); $tunnelRegistry->method('getById')->with($tunnelId)->willReturn([ 'id' => $tunnelId, 'tunnel_type' => 'service', 'service_key' => 'mysql_default', 'local_port' => 3306, ]); $tunnelRegistry->expects(self::once())->method('deleteTunnel')->with($tunnelId); $logger = $this->createMock(LoggerInterface::class); $nginxMapManager = $this->createMock(NginxGlobalMapManager::class); $nginxMapManager->expects(self::never())->method('removeTunnelMapping'); $nginxMapManager->expects(self::never())->method('addTunnelMapping'); $scopeConfig = $this->createMock(ScopeConfigInterface::class); $resource = $this->createMock(ResourceConnection::class); $resource->expects(self::never())->method('getConnection'); $pidPath = $this->tmpDir . '/' . $tunnelId . '.pid'; $keyPath = $this->tmpDir . '/' . $tunnelId . '.key'; file_put_contents($pidPath, '12345'); file_put_contents($keyPath, 'hs://x'); $tunnelProcessPaths = $this->createMock(TunnelProcessPaths::class); $tunnelProcessPaths->method('getPidFilePath')->with($tunnelId)->willReturn($pidPath); $tunnelProcessPaths->method('getKeyFilePath')->with($tunnelId)->willReturn($keyPath); $provisioner = new TunnelStoreProvisioner( $storeManager, $storeFactory, $storeResource, $storeRepository, $configWriter, $typeList, $reinitableConfig, $tunnelRegistry, $logger, $nginxMapManager, $scopeConfig, $tunnelProcessPaths, $resource ); $provisioner->teardownTunnel($tunnelId); self::assertFileDoesNotExist($pidPath); self::assertFileDoesNotExist($keyPath); } }