コード例 #1
0
 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();
 }
コード例 #2
0
function phoromatic_system_id_to_name($system_id, $aid = false)
{
    return phoromatic_server::system_id_to_name($system_id, $aid);
}
コード例 #3
0
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = '<h1>Phoromatic</h1>';
        $main .= phoromatic_systems_needing_attention();
        $main .= '<p>Phoromatic is the remote management and test orchestration component to the <a href="http://www.phoronix-test-suite.com/">Phoronix Test Suite</a>. Phoromatic allows you to take advantage of the Phoronix Test Suite\'s vast feature-set across multiple systems over the LAN/WAN, manage entire test farms of systems for benchmarking via a centralized interface, centrally collect test results, and carry out other enteprise-focused tasks.</p>';
        $main_page_message = phoromatic_server::read_setting('main_page_message');
        if (!PHOROMATIC_USER_IS_VIEWER) {
            $main .= '<p>To get started with your new account, the basic steps to get started include:</p>
				<ol>
					<li>Connect/sync the Phoronix Test Suite client systems (the systems to be benchmarked) to this account. In the simplest form, you just need to run the following command on the test systems: <strong>phoronix-test-suite phoromatic.connect ' . phoromatic_web_socket_server_addr() . '</strong>. For more information view the instructions on the <a href="?systems">systems page</a>.</li>
					<li>Configure your <a href="?settings">account settings</a>.</li>
					<li><a href="?schedules">Create a test schedule</a>. A schedule is for running test(s) on selected system(s) on a routine, timed basis or whenever a custom trigger is passed to the Phoromatic server. A test schedule could be for running benchmarks on a daily basis, whenever a new Git commit is applied to a code-base, or other events occurred. You can also enrich the potential by adding pre/post-test hooks for ensuring the system is set to a proper state for benchmarking. Alternatively, you can <a href="?benchmark">create a benchmark ticket</a> for one-time testing on one or more systems.</li>
					<li>View the automatically generated <a href="?results">test results</a>.</li>';
            if (!empty($main_page_message)) {
                $main .= '<li><strong>' . $main_page_message . '</strong></li>';
            } else {
                $main .= '<li><strong>If you are interested in Phoromatic and the Phoronix Test Suite for enterprise testing, please <a href="http://commercial.phoronix-test-suite.com/">contact us</a> for commercial support, custom test development, custom engineering services, and other professional services. It\'s not without corporate support and sponsorship that we can continue to develop this leading open-source Linux benchmarking software. If you run into any problems with our open-source software or would like to contribute patches, you can do so via our <a href="https://www.github.com/phoronix-test-suite/phoronix-test-suite">GitHub project</a>.</strong></li>
				</ol>';
            }
        } else {
            if (!empty($main_page_message)) {
                $main .= '<p><strong>' . $main_page_message . '</strong></p>';
            }
        }
        $main .= '<hr /><div id="phoromatic_fixed_main_table">';
        $systems_needing_attention = phoromatic_server::systems_appearing_down($_SESSION['AccountID']);
        $systems_idling = phoromatic_server::systems_idling($_SESSION['AccountID']);
        $systems_shutdown = phoromatic_server::systems_shutdown($_SESSION['AccountID']);
        $systems_running_tests = phoromatic_server::systems_running_tests($_SESSION['AccountID']);
        $main .= '<div id="phoromatic_main_table_cell">
			<h2>' . pts_strings::plural_handler(count($systems_running_tests), 'System') . ' Running Tests</h2>
			<h2>' . pts_strings::plural_handler(count($systems_idling), 'System') . ' Idling</h2>
			<h2>' . pts_strings::plural_handler(count($systems_shutdown), 'System') . ' Shutdown</h2>
			<h2>' . pts_strings::plural_handler(count($systems_needing_attention), 'System') . ' Needing Attention</h2>';
        $main .= '<hr /><h2>Systems Running Tests</h2>';
        $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 AND CurrentTask NOT LIKE \'%Idling%\' AND CurrentTask NOT LIKE \'%Shutdown%\' ORDER BY LastCommunication DESC');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $result = $stmt->execute();
        while ($result && ($row = $result->fetchArray())) {
            $main .= '<div class="phoromatic_overview_box">';
            $main .= '<h1><a href="?systems/' . $row['SystemID'] . '">' . $row['Title'] . '</a></h1>';
            $main .= $row['CurrentTask'] . '<br />';
            if (!empty($row['CurrentProcessSchedule'])) {
                $main .= '<a href="?schedules/' . $row['CurrentProcessSchedule'] . '">' . phoromatic_server::schedule_id_to_name($row['CurrentProcessSchedule']) . '</a><br />';
            }
            $time_remaining = phoromatic_compute_estimated_time_remaining($row['EstimatedTimeForTask'], $row['LastCommunication']);
            if ($time_remaining) {
                $main .= '<em>~ ' . pts_strings::plural_handler($time_remaining, 'Minute') . ' Remaining</em>';
            }
            $main .= '</div>';
        }
        $main .= '</div>';
        $schedules_today = phoromatic_server::schedules_today($_SESSION['AccountID']);
        $schedules_total = phoromatic_server::schedules_total($_SESSION['AccountID']);
        $benchmark_tickets_today = phoromatic_server::benchmark_tickets_today($_SESSION['AccountID']);
        $main .= '<div id="phoromatic_main_table_cell">
		<h2>' . pts_strings::plural_handler(count($schedules_today), 'Schedule') . ' Active Today</h2>
		<h2>' . pts_strings::plural_handler(count($schedules_total), 'Schedule') . ' In Total</h2>
		<h2>' . pts_strings::plural_handler(count($benchmark_tickets_today), 'Active Benchmark Ticket') . '</h2>
		<h2> &nbsp; </h2>';
        $main .= '<hr /><h2>Today\'s Scheduled Tests</h2>';
        foreach ($schedules_today as &$row) {
            $systems_for_schedule = phoromatic_server::systems_associated_with_schedule($_SESSION['AccountID'], $row['ScheduleID']);
            $extra_css = null;
            if (empty($systems_for_schedule)) {
                $extra_css = ' opacity: 0.4;';
            }
            list($h, $m) = explode('.', $row['RunAt']);
            $main .= '<div style="' . $extra_css . '" class="phoromatic_overview_box">';
            $main .= '<h1><a href="?schedules/' . $row['ScheduleID'] . '">' . $row['Title'] . '</a></h1>';
            if (!empty($systems_for_schedule)) {
                if ($row['RunAt'] > date('H.i')) {
                    $run_in_future = true;
                    $main .= '<h3>Runs In ' . pts_strings::format_time($h * 60 + $m - (date('H') * 60 + date('i')), 'MINUTES') . '</h3>';
                } else {
                    $run_in_future = false;
                    $main .= '<h3>Triggered ' . pts_strings::format_time(max(1, date('H') * 60 + date('i') - ($h * 60 + $m)), 'MINUTES') . ' Ago</h3>';
                }
            }
            foreach ($systems_for_schedule as $system_id) {
                $pprid = self::result_match($row['ScheduleID'], $system_id, date('Y-m-d'));
                if ($pprid) {
                    $main .= '<a href="?result/' . $pprid . '">';
                }
                $main .= phoromatic_server::system_id_to_name($system_id);
                if ($pprid) {
                    $main .= '</a>';
                } else {
                    if (!$run_in_future) {
                        $sys_info = self::system_info($system_id);
                        $last_comm_diff = time() - strtotime($sys_info['LastCommunication']);
                        $main .= ' <sup><a href="?systems/' . $system_id . '">';
                        if ($last_comm_diff > 3600) {
                            $main .= '<strong>Last Communication: ' . pts_strings::format_time($last_comm_diff, 'SECONDS', true, 60) . ' Ago</strong>';
                        } else {
                            $main .= $sys_info['CurrentTask'];
                        }
                        $main .= '</a></sup>';
                    }
                }
                $main .= '<br />';
            }
            $main .= '</div>';
        }
        $main .= '</div>';
        $results_today = phoromatic_server::test_results($_SESSION['AccountID'], strtotime('today'));
        $results_this_week = phoromatic_server::test_results($_SESSION['AccountID'], mktime(0, 0, 0, date('n'), date('j') - date('N') + 1));
        $results_total = phoromatic_server::test_results($_SESSION['AccountID'], null);
        $main .= '<div id="phoromatic_main_table_cell">
		<h2>' . pts_strings::plural_handler(count($results_today), 'Test Result') . ' Today</h2>
		<h2>' . pts_strings::plural_handler(count($results_this_week), 'Test Result') . ' This Week</h2>
		<h2>' . pts_strings::plural_handler(count($results_total), 'Test Result') . ' Total</h2>
		<h2>' . pts_strings::plural_handler(phoromatic_server::test_results_benchmark_count($_SESSION['AccountID']), 'Benchmark Result') . ' Total</h2>
		<hr /><h2>Today\'s Results</h2>';
        foreach ($results_today as $result) {
            $main .= '<h3><a href="?result/' . $result['PPRID'] . '">' . $result['Title'] . '</a></h3>';
        }
        $main .= '</div>';
        $main .= '</div>';
        /*
        		$has_flagged_results = false;
        		$stmt = phoromatic_server::$db->prepare('SELECT ScheduleID, GROUP_CONCAT(SystemID,\',\') AS Systems FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID NOT LIKE 0 GROUP BY ScheduleID ORDER BY UploadTime DESC');
        		$stmt->bindValue(':account_id', $_SESSION['AccountID']);
        		$test_result_result = $stmt->execute();
        		while($test_result_row = $test_result_result->fetchArray())
        		{
        			$systems = array_count_values(explode(',', $test_result_row['Systems']));
        
        			foreach($systems as $system_id => $system_count)
        			{
        				if($system_count < 2)
        					unset($systems[$system_id]);
        			}
        
        			$printed_schedule_name = false;
        			if(!empty($systems))
        			{
        				foreach(array_keys($systems) as $system_id)
        				{
        					$stmt_uploads = phoromatic_server::$db->prepare('SELECT PPRID, UploadID FROM phoromatic_results WHERE AccountID = :account_id AND SystemID = :system_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC LIMIT 2');
        					$stmt_uploads->bindValue(':account_id', $_SESSION['AccountID']);
        					$stmt_uploads->bindValue(':system_id', $system_id);
        					$stmt_uploads->bindValue(':schedule_id', $test_result_row['ScheduleID']);
        					$result_uploads = $stmt_uploads->execute();
        
        					$result_file = array();
        					$pprids = array();
        					while($result_uploads_row = $result_uploads->fetchArray())
        					{
        						$composite_xml = phoromatic_server::phoromatic_account_result_path($_SESSION['AccountID'], $result_uploads_row['UploadID']) . 'composite.xml';
        						if(is_file($composite_xml))
        						{
        							array_push($result_file, new pts_result_merge_select($composite_xml));
        						}
        						array_push($pprids, $result_uploads_row['PPRID']);
        					}
        					$result_file = array_reverse($result_file);
        
        					if(count($result_file) == 2)
        					{
        						$writer = new pts_result_file_writer(null);
        						$attributes = array();
        						pts_merge::merge_test_results_process($writer, $result_file, $attributes);
        						$result_file = new pts_result_file($writer->get_xml());
        
        						foreach($result_file->get_result_objects('ONLY_CHANGED_RESULTS') as $i => $result_object)
        						{
        							$vari = round($result_object->largest_result_variation(), 3);
        							if(abs($vari) < 0.03)
        								continue;
        							if(!$has_flagged_results)
        							{
        								$main .= '<hr /><h2>Flagged Results</h2>';
        								$main .= '<p>Displayed are results for each system of each scheduled test where there is a measurable change (currently set to a 0.1% threshold) when comparing the most recent result to the previous result for that system for that test schedule. Click on the change to jump to that individualized result file comparison.</p>';
        								$main .= '<span style="font-size: 80%;">';
        								$has_flagged_results = true;
        							}
        							if(!$printed_schedule_name)
        							{
        								$main .= '<h3>' . phoromatic_schedule_id_to_name($test_result_row['ScheduleID']) . '</h3><p>';
        								$printed_schedule_name = true;
        							}
        
        							$pcolor = $vari > 0 ? 'green' : 'red';
        
        							$main .= '<a href="?result/' . implode(',', $pprids) . '#' . $result_object->get_comparison_hash(true, false) . '"><span style="color: ' . $pcolor . ';"><strong>' . phoromatic_system_id_to_name($system_id) . ' - ' . $result_object->test_profile->get_title() . ':</strong> ' . implode(' &gt; ', $result_file->get_system_identifiers()) . ': ' . ($vari * 100) . '%</span></a><br />';
        						}
        					}
        				}
        			}
        			if($printed_schedule_name)
        				$main .= '</p>';
        		}
        		if($has_flagged_results)
        			$main .= '</span>';
        */
        // ACTIVE TEST SCHEDULES
        /*
        $main .= '<div style="float: left; width: 50%;"><ul><li><h1>Active Test Schedules</h1></li>';
        $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, Description, RunTargetSystems, RunTargetGroups, ActiveOn, RunAt 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
        	{
        		$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(phoromatic_results_for_schedule($row['ScheduleID']), 'Result') . '</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_main($main, phoromatic_webui_right_panel_logged_in());
        echo phoromatic_webui_footer();
    }
コード例 #4
0
 public static function generate_result_export_dump($account_id)
 {
     pts_file_io::mkdir(self::phoromatic_path() . 'result-export/');
     $export_path = self::phoromatic_path() . 'result-export/' . $account_id . '/';
     pts_file_io::mkdir($export_path);
     $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules WHERE AccountID = :account_id AND State = 1 AND (SELECT COUNT(*) FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = phoromatic_schedules.ScheduleID) > 0 AND (SELECT COUNT(*) FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = phoromatic_schedules.ScheduleID) > 4 ORDER BY Title ASC');
     $stmt->bindValue(':account_id', $account_id);
     $result = $stmt->execute();
     $exported_result_index = array('phoromatic' => array());
     while ($result && ($row = $result->fetchArray())) {
         $id = str_replace(' ', '-', strtolower($row['Title']));
         $triggers = array();
         $stmt2 = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
         $stmt2->bindValue(':account_id', $row['AccountID']);
         $stmt2->bindValue(':schedule_id', $row['ScheduleID']);
         $result2 = $stmt2->execute();
         pts_file_io::mkdir($export_path);
         while ($result2 && ($row2 = $result2->fetchArray())) {
             $composite_xml = phoromatic_server::phoromatic_account_result_path($row2['AccountID'], $row2['UploadID']) . 'composite.xml';
             if (is_file($composite_xml)) {
                 pts_file_io::mkdir($export_path . $id . '/' . $row2['Trigger']);
                 pts_file_io::mkdir($export_path . $id . '/' . $row2['Trigger'] . '/' . phoromatic_server::system_id_to_name($row2['SystemID'], $row2['AccountID']));
                 copy($composite_xml, $export_path . $id . '/' . $row2['Trigger'] . '/' . phoromatic_server::system_id_to_name($row2['SystemID'], $row2['AccountID']) . '/composite.xml');
             }
             pts_arrays::unique_push($triggers, $row2['Trigger']);
         }
         $exported_result_index['phoromatic'][$id] = array('title' => $row['Title'], 'id' => $id, 'description' => $row['Description'], 'triggers' => $triggers);
     }
     $exported_result_index = json_encode($exported_result_index, JSON_PRETTY_PRINT);
     file_put_contents($export_path . '/export-index.json', $exported_result_index);
 }
コード例 #5
0
 public function __construct()
 {
     $systems_already_reported = array();
     pts_client::fork(array('pts_phoromatic_event_server', 'ob_cache_run'), null);
     $is_first_run = true;
     while (true) {
         $hour = date('G');
         $minute = date('i');
         phoromatic_server::prepare_database();
         if ($is_first_run || $minute == 0) {
             if ($is_first_run || $hour == 8) {
                 pts_client::fork(array('pts_phoromatic_event_server', 'ob_cache_run'), null);
             }
             // Check for basic hung systems
             $stmt = phoromatic_server::$db->prepare('SELECT LastCommunication, CurrentTask, EstimatedTimeForTask, SystemID, AccountID, LastIP FROM phoromatic_systems WHERE State > 0 ORDER BY LastCommunication DESC');
             $result = $stmt ? $stmt->execute() : false;
             while ($result && ($row = $result->fetchArray())) {
                 $last_comm = strtotime($row['LastCommunication']);
                 if ($last_comm > time() - 3600) {
                     continue;
                 }
                 // if last comm time is less than an hour, still might be busy testing
                 if ($last_comm < time() - 3600 * 3 && !$is_first_run) {
                     continue;
                 }
                 // it's already been reported enough for now...
                 if (stripos($row['CurrentTask'], 'shutdown') !== false || stripos($row['CurrentTask'], 'shutting down') !== false) {
                     continue;
                 }
                 // if the system shutdown, no reason to report it
                 if (phoromatic_server::estimated_time_remaining_diff($row['EstimatedTimeForTask'], $row['LastCommunication']) > 0) {
                     continue;
                 }
                 // system task time didn't run out yet
                 // UPDATE SYSTEM STATUS TO "UNKNOWN"
                 $stmt_unknown = phoromatic_server::$db->prepare('UPDATE phoromatic_systems SET CurrentTask = :unknown_state WHERE AccountID = :account_id AND SystemID = :system_id');
                 $stmt_unknown->bindValue(':account_id', $row['AccountID']);
                 $stmt_unknown->bindValue(':system_id', $row['SystemID']);
                 $stmt_unknown->bindValue(':unknown_state', 'Unknown');
                 $stmt_unknown->execute();
                 $stmt_email = phoromatic_server::$db->prepare('SELECT UserName, Email FROM phoromatic_users WHERE UserID IN (SELECT UserID FROM phoromatic_user_settings WHERE AccountID = :account_id AND NotifyOnHungSystems = 1) AND AccountID = :account_id');
                 $stmt_email->bindValue(':account_id', $row['AccountID']);
                 $result_email = $stmt_email->execute();
                 while ($row_email = $result_email->fetchArray()) {
                     if (empty($row_email['Email'])) {
                         continue;
                     }
                     phoromatic_server::send_email($row_email['Email'], 'Phoromatic System Potential Hang: ' . phoromatic_server::system_id_to_name($row['SystemID'], $row['AccountID']), phoromatic_server::account_id_to_group_admin_email($row['AccountID']), '<p><strong>' . $row_email['UserName'] . ':</strong></p><p>One of the systems associated with your Phoromatic account has not been communicating with the Phoromatic Server in more than sixty minutes. Below is the system information details:</p><p><strong>System:</strong> ' . phoromatic_server::system_id_to_name($row['SystemID'], $row['AccountID']) . '<br /><strong>Last Communication:</strong> ' . phoromatic_server::user_friendly_timedate($row['LastCommunication']) . '<br /><strong>Last Task:</strong> ' . $row['CurrentTask'] . '<br /><strong>Local IP:</strong> ' . $row['LastIP'] . '</p>');
                 }
             }
         }
         if ($is_first_run || $minute % 2 == 0) {
             // Check for systems to wake
             $stmt = phoromatic_server::$db->prepare('SELECT LastCommunication, CurrentTask, SystemID, AccountID, NetworkMAC, LastIP, MaintenanceMode FROM phoromatic_systems WHERE State > 0 AND NetworkMAC NOT LIKE \'\' AND NetworkWakeOnLAN LIKE \'%g%\' ORDER BY LastCommunication DESC');
             $result = $stmt ? $stmt->execute() : false;
             while ($result && ($row = $result->fetchArray())) {
                 if (!isset($phoromatic_account_settings[$row['AccountID']])) {
                     $stmt1 = phoromatic_server::$db->prepare('SELECT NetworkPowerUpWhenNeeded, PowerOnSystemDaily FROM phoromatic_account_settings WHERE AccountID = :account_id');
                     $stmt1->bindValue(':account_id', $row['AccountID']);
                     $result1 = $stmt1->execute();
                     $phoromatic_account_settings[$row['AccountID']] = $result1->fetchArray(SQLITE3_ASSOC);
                 }
                 $last_comm = strtotime($row['LastCommunication']);
                 if ($last_comm < time() - 360 && $row['MaintenanceMode'] == 1) {
                     self::send_wol_wakeup($row['NetworkMAC'], $row['LastIP']);
                     continue;
                 }
                 if ($minute % 20 == 0 && $last_comm < time() - 3600 * 18 && $phoromatic_account_settings[$row['AccountID']]['PowerOnSystemDaily'] == 1) {
                     // Daily power on test if system hasn't communicated / powered on in a day
                     // XXX right now the "daily" power on test is 18 hours. change or make user value in future?
                     // Just doing this check every 20 minutes as not too vital
                     self::send_wol_wakeup($row['NetworkMAC'], $row['LastIP']);
                     continue;
                 }
                 if ($last_comm < time() - 600 || stripos($row['CurrentTask'], 'Shutdown') !== false) {
                     // System hasn't communicated in a number of minutes so it might be powered off
                     if (phoromatic_server::system_has_outstanding_jobs($row['AccountID'], $row['SystemID']) !== false) {
                         // Make sure account has network WoL enabled
                         if ($phoromatic_account_settings[$row['AccountID']]['NetworkPowerUpWhenNeeded'] == 1) {
                             self::send_wol_wakeup($row['NetworkMAC'], $row['LastIP']);
                         }
                     }
                 }
             }
         }
         if ($minute % 8 == 0 && $hour > 1) {
             // See if system appears down
             $stmt = phoromatic_server::$db->prepare('SELECT LastCommunication, CurrentTask, SystemID, AccountID, LastIP FROM phoromatic_systems WHERE State > 0 ORDER BY LastCommunication DESC');
             $result = $stmt ? $stmt->execute() : false;
             while ($result && ($row = $result->fetchArray())) {
                 $sys_hash = sha1($row['AccountID'] . $row['SystemID']);
                 // Avoid sending duplicate messages over time
                 if (isset($systems_already_reported[$sys_hash]) && $systems_already_reported[$sys_hash] > time() - 3600 * 24) {
                     continue;
                 }
                 if (phoromatic_server::system_check_if_down($row['AccountID'], $row['SystemID'], $row['LastCommunication'], $row['CurrentTask'])) {
                     if (strtotime($row['LastCommunication']) < time() - 86400 * 7) {
                         // If system hasn't been online in a week, likely has bigger worries...
                         continue;
                     }
                     $stmt_email = phoromatic_server::$db->prepare('SELECT UserName, Email FROM phoromatic_users WHERE UserID IN (SELECT UserID FROM phoromatic_user_settings WHERE AccountID = :account_id AND NotifyOnHungSystems = 1) AND AccountID = :account_id');
                     $stmt_email->bindValue(':account_id', $row['AccountID']);
                     $result_email = $stmt_email->execute();
                     while ($row_email = $result_email->fetchArray()) {
                         if (empty($row_email['Email'])) {
                             continue;
                         }
                         phoromatic_server::send_email($row_email['Email'], 'Phoromatic System Potential Problem: ' . phoromatic_server::system_id_to_name($row['SystemID'], $row['AccountID']), phoromatic_server::account_id_to_group_admin_email($row['AccountID']), '<p><strong>' . $row_email['UserName'] . ':</strong></p><p>One of the systems associated with your Phoromatic account has not been communicating with the Phoromatic Server and is part of a current active test schedule. Below is the system information details:</p><p><strong>System:</strong> ' . phoromatic_server::system_id_to_name($row['SystemID'], $row['AccountID']) . '<br /><strong>Last Communication:</strong> ' . phoromatic_server::user_friendly_timedate($row['LastCommunication']) . '<br /><strong>Last Task:</strong> ' . $row['CurrentTask'] . '<br /><strong>Local IP:</strong> ' . $row['LastIP'] . '</p>');
                     }
                     $systems_already_reported[$sys_hash] = time();
                 }
             }
         }
         phoromatic_server::close_database();
         sleep(60 - date('s') + 1);
         $is_first_run = false;
     }
 }
コード例 #6
0
/*
	Phoronix Test Suite
	URLs: http://www.phoronix.com, http://www.phoronix-test-suite.com/
	Copyright (C) 2015, Phoronix Media
	Copyright (C) 2015, Michael Larabel

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
$result_share_opt = phoromatic_server::read_setting('force_result_sharing') ? '1 = 1' : 'AccountID IN (SELECT AccountID FROM phoromatic_account_settings WHERE LetOtherGroupsViewResults = "1")';
$stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, PPRID, UploadTime, AccountID FROM phoromatic_results WHERE ' . $result_share_opt . ' OR AccountID = :account_id ORDER BY UploadTime DESC LIMIT 30');
$stmt->bindValue(':account_id', ACCOUNT_ID);
$result = $stmt->execute();
$results = array();
while ($row = $result->fetchArray()) {
    $results[$row['PPRID']] = array('Title' => $row['Title'], 'SystemName' => phoromatic_server::system_id_to_name($row['SystemID'], $row['AccountID']), 'UploadTime' => $row['UploadTime'], 'GroupName' => phoromatic_server::account_id_to_group_name($row['AccountID']));
}
$json['phoromatic']['results'] = $results;
$json['phoromatic']['response'] = 'results';
echo json_encode($json);
return;
コード例 #7
0
    public static function render_page_process($PATH)
    {
        echo phoromatic_webui_header_logged_in();
        $main = null;
        if (isset($PATH[0]) && !empty($PATH[0])) {
            ini_set('memory_limit', '4G');
            if (isset($_POST['view_results_from_past']) && is_numeric($_POST['view_results_from_past'])) {
                $cut_duration = $_POST['view_results_from_past'];
            } else {
                $cut_duration = 21;
            }
            $stmt = phoromatic_server::$db->prepare('SELECT UploadID, UploadTime, ScheduleID, Trigger, SystemID 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();
            $cutoff_time = is_numeric($cut_duration) ? strtotime('today -' . $cut_duration . ' days') : false;
            $show_only_latest_systems = array();
            $result_files = array();
            while ($test_result_result && ($row = $test_result_result->fetchArray())) {
                if ($cutoff_time !== false && strtotime($row['UploadTime']) < $cutoff_time) {
                    break;
                }
                $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 = phoromatic_server::system_id_to_name($row['SystemID']) . ': ' . $row['Trigger'];
                array_push($result_files, new pts_result_merge_select($composite_xml, null, $system_name));
                if (!isset($show_only_latest_systems[$_SESSION['AccountID'] . $row['SystemID']])) {
                    $show_only_latest_systems[$_SESSION['AccountID'] . $row['SystemID']] = new pts_result_merge_select($composite_xml, null, $system_name);
                }
            }
            if (count($result_files) < 21) {
                $show_only_latest_systems = null;
            }
            $attributes = array('new_result_file_title' => phoromatic_schedule_id_to_name($row['ScheduleID']));
            $result_file = new pts_result_file(null, true);
            $result_file->merge($result_files, $attributes);
            $extra_attributes = array('reverse_result_buffer' => true, 'force_simple_keys' => true, 'force_line_graph_compact' => true, 'force_tracking_line_graph' => true);
            if (isset($_POST['normalize_results']) && $_POST['normalize_results']) {
                $extra_attributes['normalize_result_buffer'] = true;
            }
            $main .= '<h1>' . $result_file->get_title() . '</h1>';
            if ($result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true))) {
                $table = new pts_ResultFileCompactSystemsTable($result_file, $intent);
            } else {
                $table = new pts_ResultFileSystemsTable($result_file);
            }
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $table = new pts_ResultFileTable($result_file, $intent);
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $main .= '<div id="pts_results_area">';
            foreach ($result_file->get_result_objects(isset($_POST['show_only_changed_results']) ? 'ONLY_CHANGED_RESULTS' : -1) as $i => $result_object) {
                $main .= '<h2><a name="r-' . $i . '"></a><a name="' . $result_object->get_comparison_hash(true, false) . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
                $main .= '<p class="result_object">';
                $main .= pts_render::render_graph_inline_embed($result_object, $result_file, $extra_attributes);
                $main .= '</p>';
            }
            $main .= '</div>';
            $right = '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_result_view" method="post">';
            $right .= '<p>Compare results for the past: ';
            $right .= '<select name="view_results_from_past" id="view_results_from_past">';
            $oldest_upload_time = strtotime(phoromatic_oldest_result_for_schedule($PATH[0]));
            $opts = array('Two Weeks' => 14, 'Three Weeks' => 21, 'One Month' => 30, 'Two Months' => 60, 'Quarter' => 90, 'Six Months' => 180, 'Year' => 365);
            foreach ($opts as $str_name => $time_offset) {
                if ($oldest_upload_time > time() - 86400 * $time_offset) {
                    break;
                }
                $right .= '<option value="' . $time_offset . '">' . $str_name . '</option>';
            }
            $right .= '<option value="all">All Results</option>';
            $right .= '</select>';
            $right .= '</p>';
            $right .= '<p><input type="checkbox" name="normalize_results" value="1" ' . (isset($_POST['normalize_results']) ? 'checked="checked" ' : null) . '/> Normalize Results?</p>';
            $right .= '<p><input type="submit" value="Refresh Results"></p></form>';
        } else {
            if (empty($PATH)) {
                $main .= '<h1>Phoromatic Tracker</h1>
					<p>The Phoromatic Tracker will show result schedules that have enough uploaded test results from the associated systems to begin providing concise overviews of performance over time.</p>
					<div class="pts_phoromatic_info_box_area">
					<ul>
						<li><h1>Trackable Results</h1></li>';
                $stmt = phoromatic_server::$db->prepare('SELECT Title, ScheduleID, Description, RunTargetSystems, RunTargetGroups, RunAt, ActiveOn, (SELECT COUNT(*) FROM phoromatic_results WHERE ScheduleID = phoromatic_schedules.ScheduleID) AS UploadedResultCount 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 Relevant Schedules Found</li>';
                } else {
                    do {
                        if ($row['UploadedResultCount'] > ($row['RunTargetSystems'] + $row['RunTargetGroups'] + 1) * 7) {
                            $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="?tracker/' . $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($row['UploadedResultCount'], 'Result') . ' Total</td></tr></table></li></a>';
                        }
                    } while ($row = $result->fetchArray());
                }
                $main .= '</ul>
			</div>';
                $right = null;
            }
        }
        echo phoromatic_webui_main($main, $right);
        echo phoromatic_webui_footer();
    }
コード例 #8
0
    public static function render_page_process($PATH)
    {
        if (PHOROMATIC_USER_IS_VIEWER) {
            return;
        }
        $is_new = true;
        if (!empty($PATH[0]) && $PATH[0] == 'all') {
            $main = '<h1>Past Benchmark Tickets</h1>';
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_benchmark_tickets WHERE AccountID = :account_id AND State >= 0 ORDER BY TicketIssueTime DESC');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $result = $stmt->execute();
            $main .= '<ol>';
            if ($result) {
                $row = $result->fetchArray();
                if (!empty($row)) {
                    do {
                        $main .= '<li><a href="?benchmark/' . $row['TicketID'] . '">' . $row['Title'] . '</a></li>';
                    } while ($row = $result->fetchArray());
                }
            } else {
                $main .= '<li>No Benchmark Tickets Found</li>';
            }
            $main .= '</ol>';
        } else {
            if (!empty($PATH[0]) && is_numeric($PATH[0])) {
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_benchmark_tickets WHERE AccountID = :account_id AND TicketID = :ticket_id');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':ticket_id', $PATH[0]);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if (!empty($row)) {
                    if (isset($_GET['remove'])) {
                        $stmt = phoromatic_server::$db->prepare('DELETE FROM phoromatic_benchmark_tickets WHERE AccountID = :account_id AND TicketID = :ticket_id');
                        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                        $stmt->bindValue(':ticket_id', $PATH[0]);
                        $result = $stmt->execute();
                        header('Location: /?benchmark');
                    } else {
                        if (isset($_GET['repeat'])) {
                            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_benchmark_tickets SET TicketIssueTime = :new_ticket_time, State = 1 WHERE AccountID = :account_id AND TicketID = :ticket_id');
                            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                            $stmt->bindValue(':ticket_id', $PATH[0]);
                            $stmt->bindValue(':new_ticket_time', time());
                            $result = $stmt->execute();
                        } else {
                            if (isset($_GET['disable'])) {
                                $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_benchmark_tickets SET State = 0 WHERE AccountID = :account_id AND TicketID = :ticket_id');
                                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                                $stmt->bindValue(':ticket_id', $PATH[0]);
                                $result = $stmt->execute();
                            }
                        }
                    }
                    $main = null;
                    $main .= '<h1>' . $row['Title'] . '</h1>';
                    $main .= '<h3>' . $row['Description'] . '</h3>';
                    $main .= '<p>This benchmark ticket was created on <strong>' . date('j F Y \\a\\t H:i', strtotime($row['LastModifiedOn'])) . '</strong> by <strong>' . $row['LastModifiedBy'] . '. The ticket was last issued for testing at ' . date('j F Y \\a\\t H:i', $row['TicketIssueTime']) . '</strong>.';
                    $main .= '<p> <a href="/?benchmark/' . $PATH[0] . '/&repeat">Repeat Ticket</a> &nbsp; &nbsp; &nbsp; <a href="/?benchmark/' . $PATH[0] . '/&remove">Remove Ticket</a>' . (!isset($_GET['disable']) && $row['State'] > 0 ? ' &nbsp; &nbsp; &nbsp; <a href="/?benchmark/' . $PATH[0] . '/&disable">End Ticket</a>' : null) . '</p>';
                    $main .= '<hr /><h1>System Targets</h1><ol>';
                    foreach (explode(',', $row['RunTargetSystems']) as $system_id) {
                        $main .= '<li><a href="?systems/' . $system_id . '">' . phoromatic_server::system_id_to_name($system_id) . '</a></li>';
                    }
                    $main .= '</ol>';
                    $main .= '<hr /><h1>Ticket Payload</h1>';
                    $main .= '<p>This ticket runs the <strong>' . $row['SuiteToRun'] . '</strong> test suite:</p>';
                    $main .= '<div style="max-height: 400px; overflow-y: scroll;">';
                    $xml_path = phoromatic_server::phoromatic_account_suite_path($_SESSION['AccountID'], $row['SuiteToRun']) . 'suite-definition.xml';
                    if (is_file($xml_path)) {
                        $test_suite = new pts_test_suite($xml_path);
                        //	$main .= '<h2>' . $test_suite->get_title() . '</h2>';
                        //	$main .= '<p><strong>' . $test_suite->get_maintainer() . '</strong></p>';
                        //	$main .= '<p><em>' . $test_suite->get_description() . '</em></p>';
                        foreach ($test_suite->get_contained_test_result_objects() as $tro) {
                            $main .= '<h3>' . $tro->test_profile->get_title() . ' [' . $tro->test_profile->get_identifier() . ']</h3>';
                            $main .= '<p>' . $tro->get_arguments_description() . '</p>';
                        }
                        //$main .= '<hr />';
                    }
                    $main .= '</div><hr />';
                    $main .= '<div class="pts_phoromatic_info_box_area">';
                    $main .= '<div style="margin: 0 5%;"><ul style="max-height: 100%;"><li><h1>Test Results</h1></li>';
                    $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID, ScheduleID, PPRID, UploadTime, TimesViewed FROM phoromatic_results WHERE AccountID = :account_id AND BenchmarkTicketID = :ticket_id ORDER BY UploadTime DESC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':ticket_id', $PATH[0]);
                    $test_result_result = $stmt->execute();
                    $results = 0;
                    while ($test_result_row = $test_result_result->fetchArray()) {
                        $main .= '<a onclick=""><li id="result_select_' . $test_result_row['PPRID'] . '"><input type="checkbox" id="result_compare_checkbox_' . $test_result_row['PPRID'] . '" onclick="javascript:phoromatic_checkbox_toggle_result_comparison(\'' . $test_result_row['PPRID'] . '\');" onchange="return false;"></input> <span onclick="javascript:phoromatic_window_redirect(\'?result/' . $test_result_row['PPRID'] . '\');">' . $test_result_row['Title'] . '</span><br /><table><tr><td>' . phoromatic_system_id_to_name($test_result_row['SystemID']) . '</td><td>' . phoromatic_user_friendly_timedate($test_result_row['UploadTime']) . '</td><td>' . $test_result_row['TimesViewed'] . ' Times Viewed</td></table></li></a>';
                        $results++;
                    }
                    if ($results == 0) {
                        $main .= '<li class="light" style="text-align: center;">No Results Found</li>';
                    } else {
                        if ($results > 3) {
                            $main .= '<a onclick=""><li id="global_bottom_totals"><input type="checkbox" id="global_checkbox" onclick="javascript:phoromatic_toggle_checkboxes_on_page(this);" onchange="return false;"></input> <strong>' . $results . ' Results</strong></li></a>';
                        }
                    }
                    $main .= '</ul></div>';
                    $main .= '</div>';
                }
            } else {
                if (isset($_POST['benchmark_title']) && !empty($_POST['benchmark_title'])) {
                    $title = phoromatic_get_posted_var('benchmark_title');
                    $description = phoromatic_get_posted_var('benchmark_description');
                    $result_identifier = phoromatic_get_posted_var('benchmark_identifier');
                    $suite_to_run = phoromatic_get_posted_var('suite_to_run');
                    if (strlen($title) < 3) {
                        echo '<h2>Title must be at least three characters.</h2>';
                        exit;
                    }
                    if (strlen($result_identifier) < 3) {
                        echo '<h2>Identifier must be at least three characters.</h2>';
                        exit;
                    }
                    if (strlen($suite_to_run) < 3) {
                        echo '<h2>You must specify a suite to run.</h2>';
                        exit;
                    }
                    $run_target_systems = phoromatic_get_posted_var('run_on_systems', array());
                    $run_target_groups = phoromatic_get_posted_var('run_on_groups', array());
                    if (!is_array($run_target_systems)) {
                        $run_target_systems = array();
                    }
                    if (!is_array($run_target_groups)) {
                        $run_target_groups = array();
                    }
                    $run_target_systems = implode(',', $run_target_systems);
                    $run_target_groups = implode(',', $run_target_groups);
                    if ($is_new) {
                        do {
                            $ticket_id = rand(10, 999999);
                            $matching_tickets = phoromatic_server::$db->querySingle('SELECT TicketID FROM phoromatic_benchmark_tickets WHERE TicketID = \'' . $ticket_id . '\'');
                        } while (!empty($matching_tickets));
                    }
                    $env_vars = array();
                    if (is_numeric($_POST['PTS_CONCURRENT_TEST_RUNS']) && $_POST['PTS_CONCURRENT_TEST_RUNS'] > 0) {
                        array_push($env_vars, 'PTS_CONCURRENT_TEST_RUNS=' . $_POST['PTS_CONCURRENT_TEST_RUNS']);
                    }
                    if (is_numeric($_POST['TOTAL_LOOP_TIME']) && $_POST['TOTAL_LOOP_TIME'] > 0) {
                        array_push($env_vars, 'TOTAL_LOOP_TIME=' . $_POST['TOTAL_LOOP_TIME']);
                    }
                    $env_vars = implode(';', $env_vars);
                    // Add benchmark
                    $stmt = phoromatic_server::$db->prepare('INSERT OR REPLACE INTO phoromatic_benchmark_tickets (AccountID, TicketID, TicketIssueTime, Title, ResultIdentifier, SuiteToRun, Description, State, LastModifiedBy, LastModifiedOn, RunTargetGroups, RunTargetSystems, EnvironmentVariables) VALUES (:account_id, :ticket_id, :ticket_time, :title, :result_identifier, :suite_to_run, :description, :state, :modified_by, :modified_on, :run_target_groups, :run_target_systems, :environment_variables)');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':ticket_id', $ticket_id);
                    $stmt->bindValue(':ticket_time', time());
                    $stmt->bindValue(':title', $title);
                    $stmt->bindValue(':result_identifier', $result_identifier);
                    $stmt->bindValue(':suite_to_run', $suite_to_run);
                    $stmt->bindValue(':description', $description);
                    $stmt->bindValue(':state', 1);
                    $stmt->bindValue(':modified_by', $_SESSION['UserName']);
                    $stmt->bindValue(':modified_on', phoromatic_server::current_time());
                    $stmt->bindValue(':public_key', $public_key);
                    $stmt->bindValue(':run_target_groups', $run_target_groups);
                    $stmt->bindValue(':run_target_systems', $run_target_systems);
                    $stmt->bindValue(':environment_variables', $env_vars);
                    $result = $stmt->execute();
                    phoromatic_add_activity_stream_event('benchmark', $benchmark_id, $is_new ? 'added' : 'modified');
                    if ($result) {
                        header('Location: ?benchmark/' . $schedule_id);
                    }
                }
                $main = '
			<h2>' . ($is_new ? 'Create' : 'Edit') . ' A Benchmark</h2>
			<p>This page allows you to run a test suite -- consisting of a single or multiple test suites -- on a given set/group of systems right away at their next earliest possibility. This benchmark mode is an alternative to the <a href="?schedules">benchmark schedules</a> for reptitive/routine testing.</p>';
                $local_suites = pts_file_io::glob(phoromatic_server::phoromatic_account_suite_path($_SESSION['AccountID']) . '*/suite-definition.xml');
                if (empty($local_suites)) {
                    $main .= '<p><strong>Before you can create a benchmark ticket you must first <a href="?build_suite">create a test suite</a> with the tests you wish to run.</strong></p>';
                } else {
                    $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="run_benchmark" id="run_benchmark" method="post" enctype="multipart/form-data" onsubmit="return validate_run_benchmark();">
				<h3>Title:</h3>
				<p>The title is the name of the result file for this test run.</p>
				<p><input type="text" name="benchmark_title" value="' . (!$is_new ? $e_schedule['Title'] : null) . '" /></p>
				<h3>Test Run Identifier:</h3>
				<p>The test run identifier is the per-system name for the system(s) being benchmarked. The following variables may be used: <strong>.SYSTEM</strong>, <strong>.GROUP</strong>. Any custom per-user system variables set via the individual system pages can also be used.</p>
				<p><input type="text" name="benchmark_identifier" value="' . (!$is_new ? $e_schedule['Identifier'] : null) . '" /></p>
				<h3>Test Suite To Run:</h3>
				<p><a href="?build_suite">Build a suite</a> to add/select more tests to run or <a href="?local_suites">view local suites</a> for more information on a particular suite. A test suite is a set of test profiles to run in a pre-defined manner.</p>';
                    $main .= '<p><select name="suite_to_run">';
                    foreach ($local_suites as $xml_path) {
                        $id = basename(dirname($xml_path));
                        $test_suite = new pts_test_suite($xml_path);
                        $main .= '<option value="' . $id . '">' . $test_suite->get_title() . ' - ' . $id . '</option>';
                    }
                    $main .= '</select></p>';
                    $main .= '<h3>Description:</h3>
				<p>The description is an optional way to add more details about the intent or objective of this test run.</p>
				<p><textarea name="benchmark_description" id="benchmark_description" cols="50" rows="3">' . (!$is_new ? $e_schedule['Description'] : null) . '</textarea></p>
				<hr /><h3>System Targets:</h3>
				<p>Select the systems that should be benchmarked at their next earliest convenience.</p>
				<p style="white-space: nowrap;">';
                    $stmt = phoromatic_server::$db->prepare('SELECT Title, SystemID FROM phoromatic_systems WHERE AccountID = :account_id AND State >= 0 ORDER BY Title ASC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $result = $stmt->execute();
                    if (!$is_new) {
                        $e_schedule['RunTargetSystems'] = explode(',', $e_schedule['RunTargetSystems']);
                        $e_schedule['RunTargetGroups'] = explode(',', $e_schedule['RunTargetGroups']);
                    }
                    if ($row = $result->fetchArray()) {
                        $main .= '<h4>Systems: ';
                        do {
                            $main .= '<input type="checkbox" name="run_on_systems[]" value="' . $row['SystemID'] . '" ' . (!$is_new && in_array($row['SystemID'], $e_schedule['RunTargetSystems']) ? 'checked="checked" ' : null) . '/> ' . $row['Title'] . ' ';
                        } while ($row = $result->fetchArray());
                        $main .= '</h4>';
                    }
                    $stmt = phoromatic_server::$db->prepare('SELECT GroupName FROM phoromatic_groups WHERE AccountID = :account_id ORDER BY GroupName ASC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $result = $stmt->execute();
                    if ($row = $result->fetchArray()) {
                        $main .= '<h4>Groups: ';
                        do {
                            $main .= '<input type="checkbox" name="run_on_groups[]" value="' . $row['GroupName'] . '" ' . (!$is_new && in_array($row['GroupName'], $e_schedule['RunTargetGroups']) ? 'checked="checked" ' : null) . '/> ' . $row['GroupName'] . ' ';
                        } while ($row = $result->fetchArray());
                        $main .= '</h4>';
                    }
                    $main .= '</p>
				<hr /><h3>Environment Options</h3>
				<h4>Stress Testing</h4>
				<p>If you wish to test systems for stability/reliability rather than performance, use this option and specify the number of tests to run concurrently (two or more) and (optionally) for the total period of time to continue looping the benchmarks. These options are intended to just stress the system and will not record any benchmark results. From the command-line this testing mode can be used via the <em>phoronix-test-suite stress-run</em> sub-command.</p>
				<p><strong>Concurrent Number Of Test Processes:</strong> <select name="PTS_CONCURRENT_TEST_RUNS"><option value="0">Disabled</option>';
                    for ($i = 2; $i <= 24; $i++) {
                        $main .= '<option value="' . $i . '">' . $i . '</option>';
                    }
                    $main .= '</select></p>
				<p><strong>Force Loop Time:</strong> <select name="TOTAL_LOOP_TIME"><option value="0">Disabled</option>';
                    $s = true;
                    for ($i = 60; $i <= 60 * 24 * 90; $i += 60) {
                        if ($i > 10080) {
                            // 7 days
                            if ($i % 1440 != 0) {
                                continue;
                            }
                        } else {
                            if ($i > 480) {
                                $s = !$s;
                                if (!$s) {
                                    continue;
                                }
                            }
                        }
                        $main .= '<option value="' . $i . '">' . pts_strings::format_time($i, 'MINUTES') . '</option>';
                    }
                    $main .= '</select></p>

				<h4>System Monitoring</h4>
				<p>The Phoronix Test Suite system monitor module allows for select hardware/software sensors to be logged in real-time while running the selected test suite. The supported sensors are then shown within the result file upon the test\'s completion.</p>';
                    foreach (phodevi::available_sensors() as $sensor) {
                        $main .= '<input type="checkbox" name="MONITOR" value="' . phodevi::sensor_identifier($sensor) . '" /> ' . phodevi::sensor_name($sensor) . ' &nbsp; ';
                    }
                    $main .= '<hr /><p align="left"><input name="submit" value="' . ($is_new ? 'Run' : 'Edit') . ' Benchmark" type="submit" onclick="return pts_rmm_validate_schedule();" /></p>
					</form>';
                }
            }
        }
        $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_benchmark_tickets WHERE AccountID = :account_id AND State >= 0 AND TicketIssueTime > :time_cutoff ORDER BY TicketIssueTime DESC LIMIT 30');
        $stmt->bindValue(':account_id', $_SESSION['AccountID']);
        $stmt->bindValue(':time_cutoff', time() - 60 * 60 * 24 * 14);
        $result = $stmt->execute();
        $right = '<ul><li>Benchmark Tickets</li>';
        if ($result) {
            $row = $result->fetchArray();
            if (!empty($row)) {
                do {
                    $right .= '<li><a href="?benchmark/' . $row['TicketID'] . '">' . $row['Title'] . '</a></li>';
                } while ($row = $result->fetchArray());
            }
        }
        $right .= '<li><em><a href="?benchmark/all">View All Past Tickets</a></em></li>';
        $right .= '</ul>';
        echo phoromatic_webui_header_logged_in();
        echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in($right));
        echo phoromatic_webui_footer();
    }