Skip to content

Commit d43bec5

Browse files
author
Oleksandr Gorkun
committed
MAGETWO-81431: Static content deployment failed with compact strategy and several jobs
1 parent e1770f8 commit d43bec5

File tree

1 file changed

+258
-17
lines changed

1 file changed

+258
-17
lines changed

dev/tests/integration/testsuite/Magento/Framework/ParallelProcess/ProcessManagerTest.php

Lines changed: 258 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,288 @@
66

77
namespace Magento\Framework\ParallelProcess;
88

9+
use Magento\Framework\App\Cache;
910
use Magento\Framework\ParallelProcess\Fork\PcntlForkManager;
1011
use Magento\Framework\ParallelProcess\Process\Data;
1112
use Magento\Framework\ParallelProcess\Process\ExitedWithErrorException;
1213
use Magento\Framework\ParallelProcess\Process\RunnerInterface;
1314
use PHPUnit\Framework\TestCase;
15+
use Magento\TestFramework\Helper\Bootstrap;
1416

1517
class ProcessManagerTest extends TestCase
1618
{
17-
public function testRun()
19+
/**
20+
* @var Cache
21+
*/
22+
private $cache;
23+
24+
/**
25+
* @var \ArrayObject
26+
*/
27+
private $createdCacheIds;
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected function setUp()
33+
{
34+
parent::setUp();
35+
$this->cache = Bootstrap::getObjectManager()->get(Cache::class);
36+
$this->createdCacheIds = new \ArrayObject();
37+
}
38+
39+
/**
40+
* @inheritDoc
41+
*/
42+
protected function tearDown()
1843
{
19-
$runner = new class implements RunnerInterface {
44+
parent::tearDown();
45+
foreach ($this->createdCacheIds as $cacheId) {
46+
$this->cache->remove($cacheId);
47+
}
48+
}
49+
50+
/**
51+
* @param int|null $limit Max number of processes.
52+
* @param array $processes
53+
*
54+
* @dataProvider getSuccessfulProcesses
55+
*/
56+
public function testRun(array $processes, int $limit = null)
57+
{
58+
$cache = $this->cache;
59+
$createCacheId = function (string $id): string
60+
{
61+
return 'magento2_parallel_process_test_id_' . $id;
62+
};
63+
foreach ($processes as $process) {
64+
$this->createdCacheIds[] = $createCacheId($process['id']);
65+
}
66+
$runner = new class ($cache, $createCacheId) implements RunnerInterface {
67+
/**
68+
* @var Cache
69+
*/
70+
private $cache;
71+
72+
/**
73+
* @var callable
74+
*/
75+
private $createCacheId;
76+
77+
public function __construct($cache, $createId)
78+
{
79+
$this->cache = $cache;
80+
$this->createCacheId = $createId;
81+
}
82+
2083
/**
2184
* @inheritDoc
2285
*/
2386
public function run(array $data)
2487
{
25-
usleep(rand (50, 200));
26-
echo PHP_EOL.$data['id'].PHP_EOL;
88+
usleep(rand(32, 256));
89+
90+
foreach ($data['depends'] as $dependsOnId) {
91+
$dependencyResult = $this->cache
92+
->load(($this->createCacheId)($dependsOnId));
93+
if ($dependencyResult !== 'success') {
94+
throw new \RuntimeException(
95+
'Provider process didn\'t successfully finish'
96+
);
97+
}
98+
}
99+
$id = ($this->createCacheId)($data['id']);
100+
$this->cache->save('success', $id);
27101
}
28102
};
29103
$fork = new PcntlForkManager();
30-
$successful = [];
31-
$failed = [];
32-
for ($i = 1; $i <= 10; $i++) {
33-
if (rand(0,1)) {
34-
$dependsOn = ['id'.rand(1,10)];
35-
if ($dependsOn[0] === 'id'.$i) {
36-
$dependsOn = [];
104+
/** @var Data[] $data */
105+
$data = [];
106+
foreach ($processes as $process) {
107+
$data[] = new Data($process['id'], $process, $process['depends']);
108+
}
109+
$manager = new ProcessManager($runner, $fork, $data, $limit);
110+
111+
$manager->run();
112+
}
113+
114+
/**
115+
* @return array
116+
*/
117+
public function getSuccessfulProcesses()
118+
{
119+
$processes = [
120+
['id' => 'id1', 'depends' => []],
121+
['id' => 'id2', 'depends' => []],
122+
['id' => 'id3', 'depends' => []],
123+
['id' => 'id4', 'depends' => ['id1']],
124+
['id' => 'id5', 'depends' => ['id1', 'id2']],
125+
['id' => 'id6', 'depends' => ['id3']],
126+
['id' => 'id7', 'depends' => ['id5']],
127+
['id' => 'id8', 'depends' => ['id1']],
128+
['id' => 'id9', 'depends' => ['id1']],
129+
['id' => 'id10', 'depends' => ['id1']],
130+
];
131+
132+
return [
133+
[
134+
'processes' => $processes,
135+
'limit' => 5
136+
],
137+
[
138+
'processes' => $processes,
139+
'limit' => 15
140+
],
141+
[
142+
'processes' => $processes,
143+
'limit' => 1
144+
],
145+
[
146+
'processes' => $processes,
147+
'limit' => null
148+
],
149+
];
150+
}
151+
152+
/**
153+
* @param int|null $limit Max number of processes.
154+
* @param array $processes
155+
* @param string[] $wasNotLaunched
156+
* @param string[] $finished
157+
*
158+
* @dataProvider getFailingProcesses
159+
*/
160+
public function testFailures(
161+
array $processes,
162+
array $wasNotLaunched,
163+
array $finished,
164+
int $limit =null
165+
) {
166+
$cache = $this->cache;
167+
$createCacheId = function (string $id): string
168+
{
169+
return 'magento2_parallel_process_test_id_' . $id;
170+
};
171+
foreach ($processes as $process) {
172+
$this->createdCacheIds[] = $createCacheId($process['id']);
173+
}
174+
$runner = new class ($cache, $createCacheId) implements RunnerInterface {
175+
/**
176+
* @var Cache
177+
*/
178+
private $cache;
179+
180+
/**
181+
* @var callable
182+
*/
183+
private $createCacheId;
184+
185+
public function __construct($cache, $createId)
186+
{
187+
$this->cache = $cache;
188+
$this->createCacheId = $createId;
189+
}
190+
191+
/**
192+
* @inheritDoc
193+
*/
194+
public function run(array $data)
195+
{
196+
usleep(rand(32, 256));
197+
198+
if ($data['depends']) {
199+
foreach ($data['depends'] as $dependsOnId) {
200+
if ($this->cache->load(($this->createCacheId)($dependsOnId)) !== 'success') {
201+
$id = ($this->createCacheId)($data['id']);
202+
$this->cache->save('failure', $id);
203+
throw new \RuntimeException();
204+
}
205+
}
206+
} else {
207+
if (!isset($data['success'])) {
208+
throw new \RuntimeException('Failed');
209+
} else {
210+
$id = ($this->createCacheId)($data['id']);
211+
$this->cache->save('success', $id);
212+
}
37213
}
38-
} else {
39-
$dependsOn = [];
40214
}
41-
$successful[] = new Data('id' . $i, ['id'=>'id'.$i], $dependsOn);
215+
};
216+
$fork = new PcntlForkManager();
217+
/** @var Data[] $data */
218+
$data = [];
219+
foreach ($processes as $process) {
220+
$data[] = new Data($process['id'], $process, $process['depends']);
42221
}
43-
$failed[] = new Data('idFailed', []);
222+
$manager = new ProcessManager($runner, $fork, $data, $limit);
44223

45-
$manager = new ProcessManager($runner, $fork, array_merge($successful, $failed), 8);
224+
/** @var string[] $actuallyFailed */
225+
$actuallyFailed = [];
46226
try {
47227
$manager->run();
48228
} catch (ExitedWithErrorException $exception) {
49-
$this->assertEquals($failed, $exception->getFailedProcesses());
229+
$actuallyFailed = array_map(
230+
function (Data $data) {
231+
return $data->getId();
232+
},
233+
$exception->getFailedProcesses()
234+
);
235+
}
236+
foreach ($processes as $process) {
237+
if (!isset($process['success'])) {
238+
$this->assertContains($process['id'], $actuallyFailed);
239+
}
240+
}
241+
foreach ($wasNotLaunched as $id) {
242+
$this->assertFalse($this->cache->load($createCacheId($id)));
50243
}
244+
foreach ($finished as $id) {
245+
$this->assertNotContains($id, $actuallyFailed);
246+
$this->assertNotEmpty($this->cache->load($createCacheId($id)));
247+
}
248+
}
249+
250+
/**
251+
* @return array
252+
*/
253+
public function getFailingProcesses()
254+
{
255+
$processes = [];
256+
$processes[] = ['id' => 'id1', 'depends' => []];
257+
$processes[] = ['id' => 'id2', 'depends' => []];
258+
$processes[] = ['id' => 'id3', 'depends' => []];
259+
$processes[] = ['id' => 'id4', 'depends' => ['id1']];
260+
$processes[] = ['id' => 'id5', 'depends' => ['id1', 'id2']];
261+
$processes[] = ['id' => 'id6', 'depends' => ['id3']];
262+
$processes[] = ['id' => 'id7', 'depends' => [], 'success' => true];
263+
$wasNotLaunched = ['id4', 'id5', 'id6'];
264+
$finished = ['id7'];
265+
266+
return [
267+
[
268+
'processes' => $processes,
269+
'wasNotLaunched' => $wasNotLaunched,
270+
'finished' => $finished,
271+
'limit' => 5,
272+
],
273+
[
274+
'processes' => $processes,
275+
'wasNotLaunched' => $wasNotLaunched,
276+
'finished' => $finished,
277+
'limit' => 15,
278+
],
279+
[
280+
'processes' => $processes,
281+
'wasNotLaunched' => $wasNotLaunched,
282+
'finished' => $finished,
283+
'limit' => 1,
284+
],
285+
[
286+
'processes' => $processes,
287+
'wasNotLaunched' => $wasNotLaunched,
288+
'finished' => $finished,
289+
'limit' => null,
290+
],
291+
];
51292
}
52293
}

0 commit comments

Comments
 (0)