public static function run($r) { pts_file_io::unlink(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/web-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; } $server_launcher = '#!/bin/sh' . PHP_EOL; $web_port = 0; $remote_access = pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort', 'FALSE'); $remote_access = is_numeric($remote_access) && $remote_access > 1 ? $remote_access : false; $blocked_ports = array(2049, 3659, 4045, 6000); if ($remote_access) { // ALLOWING SERVER TO BE REMOTELY ACCESSIBLE $server_ip = '0.0.0.0'; $fp = false; $errno = null; $errstr = null; if (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false) { 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); fclose($fp); return false; } else { $web_port = $remote_access; $web_socket_port = pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort', ''); if ($web_socket_port == null || !is_numeric($web_socket_port)) { $web_socket_port = $web_port - 1; } } } else { echo PHP_EOL . PHP_EOL . 'You must first configure the remote GUI/WEBUI settings via:' . pts_config::get_config_file_location() . PHP_EOL . PHP_EOL; return false; } // WebSocket Server Setup $server_launcher .= 'export PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL; $server_launcher .= 'export PTS_WEBSOCKET_SERVER=GUI' . 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; // HTTP Server Setup 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 false; } else { $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'web-interface/ 2> /dev/null &' . PHP_EOL; //2> /dev/null } $server_launcher .= 'http_server_pid=$!' . PHP_EOL; $server_launcher .= 'sleep 1' . PHP_EOL; $server_launcher .= 'echo "The Web Interface Is Accessible At: http://localhost:' . $web_port . '"' . PHP_EOL; $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL . 'read var_name'; // Shutdown / Kill Servers $server_launcher .= PHP_EOL . 'kill $http_server_pid'; $server_launcher .= PHP_EOL . 'kill $websocket_server_pid'; $server_launcher .= PHP_EOL . 'rm -f ~/.phoronix-test-suite/run-lock*'; file_put_contents(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/web-server-launcher', $server_launcher); }
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 system_monitor_task_post_test(&$test_profile) { $test_directory = $test_profile->get_install_dir(); foreach (self::$monitoring_sensors as $sensor_r) { if ($sensor_r[1] == array('sys', 'time')) { // sys.time is a special case $end_time = microtime(true); // Delta time $result_value = $end_time - $sensor_r[3]; if ($result_value < 3) { // The test ended too fast $result_value = null; } } else { // Kill the sensor monitoring thread if (function_exists('posix_kill') == false) { pts_client::$display->test_run_error('The PHP POSIX extension is required for this test.'); return false; } posix_kill($sensor_r[0], SIGTERM); $sensor_values = explode("\n", pts_file_io::file_get_contents($sensor_r[3])); pts_file_io::unlink($sensor_r[3]); if (count($sensor_values) == 0) { continue; } switch ($sensor_r[2]) { case 'MAX': $result_value = max($sensor_values); break; case 'MIN': $result_value = min($sensor_values); break; case 'AVG': $result_value = array_sum($sensor_values) / count($sensor_values); break; case 'ALL': $result_value = implode(',', $sensor_values); break; default: $result_value = null; break; } } if ($result_value != null) { // For now it's only possible to return one result per test return $result_value; } } return false; }
public static function release_lock($lock_file) { // Remove lock if (isset(self::$lock_pointers[$lock_file]) == false) { return false; } if (is_resource(self::$lock_pointers[$lock_file])) { fclose(self::$lock_pointers[$lock_file]); } pts_file_io::unlink($lock_file); unset(self::$lock_pointers[$lock_file]); }
public function process_test_run_request($run_index) { $result = false; if ($this->result_file && $this->result_file->get_test_count() > 0) { $this->result_file->get_xml(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/composite.xml'); } if (is_object($run_index)) { $test_run_request = $run_index; $run_index = 0; } else { $test_run_request = $this->get_test_to_run($run_index); } if ($run_index != 0 && count(pts_file_io::glob($test_run_request->test_profile->get_install_dir() . 'cache-share-*.pt2so')) == 0) { // Sleep for six seconds between tests by default sleep(6); } if ($test_run_request == false) { return; } $active_result_buffer = pts_test_execution::run_test($this, $test_run_request); if (pts_file_io::unlink(PTS_USER_PATH . 'halt-testing')) { // Stop the testing process entirely return false; } else { if (pts_file_io::unlink(PTS_USER_PATH . 'skip-test')) { // Just skip the current test and do not save the results, but continue testing return true; } else { if (pts_client::read_env('LIMIT_ELAPSED_TEST_TIME') > 0 && PTS_INIT_TIME + pts_client::read_env('LIMIT_ELAPSED_TEST_TIME') * 60 > time()) { // Allocated amount of time has expired return false; } } } $test_successful = false; if ($test_run_request->test_profile->get_display_format() == 'NO_RESULT') { $test_successful = true; } else { if ($test_run_request instanceof pts_test_result && $test_run_request->active) { $end_result = $test_run_request->active->get_result(); // removed count($result) > 0 in the move to pts_test_result if (count($test_run_request) > 0 && (is_numeric($end_result) && $end_result > 0 || !is_numeric($end_result) && isset($end_result[3]))) { pts_module_manager::module_process('__post_test_run_success', $test_run_request); $test_identifier = $this->get_results_identifier(); $test_successful = true; if (!empty($test_identifier)) { $test_run_request->test_result_buffer = new pts_test_result_buffer(); $test_run_request->test_result_buffer->add_test_result($this->results_identifier, $test_run_request->active->get_result(), $active_result_buffer->get_values_as_string(), self::process_json_report_attributes($test_run_request), $test_run_request->active->get_min_result(), $test_run_request->active->get_max_result()); $this->result_file->add_result($test_run_request); if ($test_run_request->secondary_linked_results != null && is_array($test_run_request->secondary_linked_results)) { foreach ($test_run_request->secondary_linked_results as &$run_request_minor) { if (strpos($run_request_minor->get_arguments_description(), $test_run_request->get_arguments_description()) === false) { $run_request_minor->set_used_arguments_description($test_run_request->get_arguments_description() . ' - ' . $run_request_minor->get_arguments_description()); $run_request_minor->set_used_arguments($test_run_request->get_arguments() . ' - ' . $run_request_minor->get_arguments_description()); } $run_request_minor->test_result_buffer = new pts_test_result_buffer(); $run_request_minor->test_result_buffer->add_test_result($this->results_identifier, $run_request_minor->active->get_result(), $run_request_minor->active->get_values_as_string(), self::process_json_report_attributes($test_run_request), $run_request_minor->active->get_min_result(), $run_request_minor->active->get_max_result()); $this->result_file->add_result($run_request_minor); } } if ($this->get_results_identifier() != null && $this->get_file_name() != null && pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/SaveTestLogs', 'FALSE')) { static $xml_write_pos = 1; pts_file_io::mkdir(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/' . $xml_write_pos . '/'); if (is_dir(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier())) { $test_log_write_dir = PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/' . $xml_write_pos . '/' . $this->get_results_identifier() . '/'; if (is_dir($test_log_write_dir)) { pts_file_io::delete($test_log_write_dir, null, true); } rename(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier() . '/', $test_log_write_dir); } $xml_write_pos++; } } } pts_file_io::unlink(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/active/'); } } if ($test_successful == false && $test_run_request->test_profile->get_identifier() != null) { array_push($this->failed_tests_to_run, $test_run_request); // For now delete the failed test log files, but it may be a good idea to keep them pts_file_io::delete(PTS_SAVE_RESULTS_PATH . $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier() . '/', null, true); } pts_module_manager::module_process('__post_test_run_process', $this->result_file); return true; }
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($r) { if (pts_openbenchmarking_client::user_name() == false) { echo PHP_EOL . 'You must first be logged into an OpenBenchmarking.org account.' . PHP_EOL; echo PHP_EOL . 'Create An Account: http://openbenchmarking.org/'; echo PHP_EOL . 'Log-In Command: phoronix-test-suite openbenchmarking-setup' . PHP_EOL . PHP_EOL; return false; } ini_set('memory_limit', '2048M'); foreach (pts_types::identifiers_to_test_profile_objects($r, false, true) as $test_profile) { $qualified_identifier = $test_profile->get_identifier(); // First make sure the test profile is already in the OpenBenchmarking.org database... $json = pts_openbenchmarking::make_openbenchmarking_request('is_test_profile', array('i' => $qualified_identifier)); $json = json_decode($json, true); if (!isset($json['openbenchmarking']['test']['valid']) || $json['openbenchmarking']['test']['valid'] != 'TRUE') { echo PHP_EOL . $qualified_identifier . ' must first be uploaded to OpenBenchmarking.org.' . PHP_EOL; // break; } // Set some other things... pts_client::pts_set_environment_variable('FORCE_TIMES_TO_RUN', 1); pts_client::pts_set_environment_variable('TEST_RESULTS_NAME', $test_profile->get_title() . ' Testing ' . date('Y-m-d')); pts_client::pts_set_environment_variable('TEST_RESULTS_IDENTIFIER', 'Sample Run'); pts_client::pts_set_environment_variable('TEST_RESULTS_DESCRIPTION', 1); pts_openbenchmarking_client::override_client_setting('AutoUploadResults', true); pts_openbenchmarking_client::override_client_setting('UploadSystemLogsByDefault', true); // Take screenshots pts_client::pts_set_environment_variable('SCREENSHOT_INTERVAL', 9); pts_module_manager::attach_module('timed_screenshot'); $force_ss = true; $reference_ss_file = pts_module_manager::module_call('timed_screenshot', 'take_screenshot', $force_ss); sleep(2); $apitrace = pts_file_io::glob('/usr/local/lib/*/apitrace/wrappers/glxtrace.so'); if (!empty($apitrace) && pts_client::executable_in_path('apitrace')) { $apitrace = array_shift($apitrace); putenv('LD_PRELOAD=' . $apitrace); } else { $apitrace = false; } // So for any compiling tasks they will try to use the most aggressive instructions possible putenv('CFLAGS=-march=native -O3'); putenv('CXXFLAGS=-march=native -O3'); pts_test_installer::standard_install($qualified_identifier, true); $run_manager = new pts_test_run_manager(false, 2); $run_manager->standard_run($qualified_identifier); if ($apitrace) { putenv('LD_PRELOAD='); } if ($reference_ss_file) { $reference_ss = pts_image::image_file_to_gd($reference_ss_file); unlink($reference_ss_file); $screenshots_gd = array(); $screenshots = pts_module_manager::module_call('timed_screenshot', 'get_screenshots'); var_dump($screenshots); foreach ($screenshots as $ss_file) { $screenshots_gd[$ss_file] = pts_image::image_file_to_gd($ss_file); if ($screenshots_gd[$ss_file] == false) { continue; } $ss_delta = pts_image::gd_image_delta_composite($reference_ss, $screenshots_gd[$ss_file], true); if (count($ss_delta) < floor(imagesx($reference_ss) * 0.5600000000000001) || filesize($ss_file) > 2097152) { // If less than 56% of the pixels are changing on X, then likely not much to show off... (CLI only likely) // Or if filesize of image is beyond 2MB //echo 'dropping' . $ss_file . PHP_EOL; unset($screenshots_gd[$ss_file]); pts_file_io::unlink($ss_file); } } $ss_files = array_keys($screenshots_gd); shuffle($ss_files); // Don't upload more than 4MB worth of screenshots while (pts_file_io::array_filesize($ss_files) > 1048576 * 2) { $f = array_pop($ss_files); unlink($f); } if (count($ss_files) > 0) { $c = 1; foreach ($ss_files as $i => $file) { $new_file = dirname($file) . '/screenshot-' . $c . '.png'; rename($file, $new_file); $ss_files[$i] = $new_file; $c++; } $ss_zip_file = PTS_OPENBENCHMARKING_SCRATCH_PATH . 'screenshots-' . $test_profile->get_identifier_base_name() . '-' . $test_profile->get_test_profile_version() . '.zip'; $zip_created = pts_compression::zip_archive_create($ss_zip_file, $ss_files); if ($zip_created) { echo count($ss_files) . ' screenshots captured for use.'; //'tp_sha1' => sha1_file($zip_file), //'tp_zip' => base64_encode(file_get_contents($zip_file)), } foreach ($ss_files as $file) { // pts_file_io::unlink($file); } } } $test_binary = self::locate_test_profile_lead_binary($test_profile); $shared_library_dependencies = array(); $instruction_usage = array(); $gl_calls = null; if (is_executable($test_binary)) { if ($apitrace) { // Find the trace... $test_binary_dir = dirname($test_binary); $trace_file = glob($test_binary_dir . '/*.trace'); if ($trace_file) { echo 'Analyzing GL traces'; $trace_file = array_shift($trace_file); $gl_usage = self::analyze_apitrace_trace_glpop($trace_file); if (!empty($gl_usage)) { $gl_calls = implode(',', $gl_usage); } } } $ldd = trim(shell_exec('ldd ' . $test_binary)); foreach (explode(PHP_EOL, $ldd) as $line) { $line = explode(' => ', $line); if (count($line) == 2) { $shared_library_dependencies[] = trim(basename($line[0])); } } echo PHP_EOL . 'SHARED LIBRARY DEPENDENCIES: ' . PHP_EOL; print_r($shared_library_dependencies); foreach (array('core-avx-i', 'bdver2') as $march) { // So for any compiling tasks they will try to use the most aggressive instructions possible putenv('CFLAGS=-march=' . $march . ' -O3'); putenv('CXXFLAGS=-march=' . $march . ' -O3'); pts_test_installer::standard_install($qualified_identifier, true); $instruction_usage[$march] = self::analyze_binary_instruction_usage($test_binary); if ($instruction_usage[$march] == null) { unset($instruction_usage[$march]); } } if (!empty($instruction_usage) && count(array_unique($instruction_usage)) == 1) { $generic = array_pop($instruction_usage); $instruction_usage = array('generic' => $generic); } var_dump($instruction_usage); } else { echo PHP_EOL . $test_binary; echo PHP_EOL . 'Test binary could not be found.' . PHP_EOL; // return false; } } sleep(10); var_dump($shared_library_dependencies); var_dump($instruction_usage); var_dump($gl_calls); $server_response = pts_openbenchmarking::make_openbenchmarking_request('upload_test_meta', array('i' => $test_profile->get_identifier(), 'screenshots_zip' => $ss_zip_conts = base64_encode(file_get_contents($ss_zip_file)), 'screenshots_zip_sha1' => sha1($ss_zip_conts), 'ldd_libraries' => implode(',', $shared_library_dependencies), 'opengl_calls' => $gl_calls, 'instruction_set_usage' => base64_encode(json_encode($instruction_usage)))); var_dump($server_response); $json = json_decode($server_response, true); pts_file_io::unlink($ss_zip_file); }
public static function run_matisk($args) { echo PHP_EOL . 'MATISK For The Phoronix Test Suite' . PHP_EOL; if (!isset($args[0]) || !is_file($args[0])) { echo PHP_EOL . 'You must specify a MATISK INI file to load.' . PHP_EOL . PHP_EOL; return false; } self::$matisk_config_dir = dirname($args[0]) . '/'; pts_file_io::mkdir(pts_module::save_dir()); $ini = parse_ini_file($args[0], true); foreach (self::$ini_struct as $section => $items) { foreach ($items as $key => $r) { if (is_array($r) && !isset($ini[$section][$key])) { $ini[$section][$key] = $r[0]; } } } // Checks if (pts_test_suite::is_suite($ini['workload']['suite']) == false) { // See if the XML suite-definition was just tossed into the same directory if (($xml_file = self::find_file($ini['workload']['suite'] . '.xml')) !== false) { pts_file_io::mkdir(PTS_TEST_SUITE_PATH . 'local/' . $ini['workload']['suite']); copy($xml_file, PTS_TEST_SUITE_PATH . 'local/' . $ini['workload']['suite'] . '/suite-definition.xml'); } if (pts_test_suite::is_suite($ini['workload']['suite']) == false) { echo PHP_EOL . 'A test suite must be specified to execute. If a suite needs to be constructed, run: ' . PHP_EOL . 'phoronix-test-suite build-suite' . PHP_EOL . PHP_EOL; return false; } } if ($ini['set_context']['external_contexts'] != null) { switch ($ini['set_context']['external_contexts_delimiter']) { case 'EOL': case '': $ini['set_context']['external_contexts_delimiter'] = PHP_EOL; break; case 'TAB': $ini['set_context']['external_contexts_delimiter'] = "\t"; break; } if ($ff = self::find_file($ini['set_context']['external_contexts'])) { if (is_executable($ff)) { $ini['set_context']['context'] = shell_exec($ff . ' 2> /dev/null'); } else { $ini['set_context']['context'] = file_get_contents($ff); } } else { // Hopefully it's a command to execute then... $ini['set_context']['context'] = shell_exec($ini['set_context']['external_contexts'] . ' 2> /dev/null'); } $ini['set_context']['context'] = explode($ini['set_context']['external_contexts_delimiter'], $ini['set_context']['context']); } else { if ($ini['set_context']['context'] != null && !is_array($ini['set_context']['context'])) { $ini['set_context']['context'] = array($ini['set_context']['context']); } } if (is_array($ini['set_context']['context']) && count($ini['set_context']['context']) > 0) { foreach ($ini['set_context']['context'] as $i => $context) { if ($context == null) { unset($ini['set_context']['context'][$i]); } } // Context testing if (count($ini['set_context']['context']) > 0 && $ini['set_context']['pre_run'] == null && $ini['set_context']['pre_install'] == null) { echo PHP_EOL . 'The pre_run or pre_install set_context fields must be set in order to set the system\'s context.' . PHP_EOL; return false; } if ($ini['set_context']['reverse_context_order']) { $ini['set_context']['context'] = array_reverse($ini['set_context']['context']); } } if (pts_strings::string_bool($ini['workload']['save_results'])) { if ($ini['workload']['save_name'] == null) { echo PHP_EOL . 'The save_name field cannot be left empty when saving the test results.' . PHP_EOL; return false; } /* if($ini['workload']['result_identifier'] == null) { echo PHP_EOL . 'The result_identifier field cannot be left empty when saving the test results.' . PHP_EOL; return false; } */ } if (!empty($ini['environmental_variables']) && is_array($ini['environmental_variables'])) { foreach ($ini['environmental_variables'] as $key => $value) { putenv(trim($key) . '=' . trim($value)); } } if (empty($ini['set_context']['context'])) { $ini['set_context']['context'] = array($ini['workload']['result_identifier']); } if (pts_strings::string_bool($ini['set_context']['log_context_outputs'])) { pts_file_io::mkdir(pts_module::save_dir() . $ini['workload']['save_name']); } $spent_context_file = pts_module::save_dir() . $ini['workload']['save_name'] . '.spent-contexts'; if (!is_file($spent_context_file)) { touch($spent_context_file); } else { // If recovering from an existing run, don't rerun contexts that were already executed $spent_contexts = pts_file_io::file_get_contents($spent_context_file); $spent_contexts = explode(PHP_EOL, $spent_contexts); foreach ($spent_contexts as $sc) { if (($key = array_search($sc, $ini['set_context']['context'])) !== false) { unset($ini['set_context']['context'][$key]); } } } if ($ini['set_context']['reboot_support'] && phodevi::is_linux()) { // In case a set-context involves a reboot, auto-recover $xdg_config_home = is_dir('/etc/xdg/autostart') && is_writable('/etc/xdg/autostart') ? '/etc/xdg/autostart' : pts_client::read_env('XDG_CONFIG_HOME'); if ($xdg_config_home == false) { $xdg_config_home = pts_client::user_home_directory() . '.config'; } if ($xdg_config_home != false && is_dir($xdg_config_home)) { $autostart_dir = $xdg_config_home . '/autostart/'; pts_file_io::mkdir($xdg_config_home . '/autostart/'); } file_put_contents($xdg_config_home . '/autostart/phoronix-test-suite-matisk.desktop', ' [Desktop Entry] Name=Phoronix Test Suite Matisk Recovery GenericName=Phoronix Test Suite Comment=Matisk Auto-Recovery Support Exec=gnome-terminal -e \'phoronix-test-suite matisk ' . $args[0] . '\' Icon=phoronix-test-suite Type=Application Encoding=UTF-8 Categories=System;Monitor;'); } if ($ini['installation']['block_phodevi_caching']) { // Block Phodevi caching if changing out system components and there is a chance one of the strings of changed contexts might be cached (e.g. OpenGL user-space driver) phodevi::$allow_phodevi_caching = false; } if (phodevi::system_uptime() < 60) { echo PHP_EOL . 'Sleeping 45 seconds while waiting for the system to settle...' . PHP_EOL; sleep(45); } self::$ini = $ini; $total_context_count = count(self::$ini['set_context']['context']); while (($context = array_shift(self::$ini['set_context']['context'])) !== null) { echo PHP_EOL . ($total_context_count - count(self::$ini['set_context']['context'])) . ' of ' . $total_context_count . ' in test execution queue [' . $context . ']' . PHP_EOL . PHP_EOL; self::$context = $context; if (pts_strings::string_bool(self::$ini['installation']['install_check']) || $ini['set_context']['pre_install'] != null) { self::process_user_config_external_hook_process('pre_install'); $force_install = false; $no_prompts = true; if (pts_strings::string_bool(self::$ini['installation']['force_install'])) { $force_install = true; } if (self::$ini['installation']['external_download_cache'] != null) { pts_test_install_manager::add_external_download_cache(self::$ini['installation']['external_download_cache']); } // Do the actual test installation pts_test_installer::standard_install(self::$ini['workload']['suite'], $force_install, $no_prompts); self::process_user_config_external_hook_process('post_install'); } $batch_mode = false; $auto_mode = true; $test_run_manager = new pts_test_run_manager($batch_mode, $auto_mode); if ($test_run_manager->initial_checks(self::$ini['workload']['suite']) == false) { return false; } if (self::$skip_test_set == false) { self::process_user_config_external_hook_process('pre_run'); // Load the tests to run if ($test_run_manager->load_tests_to_run(self::$ini['workload']['suite']) == false) { return false; } // Save results? $result_identifier = $ini['workload']['result_identifier']; if ($result_identifier == null) { $result_identifier = '$MATISK_CONTEXT'; } // Allow $MATIISK_CONTEXT as a valid user variable to pass it... $result_identifier = str_replace('$MATISK_CONTEXT', self::$context, $result_identifier); $test_run_manager->set_save_name(self::$ini['workload']['save_name']); $test_run_manager->set_results_identifier($result_identifier); $test_run_manager->set_description(self::$ini['workload']['description']); // Don't upload results unless it's the last in queue where the context count is now 0 $test_run_manager->auto_upload_to_openbenchmarking(count(self::$ini['set_context']['context']) == 0 && self::$ini['general']['upload_to_openbenchmarking']); // Run the actual tests $test_run_manager->pre_execution_process(); $test_run_manager->call_test_runs(); $test_run_manager->post_execution_process(); } self::$skip_test_set = false; file_put_contents($spent_context_file, self::$context . PHP_EOL, FILE_APPEND); pts_file_io::unlink(pts_module::save_dir() . self::$context . '.last-call'); self::process_user_config_external_hook_process('post_run'); } unlink($spent_context_file); isset($xdg_config_home) && pts_file_io::unlink($xdg_config_home . '/autostart/phoronix-test-suite-matisk.desktop'); }
public static function run($r) { // Lets get stuff ready. 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; } $web_port = 0; $blocked_ports = array(2049, 3659, 4045, 6000); // SERVER JUST RUNNING FOR LOCAL SYSTEM, SO ALSO COME UP WITH RANDOM FREE PORT $server_ip = 'localhost'; // Randomly choose a port and ensure it's not being used... $fp = false; $errno = null; $errstr = null; do { if ($fp != false) { fclose($fp); } $web_port = rand(2000, 5999); $web_socket_port = $web_port - 1; } while (($fp = fsockopen('127.0.0.1', $web_port, $errno, $errstr, 5)) != false || ($fp = fsockopen('127.0.0.1', $web_socket_port, $errno, $errstr, 5)) != false || in_array($web_port, $blocked_ports) || in_array($web_socket_port, $blocked_ports)); // Check if we are running on Windows or a *nix. if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $script_path = PTS_USER_PATH . 'web-server-launcher.bat'; pts_file_io::unlink($script_path); // Lets turn off echo so we don't need to see every command. $server_launcher = '@echo off' . PHP_EOL; $server_launcher .= 'if "%~1"==":run_ws_server" goto :run_ws_server' . PHP_EOL; $server_launcher .= 'if "%~1"==":run_local_server" goto :run_local_server' . PHP_EOL; $server_launcher .= 'set CURRENT_DIR="%cd%"' . PHP_EOL . PHP_EOL; $server_launcher .= 'start cmd /c "%~f0" :run_ws_server' . PHP_EOL; $server_launcher .= 'start cmd /c "%~f0" :run_local_server' . PHP_EOL . PHP_EOL; // Setup configurations $server_launcher .= 'set PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL; $server_launcher .= 'set PTS_MODE="CLIENT"' . PHP_EOL . PHP_EOL; // Windows has no sleep so we ping an invalid ip for a second! $server_launcher .= 'ping 192.0.2.2 -n 1 -w 1000 > nul' . PHP_EOL; // Browser Launching if (($browser = pts_client::executable_in_path('chromium-browser')) || ($browser = pts_client::executable_in_path('google-chrome'))) { $server_launcher .= 'echo "Launching Browser"' . PHP_EOL; $server_launcher .= $browser . ' --temp-profile --app=http://localhost:' . $web_port . ' -start-maximized'; // chromium-browser --kiosk URL starts full-screen } else { if (($browser = pts_client::executable_in_path('firefox')) || ($browser = pts_client::executable_in_path('xdg-open'))) { $server_launcher .= 'echo "Launching Browser"' . PHP_EOL; $server_launcher .= $browser . ' http://localhost:' . $web_port; // XXX: Need this here since Firefox and some other browsers will return right away rather than wait on process.... $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL . 'read var_name'; } else { $server_launcher .= 'echo "Launch: http://localhost:' . $web_port . '"' . PHP_EOL; $server_launcher .= PHP_EOL . 'echo "Press any key to kill server..."' . PHP_EOL . 'pause'; } } // Shutdown / Kill Servers (Might want to find a cleaner way) $server_launcher .= PHP_EOL . 'taskkill /f /im php.exe'; // For now lets clean this up. $server_launcher .= PHP_EOL . 'del /f ' . getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . 'run*' . PHP_EOL; $server_launcher .= 'exit /B' . PHP_EOL . PHP_EOL; // HTTP Server Setup $server_launcher .= ':run_local_server' . PHP_EOL; 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 false; } else { $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'web-interface 2> null &' . PHP_EOL; } $server_launcher .= 'exit' . PHP_EOL . PHP_EOL; // WebSocket Server Setup $server_launcher .= ':run_ws_server' . PHP_EOL; $server_launcher .= 'cd ' . getenv('PTS_DIR') . PHP_EOL; $server_launcher .= getenv('PHP_BIN') . ' pts-core\\phoronix-test-suite.php start-ws-server &' . PHP_EOL; $server_launcher .= 'exit'; // I dont believe this needs to be done for windows? //$server_launcher .= PHP_EOL . 'del /f ~\\.phoronix-test-suite\\run-lock*'; file_put_contents($script_path, $server_launcher); } else { $script_path = getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/web-server-launcher'; pts_file_io::unlink($script_path); $server_launcher = '#!/bin/sh' . PHP_EOL; // WebSocket Server Setup $server_launcher .= 'export PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL; $server_launcher .= 'export PTS_WEBSOCKET_SERVER=GUI' . 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; // HTTP Server Setup 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 false; } else { $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'web-interface/ 2> /dev/null &' . PHP_EOL; //2> /dev/null } $server_launcher .= 'http_server_pid=$!' . PHP_EOL; $server_launcher .= 'sleep 1' . PHP_EOL; // Browser Launching if (($browser = pts_client::executable_in_path('chromium-browser')) || ($browser = pts_client::executable_in_path('google-chrome'))) { $server_launcher .= 'echo "Launching Browser"' . PHP_EOL; $server_launcher .= $browser . ' --temp-profile --app=http://localhost:' . $web_port . ' -start-maximized'; // chromium-browser --kiosk URL starts full-screen } else { if (($browser = pts_client::executable_in_path('firefox')) || ($browser = pts_client::executable_in_path('xdg-open'))) { $server_launcher .= 'echo "Launching Browser"' . PHP_EOL; $server_launcher .= $browser . ' http://localhost:' . $web_port; // XXX: Need this here since Firefox and some other browsers will return right away rather than wait on process.... $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL . 'read var_name'; } else { $server_launcher .= 'echo "Launch: http://localhost:' . $web_port . '"' . PHP_EOL; $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL . 'read var_name'; } } // Shutdown / Kill Servers $server_launcher .= PHP_EOL . 'kill $http_server_pid'; $server_launcher .= PHP_EOL . 'kill $websocket_server_pid'; $server_launcher .= PHP_EOL . 'rm -f ~/.phoronix-test-suite/run-lock*'; file_put_contents($script_path, $server_launcher); } echo 'To start server run new script: ' . $script_path; }
public static function user_system_process() { $last_communication_minute = date('i'); $communication_attempts = 0; static $current_hw = null; static $current_sw = null; if (define('PHOROMATIC_START', true)) { echo PHP_EOL . 'Registering Status With Phoromatic Server @ ' . date('H:i:s') . PHP_EOL; $times_tried = 0; do { if ($times_tried > 0) { echo PHP_EOL . 'Connection to server failed. Trying again in 60 seconds...' . PHP_EOL; sleep(60); } $update_sd = phoromatic::update_system_details(); $times_tried++; } while (!$update_sd && $times_tried < 5); if (!$update_sd) { echo 'Server connection still failed. Exiting...' . PHP_EOL; return false; } $current_hw = phodevi::system_hardware(true); $current_sw = phodevi::system_software(true); echo PHP_EOL . 'Idling 30 seconds for system to settle...' . PHP_EOL; sleep(30); } do { $exit_loop = false; echo PHP_EOL . 'Checking Status From Phoromatic Server @ ' . date('H:i:s'); if ($last_communication_minute == date('i') && $communication_attempts > 2) { // Something is wrong, Phoromatic shouldn't be communicating with server more than three times a minute $response = M_PHOROMATIC_RESPONSE_IDLE; } else { $server_response = phoromatic::upload_to_remote_server(array('r' => 'status_check')); $xml_parser = new nye_XmlReader($server_response); $response = $xml_parser->getXMLValue(M_PHOROMATIC_GEN_RESPONSE); 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'); }
public static function run($args) { $result = $args[0]; $result_file = new pts_result_file($result); $result_file_identifiers = $result_file->get_system_identifiers(); if (count($result_file_identifiers) < 2) { echo PHP_EOL . 'There are not multiple test runs in this result file.' . PHP_EOL; return false; } $base_identifier = pts_user_io::prompt_text_menu('Select the base test run', $result_file_identifiers); $base_select = new pts_result_merge_select($result, $base_identifier); $compare_identifier = pts_user_io::prompt_text_menu('Select the test run to compare', $result_file_identifiers); $compare_select = new pts_result_merge_select($result, $compare_identifier); do { $extract_to = 'iqc-analyze-' . rand(100, 999); } while (is_dir(PTS_SAVE_RESULTS_PATH . $extract_to)); $extract_result = pts_merge::merge_test_results($base_select, $compare_select); pts_client::save_test_result($extract_to . '/composite.xml', $extract_result); $compare_file = new pts_result_file($extract_to); $result_file_writer = new pts_result_file_writer('Image Delta'); foreach ($compare_file->get_result_objects() as $result_object) { if ($result_object->test_profile->get_display_format() != 'IMAGE_COMPARISON') { continue; } $base_result = null; $compare_result = null; foreach ($result_object->test_result_buffer->get_buffer_items() as $buffer_item) { if ($buffer_item->get_result_identifier() == $base_identifier && $base_result == null) { $base_result = $buffer_item->get_result_value(); } else { if ($buffer_item->get_result_identifier() == $compare_identifier && $compare_result == null) { $compare_result = $buffer_item->get_result_value(); } } if ($compare_result != null && $base_result != null) { break; } } if ($compare_result == null || $base_result == null) { continue; } $base_img = imagecreatefromstring(base64_decode($base_result)); $compare_img = imagecreatefromstring(base64_decode($compare_result)); $delta_img = imagecreatefromstring(base64_decode($compare_result)); $img_width = imagesx($base_img); $img_height = imagesy($base_img); $img_changed = false; for ($x = 0; $x < $img_width; $x++) { for ($y = 0; $y < $img_height; $y++) { $base_image_color = pts_image::rgb_gd_color_at($base_img, $x, $y); $compare_image_color = pts_image::rgb_gd_color_at($compare_img, $x, $y); if ($base_image_color == $compare_image_color || pts_image::rgb_int_diff($base_image_color, $compare_image_color) < 9) { if ($cords = pts_image::color_pixel_delta($base_img, $compare_img, $x, $y)) { $pixel_rgb = pts_image::rgb_gd_color_at($delta_img, $cords[0], $cords[1]); $color_invert = imagecolorresolve($delta_img, 255 - $pixel_rgb[0], 255 - $pixel_rgb[1], 255 - $pixel_rgb[2]); imagesetpixel($delta_img, $x, $y, $color_invert); $img_changed = true; } } } } if ($img_changed) { imagepng($delta_img, PTS_SAVE_RESULTS_PATH . $extract_to . '/scratch.png'); $result_value = base64_encode(file_get_contents(PTS_SAVE_RESULTS_PATH . $extract_to . '/scratch.png', FILE_BINARY)); pts_file_io::unlink(PTS_SAVE_RESULTS_PATH . $extract_to . '/scratch.png'); $result_file_writer->add_result_from_result_object_with_value_string($result_object, $result_value); } } pts_client::save_result_file($result_file_writer, $extract_to); pts_client::display_web_page(PTS_SAVE_RESULTS_PATH . $extract_to . '/composite.xml'); }