updates to tests
diff --git a/data.py b/data.py
new file mode 100644
index 0000000..5569616
--- /dev/null
+++ b/data.py
@@ -0,0 +1,113 @@
+import re
+import sys
+
+
+splitter_rr = "(?ms)=====+\n"
+
+
+def get_data_from_output(fname):
+    results = {}
+    fc = open(fname).read()
+
+    for block in re.split(splitter_rr, fc):
+        block = block.strip()
+        if not block.startswith("[{u'__meta__':"):
+            continue
+        for val in eval(block):
+            meta = val['__meta__']
+            meta['sync'] = 's' if meta['sync'] else 'a'
+            key = "{action} {sync} {blocksize}k".format(**meta)
+            results.setdefault(key, []).append(val['bw_mean'])
+
+    processed_res = {}
+
+    for k, v in results.items():
+        v.sort()
+        med = float(sum(v)) / len(v)
+        ran = sum(abs(x - med) for x in v) / len(v)
+        processed_res[k] = (int(med), int(ran))
+
+    return processed_res
+
+
+def ksort(x):
+    op, sync, sz = x.split(" ")
+    return (op, sync, int(sz[:-1]))
+
+
+def show_data(path1, path2=None):
+    templ_1 = "  {:>10}  {:>5}  {:>5}     {:>6} ~ {:>5} {:>2}% {:>5}"
+    templ_2 = templ_1 + "      {:>6} ~ {:>5} {:>2}% {:>5} ----  {:>6}%  "
+
+    ln_1 = templ_1.replace("<", "^").replace(">", "^")
+    ln_1 = ln_1.format("Oper", "Sync", "BSZ", "BW1", "DEV1", "%", "IOPS1")
+
+    ln_2 = templ_2.replace("<", "^").replace(">", "^")
+    ln_2 = ln_2.format("Oper", "Sync", "BSZ", "BW1", "DEV1", "%",
+                       "IOPS1", "BW2", "DEV2", "%", "IOPS2", "DIFF %")
+
+    sep_1 = '-' * len(ln_1)
+    sep_2 = '-' * len(ln_2)
+
+    res_1 = get_data_from_output(path1)
+
+    if path2 is None:
+        res_2 = None
+        sep = sep_1
+        ln = ln_1
+        templ = templ_1
+    else:
+        res_2 = get_data_from_output(path2)
+        sep = sep_2
+        ln = ln_2
+        templ = templ_2
+
+    print sep
+    print ln
+    print sep
+
+    prev_tp = None
+
+    common_keys = set(res_1.keys())
+
+    if res_2 is not None:
+        common_keys &= set(res_2.keys())
+
+    for k in sorted(common_keys, key=ksort):
+        tp = k.rsplit(" ", 1)[0]
+        op, s, sz = k.split(" ")
+        s = 'sync' if s == 's' else 'async'
+
+        if tp != prev_tp and prev_tp is not None:
+            print sep
+
+        prev_tp = tp
+
+        m1, d1 = res_1[k]
+        iops1 = m1 / int(sz[:-1])
+        perc1 = int(d1 * 100.0 / m1 + 0.5)
+
+        if res_2 is not None:
+            m2, d2 = res_2[k]
+            iops2 = m2 / int(sz[:-1])
+            perc2 = int(d2 * 100.0 / m2 + 0.5)
+            avg_diff = int(((m2 - m1) * 100.) / m2 + 0.5)
+
+        if res_2 is not None:
+            print templ.format(op, s, sz, m1, d1, perc1, iops1,
+                               m2, d2, perc2, iops2, avg_diff)
+        else:
+            print templ.format(op, s, sz, m1, d1, perc1, iops1)
+
+    print sep
+
+
+def main(argv):
+    path1 = argv[0]
+    path2 = argv[1] if len(argv) > 1 else None
+    show_data(path1, path2)
+    return 0
+
+if __name__ == "__main__":
+    exit(main(sys.argv[1:]))
+# print " ", results[k]
diff --git a/data_generator.py b/data_generator.py
index b6373b1..096da3b 100644
--- a/data_generator.py
+++ b/data_generator.py
@@ -1,11 +1,11 @@
-import sys
 import os
+import sys
 import uuid
 import random
 import itertools
 
 from petname import Generate as pet_generate
