Commit | Line | Data |
---|---|---|
efdd48db JR |
1 | # Copyright (c) 2017 Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com> |
2 | # | |
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |
4 | # of this software and associated documentation files (the "Software"), to deal | |
5 | # in the Software without restriction, including without limitation the rights | |
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
7 | # copies of the Software, and to permit persons to whom the Software is | |
8 | # furnished to do so, subject to the following conditions: | |
9 | # | |
10 | # The above copyright notice and this permission notice shall be included in all | |
11 | # copies or substantial portions of the Software. | |
12 | # | |
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
19 | # SOFTWARE. | |
20 | ||
8fefa4a3 JR |
21 | import pytest |
22 | import os | |
23 | import shutil | |
24 | import subprocess | |
25 | ||
26 | import lttng_ivc.utils.ProjectFactory as ProjectFactory | |
27 | import lttng_ivc.utils.utils as utils | |
28 | import lttng_ivc.utils.runtime as Run | |
29 | import lttng_ivc.settings as Settings | |
30 | ||
31 | from lttng_ivc.utils.utils import xpath_query | |
32 | ||
33 | """ | |
34 | """ | |
35 | ||
36 | ||
37 | test_matrix_app_contexts = [ | |
38 | ("lttng-tools-2.8", "lttng-tools-2.7", False), | |
39 | ("lttng-tools-2.9", "lttng-tools-2.8", True), | |
40 | ("lttng-tools-2.8", "lttng-tools-2.9", True), | |
41 | pytest.param("lttng-tools-2.8", "lttng-tools-2.10", True, marks=pytest.mark.xfail(reason="See https://bugs.lttng.org/issues/1136")), | |
42 | ] | |
43 | ||
44 | test_matrix_blocking_timeout = [ | |
45 | ("lttng-tools-2.10", "lttng-tools-2.7", False), | |
46 | ("lttng-tools-2.10", "lttng-tools-2.8", False), | |
47 | ("lttng-tools-2.10", "lttng-tools-2.9", False), | |
48 | ("lttng-tools-2.10", "lttng-tools-2.10", True), | |
49 | ] | |
50 | ||
51 | test_matrix_monitor_timer_interval = [ | |
52 | ("lttng-tools-2.10", "lttng-tools-2.7", False), | |
53 | ("lttng-tools-2.10", "lttng-tools-2.8", False), | |
54 | ("lttng-tools-2.10", "lttng-tools-2.9", False), | |
55 | ("lttng-tools-2.10", "lttng-tools-2.10", True), | |
56 | ] | |
57 | ||
58 | runtime_matrix_app_contexts = [] | |
59 | runtime_matrix_blocking_timeout = [] | |
60 | runtime_matrix_monitor_timer_interval = [] | |
61 | ||
62 | ||
63 | if not Settings.test_only: | |
64 | runtime_matrix_app_contexts = test_matrix_app_contexts | |
65 | runtime_matrix_blocking_timeout = test_matrix_blocking_timeout | |
66 | runtime_matrix_monitor_timer_interval = test_matrix_monitor_timer_interval | |
67 | else: | |
68 | for tup in test_matrix_app_contexts: | |
69 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
70 | runtime_matrix_app_contexts.append(tup) | |
71 | for tup in test_matrix_blocking_timeout: | |
72 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
73 | runtime_matrix_blocking_timeout.append(tup) | |
74 | for tup in test_matrix_monitor_timer_interval: | |
75 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
76 | runtime_matrix_monitor_timer_interval.append(tup) | |
77 | ||
78 | ||
79 | def validate_app_context(session_name, save_file): | |
80 | xpath_provider_name = '/sessions/session[name="{}"]/domains/domain[type="JUL" or type="LOG4J"]/channels/channel/contexts/context/app/provider_name'.format(session_name) | |
81 | xpath_ctx_name = '/sessions/session[name="{}"]/domains/domain[type="JUL" or type="LOG4J"]/channels/channel/contexts/context/app/ctx_name'.format(session_name) | |
82 | xpath_node_expected = 2 | |
83 | ||
84 | # Check that the file is present | |
85 | assert(os.path.isfile(save_file)) | |
86 | # Validate provider name | |
87 | node_list = xpath_query(save_file, xpath_provider_name) | |
88 | assert(len(node_list) == xpath_node_expected) | |
89 | for node in node_list: | |
90 | assert(node.text == "myRetriever") | |
91 | ||
92 | # Validate ctx_name | |
93 | node_list = xpath_query(save_file, xpath_ctx_name) | |
94 | assert(len(node_list) == xpath_node_expected) | |
95 | for node in node_list: | |
96 | assert(node.text == "intCtx") | |
97 | ||
98 | ||
99 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_app_contexts) | |
100 | def test_save_load_app_contexts(tmpdir, tools_save_l, tools_load_l, should_load): | |
101 | ||
102 | # Prepare environment | |
103 | t_save = ProjectFactory.get_precook(tools_save_l) | |
104 | t_load = ProjectFactory.get_precook(tools_load_l) | |
105 | ||
106 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
107 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
108 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
109 | validation_path = os.path.join(str(tmpdir), 'validation') | |
110 | ||
111 | trace_name = "saved_trace" | |
112 | trace_filename = trace_name + Settings.save_ext | |
113 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
114 | ||
115 | validation_file_path = os.path.join(validation_path, trace_filename) | |
116 | ||
117 | # Craft the save | |
118 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
119 | runtime.add_project(t_save) | |
120 | ||
121 | # Start lttng-sessiond | |
122 | sessiond = utils.sessiond_spawn(runtime) | |
123 | ||
124 | runtime.run("lttng create {}".format(trace_name)) | |
125 | runtime.run("lttng enable-event --jul hello") | |
126 | runtime.run("lttng enable-event --log4j hello") | |
127 | # NOTE: For now there is a bug/quirk for which app context is applied | |
128 | # everywhere. Might need to be revisited. This influence the number of | |
129 | # node we expect in the saved file. | |
130 | runtime.run("lttng add-context --jul --type='$app.myRetriever:intCtx'") | |
131 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
132 | ||
133 | cp = runtime.subprocess_terminate(sessiond) | |
134 | if cp.returncode != 0: | |
135 | pytest.fail("Sessiond on save return code") | |
136 | ||
137 | validate_app_context(trace_name, trace_file_path) | |
138 | ||
139 | # Load the save | |
140 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
141 | runtime.add_project(t_load) | |
142 | ||
143 | # Start lttng-sessiond | |
144 | sessiond = utils.sessiond_spawn(runtime) | |
145 | ||
146 | cmd = "lttng load --input-path={} {}".format(save_load_path, trace_name) | |
147 | ||
148 | if not should_load: | |
149 | cp, out, err = runtime.run(cmd, check_return=False) | |
150 | assert(cp.returncode != 0) | |
151 | assert(utils.file_contains(err, ['Session configuration file validation failed'])) | |
152 | return | |
153 | ||
154 | runtime.run(cmd) | |
155 | ||
156 | # Since lttng list does not include context we need to re-save and | |
157 | # validate that the contexts are presend in the newly saved file. | |
158 | runtime.run("lttng save --output-path={}".format(validation_path)) | |
159 | ||
160 | cp = runtime.subprocess_terminate(sessiond) | |
161 | if cp.returncode != 0: | |
162 | pytest.fail("Sessiond on load return code") | |
163 | ||
164 | validate_app_context(trace_name, validation_file_path) | |
165 | ||
166 | ||
167 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_blocking_timeout) | |
168 | def test_save_load_blocking_timeout(tmpdir, tools_save_l, tools_load_l, should_load): | |
169 | ||
170 | # Prepare environment | |
171 | t_save = ProjectFactory.get_precook(tools_save_l) | |
172 | t_load = ProjectFactory.get_precook(tools_load_l) | |
173 | ||
174 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
175 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
176 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
177 | ||
178 | trace_name = "saved_trace" | |
179 | channel_name = "my_channel" | |
180 | trace_filename = trace_name + Settings.save_ext | |
181 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
182 | ||
183 | blocking_timeout = 1000 | |
184 | ||
185 | # Craft the save | |
186 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
187 | runtime.add_project(t_save) | |
188 | ||
189 | # Start lttng-sessiond | |
190 | sessiond = utils.sessiond_spawn(runtime) | |
191 | ||
192 | runtime.run("lttng create {}".format(trace_name)) | |
193 | runtime.run("lttng enable-channel -u --blocking-timeout {} {}".format(blocking_timeout, channel_name)) | |
194 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
195 | ||
196 | ||
197 | cp = runtime.subprocess_terminate(sessiond) | |
198 | if cp.returncode != 0: | |
199 | pytest.fail("Sessiond on save return code") | |
200 | ||
201 | assert(os.path.isfile(trace_file_path)) | |
202 | ||
203 | xpath_blocking_timeout = '/sessions/session[name="{}"]/domains/domain[type="UST"]/channels/channel[name="{}"]/blocking_timeout'.format(trace_name, channel_name) | |
204 | node = xpath_query(trace_file_path, xpath_blocking_timeout) | |
205 | assert(len(node) == 1) | |
206 | assert(node[0].text == str(blocking_timeout)) | |
207 | ||
208 | # Load the save | |
209 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
210 | runtime.add_project(t_load) | |
211 | ||
212 | # Start lttng-sessiond | |
213 | sessiond = utils.sessiond_spawn(runtime) | |
214 | ||
215 | if should_load: | |
216 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
217 | else: | |
218 | with pytest.raises(subprocess.CalledProcessError): | |
219 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
220 | cp = runtime.subprocess_terminate(sessiond) | |
221 | if cp.returncode != 0: | |
222 | pytest.fail("Sessiond on load return code") | |
223 | return | |
224 | ||
225 | cp, mi_out, err = runtime.run("lttng --mi xml list {}".format(trace_name)) | |
226 | ||
227 | cp = runtime.subprocess_terminate(sessiond) | |
228 | if cp.returncode != 0: | |
229 | pytest.fail("Sessiond on load return code") | |
230 | ||
231 | assert(os.path.isfile(mi_out)) | |
232 | xpath_mi_blocking_timeout = '/command/output/sessions/session/domains/domain/channels/channel/attributes/blocking_timeout' | |
233 | node = xpath_query(mi_out, xpath_mi_blocking_timeout) | |
234 | assert(len(node) == 1) | |
235 | assert(node[0].text == str(blocking_timeout)) | |
236 | ||
237 | ||
238 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_monitor_timer_interval) | |
239 | def test_save_load_timer_interval(tmpdir, tools_save_l, tools_load_l, should_load): | |
240 | ||
241 | # Prepare environment | |
242 | t_save = ProjectFactory.get_precook(tools_save_l) | |
243 | t_load = ProjectFactory.get_precook(tools_load_l) | |
244 | ||
245 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
246 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
247 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
248 | ||
249 | trace_name = "saved_trace" | |
250 | channel_name = "my_channel" | |
251 | trace_filename = trace_name + Settings.save_ext | |
252 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
253 | ||
254 | monitor_timer_interval = 1000 | |
255 | ||
256 | # Craft the save | |
257 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
258 | runtime.add_project(t_save) | |
259 | ||
260 | # Start lttng-sessiond | |
261 | sessiond = utils.sessiond_spawn(runtime) | |
262 | ||
263 | runtime.run("lttng create {}".format(trace_name)) | |
264 | runtime.run("lttng enable-channel -u --monitor-timer={} {}".format(monitor_timer_interval, channel_name)) | |
265 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
266 | ||
267 | assert(os.path.isfile(trace_file_path)) | |
268 | ||
269 | cp = runtime.subprocess_terminate(sessiond) | |
270 | if cp.returncode != 0: | |
271 | pytest.fail("Sessiond on save return code") | |
272 | ||
273 | assert(os.path.isfile(trace_file_path)) | |
274 | ||
275 | xpath_monitor_interval = '/sessions/session/domains/domain[type="UST"]/channels/channel/monitor_timer_interval' | |
276 | node = xpath_query(trace_file_path, xpath_monitor_interval) | |
277 | assert(len(node) == 1) | |
278 | assert(node[0].text == str(monitor_timer_interval)) | |
279 | ||
280 | # Load the save | |
281 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
282 | runtime.add_project(t_load) | |
283 | ||
284 | # Start lttng-sessiond | |
285 | sessiond = utils.sessiond_spawn(runtime) | |
286 | ||
287 | if should_load: | |
288 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
289 | else: | |
290 | with pytest.raises(subprocess.CalledProcessError): | |
291 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
292 | cp = runtime.subprocess_terminate(sessiond) | |
293 | if cp.returncode != 0: | |
294 | pytest.fail("Sessiond on load return code") | |
295 | return | |
296 | ||
297 | cp, mi_out, err = runtime.run("lttng --mi xml list {}".format(trace_name)) | |
298 | ||
299 | cp = runtime.subprocess_terminate(sessiond) | |
300 | if cp.returncode != 0: | |
301 | pytest.fail("Sessiond on load return code") | |
302 | ||
303 | assert(os.path.isfile(mi_out)) | |
304 | xpath_mi = '/command/output/sessions/session/domains/domain/channels/channel/attributes/monitor_timer_interval' | |
305 | node = xpath_query(mi_out, xpath_mi) | |
306 | assert(len(node) == 1) | |
307 | assert(node[0].text == str(monitor_timer_interval)) |