pre-release updates, bug fixes
diff --git a/config.py b/config.py
index e7830bb..ab9ec8c 100644
--- a/config.py
+++ b/config.py
@@ -28,3 +28,4 @@
cfg_dict['vm_ids_fname'] = os.path.join(cfg_dict['var_dir'], 'os_vm_ids')
cfg_dict['report'] = os.path.join(cfg_dict['var_dir'], 'report.html')
+ cfg_dict['log_file'] = os.path.join(cfg_dict['var_dir'], 'log.txt')
diff --git a/koder.yaml b/koder.yaml
deleted file mode 100644
index ab8e51b..0000000
--- a/koder.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-clouds:
- fuel:
- ext_ip: 172.16.53.3
- url: http://172.16.52.112:8000/
- creds: admin:admin@admin
- ssh_creds: root:test37
- openstack_env: test
-
- openstack:
- OS_TENANT_NAME: admin
- OS_USERNAME: admin
- OS_PASSWORD: admin
- OS_AUTH_URL: http://172.16.53.3:5000/v2.0/
-
-discover: fuel
-
-# explicit_nodes:
-# "ssh://192.168.152.43": testnode
-
-internal:
- var_dir_root: /tmp/perf_tests
-
-sensors:
- receiver_uri: udp://192.168.152.1:5699
- roles_mapping:
- ceph-osd: block-io
- testnode: system-cpu, block-io
-
-tests:
- start_test_nodes:
- openstack:
- creds: clouds
- vm_params:
- count: x2
- img_name: disk_io_perf
- flavor_name: disk_io_perf.256
- keypair_name: disk_io_perf
- network_zone_name: novanetwork
- flt_ip_pool: nova
- creds: "ssh://ubuntu@{0}::disk_io_perf.pem"
- name_templ: disk_io_perf-{0}
-
- tests:
- - io:
- cfg: tests/io_task_test.cfg
- params:
- FILENAME: /tmp/xxx.bin
-
-logging:
- extra_logs: 1
diff --git a/pretty_yaml.py b/pretty_yaml.py
new file mode 100644
index 0000000..44d4e49
--- /dev/null
+++ b/pretty_yaml.py
@@ -0,0 +1,75 @@
+def dumps_simple(val):
+ bad_symbols = set(" \r\t\n,':")
+
+ if isinstance(val, basestring):
+ if len(bad_symbols & set(val)) != 0:
+ return repr(val)
+ return val
+ elif val is True:
+ return 'true'
+ elif val is False:
+ return 'false'
+ elif val is None:
+ return 'null'
+
+ return str(val)
+
+
+def is_simple(val):
+ simple_type = isinstance(val, (str, unicode, int, long, bool, float))
+ return simple_type or val is None
+
+
+def all_nums(vals):
+ return all(isinstance(val, (int, float, long)) for val in vals)
+
+
+def dumpv(data, tab_sz=4, width=120, min_width=40):
+ tab = ' ' * tab_sz
+
+ if width < min_width:
+ width = min_width
+
+ res = []
+ if is_simple(data):
+ return [dumps_simple(data)]
+
+ if isinstance(data, (list, tuple)):
+ if all(map(is_simple, data)):
+ if all_nums(data):
+ one_line = "[{}]".format(", ".join(map(dumps_simple, data)))
+ else:
+ one_line = "[{}]".format(",".join(map(dumps_simple, data)))
+ else:
+ one_line = None
+
+ if one_line is None or len(one_line) > width:
+ pref = "-" + ' ' * (tab_sz - 1)
+
+ for val in data:
+ items = dumpv(val, tab_sz, width - tab_sz, min_width)
+ items = [pref + items[0]] + \
+ [tab + item for item in items[1:]]
+ res.extend(items)
+ else:
+ res.append(one_line)
+ elif isinstance(data, dict):
+ assert all(map(is_simple, data.keys()))
+
+ for k, v in data.items():
+ key_str = dumps_simple(k) + ": "
+ val_res = dumpv(v, tab_sz, width - tab_sz, min_width)
+
+ if len(val_res) == 1 and len(key_str + val_res[0]) < width:
+ res.append(key_str + val_res[0])
+ else:
+ res.append(key_str)
+ res.extend(tab + i for i in val_res)
+ else:
+ raise ValueError("Can't pack {0!r}".format(data))
+
+ return res
+
+
+def dumps(data, tab_sz=4, width=120, min_width=40):
+ return "\n".join(dumpv(data, tab_sz, width, min_width))
diff --git a/report.html b/report.html
deleted file mode 100644
index b82cbbd..0000000
--- a/report.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Report</title>
-</head>
-
-<body>
-%(body)s
-</body>
-
-</html>
\ No newline at end of file
diff --git a/run_test.py b/run_test.py
index 1841bc8..2e01394 100755
--- a/run_test.py
+++ b/run_test.py
@@ -28,19 +28,21 @@
logger = logging.getLogger("io-perf-tool")
-def setup_logger(logger, level=logging.DEBUG):
- logger.setLevel(level)
- ch = logging.StreamHandler()
- ch.setLevel(level)
- logger.addHandler(ch)
+def setup_logger(logger, level=logging.DEBUG, log_fname=None):
+ # logger.setLevel(level)
+ sh = logging.StreamHandler()
+ sh.setLevel(level)
log_format = '%(asctime)s - %(levelname)-6s - %(name)s - %(message)s'
formatter = logging.Formatter(log_format,
"%H:%M:%S")
- ch.setFormatter(formatter)
+ sh.setFormatter(formatter)
+ logger.addHandler(sh)
- # logger.setLevel(logging.INFO)
- # logger.addHandler(logging.FileHandler('log.txt'))
+ if log_fname is not None:
+ fh = logging.FileHandler(log_fname)
+ fh.setLevel(logging.DEBUG)
+ logger.addHandler(fh)
def format_result(res, formatter):
@@ -403,10 +405,11 @@
report_stage
]
- level = logging.DEBUG if opts.extra_logs else logging.WARNING
- setup_logger(logger, level)
-
load_config(opts.config_file)
+
+ level = logging.DEBUG if opts.extra_logs else logging.WARNING
+ setup_logger(logger, level, cfg_dict['log_file'])
+
logger.info("Store all info into {0}".format(cfg_dict['var_dir']))
ctx = Context()
diff --git a/tests/fio_configs/1.cfg b/scripts/fio_tests_configs/1.cfg
similarity index 100%
rename from tests/fio_configs/1.cfg
rename to scripts/fio_tests_configs/1.cfg
diff --git a/tests/fio_configs/2.cfg b/scripts/fio_tests_configs/2.cfg
similarity index 100%
rename from tests/fio_configs/2.cfg
rename to scripts/fio_tests_configs/2.cfg
diff --git a/tests/io_task.cfg b/scripts/fio_tests_configs/io_task.cfg
similarity index 100%
rename from tests/io_task.cfg
rename to scripts/fio_tests_configs/io_task.cfg
diff --git a/tests/io_task_test.cfg b/scripts/fio_tests_configs/io_task_test.cfg
similarity index 100%
rename from tests/io_task_test.cfg
rename to scripts/fio_tests_configs/io_task_test.cfg
diff --git a/tests.yaml b/scripts/tests.yaml
similarity index 100%
rename from tests.yaml
rename to scripts/tests.yaml
diff --git a/sensors/storage/koder.js b/sensors/storage/koder.js
new file mode 100644
index 0000000..a65a454
--- /dev/null
+++ b/sensors/storage/koder.js
@@ -0,0 +1,47 @@
+/* global _ */
+
+/*
+ * Complex scripted dashboard
+ * This script generates a dashboard object that Grafana can load. It also takes a number of user
+ * supplied URL parameters (int ARGS variable)
+ *
+ * Return a dashboard object, or a function
+ *
+ * For async scripts, return a function, this function must take a single callback function as argument,
+ * call this callback function with the dashboard object (look at scripted_async.js for an example)
+ */
+
+
+
+// accessable variables in this scope
+var window, document, ARGS, $, jQuery, moment, kbn;
+
+// Setup some variables
+var dashboard;
+
+// All url parameters are available via the ARGS object
+var ARGS;
+
+// Intialize a skeleton with nothing but a rows array and service object
+dashboard = {rows : []};
+
+// Set a title
+dashboard.title = 'Tests dash';
+
+// Set default time
+// time can be overriden in the url using from/to parameteres, but this is
+// handled automatically in grafana core during dashboard initialization
+dashboard.time = {
+ from: "now-5m",
+ to: "now"
+};
+
+dashboard.rows.push({
+ title: 'Chart',
+ height: '300px',
+ panels: [{"span": 12, "title": "writes_completed", "linewidth": 2, "type": "graph", "targets": [{"alias": "192.168.0.104 io sda1", "interval": "", "target": "disk io", "rawQuery": true, "query": "select value from \"writes_completed\" where $timeFilter and host='192.168.0.104' and device='sda1' order asc"}, {"alias": "192.168.0.104 io rbd1", "interval": "", "target": "disk io", "rawQuery": true, "query": "select value from \"writes_completed\" where $timeFilter and host='192.168.0.104' and device='rbd1' order asc"}], "tooltip": {"shared": true}, "fill": 1}, {"span": 12, "title": "sectors_written", "linewidth": 2, "type": "graph", "targets": [{"alias": "192.168.0.104 io sda1", "interval": "", "target": "disk io", "rawQuery": true, "query": "select value from \"sectors_written\" where $timeFilter and host='192.168.0.104' and device='sda1' order asc"}, {"alias": "192.168.0.104 io rbd1", "interval": "", "target": "disk io", "rawQuery": true, "query": "select value from \"sectors_written\" where $timeFilter and host='192.168.0.104' and device='rbd1' order asc"}], "tooltip": {"shared": true}, "fill": 1}]
+});
+
+
+return dashboard;
+