-from storage_api import create_storage, TEST_PATH
+from storage_api import create_storage
 
 from report import ssize_to_kb
 
@@ -13,12 +13,11 @@
 random.shuffle(types)
 tp = itertools.cycle(types)
 
-sz = ["4k", "64k", "1m"]
+sz = ["1k", "4k", "64k", "256k", "1m"]
 op_type = ["randread", "read", "randwrite", "write"]
 is_sync = ["s", "a"]
 
-
-storage = create_storage("file://" + TEST_PATH + "/sample.json", "", "")
+storage = create_storage(sys.argv[1], "", "")
 combinations = list(itertools.product(op_type, is_sync, sz))
 
 for i in range(30):
diff --git a/io-scenario/io.py b/io-scenario/io.py
index 3b62967..8a3509a 100644
--- a/io-scenario/io.py
+++ b/io-scenario/io.py
@@ -142,7 +142,9 @@
 def do_run_iozone(params, filename, timeout, iozone_path='iozone',
                   microsecond_mode=False):
 
-    cmd = [iozone_path]
+    PATTERN = "\x6d"
+
+    cmd = [iozone_path, "-V", "109"]
 
     if params.sync:
         cmd.append('-o')
@@ -171,15 +173,22 @@
         fsz = params.size
 
     for fname in all_files:
-        ccmd = [iozone_path, "-f", fname, "-i", "0",
-                "-s",  str(fsz), "-r", str(bsz), "-w"]
-        subprocess.check_output(ccmd)
+        with open(fname, "wb") as fd:
+            if fsz > 1024:
+                pattern = PATTERN * 1024 * 1024
+                for _ in range(int(fsz / 1024) + 1):
+                    fd.write(pattern)
+            else:
+                fd.write(PATTERN * 1024 * fsz)
+            fd.flush()
 
     cmd.append('-i')
 
     if params.action == 'write':
         cmd.append("0")
-    elif params.action == 'randwrite':
+    elif params.action == 'read':
+        cmd.append("1")
+    elif params.action == 'randwrite' or params.action == 'randread':
         cmd.append("2")
     else:
         raise ValueError("Unknown action {0!r}".format(params.action))
@@ -206,14 +215,13 @@
         elif params.action == 'randread':
             res['bw_mean'] = parsed_res['random read']
     except:
-        print raw_res
         raise
 
     # res['bw_dev'] = 0
     # res['bw_max'] = res["bw_mean"]
     # res['bw_min'] = res["bw_mean"]
 
-    return res
+    return res, " ".join(cmd)
 
 
 def run_iozone(benchmark, iozone_path, tmpname, timeout=None):
@@ -221,7 +229,7 @@
         benchmark.size = benchmark.blocksize * 50
         res_time = do_run_iozone(benchmark, tmpname, timeout,
                                  iozone_path=iozone_path,
-                                 microsecond_mode=True)
+                                 microsecond_mode=True)[0]
 
         size = (benchmark.blocksize * timeout * 1000000)
         size /= res_time["bw_mean"]
@@ -252,8 +260,7 @@
         if is_ubuntu or "Debian GNU/Linux" in os_release_cont:
             subprocess.check_output(["apt-get", "install", "iozone3"])
             return
-    except (IOError, OSError) as exc:
-        print exc
+    except (IOError, OSError):
         pass
 
     raise RuntimeError("Unknown host OS.")
@@ -308,11 +315,11 @@
         cmd_line.append("--prio=0")
 
     raw_out = subprocess.check_output(cmd_line)
-    return json.loads(raw_out)["jobs"][0]
+    return json.loads(raw_out)["jobs"][0], " ".join(cmd_line)
 
 
 def run_fio(benchmark, fio_path, tmpname, timeout=None):
-    job_output = run_fio_once(benchmark, fio_path, tmpname, timeout)
+    job_output, cmd_line = run_fio_once(benchmark, fio_path, tmpname, timeout)
 
     if benchmark.action in ('write', 'randwrite'):
         raw_result = job_output['write']
@@ -325,11 +332,11 @@
     for field in ["bw_mean"]:
         res[field] = raw_result[field]
 
-    return res
+    return res, cmd_line
 
 
 def locate_fio():
-    return False, None
+    return False, which('fio')
 
 
 # ----------------------------------------------------------------------------
@@ -380,6 +387,22 @@
         raise ValueError(msg)
 
 
