public static function read_sensor()
 {
     // Reads the system's temperature
     $temp_c = -1;
     if (phodevi::is_linux()) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
         }
         if ($raw_temp != -1) {
             if ($raw_temp > 1000) {
                 $raw_temp = $raw_temp / 1000;
             }
             $temp_c = pts_math::set_precision($raw_temp, 2);
         }
         if ($temp_c == -1) {
             $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
             if (($end = strpos($acpi, ' ')) > 0) {
                 $temp_c = substr($acpi, 0, $end);
             }
         }
         if ($temp_c == -1) {
             $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
             if ($sensors != false && is_numeric($sensors)) {
                 $temp_c = $sensors;
             }
         }
         if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
             $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
             if ($temp_c > 1000) {
                 $temp_c = pts_math::set_precision($temp_c / 1000, 1);
             }
         }
     } else {
         if (phodevi::is_bsd()) {
             $acpi = phodevi_bsd_parser::read_sysctl(array('hw.sensors.acpi_tz1.temp0', 'hw.acpi.thermal.tz1.temperature'));
             if (($end = strpos($acpi, ' degC')) > 0 || ($end = strpos($acpi, 'C')) > 0) {
                 $acpi = substr($acpi, 0, $end);
                 if (is_numeric($acpi)) {
                     $temp_c = $acpi;
                 }
             }
         }
     }
     return $temp_c;
 }
 public static function get_supported_devices()
 {
     if (phodevi::is_linux()) {
         $blockdev_dir = '/sys/block/';
         $glob_regex = '{[shvm]d*,nvme*,mmcblk*}';
         $disk_array = pts_file_io::glob($blockdev_dir . $glob_regex, GLOB_BRACE);
         $supported = array();
         foreach ($disk_array as $check_disk) {
             $stat_path = $check_disk . '/stat';
             if (is_file($stat_path) && pts_file_io::file_get_contents($stat_path) != null) {
                 array_push($supported, basename($check_disk));
             }
         }
         return $supported;
     }
     return NULL;
 }
 public static function read_sensor()
 {
     $iowait = -1;
     if (phodevi::is_linux() && is_file('/proc/stat')) {
         $start_stat = pts_file_io::file_get_contents('/proc/stat');
         sleep(1);
         $end_stat = pts_file_io::file_get_contents('/proc/stat');
         $start_stat = explode(' ', substr($start_stat, 0, strpos($start_stat, "\n")));
         $end_stat = explode(' ', substr($end_stat, 0, strpos($end_stat, "\n")));
         for ($i = 2, $diff_cpu_total = 0; $i < 9; $i++) {
             $diff_cpu_total += $end_stat[$i] - $start_stat[$i];
         }
         $diff_iowait = $end_stat[6] - $start_stat[6];
         $iowait = pts_math::set_precision(1000 * $diff_iowait / $diff_cpu_total / 10, 2);
     }
     return $iowait;
 }
 public static function get_supported_devices()
 {
     if (phodevi::is_linux()) {
         $disk_list = shell_exec("ls -1 /sys/class/block | grep '^[shv]d[a-z]\$'");
         // TODO make this native PHP
         $disk_array = explode("\n", $disk_list);
         $supported = array();
         foreach ($disk_array as $check_disk) {
             $stat_path = '/sys/class/block/' . $check_disk . '/stat';
             if (is_file($stat_path) && pts_file_io::file_get_contents($stat_path) != null) {
                 array_push($supported, $check_disk);
             }
         }
         return $supported;
     }
     return NULL;
 }
 public static function audio_processor_string()
 {
     $audio = null;
     if (phodevi::is_macosx()) {
         // TODO: implement
     } else {
         if (phodevi::is_bsd()) {
             foreach (array('dev.hdac.0.%desc') as $dev) {
                 $dev = phodevi_bsd_parser::read_sysctl($dev);
                 if (!empty($dev)) {
                     $audio = $dev;
                 }
             }
         } else {
             if (phodevi::is_windows()) {
                 // TODO: implement
             } else {
                 if (phodevi::is_linux()) {
                     foreach (pts_file_io::glob('/sys/class/sound/card*/hwC0D*/vendor_name') as $vendor_name) {
                         $card_dir = dirname($vendor_name) . '/';
                         if (!is_readable($card_dir . 'chip_name')) {
                             continue;
                         }
                         $vendor_name = pts_file_io::file_get_contents($vendor_name);
                         $chip_name = pts_file_io::file_get_contents($card_dir . 'chip_name');
                         $audio = $vendor_name . ' ' . $chip_name;
                         if (strpos($chip_name, 'HDMI') !== false || strpos($chip_name, 'DP') !== false) {
                             // If HDMI is in the audio string, likely the GPU-provided audio, so try to find the mainboard otherwise
                             $audio = null;
                         } else {
                             break;
                         }
                     }
                     if ($audio == null) {
                         $audio = phodevi_linux_parser::read_pci('Multimedia audio controller');
                     }
                     if ($audio == null) {
                         $audio = phodevi_linux_parser::read_pci('Audio device');
                     }
                 }
             }
         }
     }
     return $audio;
 }
 public static function read_sensor()
 {
     // speed in MB/s
     $speed = -1;
     if (phodevi::is_linux()) {
         static $sys_disk = null;
         if ($sys_disk == null) {
             foreach (pts_file_io::glob('/sys/class/block/sd*/stat') as $check_disk) {
                 if (pts_file_io::file_get_contents($check_disk) != null) {
                     $sys_disk = $check_disk;
                     break;
                 }
             }
         }
         $speed = phodevi_linux_parser::read_sys_disk_speed($sys_disk, 'READ');
     }
     return $speed;
 }
 public static function read_sensor()
 {
     // Determine the current processor frequency
     $cpu_core = 0;
     // TODO: for now just monitoring the first core
     $info = 0;
     if (phodevi::is_linux()) {
         // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
         if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq')) {
             $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq');
             $info = intval($info) / 1000;
         } else {
             if (is_file('/proc/cpuinfo')) {
                 $cpu_speeds = phodevi_linux_parser::read_cpuinfo('cpu MHz');
                 if (isset($cpu_speeds[0])) {
                     $cpu_core = isset($cpu_speeds[$cpu_core]) ? $cpu_core : 0;
                     $info = intval($cpu_speeds[$cpu_core]);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $info = shell_exec('psrinfo -v | grep MHz');
             $info = substr($info, strrpos($info, 'at') + 3);
             $info = trim(substr($info, 0, strpos($info, 'MHz')));
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('dev.cpu.0.freq');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorSpeed');
                     if (($cut_point = strpos($info, ' ')) > 0) {
                         $info = substr($info, 0, $cut_point);
                         $info = str_replace(',', '.', $info);
                     }
                     if ($info < 100) {
                         $info *= 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
 public static function read_sensor()
 {
     // Report graphics processor temperature
     $temp_c = -1;
     if (phodevi::is_nvidia_graphics()) {
         $temp_c = phodevi_parser::read_nvidia_extension('GPUCoreTemp');
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $temp_c = phodevi_linux_parser::read_ati_overdrive('Temperature');
         } else {
             foreach (array_merge(array('/sys/class/drm/card0/device/temp1_input'), pts_file_io::glob('/sys/class/drm/card0/device/hwmon/hwmon*/temp1_input')) as $temp_input) {
                 // This works for at least Nouveau driver with Linux 2.6.37 era DRM
                 if (is_readable($temp_input) == false) {
                     continue;
                 }
                 $temp_input = pts_file_io::file_get_contents($temp_input);
                 if (is_numeric($temp_input)) {
                     if ($temp_input > 1000) {
                         $temp_input /= 1000;
                     }
                     $temp_c = $temp_input;
                     break;
                 }
             }
             if ($temp_c == -1 && is_readable('/sys/kernel/debug/dri/0/i915_emon_status')) {
                 // Intel thermal
                 $i915_emon_status = file_get_contents('/sys/kernel/debug/dri/0/i915_emon_status');
                 $temp = strpos($i915_emon_status, 'GMCH temp: ');
                 if ($temp !== false) {
                     $temp = substr($i915_emon_status, $temp + 11);
                     $temp = substr($temp, 0, strpos($temp, PHP_EOL));
                     if (is_numeric($temp) && $temp > 0) {
                         $temp_c = $temp;
                     }
                 }
             }
         }
     }
     if ($temp_c > 1000 || $temp_c < 9) {
         // Invalid data
         return -1;
     }
     return $temp_c;
 }
 private function cpu_freq_linux()
 {
     $frequency = -1;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current frequency.
     if (is_file('/sys/devices/system/cpu/' . $this->cpu_to_monitor . '/cpufreq/scaling_cur_freq')) {
         $frequency = pts_file_io::file_get_contents('/sys/devices/system/cpu/' . $this->cpu_to_monitor . '/cpufreq/scaling_cur_freq');
         $frequency = intval($frequency) / 1000;
     } else {
         if (is_file('/proc/cpuinfo')) {
             $cpu_speeds = phodevi_linux_parser::read_cpuinfo('cpu MHz');
             $cpu_number = intval(substr($this->cpu_to_monitor, 3));
             //cut 'cpu' from the beginning
             if (!isset($cpu_speeds[$cpu_number])) {
                 return -1;
             }
             $frequency = intval($cpu_speeds[$cpu_number]);
         }
     }
     return $frequency;
 }
示例#10
0
 private function sys_temp_linux()
 {
     $temp_c = -1;
     $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
     }
     if ($raw_temp != -1) {
         if ($raw_temp > 1000) {
             $raw_temp = $raw_temp / 1000;
         }
         $temp_c = pts_math::set_precision($raw_temp, 2);
     }
     if ($temp_c == -1) {
         $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
         if (($end = strpos($acpi, ' ')) > 0) {
             $temp_c = substr($acpi, 0, $end);
         }
     }
     if ($temp_c == -1) {
         $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
         if ($sensors != false && is_numeric($sensors)) {
             $temp_c = $sensors;
         }
     }
     if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
         $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
         if ($temp_c > 1000) {
             $temp_c = pts_math::set_precision($temp_c / 1000, 1);
         }
     }
     return $temp_c;
 }
 public static function parse_equal_delimited_file($file, $key)
 {
     $return_value = false;
     foreach (explode("\n", pts_file_io::file_get_contents($file)) as $build_line) {
         list($descriptor, $value) = pts_strings::trim_explode('=', $build_line);
         if ($descriptor == $key) {
             $return_value = $value;
             break;
         }
     }
     return $return_value;
 }
 public function custom_test_support_check()
 {
     /*
     As of Phoronix Test Suite 4.4, the software will check for the presence of a 'support-check' file.
     Any test profile can optionally include a support-check.sh file to check for arbitrary commands not covered by
     the rest of the PTS testing architecture, e.g. to check for the presence of systemd on the target system. If
     the script finds that the system is incompatible with the test, it can write a custom error message to the file
     specified by the $TEST_CUSTOM_ERROR environment variable. If the $TEST_CUSTOM_ERROR target is written to, the PTS
     client will abort the test installation with the specified error message.
     */
     $support_check_file = $this->get_resource_dir() . 'support-check.sh';
     if (PTS_IS_CLIENT && is_file($support_check_file)) {
         $environment['TEST_CUSTOM_ERROR'] = pts_client::temporary_directory() . '/PTS-' . $this->get_identifier_base_name() . '-' . rand(1000, 9999);
         $support_check = pts_tests::call_test_script($this, 'support-check', null, null, $environment, false);
         if (is_file($environment['TEST_CUSTOM_ERROR'])) {
             $support_result = pts_file_io::file_get_contents($environment['TEST_CUSTOM_ERROR']);
             pts_file_io::delete($environment['TEST_CUSTOM_ERROR']);
             return $support_result;
         }
     }
     return true;
 }
 public static function cpu_default_frequency($cpu_core = 0)
 {
     // Find out the processor frequency
     $info = null;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
     if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq')) {
         $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq');
         $info = intval($info) / 1000000;
         if ($info > 9) {
             // For some reason on Linux 3.10 the scaling_max_freq is reported as 25GHz...
             $info = null;
         }
     }
     if ($info == null && isset(phodevi::$vfs->cpuinfo)) {
         $cpu_mhz = self::read_cpuinfo_line('cpu MHz');
         $info = $cpu_mhz / 1000;
         if (empty($info)) {
             $cpu_mhz = self::read_cpuinfo_line('clock');
             $info = $cpu_mhz / 1000;
         }
     } else {
         if ($info == null && phodevi::is_bsd()) {
             $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq_levels'));
             if ($info != null) {
                 // Popping the top speed off of dev.cpu.0.freq_levels should be the default/highest supported frequency
                 $info = pts_arrays::first_element(explode(' ', str_replace('/', ' ', $info)));
                 if (!is_numeric($info)) {
                     $info = null;
                 }
             }
             if ($info == null) {
                 $info = phodevi_bsd_parser::read_sysctl(array('hw.acpi.cpu.px_global', 'machdep.est.frequency.target', 'hw.cpuspeed'));
             }
             if ($info == null) {
                 // dev.cpu.0.freq seems to be the real/current frequency, affected by power management, etc so only use as last fallback
                 $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq'));
             }
             if (is_numeric($info)) {
                 $info = $info / 1000;
             } else {
                 $info = null;
             }
         } else {
             if ($info == null && phodevi::is_windows()) {
                 $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Stock frequency');
                 if ($info != null) {
                     if (($e = strpos($info, ' MHz')) !== false) {
                         $info = substr($info, 0, $e);
                     }
                     $info = $info / 1000;
                 }
             } else {
                 if ($info == null) {
                     $info = phodevi::read_sensor(array('cpu', 'freq'));
                     if ($info > 1000) {
                         // Convert from MHz to GHz
                         $info = $info / 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = '<h1>Settings</h1>
				<h2>User Settings</h2>
				<p>User settings are specific to your particular account, in cases where there are multiple individuals/accounts managing the same test systems and data.</p>
				';
        $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_user_settings WHERE AccountID = :account_id AND UserID = :user_id');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $stmt->bindValue(':user_id', $_SESSION['UserID']);
        $result = $stmt->execute();
        $row = $result->fetchArray();
        $user_settings = array('Email' => array('NotifyOnResultUploads' => 'Send notification when test results are uploaded to Phoromatic.', 'NotifyOnWarnings' => 'Send notification when any warnings are generated on a test system.', 'NotifyOnNewSystems' => 'Send notification when new test systems are added.', 'NotifyOnHungSystems' => 'Send notification when system(s) appear hung.'));
        $main .= '<form name="system_form" id="system_form" action="?settings" method="post">';
        foreach ($user_settings as $section => $section_settings) {
            $main .= '<h3>' . $section . '</h3><p>';
            foreach ($section_settings as $key => $setting) {
                if (isset($_POST['user_settings_update'])) {
                    if (isset($_POST[$key]) && $_POST[$key] == 'yes') {
                        $row[$key] = 1;
                    } else {
                        $row[$key] = 0;
                    }
                    $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_user_settings SET ' . $key . ' = :val WHERE AccountID = :account_id AND UserID = :user_id');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':user_id', $_SESSION['UserID']);
                    $stmt->bindValue(':val', $row[$key]);
                    $stmt->execute();
                    //echo phoromatic_server::$db->lastErrorMsg();
                }
                $main .= '<input type="checkbox" name="' . $key . '" ' . (isset($row[$key]) && $row[$key] == 1 ? 'checked="checked" ' : '') . 'value="yes" /> ' . $setting . '<br />';
            }
            $main .= '</p>';
        }
        $main .= '<p><input type="hidden" value="1" name="user_settings_update" /><input type="submit" value="Save User Settings" /></p>';
        $main .= '</form>';
        if (!PHOROMATIC_USER_IS_VIEWER) {
            $main .= '<hr />
				<h2>Account Settings</h2>
				<p>Account settings are system-wide, in cases where there are multiple individuals/accounts managing the same test systems and data.</p>';
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_account_settings WHERE AccountID = :account_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            $account_settings = array('Global Settings' => array('ArchiveResultsLocally' => 'Archive test results on local test systems after the results have been uploaded.', 'UploadSystemLogs' => 'Upload system logs when uploading test results.', 'RunInstallCommand' => 'For all test schedules, always run the install command for test(s) prior to running them on the system.', 'ForceInstallTests' => 'For all test schedules, force the test installation/re-installation of tests each time prior to running the test.', 'SystemSensorMonitoring' => 'Enable the system sensor monitoring while tests are taking place.', 'UploadResultsToOpenBenchmarking' => 'For all test schedules, also upload test results to OpenBenchmarking.org.', 'PowerOffWhenDone' => 'Power off system(s) when scheduled tests are completed for the day.', 'PreSeedTestInstalls' => 'Attempt to pre-install commonly used tests on client systems while idling.', 'NetworkPowerUpWhenNeeded' => 'Use network Wake-On-LAN to power on systems when needed.', 'LetOtherGroupsViewResults' => 'Let other accounts/groups on this Phoromatic Server view (read-only) this account\'s results.', 'LetPublicViewResults' => 'Allow public/unauthenticated visitors to access these test results from the public viewer page.', 'PowerOnSystemDaily' => 'Attempt to power-on systems daily (unless there\'s a daily test schedule / trigger on the system) to maintain the DHCP lease on the network, update any software/hardware information, etc. When the daily update is done, the system will power off unless there\'s a test to run and the power-off setting above is enabled. This option is namely useful for systems that otherwise may be idling/powered-off for long periods of time between tests.', 'AutoApproveNewSystems' => 'Enabling this option will make new test systems immediately available for this account rather than the default behavior of first needing an administrator to approve/deny the system via the Phoromatic Server web interface. With this option enabled, the systems are automatically approved by default but can be later disabled/removed via the Phoromatic web interface.'));
            $main .= '<form name="system_form" id="system_form" action="?settings" method="post">';
            $settings_updated = false;
            foreach ($account_settings as $section => $section_settings) {
                $main .= '<h3>' . $section . '</h3><p>';
                foreach ($section_settings as $key => $setting) {
                    if (isset($_POST['account_settings_update'])) {
                        if (isset($_POST[$key]) && $_POST[$key] == 'yes') {
                            $row[$key] = 1;
                        } else {
                            $row[$key] = 0;
                        }
                        $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_account_settings SET ' . $key . ' = :val WHERE AccountID = :account_id');
                        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                        $stmt->bindValue(':val', $row[$key]);
                        $stmt->execute();
                        if ($settings_updated == false) {
                            phoromatic_add_activity_stream_event('settings', null, 'modified');
                            $settings_updated = true;
                        }
                        //echo phoromatic_server::$db->lastErrorMsg();
                    }
                    $main .= '<input type="checkbox" name="' . $key . '" ' . (isset($row[$key]) && $row[$key] === 1 ? 'checked="checked" ' : '') . 'value="yes" /> ' . $setting . '<br />';
                }
                $main .= '</p>';
            }
            $main .= '<p><input type="hidden" value="1" name="account_settings_update" /><input type="submit" value="Save Account Settings" /></p>';
            $main .= '</form>';
        }
        $main .= '<hr />
			<h2>Cache Settings</h2>
			<p>Proceed to the <a href="?caches">download cache page</a> for information about the Phoromatic Server\'s download caches.</p>';
        $main .= '<hr />
			<h2>User Password</h2>
			<p>Proceed to the <a href="?password">password page</a> if you wish to update your account\'s password.</p>';
        if (!PHOROMATIC_USER_IS_VIEWER) {
            $main .= '<hr />
				<h2>Build A Suite</h2>
				<p><a href="?build_suite">Create a custom test suite</a>.</p>';
            $update_script_path = phoromatic_server::phoromatic_account_path($_SESSION['AccountID']) . 'client-update-script.sh';
            if (isset($_POST['client_update_script'])) {
                file_put_contents($update_script_path, str_replace("\r\n", PHP_EOL, $_POST['client_update_script']));
            }
            if (!is_file($update_script_path)) {
                $script_contents = pts_file_io::file_get_contents(PTS_CORE_STATIC_PATH . 'sample-pts-client-update-script.sh');
            } else {
                $script_contents = pts_file_io::file_get_contents($update_script_path);
            }
            $main .= '<form name="update_client_script_form" id="update_client_script_form" action="?settings" method="post">
<hr /><h2>Auto-Updating Clients</h2><p>If desired, you can paste a script in the below field if you wish to have Phoronix Test Suite / Phoromatic clients attempt to auto-update themselves. Any commands copied below are automatically executed by the client upon completing a test / beginning a new idle process / prior to attempting a system shutdown. If your script determines the client is to be updated, it should <em>reboot</em> the system afterwards to ensure no issues in the upgrade of the Phoronix Test Suite installation. A reference/example script is provided by default. This update script feature does not attempt to update the Phoromatic Server software.</p>
				<p><textarea style="width: 80%; height: 400px;" name="client_update_script" id="client_update_script">' . $script_contents . '</textarea></p>
				<p><input type="submit" value="Save Client Auto-Update Script" /></p>
				</form>';
        }
        echo '<div id="pts_phoromatic_main_area">' . $main . '</div>';
        echo phoromatic_webui_footer();
    }
 public static function run_test(&$test_run_manager, &$test_run_request)
 {
     $test_identifier = $test_run_request->test_profile->get_identifier();
     $extra_arguments = $test_run_request->get_arguments();
     $arguments_description = $test_run_request->get_arguments_description();
     $full_output = pts_config::read_bool_config('PhoronixTestSuite/Options/General/FullOutput', 'FALSE');
     // Do the actual test running process
     $test_directory = $test_run_request->test_profile->get_install_dir();
     if (!is_dir($test_directory)) {
         return false;
     }
     $lock_file = $test_directory . 'run_lock';
     if (pts_client::create_lock($lock_file) == false && $test_run_manager->is_multi_test_stress_run() == false) {
         self::test_run_error($test_run_manager, $test_run_request, 'The ' . $test_identifier . ' test is already running.');
         return false;
     }
     $active_result_buffer = new pts_test_result_buffer_active();
     $test_run_request->active =& $active_result_buffer;
     $execute_binary = $test_run_request->test_profile->get_test_executable();
     $times_to_run = $test_run_request->test_profile->get_times_to_run();
     $ignore_runs = $test_run_request->test_profile->get_runs_to_ignore();
     $test_type = $test_run_request->test_profile->get_test_hardware_type();
     $allow_cache_share = $test_run_request->test_profile->allow_cache_share();
     $min_length = $test_run_request->test_profile->get_min_length();
     $max_length = $test_run_request->test_profile->get_max_length();
     if ($test_run_request->test_profile->get_environment_testing_size() > 1 && ceil(disk_free_space($test_directory) / 1048576) < $test_run_request->test_profile->get_environment_testing_size()) {
         // Ensure enough space is available on disk during testing process
         self::test_run_error($test_run_manager, $test_run_request, 'There is not enough space (at ' . $test_directory . ') for this test to run.');
         pts_client::release_lock($lock_file);
         return false;
     }
     $to_execute = $test_run_request->test_profile->get_test_executable_dir();
     $pts_test_arguments = trim($test_run_request->test_profile->get_default_arguments() . ' ' . str_replace($test_run_request->test_profile->get_default_arguments(), '', $extra_arguments) . ' ' . $test_run_request->test_profile->get_default_post_arguments());
     $extra_runtime_variables = pts_tests::extra_environmental_variables($test_run_request->test_profile);
     // Start
     $cache_share_pt2so = $test_directory . 'cache-share-' . PTS_INIT_TIME . '.pt2so';
     $cache_share_present = $allow_cache_share && is_file($cache_share_pt2so);
     $test_run_request->set_used_arguments_description($arguments_description);
     pts_module_manager::module_process('__pre_test_run', $test_run_request);
     $time_test_start = time();
     pts_client::$display->test_run_start($test_run_manager, $test_run_request);
     if (!$cache_share_present) {
         $pre_output = pts_tests::call_test_script($test_run_request->test_profile, 'pre', 'Running Pre-Test Script', $pts_test_arguments, $extra_runtime_variables, true);
         if ($pre_output != null && (pts_client::is_debug_mode() || $full_output)) {
             pts_client::$display->test_run_instance_output($pre_output);
         }
         if (is_file($test_directory . 'pre-test-exit-status')) {
             // If the pre script writes its exit status to ~/pre-test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'pre-test-exit-status');
             unlink($test_directory . 'pre-test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The pre run script exited with a non-zero exit status.' . PHP_EOL);
                 self::test_run_error($test_run_manager, $test_run_request, 'This test execution has been abandoned.');
                 return false;
             }
         }
     }
     pts_client::$display->display_interrupt_message($test_run_request->test_profile->get_pre_run_message());
     $runtime_identifier = time();
     $execute_binary_prepend = '';
     if ($test_run_request->exec_binary_prepend != null) {
         $execute_binary_prepend = $test_run_request->exec_binary_prepend;
     }
     if (!$cache_share_present && $test_run_request->test_profile->is_root_required()) {
         if (phodevi::is_root() == false) {
             pts_client::$display->test_run_error('This test must be run as the root / administrator account.');
         }
         $execute_binary_prepend .= ' ' . PTS_CORE_STATIC_PATH . 'root-access.sh ';
     }
     if ($allow_cache_share && !is_file($cache_share_pt2so)) {
         $cache_share = new pts_storage_object(false, false);
     }
     if ($test_run_manager->get_results_identifier() != null && $test_run_manager->get_file_name() != null && pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/SaveTestLogs', 'FALSE')) {
         $backup_test_log_dir = PTS_SAVE_RESULTS_PATH . $test_run_manager->get_file_name() . '/test-logs/active/' . $test_run_manager->get_results_identifier() . '/';
         pts_file_io::delete($backup_test_log_dir);
         pts_file_io::mkdir($backup_test_log_dir, 0777, true);
     } else {
         $backup_test_log_dir = false;
     }
     for ($i = 0, $abort_testing = false, $time_test_start_actual = time(), $defined_times_to_run = $times_to_run; $i < $times_to_run && $i < 256 && !$abort_testing; $i++) {
         pts_client::$display->test_run_instance_header($test_run_request);
         $test_log_file = $test_directory . basename($test_identifier) . '-' . $runtime_identifier . '-' . ($i + 1) . '.log';
         $is_expected_last_run = $i == $times_to_run - 1;
         $test_extra_runtime_variables = array_merge($extra_runtime_variables, array('LOG_FILE' => $test_log_file, 'DISPLAY' => getenv('DISPLAY'), 'PATH' => getenv('PATH')));
         $restored_from_cache = false;
         if ($cache_share_present) {
             $cache_share = pts_storage_object::recover_from_file($cache_share_pt2so);
             if ($cache_share) {
                 $test_result = $cache_share->read_object('test_results_output_' . $i);
                 $test_extra_runtime_variables['LOG_FILE'] = $cache_share->read_object('log_file_location_' . $i);
                 if ($test_extra_runtime_variables['LOG_FILE'] != null) {
                     file_put_contents($test_extra_runtime_variables['LOG_FILE'], $cache_share->read_object('log_file_' . $i));
                     $test_run_time = 0;
                     // This wouldn't be used for a cache share since it would always be the same, but declare the value so the variable is at least initialized
                     $restored_from_cache = true;
                 }
             }
             unset($cache_share);
         }
         if ($restored_from_cache == false) {
             $test_run_command = 'cd ' . $to_execute . ' && ' . $execute_binary_prepend . './' . $execute_binary . ' ' . $pts_test_arguments . ' 2>&1';
             pts_client::test_profile_debug_message('Test Run Command: ' . $test_run_command);
             $is_monitoring = pts_test_result_parser::system_monitor_task_check($test_run_request->test_profile);
             $test_run_time_start = time();
             if (phodevi::is_windows() || pts_client::read_env('USE_PHOROSCRIPT_INTERPRETER') != false) {
                 $phoroscript = new pts_phoroscript_interpreter($to_execute . '/' . $execute_binary, $test_extra_runtime_variables, $to_execute);
                 $phoroscript->execute_script($pts_test_arguments);
                 $test_result = null;
             } else {
                 //$test_result = pts_client::shell_exec($test_run_command, $test_extra_runtime_variables);
                 $descriptorspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
                 $test_process = proc_open('exec ' . $execute_binary_prepend . './' . $execute_binary . ' ' . $pts_test_arguments . ' 2>&1', $descriptorspec, $pipes, $to_execute, array_merge($_ENV, pts_client::environmental_variables(), $test_extra_runtime_variables));
                 if (is_resource($test_process)) {
                     //echo proc_get_status($test_process)['pid'];
                     pts_module_manager::module_process('__test_running', $test_process);
                     $test_result = stream_get_contents($pipes[1]);
                     fclose($pipes[1]);
                     fclose($pipes[2]);
                     $return_value = proc_close($test_process);
                 }
             }
             $test_run_time = time() - $test_run_time_start;
             $monitor_result = $is_monitoring ? pts_test_result_parser::system_monitor_task_post_test($test_run_request->test_profile) : 0;
         }
         if (!isset($test_result[10240]) || pts_client::is_debug_mode() || $full_output) {
             pts_client::$display->test_run_instance_output($test_result);
         }
         if (is_file($test_log_file) && trim($test_result) == null && (filesize($test_log_file) < 10240 || pts_client::is_debug_mode() || $full_output)) {
             $test_log_file_contents = file_get_contents($test_log_file);
             pts_client::$display->test_run_instance_output($test_log_file_contents);
             unset($test_log_file_contents);
         }
         $test_run_request->test_result_standard_output = $test_result;
         $exit_status_pass = true;
         if (is_file($test_directory . 'test-exit-status')) {
             // If the test script writes its exit status to ~/test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'test-exit-status');
             unlink($test_directory . 'test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The test exited with a non-zero exit status.');
                 if ($is_expected_last_run && is_file($test_log_file)) {
                     $scan_log = pts_file_io::file_get_contents($test_log_file);
                     $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                     if ($test_run_error) {
                         self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                     }
                 }
                 $exit_status_pass = false;
             }
         }
         if (!in_array($i + 1, $ignore_runs) && $exit_status_pass) {
             if (isset($monitor_result) && $monitor_result != 0) {
                 $test_run_request->active->active_result = $monitor_result;
             } else {
                 pts_test_result_parser::parse_result($test_run_request, $test_extra_runtime_variables['LOG_FILE']);
             }
             pts_client::test_profile_debug_message('Test Result Value: ' . $test_run_request->active->active_result);
             if (!empty($test_run_request->active->active_result)) {
                 if ($test_run_time < 2 && intval($test_run_request->active->active_result) == $test_run_request->active->active_result && $test_run_request->test_profile->get_estimated_run_time() > 60 && !$restored_from_cache) {
                     // If the test ended in less than two seconds, outputted some int, and normally the test takes much longer, then it's likely some invalid run
                     self::test_run_instance_error($test_run_manager, $test_run_request, 'The test run ended prematurely.');
                     if ($is_expected_last_run && is_file($test_log_file)) {
                         $scan_log = pts_file_io::file_get_contents($test_log_file);
                         $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                         if ($test_run_error) {
                             self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                         }
                     }
                 } else {
                     // TODO integrate active_result into active buffer
                     $active_result_buffer->add_trial_run_result($test_run_request->active->active_result, $test_run_request->active->active_min_result, $test_run_request->active->active_max_result);
                 }
             } else {
                 if ($test_run_request->test_profile->get_display_format() != 'NO_RESULT') {
                     self::test_run_instance_error($test_run_manager, $test_run_request, 'The test run did not produce a result.');
                     if ($is_expected_last_run && is_file($test_log_file)) {
                         $scan_log = pts_file_io::file_get_contents($test_log_file);
                         $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                         if ($test_run_error) {
                             self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                         }
                     }
                 }
             }
             if ($allow_cache_share && !is_file($cache_share_pt2so)) {
                 $cache_share->add_object('test_results_output_' . $i, $test_run_request->active->active_result);
                 $cache_share->add_object('log_file_location_' . $i, $test_extra_runtime_variables['LOG_FILE']);
                 $cache_share->add_object('log_file_' . $i, is_file($test_log_file) ? file_get_contents($test_log_file) : null);
             }
         }
         if ($is_expected_last_run && $active_result_buffer->get_trial_run_count() > floor(($i - 2) / 2) && !$cache_share_present && $test_run_manager->do_dynamic_run_count()) {
             // The later check above ensures if the test is failing often the run count won't uselessly be increasing
             // Should we increase the run count?
             $increase_run_count = false;
             if ($defined_times_to_run == $i + 1 && $active_result_buffer->get_trial_run_count() > 0 && $active_result_buffer->get_trial_run_count() < $defined_times_to_run && $i < 64) {
                 // At least one run passed, but at least one run failed to produce a result. Increase count to try to get more successful runs
                 $increase_run_count = $defined_times_to_run - $active_result_buffer->get_trial_run_count();
             } else {
                 if ($active_result_buffer->get_trial_run_count() >= 2) {
                     // Dynamically increase run count if needed for statistical significance or other reasons
                     $increase_run_count = $test_run_manager->increase_run_count_check($active_result_buffer, $defined_times_to_run, $test_run_time);
                     if ($increase_run_count === -1) {
                         $abort_testing = true;
                     } else {
                         if ($increase_run_count == true) {
                             // Just increase the run count one at a time
                             $increase_run_count = 1;
                         }
                     }
                 }
             }
             if ($increase_run_count > 0) {
                 $times_to_run += $increase_run_count;
                 $is_expected_last_run = false;
                 //$test_run_request->test_profile->set_times_to_run($times_to_run);
             }
         }
         if ($times_to_run > 1 && $i < $times_to_run - 1) {
             if ($cache_share_present == false) {
                 $interim_output = pts_tests::call_test_script($test_run_request->test_profile, 'interim', 'Running Interim Test Script', $pts_test_arguments, $extra_runtime_variables, true);
                 if ($interim_output != null && (pts_client::is_debug_mode() || $full_output)) {
                     pts_client::$display->test_run_instance_output($interim_output);
                 }
                 //sleep(2); // Rest for a moment between tests
             }
             pts_module_manager::module_process('__interim_test_run', $test_run_request);
         }
         if (is_file($test_log_file)) {
             if ($is_expected_last_run) {
                 // For now just passing the last test log file...
                 // TODO XXX: clean this up with log files to preserve when needed, let multiple log files exist for extra_data, etc
                 pts_test_result_parser::generate_extra_data($test_run_request, $test_log_file);
             }
             if ($backup_test_log_dir) {
                 copy($test_log_file, $backup_test_log_dir . basename($test_log_file));
             }
             if (pts_client::test_profile_debug_message('Log File At: ' . $test_log_file) == false) {
                 unlink($test_log_file);
             }
         }
         if (is_file(PTS_USER_PATH . 'halt-testing') || is_file(PTS_USER_PATH . 'skip-test')) {
             pts_client::release_lock($lock_file);
             return false;
         }
         pts_client::$display->test_run_instance_complete($test_run_request);
     }
     $time_test_end_actual = time();
     if ($cache_share_present == false) {
         $post_output = pts_tests::call_test_script($test_run_request->test_profile, 'post', 'Running Post-Test Script', $pts_test_arguments, $extra_runtime_variables, true);
         if ($post_output != null && (pts_client::is_debug_mode() || $full_output)) {
             pts_client::$display->test_run_instance_output($post_output);
         }
         if (is_file($test_directory . 'post-test-exit-status')) {
             // If the post script writes its exit status to ~/post-test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'post-test-exit-status');
             unlink($test_directory . 'post-test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The post run script exited with a non-zero exit status.' . PHP_EOL);
                 $abort_testing = true;
             }
         }
     }
     if ($abort_testing) {
         self::test_run_error($test_run_manager, $test_run_request, 'This test execution has been abandoned.');
         return false;
     }
     // End
     $time_test_end = time();
     $time_test_elapsed = $time_test_end - $time_test_start;
     $time_test_elapsed_actual = $time_test_end_actual - $time_test_start_actual;
     if (!empty($min_length)) {
         if ($min_length > $time_test_elapsed_actual) {
             // The test ended too quickly, results are not valid
             self::test_run_error($test_run_manager, $test_run_request, 'This test ended prematurely.');
             return false;
         }
     }
     if (!empty($max_length)) {
         if ($max_length < $time_test_elapsed_actual) {
             // The test took too much time, results are not valid
             self::test_run_error($test_run_manager, $test_run_request, 'This test run was exhausted.');
             return false;
         }
     }
     if ($allow_cache_share && !is_file($cache_share_pt2so) && $cache_share instanceof pts_storage_object) {
         $cache_share->save_to_file($cache_share_pt2so);
         unset($cache_share);
     }
     if ($test_run_manager->get_results_identifier() != null && pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/SaveInstallationLogs', 'FALSE')) {
         if (is_file($test_run_request->test_profile->get_install_dir() . 'install.log')) {
             $backup_log_dir = PTS_SAVE_RESULTS_PATH . $test_run_manager->get_file_name() . '/installation-logs/' . $test_run_manager->get_results_identifier() . '/';
             pts_file_io::mkdir($backup_log_dir, 0777, true);
             copy($test_run_request->test_profile->get_install_dir() . 'install.log', $backup_log_dir . basename($test_identifier) . '.log');
         }
     }
     // Fill in missing test details
     if (empty($arguments_description)) {
         $arguments_description = $test_run_request->test_profile->get_test_subtitle();
     }
     $file_var_checks = array(array('pts-results-scale', 'set_result_scale', null), array('pts-results-proportion', 'set_result_proportion', null), array('pts-results-quantifier', 'set_result_quantifier', null), array('pts-test-version', 'set_version', null), array('pts-test-description', null, 'set_used_arguments_description'), array('pts-footnote', null, null));
     foreach ($file_var_checks as &$file_check) {
         list($file, $set_function, $result_set_function) = $file_check;
         if (is_file($test_directory . $file)) {
             $file_contents = pts_file_io::file_get_contents($test_directory . $file);
             unlink($test_directory . $file);
             if (!empty($file_contents)) {
                 if ($set_function != null) {
                     call_user_func(array($test_run_request->test_profile, $set_function), $file_contents);
                 } else {
                     if ($result_set_function != null) {
                         if ($result_set_function == 'set_used_arguments_description') {
                             $arguments_description = $file_contents;
                         } else {
                             call_user_func(array($test_run_request, $result_set_function), $file_contents);
                         }
                     } else {
                         if ($file == 'pts-footnote') {
                             $test_run_request->test_profile->test_installation->set_install_footnote($file_contents);
                         }
                     }
                 }
             }
         }
     }
     if (empty($arguments_description)) {
         $arguments_description = 'Phoronix Test Suite v' . PTS_VERSION;
     }
     foreach (pts_client::environmental_variables() as $key => $value) {
         $arguments_description = str_replace('$' . $key, $value, $arguments_description);
         if (!in_array($key, array('VIDEO_MEMORY', 'NUM_CPU_CORES', 'NUM_CPU_JOBS'))) {
             $extra_arguments = str_replace('$' . $key, $value, $extra_arguments);
         }
     }
     // Any device notes to add to PTS test notes area?
     foreach (phodevi::read_device_notes($test_type) as $note) {
         pts_test_notes_manager::add_note($note);
     }
     // As of PTS 4.4, this is removed and superceded effectively by reporting the notes to table
     // Any special information (such as forced AA/AF levels for graphics) to add to the description string of the result?
     /*
     if(($special_string = phodevi::read_special_settings_string($test_type)) != null)
     {
     	if(strpos($arguments_description, $special_string) === false)
     	{
     		if($arguments_description != null)
     		{
     			$arguments_description .= ' | ';
     		}
     
     		$arguments_description .= $special_string;
     	}
     }
     */
     // Result Calculation
     $test_run_request->set_used_arguments_description($arguments_description);
     $test_run_request->set_used_arguments($extra_arguments);
     pts_test_result_parser::calculate_end_result($test_run_request, $active_result_buffer);
     // Process results
     pts_client::$display->test_run_end($test_run_request);
     pts_client::$display->display_interrupt_message($test_run_request->test_profile->get_post_run_message());
     pts_module_manager::module_process('__post_test_run', $test_run_request);
     $report_elapsed_time = $cache_share_present == false && $test_run_request->active->get_result() != 0;
     pts_tests::update_test_install_xml($test_run_request->test_profile, $report_elapsed_time ? $time_test_elapsed : 0);
     pts_storage_object::add_in_file(PTS_CORE_STORAGE, 'total_testing_time', $time_test_elapsed / 60);
     if ($report_elapsed_time && pts_client::do_anonymous_usage_reporting() && $time_test_elapsed >= 60) {
         // If anonymous usage reporting enabled, report test run-time to OpenBenchmarking.org
         pts_openbenchmarking_client::upload_usage_data('test_complete', array($test_run_request, $time_test_elapsed));
     }
     // Remove lock
     pts_client::release_lock($lock_file);
     return $active_result_buffer;
 }
示例#16
0
 private static function check_user_context_log($trigger, $schedule_id, $process, $log_file, $log_output)
 {
     if (is_file($log_file) && ($lf_conts = pts_file_io::file_get_contents($log_file)) != null) {
         $context_log = $lf_conts;
         unlink($log_file);
     } else {
         $context_log = trim($log_output);
     }
     if ($context_log != null) {
         $server_response = phoromatic::upload_to_remote_server(array('r' => 'user_context_log', 'sched' => $schedule_id, 'ts' => $trigger, 'i' => $process, 'o' => $context_log));
     }
 }
 public static function run($r)
 {
     $pdf = new pts_pdf_template(pts_title(false), 'Test Client Documentation');
     $html_doc = new pts_html_template(pts_title(false), 'Test Client Documentation');
     $pdf->AddPage();
     $pdf->Image(PTS_CORE_STATIC_PATH . 'images/pts-308x160.png', 69, 85, 73, 38, 'PNG', 'http://www.phoronix-test-suite.com/');
     $pdf->Ln(120);
     $pdf->WriteStatement('www.phoronix-test-suite.com', 'C', 'http://www.phoronix-test-suite.com/');
     $pdf->Ln(15);
     $pdf->WriteBigHeaderCenter(pts_title(true));
     $pdf->WriteHeaderCenter('User Manual');
     //$pdf->WriteText($result_file->get_description());
     $pts_options = pts_documentation::client_commands_array();
     // Write the test options HTML
     $dom = new DOMDocument();
     $html = $dom->createElement('html');
     $dom->appendChild($html);
     $head = $dom->createElement('head');
     $title = $dom->createElement('title', 'User Options');
     $head->appendChild($title);
     $html->appendChild($head);
     $body = $dom->createElement('body');
     $html->appendChild($body);
     $p = $dom->createElement('p', 'The following options are currently supported by the Phoronix Test Suite client. A list of available options can also be found by running ');
     $em = $dom->createElement('em', 'phoronix-test-suite help.');
     $p->appendChild($em);
     $phr = $dom->createElement('hr');
     $p->appendChild($phr);
     $body->appendChild($p);
     foreach ($pts_options as $section => &$contents) {
         if (empty($contents)) {
             continue;
         }
         $header = $dom->createElement('h1', $section);
         $body->appendChild($header);
         sort($contents);
         foreach ($contents as &$option) {
             $sub_header = $dom->createElement('h3', $option[0]);
             $em = $dom->CreateElement('em', '  ' . implode(' ', $option[1]));
             $sub_header->appendChild($em);
             $body->appendChild($sub_header);
             $p = $dom->createElement('p', $option[2]);
             $body->appendChild($p);
         }
     }
     $dom->saveHTMLFile(PTS_PATH . 'documentation/stubs/00_user_options.html');
     // Write the module options HTML
     $dom = new DOMDocument();
     $html = $dom->createElement('html');
     $dom->appendChild($html);
     $head = $dom->createElement('head');
     $title = $dom->createElement('title', 'Module Options');
     $head->appendChild($title);
     $html->appendChild($head);
     $body = $dom->createElement('body');
     $html->appendChild($body);
     $p = $dom->createElement('p', 'The following list is the modules included with the Phoronix Test Suite that are intended to extend the functionality of pts-core. Some of these options have commands that can be run directly in a similiar manner to the other Phoronix Test Suite user commands. Some modules are just meant to be loaded directly by adding the module name to the LoadModules tag in ~/.phoronix-test-suite/user-config.xml or via the PTS_MODULES environmental variable. A list of available modules is also available by running ');
     $em = $dom->createElement('em', 'phoronix-test-suite list-modules.');
     $p->appendChild($em);
     $phr = $dom->createElement('hr');
     $p->appendChild($phr);
     $body->appendChild($p);
     foreach (pts_module_manager::available_modules(true) as $module) {
         pts_module_manager::load_module($module);
         $header = $dom->createElement('h2', pts_module_manager::module_call($module, 'module_name'));
         $body->appendChild($header);
         $desc = $dom->createElement('p', pts_module_manager::module_call($module, 'module_description'));
         $body->appendChild($desc);
         $all_options = pts_module_manager::module_call($module, 'user_commands');
         if (count($all_options) > 0) {
             //	$sub_header = $dom->createElement('h3', 'Module Commands');
             //	$body->appendChild($sub_header);
             foreach ($all_options as $key => $option) {
                 $p = $dom->createElement('p', 'phoronix-test-suite ' . $module . '.' . str_replace('_', '-', $key));
                 $body->appendChild($p);
             }
         }
         $vars = pts_module_manager::module_call($module, 'module_environmental_variables');
         if (is_array($vars) && count($vars) > 0) {
             $p = $dom->createElement('p', 'This module utilizes the following environmental variables: ' . implode(', ', $vars) . '.');
             $body->appendChild($p);
         }
     }
     $dom->saveHTMLFile(PTS_PATH . 'documentation/stubs/00_zmodule_options.html');
     // Write the external dependencies HTML
     $dom = new DOMDocument();
     $html = $dom->createElement('html');
     $dom->appendChild($html);
     $head = $dom->createElement('head');
     $title = $dom->createElement('title', 'External Dependencies');
     $head->appendChild($title);
     $html->appendChild($head);
     $body = $dom->createElement('body');
     $html->appendChild($body);
     $p = $dom->createElement('p', 'The Phoronix Test Suite has a feature known as &quot;External Dependencies&quot; where the Phoronix Test Suite can attempt to automatically install some of the test-specific dependencies on supported distributions. If running on a distribution where there is currently no External Dependencies profile, the needed package name(s) are listed for manual installation.');
     $body->appendChild($p);
     $p = $dom->createElement('p', 'Below are a list of the operating systems that currently have external dependencies support within the Phoronix Test Suite for the automatic installation of needed test files.');
     $body->appendChild($p);
     $phr = $dom->createElement('hr');
     $p->appendChild($phr);
     $exdep_generic_parser = new pts_exdep_generic_parser();
     $vendors = array_merge($exdep_generic_parser->get_vendor_aliases_formatted(), $exdep_generic_parser->get_vendors_list_formatted());
     sort($vendors);
     $ul = $dom->createElement('ul');
     $p->appendChild($ul);
     foreach ($vendors as $vendor) {
         $li = $dom->createElement('li', $vendor);
         $p->appendChild($li);
     }
     $dom->saveHTMLFile(PTS_PATH . 'documentation/stubs/02_external_dependencies.html');
     // Write the virtual suites HTML
     $dom = new DOMDocument();
     $html = $dom->createElement('html');
     $dom->appendChild($html);
     $head = $dom->createElement('head');
     $title = $dom->createElement('title', 'Virtual Test Suites');
     $head->appendChild($title);
     $html->appendChild($head);
     $body = $dom->createElement('body');
     $html->appendChild($body);
     $p = $dom->createElement('p', 'Virtual test suites are not like a traditional test suite defined by the XML suite specification. Virtual test suites are dynamically generated in real-time by the Phoronix Test Suite client based upon the specified test critera. Virtual test suites can automatically consist of all test profiles that are compatible with a particular operating system or test profiles that meet other critera. When running a virtual suite, the OpenBenchmarking.org repository of the test profiles to use for generating the dynamic suite must be prefixed. ');
     $body->appendChild($p);
     $p = $dom->createElement('p', 'Virtual test suites can be installed and run just like a normal XML test suite and shares nearly all of the same capabilities. However, when running a virtual suite, the user will be prompted to input any user-configuration options for needed test profiles just as they would need to do if running the test individually. When running a virtual suite, the user also has the ability to select individual tests within the suite to run or to run all of the contained test profiles. Virtual test suites are also only supported for an OpenBenchmarking.org repository if there is no test profile or test suite of the same name in the repository. Below is a list of common virtual test suites for the main Phoronix Test Suite repository, but the dynamic list of available virtual test suites based upon the enabled repositories is available by running ');
     $em = $dom->createElement('em', 'phoronix-test-suite list-available-virtual-suites.');
     $p->appendChild($em);
     $phr = $dom->createElement('hr');
     $p->appendChild($phr);
     $body->appendChild($p);
     foreach (pts_virtual_test_suite::available_virtual_suites() as $virtual_suite) {
         $sub_header = $dom->createElement('h3', $virtual_suite->get_title());
         $em = $dom->CreateElement('em', '  ' . $virtual_suite->get_identifier());
         $sub_header->appendChild($em);
         $body->appendChild($sub_header);
         $p = $dom->createElement('p', $virtual_suite->get_description());
         $body->appendChild($p);
     }
     $dom->saveHTMLFile(PTS_PATH . 'documentation/stubs/55_virtual_suites.html');
     // Load the HTML documentation
     foreach (pts_file_io::glob(PTS_PATH . 'documentation/stubs/*_*.html') as $html_file) {
         $pdf->html_to_pdf($html_file);
         $html_doc->html_to_html($html_file);
     }
     if (!is_writable(PTS_PATH . 'documentation/')) {
         echo PHP_EOL . 'Not writable: ' . PTS_PATH . 'documentation/';
     } else {
         $pdf_file = PTS_PATH . 'documentation/phoronix-test-suite.pdf';
         $pdf->Output($pdf_file);
         $html_doc->Output(PTS_PATH . 'documentation/phoronix-test-suite.html');
         echo PHP_EOL . 'Saved To: ' . $pdf_file . PHP_EOL . PHP_EOL;
         // Also re-generate the man page
         $man_page = '.TH phoronix-test-suite 1  "www.phoronix-test-suite.com" "' . PTS_VERSION . '"' . PHP_EOL . '.SH NAME' . PHP_EOL;
         $man_page .= 'phoronix-test-suite \\- The Phoronix Test Suite is an extensible open-source platform for performing testing and performance evaluation.' . PHP_EOL;
         $man_page .= '.SH SYNOPSIS' . PHP_EOL . '.B phoronix-test-suite [options]' . PHP_EOL . '.br' . PHP_EOL . '.B phoronix-test-suite benchmark [test | suite]' . PHP_EOL;
         $man_page .= '.SH DESCRIPTION' . PHP_EOL . pts_documentation::basic_description() . PHP_EOL;
         $man_page .= '.SH OPTIONS' . PHP_EOL . '.TP' . PHP_EOL;
         foreach ($pts_options as $section => &$contents) {
             if (empty($contents)) {
                 continue;
             }
             $man_page .= '.SH ' . strtoupper($section) . PHP_EOL;
             sort($contents);
             foreach ($contents as &$option) {
                 $man_page .= '.B ' . trim($option[0] . ' ' . (!empty($option[1]) && is_array($option[1]) ? implode(' ', $option[1]) : null)) . PHP_EOL . $option[2] . PHP_EOL . '.TP' . PHP_EOL;
             }
         }
         $man_page .= '.SH SEE ALSO' . PHP_EOL . '.B Websites:' . PHP_EOL . '.br' . PHP_EOL . 'http://www.phoronix-test-suite.com/' . PHP_EOL . '.br' . PHP_EOL . 'http://commercial.phoronix-test-suite.com/' . PHP_EOL . '.br' . PHP_EOL . 'http://www.openbenchmarking.org/' . PHP_EOL . '.br' . PHP_EOL . 'http://www.phoronix.com/' . PHP_EOL . '.br' . PHP_EOL . 'http://www.phoronix.com/forums/' . PHP_EOL;
         $man_page .= '.SH AUTHORS' . PHP_EOL . 'Copyright 2008 - ' . date('Y') . ' by Phoronix Media, Michael Larabel.' . PHP_EOL . '.TP' . PHP_EOL;
         file_put_contents(PTS_PATH . 'documentation/man-pages/phoronix-test-suite.1', $man_page);
     }
     // simple README
     $readme = '# Phoronix Test Suite ' . PTS_VERSION . PHP_EOL . 'http://www.phoronix-test-suite.com/' . PHP_EOL . PHP_EOL;
     $readme .= pts_documentation::basic_description() . PHP_EOL . PHP_EOL;
     $readme .= pts_file_io::file_get_contents(PTS_PATH . 'documentation/stubs/readme-basics.txt') . PHP_EOL . PHP_EOL;
     $readme = wordwrap($readme, 80, PHP_EOL);
     file_put_contents(PTS_PATH . 'README.md', $readme);
     // Phoromatic Documentation
     $pdf = new pts_pdf_template(pts_title(false), 'Phoromatic Documentation');
     $html_doc = new pts_html_template(pts_title(false), 'Phoromatic Documentation');
     $pdf->AddPage();
     $pdf->Image(PTS_CORE_STATIC_PATH . 'images/pts-308x160.png', 69, 85, 73, 38, 'PNG', 'http://www.phoronix-test-suite.com/');
     $pdf->Ln(120);
     $pdf->WriteStatement('www.phoronix-test-suite.com', 'C', 'http://www.phoronix-test-suite.com/');
     $pdf->Ln(15);
     $pdf->Image(PTS_CORE_STATIC_PATH . 'images/phoromatic-390x56.png', 55, 250, 0, 0, 'PNG', 'http://www.phoronix-test-suite.com/');
     //$pdf->Image(PTS_CORE_STATIC_PATH . 'images/phoromatic-390x56.png', 69, 85, 73, 38, 'PNG', 'http://www.phoromatic.com/');
     $pdf->WriteBigHeaderCenter(pts_title(true));
     $pdf->WriteHeaderCenter('Phoromatic User Manual');
     $pdf->html_to_pdf(PTS_PATH . 'documentation/phoromatic.html');
     $pdf_file = PTS_PATH . 'documentation/phoromatic.pdf';
     $pdf->Output($pdf_file);
     echo PHP_EOL . 'Saved To: ' . $pdf_file . PHP_EOL . PHP_EOL;
 }
 public static function generate_extra_data(&$test_result, &$test_log_file = null)
 {
     $parse_xml_file = $test_result->test_profile->get_file_parser_spec();
     if ($parse_xml_file == false) {
         return;
     }
     $results_parser_xml = new pts_parse_results_nye_XmlReader($parse_xml_file);
     $extra_data_identifiers = $results_parser_xml->getXMLArrayValues('PhoronixTestSuite/ExtraData/Identifier');
     $extra_results = array();
     foreach (array_keys($extra_data_identifiers) as $i) {
         $id = $extra_data_identifiers[$i];
         $frame_all_times = array();
         switch ($id) {
             case 'libframetime-output':
                 // libframetime output
                 $line_values = explode(PHP_EOL, file_get_contents($test_log_file));
                 if (!empty($line_values) && isset($line_values[3])) {
                     foreach ($line_values as &$v) {
                         if (substr($v, -3) == ' us' && substr($v, 0, 10) == 'Frametime ') {
                             $frametime = substr($v, 10);
                             $frametime = substr($frametime, 0, -3);
                             if ($frametime > 2000) {
                                 $frametime = $frametime / 1000;
                                 array_push($frame_all_times, $frametime);
                             }
                         }
                     }
                     $frame_all_times = pts_math::remove_outliers($frame_all_times);
                 }
                 break;
             case 'csv-dump-frame-latencies':
                 // Civ Beyond Earth
                 $csv_values = explode(',', pts_file_io::file_get_contents($test_log_file));
                 if (!empty($csv_values) && isset($csv_values[3])) {
                     foreach ($csv_values as $i => &$v) {
                         if (!is_numeric($v)) {
                             unset($csv_values[$i]);
                             continue;
                         }
                         array_push($frame_all_times, $v);
                     }
                 }
                 break;
             case 'com-speeds-frame-latency-totals':
                 // id Tech Games
                 $log_file = pts_file_io::file_get_contents($test_log_file);
                 $frame_all_times = array();
                 while ($log_file = strstr($log_file, 'frame:')) {
                     if (($a = strpos($log_file, ' all: ')) !== false && $a < strpos($log_file, "\n")) {
                         $all = ltrim(substr($log_file, $a + 6));
                         $all = substr($all, 0, strpos($all, ' '));
                         if (is_numeric($all) && $all > 0) {
                             array_push($frame_all_times, $all);
                         }
                     }
                     $log_file = strstr($log_file, 'bk:');
                 }
                 break;
         }
         if (isset($frame_all_times[60])) {
             // Take off the first frame as it's likely to have taken much longer when game just starting off...
             array_shift($frame_all_times);
             $tp = clone $test_result->test_profile;
             $tp->set_result_scale('Milliseconds');
             $tp->set_result_proportion('LIB');
             $tp->set_display_format('LINE_GRAPH');
             $tp->set_identifier(null);
             $extra_result = new pts_test_result($tp);
             $extra_result->active = new pts_test_result_buffer_active();
             $extra_result->set_used_arguments_description('Total Frame Time');
             $extra_result->active->set_result(implode(',', $frame_all_times));
             array_push($extra_results, $extra_result);
             //$extra_result->set_used_arguments(phodevi::sensor_name($sensor) . ' ' . $test_result->get_arguments());
         }
     }
     if (!empty($extra_results)) {
         $test_result->secondary_linked_results = $extra_results;
     }
 }
示例#19
0
 public static function available_phoromatic_servers()
 {
     $phoromatic_servers = array();
     $possible_servers = pts_network::find_zeroconf_phoromatic_servers(true);
     foreach (self::$phoromatic_servers as $server) {
         array_push($possible_servers, array($server['ip'], $server['http_port']));
     }
     $user_config_phoromatic_servers = pts_config::read_user_config('PhoronixTestSuite/Options/General/PhoromaticServers', '');
     foreach (explode(',', $user_config_phoromatic_servers) as $static_server) {
         $static_server = explode(':', $static_server);
         if (count($static_server) == 2) {
             array_push($possible_servers, array($static_server[0], $static_server[1]));
         }
     }
     if (is_file(PTS_USER_PATH . 'phoromatic-servers')) {
         $phoromatic_servers_file = pts_file_io::file_get_contents(PTS_USER_PATH . 'phoromatic-servers');
         foreach (explode(PHP_EOL, $phoromatic_servers_file) as $ps_file_line) {
             $ps_file_line = explode(':', trim($ps_file_line));
             if (count($ps_file_line) == 2 && ip2long($ps_file_line[0]) !== false && is_numeric($ps_file_line) && $ps_file_line > 100) {
                 array_push($possible_servers, array($ps_file_line[0], $ps_file_line[1]));
             }
         }
     }
     foreach ($possible_servers as $possible_server) {
         // possible_server[0] is the Phoromatic Server IP
         // possible_server[1] is the Phoromatic Server HTTP PORT
         if (in_array($possible_server[0], array_keys($phoromatic_servers))) {
             continue;
         }
         $server_response = pts_network::http_get_contents('http://' . $possible_server[0] . ':' . $possible_server[1] . '/server.php', false, false, 3);
         if (stripos($server_response, 'Phoromatic') !== false) {
             trigger_error('Phoromatic Server Auto-Detected At: ' . $possible_server[0] . ':' . $possible_server[1], E_USER_NOTICE);
             $phoromatic_servers[$possible_server[0]] = array('ip' => $possible_server[0], 'http_port' => $possible_server[1]);
         }
     }
     return $phoromatic_servers;
 }
示例#20
0
 protected static function process_user_config_external_hook_process($process)
 {
     // Check to not run the same process
     $last_call_file = pts_module::save_dir() . self::$context . '.last-call';
     if (is_file($last_call_file)) {
         $check = pts_file_io::file_get_contents($last_call_file);
         if ($process == $check) {
             unlink($last_call_file);
             return false;
         }
     }
     $process != 'post_run' && file_put_contents($last_call_file, $process);
     if (self::$ini['set_context'][$process]) {
         $command = self::find_file(self::$ini['set_context'][$process]) ? self::find_file(self::$ini['set_context'][$process]) : self::$ini['set_context'][$process];
         $descriptor_spec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
         $env_vars = null;
         pts_client::$display->test_run_instance_error('Running ' . $process . ' set-context script.');
         if (is_executable($command)) {
             // Pass the context as the first argument to the string
             $command .= ' ' . self::$context;
         } else {
             // Else find $MATISK_CONTEXT in the command string
             $command = str_replace('$MATISK_CONTEXT', self::$context, $command);
         }
         $proc = proc_open($command, $descriptor_spec, $pipes, null, $env_vars);
         echo $std_output = stream_get_contents($pipes[1]);
         $return_value = proc_close($proc);
         if (pts_strings::string_bool(self::$ini['set_context']['log_context_outputs'])) {
             file_put_contents(pts_module::save_dir() . $ini['workload']['save_name'] . '/' . self::$context . '-' . $process . '.txt', $std_output);
         }
         switch ($return_value) {
             case 8:
                 exit(0);
             case 9:
                 self::$skip_test_set = true;
                 break;
         }
     }
 }
示例#21
0
 public static function system_uptime()
 {
     // Returns the system's uptime in seconds
     $uptime = 1;
     if (is_file('/proc/uptime')) {
         $uptime = pts_strings::first_in_string(pts_file_io::file_get_contents('/proc/uptime'));
     } else {
         if (($uptime_cmd = pts_client::executable_in_path('uptime')) != false) {
             $uptime_counter = 0;
             $uptime_output = shell_exec($uptime_cmd . ' 2>&1');
             $uptime_output = substr($uptime_output, strpos($uptime_output, ' up') + 3);
             $uptime_output = substr($uptime_output, 0, strpos($uptime_output, ' user'));
             $uptime_output = substr($uptime_output, 0, strrpos($uptime_output, ',')) . ' ';
             if (($day_end_pos = strpos($uptime_output, ' day')) !== false) {
                 $day_output = substr($uptime_output, 0, $day_end_pos);
                 $day_output = substr($day_output, strrpos($day_output, ' ') + 1);
                 if (is_numeric($day_output)) {
                     $uptime_counter += $day_output * 86400;
                 }
             }
             if (($mins_end_pos = strpos($uptime_output, ' mins')) !== false) {
                 $mins_output = substr($uptime_output, 0, $day_end_pos);
                 $mins_output = substr($mins_output, strrpos($mins_output, ' ') + 1);
                 if (is_numeric($mins_output)) {
                     $uptime_counter += $mins_output * 60;
                 }
             }
             if (($time_split_pos = strpos($uptime_output, ':')) !== false) {
                 $hours_output = substr($uptime_output, 0, $time_split_pos);
                 $hours_output = substr($hours_output, strrpos($hours_output, ' ') + 1);
                 $mins_output = substr($uptime_output, $time_split_pos + 1);
                 $mins_output = substr($mins_output, 0, strpos($mins_output, ' '));
                 if (is_numeric($hours_output)) {
                     $uptime_counter += $hours_output * 3600;
                 }
                 if (is_numeric($mins_output)) {
                     $uptime_counter += $mins_output * 60;
                 }
             }
             if (is_numeric($uptime_counter) && $uptime_counter > 0) {
                 $uptime = $uptime_counter;
             }
         }
     }
     return intval($uptime);
 }
示例#22
0
 public function read_sensor()
 {
     // Graphics processor real/current frequency
     $show_memory = false;
     $core_freq = 0;
     $mem_freq = 0;
     if (phodevi::is_nvidia_graphics()) {
         $nv_freq = phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs');
         $nv_freq = pts_strings::comma_explode($nv_freq);
         $core_freq = isset($nv_freq[0]) ? $nv_freq[0] : 0;
         $mem_freq = isset($nv_freq[1]) ? $nv_freq[1] : 0;
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentClocks');
             if (is_array($od_clocks) && count($od_clocks) >= 2) {
                 $core_freq = array_shift($od_clocks);
                 $mem_freq = array_pop($od_clocks);
             }
         } else {
             if (phodevi::is_linux()) {
                 if (isset(phodevi::$vfs->radeon_pm_info)) {
                     // radeon_pm_info should be present with Linux 2.6.34+
                     foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) {
                         $pm_line = pts_strings::colon_explode($pm_line);
                         if (isset($pm_line[1])) {
                             list($descriptor, $value) = $pm_line;
                         } else {
                             continue;
                         }
                         switch ($descriptor) {
                             case 'current engine clock':
                                 $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                             case 'current memory clock':
                                 $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                         }
                     }
                     if ($core_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'sclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $core_freq = $x;
                         }
                     }
                     if ($mem_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'mclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $mem_freq = $x;
                         }
                     }
                 } else {
                     if (is_file('/sys/class/drm/card0/gt_cur_freq_mhz')) {
                         $gt_cur_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_cur_freq_mhz');
                         if ($gt_cur_freq_mhz > 2) {
                             $core_freq = $gt_cur_freq_mhz;
                         }
                     } else {
                         if (is_file('/sys/class/drm/card0/device/performance_level')) {
                             $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level');
                             $performance_level = explode(' ', $performance_level);
                             $core_string = array_search('core', $performance_level);
                             if ($core_string !== false && isset($performance_level[$core_string + 1])) {
                                 $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]);
                                 if (is_numeric($core_string) && $core_string > $core_freq) {
                                     $core_freq = $core_string;
                                 }
                             }
                             $mem_string = array_search('memory', $performance_level);
                             if ($mem_string !== false && isset($performance_level[$mem_string + 1])) {
                                 $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]);
                                 if (is_numeric($mem_string) && $mem_string > $mem_freq) {
                                     $mem_freq = $mem_string;
                                 }
                             }
                         } else {
                             if (isset(phodevi::$vfs->i915_cur_delayinfo)) {
                                 $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo;
                                 $cagf = strpos($i915_cur_delayinfo, 'CAGF: ');
                                 if ($cagf !== false) {
                                     $cagf_mhz = substr($i915_cur_delayinfo, $cagf + 6);
                                     $cagf_mhz = substr($cagf_mhz, 0, strpos($cagf_mhz, 'MHz'));
                                     if (is_numeric($cagf_mhz)) {
                                         $core_freq = $cagf_mhz;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!is_numeric($core_freq)) {
         $core_freq = 0;
     }
     if (!is_numeric($mem_freq)) {
         $mem_freq = 0;
     }
     if ($core_freq == 0 && $mem_freq == 0) {
         $show_memory = false;
         $core_freq = -1;
     }
     return $show_memory ? array($core_freq, $mem_freq) : $core_freq;
 }
 public static function monitor_string()
 {
     $monitor = null;
     if (phodevi::is_macosx()) {
         $system_profiler = shell_exec('system_profiler SPDisplaysDataType 2>&1');
         $system_profiler = substr($system_profiler, strrpos($system_profiler, 'Displays:'));
         $system_profiler = substr($system_profiler, strpos($system_profiler, "\n"));
         $monitor = trim(substr($system_profiler, 0, strpos($system_profiler, ':')));
         if ($monitor == 'Display Connector') {
             $monitor = null;
         }
     } else {
         if (phodevi::is_nvidia_graphics() && isset(phodevi::$vfs->xorg_log)) {
             $log_parse = phodevi::$vfs->xorg_log;
             $offset = 0;
             $monitor = array();
             /* e.g.
             			$ cat /var/log/Xorg.0.log | grep -i connected
             			[    18.174] (--) NVIDIA(0):     Acer P243W (DFP-0) (connected)
             			[    18.174] (--) NVIDIA(0):     Acer AL2223W (DFP-1) (connected)
             			*/
             while (($monitor_pos = strpos($log_parse, ') (connected)', $offset)) !== false || ($monitor_pos = strpos($log_parse, ') (boot, connected)', $offset)) !== false) {
                 $m = substr($log_parse, 0, $monitor_pos);
                 $m = substr($m, strrpos($m, '): ') + 2);
                 $m = trim(substr($m, 0, strpos($m, ' (')));
                 if (!empty($m) && !isset($m[32]) && isset($m[6])) {
                     array_push($monitor, $m);
                 }
                 $offset = $monitor_pos + 2;
             }
             // technically should be fine reporting multiple of the same monitor
             // but fglrx/catalyst as of late 2013 is in habit of reporting monitors twice
             $monitor = array_unique($monitor);
             $monitor = implode(' + ', $monitor);
         } else {
             if (isset(phodevi::$vfs->xorg_log)) {
                 $log_parse = phodevi::$vfs->xorg_log;
                 $offset = 0;
                 $monitor = array();
                 while (($monitor_name = strpos($log_parse, 'Monitor name:', $offset)) !== false) {
                     $log_parse = substr($log_parse, $monitor_name + 14);
                     $m = trim(substr($log_parse, 0, strpos($log_parse, "\n")));
                     if (!empty($m)) {
                         array_push($monitor, $m);
                     }
                 }
                 // technically should be fine reporting multiple of the same monitor
                 // but fglrx/catalyst as of late 2013 is in habit of reporting monitors twice
                 $monitor = array_unique($monitor);
                 $monitor = implode(' + ', $monitor);
             }
         }
     }
     if ($monitor == null && phodevi::is_linux()) {
         // Attempt to find the EDID over sysfs and then decode it for monitor name (0xFC)
         // For at least Intel DRM drivers there is e.g. /sys/class/drm/card0-HDMI-A-2/edid
         // Also works at least for Radeon DRM driver too
         foreach (glob('/sys/class/drm/*/edid') as $edid_file) {
             $edid_file = pts_file_io::file_get_contents($edid_file);
             if ($edid_file == null) {
                 continue;
             }
             $edid = bin2hex($edid_file);
             $x = 0;
             while ($x = strpos($edid, '00fc', $x)) {
                 // 00fc indicates start of EDID monitor descriptor block
                 $encoded = substr($edid, $x + 4, 36);
                 $edid_monitor_name_block = null;
                 for ($i = 0; $i < strlen($encoded); $i += 2) {
                     $hex = substr($encoded, $i, 2);
                     if ($hex == 15 || $hex == '0a') {
                         break;
                     }
                     $ch = chr(hexdec($hex));
                     $edid_monitor_name_block .= $ch;
                 }
                 $edid_monitor_name_block = trim($edid_monitor_name_block);
                 if (pts_strings::string_only_contains($edid_monitor_name_block, pts_strings::CHAR_LETTER | pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL | pts_strings::CHAR_SPACE | pts_strings::CHAR_DASH)) {
                     $monitor = $edid_monitor_name_block;
                     break;
                 }
                 $x++;
             }
             if ($monitor != null) {
                 break;
             }
         }
     }
     return empty($monitor) ? false : $monitor;
 }
示例#24
0
 private static function sys_battery_power()
 {
     // Returns power consumption rate in mW
     $rate = -1;
     if (phodevi::is_linux()) {
         $power_now = phodevi_linux_parser::read_sysfs_node('/sys/class/power_supply/*/power_now', 'POSITIVE_NUMERIC', array('status' => 'Discharging'));
         if ($power_now != -1) {
             // sysfs power_now seems to be displayed in microWatts
             $rate = pts_math::set_precision($power_now / 1000, 2);
         }
         if ($rate == -1) {
             $battery = array('/battery/BAT0/state', '/battery/BAT1/state');
             $state = phodevi_linux_parser::read_acpi($battery, 'charging state');
             $power = phodevi_linux_parser::read_acpi($battery, 'present rate');
             $voltage = phodevi_linux_parser::read_acpi($battery, 'present voltage');
             if ($state == 'discharging') {
                 $power_unit = substr($power, strrpos($power, ' ') + 1);
                 $power = substr($power, 0, strpos($power, ' '));
                 if ($power_unit == 'mA') {
                     $voltage_unit = substr($voltage, strrpos($voltage, ' ') + 1);
                     $voltage = substr($voltage, 0, strpos($voltage, ' '));
                     if ($voltage_unit == 'mV') {
                         $rate = round($power * $voltage / 1000);
                     }
                 } else {
                     if ($power_unit == 'mW') {
                         $rate = $power;
                     }
                 }
             }
         }
         if ($rate == -1 && is_file('/sys/class/power_supply/BAT0/voltage_now') && is_file('/sys/class/power_supply/BAT0/current_now')) {
             $voltage_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT0/voltage_now') / 1000;
             $current_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT0/current_now') / 1000;
             $power_now = $voltage_now * $current_now / 1000;
             if ($power_now > 1) {
                 $rate = $power_now;
             }
         }
         if ($rate == -1 && is_file('/sys/class/power_supply/BAT1/voltage_now') && is_file('/sys/class/power_supply/BAT1/current_now')) {
             $voltage_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT1/voltage_now') / 1000;
             $current_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT1/current_now') / 1000;
             $power_now = $voltage_now * $current_now / 1000;
             if ($power_now > 1) {
                 $rate = $power_now;
             }
         }
     } else {
         if (phodevi::is_macosx()) {
             $amperage = abs(phodevi_osx_parser::read_osx_system_profiler('SPPowerDataType', 'Amperage'));
             // in mA
             $voltage = phodevi_osx_parser::read_osx_system_profiler('SPPowerDataType', 'Voltage');
             // in mV
             if ($amperage > 0 && $voltage > 0) {
                 $rate = round($amperage * $voltage / 1000);
             } else {
                 if (pts_client::executable_in_path('ioreg')) {
                     $ioreg = trim(shell_exec("ioreg -l | grep LegacyBatteryInfo | cut -d '{' -f 2 | tr -d \\} | tr ',' '=' | awk -F'=' '{print (\$2*\$10/10^22)}' 2>&1"));
                     if (is_numeric($ioreg) && $ioreg > 0) {
                         $rate = $ioreg;
                     }
                 }
             }
         } else {
             if (phodevi::is_solaris()) {
                 $battery = phodevi_solaris_parser::read_hal_property('/org/freedesktop/Hal/devices/pseudo/acpi_drv_0_battery0_0', 'battery.reporting.rate');
                 if (is_numeric($battery)) {
                     $rate = $battery;
                 }
             } else {
                 if (phodevi::is_bsd()) {
                     $battery = phodevi_bsd_parser::read_acpiconf('Present rate');
                     if ($battery && substr($battery, -2) == 'mW') {
                         $rate = substr($battery, 0, strpos($battery, ' '));
                     }
                 }
             }
         }
     }
     return $rate;
 }
 public static function get_network_mac()
 {
     $mac = false;
     foreach (pts_file_io::glob('/sys/class/net/*/operstate') as $net_device_state) {
         if (pts_file_io::file_get_contents($net_device_state) == 'up') {
             $addr = dirname($net_device_state) . '/address';
             if (is_file($addr)) {
                 $mac = pts_file_io::file_get_contents($addr);
                 break;
             }
         }
     }
     if (empty($mac) && ($ifconfig = pts_client::executable_in_path('ifconfig'))) {
         $ifconfig = shell_exec($ifconfig . ' 2>&1');
         $offset = 0;
         while (($hwaddr_pos = strpos($ifconfig, 'HWaddr ', $offset)) !== false || ($hwaddr_pos = strpos($ifconfig, 'ether ', $offset)) !== false) {
             $hw_addr = substr($ifconfig, $hwaddr_pos);
             $hw_addr = substr($hw_addr, strpos($hw_addr, ' ') + 1);
             $hw_addr = substr($hw_addr, 0, strpos($hw_addr, ' '));
             $mac = $hw_addr;
             if ($mac != null) {
                 break;
             }
             $offset = $hwaddr_pos + 1;
         }
     }
     return $mac;
 }
 public static function sw_dri_display_driver()
 {
     $dri_driver = false;
     if (is_file('/proc/driver/nvidia/version')) {
         $dri_driver = 'nvidia';
     } else {
         if (is_file('/proc/dri/0/name')) {
             $driver_info = file_get_contents('/proc/dri/0/name');
             $dri_driver = substr($driver_info, 0, strpos($driver_info, ' '));
             if (in_array($dri_driver, array('i915', 'i965'))) {
                 $dri_driver = 'intel';
             }
         } else {
             if (is_file('/sys/class/drm/card0/device/vendor')) {
                 $vendor_id = pts_file_io::file_get_contents('/sys/class/drm/card0/device/vendor');
                 switch ($vendor_id) {
                     case 0x1002:
                         $dri_driver = 'radeon';
                         break;
                     case 0x8086:
                         $dri_driver = 'intel';
                         break;
                     case 0x10de:
                         // NVIDIA
                         $dri_driver = 'nouveau';
                         break;
                 }
             }
         }
     }
     return $dri_driver;
 }
 public static function read_sys_dmi($identifier)
 {
     $dmi = false;
     if (is_dir('/sys/class/dmi/id/')) {
         $ignore_words = phodevi_parser::hardware_values_to_remove();
         foreach (pts_arrays::to_array($identifier) as $id) {
             if (is_readable('/sys/class/dmi/id/' . $id)) {
                 $dmi_file = pts_file_io::file_get_contents('/sys/class/dmi/id/' . $id);
                 if (!empty($dmi_file) && !in_array(strtolower($dmi_file), $ignore_words)) {
                     $dmi = $dmi_file;
                     break;
                 }
             }
         }
     }
     return $dmi;
 }
 public static function gpu_model()
 {
     // Report graphics processor string
     $info = phodevi_parser::read_glx_renderer();
     $video_ram = phodevi::read_property('gpu', 'memory-capacity');
     if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
         $crossfire_status = phodevi_linux_parser::read_amd_pcsdb('SYSTEM/Crossfire/chain/*,Enable');
         $crossfire_status = pts_arrays::to_array($crossfire_status);
         $crossfire_card_count = 0;
         for ($i = 0; $i < count($crossfire_status); $i++) {
             if ($crossfire_status[$i] == '0x00000001') {
                 $crossfire_card_count += 2;
                 // For now assume each chain is 2 cards, but proper way would be NumSlaves + 1
             }
         }
         $adapters = phodevi_linux_parser::read_amd_graphics_adapters();
         if (count($adapters) > 0) {
             $video_ram = $video_ram > 64 ? ' ' . $video_ram . 'MB' : null;
             // assume more than 64MB of vRAM
             if ($crossfire_card_count > 1 && $crossfire_card_count <= count($adapters)) {
                 $unique_adapters = array_unique($adapters);
                 if (count($unique_adapters) == 1) {
                     if (strpos($adapters[0], 'X2') > 0 && $crossfire_card_count > 1) {
                         $crossfire_card_count -= 1;
                     }
                     $info = $crossfire_card_count . ' x ' . $adapters[0] . $video_ram . ' CrossFire';
                 } else {
                     $info = implode(', ', $unique_adapters) . ' CrossFire';
                 }
             } else {
                 $info = $adapters[0] . $video_ram;
             }
         }
     } else {
         if (phodevi::is_macosx()) {
             $system_profiler_info = implode(' + ', phodevi_osx_parser::read_osx_system_profiler('SPDisplaysDataType', 'ChipsetModel', true));
             if (!empty($system_profiler_info)) {
                 $info = $system_profiler_info;
             }
         } else {
             if (phodevi::is_nvidia_graphics()) {
                 if ($info == null) {
                     if (pts_client::executable_in_path('nvidia-settings')) {
                         $nv_gpus = shell_exec('nvidia-settings -q gpus 2>&1');
                         // TODO: search for more than one GPU
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '[0]'));
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '(') + 1);
                         $nv_gpus = substr($nv_gpus, 0, strpos($nv_gpus, ')'));
                         if (stripos($nv_gpus, 'GeForce') !== false || stripos($nv_gpus, 'Quadro') !== false) {
                             $info = $nv_gpus;
                         }
                     }
                 }
                 $sli_mode = phodevi_parser::read_nvidia_extension('SLIMode');
                 if (!empty($sli_mode) && $sli_mode != 'Off') {
                     $info .= ' SLI';
                 }
             } else {
                 if (phodevi::is_solaris()) {
                     if (($cut = strpos($info, 'DRI ')) !== false) {
                         $info = substr($info, $cut + 4);
                     }
                     if (($cut = strpos($info, ' Chipset')) !== false) {
                         $info = substr($info, 0, $cut);
                     }
                     if ($info == false && isset(phodevi::$vfs->xorg_log)) {
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 14);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (($c = strpos($xorg_log, '[')) || ($c = strpos($xorg_log, '('))) {
                                 $xorg_log = substr($xorg_log, 0, $c);
                             }
                             if (phodevi::is_product_string($xorg_log)) {
                                 $info = $xorg_log;
                             }
                         }
                     }
                 } else {
                     if (phodevi::is_bsd()) {
                         $drm_info = phodevi_bsd_parser::read_sysctl('dev.drm.0.%desc');
                         if (!$drm_info) {
                             $drm_info = phodevi_bsd_parser::read_sysctl('dev.nvidia.0.%desc');
                         }
                         if (!$drm_info) {
                             $agp_info = phodevi_bsd_parser::read_sysctl('dev.agp.0.%desc');
                             if ($agp_info != false) {
                                 $info = $agp_info;
                             }
                         } else {
                             $info = $drm_info;
                         }
                         if ($info == null && isset(phodevi::$vfs->xorg_log)) {
                             $xorg_log = phodevi::$vfs->xorg_log;
                             if (($e = strpos($xorg_log, ' at 01@00:00:0')) !== false) {
                                 $xorg_log = substr($xorg_log, 0, $e);
                                 $info = substr($xorg_log, strrpos($xorg_log, 'Found ') + 6);
                             }
                         }
                     } else {
                         if (phodevi::is_windows()) {
                             $info = phodevi_windows_parser::read_cpuz('Display Adapters', 'Name');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info) || strpos($info, 'Mesa ') !== false || strpos($info, 'Gallium ') !== false) {
         if (phodevi::is_windows() == false) {
             $info_pci = phodevi_linux_parser::read_pci('VGA compatible controller', false);
             if (!empty($info_pci)) {
                 $info = $info_pci;
                 if (strpos($info, 'Intel 2nd Generation Core Family') !== false || strpos($info, 'Gen Core') !== false) {
                     // Try to come up with a better non-generic string
                     $was_reset = false;
                     if (isset(phodevi::$vfs->xorg_log)) {
                         /*
                         $ cat /var/log/Xorg.0.log | grep -i Chipset
                         [     8.421] (II) intel: Driver for Intel Integrated Graphics Chipsets: i810,
                         [     8.421] (II) VESA: driver for VESA chipsets: vesa
                         [     8.423] (II) intel(0): Integrated Graphics Chipset: Intel(R) Sandybridge Mobile (GT2+)
                         [     8.423] (--) intel(0): Chipset: "Sandybridge Mobile (GT2+)"
                         */
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, 'Integrated Graphics Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 29);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (stripos($xorg_log, 'Intel') === false) {
                                 $xorg_log = 'Intel ' . $xorg_log;
                             }
                             // if string is too long, likely not product
                             if (!isset($xorg_log[45])) {
                                 $info = $xorg_log;
                                 $was_reset = true;
                             }
                         } else {
                             if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                                 $xorg_log = substr($xorg_log, $x + 14);
                                 $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                                 if (stripos($xorg_log, 'Intel') === false) {
                                     $xorg_log = 'Intel ' . $xorg_log;
                                 }
                                 // if string is too long, likely not product
                                 if (!isset($xorg_log[45])) {
                                     $info = $xorg_log;
                                     $was_reset = true;
                                 }
                             }
                         }
                     }
                     if ($was_reset == false && isset(phodevi::$vfs->i915_capabilities)) {
                         $i915_caps = phodevi::$vfs->i915_capabilities;
                         if (($x = strpos($i915_caps, 'gen: ')) !== false) {
                             $gen = substr($i915_caps, $x + 5);
                             $gen = substr($gen, 0, strpos($gen, PHP_EOL));
                             if (is_numeric($gen)) {
                                 $info = 'Intel Gen' . $gen;
                                 if (strpos($i915_caps, 'is_mobile: yes') !== false) {
                                     $info .= ' Mobile';
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (($start_pos = strpos($info, ' DRI ')) > 0) {
             $info = substr($info, $start_pos + 5);
         }
         if (empty($info) && isset(phodevi::$vfs->xorg_log)) {
             $log_parse = phodevi::$vfs->xorg_log;
             $log_parse = substr($log_parse, strpos($log_parse, 'Chipset') + 8);
             $log_parse = substr($log_parse, 0, strpos($log_parse, 'found'));
             if (strpos($log_parse, '(--)') === false && strlen(str_ireplace(array('ATI', 'NVIDIA', 'VIA', 'Intel'), '', $log_parse)) != strlen($log_parse)) {
                 $info = $log_parse;
             }
         }
         if (empty($info) && is_readable('/sys/class/graphics/fb0/name')) {
             switch (pts_file_io::file_get_contents('/sys/class/graphics/fb0/name')) {
                 case 'omapdrm':
                     $info = 'Texas Instruments OMAP';
                     // The OMAP DRM driver currently is for OMAP2/3/4 hardware
                     break;
                 case 'exynos':
                     $info = 'Samsung EXYNOS';
                     // The Exynos DRM driver
                     break;
                 case 'tegra_fb':
                     $info = 'NVIDIA TEGRA';
                     // The Exynos DRM driver
                     break;
                 default:
                     if (is_file('/dev/mali')) {
                         $info = 'ARM Mali';
                         // One of the ARM Mali models
                     }
                     break;
             }
         }
         if (substr($info, -1) == ')' && ($open_p = strrpos($info, '(')) != false) {
             $end_check = strpos($info, ' ', $open_p);
             $to_check = substr($info, $open_p + 1, $end_check - $open_p - 1);
             // Don't report card revision from PCI info
             if ($to_check == 'rev') {
                 $info = substr($info, 0, $open_p - 1);
             }
         }
     }
     if (($bracket_open = strpos($info, '[')) !== false) {
         // Report only the information inside the brackets if it's more relevant...
         // Mainly with Linux systems where the PCI information is reported like 'nVidia GF104 [GeForce GTX 460]'
         if (($bracket_close = strpos($info, ']', $bracket_open + 1)) !== false) {
             $inside_bracket = substr($info, $bracket_open + 1, $bracket_close - $bracket_open - 1);
             if (stripos($inside_bracket, 'Quadro') !== false || stripos($inside_bracket, 'GeForce') !== false) {
                 $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
             } else {
                 if (stripos($inside_bracket, 'Radeon') !== false || stripos($inside_bracket, 'Fire') !== false || stripos($inside_bracket, 'Fusion') !== false) {
                     $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
                 }
             }
         }
     }
     if (stripos($info, 'NVIDIA') === false && (stripos($info, 'Quadro') !== false || stripos($info, 'GeForce') !== false)) {
         $info = 'NVIDIA' . ' ' . $info;
     } else {
         if (stripos($info, 'ATI') === false && stripos($info, 'AMD') === false && (stripos($info, 'Radeon') !== false || stripos($info, 'Fire') !== false || stripos($info, 'Fusion') !== false)) {
             // Fire would be for FireGL or FirePro hardware
             $info = 'AMD ' . $info;
         }
     }
     if (phodevi::is_linux() && ($vendor = phodevi_linux_parser::read_pci_subsystem_value('VGA compatible controller')) != null && stripos($info, $vendor) === false && (stripos($info, 'AMD') !== false || stripos($info, 'NVIDIA') !== false)) {
         $info = $vendor . ' ' . $info;
     }
     if ($video_ram > 64 && strpos($info, $video_ram) == false) {
         $info .= ' ' . $video_ram . 'MB';
     }
     $clean_phrases = array('OpenGL Engine');
     $info = str_replace($clean_phrases, null, $info);
     return $info;
 }
 protected static function install_test_process(&$test_install_request, $no_prompts)
 {
     // Install a test
     $identifier = $test_install_request->test_profile->get_identifier();
     $test_install_directory = $test_install_request->test_profile->get_install_dir();
     pts_file_io::mkdir(dirname($test_install_directory));
     pts_file_io::mkdir($test_install_directory);
     $installed = false;
     if (ceil(disk_free_space($test_install_directory) / 1048576) < $test_install_request->test_profile->get_download_size() + 128) {
         self::test_install_error(null, $test_install_request, 'There is not enough space at ' . $test_install_directory . ' for the test files.');
     } else {
         if (ceil(disk_free_space($test_install_directory) / 1048576) < $test_install_request->test_profile->get_environment_size(false) + 128) {
             self::test_install_error(null, $test_install_request, 'There is not enough space at ' . $test_install_directory . ' for this test.');
         } else {
             pts_test_installer::setup_test_install_directory($test_install_request, true);
             // Download test files
             $download_test_files = pts_test_installer::download_test_files($test_install_request, false, $no_prompts);
             if ($download_test_files == false) {
                 self::test_install_error(null, $test_install_request, 'Downloading of needed test files failed.');
                 return false;
             }
             if ($test_install_request->test_profile->get_file_installer() != false) {
                 self::create_compiler_mask($test_install_request);
                 pts_module_manager::module_process('__pre_test_install', $identifier);
                 pts_client::$display->test_install_begin($test_install_request);
                 $pre_install_message = $test_install_request->test_profile->get_pre_install_message();
                 $post_install_message = $test_install_request->test_profile->get_post_install_message();
                 $install_agreement = $test_install_request->test_profile->get_installation_agreement_message();
                 if (!empty($install_agreement)) {
                     if (pts_strings::is_url($install_agreement)) {
                         $install_agreement = pts_network::http_get_contents($install_agreement);
                         if (empty($install_agreement)) {
                             self::test_install_error(null, $test_install_request, 'The user agreement could not be found. Test installation aborted.');
                             return false;
                         }
                     }
                     echo $install_agreement . PHP_EOL;
                     if (!$no_prompts) {
                         $user_agrees = pts_user_io::prompt_bool_input('Do you agree to these terms', false, 'INSTALL_AGREEMENT');
                         if (!$user_agrees) {
                             self::test_install_error(null, $test_install_request, 'User agreement failed; this test will not be installed.');
                             return false;
                         }
                     }
                 }
                 pts_client::$display->display_interrupt_message($pre_install_message);
                 $install_time_length_start = microtime(true);
                 $install_log = pts_tests::call_test_script($test_install_request->test_profile, 'install', null, $test_install_directory, $test_install_request->special_environment_vars, false);
                 $test_install_request->install_time_duration = ceil(microtime(true) - $install_time_length_start);
                 pts_client::$display->display_interrupt_message($post_install_message);
                 if (!empty($install_log)) {
                     file_put_contents($test_install_directory . 'install.log', $install_log);
                     pts_file_io::unlink($test_install_directory . 'install-failed.log');
                     pts_client::$display->test_install_output($install_log);
                 }
                 if (is_file($test_install_directory . 'install-exit-status')) {
                     // If the installer writes its exit status to ~/install-exit-status, if it's non-zero the install failed
                     $install_exit_status = pts_file_io::file_get_contents($test_install_directory . 'install-exit-status');
                     unlink($test_install_directory . 'install-exit-status');
                     if ($install_exit_status != 0 && phodevi::is_windows() == false) {
                         $install_error = null;
                         // TODO: perhaps better way to handle this than to remove pts-install.xml
                         pts_file_io::unlink($test_install_directory . 'pts-install.xml');
                         if (is_file($test_install_directory . 'install.log')) {
                             $install_log = pts_file_io::file_get_contents($test_install_directory . 'install.log');
                             $install_error = pts_tests::scan_for_error($install_log, $test_install_directory);
                             copy($test_install_directory . 'install.log', $test_install_directory . 'install-failed.log');
                         }
                         //pts_test_installer::setup_test_install_directory($test_install_request, true); // Remove installed files from the bunked installation
                         self::test_install_error(null, $test_install_request, 'The installer exited with a non-zero exit status.');
                         if ($install_error != null) {
                             $test_install_request->install_error = pts_tests::pretty_error_string($install_error);
                             if ($test_install_request->install_error != null) {
                                 self::test_install_error(null, $test_install_request, 'ERROR: ' . $test_install_request->install_error);
                             }
                         }
                         pts_client::$display->test_install_error('LOG: ' . str_replace(pts_core::user_home_directory(), '~/', $test_install_directory) . 'install-failed.log' . PHP_EOL);
                         if (pts_client::do_anonymous_usage_reporting()) {
                             // If anonymous usage reporting enabled, report test install failure to OpenBenchmarking.org
                             pts_openbenchmarking_client::upload_usage_data('test_install_failure', array($test_install_request, $install_error));
                         }
                         return false;
                     }
                 }
                 pts_module_manager::module_process('__post_test_install', $identifier);
                 $installed = true;
                 if (pts_config::read_bool_config('PhoronixTestSuite/Options/Installation/RemoveDownloadFiles', 'FALSE')) {
                     // Remove original downloaded files
                     foreach ($test_install_request->get_download_objects() as $download_object) {
                         pts_file_io::unlink($test_install_directory . $download_object->get_filename());
                     }
                 }
             } else {
                 pts_client::$display->test_install_error('No installation script found.');
                 $installed = true;
             }
             // Additional validation checks?
             $custom_validated_output = pts_tests::call_test_script($test_install_request->test_profile, 'validate-install', PHP_EOL . 'Validating Installation...' . PHP_EOL, $test_install_directory, null, false);
             if (!empty($custom_validated_output) && !pts_strings::string_bool($custom_validated_output)) {
                 $installed = false;
             }
         }
     }
     echo PHP_EOL;
     return $installed;
 }
 public static function motherboard_string()
 {
     // Returns the motherboard / system model name or number
     $info = null;
     if (phodevi::is_macosx()) {
         $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ModelName');
     } else {
         if (phodevi::is_solaris()) {
             $manufacturer = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Manufacturer', 'SystemInformation,Manufacturer'));
             $product = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Product', 'SystemInformation,Product', 'SystemInformation,Model'));
             if (count($manufacturer) == 1 && count($product) == 1) {
                 $info = $manufacturer[0] . ' ' . $product[0];
             }
         } else {
             if (phodevi::is_bsd()) {
                 $vendor = phodevi_bsd_parser::read_kenv('smbios.system.maker');
                 $product = phodevi_bsd_parser::read_kenv('smbios.system.product');
                 $version = phodevi_bsd_parser::read_kenv('smbios.system.version');
                 // for at least Lenovo ThinkPads this is where it displays ThinkPad model
                 if ($vendor != null && ($product != null || $version != null)) {
                     $info = $vendor . ' ' . $product . ' ' . $version;
                 } else {
                     if (($vendor = phodevi_bsd_parser::read_sysctl('hw.vendor')) != false && ($version = phodevi_bsd_parser::read_sysctl(array('hw.version', 'hw.product'))) != false) {
                         $info = trim($vendor . ' ' . $version);
                     } else {
                         if (($acpi = phodevi_bsd_parser::read_sysctl('dev.acpi.0.%desc')) != false) {
                             $info = trim($acpi);
                         }
                     }
                 }
             } else {
                 if (phodevi::is_linux()) {
                     $vendor = phodevi_linux_parser::read_sys_dmi(array('board_vendor', 'sys_vendor'));
                     $name = phodevi_linux_parser::read_sys_dmi(array('board_name', 'product_name'));
                     $version = phodevi_linux_parser::read_sys_dmi(array('board_version', 'product_version'));
                     if ($vendor != false && $name != false) {
                         $info = strpos($name . ' ', $vendor . ' ') === false ? $vendor . ' ' : null;
                         $info .= $name;
                         if ($version != false && strpos($info, $version) === false && pts_strings::string_only_contains($version, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL)) {
                             $info .= (substr($version, 0, 1) == 'v' ? ' ' : ' v') . $version;
                         }
                     }
                     if (empty($info)) {
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('Hardware');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                         $bios_vendor = phodevi_linux_parser::read_sys_dmi('bios_vendor');
                         $bios_version = phodevi_linux_parser::read_sys_dmi('bios_version');
                         if ($bios_vendor != null) {
                             $info = $bios_vendor . ' ' . $bios_version;
                         }
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('machine');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                     }
                     if (empty($info)) {
                         $info = phodevi_linux_parser::read_sys_dmi('product_name');
                     }
                     if (empty($info) && is_file('/sys/bus/soc/devices/soc0/machine')) {
                         $info = pts_file_io::file_get_contents('/sys/bus/soc/devices/soc0/machine');
                     }
                     if (empty($info)) {
                         // Works on the MIPS Creator CI20
                         $hardware = phodevi_linux_parser::read_cpuinfo('Hardware');
                         if (!empty($hardware)) {
                             $info = array_pop($hardware);
                         }
                     }
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Mainboard Model', null);
                     }
                 }
             }
         }
     }
     if ((strpos($info, 'Mac ') !== false || strpos($info, 'MacBook') !== false) && strpos($info, 'Apple') === false) {
         $info = 'Apple ' . $info;
     }
     // ensure words aren't repeated (e.g. VMware VMware Virtual and MSI MSI X58M (MS-7593))
     $info = implode(' ', array_unique(explode(' ', $info)));
     return $info;
 }