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
21 "/usr/local/lib/python%d.%d/site-packages"
22 % (sys
.version_info
.major
, sys
.version_info
.minor
)
26 NSEC_PER_SEC
= 1000000000
30 def __init__(self
, trace_msg_iter
, pid
):
31 self
.trace
= trace_msg_iter
34 # This dictionnary holds the results of each testcases of a test.
35 # Its layout is the following:
37 # 'event_name_1': {'check_1': 0, 'check_2: 1},
38 # 'event_name_2': {'check_1': 1}
40 # Each test classes checks the payload of different events. Each of
41 # those checks are stored in a event_name specific dictionnary in this
43 self
.expect
= defaultdict(lambda: defaultdict(int))
45 # This dictionnary holds the value recorded in the trace that are
46 # tested. Its content is use to print the values that caused a test to
48 self
.recorded_values
= {}
50 def ns_to_hour_nsec(self
, ns
):
51 d
= time
.localtime(ns
/ NSEC_PER_SEC
)
52 return "%02d:%02d:%02d.%09d" % (
60 # iterate over all the events
61 for msg
in self
.trace
:
62 if type(msg
) is not bt2
._EventMessageConst
:
65 if self
.pid
is not None and msg
.event
["pid"] != self
.pid
:
68 method_name
= "handle_%s" % msg
.event
.name
.replace(":", "_").replace(
71 # call the function to handle each event individually
72 if hasattr(TraceParser
, method_name
):
73 func
= getattr(TraceParser
, method_name
)
77 # For each event of the test case, check all entries for failed
78 for event_name
, event_results
in self
.expect
.items():
79 for val
in event_results
.keys():
80 if self
.expect
[event_name
][val
] == 0:
81 print("%s not validated" % val
)
82 print("Values of the local variables of this test:")
83 # using pprint for pretty printing the dictionnary
84 pprint
.pprint(self
.recorded_values
[event_name
])
90 def handle_compat_syscall_entry_epoll_ctl(self
, event
):
91 self
.epoll_ctl_entry(event
)
93 def handle_compat_syscall_exit_epoll_ctl(self
, event
):
94 self
.epoll_ctl_exit(event
)
96 def handle_syscall_entry_epoll_ctl(self
, event
):
97 self
.epoll_ctl_entry(event
)
99 def handle_syscall_exit_epoll_ctl(self
, event
):
100 self
.epoll_ctl_exit(event
)
102 def epoll_ctl_entry(self
, event
):
105 def epoll_ctl_exit(self
, event
):
108 # epoll_wait + epoll_pwait
109 def handle_compat_syscall_entry_epoll_wait(self
, event
):
110 self
.epoll_wait_entry(event
)
112 def handle_compat_syscall_exit_epoll_wait(self
, event
):
113 self
.epoll_wait_exit(event
)
115 def handle_syscall_entry_epoll_wait(self
, event
):
116 self
.epoll_wait_entry(event
)
118 def handle_syscall_exit_epoll_wait(self
, event
):
119 self
.epoll_wait_exit(event
)
121 def handle_compat_syscall_entry_epoll_pwait(self
, event
):
122 self
.epoll_pwait_entry(event
)
124 def handle_compat_syscall_exit_epoll_pwait(self
, event
):
125 self
.epoll_pwait_exit(event
)
127 def handle_syscall_entry_epoll_pwait(self
, event
):
128 self
.epoll_pwait_entry(event
)
130 def handle_syscall_exit_epoll_pwait(self
, event
):
131 self
.epoll_pwait_exit(event
)
133 def epoll_wait_entry(self
, event
):
136 def epoll_wait_exit(self
, event
):
139 def epoll_pwait_entry(self
, event
):
140 self
.epoll_wait_entry(event
)
142 def epoll_pwait_exit(self
, event
):
143 self
.epoll_wait_exit(event
)
146 def handle_compat_syscall_entry_poll(self
, event
):
147 self
.poll_entry(event
)
149 def handle_compat_syscall_exit_poll(self
, event
):
150 self
.poll_exit(event
)
152 def handle_syscall_entry_poll(self
, event
):
153 self
.poll_entry(event
)
155 def handle_syscall_exit_poll(self
, event
):
156 self
.poll_exit(event
)
158 def handle_compat_syscall_entry_ppoll(self
, event
):
159 self
.poll_entry(event
)
161 def handle_compat_syscall_exit_ppoll(self
, event
):
162 self
.poll_exit(event
)
164 def handle_syscall_entry_ppoll(self
, event
):
165 self
.poll_entry(event
)
167 def handle_syscall_exit_ppoll(self
, event
):
168 self
.poll_exit(event
)
170 def poll_entry(self
, event
):
173 def poll_exit(self
, event
):
177 def handle_compat_syscall_entry_epoll_create1(self
, event
):
178 self
.epoll_create_entry(event
)
180 def handle_compat_syscall_exit_epoll_create1(self
, event
):
181 self
.epoll_create_exit(event
)
183 def handle_compat_syscall_entry_epoll_create(self
, event
):
184 self
.epoll_create_entry(event
)
186 def handle_compat_syscall_exit_epoll_create(self
, event
):
187 self
.epoll_create_exit(event
)
189 def handle_syscall_entry_epoll_create1(self
, event
):
190 self
.epoll_create_entry(event
)
192 def handle_syscall_exit_epoll_create1(self
, event
):
193 self
.epoll_create_exit(event
)
195 def handle_syscall_entry_epoll_create(self
, event
):
196 self
.epoll_create_entry(event
)
198 def handle_syscall_exit_epoll_create(self
, event
):
199 self
.epoll_create_exit(event
)
201 def epoll_create_entry(self
, event
):
204 def epoll_create_exit(self
, event
):
208 def handle_syscall_entry_pselect6(self
, event
):
209 self
.select_entry(event
)
211 def handle_syscall_exit_pselect6(self
, event
):
212 self
.select_exit(event
)
214 def handle_compat_syscall_entry_pselect6(self
, event
):
215 self
.select_entry(event
)
217 def handle_compat_syscall_exit_pselect6(self
, event
):
218 self
.select_exit(event
)
220 def handle_syscall_entry_select(self
, event
):
221 self
.select_entry(event
)
223 def handle_syscall_exit_select(self
, event
):
224 self
.select_exit(event
)
226 def handle_compat_syscall_entry_select(self
, event
):
227 self
.select_entry(event
)
229 def handle_compat_syscall_exit_select(self
, event
):
230 self
.select_exit(event
)
232 def select_entry(self
, event
):
235 def select_exit(self
, event
):
239 class WorkingCases(TraceParser
):
240 def __init__(self
, trace
, validation_args
):
241 super().__init
__(trace
, validation_args
["pid"])
243 # Values expected in the trace
244 self
.epoll_wait_fd
= validation_args
["epoll_wait_fd"]
245 self
.epoll_pwait_fd
= validation_args
["epoll_pwait_fd"]
247 self
.expect
["select_entry"]["select_in_fd0"] = 0
248 self
.expect
["select_entry"]["select_in_fd1023"] = 0
249 self
.expect
["select_exit"]["select_out_fd0"] = 0
250 self
.expect
["select_exit"]["select_out_fd1023"] = 0
251 self
.expect
["poll_entry"]["poll_in_nfds1"] = 0
252 self
.expect
["poll_exit"]["poll_out_nfds1"] = 0
253 self
.expect
["epoll_ctl_entry"]["epoll_ctl_in_add"] = 0
254 self
.expect
["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 0
255 self
.expect
["epoll_wait_entry"]["epoll_wait_in_ok"] = 0
256 self
.expect
["epoll_wait_exit"]["epoll_wait_out_fd0"] = 0
257 self
.expect
["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 0
258 self
.expect
["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 0
260 def select_entry(self
, event
):
262 overflow
= event
["overflow"]
263 readfd_0
= event
["readfds"][0]
265 # check that the FD 0 is actually set in the readfds
266 if n
== 1 and readfd_0
== 1:
267 self
.expect
["select_entry"]["select_in_fd0"] = 1
269 readfd_127
= event
["readfds"][127]
270 writefd_127
= event
["writefds"][127]
271 exceptfd_127
= event
["exceptfds"][127]
273 # check that the FD 1023 is actually set in the readfds
277 and exceptfd_127
== 0
280 self
.expect
["select_entry"]["select_in_fd1023"] = 1
282 # Save values of local variables to print in case of test failure
283 self
.recorded_values
["select_entry"] = locals()
285 def select_exit(self
, event
):
288 overflow
= event
["overflow"]
289 _readfds_length
= event
["_readfds_length"]
292 # check that the FD 0 is actually set in the readfds
293 readfd_0
= event
["readfds"][0]
296 self
.expect
["select_exit"]["select_out_fd0"] = 1
297 # check that the FD 1023 is actually set in the readfds
298 if _readfds_length
== 128:
299 readfd_127
= event
["readfds"][127]
300 writefd_127
= event
["writefds"][127]
301 exceptfd_127
= event
["exceptfds"][127]
305 and exceptfd_127
== 0
308 self
.expect
["select_exit"]["select_out_fd1023"] = 1
310 # Save values of local variables to print in case of test failure
311 self
.recorded_values
["select_exit"] = locals()
313 def poll_entry(self
, event
):
315 fds_length
= event
["fds_length"]
316 overflow
= event
["overflow"]
318 # check that only one FD is set, that it has the POLLIN flag and that
319 # the raw value matches the events bit field.
320 if nfds
== 1 and fds_length
== 1:
321 fd_0
= event
["fds"][0]
323 fd_0
["raw_events"] == 0x3
324 and fd_0
["events"]["POLLIN"] == 1
325 and fd_0
["events"]["padding"] == 0
327 self
.expect
["poll_entry"]["poll_in_nfds1"] = 1
329 # Save values of local variables to print in case of test failure
330 self
.recorded_values
["poll_entry"] = locals()
332 def poll_exit(self
, event
):
334 fds_length
= event
["fds_length"]
336 # check that only one FD is set, that it has the POLLIN flag and that
337 # the raw value matches the events bit field.
338 if ret
== 1 and fds_length
== 1:
339 fd_0
= event
["fds"][0]
341 fd_0
["raw_events"] == 0x1
342 and fd_0
["events"]["POLLIN"] == 1
343 and fd_0
["events"]["padding"] == 0
345 self
.expect
["poll_exit"]["poll_out_nfds1"] = 1
347 # Save values of local variables to print in case of test failure
348 self
.recorded_values
["poll_exit"] = locals()
350 def epoll_ctl_entry(self
, event
):
352 op_enum
= event
["op_enum"]
354 _event
= event
["event"]
356 # check that we have FD 0 waiting for EPOLLIN|EPOLLPRI and that
359 (epfd
== self
.epoll_wait_fd
or epfd
== self
.epoll_pwait_fd
)
360 and "EPOLL_CTL_ADD" in op_enum
.labels
362 and _event
["data_union"]["fd"] == 0
363 and _event
["events"]["EPOLLIN"] == 1
364 and _event
["events"]["EPOLLPRI"] == 1
366 self
.expect
["epoll_ctl_entry"]["epoll_ctl_in_add"] = 1
368 # Save values of local variables to print in case of test failure
369 self
.recorded_values
["epoll_ctl_entry"] = locals()
371 def epoll_ctl_exit(self
, event
):
375 self
.expect
["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 1
377 # Save values of local variables to print in case of test failure
378 self
.recorded_values
["epoll_ctl_exit"] = locals()
380 def epoll_wait_entry(self
, event
):
382 maxevents
= event
["maxevents"]
383 timeout
= event
["timeout"]
385 if epfd
== self
.epoll_wait_fd
and maxevents
== 1 and timeout
== -1:
386 self
.expect
["epoll_wait_entry"]["epoll_wait_in_ok"] = 1
388 # Save values of local variables to print in case of test failure
389 self
.recorded_values
["epoll_wait_entry"] = locals()
391 def epoll_wait_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]
401 and fd_0
["data_union"]["fd"] == 0
402 and fd_0
["events"]["EPOLLIN"] == 1
404 self
.expect
["epoll_wait_exit"]["epoll_wait_out_fd0"] = 1
406 # Save values of local variables to print in case of test failure
407 self
.recorded_values
["epoll_wait_exit"] = locals()
409 def epoll_pwait_entry(self
, event
):
411 maxevents
= event
["maxevents"]
412 timeout
= event
["timeout"]
414 if epfd
== self
.epoll_pwait_fd
and maxevents
== 1 and timeout
== -1:
415 self
.expect
["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 1
417 # Save values of local variables to print in case of test failure
418 self
.recorded_values
["epoll_pwait_entry"] = locals()
420 def epoll_pwait_exit(self
, event
):
422 fds_length
= event
["fds_length"]
423 overflow
= event
["overflow"]
425 # check that FD 0 returned with EPOLLIN and the right data.fd
426 if ret
== 1 and fds_length
== 1:
427 fd_0
= event
["fds"][0]
430 and fd_0
["data_union"]["fd"] == 0
431 and fd_0
["events"]["EPOLLIN"] == 1
433 self
.expect
["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 1
435 # Save values of local variables to print in case of test failure
436 self
.recorded_values
["epoll_pwait_exit"] = locals()
439 class WorkingCasesTimeout(TraceParser
):
440 def __init__(self
, trace
, validation_args
):
441 super().__init
__(trace
, validation_args
["pid"])
442 self
.expect
["select_entry"]["select_timeout_in_fd0"] = 0
443 self
.expect
["select_entry"]["select_timeout_in_fd1023"] = 0
444 self
.expect
["select_exit"]["select_timeout_out"] = 0
445 self
.expect
["poll_entry"]["poll_timeout_in"] = 0
446 self
.expect
["poll_exit"]["poll_timeout_out"] = 0
447 self
.expect
["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 0
448 self
.expect
["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 0
449 self
.expect
["epoll_wait_entry"]["epoll_wait_timeout_in"] = 0
450 self
.expect
["epoll_wait_exit"]["epoll_wait_timeout_out"] = 0
452 def select_entry(self
, event
):
456 if n
== 1 and tvp
!= 0:
457 self
.expect
["select_entry"]["select_timeout_in_fd0"] = 1
459 readfd_127
= event
["readfds"][127]
460 writefd_127
= event
["writefds"][127]
461 exceptfd_127
= event
["exceptfds"][127]
466 and exceptfd_127
== 0
469 self
.expect
["select_entry"]["select_timeout_in_fd1023"] = 1
471 # Save values of local variables to print in case of test failure
472 self
.recorded_values
["select_entry"] = locals()
474 def select_exit(self
, event
):
478 if ret
== 0 and tvp
!= 0:
479 self
.expect
["select_exit"]["select_timeout_out"] = 1
481 # Save values of local variables to print in case of test failure
482 self
.recorded_values
["select_exit"] = locals()
484 def poll_entry(self
, event
):
486 fds_length
= event
["fds_length"]
488 # check that we wait on FD 0 for POLLIN and that the raw_events
489 # field matches the value of POLLIN
490 if nfds
== 1 and fds_length
== 1:
491 fd_0
= event
["fds"][0]
493 fd_0
["raw_events"] == 0x3
494 and fd_0
["events"]["POLLIN"] == 1
495 and fd_0
["events"]["padding"] == 0
497 self
.expect
["poll_entry"]["poll_timeout_in"] = 1
499 # Save values of local variables to print in case of test failure
500 self
.recorded_values
["poll_entry"] = locals()
502 def poll_exit(self
, event
):
505 fds_length
= event
["fds_length"]
507 if ret
== 0 and nfds
== 1 and fds_length
== 0:
508 self
.expect
["poll_exit"]["poll_timeout_out"] = 1
510 # Save values of local variables to print in case of test failure
511 self
.recorded_values
["poll_exit"] = locals()
513 def epoll_ctl_entry(self
, event
):
514 op_enum
= event
["op_enum"]
515 _event
= event
["event"]
517 # make sure we see a EPOLLIN|EPOLLPRI
519 "EPOLL_CTL_ADD" in op_enum
.labels
520 and _event
["events"]["EPOLLIN"] == 1
521 and _event
["events"]["EPOLLPRI"] == 1
523 self
.expect
["epoll_ctl_entry"]["epoll_ctl_timeout_in_add"] = 1
525 # Save values of local variables to print in case of test failure
526 self
.recorded_values
["epoll_ctl_entry"] = locals()
528 def epoll_ctl_exit(self
, event
):
532 self
.expect
["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 1
534 # Save values of local variables to print in case of test failure
535 self
.recorded_values
["epoll_ctl_exit"] = locals()
537 def epoll_wait_entry(self
, event
):
538 maxevents
= event
["maxevents"]
539 timeout
= event
["timeout"]
541 if maxevents
== 1 and timeout
== 1:
542 self
.expect
["epoll_wait_entry"]["epoll_wait_timeout_in"] = 1
544 # Save values of local variables to print in case of test failure
545 self
.recorded_values
["epoll_wait_entry"] = locals()
547 def epoll_wait_exit(self
, event
):
549 fds_length
= event
["fds_length"]
550 overflow
= event
["overflow"]
552 if ret
== 0 and fds_length
== 0 and overflow
== 0:
553 self
.expect
["epoll_wait_exit"]["epoll_wait_timeout_out"] = 1
555 # Save values of local variables to print in case of test failure
556 self
.recorded_values
["epoll_wait_exit"] = locals()
559 class PselectInvalidFd(TraceParser
):
560 def __init__(self
, trace
, validation_args
):
561 super().__init
__(trace
, validation_args
["pid"])
562 self
.expect
["select_entry"]["select_invalid_fd_in"] = 0
563 self
.expect
["select_exit"]["select_invalid_fd_out"] = 0
565 def select_entry(self
, event
):
567 overflow
= event
["overflow"]
569 if n
> 0 and overflow
== 0:
570 self
.expect
["select_entry"]["select_invalid_fd_in"] = 1
572 # Save values of local variables to print in case of test failure
573 self
.recorded_values
["select_entry"] = locals()
575 def select_exit(self
, event
):
577 overflow
= event
["overflow"]
578 _readfds_length
= event
["_readfds_length"]
580 # make sure the event has a ret field equal to -EBADF
581 if ret
== -9 and overflow
== 0 and _readfds_length
== 0:
582 self
.expect
["select_exit"]["select_invalid_fd_out"] = 1
584 # Save values of local variables to print in case of test failure
585 self
.recorded_values
["select_exit"] = locals()
588 class PpollBig(TraceParser
):
589 def __init__(self
, trace
, validation_args
):
590 super().__init
__(trace
, validation_args
["pid"])
591 self
.expect
["poll_entry"]["big_poll_in"] = 0
592 self
.expect
["poll_exit"]["big_poll_out"] = 0
594 def poll_entry(self
, event
):
596 fds_length
= event
["fds_length"]
597 overflow
= event
["overflow"]
599 # test of big list of FDs and the behaviour of the overflow
600 if nfds
== 2047 and fds_length
== 512 and overflow
== 1:
601 fd_0
= event
["fds"][0]
602 fd_511
= event
["fds"][511]
604 fd_0
["raw_events"] == 0x3
605 and fd_0
["events"]["POLLIN"] == 1
606 and fd_0
["events"]["padding"] == 0
607 and fd_511
["events"]["POLLIN"] == 1
608 and fd_511
["events"]["POLLPRI"] == 1
610 self
.expect
["poll_entry"]["big_poll_in"] = 1
612 # Save values of local variables to print in case of test failure
613 self
.recorded_values
["poll_entry"] = locals()
615 def poll_exit(self
, event
):
618 fds_length
= event
["fds_length"]
619 overflow
= event
["overflow"]
621 # test of big list of FDs and the behaviour of the overflow
622 if ret
== 2047 and nfds
== 2047 and fds_length
== 512 and overflow
== 1:
623 fd_0
= event
["fds"][0]
624 fd_511
= event
["fds"][511]
625 if fd_0
["events"]["POLLIN"] == 1 and fd_511
["events"]["POLLIN"] == 1:
626 self
.expect
["poll_exit"]["big_poll_out"] = 1
628 # Save values of local variables to print in case of test failure
629 self
.recorded_values
["poll_exit"] = locals()
632 class PpollFdsBufferOverflow(TraceParser
):
633 def __init__(self
, trace
, validation_args
):
634 super().__init
__(trace
, validation_args
["pid"])
635 self
.expect
["poll_entry"]["poll_overflow_in"] = 0
636 self
.expect
["poll_exit"]["poll_overflow_out"] = 0
638 def poll_entry(self
, event
):
640 fds_length
= event
["fds_length"]
641 overflow
= event
["overflow"]
643 # test that event in valid even though the target buffer is too small
644 # and the program segfaults
645 if nfds
== 100 and fds_length
== 100 and overflow
== 0:
646 fd_0
= event
["fds"][0]
647 if fd_0
["events"]["POLLIN"] == 1:
648 self
.expect
["poll_entry"]["poll_overflow_in"] = 1
650 # Save values of local variables to print in case of test failure
651 self
.recorded_values
["poll_entry"] = locals()
653 def poll_exit(self
, event
):
655 overflow
= event
["overflow"]
657 # test that event in valid even though the target buffer is too small
658 # and the program segfaults
659 if nfds
== 100 and overflow
== 0:
660 self
.expect
["poll_exit"]["poll_overflow_out"] = 1
662 # Save values of local variables to print in case of test failure
663 self
.recorded_values
["poll_exit"] = locals()
666 class PselectInvalidPointer(TraceParser
):
667 def __init__(self
, trace
, validation_args
):
668 super().__init
__(trace
, validation_args
["pid"])
669 self
.expect
["select_entry"]["pselect_invalid_in"] = 0
670 self
.expect
["select_exit"]["pselect_invalid_out"] = 0
672 def select_entry(self
, event
):
674 overflow
= event
["overflow"]
675 _readfds_length
= event
["_readfds_length"]
677 # test that event in valid even though the target buffer pointer is
678 # invalid and the program segfaults
679 if n
== 1 and overflow
== 0 and _readfds_length
== 0:
680 self
.expect
["select_entry"]["pselect_invalid_in"] = 1
682 # Save values of local variables to print in case of test failure
683 self
.recorded_values
["select_entry"] = locals()
685 def select_exit(self
, event
):
687 overflow
= event
["overflow"]
688 _readfds_length
= event
["_readfds_length"]
690 # test that event in valid even though the target buffer pointer is
691 # invalid and the program segfaults
692 if ret
== -14 and overflow
== 0 and _readfds_length
== 0:
693 self
.expect
["select_exit"]["pselect_invalid_out"] = 1
695 # Save values of local variables to print in case of test failure
696 self
.recorded_values
["select_exit"] = locals()
699 class PpollFdsULongMax(TraceParser
):
700 def __init__(self
, trace
, validation_args
):
701 super().__init
__(trace
, validation_args
["pid"])
702 self
.expect
["poll_entry"]["poll_max_in"] = 0
703 self
.expect
["poll_exit"]["poll_max_out"] = 0
705 def poll_entry(self
, event
):
707 overflow
= event
["overflow"]
709 # check the proper working of INT_MAX maxevent value
710 if nfds
== 4294967295 and overflow
== 1:
711 self
.expect
["poll_entry"]["poll_max_in"] = 1
713 # Save values of local variables to print in case of test failure
714 self
.recorded_values
["poll_entry"] = locals()
716 def poll_exit(self
, event
):
719 overflow
= event
["overflow"]
721 # check the proper working of UINT_MAX maxevent value
722 if ret
== -22 and nfds
== 4294967295 and overflow
== 0:
723 self
.expect
["poll_exit"]["poll_max_out"] = 1
725 # Save values of local variables to print in case of test failure
726 self
.recorded_values
["poll_exit"] = locals()
729 class EpollPwaitInvalidPointer(TraceParser
):
730 def __init__(self
, trace
, validation_args
):
731 super().__init
__(trace
, validation_args
["pid"])
733 # Values expected in the trace
734 self
.epoll_fd
= validation_args
["epollfd"]
736 self
.expect
["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
737 self
.expect
["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
739 def epoll_wait_entry(self
, event
):
741 maxevents
= event
["maxevents"]
742 timeout
= event
["timeout"]
744 # test that event in valid even though the target buffer pointer is
745 # invalid and the program segfaults
746 if epfd
== self
.epoll_fd
and maxevents
== 1 and timeout
== -1:
747 self
.expect
["epoll_wait_entry"]["epoll_wait_invalid_in"] = 1
749 # Save values of local variables to print in case of test failure
750 self
.recorded_values
["epoll_wait_entry"] = locals()
752 def epoll_wait_exit(self
, event
):
754 fds_length
= event
["fds_length"]
755 overflow
= event
["overflow"]
757 # test that event in valid even though the target buffer pointer is
758 # invalid and the program segfaults
759 if ret
== -14 and fds_length
== 0 and overflow
== 0:
760 self
.expect
["epoll_wait_exit"]["epoll_wait_invalid_out"] = 1
762 # Save values of local variables to print in case of test failure
763 self
.recorded_values
["epoll_wait_exit"] = locals()
766 class EpollPwaitIntMax(TraceParser
):
767 def __init__(self
, trace
, validation_args
):
768 super().__init
__(trace
, validation_args
["pid"])
770 # Values expected in the trace
771 self
.epoll_fd
= validation_args
["epollfd"]
773 self
.expect
["epoll_wait_entry"]["epoll_wait_max_in"] = 0
774 self
.expect
["epoll_wait_exit"]["epoll_wait_max_out"] = 0
776 def epoll_wait_entry(self
, event
):
778 maxevents
= event
["maxevents"]
779 timeout
= event
["timeout"]
781 # check the proper working of INT_MAX maxevent value
782 if epfd
== self
.epoll_fd
and maxevents
== 2147483647 and timeout
== -1:
783 self
.expect
["epoll_wait_entry"]["epoll_wait_max_in"] = 1
785 # Save values of local variables to print in case of test failure
786 self
.recorded_values
["epoll_wait_entry"] = locals()
788 def epoll_wait_exit(self
, event
):
790 fds_length
= event
["fds_length"]
791 overflow
= event
["overflow"]
793 # check the proper working of INT_MAX maxevent value
794 if ret
== -22 and fds_length
== 0 and overflow
== 0:
795 self
.expect
["epoll_wait_exit"]["epoll_wait_max_out"] = 1
797 # Save values of local variables to print in case of test failure
798 self
.recorded_values
["epoll_wait_exit"] = locals()
801 if __name__
== "__main__":
802 parser
= argparse
.ArgumentParser(description
="Trace parser")
803 parser
.add_argument("path", metavar
="<path/to/trace>", help="Trace path")
804 parser
.add_argument("-t", "--test", type=str, help="Test to validate")
806 "-o", "--validation-file", type=str, help="Validation file path"
808 args
= parser
.parse_args()
811 print("Need to pass a test to validate (--test/-t)")
814 if not args
.validation_file
:
815 print("Need to pass the test validation file (--validation-file/-o)")
818 traces
= bt2
.TraceCollectionMessageIterator(args
.path
)
820 with
open(args
.validation_file
) as f
:
822 test_validation_args
= json
.load(f
)
823 except Exception as e
:
824 print("Failed to parse validation file: " + str(e
))
829 if args
.test
== "working_cases":
830 t
= WorkingCases(traces
, test_validation_args
)
831 elif args
.test
== "working_cases_timeout":
832 t
= WorkingCasesTimeout(traces
, test_validation_args
)
833 elif args
.test
== "pselect_invalid_fd":
834 t
= PselectInvalidFd(traces
, test_validation_args
)
835 elif args
.test
== "ppoll_big":
836 t
= PpollBig(traces
, test_validation_args
)
837 elif args
.test
== "ppoll_fds_buffer_overflow":
838 t
= PpollFdsBufferOverflow(traces
, test_validation_args
)
839 elif args
.test
== "pselect_invalid_pointer":
840 t
= PselectInvalidPointer(traces
, test_validation_args
)
841 elif args
.test
== "ppoll_fds_ulong_max":
842 t
= PpollFdsULongMax(traces
, test_validation_args
)
843 elif args
.test
== "epoll_pwait_invalid_pointer":
844 t
= EpollPwaitInvalidPointer(traces
, test_validation_args
)
845 elif args
.test
== "epoll_pwait_int_max":
846 t
= EpollPwaitIntMax(traces
, test_validation_args
)
847 elif args
.test
== "ppoll_concurrent_write":
848 # stress test, nothing reliable to check
850 elif args
.test
== "epoll_pwait_concurrent_munmap":
851 # stress test, nothing reliable to check
854 print("Invalid test case")
This page took 0.050042 seconds and 4 git commands to generate.