Files
phoronix-test-suite/pts-core/modules/system_monitor.php
Michael Larabel d719e4aa23 phodevi: Bug fixes
2024-03-24 14:10:15 -05:00

808 lines
28 KiB
PHP

<?php
/*
Phoronix Test Suite
URLs: http://www.phoronix.com, http://www.phoronix-test-suite.com/
Copyright (C) 2008 - 2020, Phoronix Media
Copyright (C) 2008 - 2020, Michael Larabel
system_monitor.php: System sensor monitoring module for PTS
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TODO XXX: Port to new phodevi_sensor_monitor interface
class system_monitor extends pts_module_interface
{
const module_name = 'System Monitor';
const module_version = '3.4.0';
const module_description = 'This module contains sensor monitoring support.';
const module_author = 'Michael Larabel';
private static $result_identifier = null;
private static $to_monitor = array();
private static $monitor_pids = array();
private static $monitor_test_count = 0;
private static $individual_test_run_request = null;
private static $successful_test_run_request = null;
private static $individual_test_run_offsets = null;
private static $test_run_tries_offsets = null;
private static $individual_monitoring = null;
private static $per_test_try_monitoring = null;
private static $cgroup_name = 'pts_monitor'; // default name for monitoring cgroup
private static $cgroup_enabled_controllers = array();
private static $test_run_try_number = null;
private static $sensor_monitoring_frequency = 1;
private static $test_run_timer = 0;
private static $perf_per_sensor_collection;
private static $perf_per_sensor = false;
public static function module_environment_variables()
{
return array('MONITOR', 'PERFORMANCE_PER_WATT', 'PERFORMANCE_PER_SENSOR', 'MONITOR_INTERVAL', 'MONITOR_PER_RUN' );
}
public static function module_info()
{
$info = null;
$info .= PHP_EOL . 'Monitoring these sensors is as easy as running your normal Phoronix Test Suite commands but at the beginning of the command add: MONITOR=<selected sensors>. For example, this will monitor the CPU temperature and voltage during tests: '
. PHP_EOL . PHP_EOL . ' MONITOR=cpu.temp,cpu.voltage phoronix-test-suite benchmark universe'
. PHP_EOL . PHP_EOL . 'For some of the sensors there is an ability to monitor specific device, e.g. cpu.usage.cpu0 or hdd.read-speed.sda. If the PERFORMANCE_PER_WATT environment variable is set, a performance per Watt graph will also be added, assuming the system\'s power consumption can be monitored. PERFORMANCE_PER_SENSOR= will allow similar behavior but for arbitrary sensors. Below are all of the sensors supported by this version of the Phoronix Test Suite.'
. PHP_EOL . PHP_EOL . 'Supported Options:' . PHP_EOL . PHP_EOL;
foreach(self::monitor_arguments() as $arg)
{
$info .= ' - ' . $arg . PHP_EOL;
}
$info .= PHP_EOL . 'NOTE: Use the "system-sensors" command to see what sensors are available for monitoring on the system.' . PHP_EOL;
return $info;
}
//
// General Functions
//
public static function __run_manager_setup(&$test_run_manager)
{
$test_run_manager->force_results_save();
//$test_run_manager->disable_dynamic_run_count();
}
public static function __pre_run_process(&$test_run_manager)
{
self::$result_identifier = $test_run_manager->get_results_identifier();
self::$individual_monitoring = pts_env::read('MONITOR_INDIVIDUAL') !== '0';
self::$per_test_try_monitoring = pts_env::read('MONITOR_PER_RUN') === '1';
self::$to_monitor = array();
try
{
$sensor_parameters = self::prepare_sensor_parameters();
self::enable_perf_per_sensor($sensor_parameters);
self::process_sensor_list($sensor_parameters);
self::create_monitoring_cgroups();
self::print_monitored_sensors();
self::set_monitoring_interval();
// Pad some idling sensor results at the start
sleep((self::$sensor_monitoring_frequency * 8));
self::pts_start_monitoring();
}
catch(Exception $e)
{
echo PHP_EOL . 'Unloading system monitor: ' . $e->getMessage();
sleep(5);
return pts_module::MODULE_UNLOAD;
}
pts_env::set('FORCE_MIN_DURATION_PER_TEST', 1); // force each test to run at least one minute to ensure sufficient samples
}
public static function __pre_test_run($test_run_request)
{
self::$individual_test_run_request = clone $test_run_request;
// Just to pad in some idling into the run process
sleep(self::$sensor_monitoring_frequency);
// We're going to run the test for the first time (but will probably repeat it several times).
self::$test_run_try_number = 0;
self::save_log_offsets('run');
self::$test_run_timer = time();
}
public static function __test_running($test_process)
{
// Put the tested application into proper cgroups as soon as it starts.
foreach(self::$cgroup_enabled_controllers as $controller)
{
$proc_status = proc_get_status($test_process);
$parent_pid = $proc_status['pid'];
file_put_contents('/sys/fs/cgroup/' . $controller . '/' . self::$cgroup_name .'/tasks', $parent_pid);
}
if(self::$per_test_try_monitoring)
{
self::save_log_offsets('try');
}
}
public static function __interim_test_run()
{
if(self::$per_test_try_monitoring)
{
self::$test_run_try_number++;
self::save_log_offsets('try');
}
}
public static function __post_test_run_success($test_run_request)
{
if(self::$per_test_try_monitoring)
{
self::$test_run_try_number++;
self::save_log_offsets('try');
}
self::$successful_test_run_request = clone $test_run_request;
}
public static function __post_test_run_process(&$result_file)
{
// The self::$test_run_timer to contain how long each individual test run lasted, should anything else past this point want to use the info...
self::$test_run_timer = time() - self::$test_run_timer;
// Let the system return to brief idling..
//sleep(self::$sensor_monitoring_frequency * 8);
if(!empty(self::$perf_per_sensor))
{
self::process_perf_per_sensor($result_file);
}
if(self::$individual_monitoring != false && self::$successful_test_run_request)
{
foreach(self::$to_monitor as $sensor)
{
self::process_test_run_results($sensor, $result_file);
}
}
self::$test_run_tries_offsets = array();
self::$successful_test_run_request = null;
self::$individual_test_run_request = null;
self::$monitor_test_count++;
// Let the system rest before jumping to next test...
sleep((self::$sensor_monitoring_frequency * 6));
}
public static function __event_results_process(&$test_run_manager)
{
self::process_perf_per_sensor_collection($test_run_manager);
echo PHP_EOL . 'Finishing System Sensor Monitoring Process' . PHP_EOL;
foreach(self::$to_monitor as $sensor)
{
self::process_summary_results($sensor, $test_run_manager);
}
echo PHP_EOL;
foreach(self::$monitor_pids as $pid)
{
if(function_exists('posix_kill') && defined('SIGTERM'))
{
posix_kill($pid, SIGTERM);
}
else if(pts_client::executable_in_path('kill'))
{
shell_exec('kill ' . $pid . ' > /dev/null 2>&1');
}
else
{
// TODO XXX
continue;
}
if(function_exists('pcntl_waitpid'))
{
pcntl_waitpid($pid, $status);
}
}
self::$monitor_pids = array();
}
public static function __post_run_process()
{
foreach(self::$cgroup_enabled_controllers as $controller)
{
self::cgroup_remove(self::$cgroup_name, $controller);
}
}
private static function pts_start_monitoring()
{
$instant_sensors = array();
foreach(self::$to_monitor as $sensor)
{
$is_instant = $sensor->is_instant();
if($is_instant === false)
{
$pid = pts_module::pts_timed_function('pts_monitor_update', self::$sensor_monitoring_frequency, array(array($sensor)));
self::$monitor_pids[] = $pid;
}
else
{
$instant_sensors[] = $sensor;
}
}
if(!empty($instant_sensors))
{
$pid = pts_module::pts_timed_function('pts_monitor_update', self::$sensor_monitoring_frequency, array($instant_sensors));
self::$monitor_pids[] = $pid;
}
}
// Reads value of a single sensor, checks its correctness and saves it to the monitor log.
public static function pts_monitor_update($sensor_list)
{
foreach($sensor_list as $sensor)
{
$sensor_value = phodevi::read_sensor($sensor);
if($sensor_value != -1 && pts_module::is_file('logs/' . phodevi::sensor_object_identifier($sensor)))
{
pts_module::save_file('logs/' . phodevi::sensor_object_identifier($sensor), $sensor_value, true);
}
}
}
private static function parse_monitor_log($log_file, $start_offset = 0, $end_offset = -1)
{
$log_f = pts_module::read_file($log_file);
$line_breaks = explode(PHP_EOL, $log_f);
$results = array();
for($i = 0; $i < $start_offset && isset($line_breaks[$i]); $i++)
{
unset($line_breaks[$i]);
}
foreach($line_breaks as $line_number => $line)
{
if($end_offset != -1 && $line_number >= $end_offset)
{
break;
}
$line = trim($line);
if(!empty($line) && $line >= 0)
{
$results[] = $line;
}
}
if(count($results) > 0 && max($results) == 0)
{
$results = array();
}
return $results;
}
private static function monitor_arguments()
{
$args = array('all');
foreach(phodevi::available_sensors() as $sensor)
{
$supported_devices = call_user_func(array($sensor[2], 'get_supported_devices'));
if(!in_array('all.' . $sensor[0], $args))
{
$args[] = 'all.' . $sensor[0];
}
$args[] = phodevi::sensor_identifier($sensor);
if($supported_devices !== NULL)
{
$args[] = 'all.' . phodevi::sensor_identifier($sensor);
foreach($supported_devices as $device)
{
$args[] = phodevi::sensor_identifier($sensor) . '.' . $device;
}
}
}
return $args;
}
// Parse environment variable containing parameters of monitored sensors.
private static function prepare_sensor_parameters()
{
$sensor_list = pts_strings::comma_explode(pts_env::read('MONITOR'));
$to_monitor = array();
foreach($sensor_list as $sensor)
{
$sensor_split = pts_strings::trim_explode('.', $sensor);
if(!isset($sensor_split[1]))
{
continue;
}
// Set 'all' from the beginning (eg. all.cpu.frequency) as the last
// element (cpu.frequency.all). As sensor parameters are also supported
// now, it's handy to mark that we want to include all sensors of specified
// type (cpu.all) or just all supported parameters of specified sensor
// (cpu.frequency.all).
if($sensor_split[0] === 'all')
{
$sensor_split[] = 'all';
array_shift($sensor_split);
}
$type = &$sensor_split[0];
$name = &$sensor_split[1];
$parameter = &$sensor_split[2];
if(empty($to_monitor[$type][$name]))
{
$to_monitor[$type][$name] = array();
}
if($parameter !== NULL)
{
$to_monitor[$type][$name][] = $parameter;
}
}
return $to_monitor;
}
private static function enable_perf_per_sensor(&$sensor_parameters)
{
self::$perf_per_sensor = array();
if(pts_env::read('PERFORMANCE_PER_WATT'))
{
// We need to ensure the system power consumption is being tracked to get performance-per-Watt
self::$perf_per_sensor[] = array('sys', 'power');
echo PHP_EOL . 'Provide Performance-Per-Watt Metrics Using: ' . pts_client::cli_just_italic('sys.power') . PHP_EOL;
}
if(pts_env::read('PERFORMANCE_PER_SENSOR'))
{
// We need to ensure the system power consumption is being tracked to get performance-per-(arbitrary sensor)
foreach(explode(',', pts_env::read('PERFORMANCE_PER_SENSOR')) as $s)
{
$per_sensor = explode('.', $s);
if(count($per_sensor) == 2)
{
self::$perf_per_sensor[] = $per_sensor;
echo PHP_EOL . 'Providing Performance-Per-Sensor Metrics Using: ' . pts_client::cli_just_italic($per_sensor[0] . '.' . $per_sensor[1]) . PHP_EOL;
}
}
}
if(empty(self::$perf_per_sensor))
{
return false;
}
foreach(self::$perf_per_sensor as $i => $s)
{
if(empty($sensor_parameters[$s[0]][$s[1]]))
{
$sensor_parameters[$s[0]][$s[1]] = array();
}
self::$perf_per_sensor_collection[$i] = array();
}
}
// Create sensor objects basing on the sensor parameter array.
private static function process_sensor_list(&$sensor_parameters)
{
$monitor_all = array_key_exists('all', $sensor_parameters);
foreach(phodevi::query_sensors() as $sensor)
{
// instantiate sensor class if:
// a) we want to monitor all the available sensors,
// b) we want to monitor all the available sensors of the specified type,
// c) sensor type and name was passed in an environment variable
// ($sensor[0] is the type, $sensor[1] is the name, $sensor[2] is the class name)
$sensor_type_exists = array_key_exists($sensor[0], $sensor_parameters);
$sensor_name_exists = $sensor_type_exists && array_key_exists($sensor[1], $sensor_parameters[$sensor[0]]);
$monitor_all_of_this_type = $sensor_type_exists && array_key_exists('all', $sensor_parameters[$sensor[0]]);
$monitor_all_of_this_sensor = $sensor_type_exists && $sensor_name_exists
&& in_array('all', $sensor_parameters[$sensor[0]][$sensor[1]]);
$is_cgroup_sensor = $sensor[0] === 'cgroup';
if(($monitor_all && !$is_cgroup_sensor) || $monitor_all_of_this_type || $sensor_name_exists )
{
// in some cases we want to create objects representing every possible device supported by the sensor
$create_all = $monitor_all || $monitor_all_of_this_type || $monitor_all_of_this_sensor;
self::create_sensor_instances($sensor, $sensor_parameters, $create_all);
}
}
if(count(self::$to_monitor) == 0)
{
throw new Exception('No Supported Sensors Selected To Monitor');
sleep(2);
}
}
private static function create_sensor_instances(&$sensor, &$sensor_parameters, $create_all)
{
if($create_all)
{
self::create_all_sensor_instances($sensor);
return;
}
$sensor_instances = $sensor_parameters[$sensor[0]][$sensor[1]];
// If no instances specified, create one with default parameters.
if(empty($sensor_instances) )
{
self::create_single_sensor_instance($sensor, 0, NULL);
return;
}
// Create objects for all specified instances of the sensor.
foreach($sensor_instances as $instance => $param)
{
self::create_single_sensor_instance($sensor, $instance, $param);
}
}
// Create instances for all of the devices supported by specified sensor.
private static function create_all_sensor_instances(&$sensor)
{
$supported_devices = call_user_func(array($sensor[2], 'get_supported_devices'));
$instance_no = 0;
if($supported_devices === NULL)
{
self::create_single_sensor_instance($sensor, 0, NULL);
return;
}
foreach($supported_devices as $device)
{
self::create_single_sensor_instance($sensor, $instance_no++, $device);
}
}
// Create sensor object if parameters passed to it are correct.
private static function create_single_sensor_instance($sensor, $instance, $param)
{
if($sensor[0] === 'cgroup')
{
$cgroup_controller = call_user_func(array($sensor[2], 'get_cgroup_controller'));
pts_arrays::unique_push(self::$cgroup_enabled_controllers, $cgroup_controller );
self::cgroup_create(self::$cgroup_name, $cgroup_controller);
$param = self::$cgroup_name;
}
if(call_user_func(array($sensor[2], 'parameter_check'), $param) === true)
{
$sensor_object = new $sensor[2]($instance, $param);
self::$to_monitor[] = $sensor_object;
pts_module::save_file('logs/' . phodevi::sensor_object_identifier($sensor_object));
}
}
// Create cgroups in all of the needed controllers.
private static function create_monitoring_cgroups()
{
foreach(self::$cgroup_enabled_controllers as $controller)
{
self::cgroup_create(self::$cgroup_name, $controller);
}
}
private static function print_monitored_sensors()
{
echo PHP_EOL . 'Sensors To Be Logged:';
foreach(self::$to_monitor as &$sensor)
{
echo PHP_EOL . ' - ' . phodevi::sensor_object_name($sensor);
}
echo PHP_EOL;
}
private static function set_monitoring_interval()
{
if(pts_env::read('MONITOR_INTERVAL') != null)
{
$proposed_interval = pts_env::read('MONITOR_INTERVAL');
if(is_numeric($proposed_interval) && $proposed_interval >= 0.5)
{
self::$sensor_monitoring_frequency = $proposed_interval;
}
}
}
private static function cgroup_create($cgroup_name, $cgroup_controller)
{
//TODO if we allow custom cgroup names, we will have to add cgroup
//name checking ("../../../etc" isn't a sane name)
$sudo_cmd = PTS_CORE_STATIC_PATH . 'root-access.sh ';
$cgroup_path = '/sys/fs/cgroup/' . $cgroup_controller . '/' . $cgroup_name;
$return_val = null;
if(!is_dir($cgroup_path)) // cgroup filesystem doesn't allow to create regular files anyway
{
$current_user = exec('whoami');
$mkdir_cmd = 'mkdir ' . $cgroup_path;
$chmod_cmd = 'chown ' . $current_user . ' ' . $cgroup_path . '/tasks';
$command = $sudo_cmd . '"' . $mkdir_cmd . ' && ' . $chmod_cmd . '"';
exec($command);
}
if(!is_writable($cgroup_path . '/tasks'))
{
throw new Exception('could not create cgroups');
}
}
private static function cgroup_remove($cgroup_name, $cgroup_controller)
{
$sudo_cmd = PTS_CORE_STATIC_PATH . 'root-access.sh ';
$cgroup_path = '/sys/fs/cgroup/' . $cgroup_controller . '/' . $cgroup_name;
if(is_dir($cgroup_path)) // cgroup filesystem doesn't allow to create regular files anyway
{
$rmdir_cmd = 'rmdir ' . $cgroup_path;
shell_exec($sudo_cmd . $rmdir_cmd);
}
//TODO should probably return some result
}
// Saves offsets of sensor log files for the current test or for the specific test try.
// As sensor monitoring results are saved to the single file during the whole testing process,
// we need offset information to know where to start drawing chart for the individual test run from.
private static function save_log_offsets($type)
{
foreach(self::$to_monitor as &$sensor)
{
$log_f = pts_module::read_file('logs/' . phodevi::sensor_object_identifier($sensor));
$offset = count(explode(PHP_EOL, $log_f)) - 1; // as log file ends with an empty line
if($type === 'try')
{
self::$test_run_tries_offsets[phodevi::sensor_object_identifier($sensor)][self::$test_run_try_number] = $offset;
}
else if($type === 'run')
{
self::$individual_test_run_offsets[phodevi::sensor_object_identifier($sensor)] = $offset;
}
}
}
private static function process_perf_per_sensor(&$result_file)
{
foreach(self::$perf_per_sensor as $i => $s)
{
$sensor_results = self::parse_monitor_log('logs/' . phodevi::sensor_identifier($s), (isset(self::$individual_test_run_offsets[phodevi::sensor_identifier($s)]) ? self::$individual_test_run_offsets[phodevi::sensor_identifier($s)] : 0));
if(count($sensor_results) > 2 && self::$successful_test_run_request)
{
// Copy the value each time as if you are directly writing the original data, each succeeding time in the loop the used arguments gets borked
$original_parent_hash = self::$successful_test_run_request->get_comparison_hash(true, false);
$test_result = clone self::$successful_test_run_request;
$unit = 'Watt';
$res_average = pts_math::arithmetic_mean($sensor_results);
switch(phodevi::read_sensor_unit($s))
{
case 'Milliwatts':
$res_average = $res_average / 1000;
case 'Watts':
break;
default:
$unit = phodevi::read_sensor_unit($s);
}
if(!empty($unit) && $res_average > 0 && $test_result->test_profile->get_display_format() == 'BAR_GRAPH')
{
$test_result->test_profile->set_identifier(null);
//$test_result->set_used_arguments_description(phodevi::sensor_name('sys.power') . ' Monitor');
//$test_result->set_used_arguments(phodevi::sensor_name('sys.power') . ' ' . $test_result->get_arguments());
$test_result->test_result_buffer = new pts_test_result_buffer();
$test_result->set_parent_hash($original_parent_hash);
if($test_result->test_profile->get_result_proportion() == 'HIB')
{
$test_result->test_profile->set_result_scale($test_result->test_profile->get_result_scale() . ' Per ' . $unit);
$test_result->test_result_buffer->add_test_result(self::$result_identifier, round($test_result->active->get_result() / $res_average, 3));
$ro = $result_file->add_result_return_object($test_result);
}
else if($test_result->test_profile->get_result_proportion() == 'LIB')
{
return; // with below code not rendering nicely
$test_result->test_profile->set_result_proportion('HIB');
$test_result->test_profile->set_result_scale('Performance Per ' . $unit);
$test_result->test_result_buffer->add_test_result(self::$result_identifier, round((1 / $test_result->active->get_result()) / $res_average, 3));
$ro = $result_file->add_result_return_object($test_result);
}
if($ro)
{
pts_client::$display->test_run_success_inline($ro);
}
self::$perf_per_sensor_collection[$i][] = $test_result->active->get_result();
}
}
}
}
// Saves average of perf-per-watt results to the result file.
private static function process_perf_per_sensor_collection(&$test_run_manager)
{
foreach(self::$perf_per_sensor as $i => $s)
{
if(is_array(self::$perf_per_sensor_collection[$i]) && count(self::$perf_per_sensor_collection[$i]) > 2)
{
// Performance per watt/sensor overall
$unit = phodevi::read_sensor_unit($s);
$avg = pts_math::geometric_mean(self::$perf_per_sensor_collection[$i]);
$test_profile = new pts_test_profile();
$test_result = new pts_test_result($test_profile);
$test_result->test_profile->set_test_title('Meta Performance Per ' . $unit);
$test_result->test_profile->set_identifier(null);
$test_result->test_profile->set_version(null);
$test_result->test_profile->set_result_proportion(null);
$test_result->test_profile->set_display_format('BAR_GRAPH');
$test_result->test_profile->set_result_scale('Performance Per ' . $unit);
$test_result->test_profile->set_result_proportion('HIB');
$test_result->set_used_arguments_description('Performance Per ' . $unit);
$test_result->set_used_arguments('Per-Per-' . $unit);
$test_result->test_result_buffer = new pts_test_result_buffer();
$test_result->test_result_buffer->add_test_result(self::$result_identifier, pts_math::set_precision($avg, 4));
$test_run_manager->result_file->add_result($test_result);
}
}
}
private static function process_test_run_results(&$sensor, &$result_file)
{
$result_buffer = new pts_test_result_buffer();
if(self::$per_test_try_monitoring)
{
self::prepare_per_try_results($sensor, $result_buffer);
}
else
{
$sensor_results = self::parse_monitor_log('logs/' . phodevi::sensor_object_identifier($sensor),
self::$individual_test_run_offsets[phodevi::sensor_object_identifier($sensor)]);
if(count($sensor_results) > 6)
{
$result_buffer->add_test_result(self::$result_identifier, implode(',', $sensor_results), implode(',', $sensor_results));
}
}
if($result_buffer->get_count() == 0)
{
return;
}
self::write_test_run_results($result_buffer, $result_file, $sensor);
self::$individual_test_run_offsets[phodevi::sensor_object_identifier($sensor)] = array();
self::$test_run_tries_offsets[phodevi::sensor_object_identifier($sensor)] = array();
}
private static function write_test_run_results(&$result_buffer, &$result_file, &$sensor)
{
// TODO result count checks should probably be done before cloning the test_result
// Copy the value each time as if you are directly writing the original data, each succeeding time in the loop the used arguments gets borked
if(!is_object(self::$individual_test_run_request))
return;
$test_result = clone self::$individual_test_run_request;
$test_result->set_parent_hash(self::$successful_test_run_request->get_comparison_hash(true, false));
if(pts_module_manager::is_module_attached('matisk'))
{
// TODO find some better way than adding a number to distinguish the results between the MATISK runs
$arguments_description = phodevi::sensor_object_name($sensor) . ' Monitor (test ' . count($result_file->get_systems()) . ')';
$arguments_try_description = phodevi::sensor_object_name($sensor) . ' Per Test Try Monitor (test ' . count($result_file->get_systems()) . ')';
}
else
{
$arguments_description = phodevi::sensor_object_name($sensor) . ' Monitor';
$arguments_try_description = phodevi::sensor_object_name($sensor) . ' Per Test Try Monitor';
}
$scale = phodevi::read_sensor_object_unit($sensor);
$test_result->test_profile->set_identifier(null);
$test_result->test_profile->set_result_proportion(stripos($scale, 'hertz') === false && stripos($scale, 'hz') === false ? 'LIB' : 'HIB');
$test_result->test_profile->set_display_format('LINE_GRAPH');
$test_result->test_profile->set_result_scale($scale);
$test_result->set_used_arguments_description($arguments_description);
$test_result->set_used_arguments(phodevi::sensor_object_name($sensor) . ' ' . $test_result->get_arguments());
$test_result->test_result_buffer = $result_buffer;
if(self::$per_test_try_monitoring && $result_buffer->get_count() > 1)
{
$test_result->set_used_arguments_description($arguments_try_description);
}
$ro = $result_file->add_result_return_object($test_result);
if($ro)
{
pts_client::$display->test_run_success_inline($ro);
}
}
private static function prepare_per_try_results(&$sensor, &$result_buffer)
{
$sensor_offsets = self::$test_run_tries_offsets[phodevi::sensor_object_identifier($sensor)];
for($try_number = 1; $try_number <= self::$test_run_try_number; $try_number++)
{
$start_offset = $sensor_offsets[$try_number - 1];
$end_offset = $sensor_offsets[$try_number];
$sensor_results = self::parse_monitor_log('logs/' . phodevi::sensor_object_identifier($sensor),
$start_offset, $end_offset);
if(count($sensor_results) > 2)
{
$result_identifier = self::$result_identifier . " (try " . ($try_number) . ")";
$result_value = implode(',', $sensor_results);
$result_buffer->add_test_result($result_identifier, $result_value, $result_value);
}
}
}
// Generates summary result (covering all test runs) for specified sensor and adds it to the result file.
private static function process_summary_results(&$sensor, &$test_run_manager)
{
$sensor_results = self::parse_monitor_log('logs/' . phodevi::sensor_object_identifier($sensor));
pts_module::remove_file('logs/' . phodevi::sensor_object_identifier($sensor));
if(count($sensor_results) > 2 && self::$monitor_test_count > 1)
{
$test_profile = new pts_test_profile();
$test_result = new pts_test_result($test_profile);
$test_result->test_profile->set_test_title(phodevi::sensor_object_name($sensor) . ' Monitor');
$test_result->test_profile->set_identifier(null);
$test_result->test_profile->set_version(null);
$test_result->test_profile->set_result_proportion(null);
$test_result->test_profile->set_display_format('LINE_GRAPH');
$test_result->test_profile->set_result_scale(phodevi::read_sensor_object_unit($sensor));
$test_result->set_used_arguments_description('Phoronix Test Suite System Monitoring');
$test_result->set_used_arguments(phodevi::sensor_object_identifier($sensor));
$test_result->test_result_buffer = new pts_test_result_buffer();
$test_result->test_result_buffer->add_test_result(self::$result_identifier, implode(',', $sensor_results), implode(',', $sensor_results), implode(',', $sensor_results), implode(',', $sensor_results));
$ro = $test_run_manager->result_file->add_result_return_object($test_result);
if($ro)
{
pts_client::$display->test_run_success_inline($ro);
}
}
}
}
?>