public static function standard_install($items_to_install, $force_install = false, $no_prompts = false, $skip_tests_with_missing_dependencies = false) { // Refresh the pts_client::$display in case we need to run in debug mode if (pts_client::$display == false || !pts_client::$display instanceof pts_websocket_display_mode) { pts_client::init_display_mode(); } // Create a lock $lock_path = pts_client::temporary_directory() . '/phoronix-test-suite.active'; pts_client::create_lock($lock_path); // Get the test profiles $unknown_tests = array(); $test_profiles = pts_types::identifiers_to_test_profile_objects($items_to_install, true, true, $unknown_tests); // Any external dependencies? pts_external_dependencies::install_dependencies($test_profiles, $no_prompts, $skip_tests_with_missing_dependencies); // Install tests if (!is_writable(pts_client::test_install_root_path())) { trigger_error('The test installation directory is not writable.' . PHP_EOL . 'Location: ' . pts_client::test_install_root_path(), E_USER_ERROR); return false; } pts_test_installer::start_install($test_profiles, $unknown_tests, $force_install, $no_prompts); pts_client::release_lock($lock_path); return $test_profiles; }
public static function run($r) { if (pts_client::create_lock(PTS_USER_PATH . 'phoromatic_server_lock') == false) { trigger_error('The Phoromatic Server is already running.', E_USER_ERROR); return false; } pts_file_io::unlink(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/phoromatic-server-launcher'); if (PHP_VERSION_ID < 50400) { echo 'Running an unsupported PHP version. PHP 5.4+ is required to use this feature.' . PHP_EOL . PHP_EOL; return false; } if (!function_exists('socket_create_listen')) { echo 'PHP Sockets support is needed to use the Phoromatic Server.' . PHP_EOL . PHP_EOL; return false; } $server_launcher = '#!/bin/sh' . PHP_EOL; $web_port = 0; $remote_access = pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort', 'RANDOM'); $fp = false; $errno = null; $errstr = null; if ($remote_access == 'RANDOM') { do { if ($fp) { fclose($fp); } $remote_access = rand(8000, 8999); } while (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false); echo 'Port ' . $remote_access . ' chosen as random port for this instance. Change the default port via the Phoronix Test Suite user configuration file.' . PHP_EOL; } $remote_access = is_numeric($remote_access) && $remote_access > 1 ? $remote_access : false; $blocked_ports = array(2049, 3659, 4045, 6000, 9000); if ($remote_access) { // ALLOWING SERVER TO BE REMOTELY ACCESSIBLE $server_ip = '0.0.0.0'; if (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false) { fclose($fp); trigger_error('Port ' . $remote_access . ' is already in use by another server process. Close that process or change the Phoronix Test Suite server port via' . pts_config::get_config_file_location() . ' to proceed.', E_USER_ERROR); return false; } else { $web_port = $remote_access; $web_socket_port = pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort', ''); while ($web_socket_port == null || !is_numeric($web_socket_port) || ($fp = fsockopen('127.0.0.1', $web_socket_port, $errno, $errstr, 5)) != false) { if ($fp) { fclose($fp); } $web_socket_port = rand(8000, 8999); } } } else { echo PHP_EOL . PHP_EOL . 'You must first configure the remote web / Phoromatic settings via:' . PHP_EOL . ' ' . pts_config::get_config_file_location() . PHP_EOL . PHP_EOL . 'The RemoteAccessPort should be a network port to use for HTTP communication while WebSocketPort should be set to another available network port. Set to RANDOM if wishing to use randomly chosen available ports.' . PHP_EOL . PHP_EOL; return false; } if (!extension_loaded('sqlite3')) { echo PHP_EOL . PHP_EOL . 'PHP SQLite3 support must first be enabled before accessing the Phoromatic server (e.g. installing the php5-sqlite or php-pdo package depending on the distribution).' . PHP_EOL . PHP_EOL; return false; } // Setup server logger define('PHOROMATIC_SERVER', true); // Just create the logger so now it will flush it out $pts_logger = new pts_logger(); $pts_logger->clear_log(); echo pts_core::program_title(true) . ' starting Phoromatic Server' . PHP_EOL; $pts_logger->log(pts_core::program_title(true) . ' starting Phoromatic Server on ' . pts_network::get_local_ip()); echo 'Phoronix Test Suite User-Data Directory Path: ' . PTS_USER_PATH . PHP_EOL; echo 'Phoronix Test Suite Configuration File: ' . pts_config::get_config_file_location() . PHP_EOL; echo 'Phoromatic Server Log File: ' . $pts_logger->get_log_file_location() . PHP_EOL; $pts_logger->log('PTS_USER_PATH = ' . PTS_USER_PATH); $pts_logger->log('PTS_DOWNLOAD_CACHE_PATH = ' . PTS_DOWNLOAD_CACHE_PATH); $pts_logger->log('XML Configuration File = ' . pts_config::get_config_file_location()); // WebSocket Server Setup $server_launcher .= 'export PTS_WEB_PORT=' . $web_port . PHP_EOL; $server_launcher .= 'export PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL; $server_launcher .= 'export PTS_WEBSOCKET_SERVER=PHOROMATIC' . PHP_EOL; $server_launcher .= 'export PTS_NO_FLUSH_LOGGER=1' . PHP_EOL; $server_launcher .= 'export PTS_PHOROMATIC_SERVER=1' . PHP_EOL; $server_launcher .= 'export PTS_PHOROMATIC_LOG_LOCATION=' . $pts_logger->get_log_file_location() . PHP_EOL; $server_launcher .= 'cd ' . getenv('PTS_DIR') . ' && PTS_MODE="CLIENT" ' . getenv('PHP_BIN') . ' pts-core/phoronix-test-suite.php start-ws-server &' . PHP_EOL; $server_launcher .= 'websocket_server_pid=$!' . PHP_EOL; $pts_logger->log('Starting WebSocket process on port ' . $web_socket_port); $server_launcher .= 'cd ' . getenv('PTS_DIR') . ' && PTS_MODE="CLIENT" ' . getenv('PHP_BIN') . ' pts-core/phoronix-test-suite.php start-phoromatic-event-server &' . PHP_EOL; $server_launcher .= 'event_server_pid=$!' . PHP_EOL; // HTTP Server Setup if (false && pts_client::executable_in_path('nginx') && is_file('/run/php-fpm/php-fpm.pid')) { // NGINX $nginx_conf = 'error_log /tmp/error.log; pid /tmp/nginx.pid; worker_processes 1; events { worker_connections 1024; } http { client_body_temp_path /tmp/client_body; fastcgi_temp_path /tmp/fastcgi_temp; proxy_temp_path /tmp/proxy_temp; scgi_temp_path /tmp/scgi_temp; uwsgi_temp_path /tmp/uwsgi_temp; tcp_nopush on; tcp_nodelay on; keepalive_timeout 180; types_hash_max_size 2048; include /etc/nginx/mime.types; index index.php; server { listen ' . $web_port . '; listen [::]:' . $web_port . ' default ipv6only=on; access_log /tmp/access.log; error_log /tmp/error.log; root ' . PTS_CORE_PATH . 'phoromatic/public_html; index index.php; try_files $uri $uri/ /index.php; location / { autoindex on; } location ~ \\.php$ { include /etc/nginx/fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; fastcgi_split_path_info ^(.+\\.php)(/.+)$; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } } }'; $nginx_conf_file = tempnam(PTS_USER_PATH, 'nginx_conf_'); file_put_contents($nginx_conf_file, $nginx_conf); $server_launcher .= 'nginx -c ' . $nginx_conf_file . PHP_EOL . 'rm -f ' . $nginx_conf_file . PHP_EOL; } else { if (($mongoose = pts_client::executable_in_path('mongoose')) && ($php_cgi = pts_client::executable_in_path('php-cgi'))) { // Mongoose Embedded Web Server $server_launcher .= $mongoose . ' -p ' . $web_port . ' -r ' . PTS_CORE_PATH . 'phoromatic/public_html/ -I ' . $php_cgi . ' -i index.php > /dev/null 2>> $PTS_PHOROMATIC_LOG_LOCATION &' . PHP_EOL; //2> /dev/null } else { if (strpos(getenv('PHP_BIN'), 'hhvm')) { echo PHP_EOL . 'Unfortunately, the HHVM built-in web server has abandoned upstream. Users will need to use the PHP binary or other alternatives.' . PHP_EOL . PHP_EOL; return; } else { // PHP Web Server $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'phoromatic/public_html/ > /dev/null 2>> $PTS_PHOROMATIC_LOG_LOCATION &' . PHP_EOL; //2> /dev/null } } } $server_launcher .= 'http_server_pid=$!' . PHP_EOL; $server_launcher .= 'sleep 1' . PHP_EOL; $server_launcher .= 'echo "The Phoromatic Web Interface Is Accessible At: http://localhost:' . $web_port . '"' . PHP_EOL; $pts_logger->log('Starting HTTP process @ http://localhost:' . $web_port); // Avahi for zeroconf network discovery support if (pts_config::read_user_config('PhoronixTestSuite/Options/Server/AdvertiseServiceZeroConf', 'TRUE')) { if (is_dir('/etc/avahi/services') && is_writable('/etc/avahi/services')) { file_put_contents('/etc/avahi/services/phoromatic-server.service', '<?xml version="1.0" standalone=\'no\'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">phoromatic-server-%h</name> <service> <type>_http._tcp</type> <port>' . $web_port . '</port> </service> </service-group>'); } else { if (pts_client::executable_in_path('avahi-publish')) { $hostname = phodevi::read_property('system', 'hostname'); $hostname = $hostname == null ? rand(0, 99) : $hostname; $server_launcher .= 'avahi-publish -s phoromatic-server-' . $hostname . ' _http._tcp ' . $web_port . ' "Phoronix Test Suite Phoromatic" > /dev/null 2> /dev/null &' . PHP_EOL; $server_launcher .= 'avahi_publish_pid=$!' . PHP_EOL; } } } // Wait for input to shutdown process.. if (!PTS_IS_DAEMONIZED_SERVER_PROCESS) { $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL; $server_launcher .= PHP_EOL . 'read var_name'; } else { $server_launcher .= PHP_EOL . 'while [ ! -f "/var/lib/phoronix-test-suite/end-phoromatic-server" ];'; $server_launcher .= PHP_EOL . 'do'; $server_launcher .= PHP_EOL . 'sleep 1'; $server_launcher .= PHP_EOL . 'done'; $server_launcher .= PHP_EOL . 'rm -f /var/lib/phoronix-test-suite/end-phoromatic-server' . PHP_EOL; } // Shutdown / Kill Servers $server_launcher .= PHP_EOL . 'kill $http_server_pid'; $server_launcher .= PHP_EOL . 'kill $websocket_server_pid'; $server_launcher .= PHP_EOL . 'kill $event_server_pid'; if (is_writable('/etc/avahi/services') && is_file('/etc/avahi/services/phoromatic-server.service')) { $server_launcher .= PHP_EOL . 'rm -f /etc/avahi/services/phoromatic-server.service'; } else { $server_launcher .= PHP_EOL . 'kill $avahi_publish_pid'; } $server_launcher .= PHP_EOL . 'rm -f ~/.phoronix-test-suite/run-lock*'; file_put_contents(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/phoromatic-server-launcher', $server_launcher); }
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 function call_test_runs() { // Create a lock $lock_path = pts_client::temporary_directory() . '/phoronix-test-suite.active'; pts_client::create_lock($lock_path); if ($this->pre_run_message != null) { pts_client::$display->display_interrupt_message($this->pre_run_message); } // Hook into the module framework self::$test_run_process_active = true; pts_module_manager::module_process('__pre_run_process', $this); pts_file_io::unlink(PTS_USER_PATH . 'halt-testing'); pts_file_io::unlink(PTS_USER_PATH . 'skip-test'); $continue_test_flag = true; $tests_to_run_count = $this->get_test_count(); pts_client::$display->test_run_process_start($this); $total_loop_count = ($t = pts_client::read_env('TOTAL_LOOP_COUNT')) && is_numeric($t) && $t > 0 ? $t : 1; $total_loop_time = ($t = pts_client::read_env('TOTAL_LOOP_TIME')) && is_numeric($t) && $t > 9 ? $t * 60 : -1; $loop_end_time = $total_loop_time != -1 ? time() + $total_loop_time : false; $this->test_run_count = $tests_to_run_count * $total_loop_count; for ($loop = 1; $loop <= $total_loop_count && $continue_test_flag; $loop++) { for ($i = 0; $i < $tests_to_run_count && $continue_test_flag; $i++) { $this->test_run_pos = $i; $continue_test_flag = $this->process_test_run_request($i); if (pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/RemoveTestInstallOnCompletion', 'FALSE')) { // Remove the installed test if it's no longer needed in this run queue $this_test_profile_identifier = $this->get_test_to_run($this->test_run_pos)->test_profile->get_identifier(); $still_in_queue = false; for ($j = $this->test_run_pos + 1; $j < $tests_to_run_count && $still_in_queue == false; $j++) { if ($this->get_test_to_run($j)->test_profile->get_identifier() == $this_test_profile_identifier) { $still_in_queue = true; } } if ($still_in_queue == false) { pts_client::remove_installed_test($this->get_test_to_run($this->test_run_pos)->test_profile); } } if ($loop_end_time) { if (time() > $loop_end_time) { $continue_test_flag = false; } else { if ($this->test_run_count == $i + 1) { // There's still time remaining so increase the run count.... $this->test_run_count += $tests_to_run_count; } } } } } pts_file_io::unlink(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/active.xml'); foreach ($this->tests_to_run as &$run_request) { // Remove cache shares foreach (pts_file_io::glob($run_request->test_profile->get_install_dir() . 'cache-share-*.pt2so') as $cache_share_file) { unlink($cache_share_file); } } if ($this->post_run_message != null) { pts_client::$display->display_interrupt_message($this->post_run_message); } self::$test_run_process_active = -1; pts_module_manager::module_process('__post_run_process', $this); pts_client::release_lock($lock_path); // Report any tests that failed to properly run if (pts_client::is_debug_mode() || $this->get_test_count() > 3) { if (count($this->failed_tests_to_run) > 0) { echo PHP_EOL . PHP_EOL . 'The following tests failed to properly run:' . PHP_EOL . PHP_EOL; foreach ($this->failed_tests_to_run as &$run_request) { echo "\t- " . $run_request->test_profile->get_identifier() . ($run_request->get_arguments_description() != null ? ': ' . $run_request->get_arguments_description() : null) . PHP_EOL; } echo PHP_EOL; } } }
$aliases = pts_documentation::client_commands_aliases(); } if (isset($aliases[$sent_command])) { $sent_command = $aliases[$sent_command]; $replaced = true; } } } if ($replaced == false) { // Show help command, since there are no valid commands $sent_command = 'help'; } } pts_define('PTS_USER_LOCK', function_exists('posix_getpid') ? PTS_USER_PATH . 'run-lock-' . posix_getpid() : tempnam(PTS_USER_PATH, 'run-lock-')); if (QUICK_START == false) { if (pts_client::create_lock(PTS_USER_LOCK) == false) { //trigger_error('It appears that the Phoronix Test Suite is already running.' . PHP_EOL . 'For proper results, only run one instance at a time.', E_USER_WARNING); } register_shutdown_function(array('pts_client', 'process_shutdown_tasks')); //pcntl_signal(SIGTERM, array('pts_client', 'exit_client')); if (pts_client::read_env('PTS_IGNORE_MODULES') == false) { pts_client::module_framework_init(); // Initialize the PTS module system } } // Read passed arguments for ($i = 2; $i < $argc && isset($argv[$i]); $i++) { $pass_args[] = $argv[$i]; } if (QUICK_START == false) { pts_client::user_agreement_check($sent_command);
public static function run_connection($args) { if (pts_client::create_lock(PTS_USER_PATH . 'phoromatic_lock') == false) { trigger_error('Phoromatic is already running.', E_USER_ERROR); return false; } define('PHOROMATIC_PROCESS', true); if (pts_client::$pts_logger == false) { pts_client::$pts_logger = new pts_logger(); } pts_client::$pts_logger->log(pts_title(true) . ' [' . PTS_CORE_VERSION . '] starting Phoromatic client'); if (phodevi::system_uptime() < 60) { echo 'PHOROMATIC: Sleeping for 60 seconds as system freshly started.' . PHP_EOL; pts_client::$pts_logger->log('Sleeping for 60 seconds as system freshly started'); sleep(60); } $server_setup = self::setup_server_addressing($args); //$http_comm = new phoromatic_client_comm_http(); if (!$server_setup) { if (PTS_IS_DAEMONIZED_SERVER_PROCESS) { if (pts_client::executable_in_path('reboot')) { shell_exec('reboot'); sleep(5); } } return false; } $times_failed = 0; $has_success = false; $do_exit = false; $just_started = true; self::setup_system_environment(); pts_client::$pts_logger->log('SYSTEM HARDWARE: ' . phodevi::system_hardware(true)); pts_client::$pts_logger->log('SYSTEM SOFTWARE: ' . phodevi::system_software(true)); while ($do_exit == false) { $server_response = phoromatic::upload_to_remote_server(array('r' => 'start')); if ($server_response == false) { $times_failed++; pts_client::$pts_logger->log('Server response failed'); if ($times_failed >= 2) { trigger_error('Communication with server failed.', E_USER_ERROR); if (PTS_IS_DAEMONIZED_SERVER_PROCESS == false && $times_failed > 5) { return false; } else { if (PTS_IS_DAEMONIZED_SERVER_PROCESS && $times_failed > 10) { if (pts_client::executable_in_path('reboot')) { shell_exec('reboot'); sleep(5); } } } } } else { if (substr($server_response, 0, 1) == '[') { // Likely a notice/warning from server echo PHP_EOL . substr($server_response, 0, strpos($server_response, PHP_EOL)) . PHP_EOL; } else { if (substr($server_response, 0, 1) == '{') { $times_failed = 0; $json = json_decode($server_response, true); if ($has_success == false) { $has_success = true; pts_module::save_file('last-phoromatic-server', self::$server_address . ':' . self::$server_http_port . '/' . self::$account_id); } if ($json != null) { if (isset($json['phoromatic']['error']) && !empty($json['phoromatic']['error'])) { trigger_error($json['phoromatic']['error'], E_USER_ERROR); } if (isset($json['phoromatic']['response']) && !empty($json['phoromatic']['response'])) { echo PHP_EOL . $json['phoromatic']['response'] . PHP_EOL; } } if ($just_started) { if (PTS_IS_DAEMONIZED_SERVER_PROCESS) { $pid = pcntl_fork(); if ($pid == 0) { // Start the tick thread self::tick_thread(); } } $just_started = false; } if (isset($json['phoromatic']['pre_set_sys_env_vars']) && !empty($json['phoromatic']['pre_set_sys_env_vars'])) { // pre_set_sys_env_vars was added during PTS 5.8 development // Sets environment variables on client as specified via the Phoromatic Server's systems page foreach (explode(';', $json['phoromatic']['pre_set_sys_env_vars']) as $i => $v_string) { $var = explode('=', $v_string); if (count($var) == 2) { putenv($var[0] . '=' . $var[1]); } } } switch (isset($json['phoromatic']['task']) ? $json['phoromatic']['task'] : null) { case 'install': phoromatic::update_system_status('Installing Tests'); pts_suite_nye_XmlReader::set_temporary_suite('pre-seed', $json['phoromatic']['test_suite']); pts_test_installer::standard_install('pre-seed'); break; case 'benchmark': // Make sure all latest tests are available pts_openbenchmarking::refresh_repository_lists(null, true); $benchmark_timer = time(); self::$is_running_as_phoromatic_node = true; $test_flags = pts_c::auto_mode | pts_c::batch_mode; $suite_identifier = sha1(time() . rand(2, 1000)); pts_suite_nye_XmlReader::set_temporary_suite($suite_identifier, $json['phoromatic']['test_suite']); self::$p_save_identifier = $json['phoromatic']['trigger_id']; $phoromatic_results_identifier = self::$p_save_identifier; $phoromatic_save_identifier = $json['phoromatic']['save_identifier']; self::$p_schedule_id = isset($json['phoromatic']['schedule_id']) ? $json['phoromatic']['schedule_id'] : false; self::$p_trigger_id = self::$p_save_identifier; $benchmark_ticket_id = isset($json['phoromatic']['benchmark_ticket_id']) ? $json['phoromatic']['benchmark_ticket_id'] : null; phoromatic::update_system_status('Running Benchmarks For: ' . $phoromatic_save_identifier); if (pts_strings::string_bool($json['phoromatic']['settings']['RunInstallCommand'])) { if (isset($json['phoromatic']['pre_install_set_context'])) { phoromatic::set_user_context($json['phoromatic']['pre_install_set_context'], self::$p_trigger_id, self::$p_schedule_id, 'PRE_INSTALL'); } if (pts_strings::string_bool($json['phoromatic']['settings']['ForceInstallTests'])) { $test_flags |= pts_c::force_install; } pts_client::set_test_flags($test_flags); pts_test_installer::standard_install($suite_identifier); if (isset($json['phoromatic']['post_install_set_context'])) { phoromatic::set_user_context($json['phoromatic']['post_install_set_context'], self::$p_trigger_id, self::$p_schedule_id, 'POST_INSTALL'); } } $env_vars = isset($json['phoromatic']['environment_variables']) ? pts_strings::parse_value_string_vars($json['phoromatic']['environment_variables']) : array(); // Do the actual running phodevi::clear_cache(); if (pts_test_run_manager::initial_checks($suite_identifier, 0, 'SHORT')) { self::$test_run_manager = new pts_test_run_manager($test_flags); pts_test_run_manager::set_batch_mode(array('UploadResults' => isset($json['phoromatic']['settings']['UploadResultsToOpenBenchmarking']) && pts_strings::string_bool($json['phoromatic']['settings']['UploadResultsToOpenBenchmarking']), 'SaveResults' => true, 'RunAllTestCombinations' => false, 'OpenBrowser' => false)); // Load the tests to run if (self::$test_run_manager->load_tests_to_run($suite_identifier)) { phoromatic::update_system_status('Tests In Run Queue: ' . implode(', ', self::$test_run_manager->get_tests_to_run_identifiers())); if (isset($json['phoromatic']['pre_run_set_context'])) { phoromatic::set_user_context($json['phoromatic']['pre_run_set_context'], self::$p_trigger_id, self::$p_schedule_id, 'PRE_RUN'); } if (isset($json['phoromatic']['settings']['UploadResultsToOpenBenchmarking']) && pts_strings::string_bool($json['phoromatic']['settings']['UploadResultsToOpenBenchmarking'])) { self::$test_run_manager->auto_upload_to_openbenchmarking(); pts_openbenchmarking_client::override_client_setting('UploadSystemLogsByDefault', pts_strings::string_bool($json['phoromatic']['settings']['UploadSystemLogs'])); } // Save results? // Run the actual tests if (isset($env_vars['PTS_CONCURRENT_TEST_RUNS']) && $env_vars['PTS_CONCURRENT_TEST_RUNS'] > 1) { $total_loop_time = isset($env_vars['TOTAL_LOOP_TIME']) ? $env_vars['TOTAL_LOOP_TIME'] : false; pts_client::$pts_logger->log('STRESS / MULTI-TEST EXECUTION STARTED @ ' . date('Y-m-d H:i:s')); pts_client::$pts_logger->log('CONCURRENT RUNS = ' . $env_vars['PTS_CONCURRENT_TEST_RUNS'] . ' TOTAL LOOP TIME = ' . $total_loop_time); $r = self::$test_run_manager->multi_test_stress_run_execute($env_vars['PTS_CONCURRENT_TEST_RUNS'], $total_loop_time); if ($r == false) { return; } pts_client::$pts_logger->log('STRESS / MULTI-TEST EXECUTION ENDED @ ' . date('Y-m-d H:i:s')); } else { self::$test_run_manager->auto_save_results($phoromatic_save_identifier, $phoromatic_results_identifier, isset($json['phoromatic']['test_description']) ? $json['phoromatic']['test_description'] : 'A Phoromatic run.'); self::$test_run_manager->pre_execution_process(); self::$test_run_manager->call_test_runs(); } phoromatic::update_system_status('Benchmarks Completed For: ' . $phoromatic_save_identifier); self::$test_run_manager->post_execution_process(); $elapsed_benchmark_time = time() - $benchmark_timer; // Handle uploading data to server $result_file = new pts_result_file(self::$test_run_manager->get_file_name()); $upload_system_logs = pts_strings::string_bool($json['phoromatic']['settings']['UploadSystemLogs']); $server_response = self::upload_test_result($result_file, $upload_system_logs, isset($json['phoromatic']['schedule_id']) ? $json['phoromatic']['schedule_id'] : null, $phoromatic_save_identifier, $json['phoromatic']['trigger_id'], $elapsed_benchmark_time, $benchmark_ticket_id); //pts_client::$pts_logger->log('DEBUG RESPONSE MESSAGE: ' . $server_response); if (!pts_strings::string_bool($json['phoromatic']['settings']['ArchiveResultsLocally'])) { pts_client::remove_saved_result_file(self::$test_run_manager->get_file_name()); } } if (isset($json['phoromatic']['post_install_set_context'])) { phoromatic::set_user_context($json['phoromatic']['post_install_set_context'], self::$p_trigger_id, self::$p_schedule_id, 'POST_RUN'); } } self::$p_schedule_id = null; self::$is_running_as_phoromatic_node = false; break; case 'reboot': echo PHP_EOL . 'Phoromatic received a remote command to reboot.' . PHP_EOL; phoromatic::update_system_status('Attempting System Reboot'); if (pts_client::executable_in_path('reboot')) { shell_exec('reboot'); sleep(5); } break; case 'shutdown-if-supports-wake': $supports_wol = false; foreach (pts_network::get_network_wol() as $net_device) { if (strpos($net_device, 'g') !== false) { $supports_wol = true; break; } } if (!$supports_wol) { break; } case 'shutdown': if (isset($json['phoromatic']['client_update_script']) && !empty($json['phoromatic']['client_update_script'])) { self::run_client_update_script($json['phoromatic']['client_update_script']); sleep(10); } echo PHP_EOL . 'Phoromatic received a remote command to shutdown.' . PHP_EOL; phoromatic::update_system_status('Attempting System Shutdown'); if (pts_client::executable_in_path('poweroff')) { shell_exec('poweroff'); sleep(5); } break; case 'maintenance': echo PHP_EOL . 'Idling, system maintenance mode set by Phoromatic Server.' . PHP_EOL; phoromatic::update_system_status('Maintenance Mode'); sleep(60); break; case 'idle': if (isset($json['phoromatic']['client_update_script']) && !empty($json['phoromatic']['client_update_script'])) { self::run_client_update_script($json['phoromatic']['client_update_script']); } //echo PHP_EOL . 'Idling, waiting for task.' . PHP_EOL; phoromatic::update_system_status('Idling, Waiting For Task'); break; case 'exit': echo PHP_EOL . 'Phoromatic received a remote command to exit.' . PHP_EOL; phoromatic::update_system_status('Exiting Phoromatic'); $do_exit = true; break; } } } } if (!$do_exit) { if ($server_response == false) { sleep(rand(10, 30)); } else { sleep(60); } } } pts_client::release_lock(PTS_USER_PATH . 'phoromatic_lock'); }
public static function user_start() { if (pts_client::create_lock(PTS_USER_PATH . 'ekofisk_lock') == false) { trigger_error('Ekofisk is already running.', E_USER_ERROR); return false; } if (pts_openbenchmarking_client::user_name() == null) { trigger_error('You must be logged into your OpenBenchmarking.org account.', E_USER_ERROR); return false; } $last_communication_minute = null; $communication_attempts = 0; do { $exit_loop = false; if ($last_communication_minute != date('i')) { echo PHP_EOL . 'Checking State From Server @ ' . date('H:i:s'); } if ($last_communication_minute == date('i') && $communication_attempts > 3) { // Something is wrong, Phoromatic shouldn't be communicating with server more than three times a minute $response = M_PHOROMATIC_RESPONSE_IDLE; } else { $server_response = self::make_server_request(array('ekofisk_task' => 'status_check')); $json = json_decode($server_response, true); $response = $json['openbenchmarking']['response']['ekofisk']; if (date('i') != $last_communication_minute) { $last_communication_minute = date('i'); $communication_attempts = 0; } $communication_attempts++; } echo ' [' . $response . ']' . PHP_EOL; switch ($response) { case M_PHOROMATIC_RESPONSE_RUN_TEST: $test_flags = pts_c::auto_mode | pts_c::recovery_mode; do { $suite_identifier = 'phoromatic-' . rand(1000, 9999); } while (is_file(PTS_TEST_SUITE_PATH . 'local/' . $suite_identifier . '/suite-definition.xml')); file_put_contents(PTS_TEST_SUITE_PATH . 'local/' . $suite_identifier . '/suite-definition.xml', $server_response); $phoromatic_schedule_id = $xml_parser->getXMLValue(M_PHOROMATIC_ID); $phoromatic_results_identifier = $xml_parser->getXMLValue(M_PHOROMATIC_SYS_NAME); $phoromatic_trigger = $xml_parser->getXMLValue(M_PHOROMATIC_TRIGGER); if (pts_strings::string_bool($xml_parser->getXMLValue(M_PHOROMATIC_RUN_INSTALL_COMMAND, M_PHOROMATIC_RESPONSE_TRUE))) { phoromatic::set_user_context($xml_parser->getXMLValue(M_PHOROMATIC_SET_CONTEXT_PRE_INSTALL), $phoromatic_trigger, $phoromatic_schedule_id, 'INSTALL'); pts_client::set_test_flags($test_flags); pts_test_installer::standard_install($suite_identifier); } phoromatic::set_user_context($xml_parser->getXMLValue(M_PHOROMATIC_SET_CONTEXT_PRE_RUN), $phoromatic_trigger, $phoromatic_schedule_id, 'INSTALL'); // Do the actual running if (pts_test_run_manager::initial_checks($suite_identifier)) { $test_run_manager = new pts_test_run_manager($test_flags); // Load the tests to run if ($test_run_manager->load_tests_to_run($suite_identifier)) { if (pts_strings::string_bool($xml_parser->getXMLValue(M_PHOROMATIC_UPLOAD_TO_GLOBAL, 'FALSE'))) { $test_run_manager->auto_upload_to_openbenchmarking(); } // Save results? $test_run_manager->auto_save_results(date('Y-m-d H:i:s'), $phoromatic_results_identifier, 'A Phoromatic run.'); // Run the actual tests $test_run_manager->pre_execution_process(); $test_run_manager->call_test_runs(); $test_run_manager->post_execution_process(); // Upload to Phoromatic pts_file_io::unlink(PTS_TEST_SUITE_PATH . 'local/' . $suite_identifier . '/suite-definition.xml'); // Upload test results if (is_file(PTS_SAVE_RESULTS_PATH . $save_identifier . '/composite.xml')) { phoromatic::update_system_status('Uploading Test Results'); $times_tried = 0; do { if ($times_tried > 0) { echo PHP_EOL . 'Connection to server failed. Trying again in 60 seconds...' . PHP_EOL; sleep(60); } $uploaded_test_results = phoromatic::upload_test_results($save_identifier, $phoromatic_schedule_id, $phoromatic_results_identifier, $phoromatic_trigger); $times_tried++; } while ($uploaded_test_results == false && $times_tried < 5); if ($uploaded_test_results == false) { echo 'Server connection failed. Exiting...' . PHP_EOL; return false; } if (pts_strings::string_bool($xml_parser->getXMLValue(M_PHOROMATIC_ARCHIVE_RESULTS_LOCALLY, M_PHOROMATIC_RESPONSE_TRUE)) == false) { pts_client::remove_saved_result_file($save_identifier); } } } } break; case M_PHOROMATIC_RESPONSE_EXIT: echo PHP_EOL . 'Phoromatic received a remote command to exit.' . PHP_EOL; phoromatic::update_system_status('Exiting Phoromatic'); pts_client::release_lock(PTS_USER_PATH . 'phoromatic_lock'); $exit_loop = true; break; case M_PHOROMATIC_RESPONSE_SERVER_MAINTENANCE: // The Phoromatic server is down for maintenance, so don't bother updating system status and wait longer before checking back echo PHP_EOL . 'The Phoromatic server is currently down for maintenance. Waiting for service to be restored.' . PHP_EOL; sleep((15 - date('i') % 15) * 60); break; case M_PHOROMATIC_RESPONSE_SHUTDOWN: echo PHP_EOL . 'Shutting down the system.' . PHP_EOL; $exit_loop = true; shell_exec('poweroff'); // Currently assuming root break; case M_PHOROMATIC_RESPONSE_REBOOT: echo PHP_EOL . 'Rebooting the system.' . PHP_EOL; $exit_loop = true; shell_exec('reboot'); // Currently assuming root break; case M_PHOROMATIC_RESPONSE_IDLE: default: phoromatic::update_system_status('Idling, Waiting For Task'); sleep((10 - date('i') % 10) * 60); // Check with server every 10 minutes break; } if (phodevi::system_hardware(true) != $current_hw || phodevi::system_software(true) != $current_sw) { // Hardware and/or software has changed while PTS/Phoromatic has been running, update the Phoromatic Server echo 'Updating Installed Hardware / Software With Phoromatic Server' . PHP_EOL; phoromatic::update_system_details(); $current_hw = phodevi::system_hardware(true); $current_sw = phodevi::system_software(true); } } while ($exit_loop == false); phoromatic::update_system_status('Offline'); }