/** * If we have a timeline, figure out what each thread was doing at each point in time. * Basically CPU utilization from the timeline. * * @param TestPaths $localPaths Paths related to this run/step * @return array|null An array of threads with each thread being an array of slices (one for * each time period). Each slice is an array of events and the fraction of that * slice that they consumed (with a total maximum of 1 for any slice). */ function DevToolsGetCPUSlicesForStep($localPaths) { $slices = null; $slices_file = $localPaths->devtoolsCPUTimelineFile() . ".gz"; $trace_file = $localPaths->devtoolsTraceFile() . ".gz"; $script_timing = $localPaths->devtoolsScriptTimingFile() . ".gz"; if (!GetSetting('disable_timeline_processing') && !is_file($slices_file) && is_file($trace_file) && is_file(__DIR__ . '/lib/trace/trace-parser.py')) { $script = realpath(__DIR__ . '/lib/trace/trace-parser.py'); touch($slices_file); if (is_file($slices_file)) { $slices_file = realpath($slices_file); unlink($slices_file); } $user_timing = $localPaths->chromeUserTimingFile() . ".gz"; touch($user_timing); if (is_file($user_timing)) { $user_timing = realpath($user_timing); unlink($user_timing); } $trace_file = realpath($trace_file); $command = "python \"{$script}\" -t \"{$trace_file}\" -u \"{$user_timing}\" -c \"{$slices_file}\" -j \"{$script_timing}\" 2>&1"; exec($command, $output, $result); if (!is_file($slices_file)) { touch($slices_file); } } if (gz_is_file($slices_file)) { $slices = json_decode(gz_file_get_contents($slices_file), true); } if (isset($slices) && !is_array($slices)) { $slices = null; } return $slices; }
require_once __DIR__ . '/include/TestStepResult.php'; // not functional, but to declare what to expect from common.inc global $testPath, $run, $cached, $step, $id, $url, $test; $testInfo = TestInfo::fromFiles($testPath); $testStepResult = TestStepResult::fromFiles($testInfo, $run, $cached, $step); $is_mime = isset($_REQUEST['mime']) ? (bool) @$_REQUEST['mime'] : (bool) GetSetting('mime_waterfalls'); $is_state = (bool) @$_REQUEST['state']; $include_js = isset($_REQUEST['js']) ? (bool) @$_REQUEST['js'] : true; $use_dots = !isset($_REQUEST['dots']) || $_REQUEST['dots'] != 0; $show_labels = !isset($_REQUEST['labels']) || $_REQUEST['labels'] != 0; $rowcount = array_key_exists('rowcount', $_REQUEST) ? $_REQUEST['rowcount'] : 0; // Get all of the requests; $requests = $testStepResult->getRequests(); if ($include_js) { $localPaths = new TestPaths($testInfo->getRootDirectory(), $run, $cached, $step); AddRequestScriptTimings($requests, $localPaths->devtoolsScriptTimingFile()); } if (@$_REQUEST['type'] == 'connection') { $is_state = true; $include_js = false; $rows = GetConnectionRows($requests, $show_labels); } else { $rows = GetRequestRows($requests, $use_dots, $show_labels); } $page_events = GetPageEvents($testStepResult->getRawResults()); $bwIn = 0; if (isset($test) && array_key_exists('testinfo', $test) && array_key_exists('bwIn', $test['testinfo'])) { $bwIn = $test['testinfo']['bwIn']; } else { if (isset($test) && array_key_exists('test', $test) && array_key_exists('bwIn', $test['test'])) { $bwIn = $test['test']['bwIn'];
/** * Gather all of the data that we collect for a single run * * @param TestStepResult $testStepResult * @return array Array with run information which can be serialized as JSON */ private function stepDataArray($testStepResult) { if (!$testStepResult) { return null; } $ret = $testStepResult->getRawResults(); $run = $testStepResult->getRunNumber(); $cached = $testStepResult->isCachedRun(); $step = $testStepResult->getStepNumber(); $localPaths = new TestPaths($this->testInfo->getRootDirectory(), $run, $cached, $step); $nameOnlyPaths = new TestPaths("", $run, $cached, $step); $urlGenerator = UrlGenerator::create(false, $this->urlStart, $this->testInfo->getId(), $run, $cached, $step); $friendlyUrlGenerator = UrlGenerator::create(true, $this->urlStart, $this->testInfo->getId(), $run, $cached, $step); $urlPaths = new TestPaths($this->urlStart . substr($this->testInfo->getRootDirectory(), 1), $run, $cached, $step); $basic_results = $this->hasInfoFlag(self::BASIC_INFO_ONLY); if (!$basic_results && $this->fileHandler->gzFileExists($localPaths->pageSpeedFile())) { $ret['PageSpeedScore'] = $testStepResult->getPageSpeedScore(); $ret['PageSpeedData'] = $urlGenerator->getGZip($nameOnlyPaths->pageSpeedFile()); } $ret['pages'] = array(); $ret['pages']['details'] = $urlGenerator->resultPage("details"); $ret['pages']['checklist'] = $urlGenerator->resultPage("performance_optimization"); $ret['pages']['breakdown'] = $urlGenerator->resultPage("breakdown"); $ret['pages']['domains'] = $urlGenerator->resultPage("domains"); $ret['pages']['screenShot'] = $urlGenerator->resultPage("screen_shot"); $ret['thumbnails'] = array(); $ret['thumbnails']['waterfall'] = $friendlyUrlGenerator->thumbnail("waterfall.png"); $ret['thumbnails']['checklist'] = $friendlyUrlGenerator->thumbnail("optimization.png"); $ret['thumbnails']['screenShot'] = $friendlyUrlGenerator->thumbnail("screen.png"); $ret['images'] = array(); $ret['images']['waterfall'] = $friendlyUrlGenerator->generatedImage("waterfall"); $ret['images']['connectionView'] = $friendlyUrlGenerator->generatedImage("connection"); $ret['images']['checklist'] = $friendlyUrlGenerator->optimizationChecklistImage(); $ret['images']['screenShot'] = $urlGenerator->getFile($nameOnlyPaths->screenShotFile()); if ($this->fileHandler->fileExists($localPaths->screenShotPngFile())) { $ret['images']['screenShotPng'] = $urlGenerator->getFile($nameOnlyPaths->screenShotPngFile()); } $ret['rawData'] = array(); if ($this->fileHandler->gzFileExists($localPaths->devtoolsScriptTimingFile())) { $ret['rawData']['scriptTiming'] = $urlGenerator->getGZip($nameOnlyPaths->devtoolsScriptTimingFile()); } $ret['rawData']['headers'] = $urlPaths->headersFile(); $ret['rawData']['pageData'] = $urlPaths->pageDataFile(); $ret['rawData']['requestsData'] = $urlPaths->requestDataFile(); $ret['rawData']['utilization'] = $urlPaths->utilizationFile(); if ($this->fileHandler->fileExists($localPaths->bodiesFile())) { $ret['rawData']['bodies'] = $urlPaths->bodiesFile(); } if ($this->fileHandler->gzFileExists($localPaths->devtoolsTraceFile())) { $ret['rawData']['trace'] = $urlGenerator->getGZip($nameOnlyPaths->devtoolsTraceFile() . ".gz"); } if (!$basic_results) { $ret = array_merge($ret, $this->getAdditionalInfoArray($testStepResult, $urlGenerator, $nameOnlyPaths)); } return $ret; }
/** * @param TestStepResult $stepResult Results for the step to be printed */ private function printStepResults($stepResult) { if (empty($stepResult)) { return; } $run = $stepResult->getRunNumber(); $cached = $stepResult->isCachedRun() ? 1 : 0; $step = $stepResult->getStepNumber(); $testRoot = $this->testInfo->getRootDirectory(); $testId = $this->testInfo->getId(); $localPaths = new TestPaths($testRoot, $run, $cached, $step); $nameOnlyPaths = new TestPaths("", $run, $cached, $step); $urlPaths = new TestPaths($this->baseUrl . substr($testRoot, 1), $run, $cached, $step); echo "<results>\n"; echo ArrayToXML($stepResult->getRawResults()); $this->printPageSpeed($stepResult); echo "</results>\n"; // links to the relevant pages $urlGenerator = UrlGenerator::create($this->friendlyUrls, $this->baseUrl, $testId, $run, $cached, $step); echo "<pages>\n"; echo "<details>" . htmlspecialchars($urlGenerator->resultPage("details")) . "</details>\n"; echo "<checklist>" . htmlspecialchars($urlGenerator->resultPage("performance_optimization")) . "</checklist>\n"; echo "<breakdown>" . htmlspecialchars($urlGenerator->resultPage("breakdown")) . "</breakdown>\n"; echo "<domains>" . htmlspecialchars($urlGenerator->resultPage("domains")) . "</domains>\n"; echo "<screenShot>" . htmlspecialchars($urlGenerator->resultPage("screen_shot")) . "</screenShot>\n"; echo "</pages>\n"; // urls for the relevant images echo "<thumbnails>\n"; echo "<waterfall>" . htmlspecialchars($urlGenerator->thumbnail("waterfall.png")) . "</waterfall>\n"; echo "<checklist>" . htmlspecialchars($urlGenerator->thumbnail("optimization.png")) . "</checklist>\n"; if ($this->fileHandler->fileExists($localPaths->screenShotFile())) { echo "<screenShot>" . htmlspecialchars($urlGenerator->thumbnail("screen.jpg")) . "</screenShot>\n"; } echo "</thumbnails>\n"; echo "<images>\n"; echo "<waterfall>" . htmlspecialchars($urlGenerator->generatedImage("waterfall")) . "</waterfall>\n"; echo "<connectionView>" . htmlspecialchars($urlGenerator->generatedImage("connection")) . "</connectionView>\n"; echo "<checklist>" . htmlspecialchars($urlGenerator->optimizationChecklistImage()) . "</checklist>\n"; if ($this->fileHandler->fileExists($localPaths->screenShotFile())) { echo "<screenShot>" . htmlspecialchars($urlGenerator->getFile($nameOnlyPaths->screenShotFile())) . "</screenShot>\n"; } if ($this->fileHandler->fileExists($localPaths->screenShotPngFile())) { echo "<screenShotPng>" . htmlspecialchars($urlGenerator->getFile($nameOnlyPaths->screenShotPngFile())) . "</screenShotPng>\n"; } echo "</images>\n"; // raw results (files accessed directly on the file system, but via URL) echo "<rawData>\n"; if ($this->fileHandler->gzFileExists($localPaths->devtoolsScriptTimingFile())) { echo "<scriptTiming>" . htmlspecialchars($urlGenerator->getGZip($nameOnlyPaths->devtoolsScriptTimingFile())) . "</scriptTiming>\n"; } if ($this->fileHandler->gzFileExists($localPaths->headersFile())) { echo "<headers>" . $urlPaths->headersFile() . "</headers>\n"; } if ($this->fileHandler->gzFileExists($localPaths->bodiesFile())) { echo "<bodies>" . $urlPaths->bodiesFile() . "</bodies>\n"; } if ($this->fileHandler->gzFileExists($localPaths->pageDataFile())) { echo "<pageData>" . $urlPaths->pageDataFile() . "</pageData>\n"; } if ($this->fileHandler->gzFileExists($localPaths->requestDataFile())) { echo "<requestsData>" . $urlPaths->requestDataFile() . "</requestsData>\n"; } if ($this->fileHandler->gzFileExists($localPaths->utilizationFile())) { echo "<utilization>" . $urlPaths->utilizationFile() . "</utilization>\n"; } $this->printPageSpeedData($stepResult); echo "</rawData>\n"; // video frames $progress = $stepResult->getVisualProgress(); if (array_key_exists('frames', $progress) && is_array($progress['frames']) && count($progress['frames'])) { echo "<videoFrames>\n"; foreach ($progress['frames'] as $ms => $frame) { echo "<frame>\n"; echo "<time>{$ms}</time>\n"; echo "<image>" . htmlspecialchars($urlGenerator->getFile($frame['file'], $nameOnlyPaths->videoDir())) . "</image>\n"; echo "<VisuallyComplete>{$frame['progress']}</VisuallyComplete>\n"; echo "</frame>\n"; } echo "</videoFrames>\n"; } $this->printAdditionalInformation($stepResult, false); }