public function __construct($new_values = null)
 {
     if (PTS_IS_DAEMONIZED_SERVER_PROCESS || is_file('/etc/phoronix-test-suite.xml') && is_writable('/etc/phoronix-test-suite.xml')) {
         $file = '/etc/phoronix-test-suite.xml';
     } else {
         if (PTS_IS_CLIENT && is_file(pts_config::get_config_file_location())) {
             $file = pts_config::get_config_file_location();
         } else {
             if (PTS_USER_PATH . 'user-config.xml' != pts_config::get_config_file_location() && is_file(PTS_USER_PATH . 'user-config.xml')) {
                 $file = PTS_USER_PATH . 'user-config.xml';
             } else {
                 if (PTS_IS_CLIENT && is_file($t = PTS_CORE_STATIC_PATH . phodevi::read_property('system', 'vendor-identifier') . '-user-config-template.xml')) {
                     $file = $t;
                 } else {
                     if (is_file(PTS_CORE_STATIC_PATH . 'user-config-template.xml')) {
                         $file = PTS_CORE_STATIC_PATH . 'user-config-template.xml';
                     } else {
                         if (is_file(PTS_CORE_STATIC_PATH . 'user-config-defaults.xml')) {
                             $file = PTS_CORE_STATIC_PATH . 'user-config-defaults.xml';
                         } else {
                             $file = null;
                         }
                     }
                 }
             }
         }
     }
     $this->override_values = is_array($new_values) ? $new_values : false;
     parent::__construct($file);
 }
 public static function run($r)
 {
     if (count($r) == 0) {
         echo PHP_EOL . 'You must specify the tag to override along with the value.' . PHP_EOL;
         echo 'Example: phoronix-test-suite user-config-set CacheDirectory=~/cache/' . PHP_EOL . PHP_EOL;
         return false;
     }
     $new_options = array();
     foreach ($r as $user_option) {
         $user_option_r = explode('=', $user_option);
         if (count($user_option_r) > 1) {
             $user_value = substr($user_option, strlen($user_option_r[0]) + 1);
             if (substr($user_value, 0, 1) == '"') {
                 $user_value = substr($user_value, 1);
             }
             if (substr($user_value, -1) == '"') {
                 $user_value = substr($user_value, 0, -1);
             }
             if (!in_array(basename($user_option_r[0]), array('AgreementCheckSum', 'GSID'))) {
                 $new_options[$user_option_r[0]] = $user_value;
             }
         }
     }
     pts_config::user_config_generate($new_options);
     echo PHP_EOL . 'New user configuration file written.' . PHP_EOL . PHP_EOL;
 }
 public static function run($r)
 {
     if (is_file(pts_config::get_config_file_location())) {
         copy(pts_config::get_config_file_location(), PTS_USER_PATH . 'user-config-old.xml');
         unlink(pts_config::get_config_file_location());
     }
     pts_config::user_config_generate();
 }
 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);
 }
 public static function run($r)
 {
     $force_options = array('PhoronixTestSuite/Options/OpenBenchmarking/AnonymousUsageReporting' => 'FALSE');
     if (pts_network::internet_support_available() == false) {
         $force_options['PhoronixTestSuite/Options/Networking/NoInternetCommunication'] = 'TRUE';
     }
     pts_config::user_config_generate($force_options);
     $pso = pts_storage_object::recover_from_file(PTS_CORE_STORAGE);
     $pso->add_object('user_agreement_cs', 'enterprise-agree');
     $pso->save_to_file(PTS_CORE_STORAGE);
     echo PHP_EOL . 'Enterprise setup tasks executed.' . PHP_EOL . PHP_EOL;
 }
 public static function run($r)
 {
     pts_client::$display->generic_heading('Network Setup');
     if (!pts_user_io::prompt_bool_input('Configure the Phoronix Test Suite to use a HTTP proxy', false)) {
         return false;
     }
     $proxy_address = pts_user_io::prompt_user_input('Enter IP address / server name of proxy');
     $proxy_port = pts_user_io::prompt_user_input('Enter TCP port for proxy server');
     echo PHP_EOL . 'Testing Proxy Server (' . $proxy_address . ':' . $proxy_port . ')' . PHP_EOL;
     if (pts_network::http_get_contents('http://www.phoronix-test-suite.com/PTS', $proxy_address, $proxy_port) == 'PTS') {
         echo PHP_EOL . 'Proxy Setup Completed; Storing Network Settings.' . PHP_EOL;
         pts_config::user_config_generate(array('PhoronixTestSuite/Options/Networking/ProxyAddress' => $proxy_address, 'PhoronixTestSuite/Options/Networking/ProxyPort' => $proxy_port));
     } else {
         echo PHP_EOL . 'Proxy Setup Failed.' . PHP_EOL;
     }
 }
 public static function run($r)
 {
     if (getenv('PTS_WEBSOCKET_PORT') !== false) {
         $web_socket_port = getenv('PTS_WEBSOCKET_PORT');
     }
     if (!isset($web_socket_port) || !is_numeric($web_socket_port)) {
         $web_socket_port = pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort', '80');
     }
     if (!isset($web_socket_port) || !is_numeric($web_socket_port)) {
         $web_socket_port = '80';
     }
     /*
     		if(getenv('PTS_PHOROMATIC_SERVER'))
     		{
     			if(function_exists('pcntl_fork'))
     			{
     				$pid = pcntl_fork();
     
     				if($pid != -1)
     				{
     					if($pid)
     					{
     						$new_pid = $pid;
     					}
     					else
     					{
     						$event_server = new pts_phoromatic_event_server();
     						exit(0);
     					}
     				}
     			}
     			else
     			{
     				echo PHP_EOL . 'Phoromatic Event Server Fails To Start Due To Lacking PCNTL Support.' . PHP_EOL . PHP_EOL;
     			}
     		} */
     switch (getenv('PTS_WEBSOCKET_SERVER')) {
         case 'PHOROMATIC':
             pts_web_socket::$mask_send = true;
             $websocket = new pts_web_socket_server_phoromatic('localhost', $web_socket_port);
             break;
         default:
         case 'GUI':
             $websocket = new pts_web_socket_server_gui('localhost', $web_socket_port);
             break;
     }
 }
 public static function find_download_cache()
 {
     if (is_file(PTS_DOWNLOAD_CACHE_PATH . 'pts-download-cache.json')) {
         $dc_file = PTS_DOWNLOAD_CACHE_PATH . 'pts-download-cache.json';
     } else {
         if (is_file('/var/cache/phoronix-test-suite/download-cache/pts-download-cache.json')) {
             $dc_file = '/var/cache/phoronix-test-suite/download-cache/pts-download-cache.json';
         } else {
             if (is_file(PTS_SHARE_PATH . 'download-cache/pts-download-cache.json')) {
                 $dc_file = PTS_SHARE_PATH . 'download-cache/pts-download-cache.json';
             } else {
                 $dc = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
                 if (is_file($dc . 'pts-download-cache.json')) {
                     $dc_file = $dc . 'pts-download-cache.json';
                 }
             }
         }
     }
     return $dc_file;
 }
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = '<h1>Cache Settings</h1>
				<h2>Test Profile Download Cache</h2>
				<p>Below are a list of files for verification/debugging purposes that are currently cached by the Phoromatic Server and available for Phoronix Test Suite client systems to download. These are files that are needed by various test profiles in the Phoronix Test Suite. To add more data to this Phoromatic Server cache, from the server run <strong>phoronix-test-suite make-download-cache</strong> while passing the names of any tests/suites you wish to have download and generate a cache for so they can be made available to the Phoronix Test Suite clients on your network.</p>';
        $dc = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
        $dc_exists = is_file($dc . 'pts-download-cache.json');
        if ($dc_exists) {
            $cache_json = file_get_contents($dc . 'pts-download-cache.json');
            $cache_json = json_decode($cache_json, true);
        }
        if (is_file($dc . 'pts-download-cache.json')) {
            if ($cache_json && isset($cache_json['phoronix-test-suite']['download-cache'])) {
                $total_file_size = 0;
                $main .= '<table style="margin: 0 auto;"><tr><th>File</th><th>Size</th></tr>';
                foreach ($cache_json['phoronix-test-suite']['download-cache'] as $file_name => $inf) {
                    $total_file_size += $cache_json['phoronix-test-suite']['download-cache'][$file_name]['file_size'];
                    $main .= '<tr><td>' . $file_name . '</td><td>' . round(max(0.1, $cache_json['phoronix-test-suite']['download-cache'][$file_name]['file_size'] / 1000000), 1) . 'MB</td></tr>';
                }
                $main .= '</table>';
                $main .= '<p><strong>' . count($cache_json['phoronix-test-suite']['download-cache']) . ' Files / ' . round($total_file_size / 1000000) . ' MB Cache Size</strong></p>';
            }
        } else {
            $main .= '<h3>No download cache file could be found; on the Phoromatic Server you should run <strong>phoronix-test-suite make-download-cache</strong>.</h3>';
            // TODO XXX implement from the GUI
        }
        $main .= '<hr /><h2>OpenBenchmarking.org Cache Data</h2>';
        $main .= '<p>Below is information pertaining to the OpenBenchmarking.org cache present on the Phoromatic Server. To update this cache, run <strong>phoronix-test-suite make-openbenchmarking-cache</strong> from the server.</p>';
        $index_files = pts_file_io::glob(PTS_OPENBENCHMARKING_SCRATCH_PATH . '*.index');
        $main .= '<table style="margin: 0 auto;"><tr><th>Repository</th><th>Last Updated</th></tr>';
        foreach ($index_files as $index_file) {
            $index_data = json_decode(file_get_contents($index_file), true);
            $main .= '<tr><td>' . basename($index_file, '.index') . '</td><td>' . date('d F Y H:i', $index_data['main']['generated']) . '</td></tr>';
        }
        $main .= '</table>';
        echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in());
        echo phoromatic_webui_footer();
    }
 public static function run($r)
 {
     echo PHP_EOL . 'These are the default configuration options for when running the Phoronix Test Suite in a batch mode (i.e. running phoronix-test-suite batch-benchmark universe). Running in a batch mode is designed to be as autonomous as possible, except for where you\'d like any end-user interaction.' . PHP_EOL . PHP_EOL;
     $batch_options = array();
     $batch_options['PhoronixTestSuite/Options/BatchMode/SaveResults'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Save test results when in batch mode', true));
     if ($batch_options['PhoronixTestSuite/Options/BatchMode/SaveResults'] == 'TRUE') {
         $batch_options['PhoronixTestSuite/Options/BatchMode/OpenBrowser'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Open the web browser automatically when in batch mode', false));
         $batch_options['PhoronixTestSuite/Options/BatchMode/UploadResults'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Auto upload the results to OpenBenchmarking.org', true));
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptForTestIdentifier'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Prompt for test identifier', true));
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptForTestDescription'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Prompt for test description', true));
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptSaveName'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Prompt for saved results file-name', true));
     } else {
         $batch_options['PhoronixTestSuite/Options/BatchMode/OpenBrowser'] = 'FALSE';
         $batch_options['PhoronixTestSuite/Options/BatchMode/UploadResults'] = 'FALSE';
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptForTestIdentifier'] = 'FALSE';
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptForTestDescription'] = 'FALSE';
         $batch_options['PhoronixTestSuite/Options/BatchMode/PromptSaveName'] = 'FALSE';
     }
     $batch_options['PhoronixTestSuite/Options/BatchMode/RunAllTestCombinations'] = pts_config::bool_to_string(pts_user_io::prompt_bool_input('Run all test options', true));
     $batch_options['PhoronixTestSuite/Options/BatchMode/Configured'] = 'TRUE';
     pts_config::user_config_generate($batch_options);
     echo PHP_EOL . 'Batch settings saved.' . PHP_EOL . PHP_EOL;
 }
 public static function init()
 {
     self::$flags = 0;
     self::$os_identifier_sha1 = sha1(phodevi::read_property('system', 'vendor-identifier'));
     self::$is_live_cd = 1 << 1;
     self::$no_network_communication = 1 << 2;
     self::$no_openbenchmarking_reporting = 1 << 3;
     self::$user_agreement_skip = 1 << 4;
     self::$skip_md5_checks = 1 << 5;
     self::$remove_test_on_completion = 1 << 6;
     self::$no_phodevi_cache = 1 << 7;
     self::$no_external_dependencies = 1 << 8;
     self::$upload_to_openbenchmarking = 1 << 9;
     switch (self::$os_identifier_sha1) {
         case 'b28d6a7148b34595c5b397dfcf5b12ac7932b3dc':
             // Moscow 2011-04 client
             self::$flags = self::$is_live_cd | self::$no_network_communication | self::$no_openbenchmarking_reporting | self::$user_agreement_skip | self::$skip_md5_checks | self::$remove_test_on_completion;
             break;
     }
     if (pts_client::read_env('NO_FILE_HASH_CHECKS') != false || pts_client::read_env('NO_MD5_CHECKS') != false) {
         self::$flags |= self::$skip_md5_checks;
     }
     if (pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/RemoveTestInstallOnCompletion', 'FALSE')) {
         self::$flags |= self::$remove_test_on_completion;
     }
     if (pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/AlwaysUploadResultsToOpenBenchmarking', 'FALSE')) {
         self::$flags |= self::$upload_to_openbenchmarking;
     }
     if (pts_client::read_env('NO_PHODEVI_CACHE') != false) {
         self::$flags |= self::$no_phodevi_cache;
     }
     if (pts_client::read_env('NO_EXTERNAL_DEPENDENCIES') != false || pts_client::read_env('SKIP_EXTERNAL_DEPENDENCIES') == 1) {
         // NO_EXTERNAL_DEPENDENCIES was deprecated in PTS 3.6 and replaced by more versatile SKIP_EXTERNAL_DEPENDENCIES
         self::$flags |= self::$no_external_dependencies;
     }
 }
 public static function client_startup()
 {
     if (($proxy_address = pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyAddress', false)) && ($proxy_port = pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyPort', false))) {
         self::$network_proxy['proxy'] = $proxy_address . ':' . $proxy_port;
         self::$network_proxy['address'] = $proxy_address;
         self::$network_proxy['port'] = $proxy_port;
     } else {
         if (($env_proxy = getenv('http_proxy')) != false && count($env_proxy = pts_strings::colon_explode($env_proxy)) == 2) {
             self::$network_proxy['proxy'] = $env_proxy[0] . ':' . $env_proxy[1];
             self::$network_proxy['address'] = $env_proxy[0];
             self::$network_proxy['port'] = $env_proxy[1];
         }
     }
     self::$network_timeout = pts_config::read_user_config('PhoronixTestSuite/Options/Networking/Timeout', 20);
     if (ini_get('allow_url_fopen') == 'Off') {
         if (!defined('PHOROMATIC_SERVER')) {
             echo PHP_EOL . 'The allow_url_fopen option in your PHP configuration must be enabled for network support.' . PHP_EOL . PHP_EOL;
         }
         self::$disable_network_support = true;
     } else {
         if (pts_config::read_bool_config('PhoronixTestSuite/Options/Networking/NoInternetCommunication', 'FALSE')) {
             if (!defined('PHOROMATIC_SERVER')) {
                 echo PHP_EOL . 'Internet Communication Is Disabled Per Your User Configuration.' . PHP_EOL . PHP_EOL;
             }
             self::$disable_internet_support = true;
         } else {
             if (pts_config::read_bool_config('PhoronixTestSuite/Options/Networking/NoNetworkCommunication', 'FALSE')) {
                 if (!defined('PHOROMATIC_SERVER')) {
                     echo PHP_EOL . 'Network Communication Is Disabled Per Your User Configuration.' . PHP_EOL . PHP_EOL;
                 }
                 self::$disable_network_support = true;
             } else {
                 if (pts_flags::no_network_communication() == true) {
                     //echo PHP_EOL . 'Network Communication Is Disabled Per Your User Configuration.' . PHP_EOL . PHP_EOL;
                     self::$disable_network_support = true;
                 } else {
                     if (!PTS_IS_WEB_CLIENT) {
                         $server_response = pts_network::http_get_contents('http://www.phoronix-test-suite.com/PTS', false, false);
                         if ($server_response != 'PTS') {
                             // Failed to connect to PTS server
                             // As a last resort, see if it can resolve IP to Google.com as a test for Internet connectivity...
                             // i.e. in case Phoronix server is down or some other issue, so just see if Google will resolve
                             // If google.com fails to resolve, it will simply return the original string
                             if (gethostbyname('google.com') == 'google.com') {
                                 echo PHP_EOL;
                                 if (PTS_IS_DAEMONIZED_SERVER_PROCESS) {
                                     // Wait some seconds in case network is still coming up
                                     foreach (array(20, 40) as $time_to_wait) {
                                         sleep($time_to_wait);
                                         $server_response = pts_network::http_get_contents('http://www.phoronix-test-suite.com/PTS', false, false);
                                         if ($server_response != 'PTS' && gethostbyname('google.com') == 'google.com') {
                                             trigger_error('No Internet Connectivity After Wait', E_USER_WARNING);
                                             self::$disable_internet_support = true;
                                         } else {
                                             self::$disable_internet_support = false;
                                             break;
                                         }
                                     }
                                 } else {
                                     trigger_error('No Internet Connectivity', E_USER_WARNING);
                                     self::$disable_internet_support = true;
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (pts_network::network_support_available() == false && ini_get('file_uploads') == 'Off') {
         echo PHP_EOL . 'The file_uploads option in your PHP configuration must be enabled for network support.' . PHP_EOL . PHP_EOL;
     }
 }
 public function scan_download_caches($local_download_caches, $remote_download_caches, $remote_files, $phoromatic_server_caches, $skip_hash_checks = false)
 {
     $download_location = $this->test_profile->get_install_dir();
     $main_download_cache = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
     foreach ($this->test_files as &$download_package) {
         $package_filename = $download_package->get_filename();
         if (is_file($download_location . $package_filename)) {
             // File is already there in the test/destination directory, must have been previously downloaded
             // Could add an MD5 check here to ensure validity, but if it made it here it was already valid unless user modified it
             if ($download_package->get_filesize() == 0) {
                 $download_package->set_filesize(filesize($download_location . $package_filename));
             }
             $download_package->set_download_location('IN_DESTINATION_DIR');
         } else {
             if (is_file($main_download_cache . $package_filename)) {
                 // In main download cache
                 if ($download_package->get_filesize() == 0) {
                     $download_package->set_filesize(filesize($main_download_cache . $package_filename));
                 }
                 $download_package->set_download_location('MAIN_DOWNLOAD_CACHE', array($main_download_cache . $package_filename));
             } else {
                 if (is_file(PTS_SHARE_PATH . 'download-cache/' . $package_filename)) {
                     // In system's /usr/share download cache
                     if ($download_package->get_filesize() == 0) {
                         $download_package->set_filesize(filesize(PTS_SHARE_PATH . 'download-cache/' . $package_filename));
                     }
                     $download_package->set_download_location('MAIN_DOWNLOAD_CACHE', array(PTS_SHARE_PATH . 'download-cache/' . $package_filename));
                 } else {
                     // Scan the local download caches
                     foreach ($local_download_caches as &$cache_directory) {
                         if (is_file($cache_directory . $package_filename) && ($skip_hash_checks || $download_package->check_file_hash($cache_directory . $package_filename))) {
                             if ($download_package->get_filesize() == 0) {
                                 $download_package->set_filesize(filesize($cache_directory . $package_filename));
                             }
                             $download_package->set_download_location('LOCAL_DOWNLOAD_CACHE', array($cache_directory . $package_filename));
                             break;
                         }
                     }
                     // Look-aside download cache copy
                     // Check to see if the same package name with the same package check-sum is already present in another test installation
                     $lookaside_copy = pts_test_install_manager::file_lookaside_test_installations($download_package);
                     if ($lookaside_copy) {
                         if ($download_package->get_filesize() == 0) {
                             $download_package->set_filesize(filesize($lookaside_copy));
                         }
                         $download_package->set_download_location('LOOKASIDE_DOWNLOAD_CACHE', array($lookaside_copy));
                     }
                     // Check Phoromatic server caches
                     if ($download_package->get_download_location_type() == null && $phoromatic_server_caches) {
                         foreach ($phoromatic_server_caches as $server_url => $repo) {
                             if (isset($repo[$package_filename]) && ($skip_hash_checks || $repo[$package_filename]['md5'] == $download_package->get_md5() || $repo[$package_filename]['sha256'] == $download_package->get_sha256() || $download_package->get_sha256() == null && $download_package->get_md5() == null)) {
                                 $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', array($server_url . '/download-cache.php?download=' . $package_filename));
                                 break;
                             }
                         }
                     }
                     // If still not found, check remote download caches
                     if ($download_package->get_download_location_type() == null) {
                         if (isset($remote_files[$package_filename])) {
                             $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', $remote_files[$package_filename]);
                         } else {
                             if (!empty($remote_download_caches)) {
                                 // Check for files manually
                                 foreach ($remote_download_caches as $remote_dir) {
                                     $remote_file = $remote_dir . $package_filename;
                                     $stream_context = pts_network::stream_context_create();
                                     $file_pointer = fopen($remote_file, 'r', false, $stream_context);
                                     if ($file_pointer !== false) {
                                         $download_package->set_download_location('REMOTE_DOWNLOAD_CACHE', $remote_file);
                                         break;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
 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];
             $minimal_test_time = pts_config::read_user_config('PhoronixTestSuite/Options/General/MinimalTestTime', 3);
             if ($result_value < $minimal_test_time) {
                 // 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 render_page_process($PATH)
 {
     if ($_SESSION['AdminLevel'] != -40) {
         header('Location: /?main');
     }
     $main = null;
     if (isset($_POST['new_phoromatic_path']) && !empty($_POST['new_phoromatic_path'])) {
         $new_dir = dirname($_POST['new_phoromatic_path']);
         if (!is_dir($new_dir)) {
             $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> must be a valid directory.</h2>';
         } else {
             if (!is_writable($new_dir)) {
                 $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> is not a writable location.</h2>';
             } else {
                 if (!is_dir($_POST['new_phoromatic_path'])) {
                     if (mkdir($_POST['new_phoromatic_path']) == false) {
                         $main .= '<h2 style="color: red;">Failed to make directory <em>' . $_POST['new_phoromatic_path'] . '</em>.</h2>';
                     }
                 }
                 if (is_dir($_POST['new_phoromatic_path'])) {
                     $new_phoromatic_dir = pts_strings::add_trailing_slash($_POST['new_phoromatic_path']);
                     $d = glob($new_phoromatic_dir . '*');
                     if (!empty($d)) {
                         $new_phoromatic_dir .= 'phoromatic/';
                         pts_file_io::mkdir($new_phoromatic_dir);
                     }
                     $d = glob($new_phoromatic_dir . '*');
                     if (!empty($d)) {
                         $main .= '<h2 style="color: red;"><em>' . $new_phoromatic_dir . '</em> must be an empty directory.</h2>';
                     } else {
                         if (pts_file_io::copy(phoromatic_server::phoromatic_path(), $new_phoromatic_dir)) {
                             pts_config::user_config_generate(array('PhoromaticStorage' => $new_phoromatic_dir));
                             header('Location: /?admin');
                         } else {
                             $main .= '<h2 style="color: red;"><em>Failed to copy old Phoromatic data to new location.</h2>';
                         }
                     }
                 }
             }
         }
     }
     if (isset($_POST['new_dc_path']) && !empty($_POST['new_dc_path'])) {
         $new_dir = dirname($_POST['new_dc_path']);
         if (!is_dir($new_dir)) {
             $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> must be a valid directory.</h2>';
         } else {
             if (!is_writable($new_dir)) {
                 $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> is not a writable location.</h2>';
             } else {
                 if (!is_dir($_POST['new_dc_path'])) {
                     if (mkdir($_POST['new_dc_path']) == false) {
                         $main .= '<h2 style="color: red;">Failed to make directory <em>' . $_POST['new_dc_path'] . '</em>.</h2>';
                     }
                 }
                 if (is_dir($_POST['new_dc_path'])) {
                     $new_dc_dir = pts_strings::add_trailing_slash($_POST['new_dc_path']);
                     if (pts_file_io::copy(pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH))), $new_dc_dir)) {
                         pts_config::user_config_generate(array('CacheDirectory' => $new_dc_dir));
                         header('Location: /?admin');
                     } else {
                         $main .= '<h2 style="color: red;"><em>Failed to copy old Phoromatic data to new location.</h2>';
                     }
                 }
             }
         }
     }
     if (isset($_POST['new_proxy_address']) && isset($_POST['new_proxy_port'])) {
         if (pts_network::http_get_contents('http://www.phoronix-test-suite.com/PTS', $_POST['new_proxy_address'], $_POST['new_proxy_port']) == 'PTS') {
             pts_config::user_config_generate(array('PhoronixTestSuite/Options/Networking/ProxyAddress' => $_POST['new_proxy_address'], 'PhoronixTestSuite/Options/Networking/ProxyPort' => $_POST['new_proxy_port']));
         } else {
             $main .= '<h2 style="color: red;">Failed to connect via proxy server.</h2>';
         }
     }
     if (isset($_POST['new_http_port']) && isset($_POST['new_ws_port'])) {
         if (empty($_POST['new_http_port']) || !is_numeric($_POST['new_http_port']) && $_POST['new_http_port'] != 'RANDOM') {
             $main .= '<h2 style="color: red;">The HTTP port must be a valid port number or <em>RANDOM</em>.</h2>';
         }
         if (empty($_POST['new_ws_port']) || !is_numeric($_POST['new_ws_port']) && $_POST['new_ws_port'] != 'RANDOM') {
             $main .= '<h2 style="color: red;">The WebSocket port must be a valid port number or <em>RANDOM</em>.</h2>';
         }
         pts_config::user_config_generate(array('PhoronixTestSuite/Options/Server/RemoteAccessPort' => $_POST['new_http_port'], 'PhoronixTestSuite/Options/Server/WebSocketPort' => $_POST['new_ws_port']));
     }
     if (isset($_POST['add_new_users_to_account'])) {
         if (empty($_POST['add_new_users_to_account'])) {
             phoromatic_server::save_setting('add_new_users_to_account', null);
         } else {
             $stmt = phoromatic_server::$db->prepare('SELECT COUNT(AccountID) AS AccountHitCount FROM phoromatic_accounts WHERE AccountID = :account_id');
             $stmt->bindValue(':account_id', $_POST['add_new_users_to_account']);
             $result = $stmt->execute();
             $row = $result->fetchArray();
             if (empty($row['AccountHitCount'])) {
                 $main .= '<h2 style="color: red;"><em>' . $_POST['add_new_users_to_account'] . '</em> is not a valid account ID.</h2>';
             } else {
                 phoromatic_server::save_setting('add_new_users_to_account', $_POST['add_new_users_to_account']);
             }
         }
     }
     if (isset($_POST['account_creation_alt'])) {
         phoromatic_server::save_setting('account_creation_alt', $_POST['account_creation_alt']);
     }
     if (isset($_POST['main_page_message'])) {
         phoromatic_server::save_setting('main_page_message', $_POST['main_page_message']);
     }
     if (isset($_POST['force_result_sharing'])) {
         phoromatic_server::save_setting('force_result_sharing', $_POST['force_result_sharing']);
     }
     if (isset($_POST['show_local_tests_only'])) {
         phoromatic_server::save_setting('show_local_tests_only', $_POST['show_local_tests_only']);
     }
     if (isset($_POST['new_admin_support_email'])) {
         phoromatic_server::save_setting('admin_support_email', $_POST['new_admin_support_email']);
     }
     if (isset($_POST['rebuild_results_db'])) {
         foreach (pts_file_io::glob(phoromatic_server::phoromatic_path() . 'accounts/*/results/*/composite.xml') as $composite_xml) {
             $account_id = basename(dirname(dirname(dirname($composite_xml))));
             $upload_id = basename(dirname($composite_xml));
             $result_file = new pts_result_file($composite_xml);
             // Validate the XML
             $relative_id = 0;
             foreach ($result_file->get_result_objects() as $result_object) {
                 $relative_id++;
                 $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_results_results (AccountID, UploadID, AbstractID, TestProfile, ComparisonHash) VALUES (:account_id, :upload_id, :abstract_id, :test_profile, :comparison_hash)');
                 $stmt->bindValue(':account_id', $account_id);
                 $stmt->bindValue(':upload_id', $upload_id);
                 $stmt->bindValue(':abstract_id', $relative_id);
                 $stmt->bindValue(':test_profile', $result_object->test_profile->get_identifier());
                 $stmt->bindValue(':comparison_hash', $result_object->get_comparison_hash(true, false));
                 $result = $stmt->execute();
             }
             if ($relative_id > 0) {
                 foreach ($result_file->get_systems() as $s) {
                     $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_results_systems (AccountID, UploadID, SystemIdentifier, Hardware, Software) VALUES (:account_id, :upload_id, :system_identifier, :hardware, :software)');
                     $stmt->bindValue(':account_id', $account_id);
                     $stmt->bindValue(':upload_id', $upload_id);
                     $stmt->bindValue(':system_identifier', $s->get_identifier());
                     $stmt->bindValue(':hardware', $s->get_hardware());
                     $stmt->bindValue(':software', $s->get_software());
                     $result = $stmt->execute();
                 }
             }
         }
     }
     $main .= '<h1>Phoromatic Server Configuration</h1>';
     $main .= '<h2>Phoromatic Storage Location</h2>';
     $main .= '<p>The Phoromatic Storage location is where all Phoromatic-specific test results, account data, and other information is archived. This path is controlled via the <em>' . pts_config::get_config_file_location() . '</em> configuration file with the <em>PhoromaticStorage</em> element. Adjusting the directory from the user configuration XML file is the recommended way to adjust the Phoromatic storage path when the Phoromatic Server is not running, while using the below form is an alternative method to attempt to live migrate the storage path.</p>';
     $main .= '<p><strong>Current Storage Path:</strong> ' . phoromatic_server::phoromatic_path() . '</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_phoromatic_path" method="post">';
     $main .= '<p><input type="text" name="new_phoromatic_path" value="' . (isset($_POST['new_phoromatic_path']) ? $_POST['new_phoromatic_path'] : null) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Phoromatic Storage Location" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Download Cache Location</h2>';
     $main .= '<p>The download cache is where the Phoronix Test Suite is able to make an archive of files needed by test profiles. The Phoromatic Server is then able to allow Phoronix Test Suite client systems on the intranet. To add test files to this cache on the Phoromatic Server, run <strong>phoronix-test-suite make-download-cache <em>&lt;the test identifers you wish to download and cache&gt;</em></strong>.</p>';
     $main .= '<p><strong>Current Download Cache Path:</strong> ' . pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH))) . '</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_dc_path" method="post">';
     $main .= '<p><input type="text" name="new_dc_path" value="' . (isset($_POST['new_dc_path']) ? $_POST['new_dc_path'] : null) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Download Cache Location" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Network Proxy</h2>';
     $main .= '<p>If a network proxy is needed for the Phoromatic Server to access the open Internet, please provide the IP address and HTTP port address below.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_proxy" method="post">';
     $main .= '<p><strong>Proxy HTTP Port:</strong> <input type="text" name="new_proxy_port" size="4" value="' . (isset($_POST['new_proxy_port']) ? $_POST['new_proxy_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyPort')) . '" /></p>';
     $main .= '<p><strong>Proxy IP Address:</strong> <input type="text" name="new_proxy_address" value="' . (isset($_POST['new_proxy_address']) ? $_POST['new_proxy_address'] : pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyAddress')) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Network Proxy" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Phoromatic Server Ports</h2>';
     $main .= '<p>The HTTP and WebSocket ports for the Phoromatic Server can be adjusted via this form or the user configuration XML file. The new ports will not go into effect until the Phoromatic Server instance has been restarted.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_ports" method="post">';
     $main .= '<p><strong>HTTP Port:</strong> <input type="text" name="new_http_port" size="4" value="' . (isset($_POST['new_http_port']) ? $_POST['new_http_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort')) . '" /></p>';
     $main .= '<p><strong>WebSocket Port:</strong> <input type="text" name="new_ws_port" size="4" value="' . (isset($_POST['new_ws_port']) ? $_POST['new_ws_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort')) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Web Ports" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Support Email Address</h2>';
     $main .= '<p>This email address will be shown as the sender of emails regarding new account registration and other non-group-related messages. This email address may also be shown as a support email address in case of user problems.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="support_email" method="post">';
     $main .= '<p><strong>E-Mail:</strong> <input type="text" name="new_admin_support_email" value="' . phoromatic_server::read_setting('admin_support_email') . '" /></p>';
     $main .= '<p><input name="submit" value="Update E-Mail Address" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Account Creation</h1>';
     $main .= '<h2>Add To Existing Account</h2><p>Whenever a new account is created via the main log-in page, rather than creating a new group account, you can opt to have the account added as a viewer to an existing group of accounts. To do so, enter the account ID in the field below. The user is added to that account ID with viewer privileges while the main administrator for that account can elevate the privileges from their account\'s Users page. You can find the list of account IDs via the main rootadmin page account listing. Leave this field blank to disable the feature. This option only affects the creation of new accounts.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="add_accounts_to_one" method="post">';
     $main .= '<p><strong>Main Account ID:</strong> <input type="text" name="add_new_users_to_account" size="6" value="' . phoromatic_server::read_setting('add_new_users_to_account') . '" /></p>';
     $main .= '<p><input name="submit" value="Update Account Handling" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Account Creation</h1>';
     $main .= '<p>By default, new accounts can be created at-will from the main page of the Phoromatic Server web interface. <strong>To disable the ability to create new accounts from the main welcome page</strong>, enter a message in the field below -- e.g. account creation disabled, contact XYZ department via email to request a new account, or other string to present to the user in place of the account creation box. Leave this box empty to allow new accounts to be created. HTML input is allowed.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="account_creation_text" method="post">';
     $main .= '<p><strong>Account Creation String:</strong> <textarea name="account_creation_alt" cols="50" rows="4">' . phoromatic_server::read_setting('account_creation_alt') . '</textarea></p>';
     $main .= '<p><input name="submit" value="Update Account Handling" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Main Page Message</h1>';
     $main .= '<p>If you wish to present users with a custom message once logging into their Phoromatic account, set the HTML-allowed string below and it will be shown on the main page once logging in.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="main_page_message" method="post">';
     $main .= '<p><strong>Main Page Message String:</strong> <textarea name="main_page_message" cols="50" rows="4">' . phoromatic_server::read_setting('main_page_message') . '</textarea></p>';
     $main .= '<p><input name="submit" value="Update Main Page Message" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Force Results To Be Shared</h1>';
     $main .= '<p>If you wish to force that all accounts/groups on this Phoromatic Server instance are shared/viewable amongst other groups on this server, set this value to True. Otherwise the result sharing is limited to each group\'s selected option on the account settings page.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="force_result_share" method="post">';
     $main .= '<p><strong>Force Result Sharing:</strong> <select name="force_result_sharing"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('force_result_sharing') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Update" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Only Advertise Tests With Files Locally Cached</h1>';
     $main .= '<p>Enabling this option will only advertise test profiles on the Phoromatic Server web interface if the needed files for that test are present within the Phoromatic Server\'s PTS download cache. This feature is particularly useful for environments where the client test system lacks direct Internet access.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="show_local_tests_only" method="post">';
     $main .= '<p><strong>Only Advertise Cached Tests:</strong> <select name="show_local_tests_only"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('show_local_tests_only') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Update" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Rebuild Results/Systems SQLite Tables</h1>';
     $main .= '<p>If you somehow damaged some of your SQLite tables, this option will attempt to rebuild the phoromatic_results_results and phoromatic_results_systems tables.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="rebuild_results_db" method="post">';
     $main .= '<p><strong>Force Results Table Rebuild:</strong> <select name="rebuild_results_db"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('rebuild_results_db') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Rebuild Results Table" type="submit" /></p>';
     $main .= '</form>';
     echo phoromatic_webui_header_logged_in();
     echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in());
     echo phoromatic_webui_footer();
 }
define('REMOTE_ACCESS', true);
// XXX TODO: Is this still used with new Phoromatic?
ini_set('memory_limit', '4G');
define('PTS_MODE', 'WEB_CLIENT');
define('PTS_AUTO_LOAD_OBJECTS', true);
//error_reporting(E_ALL);
include '../../pts-core.php';
pts_core::init();
if (isset($_GET['repo'])) {
    readfile(phoromatic_server::find_download_cache());
    pts_logger::add_to_log($_SERVER['REMOTE_ADDR'] . ' requested a copy of the download cache JSON');
} else {
    if (isset($_GET['download'])) {
        $requested_file = str_replace(array('..', '/'), null, $_GET['download']);
        pts_logger::add_to_log($_SERVER['REMOTE_ADDR'] . ' is attempting to download ' . $requested_file . ' from the download cache');
        if (($dc = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)))) && is_file($dc . $requested_file)) {
            $file_path = $dc . $requested_file;
        } else {
            if (is_file(PTS_DOWNLOAD_CACHE_PATH . $requested_file)) {
                $file_path = PTS_DOWNLOAD_CACHE_PATH . $requested_file;
            } else {
                if (is_file(PTS_SHARE_PATH . 'download-cache/' . $requested_file)) {
                    $file_path = PTS_SHARE_PATH . 'download-cache/' . $requested_file;
                } else {
                    if (is_file('/var/cache/phoronix-test-suite/download-cache/' . $requested_file)) {
                        $file_path = '/var/cache/phoronix-test-suite/download-cache/' . $requested_file;
                    } else {
                        pts_logger::add_to_log($requested_file . ' could not be found in the download cache');
                        exit;
                    }
                }
 public static function download_cache_locations()
 {
     static $cache_directories = null;
     if ($cache_directories == null) {
         $cache_directories = array();
         // Phoronix Test Suite System Cache Directories
         $additional_dir_checks = array('/var/cache/phoronix-test-suite/download-cache/', '/var/cache/phoronix-test-suite/');
         foreach ($additional_dir_checks as $dir_check) {
             if (is_dir($dir_check)) {
                 $cache_directories[] = $dir_check;
                 break;
             }
         }
         // User Defined Directory Checking
         $dir_string = ($dir = pts_client::read_env('PTS_DOWNLOAD_CACHE')) != false ? $dir : null;
         foreach (array_merge(self::$extra_caches, pts_strings::colon_explode($dir_string)) as $dir_check) {
             if ($dir_check == null) {
                 continue;
             }
             $dir_check = pts_strings::parse_for_home_directory($dir_check);
             if (pts_strings::is_url($dir_check) == false && !is_dir($dir_check)) {
                 continue;
             }
             $cache_directories[] = pts_strings::add_trailing_slash($dir_check);
         }
         if (pts_config::read_bool_config('PhoronixTestSuite/Options/Installation/SearchMediaForCache', 'TRUE')) {
             $download_cache_dirs = array_merge(pts_file_io::glob('/media/*/download-cache/'), pts_file_io::glob('/media/*/*/download-cache/'), pts_file_io::glob('/run/media/*/*/download-cache/'), pts_file_io::glob('/Volumes/*/download-cache/'));
             foreach ($download_cache_dirs as $dir) {
                 $cache_directories[] = $dir;
             }
         }
     }
     return $cache_directories;
 }
 public static function run($r)
 {
     // Force refresh of OB repository to ensure the latest profiles
     pts_openbenchmarking::refresh_repository_lists(null, true);
     // Determine cache location
     $dc_write_directory = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
     echo PHP_EOL . 'Download Cache Directory: ' . $dc_write_directory . PHP_EOL;
     if ($dc_write_directory == null || !is_writable($dc_write_directory)) {
         echo 'No writable download cache directory was found. A download cache cannot be created.' . PHP_EOL . PHP_EOL;
         return false;
     }
     if (!empty($r)) {
         $test_profiles = pts_types::identifiers_to_test_profile_objects($r, true, true);
         if (count($test_profiles) > 0) {
             echo PHP_EOL . 'Downloading Test Files For: ' . implode(' ', $test_profiles);
             pts_test_installer::only_download_test_files($test_profiles, $dc_write_directory);
         }
     }
     $json_download_cache = array('phoronix-test-suite' => array('main' => array('generated' => time()), 'download-cache' => array()));
     foreach (pts_tests::partially_installed_tests() as $test) {
         $test_profile = new pts_test_profile($test);
         echo PHP_EOL . 'Checking Downloads For: ' . $test . PHP_EOL;
         foreach (pts_test_install_request::read_download_object_list($test_profile, false) as $file) {
             $cached_valid = false;
             if (is_file($dc_write_directory . $file->get_filename()) && $file->check_file_hash($dc_write_directory . $file->get_filename())) {
                 echo '   Previously Cached: ' . $file->get_filename() . PHP_EOL;
                 $cached_valid = true;
             } else {
                 if (is_dir($test_profile->get_install_dir())) {
                     if (is_file($test_profile->get_install_dir() . $file->get_filename()) && $file->check_file_hash($test_profile->get_install_dir() . $file->get_filename())) {
                         echo '   Caching: ' . $file->get_filename() . PHP_EOL;
                         if (copy($test_profile->get_install_dir() . $file->get_filename(), $dc_write_directory . $file->get_filename())) {
                             $cached_valid = true;
                         }
                     }
                 }
             }
             if ($cached_valid) {
                 if (!isset($json_download_cache['phoronix-test-suite']['download-cache'][$file->get_filename()])) {
                     $json_download_cache['phoronix-test-suite']['download-cache'][$file->get_filename()] = array('file_name' => $file->get_filename(), 'file_size' => $file->get_filesize(), 'associated_tests' => array($test_profile->get_identifier()), 'md5' => $file->get_md5(), 'sha256' => $file->get_sha256());
                 } else {
                     if ($file->get_md5() == $json_download_cache['phoronix-test-suite']['download-cache'][$file->get_filename()]['md5'] && $file->get_sha256() == $json_download_cache['phoronix-test-suite']['download-cache'][$file->get_filename()]['sha256']) {
                         array_push($json_download_cache['phoronix-test-suite']['download-cache'][$file->get_filename()]['associated_tests'], $test_profile->get_identifier());
                     }
                 }
             }
         }
     }
     // Find files in download-cache/ that weren't part of an installed test (but could have just been tossed in there) to cache
     foreach (glob($dc_write_directory . '/*') as $cached_file) {
         $file_name = basename($cached_file);
         if (!isset($json_download_cache['phoronix-test-suite']['download-cache'][$file_name]) && $file_name != 'pts-download-cache.json') {
             $json_download_cache['phoronix-test-suite']['download-cache'][$file_name] = array('file_name' => $file_name, 'file_size' => filesize($cached_file), 'associated_tests' => array(), 'md5' => md5_file($cached_file), 'sha256' => hash_file('sha256', $cached_file));
         }
     }
     $cached_tests = array();
     foreach (pts_openbenchmarking::available_tests(true, true) as $test) {
         if (pts_test_install_request::test_files_in_cache($test, true, true) == false) {
             continue;
         }
         array_push($cached_tests, $test);
     }
     $json_download_cache['phoronix-test-suite']['cached-tests'] = $cached_tests;
     file_put_contents($dc_write_directory . 'pts-download-cache.json', json_encode($json_download_cache, defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0));
     echo PHP_EOL;
 }
 public static function refresh_repository_lists($repos = null, $force_refresh = false)
 {
     if ($repos == null) {
         if ($force_refresh == false) {
             if (!defined('HAS_REFRESHED_OBO_LIST')) {
                 pts_define('HAS_REFRESHED_OBO_LIST', true);
             } else {
                 return true;
             }
         }
         $repos = self::linked_repositories();
     }
     foreach ($repos as $repo_name) {
         pts_file_io::mkdir(PTS_OPENBENCHMARKING_SCRATCH_PATH . $repo_name);
         if ($repo_name == 'local') {
             // Local is a special case, not actually a real repository
             continue;
         }
         if (!is_dir(PTS_OPENBENCHMARKING_SCRATCH_PATH . $repo_name)) {
             mkdir(PTS_OPENBENCHMARKING_SCRATCH_PATH . $repo_name, 0777, true);
         }
         $index_file = PTS_OPENBENCHMARKING_SCRATCH_PATH . $repo_name . '.index';
         $server_index = null;
         if (is_file($index_file)) {
             $repo_index = json_decode(file_get_contents($index_file), true);
             $generated_time = $repo_index['main']['generated'];
             // Refreshing the indexes once every few days should be suffice
             // Refresh approximately every three days by default
             $index_cache_ttl = 3;
             if (PTS_IS_CLIENT && ($config_ttl = pts_config::read_user_config('PhoronixTestSuite/Options/OpenBenchmarking/IndexCacheTTL'))) {
                 if ($config_ttl === 0) {
                     // if the value is 0, only rely upon manual refreshes
                     continue;
                 } else {
                     if (is_numeric($config_ttl) && $config_ttl >= 1) {
                         $index_cache_ttl = $config_ttl;
                     }
                 }
             }
             if ($generated_time > time() - 86400 * $index_cache_ttl && $force_refresh == false && (!defined('FIRST_RUN_ON_PTS_UPGRADE') || FIRST_RUN_ON_PTS_UPGRADE == false)) {
                 // The index is new enough
                 continue;
             }
             if (pts_network::internet_support_available()) {
                 $server_index = pts_openbenchmarking::make_openbenchmarking_request('repo_index', array('repo' => $repo_name));
                 self::$openbenchmarking_index_refreshed = true;
             }
             if (!$server_index && ($phoromatic_cache_index = self::phoromatic_server_ob_cache_request('index', $repo_name))) {
                 // Ensure the Phoromatic cache has a newer version of the index than what's currently on the system
                 $repo_index = json_decode($phoromatic_cache_index, true);
                 if (isset($repo_index['main']['generated'])) {
                     $cache_generated_time = $repo_index['main']['generated'];
                     if ($cache_generated_time > $generated_time) {
                         $server_index = $phoromatic_cache_index;
                     }
                     self::$openbenchmarking_index_refreshed = true;
                 }
             }
         } else {
             if (pts_network::internet_support_available()) {
                 $server_index = pts_openbenchmarking::make_openbenchmarking_request('repo_index', array('repo' => $repo_name));
                 self::$openbenchmarking_index_refreshed = true;
             }
         }
         if (!$server_index && ($phoromatic_cache_index = self::phoromatic_server_ob_cache_request('index', $repo_name))) {
             $server_index = $phoromatic_cache_index;
         }
         if ($server_index != null && json_decode($server_index) != false) {
             file_put_contents($index_file, $server_index);
         } else {
             if (PTS_IS_CLIENT && is_file('/var/cache/phoronix-test-suite/openbenchmarking.org/' . $repo_name . '.index')) {
                 copy('/var/cache/phoronix-test-suite/openbenchmarking.org/' . $repo_name . '.index', $index_file);
             }
         }
         if (!is_file($index_file)) {
             static $reported_read_failure_notice;
             if (!isset($reported_read_failure_notice[$repo_name]) && PTS_IS_CLIENT) {
                 trigger_error('Failed To Fetch OpenBenchmarking.org Repository Data: ' . $repo_name, E_USER_WARNING);
                 $reported_read_failure_notice[$repo_name] = true;
             }
         }
     }
 }
 public static function read_user_config($xml_pointer, $predefined_value = false, &$nye_xml = null)
 {
     // Generic call for reading a config file
     if ($nye_xml instanceof nye_XmlReader) {
         $read_value = $nye_xml->getXmlValue($xml_pointer);
     } else {
         if (self::$xml_user_config == null) {
             self::$xml_user_config = new pts_config_nye_XmlReader();
         }
         $read_value = self::$xml_user_config->getXmlValue($xml_pointer);
     }
     if (PTS_IS_DAEMONIZED_SERVER_PROCESS) {
         $read_value = str_replace('~/.phoronix-test-suite/', PTS_USER_PATH, $read_value);
     }
     return !empty($read_value) ? $read_value : $predefined_value;
 }
 public static function upload_test_result(&$object, $return_json_data = false)
 {
     if ($object instanceof pts_test_run_manager) {
         $result_file = new pts_result_file($object->get_file_name());
         $local_file_name = $object->get_file_name();
         $results_identifier = $object->get_results_identifier();
     } else {
         if ($object instanceof pts_result_file) {
             $result_file =& $object;
             $local_file_name = $result_file->get_identifier();
             $results_identifier = null;
         }
     }
     // Ensure the results can be shared
     if (self::result_upload_supported($result_file) == false) {
         return false;
     }
     if (pts_network::internet_support_available() == false) {
         echo PHP_EOL . 'No network support available.' . PHP_EOL;
         return false;
     }
     $composite_xml = $result_file->getRawXml();
     $system_log_dir = PTS_SAVE_RESULTS_PATH . $result_file->get_identifier() . '/system-logs/';
     $upload_system_logs = false;
     if (is_dir($system_log_dir)) {
         if (pts_config::read_bool_config('PhoronixTestSuite/Options/OpenBenchmarking/AlwaysUploadSystemLogs', 'FALSE')) {
             $upload_system_logs = true;
         } else {
             if (isset(self::$client_settings['UploadSystemLogsByDefault'])) {
                 $upload_system_logs = self::$client_settings['UploadSystemLogsByDefault'];
             } else {
                 if (is_dir($system_log_dir)) {
                     $upload_system_logs = pts_user_io::prompt_bool_input('Would you like to attach the system logs (lspci, dmesg, lsusb, etc) to the test result', true, 'UPLOAD_SYSTEM_LOGS');
                 }
             }
         }
     }
     $system_logs = null;
     $system_logs_hash = null;
     if ($upload_system_logs) {
         $is_valid_log = true;
         $finfo = function_exists('finfo_open') ? finfo_open(FILEINFO_MIME_TYPE) : false;
         foreach (pts_file_io::glob($system_log_dir . '*') as $log_dir) {
             if ($is_valid_log == false || !is_dir($log_dir)) {
                 $is_valid_log = false;
                 break;
             }
             foreach (pts_file_io::glob($log_dir . '/*') as $log_file) {
                 if (!is_file($log_file)) {
                     $is_valid_log = false;
                     break;
                 }
                 if ($finfo && substr(finfo_file($finfo, $log_file), 0, 5) != 'text/') {
                     $is_valid_log = false;
                     break;
                 }
             }
         }
         if ($is_valid_log) {
             $system_logs_zip = pts_client::create_temporary_file('.zip');
             pts_compression::zip_archive_create($system_logs_zip, $system_log_dir);
             if (filesize($system_logs_zip) < 2097152) {
                 // If it's over 2MB, probably too big
                 $system_logs = base64_encode(file_get_contents($system_logs_zip));
                 $system_logs_hash = sha1($system_logs);
             } else {
                 trigger_error('The systems log attachment is too large to upload to OpenBenchmarking.org.', E_USER_WARNING);
             }
             unlink($system_logs_zip);
         }
     }
     $composite_xml_hash = sha1($composite_xml);
     $composite_xml_type = 'composite_xml';
     // Compress the result file XML if it's big
     if (isset($composite_xml[50000]) && function_exists('gzdeflate')) {
         $composite_xml_gz = gzdeflate($composite_xml);
         if ($composite_xml_gz != false) {
             $composite_xml = $composite_xml_gz;
             $composite_xml_type = 'composite_xml_gz';
         }
     }
     $to_post = array($composite_xml_type => base64_encode($composite_xml), 'composite_xml_hash' => $composite_xml_hash, 'local_file_name' => $local_file_name, 'this_results_identifier' => $results_identifier, 'system_logs_zip' => $system_logs, 'system_logs_hash' => $system_logs_hash);
     if (isset(self::$client_settings['ResultUploadsDefaultDisplayStatus']) && is_numeric(self::$client_settings['ResultUploadsDefaultDisplayStatus'])) {
         $to_post['display_status'] = self::$client_settings['ResultUploadsDefaultDisplayStatus'];
     }
     $json_response = pts_openbenchmarking::make_openbenchmarking_request('upload_test_result', $to_post);
     $json_response = json_decode($json_response, true);
     if (!is_array($json_response)) {
         trigger_error('Unhandled Exception', E_USER_ERROR);
         return false;
     }
     if (isset($json_response['openbenchmarking']['upload']['error'])) {
         trigger_error($json_response['openbenchmarking']['upload']['error'], E_USER_ERROR);
     }
     if (isset($json_response['openbenchmarking']['upload']['url'])) {
         echo PHP_EOL . 'Results Uploaded To: ' . $json_response['openbenchmarking']['upload']['url'] . PHP_EOL;
         pts_module_manager::module_process('__event_openbenchmarking_upload', $json_response);
     }
     //$json['openbenchmarking']['upload']['id']
     if (isset(self::$client_settings['RemoveLocalResultsOnUpload']) && self::$client_settings['RemoveLocalResultsOnUpload'] && $local_file_name != null) {
         pts_client::remove_saved_result_file($local_file_name);
     }
     if ($return_json_data) {
         return isset($json_response['openbenchmarking']['upload']) ? $json_response['openbenchmarking']['upload'] : false;
     }
     return isset($json_response['openbenchmarking']['upload']['url']) ? $json_response['openbenchmarking']['upload']['url'] : false;
 }
    public static function render_page_process($PATH)
    {
        $main = null;
        echo phoromatic_webui_header_logged_in();
        if (!empty($PATH[0]) && is_numeric($PATH[0])) {
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules WHERE AccountID = :account_id AND ScheduleID = :schedule_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':schedule_id', $PATH[0]);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            if (empty($row)) {
                $main = '<h1>Test Schedules</h1>';
                $main .= '<h3>No Resource Found</h3>';
            } else {
                if (!PHOROMATIC_USER_IS_VIEWER) {
                    if (isset($_POST['add_to_schedule_select_test'])) {
                        $name = $_POST['add_to_schedule_select_test'];
                        $args = array();
                        $args_name = array();
                        foreach ($_POST as $i => $v) {
                            if (substr($i, 0, 12) == 'test_option_' && substr($i, -9) != '_selected') {
                                array_push($args, $v);
                                array_push($args_name, $_POST[$i . '_selected']);
                            }
                        }
                        $args_name = implode(' - ', $args_name);
                        $args = implode(' ', $args);
                        if (!empty($name)) {
                            $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_schedules_tests (AccountID, ScheduleID, TestProfile, TestArguments, TestDescription) VALUES (:account_id, :schedule_id, :test_profile, :test_arguments, :test_description)');
                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt->bindValue(':schedule_id', $PATH[0]);
                            $stmt->bindValue(':test_profile', $name);
                            $stmt->bindValue(':test_arguments', $args);
                            $stmt->bindValue(':test_description', $args_name);
                            $result = $stmt->execute();
                            phoromatic_add_activity_stream_event('tests_for_schedule', $PATH[0], 'added');
                        }
                    } else {
                        if (isset($PATH[1]) && $PATH[1] == 'remove' && !empty($PATH[2])) {
                            // REMOVE TEST
                            $to_remove = explode(PHP_EOL, base64_decode($PATH[2]));
                            $stmt = phoromatic_server::$db->prepare('DELETE FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = :schedule_id AND TestProfile = :test AND TestArguments = :test_args');
                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt->bindValue(':schedule_id', $PATH[0]);
                            $stmt->bindValue(':test', $to_remove[0]);
                            $stmt->bindValue(':test_args', $to_remove[1]);
                            $result = $stmt->execute();
                            phoromatic_add_activity_stream_event('tests_for_schedule', $to_remove[0] . ' - ' . $to_remove[1], 'removed');
                        } else {
                            if (isset($PATH[1]) && $PATH[1] == 'delete-trigger' && !empty($PATH[2])) {
                                // REMOVE TRIGGER
                                $trigger = base64_decode($PATH[2]);
                                $stmt = phoromatic_server::$db->prepare('DELETE FROM phoromatic_schedules_triggers WHERE AccountID = :account_id AND Trigger = :trigger AND ScheduleID = :schedule_id');
                                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                                $stmt->bindValue(':schedule_id', $PATH[0]);
                                $stmt->bindValue(':trigger', $trigger);
                                $result = $stmt->execute();
                                if ($result) {
                                    $main .= '<h2 style="color: red;">Trigger Removed: ' . $trigger . '</h2>';
                                }
                            } else {
                                if (isset($PATH[1]) && in_array($PATH[1], array('activate', 'deactivate'))) {
                                    switch ($PATH[1]) {
                                        case 'deactivate':
                                            $new_state = 0;
                                            break;
                                        case 'activate':
                                        default:
                                            $new_state = 1;
                                            break;
                                    }
                                    // REMOVE TEST
                                    $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_schedules SET State = :new_state WHERE AccountID = :account_id AND ScheduleID = :schedule_id');
                                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                                    $stmt->bindValue(':schedule_id', $PATH[0]);
                                    $stmt->bindValue(':new_state', $new_state);
                                    $result = $stmt->execute();
                                    $row['State'] = $new_state;
                                    phoromatic_add_activity_stream_event('schedule', $PATH[0], $PATH[1]);
                                } else {
                                    if (isset($_POST['do_manual_test_run'])) {
                                        $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_schedules_triggers (AccountID, ScheduleID, Trigger, TriggeredOn) VALUES (:account_id, :schedule_id, :trigger, :triggered_on)');
                                        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                                        $stmt->bindValue(':schedule_id', $PATH[0]);
                                        $stmt->bindValue(':trigger', $_SESSION['UserName'] . ' - Manual Test Run - ' . date('H:i j M Y'));
                                        $stmt->bindValue(':triggered_on', phoromatic_server::current_time());
                                        $stmt->execute();
                                        $main .= '<h2 style="color: red;">Manual Test Run Triggered</h2>';
                                    } else {
                                        if (isset($_POST['skip_current_ticket'])) {
                                            $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_schedules_trigger_skips (AccountID, ScheduleID, Trigger) VALUES (:account_id, :schedule_id, :trigger)');
                                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                                            $stmt->bindValue(':schedule_id', $PATH[0]);
                                            $stmt->bindValue(':trigger', date('Y-m-d'));
                                            $stmt->execute();
                                            $main .= '<h2 style="color: red;">Current Trigger To Be Ignored</h2>';
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                $main .= '<h1>' . $row['Title'] . '</h1>';
                $main .= '<h3>' . $row['Description'] . '</h3>';
                $main .= '<p>This schedule was last modified on <strong>' . date('j F Y \\a\\t H:i', strtotime($row['LastModifiedOn'])) . '</strong> by <strong>' . $row['LastModifiedBy'] . '</strong>.';
                if (!PHOROMATIC_USER_IS_VIEWER) {
                    $main .= '<p><a href="?sched/' . $PATH[0] . '">Edit Schedule</a> | ';
                    if ($row['State'] == 1) {
                        $main .= '<a href="?schedules/' . $PATH[0] . '/deactivate">Deactivate Schedule</a>';
                    } else {
                        $main .= '<a href="?schedules/' . $PATH[0] . '/activate">Activate Schedule</a>';
                    }
                    $main .= '</p>';
                }
                $main .= '<hr />';
                $main .= '<h2>Schedule</h2>';
                if (!empty($row['ActiveOn'])) {
                    $active_days = explode(',', $row['ActiveOn']);
                    $week = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');
                    foreach ($active_days as $i => &$day) {
                        if (!isset($week[$day])) {
                            unset($active_days[$i]);
                        } else {
                            $day = $week[$day];
                        }
                    }
                    switch (count($active_days)) {
                        case 2:
                            $day_show = implode(' and ', $active_days);
                            break;
                        default:
                            $day_show = implode(', ', $active_days);
                            break;
                    }
                    $main .= '<p>This test is scheduled to run every <strong>' . $day_show . '</strong> at <strong>' . str_replace('.', ':', $row['RunAt']) . '</strong>.</p>';
                } else {
                    $main .= '<p>This test schedule is not currently set to run a pre-defined time-based schedule.</p>';
                }
                if (!PHOROMATIC_USER_IS_VIEWER) {
                    $trigger_url = 'http://' . phoromatic_web_socket_server_ip() . '/event.php?type=trigger&user='******'UserName'] . '&public_key=' . $row['PublicKey'] . '&trigger=XXX';
                    $main .= '<p>This test schedule can be manually triggered to run at any time by calling <strong>' . $trigger_url . '</strong> where <em>XXX</em> is the trigger value to be used (if relevant, such as a time-stamp, Git/SVN commit number or hash, etc). There\'s also the option of sub-targeting system(s) part of this schedule. One option is appending <em>&sub_target_this_ip</em> if this URL is being called from one of the client test systems to only sub-target the triggered testing on that client, among other options.</p>';
                    $main .= '<p>If you wish to run this test schedule now, click the following button and the schedule will be run on all intended systems at their next earliest possible convenience.</p>';
                    $main .= '<p><form action="?schedules/' . $PATH[0] . '" name="manual_run" method="post">';
                    $main .= '<input type="hidden" name="do_manual_test_run" value="1" /><input type="submit" value="Run Test Schedule Now" onclick="return confirm(\'Run this test schedule now?\');" />';
                    $main .= '</form></p>';
                    $main .= '<p><form action="?schedules/' . $PATH[0] . '" name="skip_run" method="post">';
                    $main .= '<input type="hidden" name="skip_current_ticket" value="1" /><input type="submit" value="Skip Current Test Ticket" onclick="return confirm(\'Skip any currently active test ticket on all systems?\');" />';
                    $main .= '</form></p>';
                }
                $main .= '<hr />';
                $contexts = array('SetContextPreInstall' => 'Pre-Install', 'SetContextPostInstall' => 'Post-Install', 'SetContextPreRun' => 'Pre-Test-Run', 'SetContextPostRun' => 'Post-Test-Run');
                $scripts = 0;
                foreach ($contexts as $context => $v) {
                    if (isset($row[$context]) && !empty($row[$context]) && is_file(phoromatic_server::phoromatic_account_path($_SESSION['AccountID']) . 'context_' . $row[$context])) {
                        $scripts++;
                        $main .= '<h2>' . $v . ' Context Script</h2>';
                        $main .= '<blockquote>' . str_replace(PHP_EOL, '<br />', htmlentities(file_get_contents(phoromatic_server::phoromatic_account_path($_SESSION['AccountID']) . 'context_' . $row[$context]))) . '</blockquote>';
                    }
                }
                if ($scripts > 0) {
                    $main .= '<hr />';
                }
                $main .= '<h2>Tests To Run</h2>';
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY TestProfile ASC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':schedule_id', $PATH[0]);
                $result = $stmt->execute();
                $test_count = 0;
                $main .= '<p>';
                while ($row = $result->fetchArray()) {
                    $test_count++;
                    $main .= $row['TestProfile'] . ($row['TestDescription'] != null ? ' - <em>' . $row['TestDescription'] . '</em>' : '') . (!PHOROMATIC_USER_IS_VIEWER ? ' <a href="?schedules/' . $PATH[0] . '/remove/' . base64_encode(implode(PHP_EOL, array($row['TestProfile'], $row['TestArguments']))) . '">Remove Test</a>' : null) . '<br />';
                    /*
                    if(!PHOROMATIC_USER_IS_VIEWER && isset($_REQUEST['make_version_lock_tests']))
                    {
                    	if(strpos($row['TestProfile'], '.') == false)
                    	{
                    		$test_profile = new pts_test_profile($row['TestProfile']);
                    		$full_identifier = $test_profile->get_identifier(true);
                    
                    		$stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_schedules_tests SET TestProfile = :version_locked_tp WHERE AccountID = :account_id AND ScheduleID = :schedule_id AND TestProfile = :test');
                    		$stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    		$stmt->bindValue(':schedule_id', $PATH[0]);
                    		$stmt->bindValue(':test', $row['TestProfile']);
                    		$stmt->bindValue(':version_locked_tp', $full_identifier);
                    		$result2 = $stmt->execute();
                    	}
                    }
                    */
                }
                $main .= '</p>';
                if ($test_count == 0) {
                    $main .= '<h3 style="text-transform: uppercase;">No tests have been added yet for this test schedule.</h3>';
                }
                if (!PHOROMATIC_USER_IS_VIEWER) {
                    $main .= '<hr /><h2>Add A Test</h2>';
                    $main .= '<form action="?schedules/' . $PATH[0] . '" name="add_test" id="add_test" method="post">';
                    $main .= '<select name="add_to_schedule_select_test" id="add_to_schedule_select_test" onchange="phoromatic_schedule_test_details(\'\');">';
                    $dc = pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
                    $dc_exists = is_file($dc . 'pts-download-cache.json');
                    foreach (pts_openbenchmarking::available_tests(false, true) as $test) {
                        $cache_checked = false;
                        if ($dc_exists) {
                            $cache_json = file_get_contents($dc . 'pts-download-cache.json');
                            $cache_json = json_decode($cache_json, true);
                            if ($cache_json && isset($cache_json['phoronix-test-suite']['cached-tests'])) {
                                $cache_checked = true;
                                if (!in_array($test, $cache_json['phoronix-test-suite']['cached-tests'])) {
                                    continue;
                                }
                            }
                        }
                        if (!$cache_checked && phoromatic_server::read_setting('show_local_tests_only') && pts_test_install_request::test_files_in_cache($test, true, true) == false) {
                            continue;
                        }
                        $main .= '<option value="' . $test . '">' . $test . '</option>';
                    }
                    $main .= '</select>';
                    $main .= '<p><div id="test_details"></div></p>';
                    $main .= '</form>';
                }
                $systems_in_schedule = phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $PATH[0]);
                if (!empty($systems_in_schedule)) {
                    $main .= '<hr /><h2>Systems In Schedule</h2>';
                    if (!PHOROMATIC_USER_IS_VIEWER) {
                        $main .= '<p>To run this schedule on more systems, <a href="?sched/' . $PATH[0] . '">edit the schedule</a>.</p>';
                    }
                    $main .= '<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;"><ul><li><h1>Systems</h1></li>';
                    foreach ($systems_in_schedule as $system_id) {
                        $row = phoromatic_server::get_system_details($_SESSION['AccountID'], $system_id);
                        $main .= '<a href="?systems/' . $row['SystemID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . $row['LocalIP'] . '</td><td><strong>' . $row['CurrentTask'] . '</strong></td><td><strong>Last Communication:</strong> ' . date('j F Y H:i', strtotime($row['LastCommunication'])) . '</td></tr></table></li></a>';
                    }
                    $main .= '</ul></div><hr />';
                }
                $stmt = phoromatic_server::$db->prepare('SELECT Trigger, TriggeredOn FROM phoromatic_schedules_triggers WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY TriggeredOn DESC LIMIT 10');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':schedule_id', $PATH[0]);
                $test_result_result = $stmt->execute();
                $test_result_row = $test_result_result->fetchArray();
                if ($test_result_row) {
                    $main .= '<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;">';
                    $main .= '<ul><li><h1>Recent Triggers For This Schedule</h1></li>';
                    do {
                        $main .= '<a onclick=""><li>' . $test_result_row['Trigger'] . '<br /><table><tr><td>' . phoromatic_user_friendly_timedate($test_result_row['TriggeredOn']) . '</td><td><a href="?schedules/' . $PATH[0] . '/delete-trigger/' . base64_encode($test_result_row['Trigger']) . '">Remove Trigger</a></td></tr></table></li></a>';
                    } while ($test_result_row = $test_result_result->fetchArray());
                    $main .= '</ul>';
                    $main .= '</div>';
                }
                $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, ScheduleID, PPRID, UploadTime FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':schedule_id', $PATH[0]);
                $test_result_result = $stmt->execute();
                $test_result_row = $test_result_result->fetchArray();
                if ($test_result_row) {
                    $main .= '<div class="pts_phoromatic_info_box_area" style="margin: 0 10%;">';
                    $main .= '<ul><li><h1>Recent Test Results For This Schedule</h1></li>';
                    $results = 0;
                    do {
                        $oldest_upload_time = $test_result_row['UploadTime'];
                        if ($results > 100) {
                            continue;
                        }
                        $main .= '<a href="?result/' . $test_result_row['PPRID'] . '"><li>' . $test_result_row['Title'] . '<br /><table><tr><td>' . phoromatic_system_id_to_name($test_result_row['SystemID']) . '</td><td>' . phoromatic_user_friendly_timedate($test_result_row['UploadTime']) . '</td></tr></table></li></a>';
                        $results++;
                    } while ($test_result_row = $test_result_result->fetchArray());
                    $main .= '</ul>';
                    $main .= '</div>';
                }
                $num_results = phoromatic_results_for_schedule($PATH[0]);
                if ($num_results > 1) {
                    $main .= '<p>Jump to the latest results from the past: ';
                    $main .= '<select name="view_results_from_past" id="view_results_from_past" onchange="phoromatic_jump_to_results_from(\'' . $PATH[0] . '\', \'view_results_from_past\');">';
                    $oldest_upload_time = strtotime($oldest_upload_time);
                    $opts = array('Week' => 7, 'Three Weeks' => 21, 'Month' => 30, 'Quarter' => 90, 'Six Months' => 180, 'Year' => 365);
                    foreach ($opts as $str_name => $time_offset) {
                        if ($oldest_upload_time > time() - 86400 * $time_offset) {
                            break;
                        }
                        $main .= '<option value="' . $time_offset . '">' . $str_name . '</option>';
                    }
                    $main .= '<option value="all">All Results</option>';
                    $main .= '</select>';
                    $main .= '</p><hr />';
                }
                $main .= '<p><strong>' . $num_results . ' Test Results Available For This Schedule.</strong></p>';
            }
            echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in());
            echo phoromatic_webui_footer();
            return;
        }
        $main = '<h1>Test Schedules</h1>
			<p>Test schedules are used for tests that are intended to be run on a recurring basis -- either daily or other defined time period -- or whenever a trigger/event occurs, like a new Git commit to a software repository being tracked. Test schedules can be run on any given system(s)/group(s) and can be later edited.</p>';
        if (!PHOROMATIC_USER_IS_VIEWER) {
            $main .= '
				<hr />
				<h2>Create A Schedule</h2>
				<p><a href="?sched">Create a schedule</a> followed by adding tests/suites to run for that schedule on the selected systems.</p>';
        }
        $main .= '<hr /><h2>Current Schedules</h2>';
        $main .= '<div class="pts_phoromatic_info_box_area">
					<ul>
						<li><h1>Active Test Schedules</h1></li>';
        $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, Description, RunTargetSystems, RunTargetGroups, RunAt, ActiveOn FROM phoromatic_schedules WHERE AccountID = :account_id AND State >= 1 ORDER BY Title ASC');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $result = $stmt->execute();
        $row = $result->fetchArray();
        if ($row == false) {
            $main .= '<li class="light" style="text-align: center;">No Schedules Found</li>';
        } else {
            do {
                $stmt_tests = phoromatic_server::$db->prepare('SELECT COUNT(*) AS TestCount FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY TestProfile ASC');
                $stmt_tests->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt_tests->bindValue(':schedule_id', $row['ScheduleID']);
                $result_tests = $stmt_tests->execute();
                $row_tests = $result_tests->fetchArray();
                $test_count = !empty($row_tests) ? $row_tests['TestCount'] : 0;
                $group_count = empty($row['RunTargetGroups']) ? 0 : count(explode(',', $row['RunTargetGroups']));
                $main .= '<a href="?schedules/' . $row['ScheduleID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . pts_strings::plural_handler(count(phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $row['ScheduleID'])), 'System') . '</td><td>' . pts_strings::plural_handler($group_count, 'Group') . '</td><td>' . pts_strings::plural_handler($test_count, 'Test') . '</td><td>' . pts_strings::plural_handler(phoromatic_results_for_schedule($row['ScheduleID']), 'Result') . ' Total</td><td>' . pts_strings::plural_handler(phoromatic_results_for_schedule($row['ScheduleID'], 'TODAY'), 'Result') . ' Today</td><td><strong>' . phoromatic_schedule_activeon_string($row['ActiveOn'], $row['RunAt']) . '</strong></td></tr></table></li></a>';
            } while ($row = $result->fetchArray());
        }
        $main .= '</ul>
			</div>';
        $main .= '<hr /><h2>Schedule Overview</h2>';
        $week = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');
        foreach ($week as $i => $day) {
            $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, RunAt, RunTargetGroups, RunTargetSystems FROM phoromatic_schedules WHERE AccountID = :account_id AND State >= 1 AND ActiveOn LIKE :active_on ORDER BY RunAt,ActiveOn,Title ASC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':active_on', '%' . $i . '%');
            $result = $stmt->execute();
            $has_matched = false;
            while ($row = $result->fetchArray()) {
                if (!$has_matched) {
                    $main .= '<h3>' . $day . '</h3>' . PHP_EOL . '<p>';
                    $has_matched = true;
                }
                $main .= '<em>' . $row['RunAt'] . '</em> <a href="?schedules/' . $row['ScheduleID'] . '">' . $row['Title'] . '</a>';
                //$main .= $row['RunTargetSystems'] . ' ' . $row['RunTargetGroups'];
                $main .= '<br />';
            }
            if ($has_matched) {
                $main .= '</p>' . PHP_EOL;
            }
        }
        $main .= '<div class="pts_phoromatic_info_box_area">
					<ul>
						<li><h1>Deactivated Test Schedules</h1></li>';
        $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, Description, RunTargetSystems, RunTargetGroups, RunAt, ActiveOn FROM phoromatic_schedules WHERE AccountID = :account_id AND State < 1 ORDER BY Title ASC');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $result = $stmt->execute();
        $row = $result->fetchArray();
        if ($row == false) {
            $main .= '<li class="light" style="text-align: center;">No Schedules Found</li>';
        } else {
            do {
                $stmt_tests = phoromatic_server::$db->prepare('SELECT COUNT(*) AS TestCount FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY TestProfile ASC');
                $stmt_tests->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt_tests->bindValue(':schedule_id', $row['ScheduleID']);
                $result_tests = $stmt_tests->execute();
                $row_tests = $result_tests->fetchArray();
                $test_count = !empty($row_tests) ? $row_tests['TestCount'] : 0;
                $group_count = empty($row['RunTargetGroups']) ? 0 : count(explode(',', $row['RunTargetGroups']));
                $main .= '<a href="?schedules/' . $row['ScheduleID'] . '"><li>' . $row['Title'] . '<br /><table><tr><td>' . pts_strings::plural_handler(count(phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $row['ScheduleID'])), 'System') . '</td><td>' . pts_strings::plural_handler($group_count, 'Group') . '</td><td>' . pts_strings::plural_handler($test_count, 'Test') . '</td><td>' . pts_strings::plural_handler(phoromatic_results_for_schedule($row['ScheduleID']), 'Result') . ' Total</td><td>' . pts_strings::plural_handler(phoromatic_results_for_schedule($row['ScheduleID'], 'TODAY'), 'Result') . ' Today</td><td><strong>' . phoromatic_schedule_activeon_string($row['ActiveOn'], $row['RunAt']) . '</strong></td></tr></table></li></a>';
            } while ($row = $result->fetchArray());
        }
        $main .= '</ul>
			</div>';
        echo '<div id="pts_phoromatic_main_area">' . $main . '</div>';
        echo phoromatic_webui_footer();
    }
    public static function render_page_process($PATH)
    {
        if (isset($_POST['suite_title'])) {
            //	echo '<pre>';
            //	var_dump($_POST);
            //	echo '</pre>';
            if (strlen($_POST['suite_title']) < 3) {
                echo '<h2>Suite title must be at least three characters.</h2>';
            }
            //echo 'TEST SUITE: ' . $_POST['suite_title'] . '<br />';
            //echo 'TEST SUITE: ' . $_POST['suite_description'] . '<br />';
            $tests = array();
            foreach ($_POST['test_add'] as $i => $test_identifier) {
                $test_prefix = $_POST['test_prefix'][$i];
                $args = array();
                $args_name = array();
                foreach ($_POST as $i => $v) {
                    if (strpos($i, $test_prefix) !== false && substr($i, -9) != '_selected') {
                        if (strpos($v, '||') !== false) {
                            $opts = explode('||', $v);
                            $a = array();
                            $d = array();
                            foreach ($opts as $opt) {
                                $t = explode('::', $opt);
                                array_push($a, $t[1]);
                                array_push($d, $t[0]);
                            }
                            array_push($args, $a);
                            array_push($args_name, $d);
                        } else {
                            array_push($args, array($v));
                            array_push($args_name, array($_POST[$i . '_selected']));
                        }
                    }
                }
                $test_args = array();
                $test_args_description = array();
                pts_test_run_options::compute_all_combinations($test_args, null, $args, 0);
                pts_test_run_options::compute_all_combinations($test_args_description, null, $args_name, 0, ' - ');
                foreach (array_keys($test_args) as $i) {
                    array_push($tests, array('test' => $test_identifier, 'description' => $test_args_description[$i], 'args' => $test_args[$i]));
                }
            }
            if (count($tests) < 1) {
                echo '<h2>You must add at least one test to the suite.</h2>';
            }
            $suite_writer = new pts_test_suite_writer();
            $version_bump = 0;
            do {
                $suite_version = '1.' . $version_bump . '.0';
                $suite_id = $suite_writer->clean_save_name_string($_POST['suite_title']) . '-' . $suite_version;
                $suite_dir = phoromatic_server::phoromatic_account_suite_path($_SESSION['AccountID'], $suite_id);
                $version_bump++;
            } while (is_dir($suite_dir));
            pts_file_io::mkdir($suite_dir);
            $save_to = $suite_dir . '/suite-definition.xml';
            $suite_writer->add_suite_information($_POST['suite_title'], $suite_version, $_SESSION['UserName'], 'System', $_POST['suite_description']);
            foreach ($tests as $m) {
                $suite_writer->add_to_suite($m['test'], $m['args'], $m['description']);
            }
            $suite_writer->save_xml($save_to);
            echo '<h2>Saved As ' . $suite_id . '</h2>';
        }
        echo phoromatic_webui_header_logged_in();
        $main = '<h1>Local Suites</h1><p>Find already created local test suites by your account/group via the <a href="/?local_suites">local suites</a> page.</p>';
        if (!PHOROMATIC_USER_IS_VIEWER) {
            $main .= '<h1>Build Suite</h1><p>A test suite in the realm of the Phoronix Test Suite, OpenBenchmarking.org, and Phoromatic is <strong>a collection of test profiles with predefined settings</strong>. Establishing a test suite makes it easy to run repetitive testing on the same set of test profiles by simply referencing the test suite name.</p>';
            $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="build_suite" id="build_suite" method="post" onsubmit="return validate_suite();">
			<h3>Title:</h3>
			<p><input type="text" name="suite_title" /></p>
			<h3>Description:</h3>
			<p><textarea name="suite_description" id="suite_description" cols="60" rows="2"></textarea></p>
			<h3>Tests In Schedule:</h3>
			<p><div id="test_details"></div></p>
			<h3>Add Another Test</h3>';
            $main .= '<select name="add_to_suite_select_test" id="add_to_suite_select_test" onchange="phoromatic_build_suite_test_details();">';
            $dc = pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
            $dc_exists = is_file($dc . 'pts-download-cache.json');
            foreach (pts_openbenchmarking::available_tests(false, true) as $test) {
                $cache_checked = false;
                if ($dc_exists) {
                    $cache_json = file_get_contents($dc . 'pts-download-cache.json');
                    $cache_json = json_decode($cache_json, true);
                    if ($cache_json && isset($cache_json['phoronix-test-suite']['cached-tests'])) {
                        $cache_checked = true;
                        if (!in_array($test, $cache_json['phoronix-test-suite']['cached-tests'])) {
                            continue;
                        }
                    }
                }
                if (!$cache_checked && phoromatic_server::read_setting('show_local_tests_only') && pts_test_install_request::test_files_in_cache($test, true, true) == false) {
                    continue;
                }
                $main .= '<option value="' . $test . '">' . $test . '</option>';
            }
            $main .= '</select>';
            $main .= '<p align="right"><input name="submit" value="Create Suite" type="submit" onclick="return pts_rmm_validate_suite();" /></p>';
        }
        echo '<div id="pts_phoromatic_main_area">' . $main . '</div>';
        echo phoromatic_webui_footer();
    }
        }
        //pts_logger::add_to_log($requested_file . ' to be downloaded from ' . $file_path);
        ob_end_clean();
        if (isset($_GET['m']) && $_GET['m']) {
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file_path));
        }
        readfile($file_path);
        exit;
    } else {
        echo '<h1>Phoromatic Server Download Cache</h1>';
        $possible_paths = array(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)), PTS_DOWNLOAD_CACHE_PATH, PTS_SHARE_PATH . 'download-cache/', '/var/cache/phoronix-test-suite/download-cache/');
        $files = array();
        foreach ($possible_paths as $possible_path) {
            foreach (pts_file_io::glob($possible_path . '/*') as $file) {
                if (is_readable($file)) {
                    $basename = basename($file);
                    if (!in_array($basename, $files)) {
                        echo '<p><a href="?m=1&download=' . $basename . '">' . $basename . ' </a></p>' . PHP_EOL;
                        array_push($files, $basename);
                    }
                }
            }
        }
    }
}
 public static function display_web_page($URL, $alt_text = null, $default_open = true, $auto_open = false)
 {
     if (pts_client::read_env('DISPLAY') == false && pts_client::read_env('WAYLAND_DISPLAY') == false && phodevi::is_windows() == false && phodevi::is_macosx() == false || defined('PHOROMATIC_PROCESS')) {
         return;
     }
     if ($auto_open == false) {
         $view_results = pts_user_io::prompt_bool_input($alt_text == null ? 'Do you want to view the results in your web browser' : $alt_text, $default_open);
     } else {
         $view_results = true;
     }
     if ($view_results) {
         static $browser = null;
         if ($browser == null) {
             $config_browser = pts_config::read_user_config('PhoronixTestSuite/Options/General/DefaultBrowser', null);
             if ($config_browser != null && (is_executable($config_browser) || ($config_browser = pts_client::executable_in_path($config_browser)))) {
                 $browser = $config_browser;
             } else {
                 if (phodevi::is_windows()) {
                     $windows_browsers = array('C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe', 'C:\\Program Files\\Internet Explorer\\iexplore.exe');
                     foreach ($windows_browsers as $browser_test) {
                         if (is_executable($browser_test)) {
                             $browser = $browser_test;
                             break;
                         }
                     }
                     if (substr($URL, 0, 1) == '\\') {
                         $URL = 'file:///C:' . str_replace('/', '\\', $URL);
                     }
                 } else {
                     $possible_browsers = array('firefox', 'mozilla', 'x-www-browser', 'open', 'xdg-open', 'iceweasel', 'konqueror', 'epiphany', 'google-chrome');
                     foreach ($possible_browsers as &$b) {
                         if ($b = pts_client::executable_in_path($b)) {
                             $browser = $b;
                             break;
                         }
                     }
                 }
             }
         }
         if ($browser != null) {
             shell_exec($browser . ' "' . $URL . '" 2> /dev/null &');
         } else {
             echo PHP_EOL . 'No Web Browser Found.' . PHP_EOL;
         }
     }
 }
 public function determine_tests_to_run(&$to_run_objects)
 {
     $unique_test_count = count(array_unique($to_run_objects));
     $run_contains_a_no_result_type = false;
     $request_results_save = false;
     foreach ($to_run_objects as &$run_object) {
         // TODO: determine whether to print the titles of what's being run?
         if ($run_object instanceof pts_test_profile) {
             if ($run_object->get_identifier() == null || $run_object->get_title() == null || $this->validate_test_to_run($run_object) == false) {
                 continue;
             }
             if ($run_contains_a_no_result_type == false && $run_object->get_display_format() == 'NO_RESULT') {
                 $run_contains_a_no_result_type = true;
             }
             if ($request_results_save == false && $run_object->do_auto_save_results()) {
                 $request_results_save = true;
             }
             foreach (self::test_prompts_to_result_objects($run_object) as $result_object) {
                 $this->add_test_result_object($result_object);
             }
         } else {
             if ($run_object instanceof pts_test_suite) {
                 $this->pre_run_message = $run_object->get_pre_run_message();
                 $this->post_run_message = $run_object->get_post_run_message();
                 if ($run_object->get_run_mode() == 'PCQS') {
                     $this->is_pcqs = true;
                 }
                 foreach ($run_object->get_contained_test_result_objects() as $result_object) {
                     $this->add_test_result_object($result_object);
                 }
             } else {
                 if ($run_object instanceof pts_virtual_test_queue) {
                     foreach ($run_object->get_contained_test_result_objects() as $result_object) {
                         $this->add_test_result_object($result_object);
                     }
                 } else {
                     if ($run_object instanceof pts_result_file) {
                         // Print the $to_run ?
                         $this->run_description = $run_object->get_description();
                         $preset_vars = $run_object->get_preset_environment_variables();
                         $result_objects = $run_object->get_result_objects();
                         $this->set_save_name($run_object->get_identifier(), false);
                         $this->file_name_title = $run_object->get_title();
                         pts_module_manager::process_environment_variables_string_to_set($preset_vars);
                         foreach ($result_objects as &$result_object) {
                             if ($result_object->test_profile->get_identifier() == null) {
                                 continue;
                             }
                             $test_result = new pts_test_result($result_object->test_profile);
                             $test_result->set_used_arguments($result_object->get_arguments());
                             $test_result->set_used_arguments_description($result_object->get_arguments_description());
                             $this->add_test_result_object($test_result);
                         }
                     } else {
                         if ($run_object instanceof pts_virtual_test_suite) {
                             $virtual_suite_tests = $run_object->get_contained_test_profiles();
                             foreach (array_keys($virtual_suite_tests) as $i) {
                                 if ($virtual_suite_tests[$i]->is_supported(false) == false || $this->validate_test_to_run($virtual_suite_tests[$i]) == false) {
                                     unset($virtual_suite_tests[$i]);
                                 }
                             }
                             sort($virtual_suite_tests);
                             if (count($virtual_suite_tests) > 1) {
                                 array_push($virtual_suite_tests, 'All Tests In Suite');
                             }
                             if (!$this->auto_mode && !$this->batch_mode) {
                                 $run_index = explode(',', pts_user_io::prompt_text_menu('Select the tests in the virtual suite to run', $virtual_suite_tests, true, true));
                             } else {
                                 $run_index = -1;
                             }
                             if (count($virtual_suite_tests) > 2 && in_array(count($virtual_suite_tests) - 1, $run_index) || $run_index == -1) {
                                 // The appended 'All Tests In Suite' was selected, so run all
                             } else {
                                 foreach (array_keys($virtual_suite_tests) as $i) {
                                     if (!in_array($i, $run_index)) {
                                         unset($virtual_suite_tests[$i]);
                                     }
                                 }
                             }
                             foreach ($virtual_suite_tests as &$test_profile) {
                                 if ($test_profile instanceof pts_test_profile) {
                                     // The user is to configure virtual suites manually
                                     foreach (self::test_prompts_to_result_objects($test_profile) as $result_object) {
                                         $this->add_test_result_object($result_object);
                                     }
                                 }
                             }
                         } else {
                             trigger_error($run_object . ' is not recognized.', E_USER_ERROR);
                             continue;
                         }
                     }
                 }
             }
         }
     }
     // AlwaysUploadResultsToOpenBenchmarking AutoSortRunQueue
     if (pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/AutoSortRunQueue', 'TRUE') && $this->force_save_results == false) {
         // Not that it matters much, but if $this->force_save_results is set that means likely running from a result file...
         // so if running a result file, don't change the ordering of the existing results
         // Sort the run order so that all tests that are similar are grouped together, etc
         usort($this->tests_to_run, array('pts_test_run_manager', 'cmp_result_object_sort'));
     }
     if (pts_client::read_env('RUN_TESTS_IN_RANDOM_ORDER')) {
         shuffle($this->tests_to_run);
     }
     $this->prompt_save_results = $run_contains_a_no_result_type == false || $unique_test_count > 1;
     $this->force_save_results = $this->force_save_results || $request_results_save;
 }
 public static function render_page_process($PATH)
 {
     $main = null;
     $identifier_item = isset($PATH[1]) ? $PATH[0] . '/' . $PATH[1] : false;
     if ($identifier_item && pts_test_profile::is_test_profile($identifier_item)) {
         $tp = new pts_test_profile($identifier_item);
         $tp_identifier = $tp->get_identifier(false);
         $main .= '<h1>' . $tp->get_title() . '</h1><p>' . $tp->get_description() . '</p>';
         $main .= '<p><strong>' . $tp->get_test_hardware_type() . ' - ' . phoromatic_server::test_result_count_for_test_profile($_SESSION['AccountID'], $tp_identifier) . ' Results On This Account - ' . $tp->get_test_software_type() . ' - Maintained By: ' . $tp->get_maintainer() . ' - Supported Platforms: ' . implode(', ', $tp->get_supported_platforms()) . '</strong></p>';
         $main .= '<p><a href="http://openbenchmarking.org/test/' . $tp_identifier . '">Find out more about this test profile on OpenBenchmarking.org</a>.</p>';
         $main .= '<h2>Recent Results With This Test</h2>';
         $stmt = phoromatic_server::$db->prepare('SELECT Title, PPRID FROM phoromatic_results WHERE AccountID = :account_id AND UploadID IN (SELECT DISTINCT UploadID FROM phoromatic_results_results WHERE AccountID = :account_id AND TestProfile LIKE :tp) ORDER BY UploadTime DESC LIMIT 30');
         $stmt->bindValue(':account_id', $_SESSION['AccountID']);
         $stmt->bindValue(':tp', $tp_identifier . '%');
         $result = $stmt->execute();
         $recent_result_count = 0;
         while ($result && ($row = $result->fetchArray())) {
             $recent_result_count++;
             $main .= '<h2><a href="/?result/' . $row['PPRID'] . '">' . $row['Title'] . '</a></h2>';
         }
         if ($recent_result_count == 0) {
             $main .= '<p>No results found on this Phoromatic Server for the ' . $tp->get_title() . ' test profile.</p>';
         } else {
             if ($recent_result_count > 5) {
                 $stmt = phoromatic_server::$db->prepare('SELECT UploadID, SystemID, UploadTime FROM phoromatic_results WHERE AccountID = :account_id AND UploadID IN (SELECT DISTINCT UploadID FROM phoromatic_results_results WHERE AccountID = :account_id AND TestProfile LIKE :tp) ORDER BY UploadTime DESC LIMIT 1000');
                 $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                 $stmt->bindValue(':tp', $tp_identifier . '%');
                 $result = $stmt->execute();
                 $recent_result_count = 0;
                 $result_file = new pts_result_file(null, true);
                 while ($result && ($row = $result->fetchArray())) {
                     $composite_xml = phoromatic_server::phoromatic_account_result_path($_SESSION['AccountID'], $row['UploadID']) . 'composite.xml';
                     if (!is_file($composite_xml)) {
                         continue;
                     }
                     // Add to result file
                     $system_name = strtotime($row['UploadTime']) . ': ' . phoromatic_server::system_id_to_name($row['SystemID']);
                     $sub_result_file = new pts_result_file($composite_xml, true);
                     foreach ($sub_result_file->get_result_objects() as $obj) {
                         if ($obj->test_profile->get_identifier(false) == $tp_identifier) {
                             $obj->test_result_buffer->rename(null, $system_name);
                             $result_file->add_result($obj);
                         }
                     }
                 }
                 $table = null;
                 $extra_attributes = array('multi_way_comparison_invert_default' => false);
                 $f = false;
                 foreach ($result_file->get_result_objects() as $obj) {
                     $obj->test_profile->set_display_format('SCATTER_PLOT');
                     foreach ($obj->test_result_buffer->buffer_items as $i => &$item) {
                         if (!is_numeric(substr($item->get_result_identifier(), 0, strpos($item->get_result_identifier(), ':')))) {
                             unset($obj->test_result_buffer->buffer_items[$i]);
                         }
                     }
                     $result_file = null;
                     $main .= '<p align="center">' . pts_render::render_graph_inline_embed($obj, $result_file, $extra_attributes) . '</p>';
                 }
             }
         }
     } else {
         $dc = pts_strings::add_trailing_slash(pts_strings::parse_for_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH)));
         $dc_exists = is_file($dc . 'pts-download-cache.json');
         if ($dc_exists) {
             $cache_json = file_get_contents($dc . 'pts-download-cache.json');
             $cache_json = json_decode($cache_json, true);
         }
         $test_counts_for_account = phoromatic_server::test_result_count_for_test_profiles($_SESSION['AccountID']);
         foreach (pts_openbenchmarking::available_tests() as $test) {
             $cache_checked = false;
             if ($dc_exists) {
                 if ($cache_json && isset($cache_json['phoronix-test-suite']['cached-tests'])) {
                     $cache_checked = true;
                     if (!in_array($test, $cache_json['phoronix-test-suite']['cached-tests'])) {
                         //continue;
                     }
                 }
             }
             if (!$cache_checked && phoromatic_server::read_setting('show_local_tests_only') && pts_test_install_request::test_files_in_cache($test, true, true) == false) {
                 continue;
             }
             $tp = new pts_test_profile($test);
             if ($tp->get_title() == null) {
                 continue;
             }
             $test_count = 0;
             $tpid = $tp->get_identifier(false);
             foreach ($test_counts_for_account as $test => $count) {
                 if (strpos($test, $tpid) !== false) {
                     $test_count += $count;
                     unset($test_counts_for_account[$test]);
                 }
             }
             $main .= '<h1 style="margin-bottom: 0;"><a href="/?tests/' . $tp->get_identifier(false) . '">' . $tp->get_title() . '</a></h1>';
             $main .= '<p style="font-size: 90%;"><strong>' . $tp->get_test_hardware_type() . '</strong> <em>-</em> ' . $test_count . ' Results On This Account' . ' </p>';
         }
     }
     echo phoromatic_webui_header_logged_in();
     echo '<div id="pts_phoromatic_main_area">' . $main . '</div>';
     echo phoromatic_webui_footer();
 }
 public static function run_test(&$test_run_manager, &$test_run_request)
 {
     $test_identifier = $test_run_request->test_profile->get_identifier();
     $extra_arguments = $test_run_request->get_arguments();
     $arguments_description = $test_run_request->get_arguments_description();
     $full_output = pts_config::read_bool_config('PhoronixTestSuite/Options/General/FullOutput', 'FALSE');
     // Do the actual test running process
     $test_directory = $test_run_request->test_profile->get_install_dir();
     if (!is_dir($test_directory)) {
         return false;
     }
     $lock_file = $test_directory . 'run_lock';
     if (pts_client::create_lock($lock_file) == false && $test_run_manager->is_multi_test_stress_run() == false) {
         self::test_run_error($test_run_manager, $test_run_request, 'The ' . $test_identifier . ' test is already running.');
         return false;
     }
     $active_result_buffer = new pts_test_result_buffer_active();
     $test_run_request->active =& $active_result_buffer;
     $execute_binary = $test_run_request->test_profile->get_test_executable();
     $times_to_run = $test_run_request->test_profile->get_times_to_run();
     $ignore_runs = $test_run_request->test_profile->get_runs_to_ignore();
     $test_type = $test_run_request->test_profile->get_test_hardware_type();
     $allow_cache_share = $test_run_request->test_profile->allow_cache_share();
     $min_length = $test_run_request->test_profile->get_min_length();
     $max_length = $test_run_request->test_profile->get_max_length();
     if ($test_run_request->test_profile->get_environment_testing_size() > 1 && ceil(disk_free_space($test_directory) / 1048576) < $test_run_request->test_profile->get_environment_testing_size()) {
         // Ensure enough space is available on disk during testing process
         self::test_run_error($test_run_manager, $test_run_request, 'There is not enough space (at ' . $test_directory . ') for this test to run.');
         pts_client::release_lock($lock_file);
         return false;
     }
     $to_execute = $test_run_request->test_profile->get_test_executable_dir();
     $pts_test_arguments = trim($test_run_request->test_profile->get_default_arguments() . ' ' . str_replace($test_run_request->test_profile->get_default_arguments(), '', $extra_arguments) . ' ' . $test_run_request->test_profile->get_default_post_arguments());
     $extra_runtime_variables = pts_tests::extra_environmental_variables($test_run_request->test_profile);
     // Start
     $cache_share_pt2so = $test_directory . 'cache-share-' . PTS_INIT_TIME . '.pt2so';
     $cache_share_present = $allow_cache_share && is_file($cache_share_pt2so);
     $test_run_request->set_used_arguments_description($arguments_description);
     pts_module_manager::module_process('__pre_test_run', $test_run_request);
     $time_test_start = time();
     pts_client::$display->test_run_start($test_run_manager, $test_run_request);
     if (!$cache_share_present) {
         $pre_output = pts_tests::call_test_script($test_run_request->test_profile, 'pre', 'Running Pre-Test Script', $pts_test_arguments, $extra_runtime_variables, true);
         if ($pre_output != null && (pts_client::is_debug_mode() || $full_output)) {
             pts_client::$display->test_run_instance_output($pre_output);
         }
         if (is_file($test_directory . 'pre-test-exit-status')) {
             // If the pre script writes its exit status to ~/pre-test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'pre-test-exit-status');
             unlink($test_directory . 'pre-test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The pre run script exited with a non-zero exit status.' . PHP_EOL);
                 self::test_run_error($test_run_manager, $test_run_request, 'This test execution has been abandoned.');
                 return false;
             }
         }
     }
     pts_client::$display->display_interrupt_message($test_run_request->test_profile->get_pre_run_message());
     $runtime_identifier = time();
     $execute_binary_prepend = '';
     if ($test_run_request->exec_binary_prepend != null) {
         $execute_binary_prepend = $test_run_request->exec_binary_prepend;
     }
     if (!$cache_share_present && $test_run_request->test_profile->is_root_required()) {
         if (phodevi::is_root() == false) {
             pts_client::$display->test_run_error('This test must be run as the root / administrator account.');
         }
         $execute_binary_prepend .= ' ' . PTS_CORE_STATIC_PATH . 'root-access.sh ';
     }
     if ($allow_cache_share && !is_file($cache_share_pt2so)) {
         $cache_share = new pts_storage_object(false, false);
     }
     if ($test_run_manager->get_results_identifier() != null && $test_run_manager->get_file_name() != null && pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/SaveTestLogs', 'FALSE')) {
         $backup_test_log_dir = PTS_SAVE_RESULTS_PATH . $test_run_manager->get_file_name() . '/test-logs/active/' . $test_run_manager->get_results_identifier() . '/';
         pts_file_io::delete($backup_test_log_dir);
         pts_file_io::mkdir($backup_test_log_dir, 0777, true);
     } else {
         $backup_test_log_dir = false;
     }
     for ($i = 0, $abort_testing = false, $time_test_start_actual = time(), $defined_times_to_run = $times_to_run; $i < $times_to_run && $i < 256 && !$abort_testing; $i++) {
         pts_client::$display->test_run_instance_header($test_run_request);
         $test_log_file = $test_directory . basename($test_identifier) . '-' . $runtime_identifier . '-' . ($i + 1) . '.log';
         $is_expected_last_run = $i == $times_to_run - 1;
         $test_extra_runtime_variables = array_merge($extra_runtime_variables, array('LOG_FILE' => $test_log_file, 'DISPLAY' => getenv('DISPLAY'), 'PATH' => getenv('PATH')));
         $restored_from_cache = false;
         if ($cache_share_present) {
             $cache_share = pts_storage_object::recover_from_file($cache_share_pt2so);
             if ($cache_share) {
                 $test_result = $cache_share->read_object('test_results_output_' . $i);
                 $test_extra_runtime_variables['LOG_FILE'] = $cache_share->read_object('log_file_location_' . $i);
                 if ($test_extra_runtime_variables['LOG_FILE'] != null) {
                     file_put_contents($test_extra_runtime_variables['LOG_FILE'], $cache_share->read_object('log_file_' . $i));
                     $test_run_time = 0;
                     // This wouldn't be used for a cache share since it would always be the same, but declare the value so the variable is at least initialized
                     $restored_from_cache = true;
                 }
             }
             unset($cache_share);
         }
         if ($restored_from_cache == false) {
             $test_run_command = 'cd ' . $to_execute . ' && ' . $execute_binary_prepend . './' . $execute_binary . ' ' . $pts_test_arguments . ' 2>&1';
             pts_client::test_profile_debug_message('Test Run Command: ' . $test_run_command);
             $is_monitoring = pts_test_result_parser::system_monitor_task_check($test_run_request->test_profile);
             $test_run_time_start = time();
             if (phodevi::is_windows() || pts_client::read_env('USE_PHOROSCRIPT_INTERPRETER') != false) {
                 $phoroscript = new pts_phoroscript_interpreter($to_execute . '/' . $execute_binary, $test_extra_runtime_variables, $to_execute);
                 $phoroscript->execute_script($pts_test_arguments);
                 $test_result = null;
             } else {
                 //$test_result = pts_client::shell_exec($test_run_command, $test_extra_runtime_variables);
                 $descriptorspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
                 $test_process = proc_open('exec ' . $execute_binary_prepend . './' . $execute_binary . ' ' . $pts_test_arguments . ' 2>&1', $descriptorspec, $pipes, $to_execute, array_merge($_ENV, pts_client::environmental_variables(), $test_extra_runtime_variables));
                 if (is_resource($test_process)) {
                     //echo proc_get_status($test_process)['pid'];
                     pts_module_manager::module_process('__test_running', $test_process);
                     $test_result = stream_get_contents($pipes[1]);
                     fclose($pipes[1]);
                     fclose($pipes[2]);
                     $return_value = proc_close($test_process);
                 }
             }
             $test_run_time = time() - $test_run_time_start;
             $monitor_result = $is_monitoring ? pts_test_result_parser::system_monitor_task_post_test($test_run_request->test_profile) : 0;
         }
         if (!isset($test_result[10240]) || pts_client::is_debug_mode() || $full_output) {
             pts_client::$display->test_run_instance_output($test_result);
         }
         if (is_file($test_log_file) && trim($test_result) == null && (filesize($test_log_file) < 10240 || pts_client::is_debug_mode() || $full_output)) {
             $test_log_file_contents = file_get_contents($test_log_file);
             pts_client::$display->test_run_instance_output($test_log_file_contents);
             unset($test_log_file_contents);
         }
         $test_run_request->test_result_standard_output = $test_result;
         $exit_status_pass = true;
         if (is_file($test_directory . 'test-exit-status')) {
             // If the test script writes its exit status to ~/test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'test-exit-status');
             unlink($test_directory . 'test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The test exited with a non-zero exit status.');
                 if ($is_expected_last_run && is_file($test_log_file)) {
                     $scan_log = pts_file_io::file_get_contents($test_log_file);
                     $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                     if ($test_run_error) {
                         self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                     }
                 }
                 $exit_status_pass = false;
             }
         }
         if (!in_array($i + 1, $ignore_runs) && $exit_status_pass) {
             if (isset($monitor_result) && $monitor_result != 0) {
                 $test_run_request->active->active_result = $monitor_result;
             } else {
                 pts_test_result_parser::parse_result($test_run_request, $test_extra_runtime_variables['LOG_FILE']);
             }
             pts_client::test_profile_debug_message('Test Result Value: ' . $test_run_request->active->active_result);
             if (!empty($test_run_request->active->active_result)) {
                 if ($test_run_time < 2 && intval($test_run_request->active->active_result) == $test_run_request->active->active_result && $test_run_request->test_profile->get_estimated_run_time() > 60 && !$restored_from_cache) {
                     // If the test ended in less than two seconds, outputted some int, and normally the test takes much longer, then it's likely some invalid run
                     self::test_run_instance_error($test_run_manager, $test_run_request, 'The test run ended prematurely.');
                     if ($is_expected_last_run && is_file($test_log_file)) {
                         $scan_log = pts_file_io::file_get_contents($test_log_file);
                         $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                         if ($test_run_error) {
                             self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                         }
                     }
                 } else {
                     // TODO integrate active_result into active buffer
                     $active_result_buffer->add_trial_run_result($test_run_request->active->active_result, $test_run_request->active->active_min_result, $test_run_request->active->active_max_result);
                 }
             } else {
                 if ($test_run_request->test_profile->get_display_format() != 'NO_RESULT') {
                     self::test_run_instance_error($test_run_manager, $test_run_request, 'The test run did not produce a result.');
                     if ($is_expected_last_run && is_file($test_log_file)) {
                         $scan_log = pts_file_io::file_get_contents($test_log_file);
                         $test_run_error = pts_tests::scan_for_error($scan_log, $test_run_request->test_profile->get_test_executable_dir());
                         if ($test_run_error) {
                             self::test_run_instance_error($test_run_manager, $test_run_request, 'E: ' . $test_run_error);
                         }
                     }
                 }
             }
             if ($allow_cache_share && !is_file($cache_share_pt2so)) {
                 $cache_share->add_object('test_results_output_' . $i, $test_run_request->active->active_result);
                 $cache_share->add_object('log_file_location_' . $i, $test_extra_runtime_variables['LOG_FILE']);
                 $cache_share->add_object('log_file_' . $i, is_file($test_log_file) ? file_get_contents($test_log_file) : null);
             }
         }
         if ($is_expected_last_run && $active_result_buffer->get_trial_run_count() > floor(($i - 2) / 2) && !$cache_share_present && $test_run_manager->do_dynamic_run_count()) {
             // The later check above ensures if the test is failing often the run count won't uselessly be increasing
             // Should we increase the run count?
             $increase_run_count = false;
             if ($defined_times_to_run == $i + 1 && $active_result_buffer->get_trial_run_count() > 0 && $active_result_buffer->get_trial_run_count() < $defined_times_to_run && $i < 64) {
                 // At least one run passed, but at least one run failed to produce a result. Increase count to try to get more successful runs
                 $increase_run_count = $defined_times_to_run - $active_result_buffer->get_trial_run_count();
             } else {
                 if ($active_result_buffer->get_trial_run_count() >= 2) {
                     // Dynamically increase run count if needed for statistical significance or other reasons
                     $increase_run_count = $test_run_manager->increase_run_count_check($active_result_buffer, $defined_times_to_run, $test_run_time);
                     if ($increase_run_count === -1) {
                         $abort_testing = true;
                     } else {
                         if ($increase_run_count == true) {
                             // Just increase the run count one at a time
                             $increase_run_count = 1;
                         }
                     }
                 }
             }
             if ($increase_run_count > 0) {
                 $times_to_run += $increase_run_count;
                 $is_expected_last_run = false;
                 //$test_run_request->test_profile->set_times_to_run($times_to_run);
             }
         }
         if ($times_to_run > 1 && $i < $times_to_run - 1) {
             if ($cache_share_present == false) {
                 $interim_output = pts_tests::call_test_script($test_run_request->test_profile, 'interim', 'Running Interim Test Script', $pts_test_arguments, $extra_runtime_variables, true);
                 if ($interim_output != null && (pts_client::is_debug_mode() || $full_output)) {
                     pts_client::$display->test_run_instance_output($interim_output);
                 }
                 //sleep(2); // Rest for a moment between tests
             }
             pts_module_manager::module_process('__interim_test_run', $test_run_request);
         }
         if (is_file($test_log_file)) {
             if ($is_expected_last_run) {
                 // For now just passing the last test log file...
                 // TODO XXX: clean this up with log files to preserve when needed, let multiple log files exist for extra_data, etc
                 pts_test_result_parser::generate_extra_data($test_run_request, $test_log_file);
             }
             if ($backup_test_log_dir) {
                 copy($test_log_file, $backup_test_log_dir . basename($test_log_file));
             }
             if (pts_client::test_profile_debug_message('Log File At: ' . $test_log_file) == false) {
                 unlink($test_log_file);
             }
         }
         if (is_file(PTS_USER_PATH . 'halt-testing') || is_file(PTS_USER_PATH . 'skip-test')) {
             pts_client::release_lock($lock_file);
             return false;
         }
         pts_client::$display->test_run_instance_complete($test_run_request);
     }
     $time_test_end_actual = time();
     if ($cache_share_present == false) {
         $post_output = pts_tests::call_test_script($test_run_request->test_profile, 'post', 'Running Post-Test Script', $pts_test_arguments, $extra_runtime_variables, true);
         if ($post_output != null && (pts_client::is_debug_mode() || $full_output)) {
             pts_client::$display->test_run_instance_output($post_output);
         }
         if (is_file($test_directory . 'post-test-exit-status')) {
             // If the post script writes its exit status to ~/post-test-exit-status, if it's non-zero the test run failed
             $exit_status = pts_file_io::file_get_contents($test_directory . 'post-test-exit-status');
             unlink($test_directory . 'post-test-exit-status');
             if ($exit_status != 0) {
                 self::test_run_instance_error($test_run_manager, $test_run_request, 'The post run script exited with a non-zero exit status.' . PHP_EOL);
                 $abort_testing = true;
             }
         }
     }
     if ($abort_testing) {
         self::test_run_error($test_run_manager, $test_run_request, 'This test execution has been abandoned.');
         return false;
     }
     // End
     $time_test_end = time();
     $time_test_elapsed = $time_test_end - $time_test_start;
     $time_test_elapsed_actual = $time_test_end_actual - $time_test_start_actual;
     if (!empty($min_length)) {
         if ($min_length > $time_test_elapsed_actual) {
             // The test ended too quickly, results are not valid
             self::test_run_error($test_run_manager, $test_run_request, 'This test ended prematurely.');
             return false;
         }
     }
     if (!empty($max_length)) {
         if ($max_length < $time_test_elapsed_actual) {
             // The test took too much time, results are not valid
             self::test_run_error($test_run_manager, $test_run_request, 'This test run was exhausted.');
             return false;
         }
     }
     if ($allow_cache_share && !is_file($cache_share_pt2so) && $cache_share instanceof pts_storage_object) {
         $cache_share->save_to_file($cache_share_pt2so);
         unset($cache_share);
     }
     if ($test_run_manager->get_results_identifier() != null && pts_config::read_bool_config('PhoronixTestSuite/Options/Testing/SaveInstallationLogs', 'FALSE')) {
         if (is_file($test_run_request->test_profile->get_install_dir() . 'install.log')) {
             $backup_log_dir = PTS_SAVE_RESULTS_PATH . $test_run_manager->get_file_name() . '/installation-logs/' . $test_run_manager->get_results_identifier() . '/';
             pts_file_io::mkdir($backup_log_dir, 0777, true);
             copy($test_run_request->test_profile->get_install_dir() . 'install.log', $backup_log_dir . basename($test_identifier) . '.log');
         }
     }
     // Fill in missing test details
     if (empty($arguments_description)) {
         $arguments_description = $test_run_request->test_profile->get_test_subtitle();
     }
     $file_var_checks = array(array('pts-results-scale', 'set_result_scale', null), array('pts-results-proportion', 'set_result_proportion', null), array('pts-results-quantifier', 'set_result_quantifier', null), array('pts-test-version', 'set_version', null), array('pts-test-description', null, 'set_used_arguments_description'), array('pts-footnote', null, null));
     foreach ($file_var_checks as &$file_check) {
         list($file, $set_function, $result_set_function) = $file_check;
         if (is_file($test_directory . $file)) {
             $file_contents = pts_file_io::file_get_contents($test_directory . $file);
             unlink($test_directory . $file);
             if (!empty($file_contents)) {
                 if ($set_function != null) {
                     call_user_func(array($test_run_request->test_profile, $set_function), $file_contents);
                 } else {
                     if ($result_set_function != null) {
                         if ($result_set_function == 'set_used_arguments_description') {
                             $arguments_description = $file_contents;
                         } else {
                             call_user_func(array($test_run_request, $result_set_function), $file_contents);
                         }
                     } else {
                         if ($file == 'pts-footnote') {
                             $test_run_request->test_profile->test_installation->set_install_footnote($file_contents);
                         }
                     }
                 }
             }
         }
     }
     if (empty($arguments_description)) {
         $arguments_description = 'Phoronix Test Suite v' . PTS_VERSION;
     }
     foreach (pts_client::environmental_variables() as $key => $value) {
         $arguments_description = str_replace('$' . $key, $value, $arguments_description);
         if (!in_array($key, array('VIDEO_MEMORY', 'NUM_CPU_CORES', 'NUM_CPU_JOBS'))) {
             $extra_arguments = str_replace('$' . $key, $value, $extra_arguments);
         }
     }
     // Any device notes to add to PTS test notes area?
     foreach (phodevi::read_device_notes($test_type) as $note) {
         pts_test_notes_manager::add_note($note);
     }
     // As of PTS 4.4, this is removed and superceded effectively by reporting the notes to table
     // Any special information (such as forced AA/AF levels for graphics) to add to the description string of the result?
     /*
     if(($special_string = phodevi::read_special_settings_string($test_type)) != null)
     {
     	if(strpos($arguments_description, $special_string) === false)
     	{
     		if($arguments_description != null)
     		{
     			$arguments_description .= ' | ';
     		}
     
     		$arguments_description .= $special_string;
     	}
     }
     */
     // Result Calculation
     $test_run_request->set_used_arguments_description($arguments_description);
     $test_run_request->set_used_arguments($extra_arguments);
     pts_test_result_parser::calculate_end_result($test_run_request, $active_result_buffer);
     // Process results
     pts_client::$display->test_run_end($test_run_request);
     pts_client::$display->display_interrupt_message($test_run_request->test_profile->get_post_run_message());
     pts_module_manager::module_process('__post_test_run', $test_run_request);
     $report_elapsed_time = $cache_share_present == false && $test_run_request->active->get_result() != 0;
     pts_tests::update_test_install_xml($test_run_request->test_profile, $report_elapsed_time ? $time_test_elapsed : 0);
     pts_storage_object::add_in_file(PTS_CORE_STORAGE, 'total_testing_time', $time_test_elapsed / 60);
     if ($report_elapsed_time && pts_client::do_anonymous_usage_reporting() && $time_test_elapsed >= 60) {
         // If anonymous usage reporting enabled, report test run-time to OpenBenchmarking.org
         pts_openbenchmarking_client::upload_usage_data('test_complete', array($test_run_request, $time_test_elapsed));
     }
     // Remove lock
     pts_client::release_lock($lock_file);
     return $active_result_buffer;
 }
 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 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);
    }