/**
* 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;
}
Esempio n. 2
0
function GetLastFrameHistogram($test, $run)
{
    $histogram = null;
    $testPath = GetTestPath($test);
    $videoPath = "./{$testPath}/video_{$run}";
    $files = glob("{$videoPath}/*.jpg");
    if ($files) {
        rsort($files);
        $lastFrame = $files[0];
        if (gz_is_file("{$testPath}/{$run}.0.histograms.json")) {
            $histograms = json_decode(gz_file_get_contents("{$testPath}/{$run}.0.histograms.json"), true);
        }
        $histogram = GetImageHistogram($lastFrame, null, $histograms);
    }
    return $histogram;
}
Esempio n. 3
0
/**
* Recursively compress the text files in the given directory and all directories under it
*     
* @param mixed $dir
*/
function CheckDir($dir, $startWith = '')
{
    $started = false;
    if (!strlen($startWith)) {
        $started = true;
    }
    // compress the text data files
    $f = scandir($dir);
    foreach ($f as $file) {
        if (!$started && $file == $startWith) {
            $started = true;
        }
        if ($started) {
            if (gz_is_file("{$dir}/{$file}/testinfo.json")) {
                CheckTest("{$dir}/{$file}");
            } elseif (is_dir("{$dir}/{$file}") && $file != '.' && $file != '..') {
                CheckDir("{$dir}/{$file}");
            }
        }
    }
}
Esempio n. 4
0
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";
}
Esempio n. 5
0
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;
}
/**
* 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;
}
Esempio n. 7
0
<?php

include 'common.inc';
$file = "{$testPath}/{$_GET['file']}";
if (isset($_GET['file']) && strlen($_GET['file']) && strpos($_GET['file'], '/') === false && strpos($_GET['file'], '\\') === false && strpos($_GET['file'], '..') === false && strpos($_GET['file'], 'testinfo') === false && gz_is_file($file)) {
    header("Content-disposition: attachment; filename={$_GET['file']}");
    if (strpos($_GET['file'], 'pagespeed') !== false || strpos($_GET['file'], '.json') !== false) {
        header("Content-type: application/json");
    } else {
        header("Content-type: application/octet-stream");
    }
    gz_readfile_chunked($file);
} else {
    header("HTTP/1.0 404 Not Found");
}
Esempio n. 8
0
    $labelHeight = 0;
}
$start = microtime(true);
// if FreeType isn't supported we can't draw text
$gdinfo = gd_info();
if (!isset($gdinfo['FreeType Support']) || !$gdinfo['FreeType Support']) {
    $labelHeight = 0;
    $timeHeight = 0;
}
// Load the information about the video that needs rendering
if (isset($_REQUEST['id'])) {
    $videoId = trim($_REQUEST['id']);
    $videoPath = './' . GetVideoPath($_REQUEST['id']);
    if (!is_file("{$videoPath}/video.ini")) {
        $optionsFile = "{$videoPath}/testinfo.json";
        if (gz_is_file($optionsFile)) {
            $tests = json_decode(gz_file_get_contents($optionsFile), true);
            if (isset($tests) && !is_array($tests)) {
                unset($tests);
            }
        }
    }
}
// Render the video
if (isset($tests) && count($tests)) {
    $lock = Lock("video-{$videoId}", false, 600);
    if ($lock) {
        RenderVideo($tests);
        if (is_file("{$videoPath}/render.mp4")) {
            rename("{$videoPath}/render.mp4", "{$videoPath}/video.mp4");
        }
Esempio n. 9
0
/**
 * @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;
}
Esempio n. 10
0
<?php

/*
  To update the timeline, clone the inspector from a chromium build: out\Release\resources\inspector
*/
chdir('..');
include 'common.inc';
$newTimeline = gz_is_file("{$testPath}/{$run}{$cachedText}_trace.json");
$timelineUrlParam = "/getTimeline.php?timeline=t:{$id},r:{$run},c:{$cached}";
?>
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
  html, body{min-height: 100% !important; height: 100%;}
  body {margin:0px;padding:0px;overflow:hidden;}
  #devtools {overflow:hidden;height:100%;width:100%}
