Fix: test: babeltrace1 python bindings exposes `op_enum` as a string
[lttng-tools.git] / tests / regression / kernel / validate_select_poll_epoll.py
CommitLineData
a0b1f42c 1#!/usr/bin/env python3
9d16b343
MJ
2#
3# Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4#
5# SPDX-License-Identifier: GPL-2.0-only
6#
a0b1f42c 7
4c4634e3
FD
8import argparse
9import pprint
a0b1f42c
JD
10import sys
11import time
2af9cd67 12import json
4c4634e3
FD
13
14from collections import defaultdict
a0b1f42c
JD
15
16NSEC_PER_SEC = 1000000000
17
18try:
19 from babeltrace import TraceCollection
20except ImportError:
21 # quick fix for debian-based distros
22 sys.path.append("/usr/local/lib/python%d.%d/site-packages" %
23 (sys.version_info.major, sys.version_info.minor))
24 from babeltrace import TraceCollection
25
26
27class TraceParser:
28 def __init__(self, trace, pid):
29 self.trace = trace
30 self.pid = pid
4c4634e3
FD
31
32 # This dictionnary holds the results of each testcases of a test.
33 # Its layout is the following:
34 # self.expect={
35 # 'event_name_1': {'check_1': 0, 'check_2: 1},
36 # 'event_name_2': {'check_1': 1}
37 # }
38 # Each test classes checks the payload of different events. Each of
39 # those checks are stored in a event_name specific dictionnary in this
40 # data structure.
41 self.expect = defaultdict(lambda : defaultdict(int))
42
43 # This dictionnary holds the value recorded in the trace that are
44 # tested. Its content is use to print the values that caused a test to
45 # fail.
46 self.recorded_values = {}
a0b1f42c
JD
47
48 def ns_to_hour_nsec(self, ns):
49 d = time.localtime(ns/NSEC_PER_SEC)
50 return "%02d:%02d:%02d.%09d" % (d.tm_hour, d.tm_min, d.tm_sec,
51 ns % NSEC_PER_SEC)
52
53 def parse(self):
54 # iterate over all the events
55 for event in self.trace.events:
56 if self.pid is not None and event["pid"] != self.pid:
57 continue
58
59 method_name = "handle_%s" % event.name.replace(":", "_").replace(
60 "+", "_")
61 # call the function to handle each event individually
62 if hasattr(TraceParser, method_name):
63 func = getattr(TraceParser, method_name)
64 func(self, event)
65
66 ret = 0
4c4634e3
FD
67 # For each event of the test case, check all entries for failed
68 for event_name, event_results in self.expect.items():
69 for val in event_results.keys():
70 if self.expect[event_name][val] == 0:
71 print("%s not validated" % val)
72 print("Values of the local variables of this test:")
73 # using pprint for pretty printing the dictionnary
74 pprint.pprint(self.recorded_values[event_name])
75 ret = 1
a0b1f42c
JD
76
77 return ret
78
79 # epoll_ctl
80 def handle_compat_syscall_entry_epoll_ctl(self, event):
81 self.epoll_ctl_entry(event)
82
83 def handle_compat_syscall_exit_epoll_ctl(self, event):
84 self.epoll_ctl_exit(event)
85
86 def handle_syscall_entry_epoll_ctl(self, event):
87 self.epoll_ctl_entry(event)
88
89 def handle_syscall_exit_epoll_ctl(self, event):
90 self.epoll_ctl_exit(event)
91
92 def epoll_ctl_entry(self, event):
93 pass
94
95 def epoll_ctl_exit(self, event):
96 pass
97
98 # epoll_wait + epoll_pwait
99 def handle_compat_syscall_entry_epoll_wait(self, event):
100 self.epoll_wait_entry(event)
101
102 def handle_compat_syscall_exit_epoll_wait(self, event):
103 self.epoll_wait_exit(event)
104
105 def handle_syscall_entry_epoll_wait(self, event):
106 self.epoll_wait_entry(event)
107
108 def handle_syscall_exit_epoll_wait(self, event):
109 self.epoll_wait_exit(event)
110
111 def handle_compat_syscall_entry_epoll_pwait(self, event):
2af9cd67 112 self.epoll_pwait_entry(event)
a0b1f42c
JD
113
114 def handle_compat_syscall_exit_epoll_pwait(self, event):
2af9cd67 115 self.epoll_pwait_exit(event)
a0b1f42c
JD
116
117 def handle_syscall_entry_epoll_pwait(self, event):
2af9cd67 118 self.epoll_pwait_entry(event)
a0b1f42c
JD
119
120 def handle_syscall_exit_epoll_pwait(self, event):
2af9cd67 121 self.epoll_pwait_exit(event)
a0b1f42c
JD
122
123 def epoll_wait_entry(self, event):
124 pass
125
126 def epoll_wait_exit(self, event):
127 pass
128
2af9cd67
JG
129 def epoll_pwait_entry(self, event):
130 self.epoll_wait_entry(event)
131
132 def epoll_pwait_exit(self, event):
133 self.epoll_wait_exit(event)
134
a0b1f42c
JD
135 ## poll + ppoll
136 def handle_compat_syscall_entry_poll(self, event):
137 self.poll_entry(event)
138
139 def handle_compat_syscall_exit_poll(self, event):
140 self.poll_exit(event)
141
142 def handle_syscall_entry_poll(self, event):
143 self.poll_entry(event)
144
145 def handle_syscall_exit_poll(self, event):
146 self.poll_exit(event)
147
148 def handle_compat_syscall_entry_ppoll(self, event):
149 self.poll_entry(event)
150
151 def handle_compat_syscall_exit_ppoll(self, event):
152 self.poll_exit(event)
153
154 def handle_syscall_entry_ppoll(self, event):
155 self.poll_entry(event)
156
157 def handle_syscall_exit_ppoll(self, event):
158 self.poll_exit(event)
159
160 def poll_entry(self, event):
161 pass
162
163 def poll_exit(self, event):
164 pass
165
166 # epoll_create
167 def handle_compat_syscall_entry_epoll_create1(self, event):
168 self.epoll_create_entry(event)
169
170 def handle_compat_syscall_exit_epoll_create1(self, event):
171 self.epoll_create_exit(event)
172
173 def handle_compat_syscall_entry_epoll_create(self, event):
174 self.epoll_create_entry(event)
175
176 def handle_compat_syscall_exit_epoll_create(self, event):
177 self.epoll_create_exit(event)
178
179 def handle_syscall_entry_epoll_create1(self, event):
180 self.epoll_create_entry(event)
181
182 def handle_syscall_exit_epoll_create1(self, event):
183 self.epoll_create_exit(event)
184
185 def handle_syscall_entry_epoll_create(self, event):
186 self.epoll_create_entry(event)
187
188 def handle_syscall_exit_epoll_create(self, event):
189 self.epoll_create_exit(event)
190
191 def epoll_create_entry(self, event):
192 pass
193
194 def epoll_create_exit(self, event):
195 pass
196
197 # select + pselect6
198 def handle_syscall_entry_pselect6(self, event):
199 self.select_entry(event)
200
201 def handle_syscall_exit_pselect6(self, event):
202 self.select_exit(event)
203
204 def handle_compat_syscall_entry_pselect6(self, event):
205 self.select_entry(event)
206
207 def handle_compat_syscall_exit_pselect6(self, event):
208 self.select_exit(event)
209
210 def handle_syscall_entry_select(self, event):
211 self.select_entry(event)
212
213 def handle_syscall_exit_select(self, event):
214 self.select_exit(event)
215
216 def handle_compat_syscall_entry_select(self, event):
217 self.select_entry(event)
218
219 def handle_compat_syscall_exit_select(self, event):
220 self.select_exit(event)
221
222 def select_entry(self, event):
223 pass
224
225 def select_exit(self, event):
226 pass
227
228
229class Test1(TraceParser):
2af9cd67
JG
230 def __init__(self, trace, validation_args):
231 super().__init__(trace, validation_args['pid'])
232
233 # Values expected in the trace
234 self.epoll_wait_fd = validation_args['epoll_wait_fd']
235 self.epoll_pwait_fd = validation_args['epoll_pwait_fd']
236
4c4634e3
FD
237 self.expect["select_entry"]["select_in_fd0"] = 0
238 self.expect["select_entry"]["select_in_fd1023"] = 0
239 self.expect["select_exit"]["select_out_fd0"] = 0
240 self.expect["select_exit"]["select_out_fd1023"] = 0
241 self.expect["poll_entry"]["poll_in_nfds1"] = 0
242 self.expect["poll_exit"]["poll_out_nfds1"] = 0
243 self.expect["epoll_ctl_entry"]["epoll_ctl_in_add"] = 0
244 self.expect["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 0
245 self.expect["epoll_wait_entry"]["epoll_wait_in_ok"] = 0
246 self.expect["epoll_wait_exit"]["epoll_wait_out_fd0"] = 0
2af9cd67
JG
247 self.expect["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 0
248 self.expect["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 0
a0b1f42c
JD
249
250 def select_entry(self, event):
a0b1f42c
JD
251 n = event["n"]
252 overflow = event["overflow"]
4c4634e3 253 readfd_0 = event["readfds"][0]
a0b1f42c
JD
254
255 # check that the FD 0 is actually set in the readfds
4c4634e3
FD
256 if n == 1 and readfd_0 == 1:
257 self.expect["select_entry"]["select_in_fd0"] = 1
a0b1f42c 258 if n == 1023:
4c4634e3
FD
259 readfd_127 = event["readfds"][127]
260 writefd_127 = event["writefds"][127]
261 exceptfd_127 = event["exceptfds"][127]
262
a0b1f42c 263 # check that the FD 1023 is actually set in the readfds
4c4634e3
FD
264 if readfd_127 == 0x40 and writefd_127 == 0 and \
265 exceptfd_127 == 0 and overflow == 0:
266 self.expect["select_entry"]["select_in_fd1023"] = 1
267
268 # Save values of local variables to print in case of test failure
269 self.recorded_values["select_entry"] = locals()
a0b1f42c
JD
270
271 def select_exit(self, event):
a0b1f42c 272 ret = event["ret"]
a0b1f42c 273 tvp = event["tvp"]
4c4634e3 274 overflow = event["overflow"]
a0b1f42c 275 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
276
277 if ret == 1:
278 # check that the FD 0 is actually set in the readfds
4c4634e3
FD
279 readfd_0 = event["readfds"][0]
280
281 if readfd_0 == 1:
282 self.expect["select_exit"]["select_out_fd0"] = 1
a0b1f42c 283 # check that the FD 1023 is actually set in the readfds
4c4634e3
FD
284 if _readfds_length == 128:
285 readfd_127 = event["readfds"][127]
286 writefd_127 = event["writefds"][127]
287 exceptfd_127 = event["exceptfds"][127]
288 if readfd_127 == 0x40 and writefd_127 == 0 and \
289 exceptfd_127 == 0 and tvp == 0:
290 self.expect["select_exit"]["select_out_fd1023"] = 1
291
292 # Save values of local variables to print in case of test failure
293 self.recorded_values["select_exit"] = locals()
a0b1f42c
JD
294
295 def poll_entry(self, event):
a0b1f42c
JD
296 nfds = event["nfds"]
297 fds_length = event["fds_length"]
298 overflow = event["overflow"]
a0b1f42c
JD
299
300 # check that only one FD is set, that it has the POLLIN flag and that
301 # the raw value matches the events bit field.
4c4634e3
FD
302 if nfds == 1 and fds_length == 1:
303 fd_0 = event["fds"][0]
304 if fd_0["raw_events"] == 0x3 and fd_0["events"]["POLLIN"] == 1 and \
305 fd_0["events"]["padding"] == 0:
306 self.expect["poll_entry"]["poll_in_nfds1"] = 1
307
308 # Save values of local variables to print in case of test failure
309 self.recorded_values["poll_entry"] = locals()
a0b1f42c
JD
310
311 def poll_exit(self, event):
a0b1f42c 312 ret = event["ret"]
a0b1f42c 313 fds_length = event["fds_length"]
a0b1f42c
JD
314
315 # check that only one FD is set, that it has the POLLIN flag and that
316 # the raw value matches the events bit field.
4c4634e3
FD
317 if ret == 1 and fds_length == 1:
318 fd_0 = event["fds"][0]
319 if fd_0["raw_events"] == 0x1 and fd_0["events"]["POLLIN"] == 1 and \
320 fd_0["events"]["padding"] == 0:
321 self.expect["poll_exit"]["poll_out_nfds1"] = 1
322
323 # Save values of local variables to print in case of test failure
324 self.recorded_values["poll_exit"] = locals()
a0b1f42c
JD
325
326 def epoll_ctl_entry(self, event):
a0b1f42c
JD
327 epfd = event["epfd"]
328 op_enum = event["op_enum"]
329 fd = event["fd"]
330 _event = event["event"]
331
332 # check that we have FD 0 waiting for EPOLLIN|EPOLLPRI and that
333 # data.fd = 0
b1986eff 334 if (epfd == self.epoll_wait_fd or epfd == self.epoll_pwait_fd) and 'EPOLL_CTL_ADD' == op_enum and fd == 0 and \
a0b1f42c
JD
335 _event["data_union"]["fd"] == 0 and \
336 _event["events"]["EPOLLIN"] == 1 and \
337 _event["events"]["EPOLLPRI"] == 1:
4c4634e3
FD
338 self.expect["epoll_ctl_entry"]["epoll_ctl_in_add"] = 1
339
340 # Save values of local variables to print in case of test failure
341 self.recorded_values["epoll_ctl_entry"] = locals()
a0b1f42c
JD
342
343 def epoll_ctl_exit(self, event):
a0b1f42c
JD
344 ret = event["ret"]
345
346 if ret == 0:
4c4634e3
FD
347 self.expect["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 1
348
349 # Save values of local variables to print in case of test failure
350 self.recorded_values["epoll_ctl_exit"] = locals()
a0b1f42c
JD
351
352 def epoll_wait_entry(self, event):
a0b1f42c
JD
353 epfd = event["epfd"]
354 maxevents = event["maxevents"]
355 timeout = event["timeout"]
356
2af9cd67 357 if epfd == self.epoll_wait_fd and maxevents == 1 and timeout == -1:
4c4634e3
FD
358 self.expect["epoll_wait_entry"]["epoll_wait_in_ok"] = 1
359
360 # Save values of local variables to print in case of test failure
361 self.recorded_values["epoll_wait_entry"] = locals()
a0b1f42c
JD
362
363 def epoll_wait_exit(self, event):
a0b1f42c
JD
364 ret = event["ret"]
365 fds_length = event["fds_length"]
366 overflow = event["overflow"]
a0b1f42c
JD
367
368 # check that FD 0 returned with EPOLLIN and the right data.fd
4c4634e3
FD
369 if ret == 1 and fds_length == 1:
370 fd_0 = event["fds"][0]
371 if overflow == 0 and fd_0["data_union"]["fd"] == 0 and \
372 fd_0["events"]["EPOLLIN"] == 1:
373 self.expect["epoll_wait_exit"]["epoll_wait_out_fd0"] = 1
374
375 # Save values of local variables to print in case of test failure
376 self.recorded_values["epoll_wait_exit"] = locals()
a0b1f42c 377
2af9cd67
JG
378 def epoll_pwait_entry(self, event):
379 epfd = event["epfd"]
380 maxevents = event["maxevents"]
381 timeout = event["timeout"]
382
383 if epfd == self.epoll_pwait_fd and maxevents == 1 and timeout == -1:
384 self.expect["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 1
385
386 # Save values of local variables to print in case of test failure
387 self.recorded_values["epoll_pwait_entry"] = locals()
388
389 def epoll_pwait_exit(self, event):
390 ret = event["ret"]
391 fds_length = event["fds_length"]
392 overflow = event["overflow"]
393
394 # check that FD 0 returned with EPOLLIN and the right data.fd
395 if ret == 1 and fds_length == 1:
396 fd_0 = event["fds"][0]
397 if overflow == 0 and fd_0["data_union"]["fd"] == 0 and \
398 fd_0["events"]["EPOLLIN"] == 1:
399 self.expect["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 1
400
401 # Save values of local variables to print in case of test failure
402 self.recorded_values["epoll_pwait_exit"] = locals()
a0b1f42c
JD
403
404class Test2(TraceParser):
2af9cd67
JG
405 def __init__(self, trace, validation_args):
406 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
407 self.expect["select_entry"]["select_timeout_in_fd0"] = 0
408 self.expect["select_entry"]["select_timeout_in_fd1023"] = 0
409 self.expect["select_exit"]["select_timeout_out"] = 0
410 self.expect["poll_entry"]["poll_timeout_in"] = 0
411 self.expect["poll_exit"]["poll_timeout_out"] = 0
412 self.expect["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 0
413 self.expect["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 0
414 self.expect["epoll_wait_entry"]["epoll_wait_timeout_in"] = 0
415 self.expect["epoll_wait_exit"]["epoll_wait_timeout_out"] = 0
a0b1f42c
JD
416
417 def select_entry(self, event):
a0b1f42c 418 n = event["n"]
a0b1f42c 419 tvp = event["tvp"]
a0b1f42c
JD
420
421 if n == 1 and tvp != 0:
4c4634e3 422 self.expect["select_entry"]["select_timeout_in_fd0"] = 1
a0b1f42c 423 if n == 1023:
4c4634e3
FD
424 readfd_127 = event["readfds"][127]
425 writefd_127 = event["writefds"][127]
426 exceptfd_127 = event["exceptfds"][127]
427
428 if readfd_127 == 0x40 and writefd_127 == 0 and \
429 exceptfd_127 == 0 and tvp != 0:
430 self.expect["select_entry"]["select_timeout_in_fd1023"] = 1
431
432 # Save values of local variables to print in case of test failure
433 self.recorded_values["select_entry"] = locals()
a0b1f42c
JD
434
435 def select_exit(self, event):
a0b1f42c 436 ret = event["ret"]
a0b1f42c 437 tvp = event["tvp"]
a0b1f42c
JD
438
439 if ret == 0 and tvp != 0:
4c4634e3
FD
440 self.expect["select_exit"]["select_timeout_out"] = 1
441
442 # Save values of local variables to print in case of test failure
443 self.recorded_values["select_exit"] = locals()
a0b1f42c
JD
444
445 def poll_entry(self, event):
a0b1f42c
JD
446 nfds = event["nfds"]
447 fds_length = event["fds_length"]
a0b1f42c
JD
448
449 # check that we wait on FD 0 for POLLIN and that the raw_events
450 # field matches the value of POLLIN
4c4634e3
FD
451 if nfds == 1 and fds_length == 1:
452 fd_0 = event["fds"][0]
453 if fd_0["raw_events"] == 0x3 and \
454 fd_0["events"]["POLLIN"] == 1 and \
455 fd_0["events"]["padding"] == 0:
456 self.expect["poll_entry"]["poll_timeout_in"] = 1
457
458 # Save values of local variables to print in case of test failure
459 self.recorded_values["poll_entry"] = locals()
a0b1f42c
JD
460
461 def poll_exit(self, event):
a0b1f42c
JD
462 ret = event["ret"]
463 nfds = event["nfds"]
464 fds_length = event["fds_length"]
a0b1f42c
JD
465
466 if ret == 0 and nfds == 1 and fds_length == 0:
4c4634e3
FD
467 self.expect["poll_exit"]["poll_timeout_out"] = 1
468
469 # Save values of local variables to print in case of test failure
470 self.recorded_values["poll_exit"] = locals()
a0b1f42c
JD
471
472 def epoll_ctl_entry(self, event):
a0b1f42c 473 op_enum = event["op_enum"]
a0b1f42c
JD
474 _event = event["event"]
475
476 # make sure we see a EPOLLIN|EPOLLPRI
477 if op_enum == "EPOLL_CTL_ADD" and \
478 _event["events"]["EPOLLIN"] == 1 and \
479 _event["events"]["EPOLLPRI"] == 1:
4c4634e3
FD
480 self.expect["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 1
481
482 # Save values of local variables to print in case of test failure
483 self.recorded_values["epoll_ctl_entry"] = locals()
a0b1f42c
JD
484
485 def epoll_ctl_exit(self, event):
a0b1f42c
JD
486 ret = event["ret"]
487
488 if ret == 0:
4c4634e3
FD
489 self.expect["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 1
490
491 # Save values of local variables to print in case of test failure
492 self.recorded_values["epoll_ctl_exit"] = locals()
a0b1f42c
JD
493
494 def epoll_wait_entry(self, event):
a0b1f42c
JD
495 maxevents = event["maxevents"]
496 timeout = event["timeout"]
497
498 if maxevents == 1 and timeout == 1:
4c4634e3
FD
499 self.expect["epoll_wait_entry"]["epoll_wait_timeout_in"] = 1
500
501 # Save values of local variables to print in case of test failure
502 self.recorded_values["epoll_wait_entry"] = locals()
a0b1f42c
JD
503
504 def epoll_wait_exit(self, event):
a0b1f42c
JD
505 ret = event["ret"]
506 fds_length = event["fds_length"]
507 overflow = event["overflow"]
a0b1f42c
JD
508
509 if ret == 0 and fds_length == 0 and overflow == 0:
4c4634e3
FD
510 self.expect["epoll_wait_exit"]["epoll_wait_timeout_out"] = 1
511
512 # Save values of local variables to print in case of test failure
513 self.recorded_values["epoll_wait_exit"] = locals()
a0b1f42c
JD
514
515
516class Test3(TraceParser):
2af9cd67
JG
517 def __init__(self, trace, validation_args):
518 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
519 self.expect["select_entry"]["select_invalid_fd_in"] = 0
520 self.expect["select_exit"]["select_invalid_fd_out"] = 0
a0b1f42c
JD
521
522 def select_entry(self, event):
a0b1f42c
JD
523 n = event["n"]
524 overflow = event["overflow"]
a0b1f42c 525
8b3b99e2 526 if n > 0 and overflow == 0:
4c4634e3
FD
527 self.expect["select_entry"]["select_invalid_fd_in"] = 1
528
529 # Save values of local variables to print in case of test failure
530 self.recorded_values["select_entry"] = locals()
a0b1f42c
JD
531
532 def select_exit(self, event):
a0b1f42c
JD
533 ret = event["ret"]
534 overflow = event["overflow"]
a0b1f42c 535 _readfds_length = event["_readfds_length"]
a0b1f42c 536
8b3b99e2 537 # make sure the event has a ret field equal to -EBADF
a0b1f42c 538 if ret == -9 and overflow == 0 and _readfds_length == 0:
4c4634e3
FD
539 self.expect["select_exit"]["select_invalid_fd_out"] = 1
540
541 # Save values of local variables to print in case of test failure
542 self.recorded_values["select_exit"] = locals()
a0b1f42c
JD
543
544
545class Test4(TraceParser):
2af9cd67
JG
546 def __init__(self, trace, validation_args):
547 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
548 self.expect["poll_entry"]["big_poll_in"] = 0
549 self.expect["poll_exit"]["big_poll_out"] = 0
a0b1f42c
JD
550
551 def poll_entry(self, event):
a0b1f42c
JD
552 nfds = event["nfds"]
553 fds_length = event["fds_length"]
554 overflow = event["overflow"]
a0b1f42c
JD
555
556 # test of big list of FDs and the behaviour of the overflow
4c4634e3
FD
557 if nfds == 2047 and fds_length == 512 and overflow == 1:
558 fd_0 = event["fds"][0]
559 fd_511 = event["fds"][511]
560 if fd_0["raw_events"] == 0x3 and fd_0["events"]["POLLIN"] == 1 and \
561 fd_0["events"]["padding"] == 0 and \
562 fd_511["events"]["POLLIN"] == 1 and \
563 fd_511["events"]["POLLPRI"] == 1:
564 self.expect["poll_entry"]["big_poll_in"] = 1
565
566 # Save values of local variables to print in case of test failure
567 self.recorded_values["poll_entry"] = locals()
a0b1f42c
JD
568
569 def poll_exit(self, event):
a0b1f42c
JD
570 ret = event["ret"]
571 nfds = event["nfds"]
572 fds_length = event["fds_length"]
573 overflow = event["overflow"]
a0b1f42c
JD
574
575 # test of big list of FDs and the behaviour of the overflow
4c4634e3
FD
576 if ret == 2047 and nfds == 2047 and fds_length == 512 and overflow == 1:
577 fd_0 = event["fds"][0]
578 fd_511 = event["fds"][511]
579 if fd_0["events"]["POLLIN"] == 1 and fd_511["events"]["POLLIN"] == 1:
580 self.expect["poll_exit"]["big_poll_out"] = 1
a0b1f42c 581
4c4634e3
FD
582 # Save values of local variables to print in case of test failure
583 self.recorded_values["poll_exit"] = locals()
a0b1f42c
JD
584
585class Test5(TraceParser):
2af9cd67
JG
586 def __init__(self, trace, validation_args):
587 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
588 self.expect["poll_entry"]["poll_overflow_in"] = 0
589 self.expect["poll_exit"]["poll_overflow_out"] = 0
a0b1f42c
JD
590
591 def poll_entry(self, event):
a0b1f42c
JD
592 nfds = event["nfds"]
593 fds_length = event["fds_length"]
594 overflow = event["overflow"]
a0b1f42c
JD
595
596 # test that event in valid even though the target buffer is too small
597 # and the program segfaults
4c4634e3
FD
598 if nfds == 100 and fds_length == 100 and overflow == 0:
599 fd_0 = event["fds"][0]
600 if fd_0["events"]["POLLIN"] == 1:
601 self.expect["poll_entry"]["poll_overflow_in"] = 1
602
603 # Save values of local variables to print in case of test failure
604 self.recorded_values["poll_entry"] = locals()
a0b1f42c
JD
605
606 def poll_exit(self, event):
a0b1f42c 607 nfds = event["nfds"]
a0b1f42c 608 overflow = event["overflow"]
a0b1f42c
JD
609
610 # test that event in valid even though the target buffer is too small
611 # and the program segfaults
612 if nfds == 100 and overflow == 0:
4c4634e3
FD
613 self.expect["poll_exit"]["poll_overflow_out"] = 1
614
615 # Save values of local variables to print in case of test failure
616 self.recorded_values["poll_exit"] = locals()
a0b1f42c
JD
617
618
619class Test6(TraceParser):
2af9cd67
JG
620 def __init__(self, trace, validation_args):
621 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
622 self.expect["select_entry"]["pselect_invalid_in"] = 0
623 self.expect["select_exit"]["pselect_invalid_out"] = 0
a0b1f42c
JD
624
625 def select_entry(self, event):
a0b1f42c
JD
626 n = event["n"]
627 overflow = event["overflow"]
a0b1f42c 628 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
629
630 # test that event in valid even though the target buffer pointer is
631 # invalid and the program segfaults
632 if n == 1 and overflow == 0 and _readfds_length == 0:
4c4634e3
FD
633 self.expect["select_entry"]["pselect_invalid_in"] = 1
634
635 # Save values of local variables to print in case of test failure
636 self.recorded_values["select_entry"] = locals()
a0b1f42c
JD
637
638 def select_exit(self, event):
a0b1f42c
JD
639 ret = event["ret"]
640 overflow = event["overflow"]
a0b1f42c 641 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
642
643 # test that event in valid even though the target buffer pointer is
644 # invalid and the program segfaults
645 if ret == -14 and overflow == 0 and _readfds_length == 0:
4c4634e3
FD
646 self.expect["select_exit"]["pselect_invalid_out"] = 1
647
648 # Save values of local variables to print in case of test failure
649 self.recorded_values["select_exit"] = locals()
a0b1f42c
JD
650
651
652class Test7(TraceParser):
2af9cd67
JG
653 def __init__(self, trace, validation_args):
654 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
655 self.expect["poll_entry"]["poll_max_in"] = 0
656 self.expect["poll_exit"]["poll_max_out"] = 0
a0b1f42c
JD
657
658 def poll_entry(self, event):
a0b1f42c 659 nfds = event["nfds"]
a0b1f42c 660 overflow = event["overflow"]
a0b1f42c
JD
661
662 # check the proper working of INT_MAX maxevent value
663 if nfds == 4294967295 and overflow == 1:
4c4634e3
FD
664 self.expect["poll_entry"]["poll_max_in"] = 1
665
666 # Save values of local variables to print in case of test failure
667 self.recorded_values["poll_entry"] = locals()
668
a0b1f42c
JD
669
670 def poll_exit(self, event):
a0b1f42c
JD
671 ret = event["ret"]
672 nfds = event["nfds"]
a0b1f42c 673 overflow = event["overflow"]
a0b1f42c
JD
674
675 # check the proper working of UINT_MAX maxevent value
676 if ret == -22 and nfds == 4294967295 and overflow == 0:
4c4634e3
FD
677 self.expect["poll_exit"]["poll_max_out"] = 1
678
679 # Save values of local variables to print in case of test failure
680 self.recorded_values["poll_exit"] = locals()
a0b1f42c
JD
681
682
683class Test8(TraceParser):
2af9cd67
JG
684 def __init__(self, trace, validation_args):
685 super().__init__(trace, validation_args['pid'])
686
687 # Values expected in the trace
688 self.epoll_fd = validation_args['epollfd']
689
4c4634e3
FD
690 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
691 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
a0b1f42c
JD
692
693 def epoll_wait_entry(self, event):
a0b1f42c
JD
694 epfd = event["epfd"]
695 maxevents = event["maxevents"]
696 timeout = event["timeout"]
697
698 # test that event in valid even though the target buffer pointer is
699 # invalid and the program segfaults
2af9cd67 700 if epfd == self.epoll_fd and maxevents == 1 and timeout == -1:
4c4634e3
FD
701 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 1
702
703 # Save values of local variables to print in case of test failure
704 self.recorded_values["epoll_wait_entry"] = locals()
a0b1f42c
JD
705
706 def epoll_wait_exit(self, event):
a0b1f42c
JD
707 ret = event["ret"]
708 fds_length = event["fds_length"]
709 overflow = event["overflow"]
a0b1f42c
JD
710
711 # test that event in valid even though the target buffer pointer is
712 # invalid and the program segfaults
713 if ret == -14 and fds_length == 0 and overflow == 0:
4c4634e3
FD
714 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 1
715
716 # Save values of local variables to print in case of test failure
717 self.recorded_values["epoll_wait_exit"] = locals()
a0b1f42c
JD
718
719
720class Test9(TraceParser):
2af9cd67
JG
721 def __init__(self, trace, validation_args):
722 super().__init__(trace, validation_args['pid'])
723
724 # Values expected in the trace
725 self.epoll_fd = validation_args['epollfd']
726
4c4634e3
FD
727 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 0
728 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 0
a0b1f42c
JD
729
730 def epoll_wait_entry(self, event):
a0b1f42c
JD
731 epfd = event["epfd"]
732 maxevents = event["maxevents"]
733 timeout = event["timeout"]
734
735 # check the proper working of INT_MAX maxevent value
2af9cd67 736 if epfd == self.epoll_fd and maxevents == 2147483647 and timeout == -1:
4c4634e3
FD
737 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 1
738
739 # Save values of local variables to print in case of test failure
740 self.recorded_values["epoll_wait_entry"] = locals()
a0b1f42c
JD
741
742 def epoll_wait_exit(self, event):
a0b1f42c
JD
743 ret = event["ret"]
744 fds_length = event["fds_length"]
745 overflow = event["overflow"]
a0b1f42c
JD
746
747 # check the proper working of INT_MAX maxevent value
748 if ret == -22 and fds_length == 0 and overflow == 0:
4c4634e3
FD
749 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 1
750
751 # Save values of local variables to print in case of test failure
752 self.recorded_values["epoll_wait_exit"] = locals()
a0b1f42c
JD
753
754
755if __name__ == "__main__":
756 parser = argparse.ArgumentParser(description='Trace parser')
757 parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
758 parser.add_argument('-t', '--test', type=int, help='Test to validate')
2af9cd67 759 parser.add_argument('-o', '--validation-file', type=str, help='Validation file path')
a0b1f42c
JD
760 args = parser.parse_args()
761
762 if not args.test:
2af9cd67 763 print("Need to pass a test to validate (--test/-t)")
a0b1f42c
JD
764 sys.exit(1)
765
2af9cd67
JG
766 if not args.validation_file:
767 print("Need to pass the test validation file (--validation-file/-o)")
a0b1f42c
JD
768 sys.exit(1)
769
770 traces = TraceCollection()
771 handle = traces.add_traces_recursive(args.path, "ctf")
772 if handle is None:
773 sys.exit(1)
774
2af9cd67
JG
775 with open(args.validation_file) as f:
776 try:
777 test_validation_args = json.load(f)
778 except Exception as e:
779 print('Failed to parse validation file: ' + str(e))
780 sys.exit(1)
781
a0b1f42c
JD
782 t = None
783
784 if args.test == 1:
2af9cd67 785 t = Test1(traces, test_validation_args)
a0b1f42c 786 elif args.test == 2:
2af9cd67 787 t = Test2(traces, test_validation_args)
a0b1f42c 788 elif args.test == 3:
2af9cd67 789 t = Test3(traces, test_validation_args)
a0b1f42c 790 elif args.test == 4:
2af9cd67 791 t = Test4(traces, test_validation_args)
a0b1f42c 792 elif args.test == 5:
2af9cd67 793 t = Test5(traces, test_validation_args)
a0b1f42c 794 elif args.test == 6:
2af9cd67 795 t = Test6(traces, test_validation_args)
a0b1f42c 796 elif args.test == 7:
2af9cd67 797 t = Test7(traces, test_validation_args)
a0b1f42c 798 elif args.test == 8:
2af9cd67 799 t = Test8(traces, test_validation_args)
a0b1f42c 800 elif args.test == 9:
2af9cd67 801 t = Test9(traces, test_validation_args)
a0b1f42c
JD
802 elif args.test == 10:
803 # stress test, nothing reliable to check
804 ret = 0
805 elif args.test == 11:
806 # stress test, nothing reliable to check
807 ret = 0
808 else:
809 print("Invalid test case")
810 sys.exit(1)
811
812 if t is not None:
813 ret = t.parse()
814
815 for h in handle.values():
816 traces.remove_trace(h)
817
818 sys.exit(ret)
This page took 0.071435 seconds and 4 git commands to generate.