Skip to content

Commit 60269f6

Browse files
committed
test(install): cover async process pid handling
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 11c2165 commit 60269f6

1 file changed

Lines changed: 150 additions & 0 deletions

File tree

tests/php/Unit/Service/InstallServiceTest.php

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use OCA\Libresign\Service\CaIdentifierService;
1414
use OCA\Libresign\Service\Install\InstallService;
1515
use OCA\Libresign\Service\Install\SignSetupService;
16+
use OCA\Libresign\Service\Process\ProcessManager;
17+
use OCA\Libresign\Vendor\Symfony\Component\Process\Process;
1618
use OCP\Files\AppData\IAppDataFactory;
1719
use OCP\Http\Client\IClientService;
1820
use OCP\IAppConfig;
@@ -32,6 +34,7 @@ final class InstallServiceTest extends \OCA\Libresign\Tests\Unit\TestCase {
3234
private SignSetupService&MockObject $ignSetupService;
3335
private IAppDataFactory&MockObject $appDataFactory;
3436
private CaIdentifierService&MockObject $caIdentifierService;
37+
private ProcessManager&MockObject $processManager;
3538

3639
public function setUp(): void {
3740
parent::setUp();
@@ -47,6 +50,7 @@ protected function getInstallService(): InstallService {
4750
$this->ignSetupService = $this->createMock(SignSetupService::class);
4851
$this->appDataFactory = $this->createMock(IAppDataFactory::class);
4952
$this->caIdentifierService = $this->createMock(CaIdentifierService::class);
53+
$this->processManager = $this->createMock(ProcessManager::class);
5054
return new InstallService(
5155
$this->cacheFactory,
5256
$this->clientService,
@@ -57,6 +61,7 @@ protected function getInstallService(): InstallService {
5761
$this->ignSetupService,
5862
$this->appDataFactory,
5963
$this->caIdentifierService,
64+
$this->processManager,
6065
);
6166
}
6267

@@ -168,4 +173,149 @@ public static function providerGetFolder(): array {
168173
['x86_64', 'test/folder1/folder2', 'folder2'],
169174
];
170175
}
176+
177+
public function testGetInstallPidReadsMatchingPidFromRegistry(): void {
178+
$installService = $this->getInstallService();
179+
$installService->setResource('cfssl');
180+
181+
$this->processManager->expects($this->once())
182+
->method('findRunningPid')
183+
->with('install', $this->callback('is_callable'))
184+
->willReturnCallback(function (string $_source, callable $filter): int {
185+
return $filter([
186+
'pid' => 123,
187+
'context' => ['resource' => 'cfssl'],
188+
'createdAt' => 123,
189+
]) ? 123 : 0;
190+
});
191+
192+
$actual = self::invokePrivate($installService, 'getInstallPid');
193+
194+
$this->assertSame(123, $actual);
195+
}
196+
197+
public function testGetInstallPidValidatesRequestedPidAgainstResource(): void {
198+
$installService = $this->getInstallService();
199+
$installService->setResource('cfssl');
200+
201+
$this->processManager->expects($this->once())
202+
->method('findRunningPid')
203+
->with('install', $this->callback('is_callable'))
204+
->willReturn(0);
205+
206+
$this->processManager->expects($this->once())
207+
->method('unregister')
208+
->with('install', 123);
209+
210+
$actual = self::invokePrivate($installService, 'getInstallPid', [123]);
211+
212+
$this->assertSame(0, $actual);
213+
}
214+
215+
public function testGetInstallPidKeepsRequestedPidWhenResourceMatches(): void {
216+
$installService = $this->getInstallService();
217+
$installService->setResource('cfssl');
218+
219+
$this->processManager->expects($this->once())
220+
->method('findRunningPid')
221+
->with('install', $this->callback('is_callable'))
222+
->willReturnCallback(function (string $_source, callable $filter): int {
223+
return $filter([
224+
'pid' => 321,
225+
'context' => ['resource' => 'cfssl'],
226+
'createdAt' => 123,
227+
]) ? 321 : 0;
228+
});
229+
230+
$this->processManager->expects($this->never())
231+
->method('unregister');
232+
233+
$actual = self::invokePrivate($installService, 'getInstallPid', [321]);
234+
235+
$this->assertSame(321, $actual);
236+
}
237+
238+
public function testRunAsyncRegistersPidWhenProcessStarts(): void {
239+
$process = $this->createMock(Process::class);
240+
$process->expects($this->once())
241+
->method('setOptions')
242+
->with(['create_new_console' => true]);
243+
$process->expects($this->once())
244+
->method('setTimeout')
245+
->with(null);
246+
$process->expects($this->once())
247+
->method('start');
248+
$process->expects($this->once())
249+
->method('getPid')
250+
->willReturn(321);
251+
252+
$installService = $this->getInstallServiceWithProcess($process);
253+
$installService->setResource('cfssl');
254+
255+
$this->processManager->expects($this->once())
256+
->method('register')
257+
->with('install', 321, ['resource' => 'cfssl']);
258+
259+
self::invokePrivate($installService, 'runAsync');
260+
}
261+
262+
public function testRunAsyncLogsErrorWhenPidIsMissing(): void {
263+
$process = $this->createMock(Process::class);
264+
$process->expects($this->once())
265+
->method('setOptions')
266+
->with(['create_new_console' => true]);
267+
$process->expects($this->once())
268+
->method('setTimeout')
269+
->with(null);
270+
$process->expects($this->once())
271+
->method('start');
272+
$process->expects($this->once())
273+
->method('getPid')
274+
->willReturn(null);
275+
276+
$installService = $this->getInstallServiceWithProcess($process);
277+
$installService->setResource('cfssl');
278+
279+
$this->processManager->expects($this->never())
280+
->method('register');
281+
$this->logger->expects($this->once())
282+
->method('error')
283+
->with($this->stringContains('Error to get PID of background install proccess'));
284+
285+
self::invokePrivate($installService, 'runAsync');
286+
}
287+
288+
private function getInstallServiceWithProcess(Process $process): InstallService&MockObject {
289+
$this->cacheFactory = $this->createMock(ICacheFactory::class);
290+
$this->clientService = $this->createMock(IClientService::class);
291+
$this->certificateEngineFactory = $this->createMock(CertificateEngineFactory::class);
292+
$this->config = $this->createMock(IConfig::class);
293+
$this->appConfig = $this->createMock(IAppConfig::class);
294+
$this->logger = $this->createMock(LoggerInterface::class);
295+
$this->ignSetupService = $this->createMock(SignSetupService::class);
296+
$this->appDataFactory = $this->createMock(IAppDataFactory::class);
297+
$this->caIdentifierService = $this->createMock(CaIdentifierService::class);
298+
$this->processManager = $this->createMock(ProcessManager::class);
299+
300+
$installService = $this->getMockBuilder(InstallService::class)
301+
->setConstructorArgs([
302+
$this->cacheFactory,
303+
$this->clientService,
304+
$this->certificateEngineFactory,
305+
$this->config,
306+
$this->appConfig,
307+
$this->logger,
308+
$this->ignSetupService,
309+
$this->appDataFactory,
310+
$this->caIdentifierService,
311+
$this->processManager,
312+
])
313+
->onlyMethods(['createProcess'])
314+
->getMock();
315+
316+
$installService->method('createProcess')
317+
->willReturn($process);
318+
319+
return $installService;
320+
}
171321
}

0 commit comments

Comments
 (0)