public static function network_device_string()
 {
     $network = array();
     if (phodevi::is_macosx()) {
         // TODO: implement
     } else {
         if (phodevi::is_bsd()) {
             foreach (array('dev.em.0.%desc', 'dev.wpi.0.%desc', 'dev.mskc.0.%desc') as $controller) {
                 $pci = phodevi_bsd_parser::read_sysctl($controller);
                 if (!empty($pci)) {
                     array_push($network, $pci);
                 }
             }
         } else {
             if (phodevi::is_windows()) {
                 // TODO: implement
             } else {
                 if (phodevi::is_linux()) {
                     foreach (array('Ethernet controller', 'Network controller') as $controller) {
                         $pci = phodevi_linux_parser::read_pci($controller);
                         if (!empty($pci)) {
                             array_push($network, $pci);
                         }
                     }
                 }
             }
         }
     }
     return implode(' + ', $network);
 }
 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 install_dependencies(&$test_profiles)
 {
     // PTS External Dependencies install on distribution
     if (phodevi::is_windows() || phodevi::is_macosx() || pts_flags::no_external_dependencies()) {
         // Windows doesn't use any external dependencies
         return true;
     }
     // Find all the tests that need to be checked
     $tests_to_check = array();
     foreach ($test_profiles as $test_profile) {
         if (!in_array($test_profile, $tests_to_check) && $test_profile->is_supported()) {
             array_push($tests_to_check, $test_profile);
         }
     }
     // Find all of the POSSIBLE test dependencies
     $required_test_dependencies = array();
     foreach ($tests_to_check as &$test_profile) {
         foreach ($test_profile->get_dependencies() as $test_dependency) {
             if (empty($test_dependency)) {
                 continue;
             }
             if (isset($required_test_dependencies[$test_dependency]) == false) {
                 $required_test_dependencies[$test_dependency] = array();
             }
             array_push($required_test_dependencies[$test_dependency], $test_profile);
         }
     }
     if (pts_c::$test_flags & pts_c::skip_tests_with_missing_dependencies) {
         // Remove tests that have external dependencies that aren't satisfied and then return
         $generic_packages_needed = array();
         $required_test_dependencies_copy = $required_test_dependencies;
         $dependencies_to_install = self::check_dependencies_missing_from_system($required_test_dependencies_copy, $generic_packages_needed);
         self::remove_tests_with_missing_dependencies($test_profiles, $generic_packages_needed, $required_test_dependencies);
         return true;
     }
     if (!empty($required_test_dependencies)) {
         // The 'common-dependencies' package is any general non-explicitly-required but nice-to-have packages like mesa-utils for providing glxinfo about the system
         // So if we're going to be installing external dependencies anyways, might as well try to see the common-dependencies are satisfied
         $required_test_dependencies['common-dependencies'] = array();
     }
     // Does the user wish to skip any particular dependencies?
     if (pts_client::read_env('SKIP_EXTERNAL_DEPENDENCIES')) {
         $dependencies_to_skip = explode(',', pts_client::read_env('SKIP_EXTERNAL_DEPENDENCIES'));
         foreach ($dependencies_to_skip as $dependency_name) {
             if (isset($required_test_dependencies[$dependency_name])) {
                 unset($required_test_dependencies[$dependency_name]);
             }
         }
     }
     // Make a copy for use to check at end of process to see if all dependencies were actually found
     $required_test_dependencies_copy = $required_test_dependencies;
     // Find the dependencies that are actually missing from the system
     $dependencies_to_install = self::check_dependencies_missing_from_system($required_test_dependencies);
     // If it's automated and can't install without root, return true if there are no dependencies to do otherwise false
     if (pts_c::$test_flags & pts_c::auto_mode && phodevi::is_root() == false) {
         return count($dependencies_to_install) == 0;
     }
     // Do the actual dependency install process
     if (count($dependencies_to_install) > 0) {
         self::install_packages_on_system($dependencies_to_install);
     }
     // There were some dependencies not supported on this OS or are missing from the distro's XML file
     if (count($required_test_dependencies) > 0 && count($dependencies_to_install) == 0) {
         $exdep_generic_parser = new pts_exdep_generic_parser();
         $to_report = array();
         foreach (array_keys($required_test_dependencies) as $dependency) {
             $dependency_data = $exdep_generic_parser->get_package_data($dependency);
             if ($dependency_data['possible_packages'] != null) {
                 array_push($to_report, $dependency_data['title'] . PHP_EOL . 'Possible Package Names: ' . $dependency_data['possible_packages']);
             }
         }
         if (count($to_report) > 0) {
             echo PHP_EOL . 'Some additional dependencies are required, but they could not be installed automatically for your operating system.' . PHP_EOL . 'Below are the software packages that must be installed.' . PHP_EOL . PHP_EOL;
             foreach ($to_report as $report) {
                 pts_client::$display->generic_heading($report);
             }
             if (pts_c::$test_flags ^ pts_c::batch_mode && pts_c::$test_flags ^ pts_c::auto_mode) {
                 echo 'The above dependencies should be installed before proceeding. Press any key when you\'re ready to continue.';
                 pts_user_io::read_user_input();
                 echo PHP_EOL;
             }
         }
     }
     // Find the dependencies that are still missing from the system
     if (pts_c::$test_flags ^ pts_c::batch_mode && pts_c::$test_flags ^ pts_c::auto_mode && !defined('PHOROMATIC_PROCESS')) {
         $generic_packages_needed = array();
         $required_test_dependencies = $required_test_dependencies_copy;
         $dependencies_to_install = self::check_dependencies_missing_from_system($required_test_dependencies_copy, $generic_packages_needed);
         if (count($generic_packages_needed) > 0) {
             echo PHP_EOL . 'There are dependencies still missing from the system:' . PHP_EOL;
             echo pts_user_io::display_text_list(self::generic_names_to_titles($generic_packages_needed));
             $actions = array('IGNORE' => 'Ignore missing dependencies and proceed with installation.', 'SKIP_TESTS_WITH_MISSING_DEPS' => 'Skip installing the tests with missing dependencies.', 'REATTEMPT_DEP_INSTALL' => 'Re-attempt to install the missing dependencies.', 'QUIT' => 'Quit the current Phoronix Test Suite process.');
             $selected_action = pts_user_io::prompt_text_menu('Missing dependencies action', $actions, false, true);
             switch ($selected_action) {
                 case 'IGNORE':
                     break;
                 case 'SKIP_TESTS_WITH_MISSING_DEPS':
                     // Unset the tests that have dependencies still missing
                     self::remove_tests_with_missing_dependencies($test_profiles, $generic_packages_needed, $required_test_dependencies);
                     break;
                 case 'REATTEMPT_DEP_INSTALL':
                     self::install_packages_on_system($dependencies_to_install);
                     break;
                 case 'QUIT':
                     exit(0);
             }
         }
     }
     return true;
 }
 public function get_test_executable_dir()
 {
     $to_execute = null;
     $test_dir = $this->get_install_dir();
     $execute_binary = $this->get_test_executable();
     if (is_executable($test_dir . $execute_binary) || phodevi::is_windows() && is_file($test_dir . $execute_binary)) {
         $to_execute = $test_dir;
     }
     return $to_execute;
 }
 public static function cpu_model()
 {
     // Returns the processor name / frequency information
     $info = null;
     if (isset(phodevi::$vfs->cpuinfo)) {
         $physical_cpu_ids = phodevi_linux_parser::read_cpuinfo('physical id');
         $physical_cpu_count = count(array_unique($physical_cpu_ids));
         $cpu_strings = phodevi_linux_parser::read_cpuinfo(array('model name', 'Processor', 'cpu', 'cpu model'));
         $cpu_strings_unique = array_unique($cpu_strings);
         if ($physical_cpu_count == 1 || empty($physical_cpu_count)) {
             // Just one processor
             if (isset($cpu_strings[0]) && ($cut = strpos($cpu_strings[0], ' (')) !== false) {
                 $cpu_strings[0] = substr($cpu_strings[0], 0, $cut);
             }
             $info = isset($cpu_strings[0]) ? $cpu_strings[0] : null;
             if (strpos($info, 'ARM') !== false) {
                 if (is_dir('/sys/devices/system/exynos-core/') && stripos($info, 'Exynos') === false) {
                     $info = 'Exynos ' . $info;
                 }
             }
         } else {
             if ($physical_cpu_count > 1 && count($cpu_strings_unique) == 1) {
                 // Multiple processors, same model
                 $info = $physical_cpu_count . ' x ' . $cpu_strings[0];
             } else {
                 if ($physical_cpu_count > 1 && count($cpu_strings_unique) > 1) {
                     // Multiple processors, different models
                     $current_id = -1;
                     $current_string = $cpu_strings[0];
                     $current_count = 0;
                     $cpus = array();
                     for ($i = 0; $i < count($physical_cpu_ids); $i++) {
                         if ($current_string != $cpu_strings[$i] || $i == count($physical_cpu_ids) - 1) {
                             array_push($cpus, $current_count . ' x ' . $current_string);
                             $current_string = $cpu_strings[$i];
                             $current_count = 0;
                         }
                         if ($physical_cpu_ids[$i] != $current_id) {
                             $current_count++;
                             $current_id = $physical_cpu_ids[$i];
                         }
                     }
                     $info = implode(', ', $cpus);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('CPUType', '-C');
             if (count($dmi_cpu) == 0) {
                 $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorName');
             }
             if (count($dmi_cpu) > 0) {
                 $info = $dmi_cpu[0];
             } else {
                 $info = trim(shell_exec('dmesg 2>&1 | grep cpu0'));
                 $info = trim(substr($info, strrpos($info, 'cpu0:') + 6));
                 if (empty($info)) {
                     $info = array_pop(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorManufacturer'));
                 }
             }
             //TODO: Add in proper support for reading multiple CPUs, similar to the code from above
             $physical_cpu_count = count(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorSocketType'));
             if ($physical_cpu_count > 1 && !empty($info)) {
                 // TODO: For now assuming when multiple CPUs are installed, that they are of the same type
                 $info = $physical_cpu_count . ' x ' . $info;
             }
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('hw.model');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorName');
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Name');
                         if (!$info) {
                             $info = getenv('PROCESSOR_IDENTIFIER');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info)) {
         $info = 'Unknown';
     } else {
         if (($strip_point = strpos($info, '@')) > 0) {
             $info = trim(substr($info, 0, $strip_point));
             // stripping out the reported freq, since the CPU could be overclocked, etc
         }
         $info = pts_strings::strip_string($info);
         // It seems Intel doesn't report its name when reporting Pentium hardware
         if (strpos($info, 'Pentium') !== false && strpos($info, 'Intel') === false) {
             $info = 'Intel ' . $info;
         }
         if (substr($info, 0, 5) == 'Intel') {
             $cpu_words = explode(' ', $info);
             $cpu_words_count = count($cpu_words);
             // Convert strings like 'Intel Core i7 M 620' -> 'Intel Core i7 620M' and 'Intel Core i7 X 990' -> 'Intel Core i7 990X' to better reflect Intel product marketing names
             if ($cpu_words_count > 4 && is_numeric($cpu_words[$cpu_words_count - 1]) && strlen($cpu_words[$cpu_words_count - 2]) == 1 && strlen($cpu_words[$cpu_words_count - 3]) == 2) {
                 $cpu_words[$cpu_words_count - 1] .= $cpu_words[$cpu_words_count - 2];
                 unset($cpu_words[$cpu_words_count - 2]);
                 $info = implode(' ', $cpu_words);
             }
         }
     }
     return $info;
 }
 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;
 }
 public static function test_profile_system_compatibility_check(&$test_profile, $report_errors = false)
 {
     $valid_test_profile = true;
     $test_type = $test_profile->get_test_hardware_type();
     $skip_tests = pts_client::read_env('SKIP_TESTS') ? pts_strings::comma_explode(pts_client::read_env('SKIP_TESTS')) : false;
     $skip_test_subsystems = pts_client::read_env('SKIP_TESTING_SUBSYSTEMS') ? pts_strings::comma_explode(strtolower(pts_client::read_env('SKIP_TESTING_SUBSYSTEMS'))) : false;
     $display_driver = phodevi::read_property('system', 'display-driver');
     $gpu = phodevi::read_name('gpu');
     if ($test_profile->is_supported(false) == false) {
         $valid_test_profile = false;
     } else {
         if ($test_type == 'Graphics' && pts_client::read_env('DISPLAY') == false && pts_client::read_env('WAYLAND_DISPLAY') == false && phodevi::is_windows() == false && phodevi::is_macosx() == false) {
             $report_errors && pts_client::$display->test_run_error('No display server was found, cannot run ' . $test_profile);
             $valid_test_profile = false;
         } else {
             if ($test_type == 'Graphics' && in_array($display_driver, array('vesa', 'nv', 'cirrus')) && stripos($gpu, 'LLVM') === false) {
                 // These display drivers end up being in known configurations without 3D hardware support so unless an LLVM-based string is reported as the GPU, don't advertise 3D tests
                 $report_errors && pts_client::$display->test_run_error('3D acceleration support not available, cannot run ' . $test_profile);
                 $valid_test_profile = false;
             } else {
                 if ($test_type == 'Disk' && stripos(phodevi::read_property('system', 'filesystem'), 'SquashFS') !== false) {
                     $report_errors && pts_client::$display->test_run_error('Running on a RAM-based live file-system, cannot run ' . $test_profile);
                     $valid_test_profile = false;
                 } else {
                     if (pts_client::read_env('NO_' . strtoupper($test_type) . '_TESTS') || $skip_tests && (in_array($test_profile, $skip_tests) || in_array($test_type, $skip_tests) || in_array($test_profile->get_identifier(false), $skip_tests) || in_array($test_profile->get_identifier_base_name(), $skip_tests))) {
                         $report_errors && pts_client::$display->test_run_error('Due to a pre-set environmental variable, skipping ' . $test_profile);
                         $valid_test_profile = false;
                     } else {
                         if ($skip_test_subsystems && in_array(strtolower($test_profile->get_test_hardware_type()), $skip_test_subsystems)) {
                             $report_errors && pts_client::$display->test_run_error('Due to a pre-set environmental variable, skipping ' . $test_profile);
                             $valid_test_profile = false;
                         } else {
                             if ($test_profile->is_root_required() && $this->batch_mode && phodevi::is_root() == false) {
                                 $report_errors && pts_client::$display->test_run_error('Cannot run ' . $test_profile . ' in batch mode as root access is required.');
                                 $valid_test_profile = false;
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($valid_test_profile == false && pts_client::read_env('SKIP_ALL_TEST_SUPPORT_CHECKS')) {
         $report_errors && pts_client::$display->test_run_error('SKIP_ALL_TEST_SUPPORT_CHECKS is set for ' . $test_profile . '.');
         $valid_test_profile = true;
     }
     return $valid_test_profile;
 }
 public static function memory_capacity()
 {
     // Returns physical memory capacity
     if (isset(phodevi::$vfs->meminfo)) {
         $info = phodevi::$vfs->meminfo;
         $info = substr($info, strpos($info, 'MemTotal:') + 9);
         $info = intval(trim(substr($info, 0, strpos($info, 'kB'))));
         $info = floor($info / 1024);
         if (is_numeric($info) && $info > 950) {
             if ($info > 4608) {
                 $info = ceil($info / 1024) * 1024;
             } else {
                 if ($info > 1536) {
                     $info = ceil($info / 512) * 512;
                 } else {
                     $info = ceil($info / 256) * 256;
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $info = shell_exec('prtconf 2>&1 | grep Memory');
             $info = substr($info, strpos($info, ':') + 2);
             $info = substr($info, 0, strpos($info, 'Megabytes'));
         } else {
             if (phodevi::is_bsd()) {
                 $mem_size = phodevi_bsd_parser::read_sysctl('hw.physmem');
                 if ($mem_size == false) {
                     $mem_size = phodevi_bsd_parser::read_sysctl('hw.realmem');
                 }
                 $info = ceil(floor($mem_size / 1048576) / 256) * 256;
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'Memory');
                     $info = explode(' ', $info);
                     $info = isset($info[1]) && $info[1] == 'GB' ? $info[0] * 1024 : $info[0];
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Memory Size', null);
                         if ($info != null) {
                             if (($e = strpos($info, ' MBytes')) !== false) {
                                 $info = substr($info, 0, $e);
                             }
                             $info = trim($info);
                         }
                     } else {
                         $info = null;
                     }
                 }
             }
         }
     }
     return $info;
 }
Esempio n. 9
0
 public static function call_test_script($test_profile, $script_name, $print_string = null, $pass_argument = null, $extra_vars_append = null, $use_ctp = true)
 {
     $extra_vars = pts_tests::extra_environmental_variables($test_profile);
     if (isset($extra_vars_append['PATH'])) {
         // Special case variable where you likely want the two merged rather than overwriting
         $extra_vars['PATH'] = $extra_vars_append['PATH'] . (substr($extra_vars_append['PATH'], -1) != ':' ? ':' : null) . $extra_vars['PATH'];
         unset($extra_vars_append['PATH']);
     }
     if (is_array($extra_vars_append)) {
         $extra_vars = array_merge($extra_vars, $extra_vars_append);
     }
     // TODO: call_test_script could be better cleaned up to fit more closely with new pts_test_profile functions
     $result = null;
     $test_directory = $test_profile->get_install_dir();
     pts_file_io::mkdir($test_directory, 0777, true);
     $os_postfix = '_' . strtolower(phodevi::operating_system());
     $test_profiles = array($test_profile);
     if ($use_ctp) {
         $test_profiles = array_merge($test_profiles, $test_profile->extended_test_profiles());
     }
     if (pts_client::executable_in_path('bash')) {
         $sh = 'bash';
     } else {
         $sh = 'sh';
     }
     foreach ($test_profiles as &$this_test_profile) {
         $test_resources_location = $this_test_profile->get_resource_dir();
         if (is_file($run_file = $test_resources_location . $script_name . $os_postfix . '.sh') || is_file($run_file = $test_resources_location . $script_name . '.sh')) {
             if (!empty($print_string)) {
                 pts_client::$display->test_run_message($print_string);
             }
             if (phodevi::is_windows() || pts_client::read_env('USE_PHOROSCRIPT_INTERPRETER') != false) {
                 $phoroscript = new pts_phoroscript_interpreter($run_file, $extra_vars, $test_directory);
                 $phoroscript->execute_script($pass_argument);
                 $this_result = null;
             } else {
                 $this_result = pts_client::shell_exec('cd ' . $test_directory . ' && ' . $sh . ' ' . $run_file . ' "' . $pass_argument . '" 2>&1', $extra_vars);
             }
             if (trim($this_result) != null) {
                 $result = $this_result;
             }
         }
     }
     return $result;
 }
 public static function sw_opengl_driver()
 {
     // OpenGL version
     $info = null;
     if (phodevi::is_windows()) {
         $info = null;
         // TODO: Windows support
     } else {
         if (pts_client::executable_in_path('nvidia-settings')) {
             $info = phodevi_parser::read_nvidia_extension('OpenGLVersion');
         }
     }
     if ($info == null) {
         $info = phodevi_parser::software_glxinfo_version();
         if ($info && ($pos = strpos($info, ' ')) != false && strpos($info, 'Mesa') === false) {
             $info = substr($info, 0, $pos);
         }
         $renderer = phodevi_parser::read_glx_renderer();
         if ($renderer && ($s = strpos($renderer, 'Gallium')) !== false) {
             $renderer = substr($renderer, $s);
             $renderer = substr($renderer, 0, strpos($renderer, ' ', strpos($renderer, '.')));
             $info .= ' ' . $renderer . '';
         }
     }
     return $info;
 }
 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;
 }
 public static function chipset_string()
 {
     $info = false;
     if (phodevi::is_macosx()) {
         $sb_vendor = phodevi_osx_parser::read_osx_system_profiler('SPSerialATADataType', 'Vendor');
         $sb_product = phodevi_osx_parser::read_osx_system_profiler('SPSerialATADataType', 'Product');
         if ($sb_product == 'SSD') {
             $sb_product = null;
         }
         if (($cut_point = strpos($sb_product, ' ')) > 0) {
             $sb_product = substr($sb_product, 0, $cut_point);
         }
         // TODO: Can't find Northbridge
         $info = $sb_vendor . ' ' . $sb_product;
     } else {
         if (phodevi::is_windows()) {
             $info = phodevi_windows_parser::read_cpuz('Northbridge', null);
             if ($info != null) {
                 if (($e = strpos($info, 'rev')) !== false) {
                     $info = substr($info, 0, $e);
                 }
                 $info = trim($info);
             }
         } else {
             if (phodevi::is_solaris()) {
                 // Vendor Detection
                 $vendor_possible_udis = array('/org/freedesktop/Hal/devices/pci_0_0/pci_ide_3_2_0', '/org/freedesktop/Hal/devices/pci_0_0/pci_ide_1f_1_1');
                 $info = phodevi_solaris_parser::read_hal_property($vendor_possible_udis, 'info.vendor');
                 // TODO: Northbridge and Southbridge Detection For Solaris
             } else {
                 if (phodevi::is_linux() || phodevi::is_hurd()) {
                     $info = phodevi_linux_parser::read_pci(array('RAM memory', 'Host bridge'));
                     if (count(explode(' ', $info)) == 1) {
                         $bridge = phodevi_linux_parser::read_pci(array('Bridge', 'PCI bridge'));
                         if (!empty($bridge)) {
                             $match = false;
                             $break_words = array('Ethernet', 'PCI', 'High', 'USB');
                             for ($i = 0; $i < count($break_words) && !$match; $i++) {
                                 if (($pos = strpos($bridge, $break_words[$i])) > 0) {
                                     $bridge = trim(substr($bridge, 0, $pos));
                                     $info = $bridge;
                                     $match = true;
                                 }
                             }
                         }
                     }
                     if (!isset($bridge) || !empty($bridge)) {
                         // Attempt to detect Southbridge (if applicable)
                         $southbridge = phodevi_linux_parser::read_pci(array('ISA bridge', 'SATA controller'), false);
                         $southbridge_clean = null;
                         if (($start_cut = strpos($southbridge, '(')) > 0 && ($end_cut = strpos($southbridge, ')', $start_cut + 1)) > 0) {
                             $southbridge_extract = substr($southbridge, $start_cut + 1, $end_cut - $start_cut - 1);
                             if (strpos($southbridge_extract, 'rev') === false) {
                                 $southbridge_extract = explode(' ', $southbridge_extract);
                                 $southbridge_clean = $southbridge_extract[0];
                             } else {
                                 if (($s = strpos($southbridge, 'ICH')) > 0) {
                                     $southbridge_extract = substr($southbridge, $s);
                                     $southbridge_clean = substr($southbridge_extract, 0, strpos($southbridge_extract, ' '));
                                 }
                             }
                         } else {
                             if (($start_cut = strpos($southbridge, 'SB')) !== false) {
                                 $southbridge_extract = substr($southbridge, $start_cut);
                                 $southbridge_clean = substr($southbridge_extract, 0, strpos($southbridge_extract, ' '));
                             }
                         }
                         if (!empty($southbridge_clean) && $southbridge_clean != 'SB') {
                             $info .= ' + ' . $southbridge_clean;
                         }
                     }
                 }
             }
         }
     }
     return $info;
 }
 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;
 }
 public function execute_script($pass_arguments = null)
 {
     if ($this->script_file == null) {
         return false;
     }
     $script_contents = file_get_contents($this->script_file);
     $prev_exit_status = 0;
     $script_pointer = -1;
     do {
         $exit_status = 0;
         if ($prev_exit_status != 0) {
             $exit_status = $prev_exit_status;
             $prev_exit_status = 0;
         }
         $script_contents = substr($script_contents, $script_pointer + 1);
         $line = $script_contents;
         $prev_script_pointer = $script_pointer;
         if (($script_pointer = strpos($line, "\n")) !== false) {
             $line = substr($line, 0, $script_pointer);
         }
         $line_r = $line != null ? pts_strings::trim_explode(' ', $line) : null;
         switch (isset($line_r[0]) ? $line_r[0] : null) {
             case '':
                 break;
             case 'mv':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[2] = $this->get_real_path($line_r[2], $pass_arguments);
                 //pts_file_io::delete($line_r[2], null, true);
                 //copy($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 //pts_file_io::delete($line_r[1], null, true);
                 rename($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 break;
             case 'cp':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[2] = $this->get_real_path($line_r[2], $pass_arguments);
                 copy($line_r[1], $line_r[2] . (is_dir($line_r[2]) ? basename($line_r[1]) : null));
                 break;
             case 'cat':
                 // TODO: implement folder support better
                 $line_r[1] = $this->get_real_path($line_r[1], $pass_arguments);
                 $line_r[3] = $this->get_real_path($line_r[3], $pass_arguments);
                 copy($line_r[1], $line_r[3]);
                 break;
             case 'cd':
                 if ($line_r[1] == '..') {
                     if (substr($this->var_current_directory, -1) == '/') {
                         $this->var_current_directory = substr($this->var_current_directory, 0, -1);
                     }
                     $this->var_current_directory = substr($this->var_current_directory, 0, strrpos($this->var_current_directory, '/') + 1);
                 } else {
                     if ($line_r[1] == '~') {
                         $this->var_current_directory = $this->environmental_variables["HOME"];
                     } else {
                         if (substr($line_r[1], 0, 1) == '"') {
                             // On Windows some directories are encased in quotes for spaces in the directory names
                             array_shift($line_r);
                             $this->var_current_directory = implode(' ', $line_r);
                         } else {
                             if (is_readable($line_r[1])) {
                                 $this->var_current_directory = $line_r[1];
                             } else {
                                 if (is_readable($this->get_real_path($line_r[1], $pass_arguments))) {
                                     $this->var_current_directory = $this->get_real_path($line_r[1], $pass_arguments);
                                 }
                             }
                         }
                     }
                 }
                 break;
             case 'touch':
                 if (!is_file($this->var_current_directory . $line_r[1]) && is_writable($this->var_current_directory)) {
                     touch($this->var_current_directory . $line_r[1]);
                 }
                 break;
             case 'mkdir':
                 pts_file_io::mkdir($this->var_current_directory . $line_r[1]);
                 break;
             case 'rm':
                 for ($i = 1; $i < count($line_r); $i++) {
                     if (is_file($this->var_current_directory . $line_r[$i])) {
                         unlink($this->var_current_directory . $line_r[$i]);
                     } else {
                         if (is_dir($this->var_current_directory . $line_r[$i])) {
                             pts_file_io::delete($this->var_current_directory . $line_r[$i], null, true);
                         }
                     }
                 }
                 break;
             case 'chmod':
                 $chmod_file = self::find_file_in_array($line_r);
                 if ($chmod_file) {
                     chmod($chmod_file, 0755);
                 }
                 break;
             case 'unzip':
                 $zip_file = self::find_file_in_array($line_r);
                 pts_compression::zip_archive_extract($zip_file, $this->var_current_directory);
                 break;
             case 'tar':
                 // TODO: implement
                 break;
             case 'echo':
                 if ($line == "echo \$? > ~/install-exit-status") {
                     file_put_contents($this->var_current_directory . "install-exit-status", $exit_status);
                     break;
                 } else {
                     if ($line == "echo \$? > ~/test-exit-status") {
                         file_put_contents($this->var_current_directory . "test-exit-status", $exit_status);
                         break;
                     }
                 }
                 $start_echo = strpos($script_contents, "\"") + 1;
                 $end_echo = $start_echo - 1;
                 do {
                     $end_echo = strpos($script_contents, "\"", $end_echo + 1);
                 } while ($script_contents[$end_echo - 1] == "\\");
                 $script_pointer = strpos($script_contents, "\n", $end_echo);
                 $line_remainder = substr($script_contents, $end_echo + 1, $script_pointer - $end_echo - 1);
                 $echo_contents = substr($script_contents, $start_echo, $end_echo - $start_echo);
                 $this->parse_variables_in_string($echo_contents, $pass_arguments);
                 $echo_contents = str_replace("\\\$", "\$", $echo_contents);
                 $echo_contents = str_replace("\\\"", "\"", $echo_contents);
                 if (($to_file = strpos($line_remainder, ' > ')) !== false) {
                     $to_file = trim(substr($line_remainder, $to_file + 3));
                     if (($end_file = strpos($to_file, ' ')) !== false) {
                         $to_file = substr($to_file, 0, $end_file);
                     }
                     // TODO: right now it's expecting the file location pipe to be relative location
                     $echo_dir = pts_strings::add_trailing_slash(str_replace('"', null, $this->var_current_directory));
                     // needed for phodevi::is_windows() specviewperf10
                     file_put_contents($echo_dir . $to_file, $echo_contents . "\n");
                 } else {
                     echo $echo_contents;
                 }
                 break;
             case '#!/bin/sh':
             case '#':
             case null:
                 // IGNORE
                 break;
             case 'case':
                 //echo "\nUNHANDLED EVENT\n";
                 return false;
                 // TODO: decide how to handle
                 break;
             default:
                 $exec_output = array();
                 if (phodevi::is_windows() && substr($line, 0, 2) == "./") {
                     $line = substr($line, 2);
                 }
                 $this->parse_variables_in_string($line, $pass_arguments);
                 $cd_dir = $this->var_current_directory;
                 if (phodevi::is_windows() && strpos($cd_dir, ':\\') === 1) {
                     $cd_dir = str_replace('/', '\\', $cd_dir);
                     $cd_dir = str_replace('\\\\', '\\', $cd_dir);
                 }
                 exec("cd " . $cd_dir . " && " . $line . " 2>&1", $exec_output, $prev_exit_status);
                 break;
         }
     } while ($script_contents != false);
 }
Esempio n. 15
0
 public static function display_web_page($URL, $alt_text = null, $default_open = true, $auto_open = false)
 {
     if (pts_client::read_env('DISPLAY') == false && pts_client::read_env('WAYLAND_DISPLAY') == false && phodevi::is_windows() == false && phodevi::is_macosx() == false || defined('PHOROMATIC_PROCESS')) {
         return;
     }
     if ($auto_open == false) {
         $view_results = pts_user_io::prompt_bool_input($alt_text == null ? 'Do you want to view the results in your web browser' : $alt_text, $default_open);
     } else {
         $view_results = true;
     }
     if ($view_results) {
         static $browser = null;
         if ($browser == null) {
             $config_browser = pts_config::read_user_config('PhoronixTestSuite/Options/General/DefaultBrowser', null);
             if ($config_browser != null && (is_executable($config_browser) || ($config_browser = pts_client::executable_in_path($config_browser)))) {
                 $browser = $config_browser;
             } else {
                 if (phodevi::is_windows()) {
                     $windows_browsers = array('C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe', 'C:\\Program Files\\Internet Explorer\\iexplore.exe');
                     foreach ($windows_browsers as $browser_test) {
                         if (is_executable($browser_test)) {
                             $browser = $browser_test;
                             break;
                         }
                     }
                     if (substr($URL, 0, 1) == '\\') {
                         $URL = 'file:///C:' . str_replace('/', '\\', $URL);
                     }
                 } else {
                     $possible_browsers = array('firefox', 'mozilla', 'x-www-browser', 'open', 'xdg-open', 'iceweasel', 'konqueror', 'epiphany', 'google-chrome');
                     foreach ($possible_browsers as &$b) {
                         if ($b = pts_client::executable_in_path($b)) {
                             $browser = $b;
                             break;
                         }
                     }
                 }
             }
         }
         if ($browser != null) {
             shell_exec($browser . ' "' . $URL . '" 2> /dev/null &');
         } else {
             echo PHP_EOL . 'No Web Browser Found.' . PHP_EOL;
         }
     }
 }
 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 add_trailing_slash($path)
 {
     if (PTS_IS_CLIENT && phodevi::is_windows() && strpos($path, ':\\') === 1) {
         return $path . (substr($path, -1) == '\\' ? null : '\\');
     } else {
         return $path . (substr($path, -1) == '/' ? null : '/');
     }
 }