Skip to content

Commit

Permalink
Merge pull request #254 from dritter/exclude_cachelist
Browse files Browse the repository at this point in the history
Add ability to exclude files from opcode cache listing
  • Loading branch information
gordalina authored Nov 15, 2024
2 parents fe49fbd + e7ee134 commit 1c79a08
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 7 deletions.
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);
}
}

0 comments on commit 1c79a08

Please sign in to comment.