Skip to content

Commit 1f63ebd

Browse files
authored
Merge pull request #10 from Roave/fix/ignore-negative-memory-measurements
Fix: Skip baseline memory profiles that are negative (instead of crashing)
2 parents 585fece + c379cc5 commit 1f63ebd

File tree

4 files changed

+53
-70
lines changed

4 files changed

+53
-70
lines changed

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
"bin/roave-no-leaks"
2525
],
2626
"require-dev": {
27-
"doctrine/coding-standard": "^5.0",
27+
"doctrine/coding-standard": "^6.0.0",
2828
"infection/infection": "^0.12.2",
2929
"phpstan/phpstan": "^0.11.4",
3030
"phpstan/phpstan-phpunit": "^0.11.0",
3131
"phpstan/phpstan-strict-rules": "^0.11.0",
3232
"psalm/plugin-phpunit": "^0.5.3",
33-
"squizlabs/php_codesniffer": "^3.4",
34-
"vimeo/psalm": "^3.2"
33+
"squizlabs/php_codesniffer": "^3.4.1",
34+
"vimeo/psalm": "^3.2.2"
3535
}
3636
}

src/CollectTestExecutionMemoryFootprints.php

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
namespace Roave\NoLeaks\PHPUnit;
66

77
use Exception;
8-
use PHPUnit\Framework\AssertionFailedError;
9-
use PHPUnit\Framework\Test;
108
use PHPUnit\Framework\TestListener;
9+
use PHPUnit\Framework\TestListenerDefaultImplementation;
1110
use PHPUnit\Framework\TestSuite;
12-
use PHPUnit\Framework\Warning;
1311
use PHPUnit\Runner\AfterLastTestHook;
1412
use PHPUnit\Runner\AfterSuccessfulTestHook;
1513
use PHPUnit\Runner\BeforeTestHook;
16-
use Throwable;
1714
use function array_combine;
1815
use function array_filter;
1916
use function array_intersect_key;
@@ -38,6 +35,8 @@ final class CollectTestExecutionMemoryFootprints implements
3835
AfterLastTestHook,
3936
TestListener
4037
{
38+
use TestListenerDefaultImplementation;
39+
4140
/** @var array<string, array<int, int>> */
4241
private $preTestMemoryUsages = [];
4342

@@ -106,40 +105,4 @@ public function executeAfterLastTest() : void
106105
));
107106
}
108107
}
109-
110-
public function addError(Test $test, Throwable $t, float $time) : void
111-
{
112-
}
113-
114-
public function addWarning(Test $test, Warning $e, float $time) : void
115-
{
116-
}
117-
118-
public function addFailure(Test $test, AssertionFailedError $e, float $time) : void
119-
{
120-
}
121-
122-
public function addIncompleteTest(Test $test, Throwable $t, float $time) : void
123-
{
124-
}
125-
126-
public function addRiskyTest(Test $test, Throwable $t, float $time) : void
127-
{
128-
}
129-
130-
public function addSkippedTest(Test $test, Throwable $t, float $time) : void
131-
{
132-
}
133-
134-
public function endTestSuite(TestSuite $suite) : void
135-
{
136-
}
137-
138-
public function startTest(Test $test) : void
139-
{
140-
}
141-
142-
public function endTest(Test $test, float $time) : void
143-
{
144-
}
145108
}

src/MeasuredBaselineTestMemoryLeak.php

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,28 @@ public static function fromBaselineTestMemoryUsages(
5151
throw new Exception('Pre- and post- baseline test run collected memory usages don\'t match in number');
5252
}
5353

54-
if (count($preBaselineTestMemoryUsages) < 3) {
55-
throw new Exception(sprintf(
56-
'At least 3 baseline test run memory profiles are required, %d given',
57-
count($preBaselineTestMemoryUsages)
58-
));
59-
}
54+
$memoryUsages = array_map(static function (int $beforeRun, int $afterRun) : int {
55+
return $afterRun - $beforeRun;
56+
}, $preBaselineTestMemoryUsages, $postBaselineTestMemoryUsages);
6057

