Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: GPL-2.0-only |
d907165c | 2 | # |
0235b0db | 3 | # Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com> |
d907165c | 4 | # |
d907165c SM |
5 | |
6 | import unittest | |
7 | import bt2 | |
8 | import os | |
a38d7650 | 9 | import re |
d907165c SM |
10 | |
11 | ||
bbff0ab4 | 12 | test_ctf_traces_path = os.environ['BT_CTF_TRACES_PATH'] |
d907165c SM |
13 | |
14 | ||
1d4ac4b6 FD |
15 | # Key to sort streams in a predictable order. |
16 | def sort_predictably(stream): | |
0dc26f89 | 17 | return stream['port-name'] |
d907165c SM |
18 | |
19 | ||
20 | class QueryTraceInfoClockOffsetTestCase(unittest.TestCase): | |
d907165c SM |
21 | def setUp(self): |
22 | ctf = bt2.find_plugin('ctf') | |
23 | self._fs = ctf.source_component_classes['fs'] | |
24 | ||
73760435 | 25 | self._inputs = [ |
cfbd7cf3 FD |
26 | os.path.join(test_ctf_traces_path, 'intersection', '3eventsintersect') |
27 | ] | |
d907165c SM |
28 | |
29 | def _check(self, trace, offset): | |
5f2a1585 | 30 | streams = sorted(trace['stream-infos'], key=sort_predictably) |
d907165c SM |
31 | self.assertEqual(streams[0]['range-ns']['begin'], 13515309000000000 + offset) |
32 | self.assertEqual(streams[0]['range-ns']['end'], 13515309000000100 + offset) | |
33 | self.assertEqual(streams[1]['range-ns']['begin'], 13515309000000070 + offset) | |
34 | self.assertEqual(streams[1]['range-ns']['end'], 13515309000000120 + offset) | |
35 | ||
36 | # Test various cominations of the clock-class-offset-s and | |
5f2a1585 | 37 | # clock-class-offset-ns parameters to babeltrace.trace-infos queries. |
d907165c SM |
38 | |
39 | # Without clock class offset | |
40 | ||
41 | def test_no_clock_class_offset(self): | |
3c729b9a | 42 | res = bt2.QueryExecutor( |
5f2a1585 | 43 | self._fs, 'babeltrace.trace-infos', {'inputs': self._inputs} |
3c729b9a | 44 | ).query() |
d907165c SM |
45 | trace = res[0] |
46 | self._check(trace, 0) | |
47 | ||
48 | # With clock-class-offset-s | |
49 | ||
50 | def test_clock_class_offset_s(self): | |
3c729b9a | 51 | res = bt2.QueryExecutor( |
1a29b831 | 52 | self._fs, |
5f2a1585 | 53 | 'babeltrace.trace-infos', |
1a29b831 | 54 | {'inputs': self._inputs, 'clock-class-offset-s': 2}, |
3c729b9a | 55 | ).query() |
d907165c SM |
56 | trace = res[0] |
57 | self._check(trace, 2000000000) | |
58 | ||
59 | # With clock-class-offset-ns | |
60 | ||
61 | def test_clock_class_offset_ns(self): | |
3c729b9a | 62 | res = bt2.QueryExecutor( |
1a29b831 | 63 | self._fs, |
5f2a1585 | 64 | 'babeltrace.trace-infos', |
1a29b831 | 65 | {'inputs': self._inputs, 'clock-class-offset-ns': 2}, |
3c729b9a | 66 | ).query() |
d907165c SM |
67 | trace = res[0] |
68 | self._check(trace, 2) | |
69 | ||
70 | # With both, negative | |
71 | ||
72 | def test_clock_class_offset_both(self): | |
3c729b9a | 73 | res = bt2.QueryExecutor( |
cfbd7cf3 | 74 | self._fs, |
5f2a1585 | 75 | 'babeltrace.trace-infos', |
cfbd7cf3 | 76 | { |
73760435 | 77 | 'inputs': self._inputs, |
cfbd7cf3 FD |
78 | 'clock-class-offset-s': -2, |
79 | 'clock-class-offset-ns': -2, | |
80 | }, | |
3c729b9a | 81 | ).query() |
d907165c SM |
82 | trace = res[0] |
83 | self._check(trace, -2000000002) | |
84 | ||
85 | def test_clock_class_offset_s_wrong_type(self): | |
a635e507 | 86 | with self.assertRaises(bt2._Error): |
3c729b9a | 87 | bt2.QueryExecutor( |
cfbd7cf3 | 88 | self._fs, |
5f2a1585 | 89 | 'babeltrace.trace-infos', |
73760435 | 90 | {'inputs': self._inputs, 'clock-class-offset-s': "2"}, |
3c729b9a | 91 | ).query() |
d907165c SM |
92 | |
93 | def test_clock_class_offset_s_wrong_type_none(self): | |
a635e507 | 94 | with self.assertRaises(bt2._Error): |
3c729b9a | 95 | bt2.QueryExecutor( |
cfbd7cf3 | 96 | self._fs, |
5f2a1585 | 97 | 'babeltrace.trace-infos', |
73760435 | 98 | {'inputs': self._inputs, 'clock-class-offset-s': None}, |
3c729b9a | 99 | ).query() |
d907165c SM |
100 | |
101 | def test_clock_class_offset_ns_wrong_type(self): | |
a635e507 | 102 | with self.assertRaises(bt2._Error): |
3c729b9a | 103 | bt2.QueryExecutor( |
cfbd7cf3 | 104 | self._fs, |
5f2a1585 | 105 | 'babeltrace.trace-infos', |
73760435 | 106 | {'inputs': self._inputs, 'clock-class-offset-ns': "2"}, |
3c729b9a | 107 | ).query() |
d907165c SM |
108 | |
109 | def test_clock_class_offset_ns_wrong_type_none(self): | |
a635e507 | 110 | with self.assertRaises(bt2._Error): |
3c729b9a | 111 | bt2.QueryExecutor( |
cfbd7cf3 | 112 | self._fs, |
5f2a1585 | 113 | 'babeltrace.trace-infos', |
73760435 | 114 | {'inputs': self._inputs, 'clock-class-offset-ns': None}, |
3c729b9a | 115 | ).query() |
d907165c | 116 | |
a38d7650 SM |
117 | |
118 | class QueryTraceInfoPortNameTestCase(unittest.TestCase): | |
119 | def setUp(self): | |
120 | ctf = bt2.find_plugin("ctf") | |
121 | self._fs = ctf.source_component_classes["fs"] | |
122 | ||
a38d7650 | 123 | def test_trace_uuid_stream_class_id_no_stream_id(self): |
3c729b9a | 124 | res = bt2.QueryExecutor( |
a38d7650 | 125 | self._fs, |
5f2a1585 | 126 | "babeltrace.trace-infos", |
a38d7650 | 127 | { |
73760435 | 128 | "inputs": [ |
a38d7650 SM |
129 | os.path.join( |
130 | test_ctf_traces_path, "intersection", "3eventsintersect" | |
131 | ) | |
132 | ] | |
133 | }, | |
3c729b9a | 134 | ).query() |
f2bad367 | 135 | |
f2bad367 | 136 | if os.environ['BT_OS_TYPE'] == 'mingw': |
b00e2e76 SM |
137 | os_stream_path = ( |
138 | '\\tests\\data\\ctf-traces\\intersection\\3eventsintersect\\' | |
139 | ) | |
140 | else: | |
141 | os_stream_path = '/tests/data/ctf-traces/intersection/3eventsintersect/' | |
f2bad367 | 142 | |
a38d7650 SM |
143 | self.assertEqual(len(res), 1) |
144 | trace = res[0] | |
5f2a1585 | 145 | streams = sorted(trace["stream-infos"], key=sort_predictably) |
a38d7650 | 146 | self.assertEqual(len(streams), 2) |
5687169d | 147 | self.assertRegex( |
a38d7650 | 148 | str(streams[0]["port-name"]), |
f2bad367 | 149 | r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*" |
b00e2e76 | 150 | + re.escape(os_stream_path + "test_stream_0") |
f2bad367 | 151 | + r"$", |
a38d7650 | 152 | ) |
5687169d | 153 | self.assertRegex( |
a38d7650 | 154 | str(streams[1]["port-name"]), |
f2bad367 | 155 | r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*" |
b00e2e76 | 156 | + re.escape(os_stream_path + "test_stream_1") |
f2bad367 | 157 | + r"$", |
a38d7650 SM |
158 | ) |
159 | ||
160 | def test_trace_uuid_no_stream_class_id_no_stream_id(self): | |
3c729b9a | 161 | res = bt2.QueryExecutor( |
a38d7650 | 162 | self._fs, |
5f2a1585 | 163 | "babeltrace.trace-infos", |
73760435 | 164 | {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]}, |
3c729b9a | 165 | ).query() |
f2bad367 | 166 | |
f2bad367 | 167 | if os.environ['BT_OS_TYPE'] == 'mingw': |
b00e2e76 SM |
168 | os_stream_path = '\\tests\\data\\ctf-traces\\succeed\\succeed1\\dummystream' |
169 | else: | |
170 | os_stream_path = '/tests/data/ctf-traces/succeed/succeed1/dummystream' | |
f2bad367 | 171 | |
a38d7650 SM |
172 | self.assertEqual(len(res), 1) |
173 | trace = res[0] | |
5f2a1585 | 174 | streams = sorted(trace["stream-infos"], key=sort_predictably) |
a38d7650 | 175 | self.assertEqual(len(streams), 1) |
5687169d | 176 | self.assertRegex( |
a38d7650 | 177 | str(streams[0]["port-name"]), |
f2bad367 | 178 | r"^2a6422d0-6cee-11e0-8c08-cb07d7b3a564 \| .*" |
b00e2e76 | 179 | + re.escape(os_stream_path) |
f2bad367 | 180 | + r"$", |
a38d7650 SM |
181 | ) |
182 | ||
183 | ||
1d4ac4b6 FD |
184 | class QueryTraceInfoRangeTestCase(unittest.TestCase): |
185 | def setUp(self): | |
186 | ctf = bt2.find_plugin("ctf") | |
187 | self._fs = ctf.source_component_classes["fs"] | |
188 | ||
1d4ac4b6 | 189 | def test_trace_no_range(self): |
1a29b831 | 190 | # This trace has no `timestamp_begin` and `timestamp_end` in its |
5f2a1585 | 191 | # packet context. The `babeltrace.trace-infos` query should omit |
1a29b831 PP |
192 | # the `range-ns` fields in the `trace` and `stream` data |
193 | # structures. | |
1d4ac4b6 | 194 | |
3c729b9a | 195 | res = bt2.QueryExecutor( |
1d4ac4b6 | 196 | self._fs, |
5f2a1585 | 197 | "babeltrace.trace-infos", |
73760435 | 198 | {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]}, |
3c729b9a | 199 | ).query() |
1d4ac4b6 FD |
200 | |
201 | self.assertEqual(len(res), 1) | |
202 | trace = res[0] | |
5f2a1585 | 203 | streams = trace["stream-infos"] |
1d4ac4b6 FD |
204 | self.assertEqual(len(streams), 1) |
205 | ||
206 | self.assertRaises(KeyError, lambda: trace['range-ns']) | |
207 | self.assertRaises(KeyError, lambda: streams[0]['range-ns']) | |
208 | ||
ce75de14 SM |
209 | def test_trace_with_tracefile_rotation(self): |
210 | res = bt2.QueryExecutor( | |
211 | self._fs, | |
212 | "babeltrace.trace-infos", | |
213 | { | |
214 | "inputs": [ | |
215 | os.path.join( | |
216 | test_ctf_traces_path, | |
217 | "succeed", | |
218 | "lttng-tracefile-rotation", | |
219 | "kernel", | |
220 | ) | |
221 | ] | |
222 | }, | |
223 | ).query() | |
224 | ||
225 | self.assertEqual(len(res), 1) | |
226 | trace = res[0] | |
227 | streams = trace["stream-infos"] | |
228 | self.assertEqual(len(streams), 4) | |
229 | ||
230 | # Note: the end timestamps are not the end timestamps found in the | |
231 | # index files, because fix_index_lttng_event_after_packet_bug changes | |
232 | # them based on the time of the last event in the stream. | |
233 | ||
234 | self.assertEqual(streams[0]['range-ns']['begin'], 1571261795455986789) | |
235 | self.assertEqual(streams[0]['range-ns']['end'], 1571261797582611840) | |
236 | ||
237 | self.assertEqual(streams[1]['range-ns']['begin'], 1571261795456368232) | |
238 | self.assertEqual(streams[1]['range-ns']['end'], 1571261797577754111) | |
239 | ||
240 | self.assertEqual(streams[2]['range-ns']['begin'], 1571261795456748255) | |
241 | self.assertEqual(streams[2]['range-ns']['end'], 1571261797577727795) | |
242 | ||
243 | self.assertEqual(streams[3]['range-ns']['begin'], 1571261795457285142) | |
244 | self.assertEqual(streams[3]['range-ns']['end'], 1571261797582522088) | |
245 | ||
1d4ac4b6 | 246 | |
8e03dac5 FD |
247 | class QueryTraceInfoPacketTimestampQuirksTestCase(unittest.TestCase): |
248 | def setUp(self): | |
249 | ctf = bt2.find_plugin('ctf') | |
250 | self._fs = ctf.source_component_classes['fs'] | |
251 | self._path = os.path.join(test_ctf_traces_path, 'succeed') | |
252 | ||
253 | def _test_lttng_quirks(self, trace_name): | |
254 | res = bt2.QueryExecutor( | |
255 | self._fs, | |
5f2a1585 | 256 | "babeltrace.trace-infos", |
8e03dac5 FD |
257 | {"inputs": [os.path.join(self._path, trace_name)]}, |
258 | ).query() | |
259 | ||
260 | self.assertEqual(len(res), 1) | |
261 | return res[0] | |
262 | ||
263 | def test_event_after_packet(self): | |
264 | trace = self._test_lttng_quirks("lttng-event-after-packet") | |
5f2a1585 | 265 | streams = trace["stream-infos"] |
8e03dac5 FD |
266 | self.assertEqual(len(streams), 1) |
267 | ||
268 | self.assertEqual(streams[0]['range-ns']['begin'], 1565957300948091100) | |
269 | self.assertEqual(streams[0]['range-ns']['end'], 1565957302180016069) | |
270 | ||
271 | def test_lttng_crash(self): | |
272 | trace = self._test_lttng_quirks("lttng-crash") | |
5f2a1585 | 273 | streams = trace["stream-infos"] |
8e03dac5 FD |
274 | self.assertEqual(len(streams), 1) |
275 | ||
276 | self.assertEqual(streams[0]['range-ns']['begin'], 1565891729288866738) | |
277 | self.assertEqual(streams[0]['range-ns']['end'], 1565891729293526525) | |
278 | ||
279 | ||
d907165c SM |
280 | if __name__ == '__main__': |
281 | unittest.main() |