ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
MigratedLanguageFileSyncLockTestCase.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
24use PHPUnit\Framework\TestCase;
25
30abstract class MigratedLanguageFileSyncLockTestCase extends TestCase
31{
33
34 protected const string MODULE = 'stest';
35
36 protected string $client_data_dir;
37
39
41
42 protected function setUp(): void
43 {
44 // never the build of the installation, see MigratedPoFixture::resetRuntime()
47
48 if (!defined('ILIAS_ABSOLUTE_PATH')) {
49 define('ILIAS_ABSOLUTE_PATH', realpath(__DIR__ . '/../../../../../'));
50 }
51
52 $this->client_data_dir = sys_get_temp_dir() . '/ilias_mlfs_lock_test_' . bin2hex(random_bytes(4));
53 mkdir($this->client_data_dir, 0775, true);
54 $this->directory = MigratedPoFixture::directory(self::MODULE, 'x/');
55 $this->manager = new LanguageFileDirectoryManager(new CustomizingLanguageFileDirectory(), $this->directory);
56 }
57
58 protected function tearDown(): void
59 {
60 MigratedPoFixture::removeDirectory($this->client_data_dir);
61
63 }
64
65 protected function lockFile(): string
66 {
67 return MigratedPoFixture::overlayLock(MigratedPoFixture::overlayBase($this->client_data_dir, $this->directory, 'de'));
68 }
69
74 protected function seedLockDirectory(): void
75 {
76 mkdir(dirname($this->lockFile()), 0775, true);
77 }
78
85 protected function runPhpWithTimeout(string $code, float $timeout_seconds): array
86 {
87 $started = ChildPhp::open(['-r', $code]);
88 if ($started === null) {
89 $this->fail('Could not start the child PHP process.');
90 }
91 [$process, $pipes] = $started;
92 stream_set_blocking($pipes[1], false);
93 stream_set_blocking($pipes[2], false);
94
95 $deadline = microtime(true) + $timeout_seconds;
96 $output = '';
97 do {
98 $output .= (string) stream_get_contents($pipes[1]);
99 $output .= (string) stream_get_contents($pipes[2]);
100 $status = proc_get_status($process);
101 if (!$status['running']) {
102 fclose($pipes[1]);
103 fclose($pipes[2]);
104 proc_close($process);
105
106 return ['finished' => true, 'exit_code' => $status['exitcode'], 'output' => $output];
107 }
108 usleep(20_000);
109 } while (microtime(true) < $deadline);
110
111 proc_terminate($process, 9);
112 usleep(100_000);
113 $output .= (string) stream_get_contents($pipes[1]);
114 $output .= (string) stream_get_contents($pipes[2]);
115 fclose($pipes[1]);
116 fclose($pipes[2]);
117 proc_close($process);
118
119 return ['finished' => false, 'exit_code' => null, 'output' => $output];
120 }
121}
trait RestoresProcessState
Whatever a test does to the process (locale, LANGUAGE/LC_*, LOCPATH, the static state of the runtime ...
static open(array $arguments, ?string $working_directory=null)
Definition: ChildPhp.php:43
Fixture of the MigratedLanguageFileSyncLock*Test classes: a throwaway client data directory and the h...
runPhpWithTimeout(string $code, float $timeout_seconds)
Runs $code in a child PHP process and kills it after $timeout_seconds, so a regression that deadlocks...
seedLockDirectory()
Forces withOverlayLock() to take a real lock without needing a shipped .po: the overlay directory alr...
static directory(string $prefix, string $path, bool $local=false)
static removeDirectory(string $directory)
static overlayLock(string $base_path)
static overlayBase(string $client_data_dir, LanguageFileDirectory $directory, string $lang_key)
The overlay of $directory's module for $lang_key without the .po extension.
static resetRuntime(?string $artifact_directory=null)
Forgets the static state of the runtime read path and points build and runtime at $artifact_directory...
A directory of language files with a path and a prefix for them.