blob: cc9530916bd1bc771dbc625f721f42799f07a4aa [file] [log] [blame]
koder aka kdanilov4643fd62015-02-10 16:20:13 -08001import os
2import json
3import time
4import yaml
5import warnings
6import functools
7import contextlib
8
9from rally import exceptions
10from rally.cmd import cliutils
11from rally.cmd.main import categories
12from rally.benchmark.scenarios.vm.utils import VMScenario
13from rally.benchmark.scenarios.vm.vmtasks import VMTasks
14
15import itest
16from utils import get_barrier
17
18
19def log(x):
20 pass
21
22
23@contextlib.contextmanager
24def patch_VMTasks_boot_runcommand_delete():
25
26 try:
27 orig = VMTasks.boot_runcommand_delete
28 except AttributeError:
29 # rally code was changed
30 log("VMTasks class was changed and have no boot_runcommand_delete"
31 " method anymore. Update patch code.")
32 raise exceptions.ScriptError("monkeypatch code fails on "
33 "VMTasks.boot_runcommand_delete")
34
35 @functools.wraps(orig)
36 def new_boot_runcommand_delete(self, *args, **kwargs):
37 if 'rally_affinity_group' in os.environ:
38 group_id = os.environ['rally_affinity_group']
39 kwargs['scheduler_hints'] = {'group': group_id}
40 return orig(self, *args, **kwargs)
41
42 VMTasks.boot_runcommand_delete = new_boot_runcommand_delete
43
44 try:
45 yield
46 finally:
47 VMTasks.boot_runcommand_delete = orig
48
49
50# should actually use mock module for this,
51# but don't wanna to add new dependency
52@contextlib.contextmanager
53def patch_VMScenario_run_command_over_ssh(test_obj,
54 barrier=None,
55 latest_start_time=None):
56
57 try:
58 orig = VMScenario.run_action
59 except AttributeError:
60 # rally code was changed
61 log("VMScenario class was changed and have no run_action"
62 " method anymore. Update patch code.")
63 raise exceptions.ScriptError("monkeypatch code fails on "
64 "VMScenario.run_action")
65
66 @functools.wraps(orig)
67 def closure(self, ssh, *args, **kwargs):
68 try:
69 ssh._client.open_sftp
70 except AttributeError:
71 # rally code was changed
72 log("Prototype of VMScenario.run_command_over_ssh "
73 "was changed. Update patch code.")
74 raise exceptions.ScriptError("monkeypatch code fails on "
75 "ssh._client.open_sftp()")
76
77 test_iter = itest.run_test_iter(test_obj, ssh)
78
79 next(test_iter)
80
81 log("Start io test")
82
83 if barrier is not None:
84 if latest_start_time is not None:
85 timeout = latest_start_time - time.time()
86 else:
87 timeout = None
88
89 if timeout is not None and timeout > 0:
90 msg = "Ready and waiting on barrier. " + \
91 "Will wait at most {0} seconds"
92 log(msg.format(int(timeout)))
93
94 if not barrier(timeout):
95 log("Barrier timeouted")
96
97 try:
98 code, out, err = next(test_iter)
99 except Exception as exc:
100 log("Rally raises exception {0}".format(exc.message))
101 raise
102
103 if 0 != code:
104 templ = "Script returns error! code={0}\n {1}"
105 log(templ.format(code, err.rstrip()))
106 else:
107 log("Test finished")
108
109 # result = {"rally": 0, "srally": 1}
110 result = {"rally": 0}
111 out = json.dumps(result)
112
113 return code, out, err
114
115 VMScenario.run_action = closure
116
117 try:
118 yield
119 finally:
120 VMScenario.run_action = orig
121
122
123def run_rally(rally_args):
124 return cliutils.run(['rally'] + rally_args, categories)
125
126
127def prepare_files(dst_testtool_path, files_dir):
128
129 # we do need temporary named files
130 with warnings.catch_warnings():
131 warnings.simplefilter("ignore")
132 yaml_file = os.tmpnam()
133
134 yaml_src_cont = open(os.path.join(files_dir, "io.yaml")).read()
135 task_params = yaml.load(yaml_src_cont)
136 rcd_params = task_params['VMTasks.boot_runcommand_delete']
137 rcd_params[0]['args']['script'] = os.path.join(files_dir, "io.py")
138 yaml_dst_cont = yaml.dump(task_params)
139
140 open(yaml_file, "w").write(yaml_dst_cont)
141
142 return yaml_file
143
144
145def run_tests_using_rally(obj,
146 files_dir,
147 testtool_py_args,
148 dst_testtool_path,
149 max_preparation_time,
150 rally_extra_opts,
151 keep_temp_files):
152
153 yaml_file, py_file = prepare_files(testtool_py_args,
154 dst_testtool_path,
155 files_dir)
156
157 try:
158 do_patch1 = patch_VMScenario_run_command_over_ssh
159 config = yaml.load(open(yaml_file).read())
160
161 vm_sec = 'VMTasks.boot_runcommand_delete'
162 concurrency = config[vm_sec][0]['runner']['concurrency']
163
164 barrier = get_barrier(concurrency)
165 max_release_time = time.time() + max_preparation_time
166
167 with patch_VMTasks_boot_runcommand_delete():
168 with do_patch1(obj, barrier, max_release_time):
169 opts = ['task', 'start', yaml_file] + list(rally_extra_opts)
170 log("Start rally with opts '{0}'".format(" ".join(opts)))
171 run_rally(opts)
172 finally:
173 if not keep_temp_files:
174 os.unlink(yaml_file)
175 os.unlink(py_file)
176
177
178def get_rally_runner(files_dir,
179 max_preparation_time,
180 rally_extra_opts,
181 keep_temp_files):
182
183 def closure(obj):
184 run_tests_using_rally(obj,
185 files_dir,
186 max_preparation_time,
187 rally_extra_opts,
188 keep_temp_files)
189 return closure