blob: e9c4caa46d5dadf86e998ca4b658f0d62cf51b2d [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):
koder aka kdanilov50f18642015-02-11 08:54:44 -080068
koder aka kdanilov4643fd62015-02-10 16:20:13 -080069 try:
70 ssh._client.open_sftp
71 except AttributeError:
72 # rally code was changed
73 log("Prototype of VMScenario.run_command_over_ssh "
74 "was changed. Update patch code.")
75 raise exceptions.ScriptError("monkeypatch code fails on "
76 "ssh._client.open_sftp()")
77
78 test_iter = itest.run_test_iter(test_obj, ssh)
79
80 next(test_iter)
81
82 log("Start io test")
83
84 if barrier is not None:
85 if latest_start_time is not None:
86 timeout = latest_start_time - time.time()
87 else:
88 timeout = None
89
90 if timeout is not None and timeout > 0:
91 msg = "Ready and waiting on barrier. " + \
92 "Will wait at most {0} seconds"
93 log(msg.format(int(timeout)))
94
95 if not barrier(timeout):
96 log("Barrier timeouted")
97
98 try:
99 code, out, err = next(test_iter)
100 except Exception as exc:
101 log("Rally raises exception {0}".format(exc.message))
102 raise
103
104 if 0 != code:
105 templ = "Script returns error! code={0}\n {1}"
106 log(templ.format(code, err.rstrip()))
107 else:
108 log("Test finished")
109
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800110 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):
koder aka kdanilov50f18642015-02-11 08:54:44 -0800124 return cliutils.run(['rally', "--rally-debug"] + rally_args, categories)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800125
126
koder aka kdanilov50f18642015-02-11 08:54:44 -0800127def prepare_files(files_dir):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800128
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,
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800147 max_preparation_time,
148 rally_extra_opts,
149 keep_temp_files):
150
koder aka kdanilov50f18642015-02-11 08:54:44 -0800151 yaml_file = prepare_files(files_dir)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800152
153 try:
154 do_patch1 = patch_VMScenario_run_command_over_ssh
155 config = yaml.load(open(yaml_file).read())
156
157 vm_sec = 'VMTasks.boot_runcommand_delete'
158 concurrency = config[vm_sec][0]['runner']['concurrency']
159
160 barrier = get_barrier(concurrency)
161 max_release_time = time.time() + max_preparation_time
162
163 with patch_VMTasks_boot_runcommand_delete():
164 with do_patch1(obj, barrier, max_release_time):
165 opts = ['task', 'start', yaml_file] + list(rally_extra_opts)
166 log("Start rally with opts '{0}'".format(" ".join(opts)))
167 run_rally(opts)
168 finally:
169 if not keep_temp_files:
170 os.unlink(yaml_file)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800171
172
173def get_rally_runner(files_dir,
174 max_preparation_time,
175 rally_extra_opts,
176 keep_temp_files):
177
178 def closure(obj):
179 run_tests_using_rally(obj,
180 files_dir,
181 max_preparation_time,
182 rally_extra_opts,
183 keep_temp_files)
184 return closure