Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ff379ef

Browse filesBrowse files
paul-mnicolas-grekas
authored andcommitted
[Bridge\PhpUnit] Handle deprecations triggered in separate processes
1 parent 788eb4f commit ff379ef
Copy full SHA for ff379ef

File tree

4 files changed

+86
-14
lines changed
Filter options

4 files changed

+86
-14
lines changed

‎src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,20 @@ public static function register($mode = 0)
238238
}
239239
}
240240

241+
public static function collectDeprecations($outputFile)
242+
{
243+
$deprecations = array();
244+
$previousErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, &$previousErrorHandler) {
245+
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
246+
return $previousErrorHandler ? $previousErrorHandler($type, $msg, $file, $line, $context) : false;
247+
}
248+
$deprecations[] = array(error_reporting(), $msg);
249+
});
250+
register_shutdown_function(function () use ($outputFile, &$deprecations) {
251+
file_put_contents($outputFile, serialize($deprecations));
252+
});
253+
}
254+
241255
private static function hasColorSupport()
242256
{
243257
if ('\\' === DIRECTORY_SEPARATOR) {

‎src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php
+45-14Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class SymfonyTestsListenerTrait
3939
private $testsWithWarnings;
4040
private $reportUselessTests;
4141
private $error;
42+
private $runsInSeparateProcess = false;
4243

4344
/**
4445
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive)
@@ -183,6 +184,12 @@ public function startTest($test)
183184
$this->reportUselessTests = $test->getTestResultObject()->isStrictAboutTestsThatDoNotTestAnything();
184185
}
185186

187+
// This event is triggered before the test is re-run in isolation
188+
if ($this->willBeIsolated($test)) {
189+
$this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec');
190+
putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$this->runsInSeparateProcess);
191+
}
192+
186193
if (class_exists('PHPUnit_Util_Blacklist', false)) {
187194
$Test = 'PHPUnit_Util_Test';
188195
$AssertionFailedError = 'PHPUnit_Framework_AssertionFailedError';
@@ -192,12 +199,14 @@ public function startTest($test)
192199
}
193200
$groups = $Test::getGroups(get_class($test), $test->getName(false));
194201

195-
if (in_array('time-sensitive', $groups, true)) {
196-
ClockMock::register(get_class($test));
197-
ClockMock::withClockMock(true);
198-
}
199-
if (in_array('dns-sensitive', $groups, true)) {
200-
DnsMock::register(get_class($test));
202+
if (!$this->runsInSeparateProcess) {
203+
if (in_array('time-sensitive', $groups, true)) {
204+
ClockMock::register(get_class($test));
205+
ClockMock::withClockMock(true);
206+
}
207+
if (in_array('dns-sensitive', $groups, true)) {
208+
DnsMock::register(get_class($test));
209+
}
201210
}
202211

203212
$annotations = $Test::parseTestMethodAnnotations(get_class($test), $test->getName(false));
@@ -245,15 +254,20 @@ public function endTest($test, $time)
245254
$this->reportUselessTests = null;
246255
}
247256

248-
$errored = false;
257+
if ($errored = null !== $this->error) {
258+
$test->getTestResultObject()->addError($test, $this->error, 0);
259+
$this->error = null;
260+
}
249261

250-
if (null !== $this->error) {
251-
if ($BaseTestRunner::STATUS_PASSED === $test->getStatus()) {
252-
$test->getTestResultObject()->addError($test, $this->error, 0);
253-
$errored = true;
262+
if ($this->runsInSeparateProcess) {
263+
foreach (unserialize(file_get_contents($this->runsInSeparateProcess)) as $deprecation) {
264+
if ($deprecation[0]) {
265+
trigger_error($deprecation[1], E_USER_DEPRECATED);
266+
} else {
267+
@trigger_error($deprecation[1], E_USER_DEPRECATED);
268+
}
254269
}
255-
256-
$this->error = null;
270+
$this->runsInSeparateProcess = false;
257271
}
258272

259273
if ($this->expectedDeprecations) {
@@ -277,7 +291,7 @@ public function endTest($test, $time)
277291
$this->expectedDeprecations = $this->gatheredDeprecations = array();
278292
$this->previousErrorHandler = null;
279293
}
280-
if (-2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) {
294+
if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) {
281295
if (in_array('time-sensitive', $groups, true)) {
282296
ClockMock::withClockMock(false);
283297
}
@@ -315,4 +329,21 @@ public function handleError($type, $msg, $file, $line, $context = array())
315329
}
316330
$this->gatheredDeprecations[] = $msg;
317331
}
332+
333+
/**
334+
* @param Test $test
335+
*
336+
* @return bool
337+
*/
338+
private function willBeIsolated($test)
339+
{
340+
if ($test->isInIsolation()) {
341+
return false;
342+
}
343+
344+
$r = new \ReflectionProperty($test, 'runTestInSeparateProcess');
345+
$r->setAccessible(true);
346+
347+
return $r->getValue($test);
348+
}
318349
}
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\PhpUnit\Tests;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
/**
8+
* Don't remove this test case, it tests the legacy group.
9+
*
10+
* @group legacy
11+
*
12+
* @runTestsInSeparateProcesses
13+
*/
14+
class ProcessIsolationTest extends TestCase
15+
{
16+
/**
17+
* @expectedDeprecation Test abc
18+
*/
19+
public function testIsolation()
20+
{
21+
@trigger_error('Test abc', E_USER_DEPRECATED);
22+
}
23+
}

‎src/Symfony/Bridge/PhpUnit/bootstrap.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/PhpUnit/bootstrap.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
// Detect if we're loaded by an actual run of phpunit
1616
if (!defined('PHPUNIT_COMPOSER_INSTALL') && !class_exists('PHPUnit_TextUI_Command', false) && !class_exists('PHPUnit\TextUI\Command', false)) {
17+
if ($ser = getenv('SYMFONY_DEPRECATIONS_SERIALIZE')) {
18+
DeprecationErrorHandler::collectDeprecations($ser);
19+
}
20+
1721
return;
1822
}
1923

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.