Best Phoronix-test-suite code snippet using pts_test_result_parser.debug_message
pts_test_result_parser.php
Source:pts_test_result_parser.php
...53 }54 if(count($sensor) != 2 || !phodevi::is_sensor_supported($sensor))55 {56 // Not a sensor or it's not supported57 pts_test_result_parser::debug_message('No supported sensor found');58 continue;59 }60 if(!is_numeric($polling_freq) || $polling_freq < 0.5)61 {62 pts_test_result_parser::debug_message('No polling frequency defined, defaulting to 2 seconds');63 $polling_freq = 2;64 }65 $polling_freq *= 1000000; // Convert from seconds to micro-seconds66 if(!in_array($report_as, array('ALL', 'MAX', 'MIN', 'AVG')))67 {68 // Not a valid reporting type69 pts_test_result_parser::debug_message('No valid Report entry found.');70 continue;71 }72 if(!function_exists('pcntl_fork'))73 {74 pts_client::$display->test_run_instance_error('PHP with PCNTL support enabled is required for this test.');75 return false;76 }77 $monitor_file = tempnam($test_directory, '.monitor');78 $pid = pcntl_fork();79 if($pid != -1)80 {81 if($pid)82 {83 // Main process still84 self::$monitoring_sensors[] = array($pid, $sensor, $report_as, $monitor_file);85 continue;86 }87 else88 {89 $sensor_values = array();90 while(is_file($monitor_file)) // when test ends, it will remove file in case the posix_kill doesn't happen91 {92 $sensor_values[] = phodevi::read_sensor($sensor);93 file_put_contents($monitor_file, implode("\n", $sensor_values));94 usleep($polling_freq);95 }96 exit(0);97 }98 }99 }100 return count(self::$monitoring_sensors) > 0;101 }102 public static function system_monitor_task_post_test(&$test_run_request, $exit_status_pass = true)103 {104 $test_directory = $test_run_request->test_profile->get_install_dir();105 $did_post_result = false;106 foreach(self::$monitoring_sensors as $sensor_r)107 {108 if($sensor_r[1] == array('sys', 'time'))109 {110 // sys.time is a special case111 $end_time = microtime(true);112 // Delta time113 $result_value = round($end_time - $sensor_r[3], 3);114 $minimal_test_time = pts_config::read_user_config('PhoronixTestSuite/Options/TestResultValidation/MinimalTestTime', 2);115 if($result_value < $minimal_test_time)116 {117 // The test ended too fast118 pts_test_result_parser::debug_message('Test Run-Time Too Short: ' . $result_value);119 $result_value = null;120 }121 }122 else123 {124 // Kill the sensor monitoring thread125 if(function_exists('posix_kill') == false)126 {127 pts_client::$display->test_run_error('The PHP POSIX extension is required for this test.');128 return $did_post_result;129 }130 posix_kill($sensor_r[0], SIGTERM);131 $sensor_values = explode("\n", pts_file_io::file_get_contents($sensor_r[3]));132 pts_file_io::unlink($sensor_r[3]);133 if(count($sensor_values) == 0)134 {135 continue;136 }137 switch($sensor_r[2])138 {139 case 'MAX':140 $result_value = max($sensor_values);141 break;142 case 'MIN':143 $result_value = min($sensor_values);144 break;145 case 'AVG':146 $result_value = pts_math::arithmetic_mean($sensor_values);147 break;148 case 'ALL':149 $result_value = implode(',', $sensor_values);150 break;151 default:152 $result_value = null;153 break;154 }155 }156 if($result_value != null && $result_value > 0 && $exit_status_pass)157 {158 // For now it's only possible to return one result per test XXX actually with PTS7 this can be changed....159 // TODO XXX for some sensors may make sense for min/max values?160 pts_test_result_parser::debug_message('Test Result Montioring Process Returning: ' . $result_value);161 self::gen_result_active_handle($test_run_request)->add_trial_run_result($result_value);162 $did_post_result = true;163 }164 }165 return $did_post_result;166 }167 public static function parse_result(&$test_run_request, $test_log_file)168 {169 $produced_result = false;170 if($test_run_request->test_profile->get_file_parser_spec() == false)171 {172 return $produced_result;173 }174 $extra_arguments = $test_run_request->get_arguments();175 $pts_test_arguments = trim($test_run_request->test_profile->get_default_arguments() . ' ' . str_replace($test_run_request->test_profile->get_default_arguments(), '', $extra_arguments) . ' ' . $test_run_request->test_profile->get_default_post_arguments());176 switch($test_run_request->test_profile->get_display_format())177 {178 case 'IMAGE_COMPARISON':179 $produced_result = self::parse_iqc_result($test_run_request, $test_log_file, $pts_test_arguments, $extra_arguments);180 break;181 case 'PASS_FAIL':182 case 'MULTI_PASS_FAIL':183 case 'BAR_GRAPH':184 default:185 $produced_result = self::parse_result_process($test_run_request, $test_log_file, $pts_test_arguments, $extra_arguments);186 break;187 }188 return $produced_result;189 }190 public static function generate_extra_data(&$test_result, &$test_log_file = null)191 {192 $definitions = $test_result->test_profile->get_results_definition('ExtraData');193 foreach($definitions->get_system_monitor_definitions() as $entry)194 {195 $frame_all_times = array();196 switch(($eid = $entry->get_identifier()))197 {198 case 'libframetime-output':199 case 'libframetime-output-no-limit':200 // libframetime output201 $line_values = explode(PHP_EOL, file_get_contents($test_log_file));202 if(!empty($line_values) && isset($line_values[3]))203 {204 foreach($line_values as &$v)205 {206 if(substr($v, -3) == ' us' && substr($v, 0, 10) == 'Frametime ')207 {208 $frametime = substr($v, 10);209 $frametime = substr($frametime, 0, -3);210 if($eid == 'libframetime-output-no-limit' || $frametime > 2000)211 {212 $frametime = $frametime / 1000;213 $frame_all_times[] = $frametime;214 }215 }216 }217 $frame_all_times = pts_math::remove_outliers($frame_all_times);218 }219 break;220 case 'csv-dump-frame-latencies':221 // Civ Beyond Earth222 $csv_values = explode(',', pts_file_io::file_get_contents($test_log_file));223 if(!isset($csv_values[10]))224 {225 $csv_values = explode(PHP_EOL, pts_file_io::file_get_contents($test_log_file));226 }227 if(!empty($csv_values) && isset($csv_values[3]))228 {229 foreach($csv_values as $i => &$v)230 {231 if(!is_numeric($v))232 {233 unset($csv_values[$i]);234 continue;235 }236 $frame_all_times[] = $v;237 }238 }239 break;240 case 'com-speeds-frame-latency-totals':241 // id Tech Games242 $log_file = pts_file_io::file_get_contents($test_log_file);243 $frame_all_times = array();244 while(($log_file = strstr($log_file, 'frame:')))245 {246 if(($a = strpos($log_file, ' all: ')) !== false && $a < strpos($log_file, "\n"))247 {248 $all = ltrim(substr($log_file, $a + 6));249 $all = substr($all, 0, strpos($all, ' '));250 if(is_numeric($all) && $all > 0)251 {252 $frame_all_times[] = $all;253 }254 }255 $log_file = strstr($log_file, 'bk:');256 }257 break;258 case 'cpu-frames-space-delimited':259 // HITMAN on Linux uses at least this method260 $log_file = pts_file_io::file_get_contents($test_log_file);261 $frame_all_times = array();262 if(($x = strpos($log_file, '---- CPU FRAMES ----')) !== false)263 {264 $log_file = trim(str_replace(PHP_EOL, ' ', substr($log_file, $x + strlen('---- CPU FRAMES ----'))));265 foreach(explode(' ', $log_file) as $inp)266 {267 if(is_numeric($inp) && $inp > 0)268 {269 $frame_all_times[] = round(1000 / $inp, 3); // since its reporting current frame270 }271 }272 }273 break;274 case 'gpu-frames-space-delimited':275 // HITMAN 2 uses at least this method276 $log_file = pts_file_io::file_get_contents($test_log_file);277 $frame_all_times = array();278 if(($x = strpos($log_file, '---- GPU FRAMES ----')) !== false)279 {280 $log_file = trim(str_replace(PHP_EOL, ' ', substr($log_file, $x + strlen('---- GPU FRAMES ----'))));281 foreach(explode(' ', $log_file) as $inp)282 {283 if(is_numeric($inp) && $inp > 0)284 {285 $frame_all_times[] = round(1000 / $inp, 3); // since its reporting current frame286 }287 }288 }289 break;290 case 'valve-source-frame-times':291 // Counter-Strike: GO At least292 $log_file = pts_file_io::file_get_contents($test_log_file);293 $frame_all_times = array();294 if(($x = strpos($log_file, 'demo tick,frame start time,frame start delta')) !== false)295 {296 $log_file = substr($log_file, $x);297 foreach(explode(PHP_EOL, $log_file) as $line)298 {299 $line = explode(',', $line);300 if(isset($line[2]) && is_numeric($line[2]) && $line[2] > 0)301 {302 $frame_all_times[] = $line[2] * 1000;303 }304 }305 }306 break;307 case 'csv-f1-frame-times':308 // F1 2018309 $log_file = pts_file_io::file_get_contents($test_log_file);310 $frame_all_times = array();311 if(($x = strpos($log_file, 'Frame,Time (ms)')) !== false)312 {313 $log_file = substr($log_file, $x);314 foreach(explode(PHP_EOL, $log_file) as $line)315 {316 $line = explode(',', $line);317 if(isset($line[1]) && is_numeric($line[1]) && $line[1] > 0)318 {319 $frame_all_times[] = $line[1];320 }321 }322 }323 break;324 case 'csv-individual-frame-times':325 // Thrones of Britannia on Linux uses at least this method326 $log_file = pts_file_io::file_get_contents($test_log_file);327 $frame_all_times = array();328 if(($x = strpos($log_file, 'individual frame times (ms):')) !== false)329 {330 $log_file = trim(str_replace(PHP_EOL, ' ', substr($log_file, $x + strlen('individual frame times (ms): '))));331 foreach(explode(', ', $log_file) as $inp)332 {333 if(is_numeric($inp) && $inp > 0)334 {335 $frame_all_times[] = $inp;336 }337 else338 {339 // hitting the end340 break;341 }342 }343 }344 break;345 }346 if(isset($frame_all_times[60]))347 {348 // Take off the first frame as it's likely to have taken much longer when game just starting off...349 // array_shift($frame_all_times);350 $tp = clone $test_result->test_profile;351 $tp->set_result_scale('Milliseconds');352 $tp->set_result_proportion('LIB');353 $tp->set_display_format('LINE_GRAPH');354 $tp->set_identifier(null);355 $extra_result = new pts_test_result($tp);356 $extra_result->active = new pts_test_result_buffer_active();357 $extra_result->set_used_arguments_description($test_result->get_arguments_description() . ' - Total Frame Time');358 $extra_result->set_used_arguments($test_result->get_arguments() . ' - ' . $extra_result->get_arguments_description()); // this formatting is weird but to preserve pre-PTS7 comparsions of extra results359 $extra_result->active->set_result(implode(',', $frame_all_times));360 self::gen_result_active_handle($test_result, $extra_result)->add_trial_run_result(implode(',', $frame_all_times));361 //$extra_result->set_used_arguments(phodevi::sensor_name($sensor) . ' ' . $test_result->get_arguments());362 }363 }364 }365 protected static function parse_iqc_result(&$test_run_request, $log_file, $pts_test_arguments, $extra_arguments)366 {367 if(!extension_loaded('gd'))368 {369 // Needs GD library to work370 return false;371 }372 $returns = false;373 $definitions = $test_run_request->test_profile->get_results_definition('ImageParser');374 foreach($definitions->get_system_monitor_definitions() as $entry)375 {376 $match_test_arguments = $entry->get_match_to_image_args();377 if(!empty($match_test_arguments) && strpos($pts_test_arguments, $match_test_arguments) === false)378 {379 // This is not the ResultsParser XML section to use as the MatchToTestArguments does not match the PTS test arguments380 continue;381 }382 $iqc_source_file = $entry->get_source_image();383 if(is_file($test_run_request->test_profile->get_install_dir() . $iqc_source_file))384 {385 $iqc_source_file = $test_run_request->test_profile->get_install_dir() . $iqc_source_file;386 }387 else388 {389 // No image file found390 continue;391 }392 $img = pts_image::image_file_to_gd($iqc_source_file);393 if($img == false)394 {395 return;396 }397 $img_sliced = imagecreatetruecolor($entry->get_image_width(), $entry->get_image_height());398 imagecopyresampled($img_sliced, $img, 0, 0, $entry->get_image_x(), $entry->get_image_y(), $entry->get_image_width(), $entry->get_image_height(), $entry->get_image_width(), $entry->get_image_height());399 $test_result = $test_run_request->test_profile->get_install_dir() . 'iqc.png';400 imagepng($img_sliced, $test_result);401 if($test_result != false)402 {403 self::gen_result_active_handle($test_run_request)->add_trial_run_result($test_result);404 $returns = true;405 }406 }407 return $returns;408 }409 protected static function parse_result_process(&$test_run_request, $log_file, $pts_test_arguments, $extra_arguments, $prefix = null)410 {411 $produced_result = false;412 if($prefix != null && substr($prefix, -1) != '_')413 {414 $prefix .= '_';415 }416 $definitions = $test_run_request->test_profile->get_results_definition('ResultsParser');417 $all_parser_entries = $definitions->get_result_parser_definitions();418 $avoid_duplicates = array();419 foreach($all_parser_entries as $entry)420 {421 $tr = clone $test_run_request;422 if($entry->get_display_format() != null)423 {424 $tr->test_profile->set_display_format($entry->get_display_format());425 }426 $is_pass_fail_test = in_array($tr->test_profile->get_display_format(), array('PASS_FAIL', 'MULTI_PASS_FAIL'));427 $is_numeric_check = !$is_pass_fail_test;428 $min_result = null;429 $max_result = null;430 $min_test_result = false;431 $max_test_result = false;432 $test_result = self::parse_result_process_entry($tr, $log_file, $pts_test_arguments, $extra_arguments, $prefix, $entry, $is_pass_fail_test, $is_numeric_check, $all_parser_entries, $min_test_result, $max_test_result);433 if($test_result != false)434 {435 // Result found436 if(in_array($test_result, $avoid_duplicates))437 {438 // Workaround for some tests like FIO that have test result parsers that could generate duplicates in handling old PTS versions while newer ones have K conversion, etc439 continue;440 }441 $avoid_duplicates[] = $test_result;442 if($is_numeric_check)443 {444 // Check if this test reports a min result value445 $min_result = $min_test_result !== false && is_numeric($min_test_result) ? $min_test_result : self::parse_result_process_entry($tr, $log_file, $pts_test_arguments, $extra_arguments, 'MIN_', $entry, $is_pass_fail_test, $is_numeric_check, $all_parser_entries);446 // Check if this test reports a max result value447 $max_result = $max_test_result !== false && is_numeric($max_test_result) ? $max_test_result : self::parse_result_process_entry($tr, $log_file, $pts_test_arguments, $extra_arguments, 'MAX_', $entry, $is_pass_fail_test, $is_numeric_check, $all_parser_entries);448 }449 self::gen_result_active_handle($test_run_request, $tr)->add_trial_run_result($test_result, $min_result, $max_result);450 $produced_result = true;451 }452 }453 return $produced_result;454 }455 protected static function parse_result_process_entry(&$test_run_request, $log_file, $pts_test_arguments, $extra_arguments, $prefix, &$e, $is_pass_fail_test, $is_numeric_check, &$all_parser_entries, &$min_test_result = false, &$max_test_result = false)456 {457 $test_result = false;458 $match_test_arguments = $e->get_match_to_test_args();459 $template = $e->get_output_template();460 $multi_match = $e->get_multi_match();461 if(!empty($match_test_arguments) && strpos($pts_test_arguments, $match_test_arguments) === false)462 {463 // This is not the ResultsParser XML section to use as the MatchToTestArguments does not match the PTS test arguments464 pts_test_result_parser::debug_message('Failed Initial Check For Matching: ' . $pts_test_arguments . ' not in ' . $match_test_arguments);465 return false;466 }467 switch($e->get_result_key())468 {469 case 'PTS_TEST_ARGUMENTS':470 $key_for_result = '#_' . $prefix . str_replace(' ', '', $pts_test_arguments) . '_#';471 break;472 case 'PTS_USER_SET_ARGUMENTS':473 $key_for_result = '#_' . $prefix . str_replace(' ', '', $extra_arguments) . '_#';474 break;475 default:476 $key_for_result = '#_' . $prefix . 'RESULT_#';477 break;478 }479 // The actual parsing here480 $start_result_pos = strrpos($template, $key_for_result);481 $test_results = array();482 if($prefix != null && $start_result_pos === false && $template != 'csv-dump-frame-latencies' && $template != 'libframetime-output' && $e->get_file_format() == null)483 {484 // XXX: technically the $prefix check shouldn't be needed, verify whether safe to have this check be unconditional on start_result_pos failing...485 //pts_test_result_parser::debug_message('Failed Additional Check');486 return false;487 }488 pts_test_result_parser::debug_message('Result Key: ' . $key_for_result);489 if(is_file($log_file))490 {491 if(filesize($log_file) > 52428800)492 {493 pts_test_result_parser::debug_message('File Too Big To Parse: ' . $log_file);494 }495 $output = file_get_contents($log_file);496 }497 else498 {499 pts_test_result_parser::debug_message('No Log File Found To Parse');500 return false;501 }502 $space_out_chars = array('(', ')', "\t");503 switch($e->get_file_format())504 {505 case 'CSV':506 $space_out_chars[] = ',';507 break;508 case 'XML':509 $xml = simplexml_load_string($output, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_PARSEHUGE | LIBXML_NOCDATA);510 $xml = json_decode(json_encode((array)$xml), true);511 $x = $xml;512 foreach(explode('/', $template) as $p)513 {514 pts_test_result_parser::debug_message('XML Trying ' . $p);515 if(isset($x[$p]))516 {517 $x = $x[$p];518 }519 else520 {521 pts_test_result_parser::debug_message('XML Failed To Find ' . $p);522 break;523 }524 }525 if(isset($x))526 {527 if(!is_array($x))528 {529 pts_test_result_parser::debug_message('XML Value Found: ' . $x);530 $test_results[] = trim($x);531 }532 }533 goto RESULTPOSTPROCESSING;534 break;535 }536 if((isset($template[($start_result_pos - 1)]) && $template[($start_result_pos - 1)] == '/') || (isset($template[($start_result_pos + strlen($key_for_result))]) && $template[($start_result_pos + strlen($key_for_result))] == '/'))537 {538 $space_out_chars[] = '/';539 }540 $end_result_pos = $start_result_pos + strlen($key_for_result);541 $end_result_line_pos = strpos($template, "\n", $end_result_pos);542 $template_line = substr($template, 0, ($end_result_line_pos === false ? strlen($template) : $end_result_line_pos));543 $template_line = substr($template_line, strrpos($template_line, "\n"));544 pts_test_result_parser::debug_message('Template Line: ' . $template_line);545 $template_r = explode(' ', pts_strings::trim_spaces(str_replace($space_out_chars, ' ', str_replace('=', ' = ', $template_line))));546 $template_r_pos = array_search($key_for_result, $template_r);547 if($template_r_pos === false)548 {549 // Look for an element that partially matches, if like a '.' or '/sec' or some other pre/post-fix is present550 foreach($template_r as $x => $r_check)551 {552 if(isset($key_for_result[$x]) && strpos($r_check, $key_for_result[$x]) !== false)553 {554 $template_r_pos = $x;555 break;556 }557 }558 }559 // Check if frame time parsing info560 if(self::check_for_frame_time_parsing($test_results, $template, $output, $prefix))561 {562 // Was frame time info, nothing else to do for parsing, $test_results already filled then563 }564 else565 {566 // Conventional searching for matching section for finding result567 if($e->get_delete_output_before() != null && ($x = strpos($output, $e->get_delete_output_before())) !== false)568 {569 $output = substr($output, $x);570 }571 if($e->get_delete_output_after() != null && ($x = strpos($output, $e->get_delete_output_after())) !== false)572 {573 $output = substr($output, 0, $x);574 }575 $line_before_hint = $e->get_line_before_hint();576 $line_after_hint = $e->get_line_after_hint();577 $line_hint = $e->get_line_hint();578 $search_key = self::determine_search_key($output, $line_hint, $line_before_hint, $line_after_hint, $template_line, $template, $template_r, $key_for_result); // SEARCH KEY579 if($search_key != null || $line_before_hint != null || $line_after_hint != null || $template_r[0] == $key_for_result)580 {581 $is_multi_match = !empty($multi_match) && $multi_match != 'NONE';582 do583 {584 $count = count($test_results);585 $possible_lines = array();586 if($line_before_hint != null)587 {588 pts_test_result_parser::debug_message('Result Parsing Line Before Hint: ' . $line_before_hint);589 $line = substr($output, strpos($output, "\n", strrpos($output, $line_before_hint)));590 $line = substr($line, 0, strpos($line, "\n", 1));591 $output = substr($output, 0, strrpos($output, "\n", strrpos($output, $line_before_hint))) . "\n";592 }593 else if($line_after_hint != null)594 {595 pts_test_result_parser::debug_message('Result Parsing Line After Hint: ' . $line_after_hint);596 $line = substr($output, 0, strrpos($output, "\n", strrpos($output, $line_after_hint)));597 $line = substr($line, strrpos($line, "\n", 1) + 1);598 $output = null;599 }600 else if($search_key != null)601 {602 if(trim($search_key) != null)603 {604 $search_key = trim($search_key);605 }606 pts_test_result_parser::debug_message('Result Parsing Search Key: "' . $search_key . '"');607 while(($line_x = strrpos($output, $search_key)) !== false)608 {609 $line = substr($output, 0, strpos($output, "\n", $line_x));610 $start_of_line = strrpos($line, "\n");611 $output = substr($line, 0, $start_of_line) . "\n";612 $possible_lines[] = substr($line, $start_of_line + 1);613 if((count($possible_lines) > 16 && $is_multi_match && phodevi::is_windows()) || $multi_match == 'REPORT_ALL')614 {615 // This vastly speeds up pts/dav1d result decoding on Windows as this expensive loop not used616 break;617 }618 }619 $line = !empty($possible_lines) ? array_shift($possible_lines) : null;620 }621 else622 {623 // Condition $template_r[0] == $key, include entire file since there is nothing to search624 pts_test_result_parser::debug_message('No Result Parsing Hint, Including Entire Result Output');625 $line = trim($output);626 }627 if($e->get_turn_chars_to_space() != null)628 {629 $line = str_replace($e->get_turn_chars_to_space(), ' ', $line);630 }631 pts_test_result_parser::debug_message('Result Line: ' . $line);632 // FALLBACK HELPERS FOR BELOW633 $did_try_colon_fallback = false;634 do635 {636 $try_again = false;637 $r = explode(' ', pts_strings::trim_spaces(str_replace($space_out_chars, ' ', str_replace('=', ' = ', $line))));638 $r_pos = array_search($key_for_result, $r);639 if($e->get_result_before_string() != null)640 {641 // Using ResultBeforeString tag642 $before_this = array_search($e->get_result_before_string(), $r);643 if($before_this && isset($r[($before_this - 1)]))644 {645 $possible_res = $r[($before_this - 1)];646 self::strip_result_cleaner($possible_res, $e);647 if($before_this !== false && (!$is_numeric_check || self::valid_numeric_input_handler($possible_res, $line)))648 {649 $test_results[] = $possible_res;650 }651 }652 }653 else if($e->get_result_after_string() != null)654 {655 // Using ResultBeforeString tag656 $after_this = array_search($e->get_result_after_string(), $r);657 if($after_this !== false)658 {659 $after_this++;660 for($f = $after_this; $f < count($r); $f++)661 {662 if(in_array($r[$f], array(':', ',', '-', '=')))663 {664 continue;665 }666 self::strip_result_cleaner($r[$f], $e);667 if(!$is_numeric_check || self::valid_numeric_input_handler($r[$f], $line))668 {669 $test_results[] = $r[$f];670 }671 break;672 }673 }674 }675 else if(isset($r[$template_r_pos]))676 {677 self::strip_result_cleaner($r[$template_r_pos], $e);678 if(!$is_numeric_check || self::valid_numeric_input_handler($r[$template_r_pos], $line))679 {680 $test_results[] = $r[$template_r_pos];681 }682 }683 else684 {685 // POSSIBLE FALLBACKS TO TRY AGAIN686 if(!$did_try_colon_fallback && strpos($line, ':') !== false)687 {688 $line = str_replace(':', ': ', $line);689 $did_try_colon_fallback = true;690 $try_again = true;691 }692 }693 if($try_again == false && empty($test_results) && !empty($possible_lines))694 {695 $line = array_shift($possible_lines);696 pts_test_result_parser::debug_message('Trying Backup Result Line: ' . $line);697 $try_again = true;698 }699 else if(!empty($test_results) && $is_multi_match && !empty($possible_lines) && $search_key != null)700 {701 // Rebuild output if it was disassembled in search key code above702 $output = implode(PHP_EOL, array_reverse($possible_lines)) . PHP_EOL;703 }704 }705 while($try_again);706 }707 while($is_multi_match && count($test_results) != $count && !empty($output));708 }709 }710 RESULTPOSTPROCESSING:711 if(empty($test_results))712 {713 pts_test_result_parser::debug_message('No Test Results');714 return false;715 }716 $multiply_by = $e->get_multiply_result_by();717 $divide_by = $e->get_divide_result_by();718 $divide_divisor = $e->get_divide_result_divisor();719 foreach($test_results as $x => &$test_result)720 {721 self::strip_result_cleaner($test_result, $e);722 // Expand validity checking here723 if($is_numeric_check == true && is_numeric($test_result) == false)724 {725 // E.g. if output time as 06:12.32 (as in blender)726 if(substr_count($test_result, ':') == 1 && substr_count($test_result, '.') == 1 && strpos($test_result, '.') > strpos($test_result, ':'))727 {728 $minutes = substr($test_result, 0, strpos($test_result, ':'));729 $seconds = ' ' . substr($test_result, strpos($test_result, ':') + 1);730 $test_result = ($minutes * 60) + $seconds;731 }732 }733 if($is_numeric_check == true && is_numeric($test_result) == false)734 {735 unset($test_results[$x]);736 continue;737 }738 if($divide_by != null && is_numeric($divide_by) && $divide_by != 0)739 {740 $test_result = $test_result / $divide_by;741 }742 if($divide_divisor != null && is_numeric($divide_divisor) && $divide_divisor != 0 && $test_result != 0)743 {744 $test_result = $divide_divisor / $test_result;745 }746 if($multiply_by != null && is_numeric($multiply_by) && $multiply_by != 0)747 {748 $test_result = $test_result * $multiply_by;749 }750 }751 if(empty($test_results))752 {753 pts_test_result_parser::debug_message('No Test Results #2');754 return false;755 }756 $test_results_group_precision = pts_math::get_precision($test_results);757 switch($multi_match)758 {759 case 'REPORT_ALL':760 $test_result = implode(',', $test_results);761 $e->set_display_format('LINE_GRAPH');762 $is_numeric_check = false;763 break;764 case 'GEOMETRIC_MEAN':765 if($is_numeric_check)766 {767 $test_result = round(pts_math::geometric_mean($test_results), $test_results_group_precision);768 if(count($test_results) > 1)769 {770 $min_test_result = min($test_results);771 $max_test_result = max($test_results);772 }773 break;774 }775 case 'HARMONIC_MEAN':776 if($is_numeric_check)777 {778 $test_result = round(pts_math::harmonic_mean($test_results), $test_results_group_precision);779 if(count($test_results) > 1)780 {781 $min_test_result = min($test_results);782 $max_test_result = max($test_results);783 }784 break;785 }786 case 'AVERAGE':787 case 'MEAN':788 default:789 if($is_numeric_check)790 {791 $test_result = round(pts_math::arithmetic_mean($test_results), $test_results_group_precision);792 if(count($test_results) > 1)793 {794 $min_test_result = min($test_results);795 $max_test_result = max($test_results);796 }797 }798 break;799 }800 if($is_pass_fail_test)801 {802 if(str_replace(array('PASS', 'FAIL', ','), null, $test_result) == null)803 {804 // already a properly formatted multi-pass fail805 }806 else if($test_result == 'TRUE' || $test_result == 'PASSED')807 {808 // pass809 $test_result = 'PASS';810 }811 else812 {813 // fail814 $test_result = 'FAIL';815 }816 }817 else if($is_numeric_check && !is_numeric($test_result))818 {819 // Final check to ensure valid data820 $test_result = false;821 }822 if($test_result != false)823 {824 if($e->get_result_scale() != null)825 {826 $test_run_request->test_profile->set_result_scale($e->get_result_scale());827 }828 if($e->get_result_proportion() != null)829 {830 $test_run_request->test_profile->set_result_proportion($e->get_result_proportion());831 }832 if($e->get_display_format() != null)833 {834 $test_run_request->test_profile->set_display_format($e->get_display_format());835 }836 if($e->get_result_precision() != null)837 {838 $test_run_request->set_result_precision($e->get_result_precision());839 }840 if($e->get_arguments_description() != null)841 {842 $test_run_request->set_used_arguments_description($e->get_arguments_description());843 }844 if($e->get_append_to_arguments_description() != null)845 {846 foreach($all_parser_entries as $parser_entry)847 {848 if($parser_entry->get_append_to_arguments_description() != null)849 {850 $test_run_request->remove_from_used_arguments_description(' - ' . $parser_entry->get_append_to_arguments_description());851 }852 }853 $test_run_request->append_to_arguments_description(' - ' . $e->get_append_to_arguments_description());854 }855 }856 pts_test_result_parser::debug_message('Test Result Parser Returning: ' . $test_result);857 return $test_result;858 }859 protected static function valid_numeric_input_handler(&$numeric_input, $line)860 {861 if(is_numeric($numeric_input))862 {863 return true;864 }865 else if(is_numeric(str_ireplace(array('m', 'h', 's'), '', $numeric_input)))866 {867 // XXhXXmXXs format868 $vtime = 0;869 $ni = $numeric_input;870 foreach(array(3600 => 'h', 60 => 'm', 1 => 's') as $m => $u)871 {872 if(($x = stripos($ni, $u)) !== false)873 {874 $extracted = substr($ni, 0, $x);875 $ni = substr($ni, ($x + 1));876 if(is_numeric($extracted))877 {878 $vtime += $extracted * $m;879 }880 else881 {882 return false;883 }884 }885 }886 if($vtime > 0 && is_numeric($vtime))887 {888 $numeric_input = $vtime;889 return true;890 }891 }892 else if(strpos($numeric_input, ':') !== false && strpos($numeric_input, '.') !== false && is_numeric(str_replace(array(':', '.'), null, $numeric_input)) && stripos($line, 'time') !== false)893 {894 // Convert e.g. 03:03.17 to seconds, relevant for at least pts/blender895 $seconds = 0;896 $formatted_time = $numeric_input;897 if(($c = strpos($formatted_time, ':')) !== false && strrpos($formatted_time, ':') == $c && is_numeric(substr($formatted_time, 0, $c)))898 {899 $seconds = (substr($formatted_time, 0, $c) * 60) + substr($formatted_time, ($c + 1));900 }901 if(!empty($seconds))902 {903 $numeric_input = $seconds;904 return true;905 }906 }907 else if(strpos($numeric_input, ':') !== false && strtolower(substr($numeric_input, -1)) == 's')908 {909 // e.g. 01h:04m:33s910 $seconds = 0;911 $invalid = false;912 foreach(explode(':', $numeric_input) as $time_segment)913 {914 $postfix = strtolower(substr($time_segment, -1));915 $value = substr($time_segment, 0, -1);916 if($value == 0 || !is_numeric($value))917 {918 continue;919 }920 switch($postfix)921 {922 case 'h':923 $seconds += ($value * 3600);924 break;925 case 'm':926 $seconds += ($value * 60);927 break;928 case 's':929 $seconds += $value;930 break;931 default:932 $invalid = true;933 break;934 }935 }936 if(!empty($seconds) && $seconds > 0 && !$invalid)937 {938 $numeric_input = $seconds;939 return true;940 }941 }942 return false;943 }944 protected static function strip_result_cleaner(&$test_result, &$e)945 {946 if($e->get_strip_from_result() != null)947 {948 $test_result = str_replace($e->get_strip_from_result(), null, $test_result);949 }950 if($e->get_strip_result_postfix() != null && substr($test_result, 0 - strlen($e->get_strip_result_postfix())) == $e->get_strip_result_postfix())951 {952 $test_result = substr($test_result, 0, 0 - strlen($e->get_strip_result_postfix()));953 }954 if(!is_numeric($test_result) && is_numeric(substr($test_result, 0, -1)))955 {956 // The test_result is numeric except for the last character, possible k/M prefix or so957 // Or do any other format conversion here958 // Made in PTS 9.4, this shouldn't break any existing result-definitions since it would have been non-numeric here already959 $result_without_last_char = substr($test_result, 0, -1);960 switch(strtolower(substr($test_result, -1)))961 {962 case 'k':963 $test_result = $result_without_last_char * 1000;964 break;965 case 'm':966 $test_result = $result_without_last_char * 1000000;967 break;968 }969 }970 }971 protected static function determine_search_key(&$output, $line_hint, $line_before_hint, $line_after_hint, $template_line, $template, $template_r, $key)972 {973 // Determine the search key to use974 $search_key = null;975 if(isset($line_hint) && $line_hint != null && strpos($template_line, $line_hint) !== false)976 {977 $search_key = $line_hint;978 }979 else if($line_before_hint != null && $line_hint != null && strpos($template, $line_hint) !== false)980 {981 $search_key = null; // doesn't really matter what this value is982 }983 else if($line_after_hint != null && $line_hint != null && strpos($template, $line_hint) !== false)984 {985 $search_key = null; // doesn't really matter what this value is986 }987 else988 {989 $first_portion_of_line = substr($template_line, 0, strpos($template_line, $key));990 if($first_portion_of_line != null && strpos($output, $first_portion_of_line) !== false)991 {992 $search_key = $first_portion_of_line;993 }994 if($search_key == null)995 {996 foreach($template_r as $line_part)997 {998 if(strpos($line_part, ':') !== false && strlen($line_part) > 1)999 {1000 // add some sort of && strrpos($template, $line_part) to make sure there isn't two of the same $search_key1001 $search_key = $line_part;1002 break;1003 }1004 }1005 }1006 if($search_key == null && $key != null)1007 {1008 // Just try searching for the first part of the string1009 /*1010 for($i = 0; $i < $template_r_pos; $i++)1011 {1012 $search_key .= $template_r . ' ';1013 }1014 */1015 // This way if there are ) or other characters stripped, the below method will work where the above one will not1016 $search_key = substr($template_line, 0, strpos($template_line, $key));1017 }1018 }1019 return $search_key;1020 }1021 protected static function check_for_frame_time_parsing(&$test_results, $template, $output, $prefix)1022 {1023 $frame_time_values = null;1024 $returns = false;1025 if($template == 'libframetime-output' || $template == 'libframetime-output-no-limit')1026 {1027 $returns = true;1028 $frame_time_values = array();1029 $line_values = explode(PHP_EOL, $output);1030 if(!empty($line_values) && isset($line_values[3]))1031 {1032 foreach($line_values as &$v)1033 {1034 if(substr($v, -3) == ' us' && substr($v, 0, 10) == 'Frametime ')1035 {1036 $frametime = substr($v, 10);1037 $frametime = substr($frametime, 0, -3);1038 if($template == 'libframetime-output-no-limit' || $frametime > 2000)1039 {1040 $frametime = $frametime / 1000;1041 $frame_time_values[] = $frametime;1042 }1043 }1044 }1045 $frame_time_values = pts_math::remove_outliers($frame_time_values);1046 }1047 }1048 else if($template == 'csv-dump-frame-latencies')1049 {1050 $returns = true;1051 $frame_time_values = explode(',', $output);1052 }1053 if(!empty($frame_time_values) && isset($frame_time_values[3]))1054 {1055 // Get rid of the first value as likely outlier1056 array_shift($frame_time_values);1057 foreach($frame_time_values as $f => &$v)1058 {1059 if(!is_numeric($v) || $v == 0)1060 {1061 unset($frame_time_values[$f]);1062 continue;1063 }1064 $v = 1000 / $v;1065 }1066 switch($prefix)1067 {1068 case 'MIN_':1069 $val = min($frame_time_values);1070 break;1071 case 'MAX_':1072 $val = max($frame_time_values);1073 break;1074 case 'AVG_':1075 default:1076 $val = pts_math::arithmetic_mean($frame_time_values);1077 break;1078 }1079 if($val != 0)1080 {1081 $test_results[] = $val;1082 }1083 }1084 return $returns;1085 }1086 public static function debug_message($message)1087 {1088 $reported = false;1089 if(PTS_IS_CLIENT && pts_client::is_debug_mode())1090 {1091 if(($x = strpos($message, ': ')) !== false)1092 {1093 $message = pts_client::cli_colored_text(substr($message, 0, $x + 1), 'yellow', true) . pts_client::cli_colored_text(substr($message, $x + 1), 'yellow', false);1094 }1095 else1096 {1097 $message = pts_client::cli_colored_text($message, 'yellow', false);1098 }1099 pts_client::$display->test_run_instance_error($message);1100 $reported = true;...
debug_message
Using AI Code Generation
1require_once('pts_test_result_parser.php');2$parser = new pts_test_result_parser();3$parser->debug_message("This is a debug message");4require_once('pts_test_result_parser.php');5$parser = new pts_test_result_parser();6$parser->debug_message("This is a debug message");7require_once('pts_test_result_parser.php');8$parser = new pts_test_result_parser();9$parser->debug_message("This is a debug message");10require_once('pts_test_result_parser.php');11$parser = new pts_test_result_parser();12$parser->debug_message("This is a debug message");13require_once('pts_test_result_parser.php');14$parser = new pts_test_result_parser();15$parser->debug_message("This is a debug message");16require_once('pts_test_result_parser.php');17$parser = new pts_test_result_parser();18$parser->debug_message("This is a debug message");19require_once('pts_test_result_parser.php');20$parser = new pts_test_result_parser();21$parser->debug_message("This is a debug message");22require_once('pts_test_result_parser.php');23$parser = new pts_test_result_parser();24$parser->debug_message("This is a debug message");
debug_message
Using AI Code Generation
1require_once('pts_test_result_parser.php');2$parser = new pts_test_result_parser();3$parser->debug_message("This is a test debug message");4require_once('pts_test_result_parser.php');5$parser = new pts_test_result_parser();6$parser->debug_message("This is a test debug message");7require_once('pts_test_result_parser.php');8$parser = new pts_test_result_parser();9$parser->debug_message("This is a test debug message");10require_once('pts_test_result_parser.php');11$parser = new pts_test_result_parser();12$parser->debug_message("This is a test debug message");13require_once('pts_test_result_parser.php');14$parser = new pts_test_result_parser();15$parser->debug_message("This is a test debug message");16require_once('pts_test_result_parser.php');17$parser = new pts_test_result_parser();18$parser->debug_message("This is a test debug message");19require_once('pts_test_result_parser.php');20$parser = new pts_test_result_parser();21$parser->debug_message("This is a test debug message");22require_once('pts_test_result_parser.php');23$parser = new pts_test_result_parser();24$parser->debug_message("This is a test debug message");
debug_message
Using AI Code Generation
1require_once('pts_test_result_parser.php');2$parser = new pts_test_result_parser();3$parser->debug_message('This is a debug message');4require_once('pts_test_result_parser.php');5$parser = new pts_test_result_parser();6$parser->debug_mode(true);7require_once('pts_test_result_parser.php');8$parser = new pts_test_result_parser();9$result = $parser->get_result();10require_once('pts_test_result_parser.php');11$parser = new pts_test_result_parser();12$count = $parser->get_result_count();13require_once('pts_test_result_parser.php');14$parser = new pts_test_result_parser();15$identifier = $parser->get_result_identifier();16require_once('pts_test_result_parser.php');17$parser = new pts_test_result_parser();18$title = $parser->get_result_title();19require_once('pts_test_result_parser.php');20$parser = new pts_test_result_parser();21$title = $parser->get_result_title();22require_once('pts_test_result_parser.php');23$parser = new pts_test_result_parser();24$scale = $parser->get_result_scale();25require_once('pts_test_result_parser.php');26$parser = new pts_test_result_parser();
debug_message
Using AI Code Generation
1include_once('pts_test_result_parser.php');2$parser = new pts_test_result_parser();3$debug_messages = $parser->get_debug_messages('result.txt');4foreach($debug_messages as $message)5{6echo $message;7echo '<br>';8}
debug_message
Using AI Code Generation
1require_once('pts_test_result_parser.php');2$parser = new pts_test_result_parser();3$parser->parse_test_result_file('2.txt');4$parser->debug_message();5$parser->print_test_result();6$parser->print_test_result('csv');7$parser->print_test_result('xml');8$parser->print_test_result('json');9$parser->print_test_result('html');10require_once('pts_test_result_parser.php');11$parser = new pts_test_result_parser();12$parser->parse_test_result_file('3.txt');13$parser->debug_message();14$parser->print_test_result();15$parser->print_test_result('csv');16$parser->print_test_result('xml');17$parser->print_test_result('json');18$parser->print_test_result('html');19require_once('pts_test_result_parser.php');20$parser = new pts_test_result_parser();21$parser->parse_test_result_file('4.txt');22$parser->debug_message();23$parser->print_test_result();24$parser->print_test_result('csv');25$parser->print_test_result('xml');26$parser->print_test_result('json');27$parser->print_test_result('html');28require_once('pts_test_result_parser.php');29$parser = new pts_test_result_parser();30$parser->parse_test_result_file('5.txt');31$parser->debug_message();32$parser->print_test_result();33$parser->print_test_result('csv');34$parser->print_test_result('xml');35$parser->print_test_result('json');36$parser->print_test_result('html');37require_once('pts_test_result_parser.php');
debug_message
Using AI Code Generation
1$path = "2.php";2$test_result = new pts_test_result_parser($path);3$test_result->debug_message($path);4$path = "2.php";5$test_result = new pts_test_result_parser($path);6$test_result->debug_message($path);7$path = "2.php";8$test_result = new pts_test_result_parser($path);9$test_result->debug_message($path);10$path = "2.php";11$test_result = new pts_test_result_parser($path);12$test_result->debug_message($path);13$path = "2.php";14$test_result = new pts_test_result_parser($path);15$test_result->debug_message($path);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Execute automation tests with debug_message on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.
Test now for FreeGet 100 minutes of automation test minutes FREE!!