Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow excluding files in opcache:status:scripts command #254

Merged
merged 4 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CacheTool\Command;

use CacheTool\CacheTool;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
Expand Down
27 changes: 22 additions & 5 deletions src/Command/OpcacheStatusScriptsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use CacheTool\Util\Formatter;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class OpcacheStatusScriptsCommand extends AbstractOpcacheCommand
Expand All @@ -26,7 +27,13 @@ protected function configure()
$this
->setName('opcache:status:scripts')
->setDescription('Show scripts in the opcode cache')
->setHelp('');
->setHelp('')
->addOption(
'exclude',
'e',
InputOption::VALUE_OPTIONAL,
'Exclude scripts that match this regex. Example: `.*vendor.*`. Delimiters are not needed.'
);
}

/**
Expand All @@ -39,26 +46,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$info = $this->getCacheTool()->opcache_get_status(true);
$this->ensureSuccessfulOpcacheCall($info);

$exclude = $input->getOption('exclude') ?? null;

$table = new Table($output);
$table
->setHeaders([
'Hits',
'Memory',
'Filename'
])
->setRows($this->processFilelist($info['scripts']))
->setRows($this->processFilelist($info['scripts'], $exclude))
;

$table->render();

return 0;
}

protected function processFileList(array $cacheList)
{
protected function processFileList(
array $cacheList,
string $exclude = null
) {
$list = [];

foreach ($cacheList as $item) {
$filteredList = $exclude ? $this->excludeFiles($cacheList, $exclude) : $cacheList;
foreach ($filteredList as $item) {
$list[] = [
number_format($item['hits']),
Formatter::bytes($item['memory_consumption']),
Expand All @@ -68,4 +80,9 @@ protected function processFileList(array $cacheList)

return $list;
}

protected function excludeFiles(array $cacheList, string $exclude = null): array
{
return array_intersect_key($cacheList, array_flip(preg_grep("({$exclude})", array_keys($cacheList), \PREG_GREP_INVERT)));
}
}
45 changes: 43 additions & 2 deletions tests/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,57 @@

namespace CacheTool\Command;

use CacheTool\CacheTool;
use CacheTool\Code;
use CacheTool\Console\Application;
use CacheTool\Console\Config;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\BufferedOutput;

abstract class CommandTest extends \PHPUnit\Framework\TestCase
{
public function runCommand($cmd)
public function runCommand($cmd, $mockData = null)
{
$app = new Application(new Config(['adapter' => 'cli']));
$app = new class($mockData, new Config(['adapter' => 'cli'])) extends Application {
protected $mockData;
public function __construct($mockData, Config $config)
{
parent::__construct($config);

$this->mockData = $mockData;
}

public function buildContainer(InputInterface $input)
{
$container = parent::buildContainer($input);

$cacheTool = CacheTool::factory(
new class($this->mockData) extends \CacheTool\Adapter\Cli {
public function __construct(protected $mockData)
{}

public function doRun(Code $code)
{
if ($this->mockData) {
$wrappedMockData = [
'errors' => null,
'result' => $this->mockData,
];
return serialize($wrappedMockData);
}

return parent::doRun($code);
}
},
$this->config['temp_dir'],
$this->logger
);
$container->set('cachetool', $cacheTool);

return $container;
}
};
$app->setAutoExit(false);

$input = new StringInput($cmd);
Expand Down
70 changes: 70 additions & 0 deletions tests/Command/OpcacheStatusScriptsCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,74 @@ public function testCommand()
$this->assertStringContainsString('Memory', $result);
$this->assertStringContainsString('Filename', $result);
}

public function testExcludingScriptsWorksAsExpected()
{
$this->assertHasOpcache();

$scriptsMock = [
'/vendor/somefile.php' => [
'full_path' => '/vendor/somefile.php',
'hits' => 1,
'memory_consumption' => 1024,
],
'/src/my/path/to/somefile.php' => [
'full_path' => '/src/my/path/to/somefile.php',
'hits' => 2,
'memory_consumption' => 1024,
],
'/src/my/other/path/to/somefile.php' => [
'full_path' => '/src/my/other/path/to/somefile.php',
'hits' => 3,
'memory_consumption' => 1024,
],
'/vendor/someotherfile.php' => [
'full_path' => '/vendor/someotherfile.php',
'hits' => 4,
'memory_consumption' => 1024,
],
];

$result = $this->runCommand('opcache:status:scripts -v -e vendor', ['scripts' => $scriptsMock]);

$this->assertStringContainsString('opcache_get_status(true)', $result);
$this->assertStringContainsString('/src/my/path/to/somefile.php', $result);
$this->assertStringNotContainsString('vendor', $result); // No findings of "vendor" expected!
}

public function testNoScriptsAreExcludedByDefault()
{
$this->assertHasOpcache();

$scriptsMock = [
'/vendor/somefile.php' => [
'full_path' => '/vendor/somefile.php',
'hits' => 1,
'memory_consumption' => 1024,
],
'/src/my/path/to/somefile.php' => [
'full_path' => '/src/my/path/to/somefile.php',
'hits' => 2,
'memory_consumption' => 1024,
],
'/src/my/other/path/to/somefile.php' => [
'full_path' => '/src/my/other/path/to/somefile.php',
'hits' => 3,
'memory_consumption' => 1024,
],
'/vendor/someotherfile.php' => [
'full_path' => '/vendor/someotherfile.php',
'hits' => 4,
'memory_consumption' => 1024,
],
];

$result = $this->runCommand('opcache:status:scripts -v', ['scripts' => $scriptsMock]);

$this->assertStringContainsString('opcache_get_status(true)', $result);
$this->assertStringContainsString('/vendor/somefile.php', $result);
$this->assertStringContainsString('/src/my/path/to/somefile.php', $result);
$this->assertStringContainsString('/src/my/other/path/to/somefile.php', $result);
$this->assertStringContainsString('/vendor/someotherfile.php', $result);
}
}
Loading