/** * returns run options represents as a hash * @return array */ public static function getRunOptions() { // default run argument values $sysInfo = get_sys_info(); $ini = get_benchmark_ini(); $defaults = array('active_range' => 100, 'collectd_rrd_dir' => '/var/lib/collectd/rrd', 'fio' => 'fio', 'fio_options' => array('direct' => TRUE, 'ioengine' => 'libaio', 'refill_buffers' => FALSE, 'scramble_buffers' => TRUE), 'font_size' => 9, 'highcharts_js_url' => 'http://code.highcharts.com/highcharts.js', 'highcharts3d_js_url' => 'http://code.highcharts.com/highcharts-3d.js', 'jquery_url' => 'http://code.jquery.com/jquery-2.1.0.min.js', 'meta_compute_service' => 'Not Specified', 'meta_cpu' => $sysInfo['cpu'], 'meta_instance_id' => 'Not Specified', 'meta_memory' => $sysInfo['memory_gb'] > 0 ? $sysInfo['memory_gb'] . ' GB' : $sysInfo['memory_mb'] . ' MB', 'meta_os' => $sysInfo['os_info'], 'meta_provider' => 'Not Specified', 'meta_storage_config' => 'Not Specified', 'meta_test_sw' => isset($ini['meta-id']) ? 'ch-' . $ini['meta-id'] . (isset($ini['meta-version']) ? ' ' . $ini['meta-version'] : '') : '', 'oio_per_thread' => 64, 'output' => trim(shell_exec('pwd')), 'precondition_passes' => 2, 'ss_max_rounds' => 25, 'ss_verification' => 10, 'test' => array('iops'), 'threads' => '{cpus}', 'threads_per_core_max' => 2, 'threads_per_target_max' => 8, 'timeout' => 86400, 'wd_test_duration' => 60); $opts = array('active_range:', 'collectd_rrd', 'collectd_rrd_dir:', 'fio:', 'font_size:', 'highcharts_js_url:', 'highcharts3d_js_url:', 'jquery_url:', 'meta_compute_service:', 'meta_compute_service_id:', 'meta_cpu:', 'meta_drive_interface:', 'meta_drive_model:', 'meta_drive_type:', 'meta_instance_id:', 'meta_memory:', 'meta_os:', 'meta_notes_storage:', 'meta_notes_test:', 'meta_provider:', 'meta_provider_id:', 'meta_region:', 'meta_resource_id:', 'meta_run_id:', 'meta_storage_config:', 'meta_storage_vol_info:', 'meta_test_id:', 'meta_test_sw:', 'no3dcharts', 'nojson', 'nopdfreport', 'noprecondition', 'nopurge', 'norandom', 'noreport', 'nosecureerase', 'notrim', 'nozerofill', 'oio_per_thread:', 'output:', 'precondition_passes:', 'randommap', 'savefio', 'secureerase_pswd:', 'sequential_only', 'skip_blocksize:', 'skip_workload:', 'ss_max_rounds:', 'ss_verification:', 'target:', 'target_skip_not_present', 'test:', 'threads:', 'threads_per_core_max:', 'threads_per_target_max:', 'timeout:', 'trim_offset_end:', 'v' => 'verbose', 'wd_test_duration:', 'wd_sleep_between:'); $options = parse_args($opts, array('skip_blocksize', 'skip_workload', 'target', 'test')); $verbose = isset($options['verbose']) && $options['verbose']; // explicit fio command foreach ($defaults as $key => $val) { if (!isset($options[$key])) { $options[$key] = $val; } } // target/test argument (expand comma separated values) foreach (array('target', 'test') as $key) { if (isset($options[$key])) { $targets = array(); foreach ($options[$key] as $temp) { foreach (explode(',', $temp) as $target) { $targets[] = trim($target); } } $options[$key] = $targets; } } foreach (get_prefixed_params('fio_') as $key => $val) { $options['fio_options'][$key] = $val; } // don't use random IO if (isset($options['norandom']) && $options['norandom']) { if (isset($options['fio']['refill_buffers'])) { unset($options['fio']['refill_buffers']); } if (isset($options['fio']['scramble_buffers'])) { unset($options['fio']['scramble_buffers']); } } // implicit nosecureerase if (!isset($options['secureerase_pswd'])) { $options['nosecureerase'] = TRUE; } // implicit nopurge if (isset($options['nosecureerase']) && $options['nosecureerase'] && isset($options['notrim']) && $options['notrim'] && isset($options['nozerofill']) && $options['nozerofill']) { $options['nopurge'] = TRUE; } // threads is based on number of CPUs if (isset($options['threads']) && preg_match('/{cpus}/', $options['threads'])) { $options['threads'] = str_replace(' ', '', str_replace('{cpus}', BlockStorageTest::getCpuCount(), $options['threads'])); // expression if (preg_match('/[\\*\\+\\-\\/]/', $options['threads'])) { eval(sprintf('$options["threads"]=%s;', $options['threads'])); } $options['threads'] *= 1; if ($options['threads'] <= 0) { $options['threads'] = 1; } } // remove targets that are not present if (isset($options['target_skip_not_present']) && isset($options['target']) && count($options['target']) > 1) { print_msg(sprintf('Checking targets %s because --target_skip_not_present argument was set', implode(', ', $options['target'])), $verbose, __FILE__, __LINE__); $targets = array(); foreach ($options['target'] as $i => $target) { if (!is_dir($target) && !file_exists($target)) { print_msg(sprintf('Skipped test target %s because it does not exist and the --target_skip_not_present argument was set', $target), $verbose, __FILE__, __LINE__); } else { $targets[] = $target; } } $options['target'] = $targets; print_msg(sprintf('Adjusted test targets is %s', implode(', ', $options['target'])), $verbose, __FILE__, __LINE__); } // adjust threads for number of targets if (isset($options['target']) && count($options['target']) > 1) { $options['threads'] = round($options['threads'] / count($options['target'])); if ($options['threads'] == 0) { $options['threads'] = 1; } } // adjust for threads_per_target_max if (isset($options['threads_per_target_max']) && $options['threads'] > $options['threads_per_target_max']) { $threads = $options['threads']; $options['threads'] = $options['threads_per_target_max']; print_msg(sprintf('Reduced threads from %d to %d for threads_per_target_max constraint %d', $threads, $options['threads'], $options['threads_per_target_max']), $verbose, __FILE__, __LINE__); } $options['threads_total'] = $options['threads'] * count($options['target']); // adjust for threads_per_core_max if (isset($options['threads_per_core_max']) && $options['threads_total'] > $options['threads_per_core_max'] * BlockStorageTest::getCpuCount()) { $threads_total = $options['threads_total']; $threads = $options['threads']; $options['threads'] = round($options['threads_per_core_max'] * BlockStorageTest::getCpuCount() / count($options['target'])); if (!$options['threads']) { $options['threads'] = 1; } $options['threads_total'] = round($options['threads'] * count($options['target'])); if ($threads != $options['threads']) { print_msg(sprintf('Reduced total threads from %d to %d [threads per target from %d to %s] for threads_per_core_max constraint %d, %d CPU cores, and %d targets', $threads_total, $options['threads_total'], $threads, $options['threads'], $options['threads_per_core_max'], BlockStorageTest::getCpuCount(), count($options['target'])), $verbose, __FILE__, __LINE__); } else { print_msg(sprintf('Ignoring threads_per_core_max constraint %d because at least 1 thread per target is required', $options['threads_per_core_max']), $verbose, __FILE__, __LINE__); } } return $options; }
/** * this method substitutes any tokens present in $str the the corresponding * benchmark or row metadata. Benchmark metata tokens include {benchmark} and * {version} * @param string $str the string containing tokens * @param array $row the data row (hash of key/value pairs) * @return string */ protected function substituteTokens($str, &$row) { if (preg_match_all('/\\{([^\\}]+)\\}/', $str, $m)) { if (!isset($this->benchmarkIni)) { $this->benchmarkIni = get_benchmark_ini(); } $meta = array('benchmark' => isset($this->benchmarkIni['meta-id']) ? $this->benchmarkIni['meta-id'] : NULL, 'version' => isset($this->benchmarkIni['meta-version']) ? $this->benchmarkIni['meta-version'] : NULL); foreach ($m[1] as $i => $token) { $sub = ''; if (isset($row[$token])) { $sub = $row[$token]; } else { if (isset($meta[$token])) { $sub = $meta[$token]; } } $str = str_replace($m[0][$i], $sub, $str); } // remove leading and trailing dash (-) and underscore (_) $str = trim($str); $str = trim(str_replace('--', '-', $str)); $str = trim(str_replace('[]', '', $str)); $str = trim(str_replace('()', '', $str)); $str = trim($str); while ($str && (substr($str, 0, 1) == '-' || substr($str, 0, 1) == '_')) { $str = trim(substr($str, 1)); } while ($str && (substr($str, -1) == '-' || substr($str, -1) == '_')) { $str = trim(substr($str, 0, -1)); } $str = trim($str); } return $str; }
/** * returns the object URI (minus container) for $file (appends --store_prefix * if applicable). Includes substitution of the following dynamic values: * {date[_format]} => a date string (optionally * formatted per [format] - see * http://php.net/manual/en/function.date.php * for valid format options - * default format is Y-m-d) * {benchmark} => benchmark name (block-storage) * (meta-id value in benchmark.ini) * {version} => benchmark version (1.0) * (meta-version value in benchmark.ini) * {iteration} => iteration number * {hostname} => the compute instance hostname * {meta_*} => any of the meta_* runtime * parameters. If a meta_* value * is designated but was not set, * at runtime, it will be removed * from the prefix * {rand} => a random number * @param string $file the file to return the URI * @return string */ protected final function getObjectUri($file) { $prefix = isset($this->options['store_prefix']) ? $this->options['store_prefix'] : BenchmarkArchiver::DEFAULT_PREFIX; if (preg_match_all('/{([^}]+)}/', $prefix, $m)) { $ini = get_benchmark_ini(); $options = file_exists($options = dirname($file) . '/.options') ? unserialize(file_get_contents($options)) : NULL; foreach ($m[1] as $value) { $sub = ''; foreach (explode('|', $value) as $check) { $check = trim($check); if (preg_match('/^date_?(.*)$/', $check, $d)) { $format = $d[1] ? $d[1] : 'Y-m-d'; $sub = date($format, filemtime($file)); } else { if ($check == 'benchmark') { $sub = isset($ini['meta-id']) ? $ini['meta-id'] : ''; } else { if ($check == 'version') { $sub = isset($ini['meta-version']) ? str_replace('.', '_', $ini['meta-version']) : ''; } else { if ($check == 'iteration') { $sub = is_numeric(basename(dirname($file))) ? basename(dirname($file)) * 1 : 1; } else { if ($check == 'hostname') { $sub = trim(shell_exec('hostname')); } else { if ($check == 'rand') { $sub = '[rand]'; } else { if ($options && isset($options[$check])) { $sub = trim(strtolower(str_replace(' ', '_', $options[$check]))); } } } } } } } if ($sub == 'not_specified' || $sub == 'na') { $sub = ''; } if ($sub) { break; } } $prefix = str_replace('{' . $value . '}', $sub, $prefix); if (!$sub) { $prefix = str_replace('//', '/', $prefix); } } if (!isset($this->randStrings[$prefix])) { $this->randStrings[$prefix] = rand(); } $prefix = str_replace('[rand]', $this->randStrings[$prefix], $prefix); } return str_replace('//', '/', sprintf('%s/%s', $prefix, basename($file))); }