61-
$memoryUsages = array_values(array_map(static function (int $beforeRun, int $afterRun) : int {
62-
$memoryUsage = $afterRun - $beforeRun;
58+
// Note: profile 0 is discarded, as it may contain autoloading and other static test suite initialisation state
59+
$relevantMemoryUsages = array_slice($memoryUsages, 1);
6360

64-
if ($memoryUsage < 0) {
65-
throw new Exception(sprintf(
66-
'Baseline memory usage of %d detected: invalid negative memory usage',
67-
$memoryUsage
68-
));
61+
$nonNegativeMemoryUsages = array_values(array_filter(
62+
$relevantMemoryUsages,
63+
static function (int $memoryUsage) : bool {
64+
return $memoryUsage >= 0;
6965
}
66+
));
7067

71-
return $memoryUsage;
72-
}, $preBaselineTestMemoryUsages, $postBaselineTestMemoryUsages));
73-
74-
// Note: profile 0 is discarded, as it may contain autoloading and other static test suite initialisation state
75-
$relevantMemoryUsages = array_slice($memoryUsages, 1);
68+
if (count($nonNegativeMemoryUsages) < 2) {
69+
throw new Exception(sprintf(
70+
'At least 3 baseline test run memory profiles are required, %d given',
71+
count($nonNegativeMemoryUsages) + 1
72+
));
73+
}
7674

77-
if (array_filter(array_count_values($relevantMemoryUsages), static function (int $count) : bool {
75+
if (array_filter(array_count_values($nonNegativeMemoryUsages), static function (int $count) : bool {
7876
return $count > 1;
7977
}) === []) {
8078
// @TODO good enough for detecting standard deviation for now, I guess? :|
@@ -84,7 +82,7 @@ public static function fromBaselineTestMemoryUsages(
8482
));
8583
}
8684

87-
return new self(...$relevantMemoryUsages);
85+
return new self(...$nonNegativeMemoryUsages);
8886
}
8987

9088
public function lessThan(int $testRunMemoryLeak) : bool

test/unit/MeasuredBaselineTestMemoryLeakTest.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,45 @@ public function testRejectsHighlyInconsistentProfiles() : void
3535
);
3636
}
3737

38-
public function testRejectsNegativeMemoryLeaks() : void
38+
public function testFiltersNegativeMemoryLeaks() : void
3939
{
40-
$this->expectExceptionMessage('Baseline memory usage of -1 detected: invalid negative memory usage');
41-
42-
MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
43-
[100, 50, 51],
44-
[200, 49, 51]
40+
self::assertEquals(
41+
MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
42+
[100, 51, 52, 53],
43+
[200, 51, 53, 54]
44+
),
45+
MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
46+
[100, 50, 51, 51, 53],
47+
[200, 49, 51, 52, 54]
48+
)
4549
);
4650
}
4751

4852
public function testRejectsDataSetWithTooFewMemoryLeakProfiles() : void
4953
{
54+
$validMeasurement = MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
55+
[100, 50, 60],
56+
[200, 50, 60]
57+
);
58+
59+
self::assertTrue($validMeasurement->lessThan(1));
60+
self::assertFalse($validMeasurement->lessThan(0));
61+
5062
$this->expectExceptionMessage('At least 3 baseline test run memory profiles are required, 2 given');
5163

5264
MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
5365
[100, 50],
54-
[200, 49]
66+
[200, 50]
67+
);
68+
}
69+
70+
public function testRejectsDataSetWithTooFewValidMemoryLeakProfiles() : void
71+
{
72+
$this->expectExceptionMessage('At least 3 baseline test run memory profiles are required, 2 given');
73+
74+
MeasuredBaselineTestMemoryLeak::fromBaselineTestMemoryUsages(
75+
[100, 50, 50],
76+
[200, 50, 49]
5577
);
5678
}
5779

0 commit comments

Comments
 (0)