+def type_size_ext(string):
+    if string.startswith("x"):
+        int(string[1:])
+        return string
+
+    if string.startswith("r"):
+        int(string[1:])
+        return string
+
+    try:
+        return re.match("\d+[KGBM]?", string, re.I).group(0)
+    except:
+        msg = "{0!r} don't looks like size-description string".format(string)
+        raise ValueError(msg)
+
+
 def ssize_to_kb(ssize):
     try:
         smap = dict(k=1, K=1, M=1024, m=1024, G=1024**2, g=1024**2)
@@ -397,6 +420,19 @@
         raise ValueError(tmpl.format(ssize))
 
 
+def get_ram_size():
+    try:
+        with open("/proc/meminfo") as fd:
+            for ln in fd:
+                if "MemTotal:" in ln:
+                    sz, kb = ln.split(':')[1].strip().split(" ")
+                    assert kb == 'kB'
+                    return int(sz)
+    except (ValueError, TypeError, AssertionError):
+        raise
+        # return None
+
+
 def parse_args(argv):
     parser = argparse.ArgumentParser(
         description="Run 'iozone' or 'fio' and return result")
@@ -417,7 +453,7 @@
         "--timeout", metavar="TIMEOUT", type=int,
         help="runtime of a single run", default=None)
     parser.add_argument(
-        "--iosize", metavar="SIZE", type=type_size,
+        "--iosize", metavar="SIZE", type=type_size_ext,
         help="file size", default=None)
     parser.add_argument(
         "-s", "--sync", default=False, action="store_true",
@@ -445,7 +481,16 @@
     argv_obj.blocksize = ssize_to_kb(argv_obj.blocksize)
 
     if argv_obj.iosize is not None:
-        argv_obj.iosize = ssize_to_kb(argv_obj.iosize)
+        if argv_obj.iosize.startswith('x'):
+            argv_obj.iosize = argv_obj.blocksize * int(argv_obj.iosize[1:])
+        elif argv_obj.iosize.startswith('r'):
+            rs = get_ram_size()
+            if rs is None:
+                sys.stderr.write("Can't determine ram size\n")
+                exit(1)
+            argv_obj.iosize = rs * int(argv_obj.iosize[1:])
+        else:
+            argv_obj.iosize = ssize_to_kb(argv_obj.iosize)
 
     benchmark = BenchmarkOption(1,
                                 argv_obj.iodepth,
@@ -469,6 +514,7 @@
                                                argv_obj.binary_path)
 
     if binary_path is None:
+        sys.stderr.write("Can't locate binary {0}\n".format(argv_obj.type))
         return 1
 
     try:
@@ -477,11 +523,12 @@
             if dt > 0:
                 time.sleep(dt)
 
-        res = run_benchmark(argv_obj.type,
-                            benchmark,
-                            binary_path,
-                            test_file_name)
-        res['__meta__'] = benchmark.__dict__
+        res, cmd = run_benchmark(argv_obj.type,
+                                 benchmark,
+                                 binary_path,
+                                 test_file_name)
+        res['__meta__'] = benchmark.__dict__.copy()
+        res['__meta__']['cmdline'] = cmd
         sys.stdout.write(json.dumps(res) + "\n")
     finally:
         if remove_binary:
@@ -500,7 +547,6 @@
     # this line would be patched in case of run under rally
     # don't modify it!
     argvs = INSERT_TOOL_ARGS(sys.argv[1:])
-
     code = 0
     for argv in argvs:
         tcode = main(argv)
diff --git a/io-scenario/io.yaml b/io-scenario/io.yaml
index df2bc51..deb4b99 100644
--- a/io-scenario/io.yaml
+++ b/io-scenario/io.yaml
@@ -2,7 +2,7 @@
     -
         args:
             flavor:
-                name: "m1.small"
+                name: "ceph.512"
             image:
                 name: "ubuntu"
 
diff --git a/run.sh b/run.sh
new file mode 100644
index 0000000..342356e
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+set -x
+set -e
+
+type="iozone"
+
+bsizes="1k 4k 64k 256k 1m"
+ops="write randwrite"
+osync="s a"
+three_times="1 2 3"
+
+for bsize in $bsizes ; do
+	for op in $ops ; do 
+		for sync in $osync ; do 
+			for xxx in $three_times ; do
+				if [[ "$ops" == "write" && "$osync" == "s" ]] ; then
+					continue
+				fi
+
+				if [[ "$sync" == "s" ]] ; then
+					ssync="-s"
+					factor="x500"
+				else
+					if [[ "$bsize" == "1k" || "$bsize" == "4k" ]] ; then
+						continue
+					fi
+
+					ssync=
+					factor="r2"
+				fi
+
+				io_opts="--type $type -a $op --iodepth 16 --blocksize $bsize --iosize $factor $ssync"
+				python run_rally_test.py -l -o "$io_opts" -t io-scenario $type --rally-extra-opts="--deployment $1"
+			done
+		done
+	done
+done
+
+# bsizes="4k 64k 256k 1m"
+# ops="randread read"
+
+# for bsize in $bsizes ; do
+# 	for op in $ops ; do 
+# 		for xxx in $three_times ; do
+# 			io_opts="--type $type -a $op --iodepth 16 --blocksize $bsize --iosize r2"
+# 			python run_rally_test.py -l -o "$io_opts" -t io-scenario $type --rally-extra-opts="--deployment $1"
+# 		done
+# 	done
+# done
+
+# bsizes="1k 4k"
+# ops="randwrite write"
+# three_times="1 2 3"
+
+# for bsize in $bsizes ; do
+# 	for op in $ops ; do 
+# 		for xxx in $three_times ; do
+# 			factor="r2"
+# 			io_opts="--type $type -a $op --iodepth 16 --blocksize $bsize --iosize $factor"
+# 			python run_rally_test.py -l -o "$io_opts" -t io-scenario $type --rally-extra-opts="--deployment $1"
+# 		done
+# 	done
+# done
+
+# ops="randread read"
+
+# for op in $ops ; do 
+# 	for xxx in $three_times ; do
+# 		io_opts="--type $type -a $op --iodepth 16 --blocksize 1k --iosize r2"
+# 		python run_rally_test.py -l -o "$io_opts" -t io-scenario $type --rally-extra-opts="--deployment $1"
+# 	done
+# done
diff --git a/run_2.sh b/run_2.sh
new file mode 100644
index 0000000..566b1d5
--- /dev/null
+++ b/run_2.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+set -x
+set -e
+
+type="iozone"
+
+bsizes="1k 4k 64k 256k 1m"
+ops="randwrite write"
+osync="s a"
+three_times="1 2 3"
+
+for bsize in $bsizes ; do
+	for op in $ops ; do 
+		for sync in $osync ; do 
+			for xxx in $three_times ; do
+				if [[ "$sync" == "s" ]] ; then
+					ssync="-s"
+					factor="x500"
+				else
+					if [[ "$bsize" == "1k" || "$bsize" == "4k" ]] ; then
+						continue
+					fi
+
+					ssync=
+					factor="r2"
+				fi
+
+				python run_rally_test.py -l -o "--type $type -a $op --iodepth 16 --blocksize $bsize --iosize $factor $ssync" -t io-scenario $type --rally-extra-opts="--deployment perf-2"
+			done
+		done
+	done
+done
+
+bsizes="4k 64k 256k 1m"
+ops="randread read"
+
+for bsize in $bsizes ; do
+	for op in $ops ; do 
+		for xxx in $three_times ; do
+			python run_rally_test.py -l -o "--type $type -a $op --iodepth 16 --blocksize $bsize --iosize r2" -t io-scenario $type --rally-extra-opts="--deployment perf-2"
+		done
+	done
+done
diff --git a/run_rally_test.py b/run_rally_test.py
index 3787da4..61fd4e7 100644
--- a/run_rally_test.py
+++ b/run_rally_test.py
@@ -185,7 +185,8 @@
 
 
 def run_test(tool, testtool_py_args_v, dst_testtool_path, files_dir,
-             rally_extra_opts, max_preparation_time=300):
+             rally_extra_opts, max_preparation_time=300,
+             keet_temp_files=False):
 
     path = 'iozone' if 'iozone' == tool else 'fio'
     testtool_local = os.path.join(files_dir, path)
