3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
5 # SPDX-License-Identifier: GPL-2.0-only
14 from collections
import defaultdict
19 # quick fix for debian-based distros
20 sys
.path
.append("/usr/local/lib/python%d.%d/site-packages" %
21 (sys
.version_info
.major
, sys
.version_info
.minor
))
24 NSEC_PER_SEC
= 1000000000
27 def __init__(self
, trace_msg_iter
, pid
):
28 self
.trace
= trace_msg_iter
31 # This dictionnary holds the results of each testcases of a test.
32 # Its layout is the following:
34 # 'event_name_1': {'check_1': 0, 'check_2: 1},
35 # 'event_name_2': {'check_1': 1}
37 # Each test classes checks the payload of different events. Each of
38 # those checks are stored in a event_name specific dictionnary in this
40 self
.expect
= defaultdict(lambda : defaultdict(int))
42 # This dictionnary holds the value recorded in the trace that are
43 # tested. Its content is use to print the values that caused a test to
45 self
.recorded_values
= {}
47 def ns_to_hour_nsec(self
, ns
):
48 d
= time
.localtime(ns
/NSEC_PER_SEC
)
49 return "%02d:%02d:%02d.%09d" % (d
.tm_hour
, d
.tm_min
, d
.tm_sec
,
53 # iterate over all the events
54 for msg
in self
.trace
:
55 if type(msg
) is not bt2
._EventMessageConst
:
58 if self
.pid
is not None and msg
.event
["pid"] != self
.pid
:
61 method_name
= "handle_%s" % msg
.event
.name
.replace(":", "_").replace(
63 # call the function to handle each event individually
64 if hasattr(TraceParser
, method_name
):
65 func
= getattr(TraceParser
, method_name
)
69 # For each event of the test case, check all entries for failed
70 for event_name
, event_results
in self
.expect
.items():
71 for val
in event_results
.keys():
72 if self
.expect
[event_name
][val
] == 0:
73 print("%s not validated" % val
)
74 print("Values of the local variables of this test:")
75 # using pprint for pretty printing the dictionnary
76 pprint
.pprint(self
.recorded_values
[event_name
])
82 def handle_compat_syscall_entry_epoll_ctl(self
, event
):
83 self
.epoll_ctl_entry(event
)
85 def handle_compat_syscall_exit_epoll_ctl(self
, event
):
86 self
.epoll_ctl_exit(event
)
88 def handle_syscall_entry_epoll_ctl(self
, event
):
89 self
.epoll_ctl_entry(event
)
91 def handle_syscall_exit_epoll_ctl(self
, event
):
92 self
.epoll_ctl_exit(event
)
94 def epoll_ctl_entry(self
, event
):
97 def epoll_ctl_exit(self
, event
):
100 # epoll_wait + epoll_pwait
101 def handle_compat_syscall_entry_epoll_wait(self
, event
):
102 self
.epoll_wait_entry(event
)
104 def handle_compat_syscall_exit_epoll_wait(self
, event
):
105 self
.epoll_wait_exit(event
)
107 def handle_syscall_entry_epoll_wait(self
, event
):
108 self
.epoll_wait_entry(event
)
110 def handle_syscall_exit_epoll_wait(self
, event
):
111 self
.epoll_wait_exit(event
)
113 def handle_compat_syscall_entry_epoll_pwait(self
, event
):
114 self
.epoll_pwait_entry(event
)
116 def handle_compat_syscall_exit_epoll_pwait(self
, event
):
117 self
.epoll_pwait_exit(event
)
119 def handle_syscall_entry_epoll_pwait(self
, event
):
120 self
.epoll_pwait_entry(event
)
122 def handle_syscall_exit_epoll_pwait(self
, event
):
123 self
.epoll_pwait_exit(event
)
125 def epoll_wait_entry(self
, event
):
128 def epoll_wait_exit(self
, event
):
131 def epoll_pwait_entry(self
, event
):
132 self
.epoll_wait_entry(event
)
134 def epoll_pwait_exit(self
, event
):
135 self
.epoll_wait_exit(event
)
138 def handle_compat_syscall_entry_poll(self
, event
):
139 self
.poll_entry(event
)
141 def handle_compat_syscall_exit_poll(self
, event
):
142 self
.poll_exit(event
)
144 def handle_syscall_entry_poll(self
, event
):
145 self
.poll_entry(event
)
147 def handle_syscall_exit_poll(self
, event
):
148 self
.poll_exit(event
)
150 def handle_compat_syscall_entry_ppoll(self
, event
):
151 self
.poll_entry(event
)
153 def handle_compat_syscall_exit_ppoll(self
, event
):
154 self
.poll_exit(event
)
156 def handle_syscall_entry_ppoll(self
, event
):
157 self
.poll_entry(event
)
159 def handle_syscall_exit_ppoll(self
, event
):
160 self
.poll_exit(event
)
162 def poll_entry(self
, event
):
165 def poll_exit(self
, event
):
169 def handle_compat_syscall_entry_epoll_create1(self
, event
):
170 self
.epoll_create_entry(event
)
172 def handle_compat_syscall_exit_epoll_create1(self
, event
):
173 self
.epoll_create_exit(event
)
175 def handle_compat_syscall_entry_epoll_create(self
, event
):
176 self
.epoll_create_entry(event
)
178 def handle_compat_syscall_exit_epoll_create(self
, event
):
179 self
.epoll_create_exit(event
)
181 def handle_syscall_entry_epoll_create1(self
, event
):
182 self
.epoll_create_entry(event
)
184 def handle_syscall_exit_epoll_create1(self
, event
):
185 self
.epoll_create_exit(event
)
187 def handle_syscall_entry_epoll_create(self
, event
):
188 self
.epoll_create_entry(event
)
190 def handle_syscall_exit_epoll_create(self
, event
):
191 self
.epoll_create_exit(event
)
193 def epoll_create_entry(self
, event
):
196 def epoll_create_exit(self
, event
):
200 def handle_syscall_entry_pselect6(self
, event
):
201 self
.select_entry(event
)
203 def handle_syscall_exit_pselect6(self
, event
):
204 self
.select_exit(event
)
206 def handle_compat_syscall_entry_pselect6(self
, event
):
207 self
.select_entry(event
)
209 def handle_compat_syscall_exit_pselect6(self
, event
):
210 self
.select_exit(event
)
212 def handle_syscall_entry_select(self
, event
):
213 self
.select_entry(event
)
215 def handle_syscall_exit_select(self
, event
):
216 self
.select_exit(event
)
218 def handle_compat_syscall_entry_select(self
, event
):
219 self
.select_entry(event
)
221 def handle_compat_syscall_exit_select(self
, event
):
222 self
.select_exit(event
)
224 def select_entry(self
, event
):
227 def select_exit(self
, event
):
231 class WorkingCases(TraceParser
):
232 def __init__(self
, trace
, validation_args
):
233 super().__init
__(trace
, validation_args
['pid'])
235 # Values expected in the trace
236 self
.epoll_wait_fd
= validation_args
['epoll_wait_fd']
237 self
.epoll_pwait_fd
= validation_args
['epoll_pwait_fd']
239 self
.expect
["select_entry"]["select_in_fd0"] = 0
240 self
.expect
["select_entry"]["select_in_fd1023"] = 0
241 self
.expect
["select_exit"]["select_out_fd0"] = 0
242 self
.expect
["select_exit"]["select_out_fd1023"] = 0
243 self
.expect
["poll_entry"]["poll_in_nfds1"] = 0
244 self
.expect
["poll_exit"]["poll_out_nfds1"] = 0
245 self
.expect
["epoll_ctl_entry"]["epoll_ctl_in_add"] = 0
246 self
.expect
["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 0
247 self
.expect
["epoll_wait_entry"]["epoll_wait_in_ok"] = 0
248 self
.expect
["epoll_wait_exit"]["epoll_wait_out_fd0"] = 0
249 self
.expect
["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 0
250 self
.expect
["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 0
252 def select_entry(self
, event
):
254 overflow
= event
["overflow"]
255 readfd_0
= event
["readfds"][0]
257 # check that the FD 0 is actually set in the readfds
258 if n
== 1 and readfd_0
== 1:
259 self
.expect
["select_entry"]["select_in_fd0"] = 1
261 readfd_127
= event
["readfds"][127]
262 writefd_127
= event
["writefds"][127]
263 exceptfd_127
= event
["exceptfds"][127]
265 # check that the FD 1023 is actually set in the readfds
266 if readfd_127
== 0x40 and writefd_127
== 0 and \
267 exceptfd_127
== 0 and overflow
== 0:
268 self
.expect
["select_entry"]["select_in_fd1023"] = 1
270 # Save values of local variables to print in case of test failure
271 self
.recorded_values
["select_entry"] = locals()
273 def select_exit(self
, event
):
276 overflow
= event
["overflow"]
277 _readfds_length
= event
["_readfds_length"]
280 # check that the FD 0 is actually set in the readfds
281 readfd_0
= event
["readfds"][0]
284 self
.expect
["select_exit"]["select_out_fd0"] = 1
285 # check that the FD 1023 is actually set in the readfds
286 if _readfds_length
== 128:
287 readfd_127
= event
["readfds"][127]
288 writefd_127
= event
["writefds"][127]
289 exceptfd_127
= event
["exceptfds"][127]
290 if readfd_127
== 0x40 and writefd_127
== 0 and \
291 exceptfd_127
== 0 and tvp
== 0:
292 self
.expect
["select_exit"]["select_out_fd1023"] = 1
294 # Save values of local variables to print in case of test failure
295 self
.recorded_values
["select_exit"] = locals()
297 def poll_entry(self
, event
):
299 fds_length
= event
["fds_length"]
300 overflow
= event
["overflow"]
302 # check that only one FD is set, that it has the POLLIN flag and that
303 # the raw value matches the events bit field.
304 if nfds
== 1 and fds_length
== 1:
305 fd_0
= event
["fds"][0]
306 if fd_0
["raw_events"] == 0x3 and fd_0
["events"]["POLLIN"] == 1 and \
307 fd_0
["events"]["padding"] == 0:
308 self
.expect
["poll_entry"]["poll_in_nfds1"] = 1
310 # Save values of local variables to print in case of test failure
311 self
.recorded_values
["poll_entry"] = locals()
313 def poll_exit(self
, event
):
315 fds_length
= event
["fds_length"]
317 # check that only one FD is set, that it has the POLLIN flag and that
318 # the raw value matches the events bit field.
319 if ret
== 1 and fds_length
== 1:
320 fd_0
= event
["fds"][0]
321 if fd_0
["raw_events"] == 0x1 and fd_0
["events"]["POLLIN"] == 1 and \
322 fd_0
["events"]["padding"] == 0:
323 self
.expect
["poll_exit"]["poll_out_nfds1"] = 1
325 # Save values of local variables to print in case of test failure
326 self
.recorded_values
["poll_exit"] = locals()
328 def epoll_ctl_entry(self
, event
):
330 op_enum
= event
["op_enum"]
332 _event
= event
["event"]
334 # check that we have FD 0 waiting for EPOLLIN|EPOLLPRI and that
336 if (epfd
== self
.epoll_wait_fd
or epfd
== self
.epoll_pwait_fd
) and 'EPOLL_CTL_ADD' in op_enum
.labels
and fd
== 0 and \
337 _event
["data_union"]["fd"] == 0 and \
338 _event
["events"]["EPOLLIN"] == 1 and \
339 _event
["events"]["EPOLLPRI"] == 1:
340 self
.expect
["epoll_ctl_entry"]["epoll_ctl_in_add"] = 1
342 # Save values of local variables to print in case of test failure
343 self
.recorded_values
["epoll_ctl_entry"] = locals()
345 def epoll_ctl_exit(self
, event
):
349 self
.expect
["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 1
351 # Save values of local variables to print in case of test failure
352 self
.recorded_values
["epoll_ctl_exit"] = locals()
354 def epoll_wait_entry(self
, event
):
356 maxevents
= event
["maxevents"]
357 timeout
= event
["timeout"]
359 if epfd
== self
.epoll_wait_fd
and maxevents
== 1 and timeout
== -1:
360 self
.expect
["epoll_wait_entry"]["epoll_wait_in_ok"] = 1
362 # Save values of local variables to print in case of test failure
363 self
.recorded_values
["epoll_wait_entry"] = locals()
365 def epoll_wait_exit(self
, event
):
367 fds_length
= event
["fds_length"]
368 overflow
= event
["overflow"]
370 # check that FD 0 returned with EPOLLIN and the right data.fd
371 if ret
== 1 and fds_length
== 1:
372 fd_0
= event
["fds"][0]
373 if overflow
== 0 and fd_0
["data_union"]["fd"] == 0 and \
374 fd_0
["events"]["EPOLLIN"] == 1:
375 self
.expect
["epoll_wait_exit"]["epoll_wait_out_fd0"] = 1
377 # Save values of local variables to print in case of test failure
378 self
.recorded_values
["epoll_wait_exit"] = locals()
380 def epoll_pwait_entry(self
, event
):
382 maxevents
= event
["maxevents"]
383 timeout
= event
["timeout"]
385 if epfd
== self
.epoll_pwait_fd
and maxevents
== 1 and timeout
== -1:
386 self
.expect
["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 1
388 # Save values of local variables to print in case of test failure
389 self
.recorded_values
["epoll_pwait_entry"] = locals()
391 def epoll_pwait_exit(self
, event
):
393 fds_length
= event
["fds_length"]
394 overflow
= event
["overflow"]
396 # check that FD 0 returned with EPOLLIN and the right data.fd
397 if ret
== 1 and fds_length
== 1:
398 fd_0
= event
["fds"][0]
399 if overflow
== 0 and fd_0
["data_union"]["fd"] == 0 and \
400 fd_0
["events"]["EPOLLIN"] == 1:
401 self
.expect
["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 1
403 # Save values of local variables to print in case of test failure
404 self
.recorded_values
["epoll_pwait_exit"] = locals()
406 class WorkingCasesTimeout(TraceParser
):
407 def __init__(self
, trace
, validation_args
):
408 super().__init
__(trace
, validation_args
['pid'])
409 self
.expect
["select_entry"]["select_timeout_in_fd0"] = 0
410 self
.expect
["select_entry"]["select_timeout_in_fd1023"] = 0
411 self
.expect
["select_exit"]["select_timeout_out"] = 0
412 self
.expect
["poll_entry"]["poll_timeout_in"] = 0
413 self
.expect
["poll_exit"]["poll_timeout_out"] = 0
414 self
.expect
["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 0
415 self
.expect
["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 0
416 self
.expect
["epoll_wait_entry"]["epoll_wait_timeout_in"] = 0
417 self
.expect
["epoll_wait_exit"]["epoll_wait_timeout_out"] = 0
419 def select_entry(self
, event
):
423 if n
== 1 and tvp
!= 0:
424 self
.expect
["select_entry"]["select_timeout_in_fd0"] = 1
426 readfd_127
= event
["readfds"][127]
427 writefd_127
= event
["writefds"][127]
428 exceptfd_127
= event
["exceptfds"][127]
430 if readfd_127
== 0x40 and writefd_127
== 0 and \
431 exceptfd_127
== 0 and tvp
!= 0:
432 self
.expect
["select_entry"]["select_timeout_in_fd1023"] = 1
434 # Save values of local variables to print in case of test failure
435 self
.recorded_values
["select_entry"] = locals()
437 def select_exit(self
, event
):
441 if ret
== 0 and tvp
!= 0:
442 self
.expect
["select_exit"]["select_timeout_out"] = 1
444 # Save values of local variables to print in case of test failure
445 self
.recorded_values
["select_exit"] = locals()
447 def poll_entry(self
, event
):
449 fds_length
= event
["fds_length"]
451 # check that we wait on FD 0 for POLLIN and that the raw_events
452 # field matches the value of POLLIN
453 if nfds
== 1 and fds_length
== 1:
454 fd_0
= event
["fds"][0]
455 if fd_0
["raw_events"] == 0x3 and \
456 fd_0
["events"]["POLLIN"] == 1 and \
457 fd_0
["events"]["padding"] == 0:
458 self
.expect
["poll_entry"]["poll_timeout_in"] = 1
460 # Save values of local variables to print in case of test failure
461 self
.recorded_values
["poll_entry"] = locals()
463 def poll_exit(self
, event
):
466 fds_length
= event
["fds_length"]
468 if ret
== 0 and nfds
== 1 and fds_length
== 0:
469 self
.expect
["poll_exit"]["poll_timeout_out"] = 1
471 # Save values of local variables to print in case of test failure
472 self
.recorded_values
["poll_exit"] = locals()
474 def epoll_ctl_entry(self
, event
):
475 op_enum
= event
["op_enum"]
476 _event
= event
["event"]
478 # make sure we see a EPOLLIN|EPOLLPRI
479 if 'EPOLL_CTL_ADD' in op_enum
.labels
and \
480 _event
["events"]["EPOLLIN"] == 1 and \
481 _event
["events"]["EPOLLPRI"] == 1:
482 self
.expect
["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 1
484 # Save values of local variables to print in case of test failure
485 self
.recorded_values
["epoll_ctl_entry"] = locals()
487 def epoll_ctl_exit(self
, event
):
491 self
.expect
["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 1
493 # Save values of local variables to print in case of test failure
494 self
.recorded_values
["epoll_ctl_exit"] = locals()
496 def epoll_wait_entry(self
, event
):
497 maxevents
= event
["maxevents"]
498 timeout
= event
["timeout"]
500 if maxevents
== 1 and timeout
== 1:
501 self
.expect
["epoll_wait_entry"]["epoll_wait_timeout_in"] = 1
503 # Save values of local variables to print in case of test failure
504 self
.recorded_values
["epoll_wait_entry"] = locals()
506 def epoll_wait_exit(self
, event
):
508 fds_length
= event
["fds_length"]
509 overflow
= event
["overflow"]
511 if ret
== 0 and fds_length
== 0 and overflow
== 0:
512 self
.expect
["epoll_wait_exit"]["epoll_wait_timeout_out"] = 1
514 # Save values of local variables to print in case of test failure
515 self
.recorded_values
["epoll_wait_exit"] = locals()
518 class PselectInvalidFd(TraceParser
):
519 def __init__(self
, trace
, validation_args
):
520 super().__init
__(trace
, validation_args
['pid'])
521 self
.expect
["select_entry"]["select_invalid_fd_in"] = 0
522 self
.expect
["select_exit"]["select_invalid_fd_out"] = 0
524 def select_entry(self
, event
):
526 overflow
= event
["overflow"]
528 if n
> 0 and overflow
== 0:
529 self
.expect
["select_entry"]["select_invalid_fd_in"] = 1
531 # Save values of local variables to print in case of test failure
532 self
.recorded_values
["select_entry"] = locals()
534 def select_exit(self
, event
):
536 overflow
= event
["overflow"]
537 _readfds_length
= event
["_readfds_length"]
539 # make sure the event has a ret field equal to -EBADF
540 if ret
== -9 and overflow
== 0 and _readfds_length
== 0:
541 self
.expect
["select_exit"]["select_invalid_fd_out"] = 1
543 # Save values of local variables to print in case of test failure
544 self
.recorded_values
["select_exit"] = locals()
547 class PpollBig(TraceParser
):
548 def __init__(self
, trace
, validation_args
):
549 super().__init
__(trace
, validation_args
['pid'])
550 self
.expect
["poll_entry"]["big_poll_in"] = 0
551 self
.expect
["poll_exit"]["big_poll_out"] = 0
553 def poll_entry(self
, event
):
555 fds_length
= event
["fds_length"]
556 overflow
= event
["overflow"]
558 # test of big list of FDs and the behaviour of the overflow
559 if nfds
== 2047 and fds_length
== 512 and overflow
== 1:
560 fd_0
= event
["fds"][0]
561 fd_511
= event
["fds"][511]
562 if fd_0
["raw_events"] == 0x3 and fd_0
["events"]["POLLIN"] == 1 and \
563 fd_0
["events"]["padding"] == 0 and \
564 fd_511
["events"]["POLLIN"] == 1 and \
565 fd_511
["events"]["POLLPRI"] == 1:
566 self
.expect
["poll_entry"]["big_poll_in"] = 1
568 # Save values of local variables to print in case of test failure
569 self
.recorded_values
["poll_entry"] = locals()
571 def poll_exit(self
, event
):
574 fds_length
= event
["fds_length"]
575 overflow
= event
["overflow"]
577 # test of big list of FDs and the behaviour of the overflow
578 if ret
== 2047 and nfds
== 2047 and fds_length
== 512 and overflow
== 1:
579 fd_0
= event
["fds"][0]
580 fd_511
= event
["fds"][511]
581 if fd_0
["events"]["POLLIN"] == 1 and fd_511
["events"]["POLLIN"] == 1:
582 self
.expect
["poll_exit"]["big_poll_out"] = 1
584 # Save values of local variables to print in case of test failure
585 self
.recorded_values
["poll_exit"] = locals()
587 class PpollFdsBufferOverflow(TraceParser
):
588 def __init__(self
, trace
, validation_args
):
589 super().__init
__(trace
, validation_args
['pid'])
590 self
.expect
["poll_entry"]["poll_overflow_in"] = 0
591 self
.expect
["poll_exit"]["poll_overflow_out"] = 0
593 def poll_entry(self
, event
):
595 fds_length
= event
["fds_length"]
596 overflow
= event
["overflow"]
598 # test that event in valid even though the target buffer is too small
599 # and the program segfaults
600 if nfds
== 100 and fds_length
== 100 and overflow
== 0:
601 fd_0
= event
["fds"][0]
602 if fd_0
["events"]["POLLIN"] == 1:
603 self
.expect
["poll_entry"]["poll_overflow_in"] = 1
605 # Save values of local variables to print in case of test failure
606 self
.recorded_values
["poll_entry"] = locals()
608 def poll_exit(self
, event
):
610 overflow
= event
["overflow"]
612 # test that event in valid even though the target buffer is too small
613 # and the program segfaults
614 if nfds
== 100 and overflow
== 0:
615 self
.expect
["poll_exit"]["poll_overflow_out"] = 1
617 # Save values of local variables to print in case of test failure
618 self
.recorded_values
["poll_exit"] = locals()
621 class PselectInvalidPointer(TraceParser
):
622 def __init__(self
, trace
, validation_args
):
623 super().__init
__(trace
, validation_args
['pid'])
624 self
.expect
["select_entry"]["pselect_invalid_in"] = 0
625 self
.expect
["select_exit"]["pselect_invalid_out"] = 0
627 def select_entry(self
, event
):
629 overflow
= event
["overflow"]
630 _readfds_length
= event
["_readfds_length"]
632 # test that event in valid even though the target buffer pointer is
633 # invalid and the program segfaults
634 if n
== 1 and overflow
== 0 and _readfds_length
== 0:
635 self
.expect
["select_entry"]["pselect_invalid_in"] = 1
637 # Save values of local variables to print in case of test failure
638 self
.recorded_values
["select_entry"] = locals()
640 def select_exit(self
, event
):
642 overflow
= event
["overflow"]
643 _readfds_length
= event
["_readfds_length"]
645 # test that event in valid even though the target buffer pointer is
646 # invalid and the program segfaults
647 if ret
== -14 and overflow
== 0 and _readfds_length
== 0:
648 self
.expect
["select_exit"]["pselect_invalid_out"] = 1
650 # Save values of local variables to print in case of test failure
651 self
.recorded_values
["select_exit"] = locals()
654 class PpollFdsULongMax(TraceParser
):
655 def __init__(self
, trace
, validation_args
):
656 super().__init
__(trace
, validation_args
['pid'])
657 self
.expect
["poll_entry"]["poll_max_in"] = 0
658 self
.expect
["poll_exit"]["poll_max_out"] = 0
660 def poll_entry(self
, event
):
662 overflow
= event
["overflow"]
664 # check the proper working of INT_MAX maxevent value
665 if nfds
== 4294967295 and overflow
== 1:
666 self
.expect
["poll_entry"]["poll_max_in"] = 1
668 # Save values of local variables to print in case of test failure
669 self
.recorded_values
["poll_entry"] = locals()
672 def poll_exit(self
, event
):
675 overflow
= event
["overflow"]
677 # check the proper working of UINT_MAX maxevent value
678 if ret
== -22 and nfds
== 4294967295 and overflow
== 0:
679 self
.expect
["poll_exit"]["poll_max_out"] = 1
681 # Save values of local variables to print in case of test failure
682 self
.recorded_values
["poll_exit"] = locals()
685 class EpollPwaitInvalidPointer(TraceParser
):
686 def __init__(self
, trace
, validation_args
):
687 super().__init
__(trace
, validation_args
['pid'])
689 # Values expected in the trace
690 self
.epoll_fd
= validation_args
['epollfd']
692 self
.expect
["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
693 self
.expect
["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
695 def epoll_wait_entry(self
, event
):
697 maxevents
= event
["maxevents"]
698 timeout
= event
["timeout"]
700 # test that event in valid even though the target buffer pointer is
701 # invalid and the program segfaults
702 if epfd
== self
.epoll_fd
and maxevents
== 1 and timeout
== -1:
703 self
.expect
["epoll_wait_entry"]["epoll_wait_invalid_in"] = 1
705 # Save values of local variables to print in case of test failure
706 self
.recorded_values
["epoll_wait_entry"] = locals()
708 def epoll_wait_exit(self
, event
):
710 fds_length
= event
["fds_length"]
711 overflow
= event
["overflow"]
713 # test that event in valid even though the target buffer pointer is
714 # invalid and the program segfaults
715 if ret
== -14 and fds_length
== 0 and overflow
== 0:
716 self
.expect
["epoll_wait_exit"]["epoll_wait_invalid_out"] = 1
718 # Save values of local variables to print in case of test failure
719 self
.recorded_values
["epoll_wait_exit"] = locals()
722 class EpollPwaitIntMax(TraceParser
):
723 def __init__(self
, trace
, validation_args
):
724 super().__init
__(trace
, validation_args
['pid'])
726 # Values expected in the trace
727 self
.epoll_fd
= validation_args
['epollfd']
729 self
.expect
["epoll_wait_entry"]["epoll_wait_max_in"] = 0
730 self
.expect
["epoll_wait_exit"]["epoll_wait_max_out"] = 0
732 def epoll_wait_entry(self
, event
):
734 maxevents
= event
["maxevents"]
735 timeout
= event
["timeout"]
737 # check the proper working of INT_MAX maxevent value
738 if epfd
== self
.epoll_fd
and maxevents
== 2147483647 and timeout
== -1:
739 self
.expect
["epoll_wait_entry"]["epoll_wait_max_in"] = 1
741 # Save values of local variables to print in case of test failure
742 self
.recorded_values
["epoll_wait_entry"] = locals()
744 def epoll_wait_exit(self
, event
):
746 fds_length
= event
["fds_length"]
747 overflow
= event
["overflow"]
749 # check the proper working of INT_MAX maxevent value
750 if ret
== -22 and fds_length
== 0 and overflow
== 0:
751 self
.expect
["epoll_wait_exit"]["epoll_wait_max_out"] = 1
753 # Save values of local variables to print in case of test failure
754 self
.recorded_values
["epoll_wait_exit"] = locals()
757 if __name__
== "__main__":
758 parser
= argparse
.ArgumentParser(description
='Trace parser')
759 parser
.add_argument('path', metavar
="<path/to/trace>", help='Trace path')
760 parser
.add_argument('-t', '--test', type=str, help='Test to validate')
761 parser
.add_argument('-o', '--validation-file', type=str, help='Validation file path')
762 args
= parser
.parse_args()
765 print("Need to pass a test to validate (--test/-t)")
768 if not args
.validation_file
:
769 print("Need to pass the test validation file (--validation-file/-o)")
772 traces
= bt2
.TraceCollectionMessageIterator(args
.path
)
774 with
open(args
.validation_file
) as f
:
776 test_validation_args
= json
.load(f
)
777 except Exception as e
:
778 print('Failed to parse validation file: ' + str(e
))
783 if args
.test
== "working_cases":
784 t
= WorkingCases(traces
, test_validation_args
)
785 elif args
.test
== "working_cases_timeout":
786 t
= WorkingCasesTimeout(traces
, test_validation_args
)
787 elif args
.test
== "pselect_invalid_fd":
788 t
= PselectInvalidFd(traces
, test_validation_args
)
789 elif args
.test
== "ppoll_big":
790 t
= PpollBig(traces
, test_validation_args
)
791 elif args
.test
== "ppoll_fds_buffer_overflow":
792 t
= PpollFdsBufferOverflow(traces
, test_validation_args
)
793 elif args
.test
== "pselect_invalid_pointer":
794 t
= PselectInvalidPointer(traces
, test_validation_args
)
795 elif args
.test
== "ppoll_fds_ulong_max":
796 t
= PpollFdsULongMax(traces
, test_validation_args
)
797 elif args
.test
== "epoll_pwait_invalid_pointer":
798 t
= EpollPwaitInvalidPointer(traces
, test_validation_args
)
799 elif args
.test
== "epoll_pwait_int_max":
800 t
= EpollPwaitIntMax(traces
, test_validation_args
)
801 elif args
.test
== "ppoll_concurrent_write":
802 # stress test, nothing reliable to check
804 elif args
.test
== "epoll_pwait_concurrent_munmap":
805 # stress test, nothing reliable to check
808 print("Invalid test case")
This page took 0.058744 seconds and 4 git commands to generate.