Commit | Line | Data |
---|---|---|
c80d4c65 SM |
1 | # Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com> |
2 | # | |
3 | # This program is free software; you can redistribute it and/or | |
4 | # modify it under the terms of the GNU General Public License | |
5 | # as published by the Free Software Foundation; only version 2 | |
6 | # of the License. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; if not, write to the Free Software | |
15 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
16 | ||
17 | import unittest | |
18 | import bt2 | |
19 | import os | |
ddf49b27 | 20 | import re |
1d88d4ae | 21 | from pathlib import PureWindowsPath, PurePosixPath |
c80d4c65 SM |
22 | |
23 | ||
b7c5d194 | 24 | test_ctf_traces_path = os.environ['BT_CTF_TRACES_PATH'] |
c80d4c65 SM |
25 | |
26 | ||
58117c6d FD |
27 | # Key to sort streams in a predictable order. |
28 | def sort_predictably(stream): | |
be861ace | 29 | return stream['port-name'] |
c80d4c65 SM |
30 | |
31 | ||
32 | class QueryTraceInfoClockOffsetTestCase(unittest.TestCase): | |
c80d4c65 SM |
33 | def setUp(self): |
34 | ctf = bt2.find_plugin('ctf') | |
35 | self._fs = ctf.source_component_classes['fs'] | |
36 | ||
a1040187 | 37 | self._inputs = [ |
61d96b89 FD |
38 | os.path.join(test_ctf_traces_path, 'intersection', '3eventsintersect') |
39 | ] | |
c80d4c65 SM |
40 | |
41 | def _check(self, trace, offset): | |
61d96b89 FD |
42 | self.assertEqual( |
43 | trace['intersection-range-ns']['begin'], 13515309000000070 + offset | |
44 | ) | |
45 | self.assertEqual( | |
46 | trace['intersection-range-ns']['end'], 13515309000000100 + offset | |
47 | ) | |
c80d4c65 | 48 | |
58117c6d | 49 | streams = sorted(trace['streams'], key=sort_predictably) |
c80d4c65 SM |
50 | self.assertEqual(streams[0]['range-ns']['begin'], 13515309000000000 + offset) |
51 | self.assertEqual(streams[0]['range-ns']['end'], 13515309000000100 + offset) | |
52 | self.assertEqual(streams[1]['range-ns']['begin'], 13515309000000070 + offset) | |
53 | self.assertEqual(streams[1]['range-ns']['end'], 13515309000000120 + offset) | |
54 | ||
55 | # Test various cominations of the clock-class-offset-s and | |
9e534aae | 56 | # clock-class-offset-ns parameters to babeltrace.trace-info queries. |
c80d4c65 SM |
57 | |
58 | # Without clock class offset | |
59 | ||
60 | def test_no_clock_class_offset(self): | |
bf403eb2 | 61 | res = bt2.QueryExecutor( |
9e534aae | 62 | self._fs, 'babeltrace.trace-info', {'inputs': self._inputs} |
bf403eb2 | 63 | ).query() |
c80d4c65 SM |
64 | trace = res[0] |
65 | self._check(trace, 0) | |
66 | ||
67 | # With clock-class-offset-s | |
68 | ||
69 | def test_clock_class_offset_s(self): | |
bf403eb2 | 70 | res = bt2.QueryExecutor( |
9e534aae PP |
71 | self._fs, |
72 | 'babeltrace.trace-info', | |
73 | {'inputs': self._inputs, 'clock-class-offset-s': 2}, | |
bf403eb2 | 74 | ).query() |
c80d4c65 SM |
75 | trace = res[0] |
76 | self._check(trace, 2000000000) | |
77 | ||
78 | # With clock-class-offset-ns | |
79 | ||
80 | def test_clock_class_offset_ns(self): | |
bf403eb2 | 81 | res = bt2.QueryExecutor( |
9e534aae PP |
82 | self._fs, |
83 | 'babeltrace.trace-info', | |
84 | {'inputs': self._inputs, 'clock-class-offset-ns': 2}, | |
bf403eb2 | 85 | ).query() |
c80d4c65 SM |
86 | trace = res[0] |
87 | self._check(trace, 2) | |
88 | ||
89 | # With both, negative | |
90 | ||
91 | def test_clock_class_offset_both(self): | |
bf403eb2 | 92 | res = bt2.QueryExecutor( |
61d96b89 | 93 | self._fs, |
9e534aae | 94 | 'babeltrace.trace-info', |
61d96b89 | 95 | { |
a1040187 | 96 | 'inputs': self._inputs, |
61d96b89 FD |
97 | 'clock-class-offset-s': -2, |
98 | 'clock-class-offset-ns': -2, | |
99 | }, | |
bf403eb2 | 100 | ).query() |
c80d4c65 SM |
101 | trace = res[0] |
102 | self._check(trace, -2000000002) | |
103 | ||
104 | def test_clock_class_offset_s_wrong_type(self): | |
574dea68 | 105 | with self.assertRaises(bt2._Error): |
bf403eb2 | 106 | bt2.QueryExecutor( |
61d96b89 | 107 | self._fs, |
9e534aae | 108 | 'babeltrace.trace-info', |
a1040187 | 109 | {'inputs': self._inputs, 'clock-class-offset-s': "2"}, |
bf403eb2 | 110 | ).query() |
c80d4c65 SM |
111 | |
112 | def test_clock_class_offset_s_wrong_type_none(self): | |
574dea68 | 113 | with self.assertRaises(bt2._Error): |
bf403eb2 | 114 | bt2.QueryExecutor( |
61d96b89 | 115 | self._fs, |
9e534aae | 116 | 'babeltrace.trace-info', |
a1040187 | 117 | {'inputs': self._inputs, 'clock-class-offset-s': None}, |
bf403eb2 | 118 | ).query() |
c80d4c65 SM |
119 | |
120 | def test_clock_class_offset_ns_wrong_type(self): | |
574dea68 | 121 | with self.assertRaises(bt2._Error): |
bf403eb2 | 122 | bt2.QueryExecutor( |
61d96b89 | 123 | self._fs, |
9e534aae | 124 | 'babeltrace.trace-info', |
a1040187 | 125 | {'inputs': self._inputs, 'clock-class-offset-ns': "2"}, |
bf403eb2 | 126 | ).query() |
c80d4c65 SM |
127 | |
128 | def test_clock_class_offset_ns_wrong_type_none(self): | |
574dea68 | 129 | with self.assertRaises(bt2._Error): |
bf403eb2 | 130 | bt2.QueryExecutor( |
61d96b89 | 131 | self._fs, |
9e534aae | 132 | 'babeltrace.trace-info', |
a1040187 | 133 | {'inputs': self._inputs, 'clock-class-offset-ns': None}, |
bf403eb2 | 134 | ).query() |
c80d4c65 | 135 | |
ddf49b27 SM |
136 | |
137 | class QueryTraceInfoPortNameTestCase(unittest.TestCase): | |
138 | def setUp(self): | |
139 | ctf = bt2.find_plugin("ctf") | |
140 | self._fs = ctf.source_component_classes["fs"] | |
141 | ||
ddf49b27 | 142 | def test_trace_uuid_stream_class_id_no_stream_id(self): |
bf403eb2 | 143 | res = bt2.QueryExecutor( |
ddf49b27 | 144 | self._fs, |
9e534aae | 145 | "babeltrace.trace-info", |
ddf49b27 | 146 | { |
a1040187 | 147 | "inputs": [ |
ddf49b27 SM |
148 | os.path.join( |
149 | test_ctf_traces_path, "intersection", "3eventsintersect" | |
150 | ) | |
151 | ] | |
152 | }, | |
bf403eb2 | 153 | ).query() |
1d88d4ae JR |
154 | |
155 | os_stream_path = PurePosixPath( | |
156 | '/tests/data/ctf-traces/intersection/3eventsintersect/' | |
157 | ) | |
158 | if os.environ['BT_OS_TYPE'] == 'mingw': | |
159 | os_stream_path = PureWindowsPath(os_stream_path) | |
160 | ||
ddf49b27 SM |
161 | self.assertEqual(len(res), 1) |
162 | trace = res[0] | |
58117c6d | 163 | streams = sorted(trace["streams"], key=sort_predictably) |
ddf49b27 SM |
164 | self.assertEqual(len(streams), 2) |
165 | self.assertRegexpMatches( | |
166 | str(streams[0]["port-name"]), | |
1d88d4ae JR |
167 | r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*" |
168 | + re.escape(str(os_stream_path / "test_stream_0")) | |
169 | + r"$", | |
ddf49b27 SM |
170 | ) |
171 | self.assertRegexpMatches( | |
172 | str(streams[1]["port-name"]), | |
1d88d4ae JR |
173 | r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*" |
174 | + re.escape(str(os_stream_path / "test_stream_1")) | |
175 | + r"$", | |
ddf49b27 SM |
176 | ) |
177 | ||
178 | def test_trace_uuid_no_stream_class_id_no_stream_id(self): | |
bf403eb2 | 179 | res = bt2.QueryExecutor( |
ddf49b27 | 180 | self._fs, |
9e534aae | 181 | "babeltrace.trace-info", |
a1040187 | 182 | {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]}, |
bf403eb2 | 183 | ).query() |
1d88d4ae JR |
184 | |
185 | os_stream_path = PurePosixPath( | |
186 | '/tests/data/ctf-traces/succeed/succeed1/dummystream' | |
187 | ) | |
188 | if os.environ['BT_OS_TYPE'] == 'mingw': | |
189 | os_stream_path = PureWindowsPath(os_stream_path) | |
190 | ||
ddf49b27 SM |
191 | self.assertEqual(len(res), 1) |
192 | trace = res[0] | |
58117c6d | 193 | streams = sorted(trace["streams"], key=sort_predictably) |
ddf49b27 SM |
194 | self.assertEqual(len(streams), 1) |
195 | self.assertRegexpMatches( | |
196 | str(streams[0]["port-name"]), | |
1d88d4ae JR |
197 | r"^2a6422d0-6cee-11e0-8c08-cb07d7b3a564 \| .*" |
198 | + re.escape(str(os_stream_path)) | |
199 | + r"$", | |
ddf49b27 SM |
200 | ) |
201 | ||
202 | ||
58117c6d FD |
203 | class QueryTraceInfoRangeTestCase(unittest.TestCase): |
204 | def setUp(self): | |
205 | ctf = bt2.find_plugin("ctf") | |
206 | self._fs = ctf.source_component_classes["fs"] | |
207 | ||
58117c6d | 208 | def test_trace_no_range(self): |
9e534aae PP |
209 | # This trace has no `timestamp_begin` and `timestamp_end` in its |
210 | # packet context. The `babeltrace.trace-info` query should omit | |
211 | # the `range-ns` fields in the `trace` and `stream` data | |
212 | # structures. | |
58117c6d | 213 | |
bf403eb2 | 214 | res = bt2.QueryExecutor( |
58117c6d | 215 | self._fs, |
9e534aae | 216 | "babeltrace.trace-info", |
a1040187 | 217 | {"inputs": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]}, |
bf403eb2 | 218 | ).query() |
58117c6d FD |
219 | |
220 | self.assertEqual(len(res), 1) | |
221 | trace = res[0] | |
222 | streams = trace["streams"] | |
223 | self.assertEqual(len(streams), 1) | |
224 | ||
225 | self.assertRaises(KeyError, lambda: trace['range-ns']) | |
226 | self.assertRaises(KeyError, lambda: streams[0]['range-ns']) | |
227 | ||
228 | ||
29b6760c FD |
229 | class QueryTraceInfoPacketTimestampQuirksTestCase(unittest.TestCase): |
230 | def setUp(self): | |
231 | ctf = bt2.find_plugin('ctf') | |
232 | self._fs = ctf.source_component_classes['fs'] | |
233 | self._path = os.path.join(test_ctf_traces_path, 'succeed') | |
234 | ||
235 | def _test_lttng_quirks(self, trace_name): | |
236 | res = bt2.QueryExecutor( | |
237 | self._fs, | |
238 | "babeltrace.trace-info", | |
239 | {"inputs": [os.path.join(self._path, trace_name)]}, | |
240 | ).query() | |
241 | ||
242 | self.assertEqual(len(res), 1) | |
243 | return res[0] | |
244 | ||
245 | def test_event_after_packet(self): | |
246 | trace = self._test_lttng_quirks("lttng-event-after-packet") | |
247 | streams = trace["streams"] | |
248 | self.assertEqual(len(streams), 1) | |
249 | ||
250 | self.assertEqual(streams[0]['range-ns']['begin'], 1565957300948091100) | |
251 | self.assertEqual(streams[0]['range-ns']['end'], 1565957302180016069) | |
252 | ||
253 | def test_lttng_crash(self): | |
254 | trace = self._test_lttng_quirks("lttng-crash") | |
255 | streams = trace["streams"] | |
256 | self.assertEqual(len(streams), 1) | |
257 | ||
258 | self.assertEqual(streams[0]['range-ns']['begin'], 1565891729288866738) | |
259 | self.assertEqual(streams[0]['range-ns']['end'], 1565891729293526525) | |
260 | ||
261 | ||
c80d4c65 SM |
262 | if __name__ == '__main__': |
263 | unittest.main() |