public static function init_files()
 {
     // Don't let the process run multiple times...
     if (pts_config::$init_process_ran) {
         return false;
     }
     pts_config::$init_process_ran = true;
     // The main PTS user client config
     pts_config::user_config_generate();
     // Generate the graph config
     $json_pre = null;
     if (is_file(PTS_USER_PATH . 'graph-config.json')) {
         $json_pre = file_get_contents(PTS_USER_PATH . 'graph-config.json');
     } else {
         if (PTS_IS_CLIENT && is_file($t = PTS_CORE_STATIC_PATH . 'graph-config-template-' . phodevi::read_property('system', 'vendor-identifier') . '.json')) {
             $json_pre = file_get_contents($t);
         } else {
             if (is_file(PTS_CORE_STATIC_PATH . 'graph-config-template.json')) {
                 $json_pre = file_get_contents(PTS_CORE_STATIC_PATH . 'graph-config-template.json');
             }
         }
     }
     $json_graph = array();
     pts_Graph::set_default_graph_values($json_graph);
     if ($json_pre != null) {
         $json_pre = json_decode($json_pre, true);
         if (is_array($json_pre)) {
             $json_graph = array_merge($json_graph, $json_pre);
         }
     }
     pts_Graph::init_graph_config($json_graph);
     file_put_contents(PTS_USER_PATH . 'graph-config.json', pts_arrays::json_encode_pretty_string($json_graph));
 }
 public static function read_sensor()
 {
     // Determine current percentage for processor usage
     if (phodevi::is_linux() || phodevi::is_bsd()) {
         $start_load = self::cpu_load_array(-1);
         sleep(1);
         $end_load = self::cpu_load_array(-1);
         for ($i = 0; $i < count($end_load); $i++) {
             $end_load[$i] -= $start_load[$i];
         }
         $percent = ($sum = array_sum($end_load)) == 0 ? 0 : 100 - $end_load[count($end_load) - 1] * 100 / $sum;
     } else {
         if (phodevi::is_solaris()) {
             // TODO: Add support for monitoring load on a per-core basis (through mpstat maybe?)
             $info = explode(' ', pts_strings::trim_spaces(pts_arrays::last_element(explode("\n", trim(shell_exec('sar -u 1 1 2>&1'))))));
             $percent = $info[1] + $info[2];
         } else {
             if (phodevi::is_macosx()) {
                 // CPU usage for user
                 $top = shell_exec('top -n 1 -l 1 2>&1');
                 $top = substr($top, strpos($top, 'CPU usage: ') + 11);
                 $percent = substr($top, 0, strpos($top, '%'));
             } else {
                 $percent = null;
             }
         }
     }
     if (!is_numeric($percent) || $percent < 0 || $percent > 100) {
         $percent = -1;
     }
     return pts_math::set_precision($percent, 2);
 }
 public static function what_provides($files_needed)
 {
     $packages_needed = array();
     foreach (pts_arrays::to_array($files_needed) as $file) {
         if (pts_client::executable_in_path('apt-file')) {
             if (!defined('APT_FILE_UPDATED')) {
                 shell_exec('apt-file update 2>&1');
                 define('APT_FILE_UPDATED', 1);
             }
             // Try appending common paths
             if (strpos($file, '.h') !== false) {
                 $apt_provides = self::run_apt_file_provides('/usr/include/' . $file);
                 if ($apt_provides != null) {
                     $packages_needed[$file] = $apt_provides;
                 }
             } else {
                 if (strpos($file, '.so') !== false) {
                     $apt_provides = self::run_apt_file_provides('/usr/lib/' . $file);
                     if ($apt_provides != null) {
                         $packages_needed[$file] = $apt_provides;
                     }
                 } else {
                     foreach (array('/usr/bin/', '/bin/', '/usr/sbin') as $possible_path) {
                         $apt_provides = self::run_apt_file_provides($possible_path . $file);
                         if ($apt_provides != null) {
                             $packages_needed[$file] = $apt_provides;
                             break;
                         }
                     }
                 }
             }
         }
     }
     return $packages_needed;
 }
 public static function run($r)
 {
     $to_run = array();
     foreach (pts_types::identifiers_to_test_profile_objects($r, false, true) as $test_profile) {
         pts_arrays::unique_push($to_run, $test_profile);
     }
     pts_test_run_manager::standard_run($to_run);
 }
 public function __construct($result_file)
 {
     $result_object = null;
     parent::__construct($result_object, $result_file);
     // System Identifiers
     if ($result_file->is_multi_way_comparison()) {
         // Multi way comparisons currently render the overview graph as blank
         $this->skip_graph = true;
         return;
     }
     $this->system_identifiers = $result_file->get_system_identifiers();
     if (count($this->system_identifiers) < 2) {
         // No point in generating this when there is only one identifier
         $this->skip_graph = true;
         return;
     }
     $result_objects = array();
     $test_titles = array();
     foreach ($result_file->get_result_objects() as $result_object) {
         if ($result_object->test_profile->get_display_format() == 'BAR_GRAPH') {
             array_push($result_objects, $result_object);
             array_push($test_titles, $result_object->test_profile->get_title());
             foreach ($result_object->test_result_buffer->buffer_items as &$buffer_item) {
                 pts_arrays::unique_push($this->graph_identifiers, $buffer_item->get_result_identifier());
             }
         }
     }
     $result_object_count = count($result_objects);
     if ($result_object_count < 3) {
         // No point in generating this if there aren't many tests
         $this->skip_graph = true;
         return;
     }
     $result_file->override_result_objects($result_objects);
     // Test Titles
     $this->i['identifier_size'] = 6.5;
     $this->i['graph_width'] = 1000;
     list($longest_title_width, $longest_title_height) = pts_svg_dom::estimate_text_dimensions(pts_strings::find_longest_string($test_titles), $this->i['identifier_size']);
     $this->i['left_start'] += 20;
     $this->graphs_per_row = min(count($this->system_identifiers) > 10 ? 6 : 10, floor(($this->i['graph_width'] - $this->i['left_start'] - $this->i['left_end_right']) / ($longest_title_width + 4)));
     $this->graph_item_width = floor(($this->i['graph_width'] - $this->i['left_start'] - $this->i['left_end_right']) / $this->graphs_per_row);
     $this->graph_row_count = ceil($result_object_count / $this->graphs_per_row);
     $this->i['top_start'] += 20 + count($this->system_identifiers) / 3 * $this->i['identifier_size'];
     $height = $this->i['top_start'] + $this->graph_row_count * ($this->graph_row_height + 15);
     $this->graph_title = $result_file->get_title();
     $this->graph_y_title = null;
     $this->i['graph_proportion'] = 'HIB';
     $this->i['show_background_lines'] = true;
     $this->update_graph_dimensions($this->i['graph_width'], $height, true);
     $this->result_file = $result_file;
     return true;
 }
 public static function read_hal_property($udi, $key)
 {
     $value = false;
     if (pts_client::executable_in_path('hal-get-property')) {
         foreach (pts_arrays::to_array($udi) as $udi_check) {
             $value = trim(shell_exec('hal-get-property --udi ' . $udi_check . ' --key ' . $key . ' 2> /dev/null'));
             if ($value != false) {
                 break;
             }
         }
     }
     return $value;
 }
 public function add_test_profile($test_profile)
 {
     $added = false;
     if (($e = pts_client::read_env('SKIP_TESTS')) != false && (in_array($test_profile->get_identifier(false), pts_strings::comma_explode($e)) || in_array($test_profile->get_identifier(true), pts_strings::comma_explode($e)))) {
         //pts_client::$display->test_install_error($test_profile->get_identifier() . ' is being skipped from installation.');
     } else {
         if (($e = pts_client::read_env('SKIP_TESTING_SUBSYSTEMS')) != false && in_array(strtolower($test_profile->get_test_hardware_type()), pts_strings::comma_explode(strtolower($e)))) {
             //pts_client::$display->test_install_error($test_profile->get_identifier() . ' is being skipped from installation.');
         } else {
             $added = pts_arrays::unique_push($this->tests_to_install, new pts_test_install_request($test_profile));
         }
     }
     return $added;
 }
 public static function read_sysctl($desc)
 {
     // Read sysctl, used by *BSDs
     $info = false;
     if (pts_client::executable_in_path('sysctl')) {
         $desc = pts_arrays::to_array($desc);
         for ($i = 0; $i < count($desc) && empty($info); $i++) {
             $output = shell_exec('sysctl ' . $desc[$i] . ' 2>&1');
             if ((($point = strpos($output, ':')) > 0 || ($point = strpos($output, '=')) > 0) && strpos($output, 'unknown oid') === false && strpos($output, 'is invalid') === false && strpos($output, 'not available') === false) {
                 $info = trim(substr($output, $point + 1));
             }
         }
     }
     return $info;
 }
 public static function image_file_to_gd($img_file)
 {
     $img = false;
     switch (strtolower(pts_arrays::last_element(explode('.', $img_file)))) {
         case 'tga':
             $img = pts_image::imagecreatefromtga($img_file);
             break;
         case 'png':
             $img = imagecreatefrompng($img_file);
             break;
         case 'jpg':
         case 'jpeg':
             $img = imagecreatefromjpeg($img_file);
             break;
     }
     return $img;
 }
 public static function __pre_run_process(&$test_run_manager)
 {
     self::$result_identifier = $test_run_manager->get_results_identifier();
     self::$individual_monitoring = pts_module::read_variable('MONITOR_INDIVIDUAL') !== '0';
     self::$to_monitor = array();
     $to_show = pts_strings::comma_explode(pts_module::read_variable('MONITOR'));
     if (pts_module::read_variable('PERFORMANCE_PER_WATT')) {
         // We need to ensure the system power consumption is being tracked to get performance-per-Watt
         pts_arrays::unique_push($to_show, 'sys.power');
         self::$individual_monitoring = true;
         echo PHP_EOL . 'To Provide Performance-Per-Watt Outputs.' . PHP_EOL;
     }
     $monitor_all = in_array('all', $to_show);
     foreach (phodevi::supported_sensors() as $sensor) {
         if ($monitor_all || in_array(phodevi::sensor_identifier($sensor), $to_show) || in_array('all.' . $sensor[0], $to_show)) {
             array_push(self::$to_monitor, $sensor);
             pts_module::save_file('logs/' . phodevi::sensor_identifier($sensor));
         }
     }
     if (in_array('i915_energy', $to_show) && is_readable('/sys/kernel/debug/dri/0/i915_energy')) {
         // For now the Intel monitoring is a special case separate from the rest
         // of the unified sensor monitoring since we're not polling it every time but just pre/post test.
         self::$monitor_i915_energy = true;
     }
     if (count(self::$to_monitor) > 0) {
         echo PHP_EOL . 'Sensors To Be Logged:';
         foreach (self::$to_monitor as &$sensor) {
             echo PHP_EOL . '   - ' . phodevi::sensor_name($sensor);
         }
         echo PHP_EOL;
         if (pts_module::read_variable('MONITOR_INTERVAL') != null) {
             $proposed_interval = pts_module::read_variable('MONITOR_INTERVAL');
             if (is_numeric($proposed_interval) && $proposed_interval >= 1) {
                 self::$sensor_monitoring_frequency = $proposed_interval;
             }
         }
         // Pad some idling sensor results at the start
         sleep(self::$sensor_monitoring_frequency * 8);
     }
     pts_module::pts_timed_function('pts_monitor_update', self::$sensor_monitoring_frequency);
 }
 public static function run($r)
 {
     pts_client::$display->generic_heading('System Information');
     echo 'Hardware:' . PHP_EOL . phodevi::system_hardware(true) . PHP_EOL . PHP_EOL;
     echo 'Software:' . PHP_EOL . phodevi::system_software(true) . PHP_EOL . PHP_EOL;
     //
     // Processor Information
     //
     $cpu_flags = phodevi_cpu::get_cpu_flags();
     echo PHP_EOL . 'PROCESSOR:' . PHP_EOL . PHP_EOL;
     echo 'Core Count: ' . phodevi_cpu::cpuinfo_core_count() . PHP_EOL;
     echo 'Thread Count: ' . phodevi_cpu::cpuinfo_thread_count() . PHP_EOL;
     echo 'Cache Size: ' . phodevi_cpu::cpuinfo_cache_size() . ' KB' . PHP_EOL;
     echo 'Instruction Set Extensions: ' . phodevi_cpu::instruction_set_extensions() . PHP_EOL;
     echo 'AES Encryption: ' . ($cpu_flags & phodevi_cpu::get_cpu_feature_constant('aes') ? 'YES' : 'NO') . PHP_EOL;
     echo 'Energy Performance Bias: ' . ($cpu_flags & phodevi_cpu::get_cpu_feature_constant('epb') ? 'YES' : 'NO') . PHP_EOL;
     echo 'Virtualization: ' . (phodevi_cpu::virtualization_technology() ? phodevi_cpu::virtualization_technology() : 'NO') . PHP_EOL;
     // Other info
     foreach (pts_arrays::to_array(pts_test_run_manager::pull_test_notes(true)) as $test_note_head => $test_note) {
         echo ucwords(str_replace('-', ' ', $test_note_head)) . ': ' . $test_note . PHP_EOL;
     }
 }
 public static function what_provides($files_needed)
 {
     $packages_needed = array();
     foreach (pts_arrays::to_array($files_needed) as $file) {
         if (pts_client::executable_in_path('dnf')) {
             $dnf_provides = self::run_dnf_provides($file);
             if ($dnf_provides != null) {
                 $packages_needed[$file] = $dnf_provides;
             } else {
                 // Try appending common paths
                 if (strpos($file, '.h') !== false) {
                     $dnf_provides = self::run_dnf_provides('/usr/include/' . $file);
                     if ($dnf_provides != null) {
                         $packages_needed[$file] = $dnf_provides;
                     }
                 } else {
                     if (strpos($file, '.so') !== false) {
                         $dnf_provides = self::run_dnf_provides('/usr/lib/' . $file);
                         if ($dnf_provides != null) {
                             $packages_needed[$file] = $dnf_provides;
                         }
                     } else {
                         foreach (array('/usr/bin/', '/bin/', '/usr/sbin') as $possible_path) {
                             $dnf_provides = self::run_dnf_provides($possible_path . $file);
                             if ($dnf_provides != null) {
                                 $packages_needed[$file] = $dnf_provides;
                                 break;
                             }
                         }
                     }
                 }
             }
         }
     }
     return $packages_needed;
 }