</style>
</head>
<body>
<script>
function DevToolsLoaded() {
  var devTools = document.getElementById("devtools").contentWindow;
<?php 
if (!$newTimeline) {
    echo "devTools.InspectorFrontendAPI._runOnceLoaded(function(){(devTools.WebInspector.inspectorView.showPanel(\"timeline\")).loadFromURL(\"{$timelineUrlParam}\");});\n";
}
?>
}
</script>
<?php 
 /**
  * @param TestStepResult $stepResult
  * @return string Markup with links
  */
 private function _getNetlogLinks($stepResult)
 {
     $localPaths = $stepResult->createTestPaths();
     if (!gz_is_file($localPaths->netlogFile())) {
         return "";
     }
     $urlGenerator = $stepResult->createUrlGenerator("", FRIENDLY_URLS);
     $zipUrl = $urlGenerator->getGZip($stepResult->createTestPaths("")->netlogFile());
     return "<br><br><a href=\"{$zipUrl}\" title=\"Download Network Log\">Net Log</a>";
 }
Esempio n. 12
0
/**
* Build the data set
* 
* @param mixed $pageData
*/
function BuildHAR(&$pageData, $id, $testPath, $options)
{
    $result = array();
    $entries = array();
    $result['log'] = array();
    $result['log']['version'] = '1.1';
    $result['log']['creator'] = array('name' => 'WebPagetest', 'version' => VER_WEBPAGETEST);
    $result['log']['pages'] = array();
    foreach ($pageData as $run => $pageRun) {
        foreach ($pageRun as $cached => $data) {
            $cached_text = '';
            if ($cached) {
                $cached_text = '_Cached';
            }
            if (!array_key_exists('browser', $result['log'])) {
                $result['log']['browser'] = array('name' => $data['browser_name'], 'version' => $data['browser_version']);
            }
            $pd = array();
            $pd['startedDateTime'] = msdate($data['date']);
            $pd['title'] = "Run {$run}, ";
            if ($cached) {
                $pd['title'] .= "Repeat View";
            } else {
                $pd['title'] .= "First View";
            }
            $pd['title'] .= " for " . $data['URL'];
            $pd['id'] = "page_{$run}_{$cached}";
            $pd['pageTimings'] = array('onLoad' => $data['docTime'], 'onContentLoad' => -1, '_startRender' => $data['render']);
            // add the pagespeed score
            if (gz_is_file("{$testPath}/{$run}{$cached_text}_pagespeed.txt")) {
                $pagespeed_data = LoadPageSpeedData("{$testPath}/{$run}{$cached_text}_pagespeed.txt");
                if ($pagespeed_data) {
                    $score = GetPageSpeedScore(null, $pagespeed_data);
                    if (strlen($score)) {
                        $pd['_pageSpeed'] = array('score' => $score, 'result' => $pagespeed_data);
                    }
                }
            }
            // dump all of our metrics into the har data as custom fields
            foreach ($data as $name => $value) {
                if (!is_array($value)) {
                    $pd["_{$name}"] = $value;
                }
            }
            // add the page-level ldata to the result
            $result['log']['pages'][] = $pd;
            // now add the object-level data to the result
            $secure = false;
            $haveLocations = false;
            $requests = getRequests($id, $testPath, $run, $cached, $secure, $haveLocations, false, true);
            foreach ($requests as &$r) {
                $entry = array();
                $entry['pageref'] = $pd['id'];
                $entry['startedDateTime'] = msdate((double) $data['date'] + $r['load_start'] / 1000.0);
                $entry['time'] = $r['all_ms'];
                $request = array();
                $request['method'] = $r['method'];
                $protocol = $r['is_secure'] ? 'https://' : 'http://';
                $request['url'] = $protocol . $r['host'] . $r['url'];
                $request['headersSize'] = -1;
                $request['bodySize'] = -1;
                $request['cookies'] = array();
                $request['headers'] = array();
                $ver = '';
                $headersSize = 0;
                if (isset($r['headers']) && isset($r['headers']['request'])) {
                    foreach ($r['headers']['request'] as &$header) {
                        $headersSize += strlen($header) + 2;
                        // add 2 for the \r\n that is on the raw headers
                        $pos = strpos($header, ':');
                        if ($pos > 0) {
                            $name = trim(substr($header, 0, $pos));
                            $val = trim(substr($header, $pos + 1));
                            if (strlen($name)) {
                                $request['headers'][] = array('name' => $name, 'value' => $val);
                            }
                            // parse out any cookies
                            if (!strcasecmp($name, 'cookie')) {
                                $cookies = explode(';', $val);
                                foreach ($cookies as &$cookie) {
                                    $pos = strpos($cookie, '=');
                                    if ($pos > 0) {
                                        $name = (string) trim(substr($cookie, 0, $pos));
                                        $val = (string) trim(substr($cookie, $pos + 1));
                                        if (strlen($name)) {
                                            $request['cookies'][] = array('name' => $name, 'value' => $val);
                                        }
                                    }
                                }
                            }
                        } else {
                            $pos = strpos($header, 'HTTP/');
                            if ($pos >= 0) {
                                $ver = (string) trim(substr($header, $pos + 5, 3));
                            }
                        }
                    }
                }
                if ($headersSize) {
                    $request['headersSize'] = $headersSize;
                }
                $request['httpVersion'] = $ver;
                $request['queryString'] = array();
                $parts = parse_url($request['url']);
                if (isset($parts['query'])) {
                    $qs = array();
                    parse_str($parts['query'], $qs);
                    foreach ($qs as $name => $val) {
                        $request['queryString'][] = array('name' => (string) $name, 'value' => (string) $val);
                    }
                }
                if (!strcasecmp(trim($request['method']), 'post')) {
                    $request['postData'] = array();
                    $request['postData']['mimeType'] = '';
                    $request['postData']['text'] = '';
                }
                $entry['request'] = $request;
                $response = array();
                $response['status'] = (int) $r['responseCode'];
                $response['statusText'] = '';
                $response['headersSize'] = -1;
                $response['bodySize'] = (int) $r['objectSize'];
                $response['headers'] = array();
                $ver = '';
                $loc = '';
                $headersSize = 0;
                if (isset($r['headers']) && isset($r['headers']['response'])) {
                    foreach ($r['headers']['response'] as &$header) {
                        $headersSize += strlen($header) + 2;
                        // add 2 for the \r\n that is on the raw headers
                        $pos = strpos($header, ':');
                        if ($pos > 0) {
                            $name = (string) trim(substr($header, 0, $pos));
                            $val = (string) trim(substr($header, $pos + 1));
                            if (strlen($name)) {
                                $response['headers'][] = array('name' => $name, 'value' => $val);
                            }
                            if (!strcasecmp($name, 'location')) {
                                $loc = (string) $val;
                            }
                        } else {
                            $pos = strpos($header, 'HTTP/');
                            if ($pos >= 0) {
                                $ver = (string) trim(substr($header, $pos + 5, 3));
                            }
                        }
                    }
                }
                if ($headersSize) {
                    $response['headersSize'] = $headersSize;
                }
                $response['httpVersion'] = $ver;
                $response['redirectURL'] = $loc;
                $response['content'] = array();
                $response['content']['size'] = (int) $r['objectSize'];
                if (isset($r['contentType']) && strlen($r['contentType'])) {
                    $response['content']['mimeType'] = (string) $r['contentType'];
                } else {
                    $response['content']['mimeType'] = '';
                }
                // unsupported fields that are required
                $response['cookies'] = array();
                $entry['response'] = $response;
                $entry['cache'] = (object) array();
                $timings = array();
                $timings['blocked'] = -1;
                $timings['dns'] = (int) $r['dns_ms'];
                if (!$timings['dns']) {
                    $timings['dns'] = -1;
                }
                // HAR did not have an ssl time until version 1.2 .  For
                // backward compatibility, "connect" includes "ssl" time.
                // WepbageTest's internal representation does not assume any
                // overlap, so we must add our connect and ssl time to get the
                // connect time expected by HAR.
                $timings['connect'] = durationOfInterval($r['connect_ms']) + durationOfInterval($r['ssl_ms']);
                if (!$timings['connect']) {
                    $timings['connect'] = -1;
                }
                $timings['ssl'] = (int) $r['ssl_ms'];
                if (!$timings['ssl']) {
                    $timings['ssl'] = -1;
                }
                // TODO(skerner): WebpageTest's data model has no way to
                // represent the difference between the states HAR calls
                // send (time required to send HTTP request to the server)
                // and wait (time spent waiting for a response from the server).
                // We lump both into "wait".  Issue 24* tracks this work.  When
                // it is resolved, read the real values for send and wait
                // instead of using the request's TTFB.
                // *: http://code.google.com/p/webpagetest/issues/detail?id=24
                $timings['send'] = 0;
                $timings['wait'] = (int) $r['ttfb_ms'];
                $timings['receive'] = (int) $r['download_ms'];
                $entry['timings'] = $timings;
                // The HAR spec defines time as the sum of the times in the
                // timings object, excluding any unknown (-1) values and ssl
                // time (which is included in "connect", for backward
                // compatibility with tools written before "ssl" was defined
                // in HAR version 1.2).
                $entry['time'] = 0;
                foreach ($timings as $timingKey => $duration) {
                    if ($timingKey != 'ssl' && $duration != UNKNOWN_TIME) {
                        $entry['time'] += $duration;
                    }
                }
                if (array_key_exists('custom_rules', $r)) {
                    $entry['_custom_rules'] = $r['custom_rules'];
                }
                // dump all of our metrics into the har data as custom fields
                foreach ($r as $name => $value) {
                    if (!is_array($value)) {
                        $entry["_{$name}"] = $value;
                    }
                }
                // add it to the list of entries
                $entries[] = $entry;
            }
            // add the bodies to the requests
            if (isset($options['bodies']) && $options['bodies']) {
                $bodies_file = $testPath . '/' . $run . $cached_text . '_bodies.zip';
                if (is_file($bodies_file)) {
                    $zip = new ZipArchive();
                    if ($zip->open($bodies_file) === TRUE) {
                        for ($i = 0; $i < $zip->numFiles; $i++) {
                            $index = intval($zip->getNameIndex($i), 10) - 1;
                            if (array_key_exists($index, $entries)) {
                                $entries[$index]['response']['content']['text'] = utf8_encode($zip->getFromIndex($i));
                            }
                        }
                    }
                }
            }
        }
    }
    $result['log']['entries'] = $entries;
    return $result;
}
/**
* 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;
}
Esempio n. 14
0
/**
* Load the test data and keep just the median run for each config
*/
function LoadMedianData($benchmark, $test_time)
{
    global $median_data;
    global $raw_data;
    if (!isset($median_data)) {
        // see if we have a custom metric to use to calculate the median for the given benchmark
        $info = GetBenchmarkInfo($benchmark);
        $median_metric = 'docTime';
        if (isset($info) && is_array($info) && array_key_exists('options', $info) && array_key_exists('median_run', $info['options'])) {
            $median_metric = $info['options']['median_run'];
        }
        $date = gmdate('Ymd_Hi', $test_time);
        $data_file = "./results/benchmarks/{$benchmark}/data/{$date}.json";
        $key = "{$benchmark}-{$date}";
        if (gz_is_file($data_file)) {
            if (!array_key_exists($key, $raw_data)) {
                $raw_data[$key] = json_decode(gz_file_get_contents($data_file), true);
                usort($raw_data[$key], 'RawDataCompare');
            }
            if (count($raw_data[$key])) {
                $tests = array();
                // group the results by test ID
                foreach ($raw_data[$key] as &$row) {
                    if (array_key_exists($median_metric, $row) && ($row['result'] == 0 || $row['result'] == 99999)) {
                        $id = $row['id'];
                        $cached = $row['cached'];
                        $key = "{$id}-{$cached}";
                        if (!array_key_exists($key, $tests)) {
                            $tests[$key] = array();
                        }
                        $tests[$key][] = $row;
                    }
                }
                // extract just the median runs
                $median_data = array();
                foreach ($tests as &$test) {
                    $times = array();
                    foreach ($test as $row) {
                        $times[] = $row[$median_metric];
                    }
                    $median_run_index = 0;
                    $count = count($times);
                    if ($count > 1) {
                        asort($times);
                        $medianIndex = (int) floor(((double) $count + 1.0) / 2.0);
                        $current = 0;
                        foreach ($times as $index => $time) {
                            $current++;
                            if ($current == $medianIndex) {
                                $median_run_index = $index;
                                break;
                            }
                        }
                    }
                    $row = $test[$median_run_index];
                    if (array_key_exists('cached', $row) && array_key_exists('url', $row) && array_key_exists('config', $row) && array_key_exists('location', $row)) {
                        $url = $row['url'];
                        if (array_key_exists('label', $row) && strlen($row['label'])) {
                            $url = $row['label'];
                        }
                        $config = $row['config'];
                        $location = $row['location'];
                        $cached = $row['cached'];
                        if (isset($loc_aliases) && count($loc_aliases)) {
                            foreach ($loc_aliases as $loc_name => &$aliases) {
                                foreach ($aliases as $alias) {
                                    if ($location == $alias) {
                                        $location = $loc_name;
                                        break 2;
                                    }
                                }
                            }
                        }
                        if (!array_key_exists($config, $median_data)) {
                            $median_data[$config] = array();
                        }
                        if (!array_key_exists($location, $median_data[$config])) {
                            $median_data[$config][$location] = array();
                        }
                        if (!array_key_exists($cached, $median_data[$config][$location])) {
                            $median_data[$config][$location][$cached] = array();
                        }
                        $median_data[$config][$location][$cached][$url] = $row;
                    }
                }
            }
        }
    }
}
Esempio n. 15
0
/**
* 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;
}
Esempio n. 16
0
/**
* Send back the data for a batch test (just the list of test ID's)
* 
* @param mixed $id
* @param mixed $testPath
*/
function BatchResult($id, $testPath)
{
    header('Content-type: text/xml');
    echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    echo "<response>";
    if (strlen($_REQUEST['r'])) {
        echo "<requestId>{$_REQUEST['r']}</requestId>";
    }
    $tests = null;
    if (gz_is_file("{$testPath}/bulk.json")) {
        $tests = json_decode(gz_file_get_contents("{$testPath}/bulk.json"), true);
    } elseif (gz_is_file("{$testPath}/tests.json")) {
        $legacyData = json_decode(gz_file_get_contents("{$testPath}/tests.json"), true);
        $tests = array();
        $tests['variations'] = array();
        $tests['urls'] = array();
        foreach ($legacyData as &$legacyTest) {
            $tests['urls'][] = array('u' => $legacyTest['url'], 'id' => $legacyTest['id']);
        }
    }
    if (count($tests['urls'])) {
        echo "<statusCode>200</statusCode>";
        echo "<statusText>Ok</statusText>";
        if (strlen($_REQUEST['r'])) {
            echo "<requestId>{$_REQUEST['r']}</requestId>";
        }
        $host = $_SERVER['HTTP_HOST'];
        $uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
        echo "<data>";
        foreach ($tests['urls'] as &$test) {
            echo "<test>";
            echo "<testId>{$test['id']}</testId>";
            echo "<testUrl>" . xml_entities($test['u']) . "</testUrl>";
            echo "<xmlUrl>http://{$host}{$uri}/xmlResult/{$test['id']}/</xmlUrl>";
            echo "<userUrl>http://{$host}{$uri}/result/{$test['id']}/</userUrl>";
            echo "<summaryCSV>http://{$host}{$uri}/result/{$test['id']}/page_data.csv</summaryCSV>";
            echo "<detailCSV>http://{$host}{$uri}/result/{$test['id']}/requests.csv</detailCSV>";
            echo "</test>";
            // go through all of the variations as well
            foreach ($test['v'] as $variationIndex => $variationId) {
                echo "<test>";
                echo "<testId>{$variationId}</testId>";
                echo "<testUrl>" . xml_entities(CreateUrlVariation($test['u'], $tests['variations'][$variationIndex]['q'])) . "</testUrl>";
                echo "<xmlUrl>http://{$host}{$uri}/xmlResult/{$variationId}/</xmlUrl>";
                echo "<userUrl>http://{$host}{$uri}/result/{$variationId}/</userUrl>";
                echo "<summaryCSV>http://{$host}{$uri}/result/{$variationId}/page_data.csv</summaryCSV>";
                echo "<detailCSV>http://{$host}{$uri}/result/{$variationId}/requests.csv</detailCSV>";
                echo "</test>";
            }
        }
        echo "</data>";
    } else {
        echo "<statusCode>404</statusCode>";
        echo "<statusText>Invalid Test ID: {$id}</statusText>";
        echo "<data>";
        echo "</data>";
    }
    echo "</response>";
}
Esempio n. 17
0
 }
 header("Content-disposition: attachment; filename={$filename}");
 header("Content-type: text/csv");
 header("Cache-Control: no-cache, must-revalidate");
 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
 if ($test['test']['batch']) {
     $tests = null;
     if (gz_is_file("{$testPath}/tests.json")) {
         $legacyData = json_decode(gz_file_get_contents("{$testPath}/tests.json"), true);
         $tests = array();
         $tests['variations'] = array();
         $tests['urls'] = array();
         foreach ($legacyData as &$legacyTest) {
             $tests['urls'][] = array('u' => $legacyTest['url'], 'id' => $legacyTest['id']);
         }
     } elseif (gz_is_file("{$testPath}/bulk.json")) {
         $tests = json_decode(gz_file_get_contents("{$testPath}/bulk.json"), true);
     }
     if (isset($tests)) {
         foreach ($tests['urls'] as &$testData) {
             RestoreTest($testData['id']);
             $path = './' . GetTestPath($testData['id']);
             if (!isset($hasCSV)) {
                 $files = glob("{$path}/*{$fileType}");
                 if ($files && is_array($files) && count($files)) {
                     $hasCSV = true;
                 } else {
                     $hasCSV = false;
                 }
             }
             $label = $testData['l'];
Esempio n. 18
0
 if (is_file("./{$dir}/video.mp4")) {
     $date = gmdate("M j, Y", filemtime("./{$dir}/video.mp4"));
 }
 $title .= " - {$date}";
 $labels = json_decode(file_get_contents("./{$dir}/labels.txt"), true);
 if (count($labels)) {
     $title .= ' : ';
     foreach ($labels as $index => $label) {
         if ($index > 0) {
             $title .= ", ";
         }
         $title .= $label;
     }
 }
 $location = null;
 if (gz_is_file("./{$dir}/testinfo.json")) {
     $tests = json_decode(gz_file_get_contents("./{$dir}/testinfo.json"), true);
     if (is_array($tests) && count($tests)) {
         foreach ($tests as &$test) {
             if (array_key_exists('location', $test)) {
                 if (!isset($location)) {
                     $location = $test['location'];
                 } elseif ($location != $test['location']) {
                     $location = '';
                 }
             } else {
                 $location = '';
             }
         }
     }
 }
Esempio n. 19
0
/**
* 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);
        }
    }
}
Esempio n. 20
0
                } elseif (substr($buffer, 0, 5) == "[{}\n,") {
                    $buffer = '[' . substr($buffer, 5);
                }
            }
            ob_flush();
            flush();
        }
        echo rtrim($buffer, "\r\n}");
        gzclose($handle);
    }
} elseif (gz_is_file("{$testPath}/{$run}{$cachedText}_timeline.json")) {
    $ok = true;
    header("Content-disposition: attachment; filename=timeline.json");
    header("Content-type: application/json");
    gz_readfile_chunked("{$testPath}/{$run}{$cachedText}_timeline.json");
} elseif (gz_is_file("{$testPath}/{$run}{$cachedText}_devtools.json")) {
    require_once 'devtools.inc.php';
    $devTools = array();
    $startOffset = null;
    GetTimeline($testPath, $run, $cached, $devTools, $startOffset);
    if (isset($devTools) && is_array($devTools) && count($devTools)) {
        foreach ($devTools as $entry) {
            $events = GetEvents($entry);
            if (count($events)) {
                if (!$ok) {
                    $ok = true;
                    header("Content-disposition: attachment; filename=timeline.json");
                    header("Content-type: application/json");
                    echo "[\"WebPagetest\"";
                }
                foreach ($events as $event) {
/**
* Gather all of the data that we collect for a single run
* 
* @param mixed $id
* @param mixed $testPath
* @param mixed $run
* @param mixed $cached
*/
function GetSingleRunData($id, $testPath, $run, $cached, &$pageData, $testInfo)
{
    $ret = null;
    if (array_key_exists($run, $pageData) && is_array($pageData[$run]) && array_key_exists($cached, $pageData[$run]) && is_array($pageData[$run][$cached])) {
        $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']), '/\\');
        $path = substr($testPath, 1);
        $ret = $pageData[$run][$cached];
        $ret['run'] = $run;
        $cachedText = '';
        if ($cached) {
            $cachedText = '_Cached';
        }
        if (isset($testInfo)) {
            if (array_key_exists('tester', $testInfo)) {
                $ret['tester'] = $testInfo['tester'];
            }
            if (array_key_exists('test_runs', $testInfo) && array_key_exists($run, $testInfo['test_runs']) && array_key_exists('tester', $testInfo['test_runs'][$run])) {
                $ret['tester'] = $testInfo['test_runs'][$run]['tester'];
            }
        }
        $basic_results = false;
        if (array_key_exists('basic', $_REQUEST) && $_REQUEST['basic']) {
            $basic_results = true;
        }
        if (!$basic_results && gz_is_file("{$testPath}/{$run}{$cachedText}_pagespeed.txt")) {
            $ret['PageSpeedScore'] = GetPageSpeedScore("{$testPath}/{$run}{$cachedText}_pagespeed.txt");
            $ret['PageSpeedData'] = "{$protocol}://{$host}{$uri}//getgzip.php?test={$id}&amp;file={$run}{$cachedText}_pagespeed.txt";
        }
        $ret['pages'] = array();
        $ret['pages']['details'] = "{$protocol}://{$host}{$uri}/details.php?test={$id}&run={$run}&cached={$cached}";
        $ret['pages']['checklist'] = "{$protocol}://{$host}{$uri}/performance_optimization.php?test={$id}&run={$run}&cached={$cached}";
        $ret['pages']['breakdown'] = "{$protocol}://{$host}{$uri}/breakdown.php?test={$id}&run={$run}&cached={$cached}";
        $ret['pages']['domains'] = "{$protocol}://{$host}{$uri}/domains.php?test={$id}&run={$run}&cached={$cached}";
        $ret['pages']['screenShot'] = "{$protocol}://{$host}{$uri}/screen_shot.php?test={$id}&run={$run}&cached={$cached}";
        $ret['thumbnails'] = array();
        $ret['thumbnails']['waterfall'] = "{$protocol}://{$host}{$uri}/result/{$id}/{$run}{$cachedText}_waterfall_thumb.png";
        $ret['thumbnails']['checklist'] = "{$protocol}://{$host}{$uri}/result/{$id}/{$run}{$cachedText}_optimization_thumb.png";
        $ret['thumbnails']['screenShot'] = "{$protocol}://{$host}{$uri}/result/{$id}/{$run}{$cachedText}_screen_thumb.png";
        $ret['images'] = array();
        $ret['images']['waterfall'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_waterfall.png";
        $ret['images']['connectionView'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_connection.png";
        $ret['images']['checklist'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_optimization.png";
        $ret['images']['screenShot'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_screen.jpg";
        if (is_file("{$testPath}/{$run}{$cachedText}_screen.png")) {
            $ret['images']['screenShotPng'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_screen.png";
        }
        $ret['rawData'] = array();
        $ret['rawData']['headers'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_report.txt";
        $ret['rawData']['pageData'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_IEWPG.txt";
        $ret['rawData']['requestsData'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_IEWTR.txt";
        $ret['rawData']['utilization'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_progress.csv";
        if (is_file("{$testPath}/{$run}{$cachedText}_bodies.zip")) {
            $ret['rawData']['bodies'] = "{$protocol}://{$host}{$uri}{$path}/{$run}{$cachedText}_bodies.zip";
        }
        if (!$basic_results) {
            $startOffset = array_key_exists('testStartOffset', $ret) ? intval(round($ret['testStartOffset'])) : 0;
            $progress = GetVisualProgress($testPath, $run, $cached, null, null, $startOffset);
            if (array_key_exists('frames', $progress) && is_array($progress['frames']) && count($progress['frames'])) {
                $cachedTextLower = strtolower($cachedText);
                $ret['videoFrames'] = array();
                foreach ($progress['frames'] as $ms => $frame) {
                    $videoFrame = array('time' => $ms);
                    $videoFrame['image'] = "http://{$host}{$uri}{$path}/video_{$run}{$cachedTextLower}/{$frame['file']}";
                    $videoFrame['VisuallyComplete'] = $frame['progress'];
                    $ret['videoFrames'][] = $videoFrame;
                }
            }
            $requests = getRequests($id, $testPath, $run, $cached, $secure, $haveLocations, false, true);
            $ret['domains'] = getDomainBreakdown($id, $testPath, $run, $cached, $requests);
            $ret['breakdown'] = getBreakdown($id, $testPath, $run, $cached, $requests);
            // check if removing requests
            $addRequests = 1;
            if (isset($_GET['requests'])) {
                if ($_GET['requests'] == 0) {
                    $addRequests = 0;
                }
            }
            // add requests
            if ($addRequests == 1) {
                $ret['requests'] = $requests;
            }
            $console_log = DevToolsGetConsoleLog($testPath, $run, $cached);
            if (isset($console_log)) {
                $ret['consoleLog'] = $console_log;
            }
            if (gz_is_file("{$testPath}/{$run}{$cachedText}_status.txt")) {
                $ret['status'] = array();
                $lines = gz_file("{$testPath}/{$run}{$cachedText}_status.txt");
                foreach ($lines as $line) {
                    $line = trim($line);
                    if (strlen($line)) {
                        list($time, $message) = explode("\t", $line);
                        if (strlen($time) && strlen($message)) {
                            $ret['status'][] = array('time' => $time, 'message' => $message);
                        }
                    }
                }
            }
        }
    }
    return $ret;
}
Esempio n. 22
0
/**
* Get the relative offset for the video capture (in milliseconds).
* This is the time between the first non-timeline event and the
* last paint or rasterize event prior to it.
* 
* @param mixed $testPath
* @param mixed $run
* @param mixed $cached
*/
function DevToolsGetVideoOffset($testPath, $run, $cached, &$endTime)
{
    $offset = 0;
    $endTime = 0;
    $lastEvent = 0;
    $cachedText = '';
    if ($cached) {
        $cachedText = '_Cached';
    }
    $devToolsFile = "{$testPath}/{$run}{$cachedText}_devtools.json";
    if (gz_is_file($devToolsFile)) {
        $events = json_decode(gz_file_get_contents($devToolsFile), true);
        if (is_array($events)) {
            $lastPaint = 0;
            $startTime = 0;
            foreach ($events as &$event) {
                if (is_array($event) && array_key_exists('method', $event)) {
                    $method_class = substr($event['method'], 0, strpos($event['method'], '.'));
                    // calculate the start time stuff
                    if ($method_class === 'Timeline') {
                        $encoded = json_encode($event);
                        $eventTime = DevToolsEventEndTime($event);
                        if ($eventTime && (!$startTime || $eventTime <= $startTime) && (!$lastPaint || $eventTime > $lastPaint)) {
                            if (strpos($encoded, '"type":"ResourceSendRequest"') !== false) {
                                $startTime = DevToolsEventTime($event);
                            }
                            if (strpos($encoded, '"type":"Rasterize"') !== false || strpos($encoded, '"type":"CompositeLayers"') !== false || strpos($encoded, '"type":"Paint"') !== false) {
                                $lastPaint = $eventTime;
                            }
                        }
                        if ($eventTime > $lastEvent && strpos($encoded, '"type":"Resource') !== false) {
                            $lastEvent = $eventTime;
                        }
                    }
                }
            }
        }
    }
    if ($startTime && $lastPaint && $lastPaint < $startTime) {
        $offset = round($startTime - $lastPaint);
    }
    if ($startTime && $lastEvent && $lastEvent > $startTime) {
        $endTime = ceil($lastEvent - $startTime);
    }
    return $offset;
}