From 49c34dfe3c4186b8a460be752891f2301ecce61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= <5175937+theofidry@users.noreply.github.com> Date: Wed, 7 Dec 2022 09:18:43 +0100 Subject: [PATCH] Refactor finders to leverage a common base (#47) --- src/HwLogicalFinder.php | 47 ++--------------- src/HwPhysicalFinder.php | 46 ++--------------- src/PopenBasedFinder.php | 63 +++++++++++++++++++++++ src/WindowsWmicFinder.php | 41 +++------------ tests/DummyPopenBasedFinder.php | 24 +++++++++ tests/HwLogicalFinderTest.php | 61 ++-------------------- tests/HwPhysicalFinderTest.php | 61 ++-------------------- tests/PopenBasedFinderTest.php | 82 ++++++++++++++++++++++++++++++ tests/PopenBasedFinderTestCase.php | 80 +++++++++++++++++++++++++++++ tests/WindowsWmicTest.php | 61 ++-------------------- 10 files changed, 274 insertions(+), 292 deletions(-) create mode 100644 src/PopenBasedFinder.php create mode 100644 tests/DummyPopenBasedFinder.php create mode 100644 tests/PopenBasedFinderTest.php create mode 100644 tests/PopenBasedFinderTestCase.php diff --git a/src/HwLogicalFinder.php b/src/HwLogicalFinder.php index 00b0502..1d49869 100644 --- a/src/HwLogicalFinder.php +++ b/src/HwLogicalFinder.php @@ -13,57 +13,16 @@ namespace Fidry\CpuCoreCounter; -use function fgets; -use function filter_var; -use function function_exists; -use function is_int; -use function is_resource; -use function pclose; -use function popen; -use const FILTER_VALIDATE_INT; - /** * Find the number of logical CPU cores for Linux, BSD and OSX. * * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L903-L909 * @see https://opensource.apple.com/source/xnu/xnu-792.2.4/libkern/libkern/sysctl.h.auto.html */ -final class HwLogicalFinder implements CpuCoreFinder +final class HwLogicalFinder extends PopenBasedFinder { - /** - * @return positive-int|null - */ - public function find(): ?int + protected function getCommand(): string { - if (!function_exists('popen')) { - return null; - } - - // -n to show only the variable value - // Use hw.logicalcpu instead of deprecated hw.ncpu; see https://github.com/php/php-src/pull/5541 - $process = popen('sysctl -n hw.logicalcpu', 'rb'); - - if (!is_resource($process)) { - return null; - } - - $processResult = fgets($process); - pclose($process); - - return false === $processResult - ? null - : self::countCpuCores($processResult); - } - - /** - * @internal - * - * @return positive-int|null - */ - public static function countCpuCores(string $process): ?int - { - $cpuCount = filter_var($process, FILTER_VALIDATE_INT); - - return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null; + return 'sysctl -n hw.logicalcpu'; } } diff --git a/src/HwPhysicalFinder.php b/src/HwPhysicalFinder.php index 76afd1f..d81929f 100644 --- a/src/HwPhysicalFinder.php +++ b/src/HwPhysicalFinder.php @@ -13,56 +13,16 @@ namespace Fidry\CpuCoreCounter; -use function fgets; -use function filter_var; -use function function_exists; -use function is_int; -use function is_resource; -use function pclose; -use function popen; -use const FILTER_VALIDATE_INT; - /** * Find the number of physical CPU cores for Linux, BSD and OSX. * * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L903-L909 * @see https://opensource.apple.com/source/xnu/xnu-792.2.4/libkern/libkern/sysctl.h.auto.html */ -final class HwPhysicalFinder implements CpuCoreFinder +final class HwPhysicalFinder extends PopenBasedFinder { - /** - * @return positive-int|null - */ - public function find(): ?int + protected function getCommand(): string { - if (!function_exists('popen')) { - return null; - } - - // -n to show only the variable value - $process = popen('sysctl -n hw.physicalcpu', 'rb'); - - if (!is_resource($process)) { - return null; - } - - $processResult = fgets($process); - pclose($process); - - return false === $processResult - ? null - : self::countCpuCores($processResult); - } - - /** - * @internal - * - * @return positive-int|null - */ - public static function countCpuCores(string $process): ?int - { - $cpuCount = filter_var($process, FILTER_VALIDATE_INT); - - return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null; + return 'sysctl -n hw.physicalcpu'; } } diff --git a/src/PopenBasedFinder.php b/src/PopenBasedFinder.php new file mode 100644 index 0000000..351e5ab --- /dev/null +++ b/src/PopenBasedFinder.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\CpuCoreCounter; + +use function fgets; +use function filter_var; +use function function_exists; +use function is_int; +use function is_resource; +use function pclose; +use function popen; +use const FILTER_VALIDATE_INT; + +abstract class PopenBasedFinder implements CpuCoreFinder +{ + /** + * @return positive-int|null + */ + public function find(): ?int + { + if (!function_exists('popen')) { + return null; + } + + $process = popen($this->getCommand(), 'rb'); + + if (!is_resource($process)) { + return null; + } + + $processResult = fgets($process); + pclose($process); + + return false === $processResult + ? null + : self::countCpuCores($processResult); + } + + /** + * @internal + * + * @return positive-int|null + */ + public static function countCpuCores(string $process): ?int + { + $cpuCount = filter_var($process, FILTER_VALIDATE_INT); + + return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null; + } + + abstract protected function getCommand(): string; +} diff --git a/src/WindowsWmicFinder.php b/src/WindowsWmicFinder.php index 99b7229..cbcf968 100644 --- a/src/WindowsWmicFinder.php +++ b/src/WindowsWmicFinder.php @@ -14,57 +14,30 @@ namespace Fidry\CpuCoreCounter; use function defined; -use function fgets; -use function filter_var; -use function function_exists; -use function is_int; -use function is_resource; -use function pclose; -use function popen; -use const FILTER_VALIDATE_INT; /** * Find the number of CPU cores for Windows. * * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L912-L916 */ -final class WindowsWmicFinder implements CpuCoreFinder +final class WindowsWmicFinder extends PopenBasedFinder { /** * @return positive-int|null */ public function find(): ?int { - if (!function_exists('popen') - || !defined('PHP_WINDOWS_VERSION_MAJOR') - ) { + if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + // Skip if not on Windows. Rely on PHP to detect the platform + // rather than reading the platform name or others. return null; } - // -n to show only the variable value - $process = popen('wmic cpu get NumberOfLogicalProcessors', 'rb'); - - if (!is_resource($process)) { - return null; - } - - $processResult = fgets($process); - pclose($process); - - return false === $processResult - ? null - : self::countCpuCores($processResult); + return parent::find(); } - /** - * @internal - * - * @return positive-int|null - */ - public static function countCpuCores(string $process): ?int + protected function getCommand(): string { - $cpuCount = filter_var($process, FILTER_VALIDATE_INT); - - return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null; + return 'wmic cpu get NumberOfLogicalProcessors'; } } diff --git a/tests/DummyPopenBasedFinder.php b/tests/DummyPopenBasedFinder.php new file mode 100644 index 0000000..4d962c3 --- /dev/null +++ b/tests/DummyPopenBasedFinder.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\CpuCoreCounter\Test; + +use Fidry\CpuCoreCounter\PopenBasedFinder; + +final class DummyPopenBasedFinder extends PopenBasedFinder +{ + protected function getCommand(): string + { + return ''; + } +} diff --git a/tests/HwLogicalFinderTest.php b/tests/HwLogicalFinderTest.php index 7acf757..3f453b7 100644 --- a/tests/HwLogicalFinderTest.php +++ b/tests/HwLogicalFinderTest.php @@ -14,70 +14,17 @@ namespace Fidry\CpuCoreCounter\Test; use Fidry\CpuCoreCounter\HwLogicalFinder; -use PHPUnit\Framework\TestCase; +use Fidry\CpuCoreCounter\PopenBasedFinder; /** * @covers \Fidry\CpuCoreCounter\HwLogicalFinder * * @internal */ -final class HwLogicalFinderTest extends TestCase +final class HwLogicalFinderTest extends PopenBasedFinderTestCase { - /** - * @dataProvider processProvider - */ - public function test_it_can_count_the_number_of_cpu_cores( - string $process, - ?int $expected - ): void { - $actual = HwLogicalFinder::countCpuCores($process); - - self::assertSame($expected, $actual); - } - - public static function processProvider(): iterable + protected function getFinder(): PopenBasedFinder { - yield 'empty' => [ - <<<'EOF' - -EOF - , - null, - ]; - - yield 'whitespace' => [ - <<<'EOF' - -EOF - , - null, - ]; - - // MyMachine™ - yield 'example from an OSX machine' => [ - <<<'EOF' -3 - -EOF - , - 3, - ]; - yield 'example with extra spaces' => [ - <<<'EOF' - 3 - -EOF - , - 3, - ]; - - yield 'no processor' => [ - <<<'EOF' -0 - -EOF - , - null, - ]; + return new HwLogicalFinder(); } } diff --git a/tests/HwPhysicalFinderTest.php b/tests/HwPhysicalFinderTest.php index c95eb10..ddfc03d 100644 --- a/tests/HwPhysicalFinderTest.php +++ b/tests/HwPhysicalFinderTest.php @@ -14,70 +14,17 @@ namespace Fidry\CpuCoreCounter\Test; use Fidry\CpuCoreCounter\HwPhysicalFinder; -use PHPUnit\Framework\TestCase; +use Fidry\CpuCoreCounter\PopenBasedFinder; /** * @covers \Fidry\CpuCoreCounter\HwPhysicalFinder * * @internal */ -final class HwPhysicalFinderTest extends TestCase +final class HwPhysicalFinderTest extends PopenBasedFinderTestCase { - /** - * @dataProvider processProvider - */ - public function test_it_can_count_the_number_of_cpu_cores( - string $process, - ?int $expected - ): void { - $actual = HwPhysicalFinder::countCpuCores($process); - - self::assertSame($expected, $actual); - } - - public static function processProvider(): iterable + protected function getFinder(): PopenBasedFinder { - yield 'empty' => [ - <<<'EOF' - -EOF - , - null, - ]; - - yield 'whitespace' => [ - <<<'EOF' - -EOF - , - null, - ]; - - // MyMachine™ - yield 'example from an OSX machine' => [ - <<<'EOF' -3 - -EOF - , - 3, - ]; - yield 'example with extra spaces' => [ - <<<'EOF' - 3 - -EOF - , - 3, - ]; - - yield 'no processor' => [ - <<<'EOF' -0 - -EOF - , - null, - ]; + return new HwPhysicalFinder(); } } diff --git a/tests/PopenBasedFinderTest.php b/tests/PopenBasedFinderTest.php new file mode 100644 index 0000000..6ea1d19 --- /dev/null +++ b/tests/PopenBasedFinderTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\CpuCoreCounter\Test; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \Fidry\CpuCoreCounter\PopenBasedFinder + * + * @internal + */ +final class PopenBasedFinderTest extends TestCase +{ + /** + * @dataProvider popenFgetsProvider + */ + public function test_it_can_count_the_number_of_cpu_cores( + string $nproc, + ?int $expected + ): void { + $actual = DummyPopenBasedFinder::countCpuCores($nproc); + + self::assertSame($expected, $actual); + } + + public static function popenFgetsProvider(): iterable + { + yield 'empty' => [ + <<<'EOF' + +EOF + , + null, + ]; + + yield 'whitespace' => [ + <<<'EOF' + +EOF + , + null, + ]; + + yield 'example from a Windows machine' => [ + <<<'EOF' +3 + +EOF + , + 3, + ]; + + yield 'example from a Windows machine with extra spaces' => [ + <<<'EOF' + 3 + +EOF + , + 3, + ]; + + yield 'no processor' => [ + <<<'EOF' +0 + +EOF + , + null, + ]; + } +} diff --git a/tests/PopenBasedFinderTestCase.php b/tests/PopenBasedFinderTestCase.php new file mode 100644 index 0000000..7400876 --- /dev/null +++ b/tests/PopenBasedFinderTestCase.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Fidry\CpuCoreCounter\Test; + +use Fidry\CpuCoreCounter\PopenBasedFinder; +use PHPUnit\Framework\TestCase; + +abstract class PopenBasedFinderTestCase extends TestCase +{ + /** + * @dataProvider processResultProvider + */ + public function test_it_can_count_the_number_of_cpu_cores( + string $processResult, + ?int $expected + ): void { + $actual = $this->getFinder()::countCpuCores($processResult); + + self::assertSame($expected, $actual); + } + + public static function processResultProvider(): iterable + { + yield 'empty' => [ + <<<'EOF' + +EOF + , + null, + ]; + + yield 'whitespace' => [ + <<<'EOF' + +EOF + , + null, + ]; + + yield 'example from a Windows machine' => [ + <<<'EOF' +3 + +EOF + , + 3, + ]; + + yield 'example from a Windows machine with extra spaces' => [ + <<<'EOF' + 3 + +EOF + , + 3, + ]; + + yield 'no processor' => [ + <<<'EOF' +0 + +EOF + , + null, + ]; + } + + abstract protected function getFinder(): PopenBasedFinder; +} diff --git a/tests/WindowsWmicTest.php b/tests/WindowsWmicTest.php index 76c94f3..d27d718 100644 --- a/tests/WindowsWmicTest.php +++ b/tests/WindowsWmicTest.php @@ -13,71 +13,18 @@ namespace Fidry\CpuCoreCounter\Test; +use Fidry\CpuCoreCounter\PopenBasedFinder; use Fidry\CpuCoreCounter\WindowsWmicFinder; -use PHPUnit\Framework\TestCase; /** * @covers \Fidry\CpuCoreCounter\WindowsWmicFinder * * @internal */ -final class WindowsWmicTest extends TestCase +final class WindowsWmicTest extends PopenBasedFinderTestCase { - /** - * @dataProvider wmicProvider - */ - public function test_it_can_count_the_number_of_cpu_cores( - string $nproc, - ?int $expected - ): void { - $actual = WindowsWmicFinder::countCpuCores($nproc); - - self::assertSame($expected, $actual); - } - - public static function wmicProvider(): iterable + protected function getFinder(): PopenBasedFinder { - yield 'empty' => [ - <<<'EOF' - -EOF - , - null, - ]; - - yield 'whitespace' => [ - <<<'EOF' - -EOF - , - null, - ]; - - yield 'example from a Windows machine' => [ - <<<'EOF' -3 - -EOF - , - 3, - ]; - - yield 'example from a Windows machine with extra spaces' => [ - <<<'EOF' - 3 - -EOF - , - 3, - ]; - - yield 'no processor' => [ - <<<'EOF' -0 - -EOF - , - null, - ]; + return new WindowsWmicFinder(); } }