public function suiteCollectionFromInput(InputInterface $input) { $files = $input->getOption('file'); $queries = $input->getOption('query'); $uuids = $input->getOption('uuid'); if (!$files && !$queries && !$uuids) { throw new \InvalidArgumentException('You must specify at least one of `--query` and/or `--uuid`'); } $collection = new SuiteCollection(); if ($files) { $collection->mergeCollection($this->xmlDecoder->decodeFiles($files)); } if ($queries) { foreach ($queries as $query) { $constraint = $this->parser->parse($query); $collection->mergeCollection($this->storage->getService()->query($constraint)); } } if ($uuids) { foreach ($uuids as $uuid) { $uuid = $this->uuidResolver->resolve($uuid); $collection->mergeCollection($this->storage->getService()->fetch($uuid)); } } return $collection; }
/** * It should merge another colleciton into itself. */ public function testMergeCollection() { $collection = new SuiteCollection([$this->suite1->reveal()]); $newCollection = new SuiteCollection([$this->suite2->reveal(), $this->suite3->reveal()]); $collection->mergeCollection($newCollection); $this->assertEquals([$this->suite1->reveal(), $this->suite2->reveal(), $this->suite3->reveal()], $collection->getSuites()); }
/** * {@inheritdoc} */ public function store(SuiteCollection $collection) { foreach ($collection->getSuites() as $suite) { $path = $this->getPath($suite->getUuid()); if (false === $this->filesystem->exists(dirname($path))) { $this->filesystem->mkdir(dirname($path)); } $collection = new SuiteCollection([$suite]); $dom = $this->xmlEncoder->encode($collection); $dom->save($path); } }
public function persist(SuiteCollection $collection) { $conn = $this->manager->getConnection(); foreach ($collection->getSuites() as $suite) { $summary = $suite->getSummary(); $id = $this->insertUpdate($conn, 'run', ['uuid' => $suite->getUuid(), 'context' => $suite->getContextName(), 'date' => $suite->getDate()->format('Y-m-d H:i:s'), 'nb_subjects' => $summary->getNbSubjects(), 'nb_iterations' => $summary->getNbIterations(), 'nb_revolutions' => $summary->getNbRevolutions(), 'min_time' => $summary->getMinTime(), 'max_time' => $summary->getMaxTime(), 'mean_time' => $summary->getMeanTime(), 'mean_rstdev' => $summary->getMeanRelStDev(), 'total_time' => $summary->getTotalTime()]); $envData = []; foreach ($suite->getEnvInformations() as $information) { foreach ($information as $key => $value) { $envData[] = ['run_id' => $id, 'provider' => $information->getName(), 'ekey' => $key, 'value' => $value]; } } $this->insertMultiple($conn, 'environment', $envData); $iterationDatas = []; $parameterAssocs = []; foreach ($suite->getBenchmarks() as $benchmark) { foreach ($benchmark->getSubjects() as $subject) { $data = ['benchmark' => $benchmark->getClass(), 'name' => $subject->getName()]; $subjectId = $this->getSubjectId($conn, $data['benchmark'], $data['name']); $subjectId = $this->insertUpdate($conn, 'subject', $data, $subjectId); foreach ($subject->getGroups() as $groupName) { $this->associateGroup($conn, $subjectId, $groupName); } foreach ($subject->getVariants() as $variant) { $data = ['revolutions' => $variant->getRevolutions(), 'retry_threshold' => $subject->getRetryThreshold(), 'output_time_unit' => $subject->getOutputTimeUnit(), 'output_time_precision' => $subject->getOutputTimePrecision(), 'output_mode' => $subject->getOutputMode(), 'sleep' => $subject->getSleep(), 'warmup' => $variant->getWarmup(), 'subject_id' => $subjectId, 'run_id' => $id]; $variantId = $this->insertUpdate($conn, 'variant', $data); foreach ($variant->getParameterSet() as $key => $value) { $value = json_encode($value); $parameterId = $this->getOrCreateParameter($conn, $key, $value); $parameterAssocs[] = ['variant_id' => $variantId, 'parameter_id' => $parameterId]; } foreach ($variant as $iteration) { $iterationDatas[] = ['time' => $iteration->getMetric(TimeResult::class, 'net', null), 'memory' => $iteration->getMetricOrDefault(MemoryResult::class, 'peak', -1), 'reject_count' => $iteration->getMetricOrDefault(RejectionCountResult::class, 'count', 0), 'variant_id' => $variantId]; } } } } // insert the iterations and variant parameter relations in batch $this->insertMultiple($conn, 'iteration', $iterationDatas); $this->insertMultiple($conn, 'variant_parameter', $parameterAssocs); } }
/** * Encode a Suite object into a XML document. * * @param SuiteCollection $suiteCollection * * @return Document */ public function encode(SuiteCollection $suiteCollection) { $dom = new Document(); $rootEl = $dom->createRoot('phpbench'); $rootEl->setAttribute('version', PhpBench::VERSION); foreach ($suiteCollection->getSuites() as $suite) { $suiteEl = $rootEl->appendElement('suite'); $suiteEl->setAttribute('context', $suite->getContextName()); $suiteEl->setAttribute('date', $suite->getDate()->format('Y-m-d H:i:s')); $suiteEl->setAttribute('config-path', $suite->getConfigPath()); $suiteEl->setAttribute('uuid', $suite->getUuid()); $envEl = $suiteEl->appendElement('env'); foreach ($suite->getEnvInformations() as $information) { $infoEl = $envEl->appendElement($information->getName()); foreach ($information as $key => $value) { $infoEl->setAttribute($key, $value); } } foreach ($suite->getBenchmarks() as $benchmark) { $this->processBenchmark($benchmark, $suiteEl); } } return $dom; }
/** * Construct the initial table from the SuiteCollection. * * @param SuiteCollection $suiteCollection * @param Config $config * * @return array */ private function buildTable(SuiteCollection $suiteCollection, Config $config) { $paramJsonFlags = null; if (true === $config['pretty_params']) { $paramJsonFlags = JSON_PRETTY_PRINT; } $table = []; $columnNames = []; foreach ($suiteCollection->getSuites() as $suite) { $env = $suite->getEnvInformations(); foreach ($suite->getBenchmarks() as $benchmark) { foreach ($benchmark->getSubjects() as $subject) { foreach ($subject->getVariants() as $variant) { $row = new Row(['suite' => $suite->getUuid(), 'date' => $suite->getDate()->format('Y-m-d'), 'stime' => $suite->getDate()->format('H:i:s'), 'benchmark' => $this->getClassShortName($benchmark->getClass()), 'benchmark_full' => $benchmark->getClass(), 'subject' => $subject->getName(), 'groups' => implode(',', $subject->getGroups()), 'params' => json_encode($variant->getParameterSet()->getArrayCopy(), $paramJsonFlags), 'revs' => $variant->getRevolutions(), 'its' => count($variant->getIterations()), 'mem_real' => Statistics::mean($variant->getMetricValues(MemoryResult::class, 'real')), 'mem_final' => Statistics::mean($variant->getMetricValues(MemoryResult::class, 'final')), 'mem_peak' => Statistics::mean($variant->getMetricValues(MemoryResult::class, 'peak'))]); // the formatter params are passed to the Formatter and // allow the formatter configurations to use tokens -- // in other words we can override formatting on a // per-row basis. $formatParams = []; if ($timeUnit = $subject->getOutputTimeUnit()) { $formatParams['output_time_unit'] = $timeUnit; } if ($mode = $subject->getOutputMode()) { $formatParams['output_mode'] = $mode; } if ($precision = $subject->getOutputTimePrecision()) { $formatParams['output_time_precision'] = $precision; } $row->setFormatParams($formatParams); $stats = $variant->getStats()->getStats(); $stats['best'] = $stats['min']; $stats['worst'] = $stats['max']; // save on duplication and lazily evaluate the // available statistics. if (null === $this->statKeys) { $this->statKeys = array_keys($stats); } $row = $row->merge($stats); // generate the environment parameters. // TODO: should we crash here if an attempt is made to // override a row? it could happen. foreach ($env as $providerName => $information) { foreach ($information as $key => $value) { $row[$providerName . '_' . $key] = $value; } } foreach ($row->getNames() as $columnName) { if (!isset($columnNames[$columnName])) { $columnNames[$columnName] = true; } } // if the iterations option is specified then we add a row for each iteration, otherwise // we continue. if (false === $config['iterations']) { $table[] = $row; continue; } foreach ($variant->getIterations() as $index => $iteration) { $row = clone $row; $row['iter'] = $index; foreach ($iteration->getResults() as $result) { $metrics = $result->getMetrics(); // otherwise prefix the metric key with the result key. foreach ($metrics as $key => $value) { // TODO: this is a hack to add the rev time to the report. if ($result instanceof TimeResult && $key === 'net') { $row[$result->getKey() . '_rev'] = $result->getRevTime($iteration->getVariant()->getRevolutions()); } $row[$result->getKey() . '_' . $key] = $value; } } $table[] = $row; } } } } } // multiple suites may have different column names, for example the // number of environment columns may differ. here we iterate over all // the rows to ensure they all have all of the columns which have been // defined. foreach ($table as $row) { foreach (array_keys($columnNames) as $columnName) { if (!isset($row[$columnName])) { $row[$columnName] = null; } } } return $table; }