Example #13
0
 public static function compact_result_file_test_object(&$mto, &$result_table = false, &$result_file, $extra_attributes = null)
 {
     $identifiers_inverted = $result_file && $result_file->is_multi_way_inverted();
     // TODO: this may need to be cleaned up, its logic is rather messy
     $condense_multi_way = isset($extra_attributes['condense_multi_way']);
     if (count($mto->test_profile->get_result_scale_offset()) > 0) {
         // It's already doing something
         return;
     }
     $scale_special = array();
     $days = array();
     $systems = array();
     $prev_date = null;
     $is_tracking = true;
     $sha1_short_count = 0;
     $buffer_count = $mto->test_result_buffer->get_count();
     if ($identifiers_inverted) {
         $system_index = 0;
         $date_index = 1;
     } else {
         $system_index = 1;
         $date_index = 0;
     }
     foreach ($mto->test_result_buffer->get_buffer_items() as $buffer_item) {
         $identifier = array_map('trim', explode(':', $buffer_item->get_result_identifier()));
         switch (count($identifier)) {
             case 2:
                 $system = $identifier[$system_index];
                 $date = $identifier[$date_index];
                 break;
             case 1:
                 $system = 0;
                 $date = $identifier[0];
                 break;
             default:
                 return;
                 break;
         }
         if (!isset($systems[$system])) {
             $systems[$system] = 0;
         }
         if (!isset($days[$date])) {
             $days[$date] = null;
         }
         if ($is_tracking) {
             // First do a dirty SHA1 hash check
             if (strlen($date) != 40 || strpos($date, ' ') !== false) {
                 if (($x = strpos($date, ' + ')) !== false) {
                     $date = substr($date, 0, $x);
                 }
                 // Check to see if only numeric changes are being made
                 $sha1_short_hash_ending = isset($date[7]) && ctype_alnum(substr($date, -8));
                 $date = str_replace('s', null, pts_strings::remove_from_string($date, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DASH | pts_strings::CHAR_DECIMAL));
                 if ($sha1_short_hash_ending) {
                     $sha1_short_count++;
                 }
                 if ($prev_date != null && $date != $prev_date && $sha1_short_hash_ending == false && $sha1_short_count < 3) {
                     $is_tracking = false;
                 }
                 $prev_date = $date;
             }
         }
     }
     if ($is_tracking) {
         $prev_date_r = explode(' ', $prev_date);
         if (count($prev_date_r) == 2 && ctype_alpha($prev_date_r[0])) {
             // This check should make it so when like testing every Ubuntu releases (Ubuntu 11.04, Ubuntu 11.10, etc) it's not in a line graph
             $is_tracking = false;
         }
     } else {
         if ($is_tracking == false && $sha1_short_count > 5) {
             // It's probably actually tracking..... based upon Stefan's Wine 1.4 example on 15 March 2012
             $is_tracking = true;
         }
     }
     foreach (array_keys($days) as $day_key) {
         $days[$day_key] = $systems;
     }
     $raw_days = $days;
     $json_days = $days;
     foreach ($mto->test_result_buffer->get_buffer_items() as $buffer_item) {
         $identifier = array_map('trim', explode(':', $buffer_item->get_result_identifier()));
         switch (count($identifier)) {
             case 2:
                 $system = $identifier[$system_index];
                 $date = $identifier[$date_index];
                 break;
             case 1:
                 $system = 0;
                 $date = $identifier[0];
                 break;
             default:
                 return;
                 break;
         }
         $days[$date][$system] = $buffer_item->get_result_value();
         $raw_days[$date][$system] = $buffer_item->get_result_raw();
         $json_days[$date][$system] = $buffer_item->get_result_json();
         if (!is_numeric($days[$date][$system])) {
             return;
         }
     }
     $mto->test_result_buffer = new pts_test_result_buffer();
     $day_keys = array_keys($days);
     if ($condense_multi_way) {
         $mto->set_used_arguments_description($mto->get_arguments_description() . ' | Composite Of: ' . implode(' - ', array_keys($days)));
         foreach (array_keys($systems) as $system_key) {
             $sum = 0;
             $count = 0;
             foreach ($day_keys as $day_key) {
                 $sum += $days[$day_key][$system_key];
                 $count++;
             }
             $mto->test_result_buffer->add_test_result($system_key, $sum / $count);
         }
     } else {
         $mto->test_profile->set_result_scale($mto->test_profile->get_result_scale() . ' | ' . implode(',', array_keys($days)));
         if ($is_tracking && $buffer_count < 16 && $result_file && pts_result_file_analyzer::analyze_result_file_intent($result_file) == false) {
             // It can't be a tracker if the result file is comparing hardware/software, etc
             $is_tracking = false;
         }
         switch ($mto->test_profile->get_display_format()) {
             //case 'HORIZONTAL_BOX_PLOT':
             //	$mto->test_profile->set_display_format('HORIZONTAL_BOX_PLOT_MULTI');
             //	break;
             case 'SCATTER_PLOT':
                 break;
             default:
                 $line_graph_type = 'LINE_GRAPH';
                 $mto->test_profile->set_display_format(!isset($extra_attributes['force_tracking_line_graph']) && (count($days) < 5 || $is_tracking == false && !isset($extra_attributes['force_line_graph_compact'])) ? 'BAR_ANALYZE_GRAPH' : $line_graph_type);
                 break;
         }
         foreach (array_keys($systems) as $system_key) {
             $results = array();
             $raw_results = array();
             $json_results = array();
             foreach ($day_keys as $day_key) {
                 array_push($results, $days[$day_key][$system_key]);
                 array_push($raw_results, $raw_days[$day_key][$system_key]);
                 pts_arrays::unique_push($json_results, $json_days[$day_key][$system_key]);
             }
             // TODO XXX: Make JSON data work for multi-way comparisons!
             if (count($json_results) == 1) {
                 $json = array_shift($json_results);
             } else {
                 $json = null;
             }
             $mto->test_result_buffer->add_test_result($system_key, implode(',', $results), implode(',', $raw_results), $json);
         }
     }
     if ($result_table !== false) {
         foreach (array_keys($systems) as $system_key) {
             foreach ($day_keys as $day_key) {
                 if (!isset($result_table[$system_key][$day_key])) {
                     $result_table[$system_key][$day_key] = array();
                 }
                 array_push($result_table[$system_key][$day_key], $days[$day_key][$system_key], $raw_days[$day_key][$system_key]);
             }
         }
     }
 }
 public function get_result_objects($select_indexes = -1)
 {
     if ($this->result_objects == null) {
         $this->result_objects = array();
         foreach ($this->xml->Result as $result) {
             array_push($this->result_objects, $this->get_result_object($result));
         }
     }
     if ($select_indexes != -1 && $select_indexes !== null) {
         $objects = array();
         if ($select_indexes == 'ONLY_CHANGED_RESULTS') {
             foreach ($this->result_objects as &$result) {
                 // Only show results where the variation was greater than or equal to 1%
                 if (abs($result->largest_result_variation(0.01)) >= 0.01) {
                     array_push($objects, $result);
                 }
             }
         } else {
             foreach (pts_arrays::to_array($select_indexes) as $index) {
                 if (isset($this->result_objects[$index])) {
                     array_push($objects, $this->result_objects[$index]);
                 }
             }
         }
         return $objects;
     }
     return $this->result_objects;
 }
 public static function result_file_to_text(&$result_file, $terminal_width = 80)
 {
     $result_output = null;
     $result_output .= $result_file->get_title() . PHP_EOL;
     $result_output .= $result_file->get_description() . PHP_EOL . PHP_EOL . PHP_EOL;
     $system_identifiers = array();
     $system_hardware = array();
     $system_software = array();
     foreach ($result_file->get_systems() as $system) {
         array_push($system_identifiers, $system->get_identifier());
         array_push($system_hardware, $system->get_hardware());
         array_push($system_software, $system->get_software());
     }
     for ($i = 0; $i < count($system_identifiers); $i++) {
         $result_output .= $system_identifiers[$i] . ': ' . PHP_EOL . PHP_EOL;
         $result_output .= "\t" . $system_hardware[$i] . PHP_EOL . PHP_EOL . "\t" . $system_software[$i] . PHP_EOL . PHP_EOL;
     }
     $longest_identifier_length = strlen(pts_strings::find_longest_string($system_identifiers)) + 2;
     foreach ($result_file->get_result_objects() as $result_object) {
         $result_output .= trim($result_object->test_profile->get_title() . ' ' . $result_object->test_profile->get_app_version() . PHP_EOL . $result_object->get_arguments_description());
         if ($result_object->test_profile->get_result_scale() != null) {
             $result_output .= PHP_EOL . '  ' . $result_object->test_profile->get_result_scale();
         }
         foreach ($result_object->test_result_buffer as &$buffers) {
             $max_value = 0;
             $min_value = pts_arrays::first_element($buffers)->get_result_value();
             foreach ($buffers as &$buffer_item) {
                 if ($buffer_item->get_result_value() > $max_value) {
                     $max_value = $buffer_item->get_result_value();
                 } else {
                     if ($buffer_item->get_result_value() < $min_value) {
                         $min_value = $buffer_item->get_result_value();
                     }
                 }
             }
             $longest_result = strlen($max_value) + 1;
             foreach ($buffers as &$buffer_item) {
                 $val = $buffer_item->get_result_value();
                 if (stripos($val, ',') !== false) {
                     $vals = explode(',', $val);
                     $val = 'MIN: ' . min($vals) . ' / AVG: ' . round(array_sum($vals) / count($vals), 2) . ' / MAX: ' . max($vals);
                 }
                 $result_output .= PHP_EOL . '    ' . $buffer_item->get_result_identifier() . ' ';
                 $result_length_offset = $longest_identifier_length - strlen($buffer_item->get_result_identifier());
                 if ($result_length_offset > 0) {
                     $result_output .= str_repeat('.', $result_length_offset) . ' ';
                 }
                 $result_output .= $val;
                 if (is_numeric($val)) {
                     $result_output .= str_repeat(' ', $longest_result - strlen($val)) . '|';
                     $current_line_length = strlen(substr($result_output, strrpos($result_output, PHP_EOL) + 1)) + 1;
                     $result_output .= str_repeat('=', round($val / $max_value * ($terminal_width - $current_line_length)));
                 }
             }
         }
         $result_output .= PHP_EOL . PHP_EOL;
     }
     return $result_output;
 }
 public static function read_sensors($attributes)
 {
     // Read LM_Sensors
     $value = false;
     if (isset(phodevi::$vfs->sensors)) {
         $sensors = phodevi::$vfs->sensors;
         $sensors_lines = explode("\n", $sensors);
         $attributes = pts_arrays::to_array($attributes);
         for ($j = 0; $j < count($attributes) && empty($value); $j++) {
             $attribute = $attributes[$j];
             for ($i = 0; $i < count($sensors_lines) && $value == false; $i++) {
                 $line = pts_strings::trim_explode(': ', $sensors_lines[$i]);
                 if (!isset($line[0])) {
                     continue;
                 }
                 $this_attribute = $line[0];
                 if ($this_attribute == $attribute) {
                     $this_remainder = trim(str_replace(array('+', '°'), ' ', $line[1]));
                     $this_value = substr($this_remainder, 0, strpos($this_remainder, ' '));
                     if (is_numeric($this_value) && $this_value > 0) {
                         $value = $this_value;
                     }
                 }
             }
         }
     }
     return $value;
 }
 public function remove_run($remove)
 {
     $remove = pts_arrays::to_array($remove);
     foreach ($this->systems as $i => &$s) {
         if (in_array($s->get_identifier(), $remove)) {
             unset($this->systems[$i]);
         }
     }
     foreach ($this->result_objects as &$result) {
         $result->test_result_buffer->remove($remove);
     }
 }
    public static function render_page_process($PATH)
    {
        $main = null;
        if (isset($PATH[0])) {
            $upload_ids = explode(',', $PATH[0]);
            foreach ($upload_ids as $i => $upload_id) {
                if (isset($upload_id[5]) && substr($upload_id, 0, 2) == 'S:') {
                    $t = explode(':', $upload_id);
                    $stmt = phoromatic_server::$db->prepare('SELECT UploadID, UploadTime FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':schedule_id', $t[1]);
                    $test_result_result = $stmt->execute();
                    $cutoff_time = is_numeric($t[2]) ? strtotime('today -' . $t[2] . ' days') : false;
                    while ($test_result_row = $test_result_result->fetchArray()) {
                        if ($cutoff_time !== false && strtotime($test_result_row['UploadTime']) < $cutoff_time) {
                            break;
                        }
                        $upload_ids[] = $test_result_row['UploadID'];
                    }
                    unset($upload_ids[$i]);
                }
            }
            $upload_ids = array_unique($upload_ids);
            $result_files = array();
            $display_rows = array();
            $system_types = array();
            $schedule_types = array();
            $trigger_types = array();
            $upload_times = array();
            $benchmark_tickets = array();
            $xml_result_hash = array();
            $tickets = array();
            foreach ($upload_ids as $id) {
                $result_share_opt = phoromatic_server::read_setting('force_result_sharing') ? '1 = 1' : 'AccountID = (SELECT AccountID FROM phoromatic_account_settings WHERE LetOtherGroupsViewResults = "1" AND AccountID = phoromatic_results.AccountID)';
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE PPRID = :pprid AND (AccountID = :account_id OR ' . $result_share_opt . ') LIMIT 1');
                $stmt->bindValue(':pprid', $id);
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $result = $stmt->execute();
                $row = $result->fetchArray();
                if (false && empty($row)) {
                    // TODO XXX
                    // XXX this code is ultimately dead
                    $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND UploadID = :upload_id LIMIT 1');
                    $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                    $stmt->bindValue(':upload_id', $id);
                    $result = $stmt->execute();
                    $row = $result->fetchArray();
                }
                if (empty($row)) {
                    continue;
                }
                $composite_xml = phoromatic_server::phoromatic_account_result_path($row['AccountID'], $row['UploadID']) . 'composite.xml';
                if (!is_file($composite_xml)) {
                    echo 'File Not Found: ' . $composite_xml;
                    return false;
                }
                $display_rows[$composite_xml] = $row;
                pts_arrays::unique_push($benchmark_tickets, $row['BenchmarkTicketID']);
                pts_arrays::unique_push($upload_times, $row['UploadTime']);
                pts_arrays::unique_push($xml_result_hash, $row['XmlUploadHash']);
                pts_arrays::unique_push($system_types, $row['SystemID']);
                pts_arrays::unique_push($schedule_types, $row['ScheduleID']);
                pts_arrays::unique_push($trigger_types, $row['Trigger']);
                pts_arrays::unique_push($tickets, $row['BenchmarkTicketID']);
                // Update view counter
                $stmt_view = phoromatic_server::$db->prepare('UPDATE phoromatic_results SET TimesViewed = (TimesViewed + 1) WHERE AccountID = :account_id AND UploadID = :upload_id');
                $stmt_view->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt_view->bindValue(':upload_id', $row['UploadID']);
                $stmt_view->execute();
            }
            $result_file_title = null;
            if (count($system_types) == 1) {
                $result_file_title = phoromatic_system_id_to_name($system_types[0]) . ' Tests';
            }
            if (!empty($tickets) && $tickets[0] != null) {
                $system_name_format = 'ORIGINAL_DATA';
            } else {
                if (count($trigger_types) == 1 && $trigger_types[0] != null && $benchmark_tickets[0] != null && count($display_rows) > 1) {
                    $system_name_format = 'TRIGGER_AND_SYSTEM';
                } else {
                    if (empty($schedule_types[0])) {
                        $system_name_format = 'ORIGINAL_DATA';
                    } else {
                        if (count($display_rows) == 1) {
                            $system_name_format = 'SYSTEM_NAME';
                        } else {
                            if (count($schedule_types) == 1 && count($system_types) == 1) {
                                $system_name_format = 'TRIGGER';
                                $result_file_title = phoromatic_schedule_id_to_name($schedule_types[0]);
                            } else {
                                if (count($schedule_types) == 1) {
                                    $system_name_format = 'TRIGGER_AND_SYSTEM';
                                } else {
                                    if (false && count($trigger_types) == 1) {
                                        // TODO XXX: this approach yields garbage strings generally without refining the selector
                                        // i.e. first make sure all the schedules match or are comparable
                                        $system_name_format = 'SYSTEM_AND_SCHEDULE';
                                    } else {
                                        $system_name_format = null;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (count($schedule_types) == 1 && $schedule_types[0] != 0) {
                self::$schedule_id = $schedule_types[0];
            }
            foreach ($display_rows as $composite_xml => $row) {
                //  $row['SystemID'] . ' ' . $row['ScheduleID'] . ' ' . $row['Trigger']
                switch ($system_name_format) {
                    case 'ORIGINAL_DATA':
                        $system_name = null;
                        break;
                    case 'SYSTEM_NAME':
                        $system_name = phoromatic_system_id_to_name($row['SystemID']);
                        break;
                    case 'TRIGGER':
                        $system_name = $row['Trigger'];
                        break;
                    case 'TRIGGER_AND_SYSTEM':
                        $system_name = phoromatic_system_id_to_name($row['SystemID']) . ': ' . $row['Trigger'];
                        break;
                    case 'SYSTEM_AND_SCHEDULE':
                        $system_name = phoromatic_schedule_id_to_name($row['ScheduleID']) . ': ' . $row['Trigger'];
                        break;
                    default:
                        $system_name = phoromatic_system_id_to_name($row['SystemID']) . ' - ' . phoromatic_schedule_id_to_name($row['ScheduleID']) . ' - ' . $row['Trigger'];
                }
                if ($system_name == null) {
                    $rf = new pts_result_file($composite_xml);
                    $identifiers = $rf->get_system_identifiers();
                    if (count($identifiers) == 1) {
                        $system_name = $identifiers[0];
                    }
                }
                $system_name = str_replace('.SYSTEM', phoromatic_system_id_to_name($row['SystemID']), $system_name);
                $system_name = str_replace('.GROUP', phoromatic_account_id_to_group_name($row['AccountID']), $system_name);
                $system_variables = explode(';', phoromatic_server::system_id_variables($row['SystemID'], $row['AccountID']));
                foreach ($system_variables as $var) {
                    $var = explode('=', $var);
                    if (count($var) == 2) {
                        $system_name = str_replace('.' . $var[0], $var[1], $system_name);
                    }
                }
                $result_files[] = new pts_result_merge_select($composite_xml, null, $system_name);
            }
            $result_file = new pts_result_file(null, true);
            $result_file->set_title('Phoromatic Results');
            if (!empty($result_files)) {
                $attributes = array('new_result_file_title' => $result_file_title);
                if (!empty($result_files)) {
                    $result_file->merge($result_files, $attributes);
                }
            }
            $extra_attributes = array();
            if (isset($_GET['upload_to_openbenchmarking'])) {
                $ob_url = pts_openbenchmarking_client::upload_test_result($result_file, false);
                if ($ob_url) {
                    header('Location: ' . $ob_url);
                }
            }
            $attribute_options = array('normalize_results' => 'normalize_result_buffer', 'sort_by_performance' => 'sort_result_buffer_values', 'sort_by_reverse' => 'reverse_result_buffer', 'sort_by_name' => 'sort_result_buffer', 'condense_comparison' => 'condense_multi_way', 'force_line_graph' => 'force_tracking_line_graph');
            $url_append = null;
            foreach ($attribute_options as $web_var => $attr_var) {
                if (isset($_REQUEST[$web_var])) {
                    $extra_attributes[$attr_var] = true;
                    $url_append .= '&' . $web_var . '=1';
                }
            }
            if (isset($_POST['transpose_comparison'])) {
                $result_file->invert_multi_way_invert();
            }
            $intent = null;
            if (isset($_GET['download']) && $_GET['download'] == 'csv') {
                $result_csv = pts_result_file_output::result_file_to_csv($result_file);
                header('Content-Description: File Transfer');
                header('Content-Type: application/csv');
                header('Content-Disposition: attachment; filename=phoromatic-result.csv');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . strlen($result_csv));
                ob_clean();
                flush();
                echo $result_csv;
                return;
            } else {
                if (isset($_GET['download']) && $_GET['download'] == 'txt') {
                    $result_txt = pts_result_file_output::result_file_to_text($result_file);
                    header('Content-Description: File Transfer');
                    header('Content-Type: application/txt');
                    header('Content-Disposition: attachment; filename=phoromatic-result.txt');
                    header('Expires: 0');
                    header('Cache-Control: must-revalidate');
                    header('Pragma: public');
                    header('Content-Length: ' . strlen($result_txt));
                    ob_clean();
                    flush();
                    echo $result_txt;
                    return;
                } else {
                    if (isset($_GET['download']) && $_GET['download'] == 'pdf') {
                        ob_start();
                        $_REQUEST['force_format'] = 'PNG';
                        // Force to PNG renderer
                        $_REQUEST['svg_dom_gd_no_interlacing'] = true;
                        // Otherwise FPDF will fail
                        $tdir = pts_client::create_temporary_directory();
                        pts_client::generate_result_file_graphs($result_file, $tdir, $extra_attributes);
                        $pdf = new pts_pdf_template($result_file->get_title(), null);
                        $pdf->AddPage();
                        $pdf->Image(PTS_CORE_STATIC_PATH . 'images/pts-308x160.png', 69, 85, 73, 38);
                        $pdf->Ln(120);
                        $pdf->WriteStatementCenter('www.phoronix-test-suite.com');
                        $pdf->Ln(15);
                        $pdf->WriteBigHeaderCenter($result_file->get_title());
                        $pdf->WriteText($result_file->get_description());
                        $pdf->AddPage();
                        $pdf->Ln(15);
                        $pdf->SetSubject($result_file->get_title() . ' Benchmarks');
                        //$pdf->SetKeywords(implode(', ', $identifiers));
                        $pdf->WriteHeader('Test Systems:');
                        foreach ($result_file->get_systems() as $s) {
                            $pdf->WriteMiniHeader($s->get_identifier());
                            $pdf->WriteText($s->get_hardware());
                            $pdf->WriteText($s->get_software());
                        }
                        $pdf->AddPage();
                        $placement = 1;
                        $results = $result_file->get_result_objects();
                        for ($i = 1; $i <= count($results); $i++) {
                            if (is_file($tdir . 'result-graphs/' . $i . '.png')) {
                                $pdf->Ln(100);
                                $pdf->Image($tdir . 'result-graphs/' . $i . '.png', 50, 40 + ($placement - 1) * 120, 120);
                            }
                            if ($placement == 2) {
                                $placement = 0;
                                if ($i != count($results)) {
                                    $pdf->AddPage();
                                }
                            }
                            $placement++;
                        }
                        ob_get_clean();
                        $pdf->Output('phoromatic.pdf', 'I');
                        //pts_file_io::delete($tdir, null, true);
                        return;
                    } else {
                        if (isset($_GET['download']) && $_GET['download'] == 'xml') {
                            echo $result_file->get_xml();
                            return;
                        }
                    }
                }
            }
            $main .= '<h1>' . $result_file->get_title() . '</h1>';
            $main .= phoromatic_annotate_entry('RESULT', implode(',', $upload_ids), 'TOP');
            if ($result_file->get_system_count() == 1 || ($intent = pts_result_file_analyzer::analyze_result_file_intent($result_file, $intent, true))) {
                $table = new pts_ResultFileCompactSystemsTable($result_file, $intent);
            } else {
                $table = new pts_ResultFileSystemsTable($result_file);
            }
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $table = new pts_ResultFileTable($result_file, $intent);
            $main .= '<p style="text-align: center; overflow: auto;" class="result_object">' . pts_render::render_graph_inline_embed($table, $result_file, $extra_attributes) . '</p>';
            $main .= '<div id="pts_results_area">';
            foreach ($result_file->get_result_objects(isset($_POST['show_only_changed_results']) ? 'ONLY_CHANGED_RESULTS' : -1) as $i => $result_object) {
                $main .= '<h2><a name="r-' . $i . '"></a><a name="' . $result_object->get_comparison_hash(true, false) . '"></a>' . $result_object->test_profile->get_title() . '</h2>';
                $main .= phoromatic_annotate_entry('RESULT', implode(',', $upload_ids), $result_object->get_comparison_hash(true, false));
                $main .= '<p class="result_object">';
                $main .= pts_render::render_graph_inline_embed($result_object, $result_file, $extra_attributes);
                $main .= '</p>';
            }
            $main .= '</div>';
        } else {
            // No result
        }
        $right = null;
        if (self::$schedule_id && !empty(self::$schedule_id)) {
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules WHERE AccountID = :account_id AND ScheduleID = :schedule_id LIMIT 1');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':schedule_id', self::$schedule_id);
            $result = $stmt->execute();
            $row = $result->fetchArray();
            if (!empty($row)) {
                $right .= '<h3><a href="?schedules/' . $row['ScheduleID'] . '">' . $row['Title'] . '</a></h3>';
                if (!empty($row['ActiveOn'])) {
                    $right .= '<p align="center"><strong>' . phoromatic_schedule_activeon_string($row['ActiveOn'], $row['RunAt']) . '</strong></p>';
                }
                $right .= '<p>Compare this result file to the latest results from the past: ';
                $right .= '<select name="view_results_from_past" id="view_results_from_past" onchange="phoromatic_jump_to_results_from(\'' . $row['ScheduleID'] . '\', \'view_results_from_past\', \'' . $PATH[0] . ',\');">';
                $oldest_upload_time = strtotime(phoromatic_oldest_result_for_schedule(self::$schedule_id));
                $opts = array('Week' => 7, 'Three Weeks' => 21, 'Month' => 30, 'Quarter' => 90, 'Six Months' => 180, 'Year' => 365);
                foreach ($opts as $str_name => $time_offset) {
                    if ($oldest_upload_time > time() - 86400 * $time_offset) {
                        break;
                    }
                    $right .= '<option value="' . $time_offset . '">' . $str_name . '</option>';
                }
                $right .= '<option value="all">All Results</option>';
                $right .= '</select>';
                $right .= '</p>';
            }
        }
        if (true) {
            $compare_results = array();
            $hash_matches = 0;
            $ticket_matches = 0;
            $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND ComparisonHash = :comparison_hash AND PPRID NOT IN (:pprid) ORDER BY UploadTime DESC LIMIT 12');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':comparison_hash', $result_file->get_contained_tests_hash(false));
            $stmt->bindValue(':pprid', implode(',', $upload_ids));
            $result = $stmt->execute();
            while ($row = $result->fetchArray()) {
                $compare_results[$row['PPRID']] = $row;
                $hash_matches++;
            }
            foreach ($benchmark_tickets as $ticket_id) {
                $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND BenchmarkTicketID = :ticket_id AND PPRID NOT IN (:pprid) ORDER BY UploadTime DESC LIMIT 12');
                $stmt->bindValue(':account_id', $_SESSION['AccountID']);
                $stmt->bindValue(':ticket_id', $ticket_id);
                $stmt->bindValue(':pprid', implode(',', $upload_ids));
                $result = $stmt->execute();
                while ($row = $result->fetchArray()) {
                    $compare_results[$row['PPRID']] = $row;
                    $ticket_matches++;
                }
            }
            if (!empty($compare_results)) {
                $right .= '<hr /><h3>Compare Results</h3><form name="compare_similar_results" onsubmit="return false;">
						<input type="hidden" value="' . implode(',', $upload_ids) . '" id="compare_similar_results_this" />';
                foreach ($compare_results as &$row) {
                    $right .= '<p><input type="checkbox" value="' . $row['PPRID'] . '" name="compare_results" /> ' . $row['Title'] . '<br /><em>' . phoromatic_system_id_to_name($row['SystemID'], $row['AccountID']) . '</em></p>';
                }
                $right .= '<p><input type="submit" value="Compare Results" id="compare_results_submit" onclick="javascript:phoromatic_do_custom_compare_results(this); return false;" /></p></form>';
                if ($ticket_matches > 3) {
                    $right .= '<p><a href="/results/ticket/' . $ticket_id . '">Find All Matching Results</a>';
                } else {
                    if ($hash_matches > 3) {
                        $right .= '<p><a href="/results/hash/' . $result_file->get_contained_tests_hash(false) . '">Find All Matching Results</a>';
                    }
                }
            }
        }
        if (count($upload_ids) > 1) {
            $checkbox_options = array('normalize_results' => 'Normalize Results', 'sort_by_performance' => 'Sort Results By Performance', 'sort_by_name' => 'Reverse Result By Identifier', 'sort_by_reverse' => 'Reverse Result Order', 'show_only_changed_results' => 'Show Only Results With Result Variation', 'force_line_graph' => 'Force Line Graph');
            if ($result_file->is_multi_way_comparison()) {
                $checkbox_options['condense_comparison'] = 'Condense Comparison';
                $checkbox_options['transpose_comparison'] = 'Transpose Comparison';
            }
            $right .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_result_view" method="post"><hr /><h3>Result Analysis Options</h3><p align="left">' . PHP_EOL;
            foreach ($checkbox_options as $val => $name) {
                $right .= '<input type="checkbox" name="' . $val . '" value="1" ' . (isset($_POST[$val]) ? 'checked="checked" ' : null) . '/> ' . $name . '<br />';
            }
            $right .= '<br /><input type="submit" value="Refresh Results"></p></form>';
        }
        if (self::$schedule_id && !empty(self::$schedule_id) && $system_types[0] && $trigger_types[0]) {
            $stmt = phoromatic_server::$db->prepare('SELECT UserContextStep FROM phoromatic_system_context_logs WHERE AccountID = :account_id AND ScheduleID = :schedule_id AND SystemID = :system_id AND TriggerID = :trigger_id');
            $stmt->bindValue(':account_id', $_SESSION['AccountID']);
            $stmt->bindValue(':system_id', $system_types[0]);
            $stmt->bindValue(':schedule_id', self::$schedule_id);
            $stmt->bindValue(':trigger_id', $trigger_types[0]);
            $result = $stmt->execute();
            if ($row = $result->fetchArray()) {
                $right .= '<hr /><h3>User Context Logs</h3>';
                do {
                    $right .= '<p><a href="?logs/context/' . $system_types[0] . ',' . self::$schedule_id . ',' . base64_encode($trigger_types[0]) . '">' . $row['UserContextStep'] . '</a></p>';
                } while ($row = $result->fetchArray());
            }
        }
        $right .= '<hr /><h3>Result Export</h3>';
        $right .= '<p><a href="/public.php?t=result&ut=' . implode(',', $upload_ids) . $url_append . '">Public Viewer</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=pdf' . $url_append . '">Download As PDF</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=csv">Download As CSV</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=xml">Download As XML</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&download=txt">Download As TEXT</a></p>';
        $right .= '<p><a href="?' . $_SERVER['QUERY_STRING'] . '/&upload_to_openbenchmarking">Upload To OpenBenchmarking.org</a></p>';
        if (is_file(phoromatic_server::phoromatic_account_result_path($_SESSION['AccountID'], $row['UploadID']) . 'system-logs.zip')) {
            $right .= '<hr /><p><a href="?logs/system/' . $row['UploadID'] . '">View System Logs</a></p>';
        }
        echo phoromatic_webui_header_logged_in();
        echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in($right));
        echo phoromatic_webui_footer();
    }
 public static function pts_timed_function($function, $time, $parameters = null)
 {
     if ($time < 0.5 && $time != -1 || $time > 300) {
         return;
     }
     //TODO improve accuracy by comparing time pre- and post- loop iteration
     if (function_exists('pcntl_fork')) {
         $pid = pcntl_fork();
         if ($pid != -1) {
             if ($pid) {
                 return $pid;
             } else {
                 $loop_continue = true;
                 /*
                 ML: I think this below check can be safely removed
                 $start_id = pts_unique_runtime_identifier();
                  && ($start_id == pts_unique_runtime_identifier() || $start_id == PTS_INIT_TIME)
                 */
                 while (pts_test_run_manager::test_run_process_active() !== -1 && is_file(PTS_USER_LOCK) && $loop_continue) {
                     //						if ($parameters == null || !is_array($parameters))
                     //						{
                     //							$parameters = array();
                     //						}
                     $parameter_array = pts_arrays::to_array($parameters);
                     call_user_func_array(array(self::module_name(), $function), $parameter_array);
                     if ($time > 0) {
                         sleep($time);
                     } else {
                         if ($time == -1) {
                             $loop_continue = false;
                         }
                     }
                 }
                 exit(0);
             }
         }
     } else {
         trigger_error('php-pcntl must be installed for the ' . self::module_name() . ' module.', E_USER_ERROR);
     }
 }
 public function subsystems_under_test()
 {
     $subsystems_to_test = array();
     foreach ($this->tests_to_run as $test_run_request) {
         pts_arrays::unique_push($subsystems_to_test, $test_run_request->test_profile->get_test_hardware_type());
     }
     return $subsystems_to_test;
 }
 private function cpu_usage_solaris()
 {
     //TODO test this on Solaris
     //TODO: Add support for monitoring load on a per-core basis (through mpstat maybe?)
     $info = explode(' ', pts_strings::trim_spaces(pts_arrays::last_element(explode("\n", trim(shell_exec('sar -u 1 1 2>&1'))))));
     $percent = $info[1] + $info[2];
     return $percent;
 }
 public static function create_compiler_mask(&$test_install_request)
 {
     if (phodevi::is_bsd()) {
         // XXX: Using the compiler-mask causes a number of tests to fail to properly install due to compiler issues with at least PC-BSD 10.0
         return false;
     }
     // or pass false to $test_install_request to bypass the test checks
     $compilers = array();
     $external_dependencies = $test_install_request != false ? $test_install_request->test_profile->get_external_dependencies() : false;
     if ($test_install_request === false || in_array('build-utilities', $external_dependencies)) {
         // Handle C/C++ compilers for this external dependency
         $compilers['CC'] = array(pts_strings::first_in_string(pts_client::read_env('CC'), ' '), 'gcc', 'clang', 'icc', 'pcc');
         $compilers['CXX'] = array(pts_strings::first_in_string(pts_client::read_env('CXX'), ' '), 'g++', 'clang++', 'cpp');
     }
     if ($test_install_request === false || in_array('fortran-compiler', $external_dependencies)) {
         // Handle Fortran for this external dependency
         $compilers['F9X'] = array(pts_strings::first_in_string(pts_client::read_env('F9X'), ' '), pts_strings::first_in_string(pts_client::read_env('F95'), ' '), 'gfortran', 'f90', 'f95', 'fortran');
     }
     if (empty($compilers)) {
         // If the test profile doesn't request a compiler external dependency, probably not compiling anything
         return false;
     }
     foreach ($compilers as $compiler_type => $possible_compilers) {
         // Compilers to check for, listed in order of priority
         $compiler_found = false;
         foreach ($possible_compilers as $i => $possible_compiler) {
             // first check to ensure not null sent to executable_in_path from env variable
             if ($possible_compiler && (($compiler_path = is_executable($possible_compiler)) || ($compiler_path = pts_client::executable_in_path($possible_compiler, 'ccache')))) {
                 // Replace the array of possible compilers with a string to the detected compiler executable
                 $compilers[$compiler_type] = $compiler_path;
                 $compiler_found = true;
                 break;
             }
         }
         if ($compiler_found == false) {
             unset($compilers[$compiler_type]);
         }
     }
     if (!empty($compilers)) {
         // Create a temporary directory that will be at front of PATH and serve for masking the actual compiler
         if ($test_install_request instanceof pts_test_install_request) {
             $mask_dir = pts_client::temporary_directory() . '/pts-compiler-mask-' . $test_install_request->test_profile->get_identifier_base_name() . $test_install_request->test_profile->get_test_profile_version() . '/';
         } else {
             $mask_dir = pts_client::temporary_directory() . '/pts-compiler-mask-' . rand(100, 999) . '/';
         }
         pts_file_io::mkdir($mask_dir);
         $compiler_extras = array('CC' => array('safeguard-names' => array('gcc', 'cc'), 'environment-variables' => 'CFLAGS'), 'CXX' => array('safeguard-names' => array('g++', 'c++'), 'environment-variables' => 'CXXFLAGS'), 'F9X' => array('safeguard-names' => array('gfortran', 'f95'), 'environment-variables' => 'F9XFLAGS'));
         foreach ($compilers as $compiler_type => $compiler_path) {
             $compiler_name = basename($compiler_path);
             $main_compiler = $mask_dir . $compiler_name;
             // take advantage of environment-variables to be sure they're found in the string
             $env_var_check = PHP_EOL;
             /*
             foreach(pts_arrays::to_array($compiler_extras[$compiler_type]['environment-variables']) as $env_var)
             {
             	// since it's a dynamic check in script could probably get rid of this check...
             	if(true || getenv($env_var))
             	{
             		$env_var_check .= 'if [[ $COMPILER_OPTIONS != "*$' . $env_var . '*" ]]' . PHP_EOL . 'then ' . PHP_EOL . 'COMPILER_OPTIONS="$COMPILER_OPTIONS $' . $env_var . '"' . PHP_EOL . 'fi' . PHP_EOL;
             	}
             }
             */
             // Write the main mask for the compiler
             file_put_contents($main_compiler, '#!/bin/bash' . PHP_EOL . 'COMPILER_OPTIONS="$@"' . PHP_EOL . $env_var_check . PHP_EOL . 'echo $COMPILER_OPTIONS >> ' . $mask_dir . $compiler_type . '-options-' . $compiler_name . PHP_EOL . $compiler_path . ' "$@"' . PHP_EOL);
             // Make executable
             chmod($main_compiler, 0755);
             // The two below code chunks ensure the proper compiler is always hit
             if ($test_install_request instanceof pts_test_install_request && !in_array($compiler_name, pts_arrays::to_array($compiler_extras[$compiler_type]['safeguard-names'])) && getenv($compiler_type) == false) {
                 // So if e.g. clang becomes the default compiler, since it's not GCC, it will ensure CC is also set to clang beyond the masking below
                 $test_install_request->special_environment_vars[$compiler_type] = $compiler_name;
             }
             // Just in case any test profile script is statically always calling 'gcc' or anything not CC, try to make sure it hits one of the safeguard-names so it redirects to the intended compiler under test
             foreach (pts_arrays::to_array($compiler_extras[$compiler_type]['safeguard-names']) as $safe_name) {
                 if (!is_file($mask_dir . $safe_name)) {
                     symlink($main_compiler, $mask_dir . $safe_name);
                 }
             }
         }
         if ($test_install_request instanceof pts_test_install_request) {
             $test_install_request->compiler_mask_dir = $mask_dir;
             // Appending the rest of the path will be done automatically within call_test_script
             $test_install_request->special_environment_vars['PATH'] = $mask_dir;
         }
         return $mask_dir;
     }
     return false;
 }
 public static function run($r)
 {
     $compare_tests = array();
     $compare_subsystems = array();
     foreach ($r as $test_object) {
         $test_object = pts_types::identifier_to_object($test_object);
         if ($test_object instanceof pts_test_profile) {
             array_push($compare_tests, $test_object->get_identifier(false));
             if (!isset($compare_subsystems[$test_object->get_test_hardware_type()])) {
                 $compare_subsystems[$test_object->get_test_hardware_type()] = 1;
             } else {
                 $compare_subsystems[$test_object->get_test_hardware_type()] += 1;
             }
         }
     }
     if (empty($compare_tests)) {
         $subsystem_under_test = pts_user_io::prompt_text_menu('Sub-System To Test', array('Processor', 'Graphics', 'Disk'));
     } else {
         arsort($compare_subsystems);
         $compare_subsystems = array_keys($compare_subsystems);
         $subsystem_under_test = array_shift($compare_subsystems);
     }
     $system_info = array_merge(phodevi::system_hardware(false), phodevi::system_software(false));
     $to_include = array();
     $to_exclude = array();
     if (isset($system_info[$subsystem_under_test])) {
         $compare_component = $system_info[$subsystem_under_test];
     } else {
         return;
     }
     switch ($subsystem_under_test) {
         case 'Processor':
             self::system_component_to_format($system_info, $to_include, array('OS', 'Compiler', 'Kernel', 'Motherboard'), true);
             break;
         case 'Graphics':
             self::system_component_to_format($system_info, $to_include, array('OS', 'Display Driver', 'OpenGL', 'Processor', 'Kernel', 'Desktop'), true);
             break;
         case 'OS':
             self::system_component_to_format($system_info, $to_include, array('Processor', 'Motherboard', 'Graphics', 'Disk'), true);
             self::system_component_to_format($system_info, $to_exclude, array('OS'));
             break;
         case 'Disk':
             self::system_component_to_format($system_info, $to_include, array('Processor', 'OS', 'Chipset', 'Motherboard', 'Kernel'), true);
             break;
     }
     $payload = array('subsystem_under_test' => $subsystem_under_test, 'component_under_test' => $compare_component, 'include_components' => implode(',', $to_include), 'exclude_components' => implode(',', $to_exclude), 'include_tests' => implode(',', $compare_tests));
     echo PHP_EOL . 'Querying test data from OpenBenchmarking.org...' . PHP_EOL;
     $json = pts_openbenchmarking::make_openbenchmarking_request('auto_generate_comparison', $payload);
     $json = json_decode($json, true);
     if (isset($json['auto_compare']['public_ids']) && isset($json['auto_compare']['count']) && $json['auto_compare']['count'] > 0) {
         echo 'Found ' . $json['auto_compare']['count'] . ' comparable results on OpenBenchmarking.org with a ' . $json['auto_compare']['accuracy'] . '% accuracy.' . PHP_EOL;
         $compare_results = array();
         foreach ($json['auto_compare']['public_ids'] as $public_id) {
             $result_xml = pts_openbenchmarking::clone_openbenchmarking_result($public_id, true);
             if ($result_xml) {
                 $result_file = new pts_result_file($result_xml);
                 $result_objects = $result_file->get_result_objects();
                 foreach ($result_objects as $i => &$result_object) {
                     if (!empty($compare_tests)) {
                         if (!in_array($result_object->test_profile->get_identifier(false), $compare_tests)) {
                             unset($result_objects[$i]);
                         }
                     } else {
                         if ($result_object->test_profile->get_test_hardware_type() != $subsystem_under_test) {
                             unset($result_objects[$i]);
                         }
                     }
                 }
                 if (count($result_objects) == 0) {
                     continue;
                 }
                 $result_file->override_result_objects($result_objects);
                 array_push($compare_results, $result_file);
             }
         }
         if (count($compare_results) > 0) {
             $result_xml = pts_merge::merge_test_results_array($compare_results);
             if (count($compare_results) > 2) {
                 $result_file = new pts_result_file($result_xml);
                 $result_objects = $result_file->get_result_objects();
                 $system_count = $result_file->get_system_count();
                 $result_count = count($result_objects);
                 $result_match_count = array();
                 if ($result_count > 3) {
                     foreach ($result_objects as $i => &$result_object) {
                         $result_match_count[$i] = $result_object->test_result_buffer->get_count();
                     }
                     arsort($result_match_count);
                     $biggest_size = pts_arrays::first_element($result_match_count);
                     if ($biggest_size == $system_count || $biggest_size > 3) {
                         foreach ($result_match_count as $key => $value) {
                             if ($value < 2) {
                                 unset($result_objects[$key]);
                             }
                         }
                     }
                     $result_file->override_result_objects($result_objects);
                     $result_xml = pts_merge::merge_test_results_array(array($result_file));
                 }
             }
             pts_client::save_test_result('auto-comparison/composite.xml', $result_xml);
         }
     }
     pts_test_installer::standard_install(array('auto-comparison'));
     pts_test_run_manager::standard_run(array('auto-comparison'));
 }
 protected static function process_user_config_external_hook_process($process, $cmd_value, $description_string = null, &$passed_obj = null)
 {
     if (!empty($cmd_value) && (is_executable($cmd_value) || ($cmd_value = pts_client::executable_in_path($cmd_value)))) {
         $descriptor_spec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
         $env_vars = array('PTS_EXTERNAL_TEST_HOOK' => $process);
         if ($passed_obj instanceof pts_test_result) {
             $env_vars['PTS_EXTERNAL_TEST_IDENTIFIER'] = $passed_obj->test_profile->get_identifier();
             $env_vars['PTS_EXTERNAL_TEST_RUN_POSITION'] = $passed_obj->test_result_buffer->get_count() + 1;
             $env_vars['PTS_EXTERNAL_TEST_RUN_COUNT'] = $passed_obj->test_profile->get_times_to_run();
             $env_vars['PTS_EXTERNAL_TEST_ARGS'] = $passed_obj->get_arguments();
             $env_vars['PTS_EXTERNAL_TEST_DESCRIPTION'] = $passed_obj->get_arguments_description();
             $env_vars['PTS_EXTERNAL_TEST_RESULT_SET'] = $passed_obj->test_result_buffer->get_values_as_string();
             $env_vars['PTS_EXTERNAL_TEST_RESULT'] = $passed_obj->get_result() != 0 ? $passed_obj->get_result() : pts_arrays::last_element($passed_obj->test_result_buffer->get_values());
             $env_vars['PTS_EXTERNAL_TEST_HASH'] = bin2hex($passed_obj->get_comparison_hash());
             $env_vars['PTS_EXTERNAL_TEST_STD_DEV_PERCENT'] = pts_math::percent_standard_deviation($passed_obj->test_result_buffer->get_values());
             if (is_file($passed_obj->test_profile->get_install_dir() . 'cache-share-' . PTS_INIT_TIME . '.pt2so')) {
                 // There's a cache share present
                 $env_vars['PTS_EXTERNAL_TEST_CACHE_SHARE'] = 1;
             }
         } else {
             if ($passed_obj instanceof pts_test_run_manager) {
                 $env_vars['PTS_EXTERNAL_TESTS_IN_QUEUE'] = implode(':', $passed_obj->get_tests_to_run_identifiers());
                 $env_vars['PTS_EXTERNAL_TEST_FILE_NAME'] = $passed_obj->get_file_name();
                 $env_vars['PTS_EXTERNAL_TEST_IDENTIFIER'] = $passed_obj->get_results_identifier();
             }
         }
         $description_string != null && pts_client::$display->test_run_instance_error($description_string);
         $proc = proc_open($cmd_value, $descriptor_spec, $pipes, null, $env_vars);
         $std_output = stream_get_contents($pipes[1]);
         $return_value = proc_close($proc);
         // If you want PTS to exit or something when your script returns !0, you could add an 'exit;' or whatever you want below
         // The contents of $std_output is anything that may have been written by your script, if you want it to be interpreted by anything in this module
         if ($return_value != 0) {
             return false;
         }
     }
     return true;
 }
Example #25
0
 public static function environmental_variables()
 {
     // The PTS environmental variables passed during the testing process, etc
     static $env_variables = null;
     if ($env_variables == null) {
         $env_variables = array('PTS_VERSION' => PTS_VERSION, 'PTS_CODENAME' => PTS_CODENAME, 'PTS_DIR' => PTS_PATH, 'PHP_BIN' => PHP_BIN, 'NUM_CPU_CORES' => phodevi::read_property('cpu', 'core-count'), 'NUM_CPU_NODES' => phodevi::read_property('cpu', 'node-count'), 'NUM_CPU_JOBS' => phodevi::read_property('cpu', 'core-count') * 2, 'SYS_MEMORY' => phodevi::read_property('memory', 'capacity'), 'VIDEO_MEMORY' => phodevi::read_property('gpu', 'memory-capacity'), 'VIDEO_WIDTH' => pts_arrays::first_element(phodevi::read_property('gpu', 'screen-resolution')), 'VIDEO_HEIGHT' => pts_arrays::last_element(phodevi::read_property('gpu', 'screen-resolution')), 'VIDEO_MONITOR_COUNT' => phodevi::read_property('monitor', 'count'), 'VIDEO_MONITOR_LAYOUT' => phodevi::read_property('monitor', 'layout'), 'VIDEO_MONITOR_SIZES' => phodevi::read_property('monitor', 'modes'), 'OPERATING_SYSTEM' => phodevi::read_property('system', 'vendor-identifier'), 'OS_VERSION' => phodevi::read_property('system', 'os-version'), 'OS_ARCH' => phodevi::read_property('system', 'kernel-architecture'), 'OS_TYPE' => phodevi::operating_system(), 'THIS_RUN_TIME' => PTS_INIT_TIME, 'DEBUG_REAL_HOME' => pts_core::user_home_directory());
         if (!pts_client::executable_in_path('cc') && pts_client::executable_in_path('gcc') && getenv('CC') == false) {
             // This helps some test profiles build correctly if they don't do a cc check internally
             $env_variables['CC'] = 'gcc';
         }
     }
     return $env_variables;
 }
 public function __construct(&$result_object = null, &$result_file = null)
 {
     // Initalize Colors
     $this->i['identifier_size'] = self::$c['size']['identifiers'];
     // Copy this since it's commonly overwritten
     $this->i['graph_orientation'] = 'VERTICAL';
     $this->i['graph_value_type'] = 'NUMERICAL';
     $this->i['hide_graph_identifiers'] = false;
     $this->i['show_graph_key'] = false;
     $this->i['show_background_lines'] = false;
     $this->i['iveland_view'] = false;
     $this->i['graph_max_value_multiplier'] = 1.285;
     $this->i['graph_max_value'] = 0;
     $this->i['bottom_offset'] = 0;
     $this->i['hide_y_title'] = false;
     $this->i['compact_result_view'] = false;
     $this->i['key_line_height'] = 0;
     $this->i['graph_height'] = 0;
     $this->i['graph_width'] = 0;
     $this->i['left_start'] = 10;
     $this->i['left_end_right'] = 10;
     $this->i['top_start'] = 62;
     $this->i['top_end_bottom'] = 22;
     $this->i['mark_count'] = 6;
     // Number of marks to make on vertical axis
     $this->i['notes'] = array();
     // Reset of setup besides config
     if ($result_object != null) {
         $test_version = $result_object->test_profile->get_app_version();
         if (isset($test_version[2]) && is_numeric($test_version[0])) {
             $test_version = 'v' . $test_version;
         }
         $this->graph_title = trim($result_object->test_profile->get_title() . ' ' . $test_version);
         $this->graph_y_title = $result_object->test_profile->get_result_scale_formatted();
         $this->test_identifier = $result_object->test_profile->get_identifier();
         $this->i['graph_proportion'] = $result_object->test_profile->get_result_proportion();
         $this->addSubTitle($result_object->get_arguments_description());
     }
     $this->update_graph_dimensions(self::$c['graph']['width'], self::$c['graph']['height'], true);
     if ($result_file != null && $result_file instanceof pts_result_file) {
         $pts_version = pts_arrays::last_element($result_file->get_system_pts_version());
         $this->is_multi_way_comparison = $result_file->is_multi_way_comparison();
     }
     if (!isset($pts_version) || empty($pts_version)) {
         $pts_version = PTS_VERSION;
     }
     $this->i['graph_version'] = 'Phoronix Test Suite ' . $pts_version;
 }
 public static function evaluate_redundant_identifier_words($identifiers)
 {
     if (count($identifiers) < 4 || strpos(pts_arrays::first_element($identifiers), ':') !== false) {
         // Probably not worth shortening so few result identifiers
         return false;
     }
     // Breakup the an identifier into an array by spaces to be used for comparison
     $common_segments = explode(' ', pts_arrays::first_element($identifiers));
     $common_segments_last = explode(' ', pts_arrays::last_element($identifiers));
     if (!isset($common_segments_last[2]) || !isset($common_segments[2])) {
         // If there aren't at least three words in identifier, probably can't be shortened well
         return false;
     }
     foreach (array_reverse($identifiers) as $id) {
         $words = explode(' ', $id);
         foreach ($words as $i => $word) {
             if (isset($common_segments[$i]) && $word != $common_segments[$i] && isset($word[2]) && !ctype_alnum(substr($word, -1))) {
                 // IS COMMON WORD
             } else {
                 unset($common_segments[$i]);
             }
         }
         if (count($common_segments) == 0) {
             return false;
         }
     }
     return $common_segments;
 }
 public static function cpu_default_frequency($cpu_core = 0)
 {
     // Find out the processor frequency
     $info = null;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
     if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq')) {
         $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq');
         $info = intval($info) / 1000000;
         if ($info > 9) {
             // For some reason on Linux 3.10 the scaling_max_freq is reported as 25GHz...
             $info = null;
         }
     }
     if ($info == null && isset(phodevi::$vfs->cpuinfo)) {
         $cpu_mhz = self::read_cpuinfo_line('cpu MHz');
         $info = $cpu_mhz / 1000;
         if (empty($info)) {
             $cpu_mhz = self::read_cpuinfo_line('clock');
             $info = $cpu_mhz / 1000;
         }
     } else {
         if ($info == null && phodevi::is_bsd()) {
             $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq_levels'));
             if ($info != null) {
                 // Popping the top speed off of dev.cpu.0.freq_levels should be the default/highest supported frequency
                 $info = pts_arrays::first_element(explode(' ', str_replace('/', ' ', $info)));
                 if (!is_numeric($info)) {
                     $info = null;
                 }
             }
             if ($info == null) {
                 $info = phodevi_bsd_parser::read_sysctl(array('hw.acpi.cpu.px_global', 'machdep.est.frequency.target', 'hw.cpuspeed'));
             }
             if ($info == null) {
                 // dev.cpu.0.freq seems to be the real/current frequency, affected by power management, etc so only use as last fallback
                 $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq'));
             }
             if (is_numeric($info)) {
                 $info = $info / 1000;
             } else {
                 $info = null;
             }
         } else {
             if ($info == null && phodevi::is_windows()) {
                 $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Stock frequency');
                 if ($info != null) {
                     if (($e = strpos($info, ' MHz')) !== false) {
                         $info = substr($info, 0, $e);
                     }
                     $info = $info / 1000;
                 }
             } else {
                 if ($info == null) {
                     $info = phodevi::read_sensor(array('cpu', 'freq'));
                     if ($info > 1000) {
                         // Convert from MHz to GHz
                         $info = $info / 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
 public static function prompt_text_menu($user_string, $options_r, $allow_multi_select = false, $return_index = false, $line_prefix = null)
 {
     $option_count = count($options_r);
     if ($option_count == 1) {
         return $return_index ? pts_arrays::last_element(array_keys($options_r)) : array_pop($options_r);
     }
     $select = array();
     do {
         echo PHP_EOL;
         $key_index = array();
         foreach (array_keys($options_r) as $i => $key) {
             $key_index[$i + 1] = $key;
             echo $line_prefix . ($i + 1) . ': ' . str_repeat(' ', strlen($option_count) - strlen($i + 1)) . $options_r[$key] . PHP_EOL;
         }
         echo $line_prefix . $user_string . ': ';
         $select_choice = pts_user_io::read_user_input();
         foreach ($allow_multi_select ? pts_strings::comma_explode($select_choice) : array($select_choice) as $choice) {
             if (in_array($choice, $options_r)) {
                 $select[] = array_search($choice, $options_r);
             } else {
                 if (isset($key_index[$choice])) {
                     $select[] = $key_index[$choice];
                 } else {
                     if ($allow_multi_select && strpos($choice, '-') !== false) {
                         $choice_range = pts_strings::trim_explode('-', $choice);
                         if (count($choice_range) == 2 && is_numeric($choice_range[0]) && is_numeric($choice_range[1]) && isset($key_index[$choice_range[0]]) && isset($key_index[$choice_range[1]])) {
                             for ($i = min($choice_range); $i <= max($choice_range); $i++) {
                                 $select[] = $key_index[$i];
                             }
                         }
                     }
                 }
             }
         }
     } while (!isset($select[0]));
     if ($return_index == false) {
         foreach ($select as &$index) {
             $index = $options_r[$index];
         }
     }
     return implode(',', $select);
 }
 public static function generate_result_export_dump($account_id)
 {
     pts_file_io::mkdir(self::phoromatic_path() . 'result-export/');
     $export_path = self::phoromatic_path() . 'result-export/' . $account_id . '/';
     pts_file_io::mkdir($export_path);
     $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_schedules WHERE AccountID = :account_id AND State = 1 AND (SELECT COUNT(*) FROM phoromatic_schedules_tests WHERE AccountID = :account_id AND ScheduleID = phoromatic_schedules.ScheduleID) > 0 AND (SELECT COUNT(*) FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = phoromatic_schedules.ScheduleID) > 4 ORDER BY Title ASC');
     $stmt->bindValue(':account_id', $account_id);
     $result = $stmt->execute();
     $exported_result_index = array('phoromatic' => array());
     while ($result && ($row = $result->fetchArray())) {
         $id = str_replace(' ', '-', strtolower($row['Title']));
         $triggers = array();
         $stmt2 = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_results WHERE AccountID = :account_id AND ScheduleID = :schedule_id ORDER BY UploadTime DESC');
         $stmt2->bindValue(':account_id', $row['AccountID']);
         $stmt2->bindValue(':schedule_id', $row['ScheduleID']);
         $result2 = $stmt2->execute();
         pts_file_io::mkdir($export_path);
         while ($result2 && ($row2 = $result2->fetchArray())) {
             $composite_xml = phoromatic_server::phoromatic_account_result_path($row2['AccountID'], $row2['UploadID']) . 'composite.xml';
             if (is_file($composite_xml)) {
                 pts_file_io::mkdir($export_path . $id . '/' . $row2['Trigger']);
                 pts_file_io::mkdir($export_path . $id . '/' . $row2['Trigger'] . '/' . phoromatic_server::system_id_to_name($row2['SystemID'], $row2['AccountID']));
                 copy($composite_xml, $export_path . $id . '/' . $row2['Trigger'] . '/' . phoromatic_server::system_id_to_name($row2['SystemID'], $row2['AccountID']) . '/composite.xml');
             }
             pts_arrays::unique_push($triggers, $row2['Trigger']);
         }
         $exported_result_index['phoromatic'][$id] = array('title' => $row['Title'], 'id' => $id, 'description' => $row['Description'], 'triggers' => $triggers);
     }
     $exported_result_index = json_encode($exported_result_index, JSON_PRETTY_PRINT);
     file_put_contents($export_path . '/export-index.json', $exported_result_index);
 }