@@ -219,8 +220,9 @@
         return rally_result
 
     finally:
-        os.unlink(yaml_file)
-        os.unlink(py_file)
+        if not keet_temp_files:
+            os.unlink(yaml_file)
+            os.unlink(py_file)
 
 
 def parse_args(argv):
@@ -236,10 +238,13 @@
                         help="cmd line options for io.py")
     parser.add_argument("-t", "--test-directory", help="directory with test",
                         dest="test_directory", required=True)
-    parser.add_argument("rally_extra_opts", nargs="*",
-                        default=[], help="rally extra options")
     parser.add_argument("--max-preparation-time", default=300,
                         type=int, dest="max_preparation_time")
+    parser.add_argument("-k", "--keep", default=False,
+                        help="keep temporary files",
+                        dest="keet_temp_files", action='store_true')
+    parser.add_argument("--rally-extra-opts", dest="rally_extra_opts",
+                        default="", help="rally extra options")
 
     return parser.parse_args(argv)
 
@@ -277,7 +282,10 @@
                             tt_argv.append('-s')
             testtool_py_args_v.append(tt_argv)
     else:
-        testtool_py_args_v = [o.split(" ") for o in opts.io_opts]
+        testtool_py_args_v = []
+        for o in opts.io_opts:
+            ttopts = [opt.strip() for opt in o.split(" ") if opt.strip() != ""]
+            testtool_py_args_v.append(ttopts)
 
     for io_argv_list in testtool_py_args_v:
         io_argv_list.extend(['--binary-path', dst_testtool_path])
