Commit | Line | Data |
---|---|---|
8fefa4a3 JR |
1 | import pytest |
2 | import os | |
3 | import shutil | |
4 | import subprocess | |
5 | ||
6 | import lttng_ivc.utils.ProjectFactory as ProjectFactory | |
7 | import lttng_ivc.utils.utils as utils | |
8 | import lttng_ivc.utils.runtime as Run | |
9 | import lttng_ivc.settings as Settings | |
10 | ||
11 | from lttng_ivc.utils.utils import xpath_query | |
12 | ||
13 | """ | |
14 | """ | |
15 | ||
16 | ||
17 | test_matrix_app_contexts = [ | |
18 | ("lttng-tools-2.8", "lttng-tools-2.7", False), | |
19 | ("lttng-tools-2.9", "lttng-tools-2.8", True), | |
20 | ("lttng-tools-2.8", "lttng-tools-2.9", True), | |
21 | pytest.param("lttng-tools-2.8", "lttng-tools-2.10", True, marks=pytest.mark.xfail(reason="See https://bugs.lttng.org/issues/1136")), | |
22 | ] | |
23 | ||
24 | test_matrix_blocking_timeout = [ | |
25 | ("lttng-tools-2.10", "lttng-tools-2.7", False), | |
26 | ("lttng-tools-2.10", "lttng-tools-2.8", False), | |
27 | ("lttng-tools-2.10", "lttng-tools-2.9", False), | |
28 | ("lttng-tools-2.10", "lttng-tools-2.10", True), | |
29 | ] | |
30 | ||
31 | test_matrix_monitor_timer_interval = [ | |
32 | ("lttng-tools-2.10", "lttng-tools-2.7", False), | |
33 | ("lttng-tools-2.10", "lttng-tools-2.8", False), | |
34 | ("lttng-tools-2.10", "lttng-tools-2.9", False), | |
35 | ("lttng-tools-2.10", "lttng-tools-2.10", True), | |
36 | ] | |
37 | ||
38 | runtime_matrix_app_contexts = [] | |
39 | runtime_matrix_blocking_timeout = [] | |
40 | runtime_matrix_monitor_timer_interval = [] | |
41 | ||
42 | ||
43 | if not Settings.test_only: | |
44 | runtime_matrix_app_contexts = test_matrix_app_contexts | |
45 | runtime_matrix_blocking_timeout = test_matrix_blocking_timeout | |
46 | runtime_matrix_monitor_timer_interval = test_matrix_monitor_timer_interval | |
47 | else: | |
48 | for tup in test_matrix_app_contexts: | |
49 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
50 | runtime_matrix_app_contexts.append(tup) | |
51 | for tup in test_matrix_blocking_timeout: | |
52 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
53 | runtime_matrix_blocking_timeout.append(tup) | |
54 | for tup in test_matrix_monitor_timer_interval: | |
55 | if(tup[0] in Settings.test_only or tup[1] in Settings.test_only): | |
56 | runtime_matrix_monitor_timer_interval.append(tup) | |
57 | ||
58 | ||
59 | def validate_app_context(session_name, save_file): | |
60 | xpath_provider_name = '/sessions/session[name="{}"]/domains/domain[type="JUL" or type="LOG4J"]/channels/channel/contexts/context/app/provider_name'.format(session_name) | |
61 | xpath_ctx_name = '/sessions/session[name="{}"]/domains/domain[type="JUL" or type="LOG4J"]/channels/channel/contexts/context/app/ctx_name'.format(session_name) | |
62 | xpath_node_expected = 2 | |
63 | ||
64 | # Check that the file is present | |
65 | assert(os.path.isfile(save_file)) | |
66 | # Validate provider name | |
67 | node_list = xpath_query(save_file, xpath_provider_name) | |
68 | assert(len(node_list) == xpath_node_expected) | |
69 | for node in node_list: | |
70 | assert(node.text == "myRetriever") | |
71 | ||
72 | # Validate ctx_name | |
73 | node_list = xpath_query(save_file, xpath_ctx_name) | |
74 | assert(len(node_list) == xpath_node_expected) | |
75 | for node in node_list: | |
76 | assert(node.text == "intCtx") | |
77 | ||
78 | ||
79 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_app_contexts) | |
80 | def test_save_load_app_contexts(tmpdir, tools_save_l, tools_load_l, should_load): | |
81 | ||
82 | # Prepare environment | |
83 | t_save = ProjectFactory.get_precook(tools_save_l) | |
84 | t_load = ProjectFactory.get_precook(tools_load_l) | |
85 | ||
86 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
87 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
88 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
89 | validation_path = os.path.join(str(tmpdir), 'validation') | |
90 | ||
91 | trace_name = "saved_trace" | |
92 | trace_filename = trace_name + Settings.save_ext | |
93 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
94 | ||
95 | validation_file_path = os.path.join(validation_path, trace_filename) | |
96 | ||
97 | # Craft the save | |
98 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
99 | runtime.add_project(t_save) | |
100 | ||
101 | # Start lttng-sessiond | |
102 | sessiond = utils.sessiond_spawn(runtime) | |
103 | ||
104 | runtime.run("lttng create {}".format(trace_name)) | |
105 | runtime.run("lttng enable-event --jul hello") | |
106 | runtime.run("lttng enable-event --log4j hello") | |
107 | # NOTE: For now there is a bug/quirk for which app context is applied | |
108 | # everywhere. Might need to be revisited. This influence the number of | |
109 | # node we expect in the saved file. | |
110 | runtime.run("lttng add-context --jul --type='$app.myRetriever:intCtx'") | |
111 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
112 | ||
113 | cp = runtime.subprocess_terminate(sessiond) | |
114 | if cp.returncode != 0: | |
115 | pytest.fail("Sessiond on save return code") | |
116 | ||
117 | validate_app_context(trace_name, trace_file_path) | |
118 | ||
119 | # Load the save | |
120 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
121 | runtime.add_project(t_load) | |
122 | ||
123 | # Start lttng-sessiond | |
124 | sessiond = utils.sessiond_spawn(runtime) | |
125 | ||
126 | cmd = "lttng load --input-path={} {}".format(save_load_path, trace_name) | |
127 | ||
128 | if not should_load: | |
129 | cp, out, err = runtime.run(cmd, check_return=False) | |
130 | assert(cp.returncode != 0) | |
131 | assert(utils.file_contains(err, ['Session configuration file validation failed'])) | |
132 | return | |
133 | ||
134 | runtime.run(cmd) | |
135 | ||
136 | # Since lttng list does not include context we need to re-save and | |
137 | # validate that the contexts are presend in the newly saved file. | |
138 | runtime.run("lttng save --output-path={}".format(validation_path)) | |
139 | ||
140 | cp = runtime.subprocess_terminate(sessiond) | |
141 | if cp.returncode != 0: | |
142 | pytest.fail("Sessiond on load return code") | |
143 | ||
144 | validate_app_context(trace_name, validation_file_path) | |
145 | ||
146 | ||
147 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_blocking_timeout) | |
148 | def test_save_load_blocking_timeout(tmpdir, tools_save_l, tools_load_l, should_load): | |
149 | ||
150 | # Prepare environment | |
151 | t_save = ProjectFactory.get_precook(tools_save_l) | |
152 | t_load = ProjectFactory.get_precook(tools_load_l) | |
153 | ||
154 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
155 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
156 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
157 | ||
158 | trace_name = "saved_trace" | |
159 | channel_name = "my_channel" | |
160 | trace_filename = trace_name + Settings.save_ext | |
161 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
162 | ||
163 | blocking_timeout = 1000 | |
164 | ||
165 | # Craft the save | |
166 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
167 | runtime.add_project(t_save) | |
168 | ||
169 | # Start lttng-sessiond | |
170 | sessiond = utils.sessiond_spawn(runtime) | |
171 | ||
172 | runtime.run("lttng create {}".format(trace_name)) | |
173 | runtime.run("lttng enable-channel -u --blocking-timeout {} {}".format(blocking_timeout, channel_name)) | |
174 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
175 | ||
176 | ||
177 | cp = runtime.subprocess_terminate(sessiond) | |
178 | if cp.returncode != 0: | |
179 | pytest.fail("Sessiond on save return code") | |
180 | ||
181 | assert(os.path.isfile(trace_file_path)) | |
182 | ||
183 | xpath_blocking_timeout = '/sessions/session[name="{}"]/domains/domain[type="UST"]/channels/channel[name="{}"]/blocking_timeout'.format(trace_name, channel_name) | |
184 | node = xpath_query(trace_file_path, xpath_blocking_timeout) | |
185 | assert(len(node) == 1) | |
186 | assert(node[0].text == str(blocking_timeout)) | |
187 | ||
188 | # Load the save | |
189 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
190 | runtime.add_project(t_load) | |
191 | ||
192 | # Start lttng-sessiond | |
193 | sessiond = utils.sessiond_spawn(runtime) | |
194 | ||
195 | if should_load: | |
196 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
197 | else: | |
198 | with pytest.raises(subprocess.CalledProcessError): | |
199 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
200 | cp = runtime.subprocess_terminate(sessiond) | |
201 | if cp.returncode != 0: | |
202 | pytest.fail("Sessiond on load return code") | |
203 | return | |
204 | ||
205 | cp, mi_out, err = runtime.run("lttng --mi xml list {}".format(trace_name)) | |
206 | ||
207 | cp = runtime.subprocess_terminate(sessiond) | |
208 | if cp.returncode != 0: | |
209 | pytest.fail("Sessiond on load return code") | |
210 | ||
211 | assert(os.path.isfile(mi_out)) | |
212 | xpath_mi_blocking_timeout = '/command/output/sessions/session/domains/domain/channels/channel/attributes/blocking_timeout' | |
213 | node = xpath_query(mi_out, xpath_mi_blocking_timeout) | |
214 | assert(len(node) == 1) | |
215 | assert(node[0].text == str(blocking_timeout)) | |
216 | ||
217 | ||
218 | @pytest.mark.parametrize("tools_save_l,tools_load_l,should_load", runtime_matrix_monitor_timer_interval) | |
219 | def test_save_load_timer_interval(tmpdir, tools_save_l, tools_load_l, should_load): | |
220 | ||
221 | # Prepare environment | |
222 | t_save = ProjectFactory.get_precook(tools_save_l) | |
223 | t_load = ProjectFactory.get_precook(tools_load_l) | |
224 | ||
225 | t_save_runtime_path = os.path.join(str(tmpdir), "tools-save") | |
226 | t_load_runtime_path = os.path.join(str(tmpdir), "tools-load") | |
227 | save_load_path = os.path.join(str(tmpdir), 'save_load') | |
228 | ||
229 | trace_name = "saved_trace" | |
230 | channel_name = "my_channel" | |
231 | trace_filename = trace_name + Settings.save_ext | |
232 | trace_file_path = os.path.join(save_load_path, trace_filename) | |
233 | ||
234 | monitor_timer_interval = 1000 | |
235 | ||
236 | # Craft the save | |
237 | with Run.get_runtime(t_save_runtime_path) as runtime: | |
238 | runtime.add_project(t_save) | |
239 | ||
240 | # Start lttng-sessiond | |
241 | sessiond = utils.sessiond_spawn(runtime) | |
242 | ||
243 | runtime.run("lttng create {}".format(trace_name)) | |
244 | runtime.run("lttng enable-channel -u --monitor-timer={} {}".format(monitor_timer_interval, channel_name)) | |
245 | runtime.run("lttng save --output-path={}".format(save_load_path)) | |
246 | ||
247 | assert(os.path.isfile(trace_file_path)) | |
248 | ||
249 | cp = runtime.subprocess_terminate(sessiond) | |
250 | if cp.returncode != 0: | |
251 | pytest.fail("Sessiond on save return code") | |
252 | ||
253 | assert(os.path.isfile(trace_file_path)) | |
254 | ||
255 | xpath_monitor_interval = '/sessions/session/domains/domain[type="UST"]/channels/channel/monitor_timer_interval' | |
256 | node = xpath_query(trace_file_path, xpath_monitor_interval) | |
257 | assert(len(node) == 1) | |
258 | assert(node[0].text == str(monitor_timer_interval)) | |
259 | ||
260 | # Load the save | |
261 | with Run.get_runtime(t_load_runtime_path) as runtime: | |
262 | runtime.add_project(t_load) | |
263 | ||
264 | # Start lttng-sessiond | |
265 | sessiond = utils.sessiond_spawn(runtime) | |
266 | ||
267 | if should_load: | |
268 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
269 | else: | |
270 | with pytest.raises(subprocess.CalledProcessError): | |
271 | runtime.run("lttng load --input-path={} {}".format(save_load_path, trace_name)) | |
272 | cp = runtime.subprocess_terminate(sessiond) | |
273 | if cp.returncode != 0: | |
274 | pytest.fail("Sessiond on load return code") | |
275 | return | |
276 | ||
277 | cp, mi_out, err = runtime.run("lttng --mi xml list {}".format(trace_name)) | |
278 | ||
279 | cp = runtime.subprocess_terminate(sessiond) | |
280 | if cp.returncode != 0: | |
281 | pytest.fail("Sessiond on load return code") | |
282 | ||
283 | assert(os.path.isfile(mi_out)) | |
284 | xpath_mi = '/command/output/sessions/session/domains/domain/channels/channel/attributes/monitor_timer_interval' | |
285 | node = xpath_query(mi_out, xpath_mi) | |
286 | assert(len(node) == 1) | |
287 | assert(node[0].text == str(monitor_timer_interval)) |