/**
  * Creates a TestResult instance by loading the results from file system
  * @param TestInfo $testInfo Related test information
  * @param int $runNumber The run to return the data for, starting from 1
  * @param bool $isCached False for first view, true for repeat view
  * @param int $stepNumber The step number, starting from 1
  * @param FileHandler $fileHandler The FileHandler to use
  * @param array $options Options for the loadPageStepData
  * @return TestStepResult|null The created instance on success, null otherwise
  */
 public static function fromFiles($testInfo, $runNumber, $isCached, $stepNumber, $fileHandler = null, $options = null)
 {
     // no support to use FileHandler so far
     $localPaths = new TestPaths($testInfo->getRootDirectory(), $runNumber, $isCached, $stepNumber);
     $runCompleted = $testInfo->isRunComplete($runNumber);
     $pageData = loadPageStepData($localPaths, $runCompleted, $options, $testInfo->getInfoArray());
     return new self($testInfo, $pageData, $runNumber, $isCached, $stepNumber, $fileHandler);
 }
/**
 * @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;
}