PK [GM
7m
lib/Dom/xpath_functions.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* This file contains functions which are to be used in XPath expressions.
*/
namespace PhpBench\Dom\functions;
use PhpBench\Tabular\Tabular\Dom\values;
/**
* Convert a DOMNodeList of parameter elements to a JSON encoded string.
*
* @param \DOMNodeList|DOMElement[]
*
* @return string
*/
function parameters_to_json($parameterEls)
{
return json_encode(parameters_to_array($parameterEls));
}
/**
* Convert a DOMNodeList of parameter elements to an array.
*
* @param \DOMNodeList|DOMElement[]
*
* @return array
*/
function parameters_to_array($parameterEls)
{
$array = array();
foreach ($parameterEls as $parameterEl) {
if (!$parameterEl instanceof \DOMElement) {
continue;
}
if ($parameterEl->getAttribute('type') === 'collection') {
$value = parameters_to_array($parameterEl->childNodes);
} else {
$value = $parameterEl->getAttribute('value');
}
$array[$parameterEl->getAttribute('name')] = $value;
}
return $array;
}
/**
* Return the class name of the given fully qualified name.
*
* @param string $classFqn
*
* @return string
*/
function class_name($classFqn)
{
$parts = explode('\\', $classFqn);
end($parts);
return current($parts);
}
/**
* Concatenate the values of the given nodes using the given delimiter.
*
* @param string $delimiter
* @param DOMNodeList|\DOMElement[] $list
*
* @return string
*/
function join_node_values($delimiter, $list)
{
$els = array();
foreach ($list as $el) {
if (!$el instanceof \DOMNode) {
continue;
}
$els[] = $el->nodeValue;
}
return implode($delimiter, $els);
}
/**
* Return a list of nodes which correspond to the given node list in the suite
* with the given context name.
*
* @param \DOMNodeList $nodeList
* @param string $suiteContext
*/
function suite($nodeList, $suiteContext)
{
if (!$nodeList) {
return;
}
$nodeList = _nodelist_to_array($nodeList);
$ownerDocument = $nodeList[0]->ownerDocument;
$xpath = new \DOMXPath($ownerDocument);
$fragment = $ownerDocument->createDocumentFragment();
foreach ($nodeList as $node) {
$path = $node->getNodePath();
$parts = explode('/', $path);
$path = implode('/', array_slice($parts, 3, count($parts)));
$path = '//suite[@context="' . $suiteContext .'"]/' . $path;
$items = $xpath->query($path);
if ($items->length === 0) {
continue;
}
$fragment->appendChild($items->item(0)->cloneNode(true));
}
return $fragment;
}
/**
* Convert a node list object into an array of nodes.
*/
function _nodelist_to_array($nodeList)
{
if (is_array($nodeList)) {
return $nodeList;
}
if (!$nodeList instanceof \DOMNodeList) {
throw new \InvalidArgumentException(sprintf(
'Expected array or \DOMNodeList, got "%s"',
is_object($nodeList) ? get_class($nodeList) : gettype($nodeList)
));
}
$nodes = array();
foreach ($nodeList as $node) {
$nodes[] = $node;
}
return $nodes;
}
function kde_mode($nodeList)
{
$values = values($nodeList);
return Statistics::kdeMode($values);
}
PK [GM % lib/Registry/RegistrableInterface.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Registry;
interface RegistrableInterface
{
/***
* Return the default configuration. This configuration will be prepended
* to all subsequent reports and should be used to provide default values.
*
* @return array
*/
public function getDefaultConfig();
/**
* Return a JSON schema which should be used to validate the configuration.
* Return an empty array() if you want to allow anything.
*
* @param OptionsResolver $options
*/
public function getSchema();
}
PK [GM3" " lib/Registry/Registry.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Registry;
use JsonSchema\Validator;
use PhpBench\DependencyInjection\Container;
/**
* Service and configuration registry.
*
* Lazily instantiates tagged services which are associated with a name
* and stores configurations which are relevant to these services.
*
* Services using this registry will typically used in association with a configuration, e.g.
*
* ```
* $config = $reg->getConfig('foobar');
* $reg->getService($config['renderer']);
* $reg->render($something, $config);
* ```
*/
class Registry
{
private $serviceMap = array();
private $container;
private $configs = array();
private $services = array();
private $validator;
private $serviceType;
public function __construct($serviceType, Container $container, Validator $validator)
{
$this->serviceType = $serviceType;
$this->container = $container;
$this->validator = $validator ?: new Validator();
}
/**
* Register a service ID with against the given name.
*
* @param string $name
* @param string $serviceId
*/
public function registerService($name, $serviceId)
{
$this->serviceMap[$name] = $serviceId;
$this->services[$name] = null;
}
/**
* Directly set a named service.
*
* @param string $name
* @param object $object
*/
public function setService($name, $object)
{
if (isset($this->services[$name])) {
throw new \InvalidArgumentException(sprintf(
'%s service "%s" already exists.',
$this->serviceType,
$name
));
}
$this->services[$name] = $object;
}
/**
* Return the named service, lazily creating it from the container
* if it has not yet been accessed.
*
* @param string $name
*
* @return object
*/
public function getService($name)
{
if (isset($this->services[$name])) {
return $this->services[$name];
}
$this->assertServiceExists($name);
$this->services[$name] = $this->container->get($this->serviceMap[$name]);
return $this->services[$name];
}
/**
* Return the named configuration.
*
* @return Config
*/
public function getConfig($name)
{
if (is_array($name)) {
$config = $name;
$name = uniqid();
$this->setConfig($name, $config);
}
$name = $this->processRawCliConfig($name);
if (!isset($this->configs[$name])) {
throw new \InvalidArgumentException(sprintf(
'No %s configuration named "%s" exists. Known configurations: "%s"',
$this->serviceType,
$name,
implode('", "', array_keys($this->configs))
));
}
return $this->configs[$name];
}
/**
* Set a named configuration.
*
* Note that all configurations must be associated with a named service
* via a configuration key equal to the configuration service type of this registry.
*
* @param string $name
* @param array $config
*/
public function setConfig($name, array $config)
{
if (isset($this->configs[$name])) {
throw new \InvalidArgumentException(sprintf(
'%s config "%s" already exists.',
$this->serviceType,
$name
));
}
$config = $this->resolveConfig($config);
if (!isset($config[$this->serviceType])) {
throw new \InvalidArgumentException(sprintf(
'%s configuration must EITHER indicate its target %s service with the "%s" key or extend an existing configuration with the "extends" key.',
$this->serviceType,
$this->serviceType,
$this->serviceType
));
}
$service = $this->getService($config[$this->serviceType]);
// eagerly validate
$config = $this->mergeAndValidateConfig($service, $config);
$this->configs[$name] = new Config($name, $config);
}
/**
* Recursively merge configs (having the "extends" key) which extend
* another report.
*
* @param array $config
* @param string $getMethod
*
* @return array
*/
private function resolveConfig(array $config)
{
if (isset($config['extends'])) {
$extended = $this->getConfig($config['extends']);
if (isset($config[$this->serviceType]) && ($extended[$this->serviceType] != $config[$this->serviceType])) {
throw new \InvalidArgumentException(sprintf(
'%s configuration for service "%s" cannot extend configuration for different service "%s"',
$this->serviceType,
$config[$this->serviceType],
$extended[$this->serviceType]
));
}
unset($config['extends']);
$config = array_replace_recursive(
$this->resolveConfig($extended->getArrayCopy()),
$config
);
}
return $config;
}
/**
* Merge the given config on to "configurable" (either a GeneratorInterface
* or a RendererInterface) instance's default config and validate it
* according to the "configurable" instance's JSON schema.
*
* @param ConfigurableInterface $configurable
* @param array $config
*
* @return array
*/
private function mergeAndValidateConfig(RegistrableInterface $configurable, array $config)
{
$config = array_replace_recursive($configurable->getDefaultConfig(), $config);
// not sure if there is a better way to convert the schema array to objects
// as expected by the validator.
$validationConfig = json_decode(json_encode($config));
$schema = $configurable->getSchema();
if (!is_array($schema)) {
throw new \InvalidArgumentException(sprintf(
'Configurable class "%s" must return the JSON schema as an array',
get_class($configurable)
));
}
$schema['properties'][$this->serviceType] = array('type' => 'string');
$schema['properties']['_name'] = array('type' => 'string');
// convert the schema to a \stdClass
$schema = json_decode(json_encode($schema));
// json_encode encodes an array instead of an object if the schema
// is empty. JSON schema requires an object.
if (empty($schema)) {
$schema = new \stdClass();
}
$this->validator->check($validationConfig, $schema);
if (!$this->validator->isValid()) {
$errorString = array();
foreach ($this->validator->getErrors() as $error) {
$errorString[] = sprintf('[%s] %s', $error['property'], $error['message']);
}
throw new \InvalidArgumentException(sprintf(
'Invalid JSON: %s%s',
PHP_EOL . PHP_EOL . PHP_EOL, implode(PHP_EOL, $errorString)
));
}
return $config;
}
private function assertServiceExists($name)
{
if (!array_key_exists($name, $this->services)) {
throw new \InvalidArgumentException(sprintf(
'%s service "%s" does not exist. Registered %s services: "%s"',
$this->serviceType,
$name,
$this->serviceType,
implode('", "', array_keys($this->services))
));
}
}
/**
* Process raw configuration as received from the CLI, for example:.
*
* ````
* {"generator": "table", "sort": ["time"]}
* ````
*
* Or simply the name of a pre-configured configuration to use:
*
* ````
* table
* ````
*
* @param array $rawConfigs
*
* @return array
*/
private function processRawCliConfig($rawConfig)
{
// If it doesn't look like a JSON string, assume it is the name of a config
if (substr($rawConfig, 0, 1) !== '{') {
return $rawConfig;
}
$config = json_decode($rawConfig, true);
if (null === $config) {
throw new \InvalidArgumentException(sprintf(
'Could not decode JSON string: %s', $rawConfig
));
}
$configName = uniqid();
$this->setConfig($configName, $config);
return $configName;
}
}
PK [GM> lib/Registry/Config.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Registry;
/**
* Configuration storage.
* Throws exceptions when accessing undefined offsets.
*/
class Config extends \ArrayObject
{
private $name;
public function __construct($name, array $config)
{
$this->name = $name;
parent::__construct($config);
}
public function offsetGet($offset)
{
if (!$this->offsetExists($offset)) {
throw new \InvalidArgumentException(sprintf(
'Configuration offset "%s" does not exist. Known offsets: "%s"',
$offset,
implode('", "', array_keys($this->getArrayCopy()))
));
}
return parent::offsetGet($offset);
}
public function getName()
{
return $this->name;
}
}
PK [GMU0 % lib/Environment/ProviderInterface.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment;
/**
* Implementors of this interface provide information about
* a specific feature of the environment, e.g. VCS, OS, etc.
*/
interface ProviderInterface
{
/**
* Return true if the instance detects a VCS repository
* in the current CWD.
*
* @return bool
*/
public function isApplicable();
/**
* Return information about the detected VCS repository.
*
* @return VcsInformation
*/
public function getInformation();
}
PK [GM̃ " lib/Environment/VcsInformation.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment;
/**
* VCS specific information. All VCS providers should
* return this object to ensure they all provide the same
* information.
*/
class VcsInformation extends Information
{
public function __construct($system, $branch, $version)
{
parent::__construct('vcs', array(
'system' => $system,
'branch' => $branch,
'version' => $version,
));
}
}
PK [GMC " lib/Environment/Provider/Uname.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment\Provider;
use PhpBench\Environment\Information;
use PhpBench\Environment\ProviderInterface;
/**
* Return the OS information (windows and unix).
*/
class Uname implements ProviderInterface
{
public function isApplicable()
{
return true;
}
public function getInformation()
{
$uname = array();
foreach (array(
'os' => 's',
'host' => 'n',
'release' => 'r',
'version' => 'v',
'machine' => 'm',
) as $key => $mode) {
$uname[$key] = php_uname($mode);
}
return new Information('uname', $uname);
}
}
PK [GMK4 4 ( lib/Environment/Provider/UnixSysload.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment\Provider;
use PhpBench\Environment\Information;
use PhpBench\Environment\ProviderInterface;
/**
* Return the load average for unix systems (1, 5, and 15 minute intervals).
*/
class UnixSysload implements ProviderInterface
{
public function isApplicable()
{
return false === stristr(PHP_OS, 'win');
}
public function getInformation()
{
$load = sys_getloadavg();
$load = array_combine(array(
'l1', 'l5', 'l15',
), $load);
return new Information('unix-sysload', $load);
}
}
PK [GM6ꟶ lib/Environment/Provider/Php.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment\Provider;
use PhpBench\Environment\Information;
use PhpBench\Environment\ProviderInterface;
/**
* Return PHP information.
*/
class Php implements ProviderInterface
{
public function isApplicable()
{
return true;
}
public function getInformation()
{
return new Information(
'php',
array(
'version' => PHP_VERSION,
)
);
}
}
PK [GMs= lib/Environment/Provider/Git.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment\Provider;
use PhpBench\Environment\ProviderInterface;
use PhpBench\Environment\VcsInformation;
use Symfony\Component\Process\Process;
/**
* Return information about the git environment.
*
* NOTE: This class returns a VcsInformation class to ensure that
* all VCS providers provide the same keys. VCS providers
* should be mutually exlusive and "polymorphic".
*/
class Git implements ProviderInterface
{
const SYSTEM = 'git';
/**
* {@inheritdoc}
*/
public function isApplicable()
{
$index = sprintf('%s/.git', getcwd());
if (file_exists($index)) {
return true;
}
return false;
}
/**
* {@inheritdoc}
*/
public function getInformation()
{
$cmd = 'git symbolic-ref HEAD';
$process = $this->exec($cmd);
if (0 !== $process->getExitCode() && stristr($process->getErrorOutput(), 'ref HEAD is not')) {
$branchName = '(unnamed branch)';
} elseif (0 === $process->getExitCode()) {
preg_match('{^refs/heads/(.*)$}', $process->getOutput(), $matches);
$branchName = $matches[1];
} else {
throw new \RuntimeException(sprintf(
'Encountered error when determining git branch exide code: %s, stderr: "%s"',
$process->getExitCode(),
$process->getErrorOutput()
));
}
$commitshRef = sprintf(
'%s/%s/%s',
getcwd(),
'.git/refs/heads',
$branchName
);
if (!file_exists($commitshRef)) {
$version = null;
} else {
$version = trim(file_get_contents($commitshRef));
}
return new VcsInformation(self::SYSTEM, $branchName, $version);
}
private function exec($cmd)
{
$process = new Process($cmd);
$process->run();
return $process;
}
}
PK [GM( ( lib/Environment/Supplier.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment;
/**
* Supplies information from the current environment.
*
* Indidual "information" is provided by "providers", which are responsible for
* saying if they can provide any information in the current environment, for
* example: if there is a .git directory, then the GIT provider will return
* some information.
*/
class Supplier
{
/**
* @var ProviderInterface[]
*/
private $providers = array();
/**
* Add a provider.
*
* @param ProviderInterface
*/
public function addProvider(ProviderInterface $provider)
{
$this->providers[] = $provider;
}
/**
* Return information from the current environment.
*
* @return Information[]
*/
public function getInformations()
{
$informations = array();
foreach ($this->providers as $provider) {
if (false === $provider->isApplicable()) {
continue;
}
$informations[] = $provider->getInformation();
}
return $informations;
}
}
PK [GMJy y lib/Environment/Information.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Environment;
/**
* Represents information about the VCS system used by the current working
* directory.
*/
class Information implements \ArrayAccess, \IteratorAggregate
{
private $name;
private $information;
/**
* __construct.
*
* @param string $system
* @param stirng $version
* @param string $branch
*/
public function __construct($name, array $information)
{
$this->name = $name;
$this->information = $information;
}
/**
* Return the name of this information, it should represent the domain of
* the infomration, e.g. "vcs", "uname".
*
* If an information is mutually exclusive then it should use a standard
* name representing the category of the thing (e.g. "vcs"). This allows
* reports and such things to reference it reliably.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
{
return $this->information[$offset];
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
{
throw new \BadMethodCallException(sprintf(
'Environmental information is immutable. Tried to set key "%s" with value "%s"',
$offset, $value
));
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
{
return array_key_exists($offset, $this->information);
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
{
throw new \BadMethodCallException(sprintf(
'Environmental information is immutable. Tried to unset key "%s"',
$offset
));
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
return new \ArrayIterator($this->information);
}
}
PK [GM9!L} } , lib/Extension/config/benchmark/executors.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
'microtime' => array(
'executor' => 'microtime',
),
'debug' => array(
'executor' => 'debug',
),
);
PK [GM̢ ) lib/Extension/config/report/renderers.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
'console' => array(
'renderer' => 'console',
),
'html' => array(
'renderer' => 'xslt',
'template' => __DIR__ . '/../../../Report/Renderer/templates/html.xsl',
),
'markdown' => array(
'renderer' => 'xslt',
'template' => __DIR__ . '/../../../Report/Renderer/templates/markdown.xsl',
),
'delimited' => array(
'renderer' => 'delimited',
),
'debug' => array(
'renderer' => 'debug',
),
);
PK [GMg8 8 * lib/Extension/config/report/generators.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
'aggregate' => array(
'generator' => 'table',
'type' => 'aggregate',
),
'default' => array(
'generator' => 'table',
'type' => 'default',
),
'compare' => array(
'generator' => 'table',
'type' => 'compare',
),
'plain' => array(
'generator' => 'table',
'type' => 'default',
'formatting' => false,
'body_only' => true,
),
'env' => array(
'generator' => 'table_custom',
'file' => __DIR__ . '/../../../Report/Generator/Tabular/env.json',
),
);
PK [GMm]I ]I lib/Extension/CoreExtension.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Extension;
use PhpBench\Benchmark\CollectionBuilder;
use PhpBench\Benchmark\Executor\DebugExecutor;
use PhpBench\Benchmark\Executor\MicrotimeExecutor;
use PhpBench\Benchmark\Metadata\Driver\AnnotationDriver;
use PhpBench\Benchmark\Metadata\Factory;
use PhpBench\Benchmark\Remote\Launcher;
use PhpBench\Benchmark\Remote\Reflector;
use PhpBench\Benchmark\Runner;
use PhpBench\Console\Application;
use PhpBench\Console\Command\Handler\ReportHandler;
use PhpBench\Console\Command\Handler\RunnerHandler;
use PhpBench\Console\Command\Handler\TimeUnitHandler;
use PhpBench\Console\Command\ReportCommand;
use PhpBench\Console\Command\RunCommand;
use PhpBench\DependencyInjection\Container;
use PhpBench\DependencyInjection\ExtensionInterface;
use PhpBench\Environment\Provider;
use PhpBench\Environment\Supplier;
use PhpBench\Progress\Logger\BlinkenLogger;
use PhpBench\Progress\Logger\DotsLogger;
use PhpBench\Progress\Logger\NullLogger;
use PhpBench\Progress\Logger\TravisLogger;
use PhpBench\Progress\Logger\VerboseLogger;
use PhpBench\Progress\LoggerRegistry;
use PhpBench\Registry\Registry;
use PhpBench\Report\Generator\CompositeGenerator;
use PhpBench\Report\Generator\Tabular\Format\TimeFormat;
use PhpBench\Report\Generator\TabularCustomGenerator;
use PhpBench\Report\Generator\TabularGenerator;
use PhpBench\Report\Renderer\ConsoleRenderer;
use PhpBench\Report\Renderer\DebugRenderer;
use PhpBench\Report\Renderer\DelimitedRenderer;
use PhpBench\Report\Renderer\XsltRenderer;
use PhpBench\Report\ReportManager;
use PhpBench\Tabular\Definition\Expander;
use PhpBench\Tabular\Definition\Loader;
use PhpBench\Tabular\Dom\XPathResolver;
use PhpBench\Tabular\Formatter;
use PhpBench\Tabular\Formatter\Format\BalanceFormat;
use PhpBench\Tabular\Formatter\Format\JSONFormat;
use PhpBench\Tabular\Formatter\Format\NumberFormat;
use PhpBench\Tabular\Formatter\Format\PrintfFormat;
use PhpBench\Tabular\Formatter\Format\TruncateFormat;
use PhpBench\Tabular\Formatter\Registry\ArrayRegistry;
use PhpBench\Tabular\TableBuilder;
use PhpBench\Tabular\Tabular;
use PhpBench\Util\TimeUnit;
use Symfony\Component\Finder\Finder;
class CoreExtension implements ExtensionInterface
{
public function configure(Container $container)
{
$container->register('console.application', function (Container $container) {
$application = new Application();
foreach (array_keys($container->getServiceIdsForTag('console.command')) as $serviceId) {
$command = $container->get($serviceId);
$application->add($command);
}
return $application;
});
$container->register('report.manager', function (Container $container) {
return new ReportManager(
$container->get('report.registry.generator'),
$container->get('report.registry.renderer')
);
});
$this->registerBenchmark($container);
$this->registerJsonSchema($container);
$this->registerTabular($container);
$this->registerCommands($container);
$this->registerRegistries($container);
$this->registerProgressLoggers($container);
$this->registerReportGenerators($container);
$this->registerReportRenderers($container);
$this->registerEnvironment($container);
$container->mergeParameters(array(
'path' => null,
'reports' => array(),
'outputs' => array(),
'executors' => array(),
'config_path' => null,
'progress' => getenv('CONTINUOUS_INTEGRATION') ? 'travis' : 'verbose',
'retry_threshold' => null,
'time_unit' => TimeUnit::MICROSECONDS,
'output_mode' => TimeUnit::MODE_TIME,
));
}
public function build(Container $container)
{
foreach ($container->getServiceIdsForTag('progress_logger') as $serviceId => $attributes) {
$progressLogger = $container->get($serviceId);
$container->get('progress_logger.registry')->addProgressLogger($attributes['name'], $progressLogger);
}
foreach ($container->getServiceIdsForTag('report_generator') as $serviceId => $attributes) {
$container->get('report.registry.generator')->registerService($attributes['name'], $serviceId);
}
foreach ($container->getServiceIdsForTag('report_renderer') as $serviceId => $attributes) {
$container->get('report.registry.renderer')->registerService($attributes['name'], $serviceId);
}
foreach ($container->getServiceIdsForTag('benchmark_executor') as $serviceId => $attributes) {
$container->get('benchmark.registry.executor')->registerService($attributes['name'], $serviceId);
}
foreach ($container->getServiceIdsForTag('environment_provider') as $serviceId => $attributes) {
$provider = $container->get($serviceId);
$container->get('environment.supplier')->addProvider($provider);
}
$generatorConfigs = array_merge(
require(__DIR__ . '/config/report/generators.php'),
$container->getParameter('reports')
);
foreach ($generatorConfigs as $name => $config) {
$container->get('report.registry.generator')->setConfig($name, $config);
}
$rendererConfigs = array_merge(
require(__DIR__ . '/config/report/renderers.php'),
$container->getParameter('outputs')
);
foreach ($rendererConfigs as $name => $config) {
$container->get('report.registry.renderer')->setConfig($name, $config);
}
$executorConfigs = array_merge(
require(__DIR__ . '/config/benchmark/executors.php'),
$container->getParameter('executors')
);
foreach ($executorConfigs as $name => $config) {
$container->get('benchmark.registry.executor')->setConfig($name, $config);
}
$this->relativizeConfigPath($container);
}
private function registerBenchmark(Container $container)
{
$container->register('benchmark.runner', function (Container $container) {
return new Runner(
$container->get('benchmark.collection_builder'),
$container->get('benchmark.registry.executor'),
$container->get('environment.supplier'),
$container->getParameter('retry_threshold'),
$container->getParameter('config_path')
);
});
$container->register('benchmark.executor.microtime', function (Container $container) {
return new MicrotimeExecutor(
$container->get('benchmark.remote.launcher')
);
}, array('benchmark_executor' => array('name' => 'microtime')));
$container->register('benchmark.executor.debug', function (Container $container) {
return new DebugExecutor(
$container->get('benchmark.remote.launcher')
);
}, array('benchmark_executor' => array('name' => 'debug')));
$container->register('benchmark.finder', function (Container $container) {
return new Finder();
});
$container->register('benchmark.remote.launcher', function (Container $container) {
return new Launcher(
$container->hasParameter('bootstrap') ? $container->getParameter('bootstrap') : null
);
});
$container->register('benchmark.remote.reflector', function (Container $container) {
return new Reflector($container->get('benchmark.remote.launcher'));
});
$container->register('benchmark.metadata.driver.annotation', function (Container $container) {
return new AnnotationDriver(
$container->get('benchmark.remote.reflector')
);
});
$container->register('benchmark.metadata_factory', function (Container $container) {
return new Factory(
$container->get('benchmark.remote.reflector'),
$container->get('benchmark.metadata.driver.annotation')
);
});
$container->register('benchmark.collection_builder', function (Container $container) {
return new CollectionBuilder(
$container->get('benchmark.metadata_factory'),
$container->get('benchmark.finder')
);
});
$container->register('benchmark.time_unit', function (Container $container) {
return new TimeUnit(TimeUnit::MICROSECONDS, $container->getParameter('time_unit'));
});
}
private function registerJsonSchema(Container $container)
{
$container->register('json_schema.validator', function (Container $container) {
return new \JsonSchema\Validator();
});
}
private function registerCommands(Container $container)
{
$container->register('console.command.handler.runner', function (Container $container) {
return new RunnerHandler(
$container->get('benchmark.runner'),
$container->get('progress_logger.registry'),
$container->getParameter('progress'),
$container->getParameter('path')
);
});
$container->register('console.command.handler.report', function (Container $container) {
return new ReportHandler(
$container->get('report.manager')
);
});
$container->register('console.command.handler.time_unit', function (Container $container) {
return new TimeUnitHandler(
$container->get('benchmark.time_unit')
);
});
$container->register('console.command.run', function (Container $container) {
return new RunCommand(
$container->get('console.command.handler.runner'),
$container->get('console.command.handler.report'),
$container->get('console.command.handler.time_unit')
);
}, array('console.command' => array()));
$container->register('console.command.report', function (Container $container) {
return new ReportCommand(
$container->get('console.command.handler.report'),
$container->get('console.command.handler.time_unit')
);
}, array('console.command' => array()));
}
private function registerProgressLoggers(Container $container)
{
$container->register('progress_logger.registry', function (Container $container) {
return new LoggerRegistry();
});
$container->register('progress_logger.dots', function (Container $container) {
return new DotsLogger($container->get('benchmark.time_unit'));
}, array('progress_logger' => array('name' => 'dots')));
$container->register('progress_logger.classdots', function (Container $container) {
return new DotsLogger($container->get('benchmark.time_unit'), true);
}, array('progress_logger' => array('name' => 'classdots')));
$container->register('progress_logger.verbose', function (Container $container) {
return new VerboseLogger($container->get('benchmark.time_unit'));
}, array('progress_logger' => array('name' => 'verbose')));
$container->register('progress_logger.travis', function (Container $container) {
return new TravisLogger($container->get('benchmark.time_unit'));
}, array('progress_logger' => array('name' => 'travis')));
$container->register('progress_logger.null', function (Container $container) {
return new NullLogger();
}, array('progress_logger' => array('name' => 'none')));
$container->register('progress_logger.blinken', function (Container $container) {
return new BlinkenLogger($container->get('benchmark.time_unit'));
}, array('progress_logger' => array('name' => 'blinken')));
}
private function registerReportGenerators(Container $container)
{
$container->register('report_generator.tabular', function (Container $container) {
return new TabularGenerator(
$container->get('tabular'),
$container->get('tabular.definition_loader')
);
}, array('report_generator' => array('name' => 'table')));
$container->register('report_generator.tabular_custom', function (Container $container) {
return new TabularCustomGenerator(
$container->get('tabular'),
$container->get('tabular.definition_loader'),
$container->getParameter('config_path')
);
}, array('report_generator' => array('name' => 'table_custom')));
$container->register('report_generator.composite', function (Container $container) {
return new CompositeGenerator($container->get('report.manager'));
}, array('report_generator' => array('name' => 'composite')));
}
private function registerReportRenderers(Container $container)
{
$container->register('report_renderer.console', function (Container $container) {
return new ConsoleRenderer();
}, array('report_renderer' => array('name' => 'console')));
$container->register('report_renderer.html', function (Container $container) {
return new XsltRenderer();
}, array('report_renderer' => array('name' => 'xslt')));
$container->register('report_renderer.debug', function (Container $container) {
return new DebugRenderer();
}, array('report_renderer' => array('name' => 'debug')));
$container->register('report_renderer.delimited', function (Container $container) {
return new DelimitedRenderer();
}, array('report_renderer' => array('name' => 'delimited')));
}
private function registerTabular(Container $container)
{
$container->register('tabular.xpath_resolver', function () {
require_once __DIR__ . '/../Dom/xpath_functions.php';
$resolver = new XPathResolver();
$resolver->registerFunction('parameters_to_json', 'PhpBench\Dom\functions\parameters_to_json');
$resolver->registerFunction('class_name', 'PhpBench\Dom\functions\class_name');
$resolver->registerFunction('join_node_values', 'PhpBench\Dom\functions\join_node_values');
$resolver->registerFunction('kde_mode', 'PhpBench\Dom\functions\join_node_values');
$resolver->registerFunction('suite', 'PhpBench\Dom\functions\suite');
return $resolver;
});
$container->register('tabular.table_builder', function (Container $container) {
return new TableBuilder($container->get('tabular.xpath_resolver'));
});
$container->register('tabular.formatter.registry', function (Container $container) {
$registry = new ArrayRegistry();
$registry->register('printf', new PrintfFormat());
$registry->register('balance', new BalanceFormat());
$registry->register('number', new NumberFormat());
$registry->register('truncate', new TruncateFormat());
$registry->register('json_format', new JSONFormat());
$registry->register('time', new TimeFormat($container->get('benchmark.time_unit')));
return $registry;
});
$container->register('tabular.formatter', function (Container $container) {
return new Formatter($container->get('tabular.formatter.registry'));
});
$container->register('tabular', function (Container $container) {
return new Tabular(
$container->get('tabular.table_builder'),
$container->get('tabular.definition_loader'),
$container->get('tabular.formatter'),
$container->get('tabular.expander')
);
});
$container->register('tabular.definition_loader', function (Container $container) {
return new Loader(
$container->get('json_schema.validator')
);
});
$container->register('tabular.expander', function (Container $container) {
return new Expander();
});
}
private function registerRegistries(Container $container)
{
foreach (array('generator', 'renderer') as $registryType) {
$container->register('report.registry.' . $registryType, function (Container $container) use ($registryType) {
return new Registry(
$registryType,
$container,
$container->get('json_schema.validator')
);
});
}
$container->register('benchmark.registry.executor', function (Container $container) {
return new Registry(
'executor',
$container,
$container->get('json_schema.validator')
);
});
}
public function registerEnvironment(Container $container)
{
$container->register('environment.provider.uname', function (Container $container) {
return new Provider\Uname();
}, array('environment_provider' => array()));
$container->register('environment.provider.php', function (Container $container) {
return new Provider\Php();
}, array('environment_provider' => array()));
$container->register('environment.provider.unix_sysload', function (Container $container) {
return new Provider\UnixSysload();
}, array('environment_provider' => array()));
$container->register('environment.provider.git', function (Container $container) {
return new Provider\Git();
}, array('environment_provider' => array()));
$container->register('environment.supplier', function (Container $container) {
return new Supplier();
});
}
private function relativizeConfigPath(Container $container)
{
if (null === $path = $container->getParameter('path')) {
return;
}
if (substr($path, 0, 1) === '/') {
return;
}
$container->setParameter('path', sprintf('%s/%s', dirname($container->getParameter('config_path')), $path));
}
}
PK [GMg ! ! lib/Util/TimeUnit.phpnu W+A
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpBench\Util;
/**
* Utility class for representing and converting time units.
*/
class TimeUnit
{
const MICROSECONDS = 'microseconds';
const MILLISECONDS = 'milliseconds';
const SECONDS = 'seconds';
const MINUTES = 'minutes';
const HOURS = 'hours';
const DAYS = 'days';
const MODE_THROUGHPUT = 'throughput';
const MODE_TIME = 'time';
/**
* @var array
*/
private static $map = array(
self::MICROSECONDS => 1,
self::MILLISECONDS => 1000,
self::SECONDS => 1000000,
self::MINUTES => 60000000,
self::HOURS => 3600000000,
self::DAYS => 86400000000,
);
/**
* @var array
*/
private static $suffixes = array(
self::MICROSECONDS => 'μs',
self::MILLISECONDS => 'ms',
self::SECONDS => 's',
self::MINUTES => 'm',
self::HOURS => 'h',
self::DAYS => 'd',
);
/**
* @var string
*/
private $sourceUnit;
/**
* @var string
*/
private $destUnit;
/**
* @var bool
*/
private $overriddenDestUnit = false;
/**
* @var bool
*/
private $overriddenMode = false;
/**
* @var bool
*/
private $overriddenPrecision = false;
/**
* @var string
*/
private $mode;
/**
* @var int
*/
private $precision;
public function __construct($sourceUnit = self::MICROSECONDS, $destUnit = self::MICROSECONDS, $mode = self::MODE_TIME, $precision = 3)
{
$this->sourceUnit = $sourceUnit;
$this->destUnit = $destUnit;
$this->mode = $mode;
$this->precision = $precision;
}
/**
* Convert instance value to given unit.
*
* @param string
*
* @return int
*/
public function toDestUnit($time, $destUnit = null, $mode = null)
{
return self::convert($time, $this->sourceUnit, $this->getDestUnit($destUnit), $this->getMode($mode));
}
/**
* Override the destination unit.
*
* @param string
*/
public function overrideDestUnit($destUnit)
{
self::validateUnit($destUnit);
$this->destUnit = $destUnit;
$this->overriddenDestUnit = true;
}
/**
* Override the mode.
*
* @param string $mode
*/
public function overrideMode($mode)
{
self::validateMode($mode);
$this->mode = $mode;
$this->overriddenMode = true;
}
/**
* Override the precision.
*
* @param int $precision
*/
public function overridePrecision($precision)
{
$this->precision = $precision;
$this->overriddenPrecision = true;
}
/**
* Return the destination unit.
*
* @param string $unit
*
* @return string
*/
public function getDestUnit($unit = null)
{
// if a unit is given, use that
if ($unit) {
return $unit;
}
// otherwise return the default
return $this->destUnit;
}
/**
* Utility method, if the dest unit is overridden, return the overridden
* value.
*
* @return string
*/
public function resolveDestUnit($unit)
{
if ($this->overriddenDestUnit) {
return $this->destUnit;
}
return $unit;
}
/**
* Utility method, if the mode is overridden, return the overridden
* value.
*
* @return string
*/
public function resolveMode($mode)
{
if ($this->overriddenMode) {
return $this->mode;
}
return $mode;
}
/**
* Utility method, if the precision is overridden, return the overridden
* value.
*
* @return string
*/
public function resolvePrecision($precision)
{
if ($this->overriddenPrecision) {
return $this->precision;
}
return $precision;
}
/**
* Return the destination mode.
*
* @param string $unit
*
* @return string
*/
public function getMode($mode = null)
{
// if a mode is given, use that
if ($mode) {
return $mode;
}
// otherwise return the default
return $this->mode;
}
/**
* Return the precision.
*/
public function getPrecision()
{
return $this->precision;
}
/**
* Return the destination unit suffix.
*
* @param string $unit
*
* @return string
*/
public function getDestSuffix($unit = null, $mode = null)
{
return self::getSuffix($this->getDestUnit($unit), $this->getMode($mode));
}
/**
* Return a human readable representation of the unit including the suffix.
*
* @param int
* @param string
* @param string
*/
public function format($time, $unit = null, $mode = null, $precision = null, $suffix = true)
{
$value = number_format($this->toDestUnit($time, $unit, $mode), $precision ?: $this->precision);
if (false === $suffix) {
return $value;
}
$suffix = $this->getDestSuffix($unit, $mode);
return $value . $suffix;
}
/**
* Convert given time in given unit to given destination unit in given mode.
*
* @static
*
* @param int $time
* @param string $unit
* @param string $destUnit
* @param string $mode
*
* @return int
*/
public static function convert($time, $unit, $destUnit, $mode)
{
self::validateMode($mode);
if ($mode === self::MODE_TIME) {
return self::convertTo($time, $unit, $destUnit);
}
return self::convertInto($time, $unit, $destUnit);
}
/**
* Convert a given time INTO the given unit. That is, how many times the
* given time will fit into the the destination unit. i.e. `x` per unit.
*
* @static
*
* @param int
* @param string
* @param string
*
* @return int
*/
public static function convertInto($time, $unit, $destUnit)
{
if (!$time) {
return 0;
}
self::validateUnit($unit);
self::validateUnit($destUnit);
$destM = self::$map[$destUnit];
$sourceM = self::$map[$unit];
$time = $destM / ($time * $sourceM);
return $time;
}
/**
* Convert the given time from the given unit to the given destination
* unit.
*
* @static
*
* @param int
* @param string
* @param string
*
* @return int
*/
public static function convertTo($time, $unit, $destUnit)
{
self::validateUnit($unit);
self::validateUnit($destUnit);
$destM = self::$map[$destUnit];
$sourceM = self::$map[$unit];
$time = ($time * $sourceM) / $destM;
return $time;
}
/**
* Return the suffix for a given unit.
*
* @static
*
* @param string
*
* @return string
*/
public static function getSuffix($unit, $mode = null)
{
if (null !== $unit) {
self::validateUnit($unit);
} else {
$unit = $this->destUnit;
}
$suffix = self::$suffixes[$unit];
if ($mode === self::MODE_THROUGHPUT) {
return sprintf('ops/%s', $suffix);
}
return $suffix;
}
private static function validateUnit($unit)
{
if (!is_string($unit)) {
throw new \InvalidArgumentException(sprintf(
'Expected string value for time unit, got "%s"',
is_object($unit) ? get_class($unit) : gettype($unit)
));
}
if (!isset(self::$map[$unit])) {
throw new \InvalidArgumentException(sprintf(
'Invalid time unit "%s", available units: "%s"',
$unit, implode('", "', array_keys(self::$map))
));
}
}
private static function validateMode($mode)
{
$validModes = array(self::MODE_THROUGHPUT, self::MODE_TIME);
if (!in_array($mode, $validModes)) {
throw new \InvalidArgumentException(sprintf(
'Time mode must be one of "%s", got "%s"',
implode('", "', $validModes), $mode
));
}
}
}
PK [GMڏ lib/Report/schema/report.xsdnu W+A