@@ -286,11 +294,33 @@
                    testtool_py_args_v,
                    dst_testtool_path,
                    files_dir=opts.test_directory,
-                   rally_extra_opts=opts.rally_extra_opts,
-                   max_preparation_time=opts.max_preparation_time)
+                   rally_extra_opts=opts.rally_extra_opts.split(" "),
+                   max_preparation_time=opts.max_preparation_time,
+                   keet_temp_files=opts.keet_temp_files)
 
-    print "Results = ",
-    pprint.pprint(res)
+    print "=" * 80
+    print pprint.pformat(res)
+    print "=" * 80
+
+    if len(res) != 0:
+        bw_mean = 0.0
+        for measurement in res:
+            bw_mean += measurement["bw_mean"]
+
+        bw_mean /= len(res)
+
+        it = ((bw_mean - measurement["bw_mean"]) ** 2 for measurement in res)
+        bw_dev = sum(it) ** 0.5
+
+        meta = res[0]['__meta__']
+        key = "{0} {1} {2}k".format(meta['action'],
+                                    's' if meta['sync'] else 'a',
+                                    meta['blocksize'])
+
+        print
+        print "====> " + json.dumps({key: (int(bw_mean), int(bw_dev))})
+        print
+        print "=" * 80
 
     return 0
 
@@ -300,6 +330,8 @@
 # glance image-create --name 'ubuntu' --disk-format qcow2
 # --container-format bare --is-public true --copy-from
 # https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img
+# nova flavor-create ceph.512 ceph.512 512 50 1
+# nova server-group-create --policy anti-affinity ceph
 
 if __name__ == '__main__':
     exit(main(sys.argv[1:]))
diff --git a/storage_api.py b/storage_api.py
index 026a46d..7841297 100644
--- a/storage_api.py
+++ b/storage_api.py
@@ -1,11 +1,12 @@
 from urlparse import urlparse
 # from gspread import WorksheetNotFound, login
+# from gspread import login
 import json
 import os
-from gspread import login, WorksheetNotFound
+# from gspread import login, WorksheetNotFound
 from config import ROW_COUNT, DOCUMENT_ID, WORK_SHEET
 
-TEST_PATH = os.environ.get("TEST_PATH", os.path.dirname(__file__) + "/test_results")
+# TEST_PATH = os.environ.get("TEST_PATH", os.path.dirname(__file__) + "/test_results")
 
 
 def get_work_sheet(sheet, name, column_names):
@@ -58,7 +59,6 @@
 
 def create_storage(url, email=None, password=None):
     u = urlparse(url)
-
     if u.scheme == 'file':
         storage = DiskStorage(u.path)
     else:
@@ -187,6 +187,6 @@
         return result
 
 
-if __name__ == "__main__":
-    storage = create_storage("file:///home/gstepanov/rally-results-processor/sample.json", "", "")
-    print storage.recent_builds()
+#if __name__ == "__main__":
+#    storage = create_storage("file:///home/gstepanov/rally-results-processor/sample.json", "", "")
+#    print storage.recent_builds()