function ProcessFile($file) { global $benchmark; echo "Reprocessing {$file}\n"; logMsg("Reprocessing {$file}", "./log/reprocess-{$benchmark}.log", true); $tests = array(); $entries = json_decode(gz_file_get_contents($file), true); if (isset($entries) && is_array($entries) && count($entries)) { echo 'Loaded ' . count($entries) . " results\n"; foreach ($entries as $entry) { if (!array_key_exists($entry['id'], $tests)) { $tests[$entry['id']] = array('url' => $entry['url'], 'label' => $entry['label'], 'location' => $entry['location'], 'config' => $entry['config'], 'id' => $entry['id']); } } unset($entries); } if (count($tests)) { $results = array(); foreach ($tests as &$test) { CollectTestResult($test, $results); } echo 'Writing ' . count($results) . " results\n"; rename($file, "{$file}.reprocessed"); gz_file_put_contents(str_replace('.json.gz', '.json', $file), json_encode($results)); } return $ok; }
function ResubmitTest($id) { echo "{$id} - Resubmitting..."; $testPath = './' . GetTestPath($id); if (gz_is_file("{$testPath}/testinfo.json")) { $test = json_decode(gz_file_get_contents("{$testPath}/testinfo.json"), true); if (array_key_exists('job_file', $test) && array_key_exists('location', $test) && is_file("{$testPath}/test.job")) { if ($lock = LockLocation($test['location'])) { if (copy("{$testPath}/test.job", $test['job_file'])) { $files = scandir($testPath); foreach ($files as $file) { if ($file != '.' && $file != '..' && strncasecmp($file, 'test', 4)) { if (is_file("{$testPath}/{$file}")) { unlink("{$testPath}/{$file}"); } elseif (is_dir("{$testPath}/{$file}")) { delTree("{$testPath}/{$file}"); } } } AddJobFile($test['workdir'], $test['job'], $test['priority'], false); $test['started'] = time(); unset($test['completeTime']); gz_file_put_contents("{$testPath}/testinfo.json", json_encode($test)); echo "OK"; } else { echo "Failed to copy job file"; } UnlockLocation($lock); } else { echo "Failed to lock location"; } } else { echo "Invalid test"; } } else { echo "Test not found"; } echo "\n"; }
/** * @param TestPaths $localPaths Paths for this run/step to get the CPU time for * @param int $endTime End time to consider (optional, will be retrieved from requests otherwise) * @return array */ function GetDevToolsCPUTimeForStep($localPaths, $endTime = 0) { if (!$endTime) { require_once __DIR__ . '/page_data.inc'; $runCompleted = IsTestRunComplete($localPaths->getRunNumber(), $testInfo); $pageData = loadPageStepData($localPaths, $runCompleted); if (isset($pageData) && is_array($pageData) && isset($pageData['fullyLoaded'])) { $endTime = $pageData['fullyLoaded']; } } $times = null; $ver = 3; $cacheFile = $localPaths->devtoolsCPUTimeCacheFile($ver); if (gz_is_file($cacheFile)) { $cache = json_decode(gz_file_get_contents($cacheFile), true); } if (isset($cache) && is_array($cache) && isset($cache[$endTime])) { $times = $cache[$endTime]; } else { $cpu = DevToolsGetCPUSlicesForStep($localPaths); if (isset($cpu) && is_array($cpu) && isset($cpu['main_thread']) && isset($cpu['slices'][$cpu['main_thread']]) && isset($cpu['slice_usecs'])) { $busy = 0; $times = array(); if (!$endTime && isset($cpu['total_usecs'])) { $endTime = $cpu['total_usecs'] / 1000; } foreach ($cpu['slices'][$cpu['main_thread']] as $name => $slices) { $last_slice = min(intval(ceil($endTime * 1000 / $cpu['slice_usecs'])), count($slices)); $times[$name] = 0; for ($i = 0; $i < $last_slice; $i++) { $times[$name] += $slices[$i] / 1000.0; } $busy += $times[$name]; $times[$name] = intval(round($times[$name])); } $times['Idle'] = max($endTime - intval(round($busy)), 0); } // Cache the result if (!isset($cache) || !is_array($cache)) { $cache = array(); } $cache[$endTime] = $times; gz_file_put_contents($cacheFile, json_encode($cache)); } return $times; }
function GetDevToolsCPUTime($testPath, $run, $cached, $endTime = 0) { $times = null; $ver = 1; $ver = 2; $cacheFile = "{$testPath}/{$run}.{$cached}.devToolsCPUTime.{$ver}"; if (gz_is_file($cacheFile)) { $cache = json_decode(gz_file_get_contents($cacheFile), true); } // If an end time wasn't specified, figure out what the fully loaded time is if (!$endTime) { if (GetDevToolsRequests($testPath, $run, $cached, $requests, $pageData) && isset($pageData) && is_array($pageData) && isset($pageData['fullyLoaded'])) { $endTime = $pageData['fullyLoaded']; } } if (isset($cache[$endTime])) { $times = $cache[$endTime]; } else { $slices = DevToolsGetCPUSlices($testPath, $run, $cached); if (isset($slices) && is_array($slices) && isset($slices[0]) && is_array($slices[0]) && count($slices[0])) { $times = array('Idle' => 0.0); foreach ($slices[0] as $ms => $breakdown) { if (!$endTime || $ms < $endTime) { $idle = 1.0; if (isset($breakdown) && is_array($breakdown) && count($breakdown)) { foreach ($breakdown as $event => $ms_time) { if (!isset($times[$event])) { $times[$event] = 0; } $times[$event] += $ms_time; $idle -= $ms_time; } } $times['Idle'] += $idle; } } // round the times to the nearest millisecond $total = 0; foreach ($times as $event => &$val) { $val = round($val); if ($event !== 'Idle') { $total += $val; } } if ($endTime && $endTime > $total) { $times['Idle'] = $endTime - $total; } } $cache[$endTime] = $times; gz_file_put_contents($cacheFile, json_encode($cache)); } return $times; }
if ($_REQUEST['force']) { delTree("./{$path}/"); } else { $exists = true; } } if (!$exists) { // set up the result directory $dest = './' . GetVideoPath($id); if (!is_dir($dest)) { mkdir($dest, 0777, true); } if (count($labels)) { file_put_contents("{$dest}/labels.txt", json_encode($labels)); } gz_file_put_contents("{$dest}/testinfo.json", json_encode($tests)); // kick off the actual rendering SendAsyncRequest("/video/render.php?id={$id}"); } } } // redirect to the destination page if ($id) { $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || isset($_SERVER['HTTP_SSL']) && $_SERVER['HTTP_SSL'] == 'On' ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST']; $uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\'); if ($xml) { header('Content-type: text/xml'); echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; echo "<response>\n"; echo "<statusCode>200</statusCode>\n";
/** * Remove sensitive data fields from HTTP headers (cookies and HTTP Auth) * */ function RemoveSensitiveHeaders($file) { $patterns = array('/(cookie:[ ]*)([^\\r\\n]*)/i', '/(authenticate:[ ]*)([^\\r\\n]*)/i'); $data = gz_file_get_contents($file); $data = preg_replace($patterns, '\\1XXXXXX', $data); gz_file_put_contents($file, $data); }
} $users[$user['email']] = $user; gz_file_put_contents('./dat/users.dat', json_encode($users)); // se if the user that logged in was an administrator $admin_users = GetSetting('admin_users'); if ($admin_users) { $admins = explode(',', $admin_users); foreach ($admins as $admin) { if (stripos(strtolower($user['email']), strtolower(trim($admin))) !== false) { $session = sha1(json_encode($token_data) . time()); setcookie("asid", $session, time() + 60 * 60 * 24 * 7 * 2, "/"); $sessions = json_decode(gz_file_get_contents('./dat/admin_sessions.dat'), true); if (!isset($sessions) || !is_array($sessions)) { $sessions = array(); } $sessions[$session] = $user; gz_file_put_contents('./dat/admin_sessions.dat', json_encode($sessions)); break; } } } Unlock($lock); } setcookie("google_id", $user['id'], time() + 60 * 60 * 24 * 7 * 2, "/"); setcookie("google_email", $user['email'], time() + 60 * 60 * 24 * 7 * 2, "/"); $redirect = isset($_COOKIE['page_before_google_oauth']) ? $_COOKIE['page_before_google_oauth'] : "{$protocol}://{$host}/"; header('Location: ' . $redirect); } ?>
/** * For each IP/Installer pair, keep track of the last 4 checks and if they * were within the last hour fail the request. * * @param mixed $installer */ function CheckIp($installer) { $ok = true; $ip = $_SERVER["REMOTE_ADDR"]; if (isset($ip) && strlen($ip)) { $lock = Lock("Installers", true, 5); if ($lock) { $now = time(); $file = "./tmp/installers.dat"; if (gz_is_file($file)) { $history = json_decode(gz_file_get_contents($file), true); } if (!isset($history) || !is_array($history)) { $history = array(); } if (isset($history[$ip])) { if (isset($history[$ip][$installer])) { $history[$ip][$installer][] = $now; if (count($history[$ip][$installer]) > 10) { array_shift($history[$ip][$installer]); } if (isset($history[$ip]["last-{$installer}"]) && $now - $history[$ip]["last-{$installer}"] < 3600) { $count = 0; foreach ($history[$ip][$installer] as $time) { if ($now - $time < 3600) { $count++; } } if ($count > 4) { $ok = false; } } } else { $history[$ip][$installer] = array($now); } } else { $history[$ip] = array($installer => array($now)); } $history[$ip]['last'] = $now; if ($ok) { $history[$ip]["last-{$installer}"] = $now; } // prune any agents that haven't connected in 7 days foreach ($history as $agent => $info) { if ($now - $info['last'] > 604800) { unset($history[$agent]); } } gz_file_put_contents($file, json_encode($history)); Unlock($lock); } } return $ok; }
function ProcessTest($id) { global $tempDir; global $name; global $count; global $total; $ok = false; $testPath = './' . GetTestPath($id); $restored = false; if (!is_dir($testPath)) { // try restoring the test several times in case there are network issues $attempt = 0; do { $attempt++; har_log("{$id} - restoring test ({$attempt})"); RestoreTest($id); if (is_dir($testPath)) { $restored = true; } else { sleep(1); } } while (!$restored && $attempt < 120); } if (is_dir($testPath)) { har_log("{$id} - generating HAR"); $har = GenerateHAR($id, $testPath, ['bodies' => 1, 'run' => 'median', 'cached' => 0]); if (isset($har) && strlen($har)) { gz_file_put_contents("{$tempDir}/{$id}.har", $har); unset($har); $file = "{$tempDir}/{$id}.har.gz"; if (is_file($file)) { $file = realpath($file); $remoteFile = "{$name}/{$id}.har.gz"; $bucket = 'httparchive'; har_log("{$id} - Uploading to {$remoteFile}"); if (gsUpload($file, $bucket, $remoteFile)) { $ok = true; } else { har_log("{$id} - error uploading HAR"); } unlink($file); } else { har_log("{$id} - error saving HAR"); } } else { har_log("{$id} - error generating HAR"); } // clean up the test if we restored it if ($restored) { delTree($testPath, true); } } else { har_log("{$id} - error restoring test"); } return $ok; }
/** * Calculate the progress for all of the images in a given directory */ function GetVisualProgress($testPath, $run, $cached, $options = null, $end = null, $startOffset = null) { $frames = null; if (substr($testPath, 0, 1) !== '.') { $testPath = './' . $testPath; } $testInfo = GetTestInfo($testPath); $completed = IsTestRunComplete($run, $testInfo); $video_directory = "{$testPath}/video_{$run}"; if ($cached) { $video_directory .= '_cached'; } $cache_file = "{$testPath}/{$run}.{$cached}.visual.dat"; if (!isset($startOffset)) { $startOffset = 0; } $dirty = false; $current_version = VIDEO_CODE_VERSION; if (isset($end)) { if (is_numeric($end)) { $end = (int) ($end * 1000); } else { unset($end); } } if (!isset($end) && !isset($options) && gz_is_file($cache_file)) { $frames = json_decode(gz_file_get_contents($cache_file), true); if (!array_key_exists('frames', $frames) || !array_key_exists('version', $frames)) { unset($frames); } elseif (array_key_exists('version', $frames) && $frames['version'] !== $current_version) { unset($frames); } } if ((!isset($frames) || !count($frames)) && is_dir($video_directory)) { $frames = array('version' => $current_version); $frames['frames'] = array(); $dirty = true; $base_path = substr($video_directory, 1); $files = scandir($video_directory); $last_file = null; $first_file = null; $previous_file = null; foreach ($files as $file) { if (strpos($file, 'frame_') !== false && strpos($file, '.hist') === false) { $parts = explode('_', $file); if (count($parts) >= 2) { $time = (int) $parts[1] * 100 - $startOffset; if ($time >= 0 && (!isset($end) || $time <= $end)) { if (isset($previous_file) && !array_key_exists(0, $frames['frames']) && $time > 0) { $frames['frames'][0] = array('path' => "{$base_path}/{$previous_file}", 'file' => $previous_file); $first_file = $previous_file; } elseif (!isset($first_file)) { $first_file = $file; } $last_file = $file; $frames['frames'][$time] = array('path' => "{$base_path}/{$file}", 'file' => $file); } $previous_file = $file; } } elseif (strpos($file, 'ms_') !== false && strpos($file, '.hist') === false) { $parts = explode('_', $file); if (count($parts) >= 2) { $time = intval($parts[1]) - $startOffset; if ($time >= 0 && (!isset($end) || $time <= $end)) { if (isset($previous_file) && !array_key_exists(0, $frames['frames']) && $time > 0) { $frames['frames'][0] = array('path' => "{$base_path}/{$previous_file}", 'file' => $previous_file); $first_file = $previous_file; } elseif (!isset($first_file)) { $first_file = $file; } $last_file = $file; $frames['frames'][$time] = array('path' => "{$base_path}/{$file}", 'file' => $file); } $previous_file = $file; } } } if (count($frames['frames']) == 1) { foreach ($frames['frames'] as $time => &$frame) { $frame['progress'] = 100; $frames['complete'] = $time; } } elseif (isset($first_file) && strlen($first_file) && isset($last_file) && strlen($last_file) && count($frames['frames'])) { $start_histogram = GetImageHistogram("{$video_directory}/{$first_file}", $options); $final_histogram = GetImageHistogram("{$video_directory}/{$last_file}", $options); foreach ($frames['frames'] as $time => &$frame) { $histogram = GetImageHistogram("{$video_directory}/{$frame['file']}", $options); $frame['progress'] = CalculateFrameProgress($histogram, $start_histogram, $final_histogram, 5); if ($frame['progress'] == 100 && !array_key_exists('complete', $frames)) { $frames['complete'] = $time; } } } } if (isset($frames) && !array_key_exists('SpeedIndex', $frames)) { $dirty = true; $frames['SpeedIndex'] = CalculateSpeedIndex($frames); } if (isset($frames)) { $frames['visualComplete'] = 0; foreach ($frames['frames'] as $time => &$frame) { if ($frame['progress'] > 0 && !array_key_exists('startRender', $frames)) { $frames['startRender'] = $time; } if ($frame['progress'] == 100) { $frames['visualComplete'] = $time; break; } } } $devTools = GetDevToolsProgress($testPath, $run, $cached); if (isset($devTools)) { if (!isset($frames)) { $frames = array(); } $frames['DevTools'] = $devTools; } if ($completed && !isset($end) && !isset($options) && $dirty && isset($frames) && count($frames)) { gz_file_put_contents($cache_file, json_encode($frames)); } return $frames; }
foreach ($lines as $line) { if (preg_match('/(?P<metric>[a-zA-Z0-9\\._\\-\\[\\]{}():;<>+$#@!~]+)=(?P<value>[0-9]*(\\.[0-9]*)?)/', $line, $matches)) { $metric = trim($matches['metric']); $value = trim($matches['value']); if (strpos($value, '.') === false) { $value = intval($value); } else { $value = floatval($value); } if (strlen($metric) && strlen($value)) { $metrics[$metric] = $value; } } } if (count($metrics)) { gz_file_put_contents("{$testPath}/{$run}_metrics.json", json_encode($metrics)); } } // create the test info files SaveTestInfo($id, $test); // write out the ini file $testInfo = "[test]\r\n"; $testInfo .= "fvonly=1\r\n"; $testInfo .= "runs={$run}\r\n"; $testInfo .= "location=Imported Test\r\n"; $testInfo .= "loc=Import\r\n"; $testInfo .= "id={$id}\r\n"; if ($test['video']) { $testInfo .= "video=1\r\n"; } $testInfo .= "connectivity=Unknown\r\n";
$test['label'] = 'PageSpeed Service Comparison'; if (array_key_exists('url', $test) && strlen($test['url'])) { $test['label'] .= ' for ' . $test['url']; } $test['view'] = 'pss'; if (!is_dir($test['path'])) { mkdir($test['path'], 0777, true); } SaveTestInfo($test['id'], $test); // write out the bulk test data $tests = array(); $tests['variations'] = array(); $tests['urls'] = array(); $tests['urls'][] = array('u' => $test['url'], 'l' => 'Original', 'id' => $original); $tests['urls'][] = array('u' => $test['url'], 'l' => 'Optimized', 'id' => $optimized); gz_file_put_contents("./{$test['path']}/bulk.json", json_encode($tests)); // redirect $url = "/results.php?test={$test['id']}"; if (FRIENDLY_URLS) { $url = "/result/{$test['id']}/"; } $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || isset($_SERVER['HTTP_SSL']) && $_SERVER['HTTP_SSL'] == 'On' ? 'https' : 'http'; header("Location: {$protocol}://{$_SERVER['HTTP_HOST']}{$url}"); } else { echo "Invalid Test. Should be /create_pss.php?original=<original test ID>&optimized=<optimized test ID>"; } } else { echo "Invalid Test IDs. Should be /create_pss.php?original=<original test ID>&optimized=<optimized test ID>"; } } else { echo "Invalid request. Should be /create_pss.php?original=<original test ID>&optimized=<optimized test ID>";
/** * If we have a timeline, figure out what each thread was doing at each point in time. * Basically CPU utilization from the timeline. * * returns 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 DevToolsGetCPUSlices($testPath, $run, $cached) { $count = 0; $slices = null; $devTools = array(); $startOffset = null; $ver = 1; $cacheFile = "{$testPath}/{$run}.{$cached}.devToolsCPUSlices.{$ver}"; if (gz_is_file($cacheFile)) { $slices = json_decode(gz_file_get_contents($cacheFile), true); } if (!isset($slices)) { GetTimeline($testPath, $run, $cached, $devTools, $startOffset); if (isset($devTools) && is_array($devTools) && count($devTools)) { // Do a first pass to get the start and end times as well as the number of threads $threads = array(0 => true); $startTime = 0; $endTime = 0; foreach ($devTools as &$entry) { if (isset($entry['method']) && $entry['method'] == 'Timeline.eventRecorded' && isset($entry['params']['record'])) { $start = DevToolsEventTime($entry); if ($start && (!$startTime || $start < $startTime)) { $startTime = $start; } $end = DevToolsEventEndTime($entry); if ($end && (!$endTime || $end > $endTime)) { $endTime = $end; } $thread = isset($entry['params']['record']['thread']) ? $entry['params']['record']['thread'] : 0; $threads[$thread] = true; } } // create time slice arrays for each thread $slices = array(); foreach ($threads as $id => $bogus) { $slices[$id] = array(); } // create 1ms time slices for the full time if ($endTime > $startTime) { $startTime = floor($startTime); $endTime = ceil($endTime); for ($i = $startTime; $i <= $endTime; $i++) { $ms = intval($i - $startTime); foreach ($threads as $id => $bogus) { $slices[$id][$ms] = array(); } } // Go through each element and account for the time foreach ($devTools as &$entry) { if (isset($entry['method']) && $entry['method'] == 'Timeline.eventRecorded' && isset($entry['params']['record'])) { $count += DevToolsGetEventTimes($entry['params']['record'], $startTime, $slices); } } } } if ($count) { // remove any threads that didn't have actual slices populated $emptyThreads = array(); foreach ($slices as $thread => &$records) { $is_empty = true; foreach ($records as $ms => &$values) { if (count($values)) { $is_empty = false; break; } } if ($is_empty) { $emptyThreads[] = $thread; } } if (count($emptyThreads)) { foreach ($emptyThreads as $thread) { unset($slices[$thread]); } } gz_file_put_contents($cacheFile, json_encode($slices)); } else { $slices = null; } } return $slices; }
/** * Create the various aggregations for the given data chunk * * @param mixed $info * @param mixed $data * @param mixed $benchmark */ function CreateAggregates(&$info, &$data, $benchmark, $run_time, $options) { foreach ($info['metrics'] as $metric) { $metric_file = "./results/benchmarks/{$benchmark}/aggregate/{$metric}.json"; if (gz_is_file($metric_file)) { $agg_data = json_decode(gz_file_get_contents($metric_file), true); } else { $agg_data = array(); } AggregateMetric($metric, $info, $data, $run_time, $agg_data, $options); gz_file_put_contents($metric_file, @json_encode($agg_data)); unset($agg_data); if (array_key_exists('labels', $info) && count($info['labels']) <= 20) { $metric_file = "./results/benchmarks/{$benchmark}/aggregate/{$metric}.labels.json"; if (gz_is_file($metric_file)) { $agg_data = json_decode(gz_file_get_contents($metric_file), true); } else { $agg_data = array(); } AggregateMetricByLabel($metric, $info, $data, $run_time, $agg_data, $options); gz_file_put_contents($metric_file, json_encode($agg_data)); unset($agg_data); } } }
/** * Calculate the progress for all of the images in a given directory */ function GetVisualProgress($testPath, $run, $cached, $options = null, $end = null, $startOffset = null) { $frames = null; if (substr($testPath, 0, 1) !== '.') { $testPath = './' . $testPath; } $testInfo = GetTestInfo($testPath); $completed = IsTestRunComplete($run, $testInfo); $video_directory = "{$testPath}/video_{$run}"; if ($cached) { $video_directory .= '_cached'; } $cache_file = "{$testPath}/{$run}.{$cached}.visual.dat"; if (!isset($startOffset)) { $startOffset = 0; } $visual_data_file = "{$testPath}/llab_{$run}.{$cached}.visual.dat"; if (gz_is_file($visual_data_file)) { $visual_data = json_decode(gz_file_get_contents($visual_data_file), true); // see if we are processing an externally-uploaded visual data file if (isset($visual_data['timespans']['page_load']['startOffset'])) { $startOffset += $visual_data['timespans']['page_load']['startOffset']; } } $dirty = false; $current_version = VIDEO_CODE_VERSION; if (isset($end)) { if (is_numeric($end)) { $end = (int) ($end * 1000); } else { unset($end); } } if (!isset($end) && !isset($options) && gz_is_file($cache_file)) { $frames = json_decode(gz_file_get_contents($cache_file), true); if (!array_key_exists('frames', $frames) || !array_key_exists('version', $frames)) { unset($frames); } elseif (array_key_exists('version', $frames) && $frames['version'] !== $current_version) { unset($frames); } } $base_path = substr($video_directory, 1); if ((!isset($frames) || !count($frames)) && (is_dir($video_directory) || gz_is_file("{$testPath}/{$run}.{$cached}.histograms.json"))) { $frames = array('version' => $current_version); $frames['frames'] = array(); $dirty = true; if (is_dir($video_directory)) { $files = scandir($video_directory); $last_file = null; $first_file = null; $previous_file = null; foreach ($files as $file) { if (strpos($file, 'frame_') !== false && strpos($file, '.hist') === false) { $parts = explode('_', $file); if (count($parts) >= 2) { $time = (int) $parts[1] * 100 - $startOffset; if ($time >= 0 && (!isset($end) || $time <= $end)) { if (isset($previous_file) && !array_key_exists(0, $frames['frames']) && $time > 0) { $frames['frames'][0] = array('path' => "{$base_path}/{$previous_file}", 'file' => $previous_file); $first_file = $previous_file; } elseif (!isset($first_file)) { $first_file = $file; } $last_file = $file; $frames['frames'][$time] = array('path' => "{$base_path}/{$file}", 'file' => $file); } $previous_file = $file; } } elseif (strpos($file, 'ms_') !== false && strpos($file, '.hist') === false) { $parts = explode('_', $file); if (count($parts) >= 2) { $time = intval($parts[1]) - $startOffset; if ($time >= 0 && (!isset($end) || $time <= $end)) { if (isset($previous_file) && !array_key_exists(0, $frames['frames']) && $time > 0) { $frames['frames'][0] = array('path' => "{$base_path}/{$previous_file}", 'file' => $previous_file); $first_file = $previous_file; } elseif (!isset($first_file)) { $first_file = $file; } $last_file = $file; $frames['frames'][$time] = array('path' => "{$base_path}/{$file}", 'file' => $file); } $previous_file = $file; } } } if (count($frames['frames']) == 1) { foreach ($frames['frames'] as $time => &$frame) { $frame['progress'] = 100; $frames['complete'] = $time; } } elseif (isset($first_file) && strlen($first_file) && isset($last_file) && strlen($last_file) && count($frames['frames'])) { $histograms = null; if (gz_is_file("{$testPath}/{$run}.{$cached}.histograms.json")) { $histograms = json_decode(gz_file_get_contents("{$testPath}/{$run}.{$cached}.histograms.json"), true); } $start_histogram = GetImageHistogram("{$video_directory}/{$first_file}", $options, $histograms); $final_histogram = GetImageHistogram("{$video_directory}/{$last_file}", $options, $histograms); foreach ($frames['frames'] as $time => &$frame) { $histogram = GetImageHistogram("{$video_directory}/{$frame['file']}", $options, $histograms); $frame['progress'] = CalculateFrameProgress($histogram, $start_histogram, $final_histogram, 5); if ($frame['progress'] == 100 && !array_key_exists('complete', $frames)) { $frames['complete'] = $time; } } } } elseif (gz_is_file("{$testPath}/{$run}.{$cached}.histograms.json")) { $raw = json_decode(gz_file_get_contents("{$testPath}/{$run}.{$cached}.histograms.json"), true); $histograms = array(); foreach ($raw as $h) { if (isset($h['time']) && isset($h['histogram'])) { $histograms[$h['time']] = $h['histogram']; } } ksort($histograms, SORT_NUMERIC); $final_histogram = end($histograms); $start_histogram = reset($histograms); foreach ($histograms as $time => $histogram) { $frames['frames'][$time] = array(); $progress = CalculateFrameProgress($histogram, $start_histogram, $final_histogram, 5); $frames['frames'][$time]['progress'] = $progress; if ($progress == 100 && !isset($frames['complete'])) { $frames['complete'] = $time; } } } } if (isset($frames) && !array_key_exists('SpeedIndex', $frames)) { $dirty = true; $frames['SpeedIndex'] = CalculateSpeedIndex($frames); } if (isset($frames)) { $frames['visualComplete'] = 0; foreach ($frames['frames'] as $time => &$frame) { if ($frame['progress'] > 0 && !array_key_exists('startRender', $frames)) { $frames['startRender'] = $time; } if (!$frames['visualComplete'] && $frame['progress'] == 100) { $frames['visualComplete'] = $time; } // fix up the frame paths in case we have a cached version referencing a relay path if (isset($frame['path'])) { $frame['path'] = $base_path . '/' . basename($frame['path']); } } } if ($completed && !isset($end) && !isset($options) && $dirty && isset($frames) && count($frames)) { gz_file_put_contents($cache_file, json_encode($frames)); } return $frames; }
if (strlen($test['label']) && strlen($variation['l'])) { $test['label'] .= ' - ' . $variation['l']; } $url = CreateUrlVariation($entry['u'], $variation['q']); if ($url) { ValidateParameters($testData, $locations, $error, $url); $entry['v'][$variation_index] = CreateTest($testData, $url); } } $testCount++; } } // write out the list of urls and the test ID for each if ($testCount) { $path = GetTestPath($test['id']); gz_file_put_contents("./{$path}/bulk.json", json_encode($bulk)); } else { $error = 'Urls could not be submitted for testing'; } } else { $error = "No valid urls submitted for bulk testing"; } } else { $test['id'] = CreateTest($test, $test['url']); if (!$test['id'] && !strlen($error)) { $error = 'Error submitting url for testing'; } } } } // redirect the browser to the test results page
function DevToolsGetConsoleLog($testPath, $run, $cached) { $console_log = null; $cachedText = ''; if ($cached) { $cachedText = '_Cached'; } $console_log_file = "{$testPath}/{$run}{$cachedText}_console_log.json"; if (gz_is_file($console_log_file)) { $console_log = json_decode(gz_file_get_contents($console_log_file), true); } elseif (gz_is_file("{$testPath}/{$run}{$cachedText}_devtools.json")) { $console_log = array(); $startOffset = null; if (GetDevToolsEvents('Console.messageAdded', $testPath, $run, $cached, $events, $startOffset) && is_array($events) && count($events)) { foreach ($events as $event) { if (is_array($event) && array_key_exists('message', $event) && is_array($event['message'])) { $console_log[] = $event['message']; } } } gz_file_put_contents($console_log_file, json_encode($console_log)); } return $console_log; }