Skip to content

Commit

Permalink
Refactor finders to leverage a common base (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry authored Dec 7, 2022
1 parent ee56c03 commit 49c34df
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 292 deletions.
47 changes: 3 additions & 44 deletions src/HwLogicalFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
46 changes: 3 additions & 43 deletions src/HwPhysicalFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
63 changes: 63 additions & 0 deletions src/PopenBasedFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/*
* This file is part of the Fidry CPUCounter Config package.
*
* (c) Théo FIDRY <[email protected]>
*
* 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;
}
41 changes: 7 additions & 34 deletions src/WindowsWmicFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
24 changes: 24 additions & 0 deletions tests/DummyPopenBasedFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/*
* This file is part of the Fidry CPUCounter Config package.
*
* (c) Théo FIDRY <[email protected]>
*
* 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 '';
}
}
61 changes: 4 additions & 57 deletions tests/HwLogicalFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Loading

0 comments on commit 49c34df

Please sign in to comment.