5 URLs: http://www.phoronix.com, http://www.phoronix-test-suite.com/
6 Copyright (C) 2009 - 2015, Phoronix Media
7 Copyright (C) 2009 - 2015, Michael Larabel
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 class pts_test_run_manager
25 public $result_file = null;
26 private $is_new_result_file = true;
28 private $tests_to_run = array();
29 private $failed_tests_to_run = array();
30 private $last_test_run_index = 0;
31 private $test_run_pos = 0;
32 private $test_run_count = 0;
34 private $file_name = null;
35 private $file_name_title = null;
36 private $results_identifier = null;
37 private $run_description = null;
39 private $force_save_results = false;
40 private $prompt_save_results = true;
41 private $post_run_message = null;
42 private $pre_run_message = null;
43 private $allow_sharing_of_results = true;
44 private $auto_upload_to_openbenchmarking = false;
45 private $is_pcqs = false;
46 private $openbenchmarking_results_data = false;
48 private $do_dynamic_run_count = false;
49 private $dynamic_run_count_on_length_or_less;
50 private $dynamic_run_count_std_deviation_threshold;
51 private $dynamic_run_count_export_script;
52 private $multi_test_stress_run = false;
54 private static $test_run_process_active = false;
55 private $batch_mode = false;
56 private $auto_mode = false;
58 public function __construct($batch_mode = false, $auto_mode = false)
60 $this->do_dynamic_run_count
= pts_config
::read_bool_config('PhoronixTestSuite/Options/TestResultValidation/DynamicRunCount', 'TRUE');
61 $this->dynamic_run_count_on_length_or_less
= pts_config
::read_user_config('PhoronixTestSuite/Options/TestResultValidation/LimitDynamicToTestLength', 20);
62 $this->dynamic_run_count_std_deviation_threshold
= pts_config
::read_user_config('PhoronixTestSuite/Options/TestResultValidation/StandardDeviationThreshold', 3.50);
63 $this->dynamic_run_count_export_script
= pts_config
::read_user_config('PhoronixTestSuite/Options/TestResultValidation/ExportResultsTo', null);
67 $this->set_batch_mode($batch_mode);
70 // 1/true is normal auto mode, 2 = auto + default benchmark mode
71 $this->auto_mode
= $auto_mode;
73 pts_module_manager
::module_process('__run_manager_setup', $this);
75 public function is_pcqs()
77 return $this->is_pcqs
;
79 public function do_dynamic_run_count()
81 return $this->do_dynamic_run_count
;
83 public function disable_dynamic_run_count()
85 $this->do_dynamic_run_count
= false;
87 public function auto_upload_to_openbenchmarking($do = true)
89 $this->auto_upload_to_openbenchmarking
= ($do == true);
91 public function increase_run_count_check(&$active_result_buffer, $scheduled_times_to_run, $latest_test_run_time)
93 // First make sure this test doesn't take too long to run where we don't want dynamic handling
94 if(floor($latest_test_run_time / 60) > $this->dynamic_run_count_on_length_or_less
)
99 // Determine if results are statistically significant, otherwise up the run count
100 $std_dev = pts_math
::percent_standard_deviation($active_result_buffer->results
);
101 if($std_dev >= $this->dynamic_run_count_std_deviation_threshold
)
103 static $last_run_count = 128; // just a number that should always cause the first check below to be true
104 static $run_std_devs;
105 $times_already_ran = $active_result_buffer->get_trial_run_count();
107 if($times_already_ran <= $last_run_count)
109 // We're now onto a new test so clear out the array
110 $run_std_devs = array();
112 $last_run_count = $times_already_ran;
113 $run_std_devs[$last_run_count] = $std_dev;
115 // If we haven't reached scheduled times to run x 2, increase count straight away
116 if($times_already_ran < ($scheduled_times_to_run * 2))
120 else if($times_already_ran < ($scheduled_times_to_run * 3))
122 // More aggressive determination whether to still keep increasing the run count
123 $first_and_now_diff = pts_arrays
::first_element($run_std_devs) - pts_arrays
::last_element($run_std_devs);
125 // Increasing the run count at least looks to be helping...
126 if($first_and_now_diff > (pts_arrays
::first_element($run_std_devs) / 2))
128 // If we are at least making progress in the right direction, increase the run count some more
132 // TODO: could add more checks and take better advantage of the array of data to better determine if it's still worth increasing
137 // Check to see if there is an external/custom script to export the results to in determining whether results are valid
138 if(($ex_file = $this->dynamic_run_count_export_script
) != null && is_executable($ex_file) ||
is_executable(($ex_file = PTS_USER_PATH
. $this->dynamic_run_count_export_script
)))
140 $exit_status = trim(shell_exec($ex_file . ' ' . $active_result_buffer->get_values_as_string() . ' > /dev/null 2>&1; echo $?'));
145 // Run the test again
148 // Results are bad, abandon testing and do not record results
152 // Return was 0 or something else, results are valid, or was some other exit status
157 // No reason to increase the run count with none of the previous checks requesting otherwise
160 protected function add_test_result_object(&$test_result)
162 if($this->validate_test_to_run($test_result->test_profile
))
164 pts_arrays
::unique_push($this->tests_to_run
, $test_result);
167 public function get_tests_to_run()
169 return $this->tests_to_run
;
171 public function get_tests_to_run_identifiers()
173 $identifiers = array();
175 foreach($this->tests_to_run
as $test_run_request)
177 array_push($identifiers, $test_run_request->test_profile
->get_identifier());
180 array_unique($identifiers);
184 public function get_estimated_run_time($index = -1)
188 $index = $this->last_test_run_index
;
192 for($i = $index; $i < count($this->tests_to_run
); $i++
)
194 $estimated_time +
= $this->tests_to_run
[$i]->test_profile
->get_estimated_run_time();
197 return $estimated_time;
199 public function get_percent_complete()
201 return round($this->last_test_run_index
/ count($this->tests_to_run
) * 100);
203 public function get_test_to_run($index)
205 $this->last_test_run_index
= $index;
206 return is_numeric($index) && isset($this->tests_to_run
[$index]) ?
$this->tests_to_run
[$index] : false;
208 public function get_test_count()
210 return count($this->tests_to_run
);
212 public function force_results_save()
214 $this->force_save_results
= true;
216 protected function do_save_results()
218 return $this->file_name
!= null;
220 public function get_file_name()
222 return $this->file_name
;
224 public function get_title()
226 return $this->file_name_title
;
228 public function get_results_identifier()
230 return $this->results_identifier
;
232 public function get_description()
234 return $this->run_description
;
236 public function get_notes()
238 return null; // TODO: Not Yet Implemented
240 public function get_internal_tags()
244 public function get_reference_id()
248 public function get_preset_environment_variables()
250 return pts_module_manager
::var_store_string();
252 public function result_already_contains_identifier()
254 if($this->result_file
)
256 foreach($this->result_file
->get_systems() as $s)
258 if($s->get_identifier() == $this->results_identifier
)
267 public function set_save_name($save_name, $is_new_save = true)
269 if(empty($save_name))
271 $save_name = date('Y-m-d-Hi');
274 $this->file_name
= self
::clean_save_name($save_name, $is_new_save);
275 $this->file_name_title
= $save_name;
276 $this->force_save_results
= true;
277 $this->result_file
= new pts_result_file($this->file_name
);
278 $this->is_new_result_file
= $this->result_file
->get_system_count() == 0;
280 public function set_results_identifier($identifier)
282 $this->results_identifier
= self
::clean_results_identifier($identifier);
284 public function prompt_save_name()
286 if($this->file_name
!= null)
291 // Prompt to save a file when running a test
294 if(($env = pts_client
::read_env('TEST_RESULTS_NAME')))
297 //echo 'Saving Results To: ' . $proposed_name . PHP_EOL;
300 if(!$this->batch_mode ||
$this->batch_mode
['PromptSaveName'])
302 $is_reserved_word = false;
303 // Be of help to the user by showing recently saved test results
304 if($save_name == null)
306 pts_tests
::recently_saved_results();
309 $save_name_length = strlen($save_name);
310 while(empty($save_name) ||
($is_reserved_word = pts_types
::is_test_or_suite($save_name)) ||
$save_name_length > 126)
312 if($is_reserved_word)
314 echo PHP_EOL
. 'The name of the saved file cannot be the same as a test/suite: ' . $save_name . PHP_EOL
;
315 $is_reserved_word = false;
317 if($save_name_length > 126)
319 echo PHP_EOL
. 'The name of the saved file must have between 2 and 126 characters in length.' . PHP_EOL
;
322 pts_client
::$display->generic_prompt('Enter a name to save these results under: ');
323 $save_name = pts_user_io
::read_user_input();
327 $this->set_save_name($save_name);
329 public function prompt_results_identifier()
331 // Prompt for a results identifier
332 $results_identifier = null;
333 $show_identifiers = array();
334 $no_repeated_tests = true;
336 if(!$this->is_new_result_file
)
338 // Running on an already-saved result
339 $current_identifiers = array();
340 $current_hardware = array();
341 $current_software = array();
343 foreach($this->result_file
->get_systems() as $s)
345 array_push($current_hardware, $s->get_hardware());
346 array_push($current_software, $s->get_software());
347 array_push($current_identifiers, $s->get_identifier());
351 foreach($this->result_file
->get_result_objects() as $result)
353 array_push($hashes, $result->get_comparison_hash(false, false));
355 foreach($this->tests_to_run
as &$run_request)
357 if($run_request instanceof pts_test_result
&& in_array($run_request->get_comparison_hash(false, false), $hashes))
359 $no_repeated_tests = false;
367 $current_identifiers = array();
368 $current_hardware = array();
369 $current_software = array();
372 if((!$this->batch_mode ||
$this->batch_mode
['PromptForTestIdentifier']) && !$this->auto_mode
)
374 if(count($current_identifiers) > 0)
376 echo PHP_EOL
. 'Current Test Identifiers:' . PHP_EOL
;
377 echo pts_user_io
::display_text_list($current_identifiers);
384 if($times_tried == 0 && ($env_identifier = pts_client
::read_env('TEST_RESULTS_IDENTIFIER')))
386 $results_identifier = isset($env_identifier) ? self
::clean_results_identifier($env_identifier) : null;
387 echo 'Test Identifier: ' . $results_identifier . PHP_EOL
;
391 pts_client
::$display->generic_prompt('Enter a unique name to describe this test run / configuration: ');
392 $results_identifier = self
::clean_results_identifier(pts_user_io
::read_user_input());
396 $identifier_pos = (($p = array_search($results_identifier, $current_identifiers)) !== false ?
$p : -1);
398 while((!$no_repeated_tests && $identifier_pos != -1) ||
(isset($current_hardware[$identifier_pos]) && $current_hardware[$identifier_pos] != phodevi
::system_hardware(true)) ||
(isset($current_software[$identifier_pos]) && $current_software[$identifier_pos] != phodevi
::system_software(true)));
400 else if(($env_identifier = pts_client
::read_env('TEST_RESULTS_IDENTIFIER')))
402 $results_identifier = self
::clean_results_identifier($env_identifier);
406 if(empty($results_identifier))
408 $results_identifier = $this->auto_generate_results_identifier();
411 $this->results_identifier
= $results_identifier;
413 public function auto_generate_results_identifier()
415 // If the save result identifier is empty, try to come up with something based upon the tests being run.
416 $results_identifier = null;
417 $subsystem_r = array();
418 $subsystems_to_test = $this->subsystems_under_test();
420 if(!$this->is_new_result_file
)
422 $result_file_intent = pts_result_file_analyzer
::analyze_result_file_intent($this->result_file
);
424 if(is_array($result_file_intent) && $result_file_intent[0] != 'Unknown')
426 array_unshift($subsystems_to_test, $result_file_intent[0]);
430 foreach($subsystems_to_test as $subsystem)
432 $components = pts_result_file_analyzer
::system_component_string_to_array(phodevi
::system_hardware(true) . ', ' . phodevi
::system_software(true));
433 if($subsystem != null && isset($components[$subsystem]))
435 $subsystem_name = pts_strings
::trim_search_query($components[$subsystem]);
437 if(phodevi
::is_vendor_string($subsystem_name) && !in_array($subsystem_name, $subsystem_r))
439 array_push($subsystem_r, $subsystem_name);
441 if(isset($subsystem_r[2]) ||
isset($subsystem_name[19]))
448 if(isset($subsystem_r[0]))
450 $results_identifier = implode(' - ', $subsystem_r);
453 if(empty($results_identifier) && !$this->batch_mode
)
455 $results_identifier = phodevi
::read_property('cpu', 'model') . ' - ' . phodevi
::read_property('gpu', 'model') . ' - ' . phodevi
::read_property('motherboard', 'identifier');
458 if(strlen($results_identifier) > 55)
460 $results_identifier = substr($results_identifier, 0, 54);
461 $results_identifier = substr($results_identifier, 0, strrpos($results_identifier, ' '));
464 if(empty($results_identifier))
466 $results_identifier = date('Y-m-d H:i');
469 $this->results_identifier
= $results_identifier;
471 return $results_identifier;
473 public static function clean_results_identifier($results_identifier)
475 $results_identifier = trim(pts_client
::swap_variables($results_identifier, array('pts_client', 'user_run_save_variables')));
476 $results_identifier = pts_strings
::remove_redundant(pts_strings
::keep_in_string($results_identifier, pts_strings
::CHAR_LETTER | pts_strings
::CHAR_NUMERIC | pts_strings
::CHAR_DASH | pts_strings
::CHAR_UNDERSCORE | pts_strings
::CHAR_COLON | pts_strings
::CHAR_COMMA | pts_strings
::CHAR_SLASH | pts_strings
::CHAR_SPACE | pts_strings
::CHAR_DECIMAL | pts_strings
::CHAR_AT | pts_strings
::CHAR_PLUS | pts_strings
::CHAR_SEMICOLON | pts_strings
::CHAR_EQUAL
), ' ');
478 return $results_identifier;
480 public function get_test_run_position()
482 return $this->test_run_pos +
1;
484 public function get_test_run_count_reported()
486 return $this->test_run_count
;
488 public function call_test_runs()
491 $lock_path = pts_client
::temporary_directory() . '/phoronix-test-suite.active';
492 pts_client
::create_lock($lock_path);
494 if($this->pre_run_message
!= null)
496 pts_client
::$display->display_interrupt_message($this->pre_run_message
);
499 // Hook into the module framework
500 self
::$test_run_process_active = true;
501 pts_module_manager
::module_process('__pre_run_process', $this);
502 pts_file_io
::unlink(PTS_USER_PATH
. 'halt-testing');
503 pts_file_io
::unlink(PTS_USER_PATH
. 'skip-test');
505 $continue_test_flag = true;
506 $tests_to_run_count = $this->get_test_count();
507 pts_client
::$display->test_run_process_start($this);
509 $total_loop_count = (($t = pts_client
::read_env('TOTAL_LOOP_COUNT')) && is_numeric($t) && $t > 0) ?
$t : 1;
510 $total_loop_time = (($t = pts_client
::read_env('TOTAL_LOOP_TIME')) && is_numeric($t) && $t > 9) ?
($t * 60) : -1;
511 $loop_end_time = $total_loop_time != -1 ?
(time() +
$total_loop_time) : false;
512 $this->test_run_count
= ($tests_to_run_count * $total_loop_count);
514 for($loop = 1; $loop <= $total_loop_count && $continue_test_flag; $loop++
)
516 for($i = 0; $i < $tests_to_run_count && $continue_test_flag; $i++
)
518 $this->test_run_pos
= $i;
519 $continue_test_flag = $this->process_test_run_request($i);
521 if(pts_config
::read_bool_config('PhoronixTestSuite/Options/Testing/RemoveTestInstallOnCompletion', 'FALSE'))
523 // Remove the installed test if it's no longer needed in this run queue
524 $this_test_profile_identifier = $this->get_test_to_run($this->test_run_pos
)->test_profile
->get_identifier();
525 $still_in_queue = false;
527 for($j = ($this->test_run_pos +
1); $j < $tests_to_run_count && $still_in_queue == false; $j++
)
529 if($this->get_test_to_run($j)->test_profile
->get_identifier() == $this_test_profile_identifier)
531 $still_in_queue = true;
535 if($still_in_queue == false)
537 pts_client
::remove_installed_test($this->get_test_to_run($this->test_run_pos
)->test_profile
);
543 if(time() > $loop_end_time)
545 $continue_test_flag = false;
547 else if($this->test_run_count
== ($i +
1))
549 // There's still time remaining so increase the run count....
550 $this->test_run_count +
= $tests_to_run_count;
556 pts_file_io
::unlink(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/active.xml');
558 foreach($this->tests_to_run
as &$run_request)
560 // Remove cache shares
561 foreach(pts_file_io
::glob($run_request->test_profile
->get_install_dir() . 'cache-share-*.pt2so') as $cache_share_file)
563 unlink($cache_share_file);
567 if($this->post_run_message
!= null)
569 pts_client
::$display->display_interrupt_message($this->post_run_message
);
572 self
::$test_run_process_active = -1;
573 pts_module_manager
::module_process('__post_run_process', $this);
574 pts_client
::release_lock($lock_path);
576 // Report any tests that failed to properly run
577 if(pts_client
::is_debug_mode() ||
$this->get_test_count() > 3)
579 if(count($this->failed_tests_to_run
) > 0)
581 echo PHP_EOL
. PHP_EOL
. 'The following tests failed to properly run:' . PHP_EOL
. PHP_EOL
;
582 foreach($this->failed_tests_to_run
as &$run_request)
584 echo "\t- " . $run_request->test_profile
->get_identifier() . ($run_request->get_arguments_description() != null ?
': ' . $run_request->get_arguments_description() : null) . PHP_EOL
;
590 public static function test_run_process_active()
592 return self
::$test_run_process_active = true;
594 public function process_test_run_request($run_index)
598 if($this->result_file
&& $this->result_file
->get_test_count() > 0)
600 $this->result_file
->get_xml(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/composite.xml');
603 if(is_object($run_index))
605 $test_run_request = $run_index;
610 $test_run_request = $this->get_test_to_run($run_index);
613 if(($run_index != 0 && count(pts_file_io
::glob($test_run_request->test_profile
->get_install_dir() . 'cache-share-*.pt2so')) == 0))
615 // Sleep for six seconds between tests by default
619 if($test_run_request == false)
624 $active_result_buffer = pts_test_execution
::run_test($this, $test_run_request);
626 if(pts_file_io
::unlink(PTS_USER_PATH
. 'halt-testing'))
628 // Stop the testing process entirely
631 else if(pts_file_io
::unlink(PTS_USER_PATH
. 'skip-test'))
633 // Just skip the current test and do not save the results, but continue testing
636 else if(pts_client
::read_env('LIMIT_ELAPSED_TEST_TIME') > 0 && (PTS_INIT_TIME +
(pts_client
::read_env('LIMIT_ELAPSED_TEST_TIME') * 60)) > time())
638 // Allocated amount of time has expired
642 $test_successful = false;
643 if($test_run_request->test_profile
->get_display_format() == 'NO_RESULT')
645 $test_successful = true;
647 else if($test_run_request instanceof pts_test_result
)
649 $end_result = $test_run_request->active
->get_result();
651 // removed count($result) > 0 in the move to pts_test_result
652 if(count($test_run_request) > 0 && ((is_numeric($end_result) && $end_result > 0) ||
(!is_numeric($end_result) && isset($end_result[3]))))
654 pts_module_manager
::module_process('__post_test_run_success', $test_run_request);
655 $test_identifier = $this->get_results_identifier();
656 $test_successful = true;
658 if(!empty($test_identifier))
660 $test_run_request->test_result_buffer
= new pts_test_result_buffer();
661 $test_run_request->test_result_buffer
->add_test_result($this->results_identifier
, $test_run_request->active
->get_result(), $active_result_buffer->get_values_as_string(), self
::process_json_report_attributes($test_run_request), $test_run_request->active
->get_min_result(), $test_run_request->active
->get_max_result());
662 $this->result_file
->add_result($test_run_request);
664 if($test_run_request->secondary_linked_results
!= null && is_array($test_run_request->secondary_linked_results
))
666 foreach($test_run_request->secondary_linked_results
as &$run_request_minor)
668 if(strpos($run_request_minor->get_arguments_description(), $test_run_request->get_arguments_description()) === false)
670 $run_request_minor->set_used_arguments_description($test_run_request->get_arguments_description() . ' - ' . $run_request_minor->get_arguments_description());
671 $run_request_minor->set_used_arguments($test_run_request->get_arguments() . ' - ' . $run_request_minor->get_arguments_description());
674 $test_run_request->test_result_buffer
->add_test_result($this->results_identifier
, $run_request_minor->active
->get_result(), $run_request_minor->active
->get_values_as_string(), self
::process_json_report_attributes($test_run_request),$run_request_minor->active
->get_min_result(), $run_request_minor->active
->get_max_result());
675 $this->result_file
->add_result($test_run_request);
679 if($this->get_results_identifier() != null && $this->get_file_name() != null && pts_config
::read_bool_config('PhoronixTestSuite/Options/Testing/SaveTestLogs', 'FALSE'))
681 static $xml_write_pos = 1;
682 pts_file_io
::mkdir(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/' . $xml_write_pos . '/');
684 if(is_dir(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier()))
686 $test_log_write_dir = PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/' . $xml_write_pos . '/' . $this->get_results_identifier() . '/';
688 if(is_dir($test_log_write_dir))
690 pts_file_io
::delete($test_log_write_dir, null, true);
693 rename(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier() . '/', $test_log_write_dir);
700 pts_file_io
::unlink(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/active/');
703 if($test_successful == false && $test_run_request->test_profile
->get_identifier() != null)
705 array_push($this->failed_tests_to_run
, $test_run_request);
707 // For now delete the failed test log files, but it may be a good idea to keep them
708 pts_file_io
::delete(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/active/' . $this->get_results_identifier() . '/', null, true);
711 pts_module_manager
::module_process('__post_test_run_process', $this->result_file
);
715 protected static function process_json_report_attributes(&$test_run_request)
717 // XXX : add to attributes JSON here
718 $json_report_attributes = null;
720 if(($t = $test_run_request->test_profile
->test_installation
->get_compiler_data()))
722 $json_report_attributes['compiler-options'] = $t;
724 if(($t = $test_run_request->test_profile
->test_installation
->get_install_footnote()))
726 $json_report_attributes['install-footnote'] = $t;
728 if(($t = $test_run_request->active
->get_min_result()) != 0)
730 $json_report_attributes['min-result'] = $t;
732 if(($t = $test_run_request->active
->get_max_result()) != 0)
734 $json_report_attributes['max-result'] = $t;
737 return $json_report_attributes;
739 public static function clean_save_name($input, $is_new_save = true)
741 $input = pts_client
::swap_variables($input, array('pts_client', 'user_run_save_variables'));
742 $input = pts_strings
::remove_redundant(pts_strings
::keep_in_string(str_replace(' ', '-', trim($input)), pts_strings
::CHAR_LETTER | pts_strings
::CHAR_NUMERIC | pts_strings
::CHAR_DASH
), '-');
746 $input = strtolower($input);
749 if(strlen($input) > 126)
751 $input = substr($input, 0, 126);
756 public function initial_checks(&$to_run, $override_display_mode = false)
758 // Refresh the pts_client::$display in case we need to run in debug mode
759 if(pts_client
::$display == false ||
!(pts_client
::$display instanceof pts_websocket_display_mode
))
761 pts_client
::init_display_mode($override_display_mode);
763 $to_run = pts_types
::identifiers_to_objects($to_run);
765 if($this->batch_mode
&& $this->batch_mode
['Configured'] == false && !$this->auto_mode
)
767 trigger_error('The batch mode must first be configured.' . PHP_EOL
. 'To configure, run phoronix-test-suite batch-setup', E_USER_ERROR
);
771 if(!is_writable(pts_client
::test_install_root_path()))
773 trigger_error('The test installation directory is not writable.' . PHP_EOL
. 'Location: ' . pts_client
::test_install_root_path(), E_USER_ERROR
);
777 // Cleanup tests to run
778 if(pts_test_run_manager
::cleanup_tests_to_run($to_run) == false)
782 else if(count($to_run) == 0)
784 trigger_error('You must enter at least one test, suite, or result identifier to run.', E_USER_ERROR
);
790 public function pre_execution_process()
792 if($this->do_save_results())
794 if($this->is_new_result_file ||
$this->result_already_contains_identifier() == false)
796 $this->result_file
->set_title($this->file_name_title
);
797 $this->result_file
->set_description($this->run_description
);
798 $this->result_file
->set_notes($this->get_notes());
799 $this->result_file
->set_internal_tags($this->get_internal_tags());
800 $this->result_file
->set_reference_id($this->get_reference_id());
801 $this->result_file
->set_preset_environment_variables($this->get_preset_environment_variables());
804 pts_client
::setup_test_result_directory($this->get_file_name());
807 protected function generate_json_system_attributes()
809 $test_external_dependencies = array();
810 $test_hardware_types = array();
811 $test_internal_tags = array();
813 foreach($this->tests_to_run
as $test_to_run)
815 $test_external_dependencies = array_merge($test_external_dependencies, $test_to_run->test_profile
->get_dependencies());
816 $test_internal_tags = array_merge($test_internal_tags, $test_to_run->test_profile
->get_internal_tags());
817 pts_arrays
::unique_push($test_hardware_types, $test_to_run->test_profile
->get_test_hardware_type());
820 return self
::pull_test_notes(false, $test_external_dependencies, $test_internal_tags, $test_hardware_types);
822 public static function pull_test_notes($show_all = false, $test_external_dependencies = array(), $test_internal_tags = array(), $test_hardware_types = array())
826 if($show_all ||
in_array('build-utilities', $test_external_dependencies))
828 // So compiler tests were run....
830 $compiler_mask_dir = pts_test_installer
::create_compiler_mask($test);
832 if($compiler_mask_dir && is_executable($compiler_mask_dir . 'cc'))
834 $compiler_configuration = phodevi_system
::sw_compiler_build_configuration($compiler_mask_dir . 'cc');
835 pts_file_io
::delete($compiler_mask_dir, null, true);
837 if(!empty($compiler_configuration))
839 $notes['compiler-configuration'] = $compiler_configuration;
843 if($show_all ||
in_array('OpenCL', $test_internal_tags))
845 // So OpenCL tests were run....
846 $gpu_compute_cores = phodevi
::read_property('gpu', 'compute-cores');
847 if($gpu_compute_cores > 0)
849 $notes['graphics-compute-cores'] = $gpu_compute_cores;
852 if($show_all ||
in_array('Disk', $test_hardware_types))
854 // A disk test was run so report some disk information...
855 $disk_scheduler = phodevi
::read_property('disk', 'scheduler');
858 $notes['disk-scheduler'] = $disk_scheduler;
861 $mount_options = phodevi
::read_property('disk', 'mount-options');
862 if($mount_options['mount-options'] != null)
864 $notes['disk-mount-options'] = $mount_options['mount-options'];
866 $extra = phodevi
::read_property('disk', 'extra-disk-details');
869 $notes['disk-details'] = $extra;
872 if(true ||
$show_all ||
in_array('Processor', $test_hardware_types) ||
in_array('System', $test_hardware_types))
874 // XXX probably makes sense always reporting the CPU scaling governor
875 $scaling_governor = phodevi
::read_property('cpu', 'scaling-governor');
876 if($scaling_governor)
878 $notes['cpu-scaling-governor'] = $scaling_governor;
881 if($show_all ||
in_array('Graphics', $test_hardware_types))
883 $accel_2d = phodevi
::read_property('gpu', '2d-acceleration');
886 $notes['graphics-2d-acceleration'] = $accel_2d;
889 $aa = phodevi
::read_property('gpu', 'aa-level');
892 $notes['graphics-aa'] = $aa;
895 $af = phodevi
::read_property('gpu', 'af-level');
898 $notes['graphics-af'] = $af;
902 if(phodevi
::read_property('system', 'kernel-parameters'))
904 $notes['kernel-parameters'] = phodevi
::read_property('system', 'kernel-parameters');
907 if(phodevi
::read_property('system', 'environment-variables'))
909 $notes['environment-variables'] = phodevi
::read_property('system', 'environment-variables');
914 public function post_execution_process()
916 if($this->do_save_results())
918 if($this->result_file
->get_test_count() == 0 && $this->is_new_result_file
)
920 pts_file_io
::delete(PTS_SAVE_RESULTS_PATH
. $this->get_file_name());
924 pts_file_io
::delete(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/test-logs/active/', null, true);
926 if($this->is_new_result_file ||
$this->result_already_contains_identifier() == false)
928 // TODO XXX JSON In null and notes
929 $sys = new pts_result_file_system($this->results_identifier
, phodevi
::system_hardware(true), phodevi
::system_software(true), $this->generate_json_system_attributes(), pts_client
::current_user(), pts_test_notes_manager
::generate_test_notes($this->tests_to_run
), date('Y-m-d H:i:s'), PTS_VERSION
);
930 $this->result_file
->add_system($sys);
934 pts_module_manager
::module_process('__event_results_process', $this);
935 pts_client
::save_test_result($this->get_file_name() . '/composite.xml', $this->result_file
->get_xml(), true, null, $this->results_identifier
);
936 pts_module_manager
::module_process('__event_results_saved', $this);
937 //echo PHP_EOL . 'Results Saved To: ; . PTS_SAVE_RESULTS_PATH . $this->get_file_name() . ;/composite.xml' . PHP_EOL;
939 if(!$this->auto_mode
)
941 if($this->batch_mode
)
943 if($this->batch_mode
['OpenBrowser'])
945 pts_client
::display_web_page(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/index.html', null, true, true);
950 pts_client
::display_web_page(PTS_SAVE_RESULTS_PATH
. $this->get_file_name() . '/index.html', null, true, false);
954 if($this->allow_sharing_of_results
&& pts_network
::internet_support_available())
956 if($this->auto_upload_to_openbenchmarking || pts_openbenchmarking_client
::auto_upload_results() || pts_config
::read_bool_config('PhoronixTestSuite/Options/Testing/AlwaysUploadResultsToOpenBenchmarking', 'FALSE'))
958 $upload_results = true;
960 else if($this->batch_mode
)
962 $upload_results = $this->batch_mode
['UploadResults'];
964 else if(!$this->auto_mode
)
966 $upload_results = pts_user_io
::prompt_bool_input('Would you like to upload the results to OpenBenchmarking.org', true);
970 $upload_results = false;
975 $this->openbenchmarking_results_data
= pts_openbenchmarking
::upload_test_result($this, true);
977 if($this->get_results_url())
979 if(!$this->auto_mode
&& !$this->batcj_mode
&& pts_openbenchmarking_client
::auto_upload_results() == false)
981 pts_client
::display_web_page($this->get_results_url(), 'Do you want to launch OpenBenchmarking.org', true);
986 echo PHP_EOL
. 'Results Failed To Upload.' . PHP_EOL
;
992 public function get_results_url()
994 return isset($this->openbenchmarking_results_data
['url']) ?
$this->openbenchmarking_results_data
['url'] : false;
996 public function get_result_upload_data()
998 return $this->openbenchmarking_results_data
;
1000 public function set_batch_mode($custom_preset = false)
1002 $this->batch_mode
= array(
1003 'UploadResults' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/UploadResults', 'TRUE'),
1004 'SaveResults' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/SaveResults', 'TRUE'),
1005 'PromptForTestDescription' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/PromptForTestDescription', 'FALSE'),
1006 'RunAllTestCombinations' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/RunAllTestCombinations', 'TRUE'),
1007 'PromptSaveName' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/PromptSaveName', 'FALSE'),
1008 'PromptForTestIdentifier' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/PromptForTestIdentifier', 'TRUE'),
1009 'Configured' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/Configured', 'FALSE'),
1010 'OpenBrowser' => pts_config
::read_bool_config('PhoronixTestSuite/Options/BatchMode/OpenBrowser', 'FALSE'),
1013 if($custom_preset && is_array($custom_preset))
1015 foreach($custom_preset as $key => $value)
1017 $this->batch_mode
[$key] = $value;
1020 $this->batch_mode
['Configured'] = true;
1023 public static function cleanup_tests_to_run(&$to_run_objects)
1025 $skip_tests = ($e = pts_client
::read_env('SKIP_TESTS')) ? pts_strings
::comma_explode($e) : false;
1026 $tests_verified = array();
1027 $tests_missing = array();
1029 foreach($to_run_objects as &$run_object)
1031 if($skip_tests && (in_array($run_object->get_identifier(false), $skip_tests) ||
($run_object instanceof pts_test_profile
&& in_array($run_object->get_identifier_base_name(), $skip_tests))))
1033 pts_client
::$display->generic_sub_heading('Skipping: ' . $run_object->get_identifier());
1036 else if($run_object instanceof pts_test_profile
)
1038 if($run_object->get_title() == null)
1040 pts_client
::$display->generic_sub_heading('Not A Test: ' . $run_object);
1045 if($run_object->is_supported(false) == false)
1049 if($run_object->is_test_installed() == false)
1051 // Check to see if older version of test is currently installed
1052 // TODO: show change-log between installed versions and upstream
1053 array_push($tests_missing, $run_object);
1058 else if($run_object instanceof pts_result_file
)
1061 foreach($run_object->get_contained_test_profiles() as $test_profile)
1063 if($test_profile == null ||
$test_profile->get_identifier() == null ||
$test_profile->is_supported(false) == false)
1067 else if($test_profile->is_test_installed() == false)
1069 array_push($tests_missing, $test_profile);
1077 if($num_installed == 0)
1082 else if($run_object instanceof pts_test_suite ||
$run_object instanceof pts_virtual_test_suite||
$run_object instanceof pts_virtual_test_queue
)
1084 if($run_object->is_core_version_supported() == false)
1086 pts_client
::$display->generic_sub_heading($run_object->get_title() . ' is a suite not supported by this version of the Phoronix Test Suite.');
1092 foreach($run_object->get_contained_test_profiles() as $test_profile)
1094 if($test_profile == null ||
$test_profile->get_identifier() == null ||
$test_profile->is_supported(false) == false)
1099 if($test_profile->is_test_installed() == false)
1101 array_push($tests_missing, $test_profile);
1109 if($num_installed == 0)
1116 pts_client
::$display->generic_sub_heading('Not Recognized: ' . $run_object);
1120 array_push($tests_verified, $run_object);
1123 $to_run_objects = $tests_verified;
1125 if(count($tests_missing) > 0 && !defined('PHOROMATIC_PROCESS'))
1127 $tests_missing = array_unique($tests_missing);
1129 if(count($tests_missing) == 1)
1131 trigger_error($tests_missing[0] . ' is not installed.', E_USER_ERROR
);
1132 // PHP_EOL . 'To install, run: phoronix-test-suite install ' . $tests_missing[0]
1136 $message = PHP_EOL
. PHP_EOL
. 'Multiple tests are not installed:' . PHP_EOL
. PHP_EOL
;
1137 $message .= pts_user_io
::display_text_list($tests_missing);
1138 //$message .= PHP_EOL . 'To install, run: phoronix-test-suite install ' . implode(' ', $tests_missing) . PHP_EOL . PHP_EOL;
1142 if(!$this->batch_mode
&& !$this->auto_mode
&& pts_client
::current_command() != 'benchmark')
1144 $stop_and_install = pts_user_io
::prompt_bool_input('Would you like to stop and install these tests now', true);
1146 if($stop_and_install)
1148 pts_test_installer
::standard_install($tests_missing);
1149 self
::cleanup_tests_to_run($to_run_objects);
1156 public function auto_save_results($save_name, $result_identifier, $description = null, $is_new_save = false)
1158 $this->set_save_name($save_name, $is_new_save);
1159 $this->set_results_identifier($result_identifier);
1160 $this->set_description($description);
1162 public function set_description($description)
1164 $this->run_description
= $description == null ? self
::auto_generate_description() : $description;
1166 public function subsystems_under_test()
1168 $subsystems_to_test = array();
1169 foreach($this->tests_to_run
as $test_run_request)
1171 pts_arrays
::unique_push($subsystems_to_test, $test_run_request->test_profile
->get_test_hardware_type());
1173 return $subsystems_to_test;
1175 protected function auto_generate_description()
1177 $hw_components = array(pts_result_file_analyzer
::system_component_string_to_array(phodevi
::system_hardware(true)));
1178 $sw_components = array(pts_result_file_analyzer
::system_component_string_to_array(phodevi
::system_software(true)));
1180 if($this->is_new_result_file
)
1182 $existing_identifiers = array();
1183 $hw_components = array();
1184 $sw_components = array();
1186 foreach($this->result_file
->get_systems() as $s)
1188 array_push($hw_components, pts_result_file_analyzer
::system_component_string_to_array($s->get_hardware()));
1189 array_push($sw_components, pts_result_file_analyzer
::system_component_string_to_array($s->get_software()));
1190 array_push($existing_identifiers, $s->get_identifier());
1193 $existing_identifier_count = count($existing_identifiers);
1197 $existing_identifier_count = 0;
1200 $auto_description = 'Running ' . implode(', ', array_unique($this->get_tests_to_run_identifiers()));
1201 $subsystems_to_test = $this->subsystems_under_test();
1203 // TODO: hook into $hw_components and $sw_components for leveraging existing result file data for comparisons already in existent
1204 // dropped: count($subsystems_to_test) == 1 && $
1205 if($existing_identifier_count == 0)
1207 switch($subsystems_to_test)
1210 $auto_description = phodevi
::read_property('gpu', 'model') . ' graphics testing with ' . phodevi
::read_property('system', 'display-driver-string') . ' / ' . phodevi
::read_property('system', 'opengl-driver');
1213 $auto_description = phodevi
::read_name('disk') . ' testing on ' . phodevi
::read_property('system', 'operating-system') . ' with a ' . phodevi
::read_property('system', 'filesystem') . ' file-system';
1217 $auto_description = phodevi
::read_property('cpu', 'model') . ' testing with a ' . phodevi
::read_name('motherboard') . ' on ' . phodevi
::read_property('system', 'operating-system');
1220 if(phodevi
::read_property('system', 'system-layer'))
1222 // Virtualization, Wine testing...
1223 $auto_description = phodevi
::read_property('system', 'system-layer') . ' testing on ' . phodevi
::read_property('system', 'operating-system');
1225 else if(phodevi
::read_name('motherboard') != null && phodevi
::read_property('gpu', 'model') != null)
1227 // Standard description
1228 $auto_description = phodevi
::read_property('cpu', 'model') . ' testing with a ' . phodevi
::read_name('motherboard') . ' and ' . phodevi
::read_property('gpu', 'model') . ' on ' . phodevi
::read_property('system', 'operating-system');
1232 // A virtualized environment or a BSD or other OS where not all hardware info is available...
1233 $auto_description = phodevi
::read_property('cpu', 'model') . ' testing on ' . phodevi
::read_property('system', 'operating-system');
1240 if($this->is_new_result_file
)
1242 $result_file_intent = pts_result_file_analyzer
::analyze_result_file_intent($this->result_file
);
1244 if(is_array($result_file_intent) && $result_file_intent[0] != 'Unknown')
1246 $auto_description = 'A ' . $result_file_intent[0] . ' comparison';
1251 $auto_description .= ' via the Phoronix Test Suite.';
1253 return $auto_description;
1255 public function save_results_prompt()
1257 if(!$this->auto_mode
)
1259 pts_client
::$display->generic_heading('System Information');
1260 echo 'Hardware:' . PHP_EOL
. phodevi
::system_hardware(true) . PHP_EOL
. PHP_EOL
;
1261 echo 'Software:' . PHP_EOL
. phodevi
::system_software(true) . PHP_EOL
. PHP_EOL
;
1264 if(($this->prompt_save_results ||
$this->force_save_results
) && count($this->tests_to_run
) > 0) // or check for DO_NOT_SAVE_RESULTS == false
1266 if($this->force_save_results || pts_client
::read_env('TEST_RESULTS_NAME'))
1268 $save_results = true;
1270 else if($this->batch_mode
)
1272 $save_results = $this->batch_mode
['SaveResults'];
1274 else if(pts_client
::is_debug_mode())
1276 $save_results = false;
1280 $save_results = pts_user_io
::prompt_bool_input('Would you like to save these test results', true);
1285 // Prompt Save File Name
1286 $this->prompt_save_name();
1288 // Prompt Identifier
1289 $this->prompt_results_identifier();
1291 if(!isset($this->run_description
[16]) ||
strpos($this->run_description
, 'via the Phoronix Test Suite') !== false)
1293 // Write the auto-description if nothing is set or attempt to auto-detect if it was a previous auto-description saved
1294 $this->run_description
= self
::auto_generate_description();
1297 // Prompt Description
1298 if(!$this->batch_mode ||
$this->batch_mode
['PromptForTestDescription'])
1300 if($this->run_description
== null)
1302 $this->run_description
= 'N/A';
1305 if(pts_client
::read_env('TEST_RESULTS_DESCRIPTION'))
1307 if(strlen(pts_client
::read_env('TEST_RESULTS_DESCRIPTION')) > 1)
1309 $this->run_description
= pts_client
::read_env('TEST_RESULTS_DESCRIPTION');
1310 echo 'Test Description: ' . $this->run_description
. PHP_EOL
;
1313 else if(!$this->auto_mode
)
1315 //echo PHP_EOL . 'Current Title: ' . $this->file_name_title . PHP_EOL;
1316 pts_client
::$display->generic_heading('If you wish, enter a new description below to better describe this result set / system configuration under test.' . PHP_EOL
. 'Press ENTER to proceed without changes.');
1317 echo 'Current Description: ' . $this->run_description
. PHP_EOL
. PHP_EOL
. 'New Description: ';
1318 $new_test_description = pts_user_io
::read_user_input();
1320 if(!empty($new_test_description))
1322 $this->run_description
= $new_test_description;
1329 public function load_tests_to_run(&$to_run_objects)
1331 // Determine what to run
1332 $this->determine_tests_to_run($to_run_objects);
1334 // Is there something to run?
1335 return $this->get_test_count() > 0;
1337 public function load_result_file_to_run($save_name, $result_identifier, &$result_file, $tests_to_complete = null)
1339 // Determine what to run
1340 $this->auto_save_results($save_name, $result_identifier);
1341 $this->run_description
= $result_file->get_description();
1342 $result_objects = $result_file->get_result_objects();
1344 // Unset result objects that shouldn't be run
1345 if(is_array($tests_to_complete))
1347 foreach(array_keys($result_objects) as $i)
1349 if(!in_array($i, $tests_to_complete))
1351 unset($result_objects[$i]);
1356 if(count($result_objects) == 0)
1362 foreach($result_objects as &$result_object)
1364 if($this->validate_test_to_run($result_object->test_profile
))
1366 $test_result = new pts_test_result($result_object->test_profile
);
1367 $test_result->set_used_arguments($result_object->get_arguments());
1368 $test_result->set_used_arguments_description($result_object->get_arguments_description());
1369 $this->add_test_result_object($test_result);
1373 // Is there something to run?
1374 return $this->get_test_count() > 0;
1376 public function load_test_run_requests_to_run($save_name, $result_identifier, &$result_file, &$test_run_requests)
1378 // Determine what to run
1379 $this->auto_save_results($save_name, $result_identifier);
1380 $this->run_description
= $result_file->get_description();
1382 if(count($test_run_requests) == 0)
1387 foreach($test_run_requests as &$test_run_request)
1389 if($this->validate_test_to_run($test_run_request->test_profile
) == false)
1394 if($test_run_request->test_profile
->get_override_values() != null)
1396 $test_run_request->test_profile
->set_override_values($test_run_request->test_profile
->get_override_values());
1399 $test_result = new pts_test_result($test_run_request->test_profile
);
1400 $test_result->set_used_arguments($test_run_request->get_arguments());
1401 $test_result->set_used_arguments_description($test_run_request->get_arguments_description());
1402 $this->add_test_result_object($test_result);
1405 // Is there something to run?
1406 return $this->get_test_count() > 0;
1408 public function is_multi_test_stress_run()
1410 return $this->multi_test_stress_run
;
1412 public function multi_test_stress_run_execute($tests_to_run_concurrently = 3, $total_loop_time = false)
1414 $continue_test_flag = true;
1415 pts_client
::$display->test_run_process_start($this);
1416 $this->disable_dynamic_run_count();
1417 $this->multi_test_stress_run
= $tests_to_run_concurrently;
1418 $possible_tests_to_run = $this->get_tests_to_run();
1419 $tests_pids_active = array();
1420 $loop_until_time = is_numeric($total_loop_time) && $total_loop_time > 1 ?
time() +
$total_loop_time : false;
1422 while(!empty($possible_tests_to_run) ||
!empty($tests_pids_active))
1424 if($continue_test_flag == false)
1427 $test_types_active = array();
1428 foreach($tests_pids_active as $pid => &$test)
1430 $ret = pcntl_waitpid($pid, $status, WNOHANG | WUNTRACED
);
1434 if(pcntl_wifexited($status) ||
!posix_getsid($pid))
1436 unset($tests_pids_active[$pid]);
1441 if(!in_array($test->test_profile
->get_test_hardware_type(), $test_types_active))
1443 array_push($test_types_active, $test->test_profile
->get_test_hardware_type());
1448 if(!empty($possible_tests_to_run) && count($tests_pids_active) < $tests_to_run_concurrently && (!$total_loop_time ||
$loop_until_time > time()))
1450 shuffle($possible_tests_to_run);
1452 $test_to_run = false;
1453 $test_run_index = -1;
1454 foreach($possible_tests_to_run as $i => $test)
1456 if(!in_array($test->test_profile
->get_test_hardware_type(), $test_types_active))
1458 $test_run_index = $i;
1459 $test_to_run = $test;
1462 if($test_run_index == -1)
1464 $test_run_index = array_rand(array_keys($possible_tests_to_run));
1465 $test_to_run = $possible_tests_to_run[$test_run_index];
1468 $pid = pcntl_fork();
1471 echo 'Forking failure.';
1475 $tests_pids_active[$pid] = $test_to_run;
1479 $continue_test_flag = $this->process_test_run_request($test_to_run);
1483 if($total_loop_time == false)
1485 unset($possible_tests_to_run[$test_run_index]);
1487 else if($total_loop_time == 'infinite')
1489 echo 'Continuing to test indefinitely' . PHP_EOL
;
1493 if($loop_until_time > time())
1495 $time_left = ceil(($loop_until_time - time()) / 60);
1496 echo 'Continuing to test for ' . $time_left . ' more minutes' . PHP_EOL
;
1500 echo 'TOTAL_LOOP_TIME elapsed; quitting....' . PHP_EOL
;
1509 foreach($this->get_tests_to_run() as $run_request)
1511 // Remove cache shares
1512 foreach(pts_file_io
::glob($run_request->test_profile
->get_install_dir() . 'cache-share-*.pt2so') as $cache_share_file)
1514 unlink($cache_share_file);
1520 protected function test_prompts_to_result_objects(&$test_profile)
1522 $result_objects = array();
1524 if($this->batch_mode
&& $this->batch_mode
['RunAllTestCombinations'])
1526 list($test_arguments, $test_arguments_description) = pts_test_run_options
::batch_user_options($test_profile);
1528 else if($this->auto_mode
== 2)
1530 list($test_arguments, $test_arguments_description) = pts_test_run_options
::default_user_options($test_profile);
1534 list($test_arguments, $test_arguments_description) = pts_test_run_options
::prompt_user_options($test_profile);
1537 foreach(array_keys($test_arguments) as $i)
1539 $test_result = new pts_test_result($test_profile);
1540 $test_result->set_used_arguments($test_arguments[$i]);
1541 $test_result->set_used_arguments_description($test_arguments_description[$i]);
1542 array_push($result_objects, $test_result);
1545 return $result_objects;
1547 public function determine_tests_to_run(&$to_run_objects)
1549 $unique_test_count = count(array_unique($to_run_objects));
1550 $run_contains_a_no_result_type = false;
1551 $request_results_save = false;
1553 foreach($to_run_objects as &$run_object)
1555 // TODO: determine whether to print the titles of what's being run?
1556 if($run_object instanceof pts_test_profile
)
1558 if($run_object->get_identifier() == null ||
$run_object->get_title() == null ||
$this->validate_test_to_run($run_object) == false)
1563 if($run_contains_a_no_result_type == false && $run_object->get_display_format() == 'NO_RESULT')
1565 $run_contains_a_no_result_type = true;
1567 if($request_results_save == false && $run_object->do_auto_save_results())
1569 $request_results_save = true;
1572 foreach(self
::test_prompts_to_result_objects($run_object) as $result_object)
1574 $this->add_test_result_object($result_object);
1577 else if($run_object instanceof pts_test_suite
)
1579 $this->pre_run_message
= $run_object->get_pre_run_message();
1580 $this->post_run_message
= $run_object->get_post_run_message();
1582 if($run_object->get_run_mode() == 'PCQS')
1584 $this->is_pcqs
= true;
1587 foreach($run_object->get_contained_test_result_objects() as $result_object)
1589 $this->add_test_result_object($result_object);
1592 else if($run_object instanceof pts_virtual_test_queue
)
1594 foreach($run_object->get_contained_test_result_objects() as $result_object)
1596 $this->add_test_result_object($result_object);
1599 else if($run_object instanceof pts_result_file
)
1601 // Print the $to_run ?
1602 $this->run_description
= $run_object->get_description();
1603 $preset_vars = $run_object->get_preset_environment_variables();
1604 $result_objects = $run_object->get_result_objects();
1606 $this->set_save_name($run_object->get_identifier(), false);
1607 $this->file_name_title
= $run_object->get_title();
1609 pts_module_manager
::process_environment_variables_string_to_set($preset_vars);
1611 foreach($result_objects as &$result_object)
1613 if($result_object->test_profile
->get_identifier() == null)
1618 $test_result = new pts_test_result($result_object->test_profile
);
1619 $test_result->set_used_arguments($result_object->get_arguments());
1620 $test_result->set_used_arguments_description($result_object->get_arguments_description());
1621 $this->add_test_result_object($test_result);
1624 else if($run_object instanceof pts_virtual_test_suite
)
1626 $virtual_suite_tests = $run_object->get_contained_test_profiles();
1628 foreach(array_keys($virtual_suite_tests) as $i)
1630 if($virtual_suite_tests[$i]->is_supported(false) == false ||
$this->validate_test_to_run($virtual_suite_tests[$i]) == false)
1632 unset($virtual_suite_tests[$i]);
1635 sort($virtual_suite_tests);
1637 if(count($virtual_suite_tests) > 1)
1639 array_push($virtual_suite_tests, 'All Tests In Suite');
1642 if(!$this->auto_mode
&& !$this->batch_mode
)
1644 $run_index = explode(',', pts_user_io
::prompt_text_menu('Select the tests in the virtual suite to run', $virtual_suite_tests, true, true));
1651 if((count($virtual_suite_tests) > 2 && in_array((count($virtual_suite_tests) - 1), $run_index)) ||
$run_index == -1)
1653 // The appended 'All Tests In Suite' was selected, so run all
1657 foreach(array_keys($virtual_suite_tests) as $i)
1659 if(!in_array($i, $run_index))
1661 unset($virtual_suite_tests[$i]);
1666 foreach($virtual_suite_tests as &$test_profile)
1668 if($test_profile instanceof pts_test_profile
)
1670 // The user is to configure virtual suites manually
1671 foreach(self
::test_prompts_to_result_objects($test_profile) as $result_object)
1673 $this->add_test_result_object($result_object);
1680 trigger_error($run_object . ' is not recognized.', E_USER_ERROR
);
1685 // AlwaysUploadResultsToOpenBenchmarking AutoSortRunQueue
1686 if(pts_config
::read_bool_config('PhoronixTestSuite/Options/Testing/AutoSortRunQueue', 'TRUE') && $this->force_save_results
== false)
1688 // Not that it matters much, but if $this->force_save_results is set that means likely running from a result file...
1689 // so if running a result file, don't change the ordering of the existing results
1691 // Sort the run order so that all tests that are similar are grouped together, etc
1692 usort($this->tests_to_run
, array('pts_test_run_manager', 'cmp_result_object_sort'));
1694 if(pts_client
::read_env('RUN_TESTS_IN_RANDOM_ORDER'))
1696 shuffle($this->tests_to_run
);
1699 $this->prompt_save_results
= $run_contains_a_no_result_type == false ||
$unique_test_count > 1;
1700 $this->force_save_results
= $this->force_save_results ||
$request_results_save;
1702 public static function cmp_result_object_sort($a, $b)
1704 $a_comp = $a->test_profile
->get_test_hardware_type() . $a->test_profile
->get_test_software_type() . $a->test_profile
->get_internal_tags_raw() . $a->test_profile
->get_result_scale_formatted() . $a->test_profile
->get_identifier(true);
1705 $b_comp = $b->test_profile
->get_test_hardware_type() . $b->test_profile
->get_test_software_type() . $b->test_profile
->get_internal_tags_raw() . $b->test_profile
->get_result_scale_formatted() . $b->test_profile
->get_identifier(true);
1707 if($a_comp == $b_comp)
1709 // So it's the same test being compared... try to sort in ascending order (such that 800 x 600 resolution comes before 1024 x 768), below way is an attempt to recognize such in weird manner
1710 if(strlen($a->get_arguments_description()) == strlen($b->get_arguments_description()))
1712 return strcmp($a->get_arguments_description(), $b->get_arguments_description());
1716 return strcmp(strlen($a->get_arguments_description()), strlen($b->get_arguments_description()));
1720 return strcmp($a_comp, $b_comp);
1722 public static function test_profile_system_compatibility_check(&$test_profile, $report_errors = false)
1724 $valid_test_profile = true;
1725 $test_type = $test_profile->get_test_hardware_type();
1726 $skip_tests = pts_client
::read_env('SKIP_TESTS') ? pts_strings
::comma_explode(pts_client
::read_env('SKIP_TESTS')) : false;
1727 $skip_test_subsystems = pts_client
::read_env('SKIP_TESTING_SUBSYSTEMS') ? pts_strings
::comma_explode(strtolower(pts_client
::read_env('SKIP_TESTING_SUBSYSTEMS'))) : false;
1728 $display_driver = phodevi
::read_property('system', 'display-driver');
1729 $gpu = phodevi
::read_name('gpu');
1731 if($test_profile->is_supported(false) == false)
1733 $valid_test_profile = false;
1735 else if($test_type == 'Graphics' && pts_client
::read_env('DISPLAY') == false && pts_client
::read_env('WAYLAND_DISPLAY') == false && phodevi
::is_windows() == false && phodevi
::is_macosx() == false)
1737 $report_errors && pts_client
::$display->test_run_error('No display server was found, cannot run ' . $test_profile);
1738 $valid_test_profile = false;
1740 else if($test_type == 'Graphics' && in_array($display_driver, array('vesa', 'nv', 'cirrus')) && stripos($gpu, 'LLVM') === false)
1742 // These display drivers end up being in known configurations without 3D hardware support so unless an LLVM-based string is reported as the GPU, don't advertise 3D tests
1743 $report_errors && pts_client
::$display->test_run_error('3D acceleration support not available, cannot run ' . $test_profile);
1744 $valid_test_profile = false;
1746 else if($test_type == 'Disk' && stripos(phodevi
::read_property('system', 'filesystem'), 'SquashFS') !== false)
1748 $report_errors && pts_client
::$display->test_run_error('Running on a RAM-based live file-system, cannot run ' . $test_profile);
1749 $valid_test_profile = false;
1751 else if(pts_client
::read_env('NO_' . strtoupper($test_type) . '_TESTS') ||
($skip_tests && (in_array($test_profile, $skip_tests) ||
in_array($test_type, $skip_tests) ||
in_array($test_profile->get_identifier(false), $skip_tests) ||
in_array($test_profile->get_identifier_base_name(), $skip_tests))))
1753 $report_errors && pts_client
::$display->test_run_error('Due to a pre-set environmental variable, skipping ' . $test_profile);
1754 $valid_test_profile = false;
1756 else if($skip_test_subsystems && in_array(strtolower($test_profile->get_test_hardware_type()), $skip_test_subsystems))
1758 $report_errors && pts_client
::$display->test_run_error('Due to a pre-set environmental variable, skipping ' . $test_profile);
1759 $valid_test_profile = false;
1761 else if($test_profile->is_root_required() && $this->batch_mode
&& phodevi
::is_root() == false)
1763 $report_errors && pts_client
::$display->test_run_error('Cannot run ' . $test_profile . ' in batch mode as root access is required.');
1764 $valid_test_profile = false;
1767 if($valid_test_profile == false && pts_client
::read_env('SKIP_ALL_TEST_SUPPORT_CHECKS'))
1769 $report_errors && pts_client
::$display->test_run_error('SKIP_ALL_TEST_SUPPORT_CHECKS is set for ' . $test_profile . '.');
1770 $valid_test_profile = true;
1773 return $valid_test_profile;
1775 protected function validate_test_to_run(&$test_profile)
1777 static $test_checks = null;
1779 if(!isset($test_checks[$test_profile->get_identifier()]))
1781 $valid_test_profile = true;
1783 if(self
::test_profile_system_compatibility_check($test_profile, true) == false)
1785 $valid_test_profile = false;
1787 else if($test_profile->get_test_executable_dir() == null)
1789 pts_client
::$display->test_run_error('The test executable for ' . $test_profile . ' could not be located.');
1790 $valid_test_profile = false;
1793 if($valid_test_profile && $this->allow_sharing_of_results
&& $test_profile->allow_results_sharing() == false)
1795 $this->allow_sharing_of_results
= false;
1798 $test_checks[$test_profile->get_identifier()] = $valid_test_profile;
1801 return $test_checks[$test_profile->get_identifier()];
1803 public function standard_run($to_run)
1805 if($this->initial_checks($to_run) == false)
1810 // Load the tests to run
1811 if($this->load_tests_to_run($to_run) == false)
1817 $this->save_results_prompt();
1819 // Run the actual tests
1820 $this->pre_execution_process();
1821 $this->call_test_runs();
1822 $this->post_execution_process();