docs: Add supported versions and fix-backport policy
[lttng-tools.git] / tests / regression / kernel / validate_select_poll_epoll.py
1 #!/usr/bin/env python3
2 #
3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4 #
5 # SPDX-License-Identifier: GPL-2.0-only
6 #
7
8 import argparse
9 import pprint
10 import sys
11 import time
12 import json
13
14 from collections import defaultdict
15
16 try:
17 import bt2
18 except ImportError:
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))
22 import bt2
23
24 NSEC_PER_SEC = 1000000000
25
26 class TraceParser:
27 def __init__(self, trace_msg_iter, pid):
28 self.trace = trace_msg_iter
29 self.pid = pid
30
31 # This dictionnary holds the results of each testcases of a test.
32 # Its layout is the following:
33 # self.expect={
34 # 'event_name_1': {'check_1': 0, 'check_2: 1},
35 # 'event_name_2': {'check_1': 1}
36 # }
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
39 # data structure.
40 self.expect = defaultdict(lambda : defaultdict(int))
41
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
44 # fail.
45 self.recorded_values = {}
46
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,
50 ns % NSEC_PER_SEC)
51
52 def parse(self):
53 # iterate over all the events
54 for msg in self.trace:
55 if type(msg) is not bt2._EventMessageConst:
56 continue
57
58 if self.pid is not None and msg.event["pid"] != self.pid:
59 continue
60
61 method_name = "handle_%s" % msg.event.name.replace(":", "_").replace(
62 "+", "_")
63 # call the function to handle each event individually
64 if hasattr(TraceParser, method_name):
65 func = getattr(TraceParser, method_name)
66 func(self, msg.event)
67
68 ret = 0
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])
77 ret = 1
78
79 return ret
80
81 # epoll_ctl
82 def handle_compat_syscall_entry_epoll_ctl(self, event):
83 self.epoll_ctl_entry(event)
84
85 def handle_compat_syscall_exit_epoll_ctl(self, event):
86 self.epoll_ctl_exit(event)
87
88 def handle_syscall_entry_epoll_ctl(self, event):
89 self.epoll_ctl_entry(event)
90
91 def handle_syscall_exit_epoll_ctl(self, event):
92 self.epoll_ctl_exit(event)
93
94 def epoll_ctl_entry(self, event):
95 pass
96
97 def epoll_ctl_exit(self, event):
98 pass
99
100 # epoll_wait + epoll_pwait
101 def handle_compat_syscall_entry_epoll_wait(self, event):
102 self.epoll_wait_entry(event)
103
104 def handle_compat_syscall_exit_epoll_wait(self, event):
105 self.epoll_wait_exit(event)
106
107 def handle_syscall_entry_epoll_wait(self, event):
108 self.epoll_wait_entry(event)
109
110 def handle_syscall_exit_epoll_wait(self, event):
111 self.epoll_wait_exit(event)
112
113 def handle_compat_syscall_entry_epoll_pwait(self, event):
114 self.epoll_pwait_entry(event)
115
116 def handle_compat_syscall_exit_epoll_pwait(self, event):
117 self.epoll_pwait_exit(event)
118
119 def handle_syscall_entry_epoll_pwait(self, event):
120 self.epoll_pwait_entry(event)
121
122 def handle_syscall_exit_epoll_pwait(self, event):
123 self.epoll_pwait_exit(event)
124
125 def epoll_wait_entry(self, event):
126 pass
127
128 def epoll_wait_exit(self, event):
129 pass
130
131 def epoll_pwait_entry(self, event):
132 self.epoll_wait_entry(event)
133
134 def epoll_pwait_exit(self, event):
135 self.epoll_wait_exit(event)
136
137 ## poll + ppoll
138 def handle_compat_syscall_entry_poll(self, event):
139 self.poll_entry(event)
140
141 def handle_compat_syscall_exit_poll(self, event):
142 self.poll_exit(event)
143
144 def handle_syscall_entry_poll(self, event):
145 self.poll_entry(event)
146
147 def handle_syscall_exit_poll(self, event):
148 self.poll_exit(event)
149
150 def handle_compat_syscall_entry_ppoll(self, event):
151 self.poll_entry(event)
152
153 def handle_compat_syscall_exit_ppoll(self, event):
154 self.poll_exit(event)
155
156 def handle_syscall_entry_ppoll(self, event):
157 self.poll_entry(event)
158
159 def handle_syscall_exit_ppoll(self, event):
160 self.poll_exit(event)
161
162 def poll_entry(self, event):
163 pass
164
165 def poll_exit(self, event):
166 pass
167
168 # epoll_create
169 def handle_compat_syscall_entry_epoll_create1(self, event):
170 self.epoll_create_entry(event)
171
172 def handle_compat_syscall_exit_epoll_create1(self, event):
173 self.epoll_create_exit(event)
174
175 def handle_compat_syscall_entry_epoll_create(self, event):
176 self.epoll_create_entry(event)
177
178 def handle_compat_syscall_exit_epoll_create(self, event):
179 self.epoll_create_exit(event)
180
181 def handle_syscall_entry_epoll_create1(self, event):
182 self.epoll_create_entry(event)
183
184 def handle_syscall_exit_epoll_create1(self, event):
185 self.epoll_create_exit(event)
186
187 def handle_syscall_entry_epoll_create(self, event):
188 self.epoll_create_entry(event)
189
190 def handle_syscall_exit_epoll_create(self, event):
191 self.epoll_create_exit(event)
192
193 def epoll_create_entry(self, event):
194 pass
195
196 def epoll_create_exit(self, event):
197 pass
198
199 # select + pselect6
200 def handle_syscall_entry_pselect6(self, event):
201 self.select_entry(event)
202
203 def handle_syscall_exit_pselect6(self, event):
204 self.select_exit(event)
205
206 def handle_compat_syscall_entry_pselect6(self, event):
207 self.select_entry(event)
208
209 def handle_compat_syscall_exit_pselect6(self, event):
210 self.select_exit(event)
211
212 def handle_syscall_entry_select(self, event):
213 self.select_entry(event)
214
215 def handle_syscall_exit_select(self, event):
216 self.select_exit(event)
217
218 def handle_compat_syscall_entry_select(self, event):
219 self.select_entry(event)
220
221 def handle_compat_syscall_exit_select(self, event):
222 self.select_exit(event)
223
224 def select_entry(self, event):
225 pass
226
227 def select_exit(self, event):
228 pass
229
230
231 class Test1(TraceParser):
232 def __init__(self, trace, validation_args):
233 super().__init__(trace, validation_args['pid'])
234
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']
238
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
251
252 def select_entry(self, event):
253 n = event["n"]
254 overflow = event["overflow"]
255 readfd_0 = event["readfds"][0]
256
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
260 if n == 1023:
261 readfd_127 = event["readfds"][127]
262 writefd_127 = event["writefds"][127]
263 exceptfd_127 = event["exceptfds"][127]
264
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
269
270 # Save values of local variables to print in case of test failure
271 self.recorded_values["select_entry"] = locals()
272
273 def select_exit(self, event):
274 ret = event["ret"]
275 tvp = event["tvp"]
276 overflow = event["overflow"]
277 _readfds_length = event["_readfds_length"]
278
279 if ret == 1:
280 # check that the FD 0 is actually set in the readfds
281 readfd_0 = event["readfds"][0]
282
283 if readfd_0 == 1:
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
293
294 # Save values of local variables to print in case of test failure
295 self.recorded_values["select_exit"] = locals()
296
297 def poll_entry(self, event):
298 nfds = event["nfds"]
299 fds_length = event["fds_length"]
300 overflow = event["overflow"]
301
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
309
310 # Save values of local variables to print in case of test failure
311 self.recorded_values["poll_entry"] = locals()
312
313 def poll_exit(self, event):
314 ret = event["ret"]
315 fds_length = event["fds_length"]
316
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
324
325 # Save values of local variables to print in case of test failure
326 self.recorded_values["poll_exit"] = locals()
327
328 def epoll_ctl_entry(self, event):
329 epfd = event["epfd"]
330 op_enum = event["op_enum"]
331 fd = event["fd"]
332 _event = event["event"]
333
334 # check that we have FD 0 waiting for EPOLLIN|EPOLLPRI and that
335 # data.fd = 0
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
341
342 # Save values of local variables to print in case of test failure
343 self.recorded_values["epoll_ctl_entry"] = locals()
344
345 def epoll_ctl_exit(self, event):
346 ret = event["ret"]
347
348 if ret == 0:
349 self.expect["epoll_ctl_exit"]["epoll_ctl_out_ok"] = 1
350
351 # Save values of local variables to print in case of test failure
352 self.recorded_values["epoll_ctl_exit"] = locals()
353
354 def epoll_wait_entry(self, event):
355 epfd = event["epfd"]
356 maxevents = event["maxevents"]
357 timeout = event["timeout"]
358
359 if epfd == self.epoll_wait_fd and maxevents == 1 and timeout == -1:
360 self.expect["epoll_wait_entry"]["epoll_wait_in_ok"] = 1
361
362 # Save values of local variables to print in case of test failure
363 self.recorded_values["epoll_wait_entry"] = locals()
364
365 def epoll_wait_exit(self, event):
366 ret = event["ret"]
367 fds_length = event["fds_length"]
368 overflow = event["overflow"]
369
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
376
377 # Save values of local variables to print in case of test failure
378 self.recorded_values["epoll_wait_exit"] = locals()
379
380 def epoll_pwait_entry(self, event):
381 epfd = event["epfd"]
382 maxevents = event["maxevents"]
383 timeout = event["timeout"]
384
385 if epfd == self.epoll_pwait_fd and maxevents == 1 and timeout == -1:
386 self.expect["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 1
387
388 # Save values of local variables to print in case of test failure
389 self.recorded_values["epoll_pwait_entry"] = locals()
390
391 def epoll_pwait_exit(self, event):
392 ret = event["ret"]
393 fds_length = event["fds_length"]
394 overflow = event["overflow"]
395
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
402
403 # Save values of local variables to print in case of test failure
404 self.recorded_values["epoll_pwait_exit"] = locals()
405
406 class Test2(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
418
419 def select_entry(self, event):
420 n = event["n"]
421 tvp = event["tvp"]
422
423 if n == 1 and tvp != 0:
424 self.expect["select_entry"]["select_timeout_in_fd0"] = 1
425 if n == 1023:
426 readfd_127 = event["readfds"][127]
427 writefd_127 = event["writefds"][127]
428 exceptfd_127 = event["exceptfds"][127]
429
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
433
434 # Save values of local variables to print in case of test failure
435 self.recorded_values["select_entry"] = locals()
436
437 def select_exit(self, event):
438 ret = event["ret"]
439 tvp = event["tvp"]
440
441 if ret == 0 and tvp != 0:
442 self.expect["select_exit"]["select_timeout_out"] = 1
443
444 # Save values of local variables to print in case of test failure
445 self.recorded_values["select_exit"] = locals()
446
447 def poll_entry(self, event):
448 nfds = event["nfds"]
449 fds_length = event["fds_length"]
450
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
459
460 # Save values of local variables to print in case of test failure
461 self.recorded_values["poll_entry"] = locals()
462
463 def poll_exit(self, event):
464 ret = event["ret"]
465 nfds = event["nfds"]
466 fds_length = event["fds_length"]
467
468 if ret == 0 and nfds == 1 and fds_length == 0:
469 self.expect["poll_exit"]["poll_timeout_out"] = 1
470
471 # Save values of local variables to print in case of test failure
472 self.recorded_values["poll_exit"] = locals()
473
474 def epoll_ctl_entry(self, event):
475 op_enum = event["op_enum"]
476 _event = event["event"]
477
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
483
484 # Save values of local variables to print in case of test failure
485 self.recorded_values["epoll_ctl_entry"] = locals()
486
487 def epoll_ctl_exit(self, event):
488 ret = event["ret"]
489
490 if ret == 0:
491 self.expect["epoll_ctl_exit"]["epoll_ctl_timeout_out_ok"] = 1
492
493 # Save values of local variables to print in case of test failure
494 self.recorded_values["epoll_ctl_exit"] = locals()
495
496 def epoll_wait_entry(self, event):
497 maxevents = event["maxevents"]
498 timeout = event["timeout"]
499
500 if maxevents == 1 and timeout == 1:
501 self.expect["epoll_wait_entry"]["epoll_wait_timeout_in"] = 1
502
503 # Save values of local variables to print in case of test failure
504 self.recorded_values["epoll_wait_entry"] = locals()
505
506 def epoll_wait_exit(self, event):
507 ret = event["ret"]
508 fds_length = event["fds_length"]
509 overflow = event["overflow"]
510
511 if ret == 0 and fds_length == 0 and overflow == 0:
512 self.expect["epoll_wait_exit"]["epoll_wait_timeout_out"] = 1
513
514 # Save values of local variables to print in case of test failure
515 self.recorded_values["epoll_wait_exit"] = locals()
516
517
518 class Test3(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
523
524 def select_entry(self, event):
525 n = event["n"]
526 overflow = event["overflow"]
527
528 if n > 0 and overflow == 0:
529 self.expect["select_entry"]["select_invalid_fd_in"] = 1
530
531 # Save values of local variables to print in case of test failure
532 self.recorded_values["select_entry"] = locals()
533
534 def select_exit(self, event):
535 ret = event["ret"]
536 overflow = event["overflow"]
537 _readfds_length = event["_readfds_length"]
538
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
542
543 # Save values of local variables to print in case of test failure
544 self.recorded_values["select_exit"] = locals()
545
546
547 class Test4(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
552
553 def poll_entry(self, event):
554 nfds = event["nfds"]
555 fds_length = event["fds_length"]
556 overflow = event["overflow"]
557
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
567
568 # Save values of local variables to print in case of test failure
569 self.recorded_values["poll_entry"] = locals()
570
571 def poll_exit(self, event):
572 ret = event["ret"]
573 nfds = event["nfds"]
574 fds_length = event["fds_length"]
575 overflow = event["overflow"]
576
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
583
584 # Save values of local variables to print in case of test failure
585 self.recorded_values["poll_exit"] = locals()
586
587 class Test5(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
592
593 def poll_entry(self, event):
594 nfds = event["nfds"]
595 fds_length = event["fds_length"]
596 overflow = event["overflow"]
597
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
604
605 # Save values of local variables to print in case of test failure
606 self.recorded_values["poll_entry"] = locals()
607
608 def poll_exit(self, event):
609 nfds = event["nfds"]
610 overflow = event["overflow"]
611
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
616
617 # Save values of local variables to print in case of test failure
618 self.recorded_values["poll_exit"] = locals()
619
620
621 class Test6(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
626
627 def select_entry(self, event):
628 n = event["n"]
629 overflow = event["overflow"]
630 _readfds_length = event["_readfds_length"]
631
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
636
637 # Save values of local variables to print in case of test failure
638 self.recorded_values["select_entry"] = locals()
639
640 def select_exit(self, event):
641 ret = event["ret"]
642 overflow = event["overflow"]
643 _readfds_length = event["_readfds_length"]
644
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
649
650 # Save values of local variables to print in case of test failure
651 self.recorded_values["select_exit"] = locals()
652
653
654 class Test7(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
659
660 def poll_entry(self, event):
661 nfds = event["nfds"]
662 overflow = event["overflow"]
663
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
667
668 # Save values of local variables to print in case of test failure
669 self.recorded_values["poll_entry"] = locals()
670
671
672 def poll_exit(self, event):
673 ret = event["ret"]
674 nfds = event["nfds"]
675 overflow = event["overflow"]
676
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
680
681 # Save values of local variables to print in case of test failure
682 self.recorded_values["poll_exit"] = locals()
683
684
685 class Test8(TraceParser):
686 def __init__(self, trace, validation_args):
687 super().__init__(trace, validation_args['pid'])
688
689 # Values expected in the trace
690 self.epoll_fd = validation_args['epollfd']
691
692 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
693 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
694
695 def epoll_wait_entry(self, event):
696 epfd = event["epfd"]
697 maxevents = event["maxevents"]
698 timeout = event["timeout"]
699
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
704
705 # Save values of local variables to print in case of test failure
706 self.recorded_values["epoll_wait_entry"] = locals()
707
708 def epoll_wait_exit(self, event):
709 ret = event["ret"]
710 fds_length = event["fds_length"]
711 overflow = event["overflow"]
712
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
717
718 # Save values of local variables to print in case of test failure
719 self.recorded_values["epoll_wait_exit"] = locals()
720
721
722 class Test9(TraceParser):
723 def __init__(self, trace, validation_args):
724 super().__init__(trace, validation_args['pid'])
725
726 # Values expected in the trace
727 self.epoll_fd = validation_args['epollfd']
728
729 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 0
730 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 0
731
732 def epoll_wait_entry(self, event):
733 epfd = event["epfd"]
734 maxevents = event["maxevents"]
735 timeout = event["timeout"]
736
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
740
741 # Save values of local variables to print in case of test failure
742 self.recorded_values["epoll_wait_entry"] = locals()
743
744 def epoll_wait_exit(self, event):
745 ret = event["ret"]
746 fds_length = event["fds_length"]
747 overflow = event["overflow"]
748
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
752
753 # Save values of local variables to print in case of test failure
754 self.recorded_values["epoll_wait_exit"] = locals()
755
756
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=int, help='Test to validate')
761 parser.add_argument('-o', '--validation-file', type=str, help='Validation file path')
762 args = parser.parse_args()
763
764 if not args.test:
765 print("Need to pass a test to validate (--test/-t)")
766 sys.exit(1)
767
768 if not args.validation_file:
769 print("Need to pass the test validation file (--validation-file/-o)")
770 sys.exit(1)
771
772 traces = bt2.TraceCollectionMessageIterator(args.path)
773
774 with open(args.validation_file) as f:
775 try:
776 test_validation_args = json.load(f)
777 except Exception as e:
778 print('Failed to parse validation file: ' + str(e))
779 sys.exit(1)
780
781 t = None
782
783 if args.test == 1:
784 t = Test1(traces, test_validation_args)
785 elif args.test == 2:
786 t = Test2(traces, test_validation_args)
787 elif args.test == 3:
788 t = Test3(traces, test_validation_args)
789 elif args.test == 4:
790 t = Test4(traces, test_validation_args)
791 elif args.test == 5:
792 t = Test5(traces, test_validation_args)
793 elif args.test == 6:
794 t = Test6(traces, test_validation_args)
795 elif args.test == 7:
796 t = Test7(traces, test_validation_args)
797 elif args.test == 8:
798 t = Test8(traces, test_validation_args)
799 elif args.test == 9:
800 t = Test9(traces, test_validation_args)
801 elif args.test == 10:
802 # stress test, nothing reliable to check
803 ret = 0
804 elif args.test == 11:
805 # stress test, nothing reliable to check
806 ret = 0
807 else:
808 print("Invalid test case")
809 sys.exit(1)
810
811 if t is not None:
812 ret = t.parse()
813
814 sys.exit(ret)
This page took 0.046521 seconds and 4 git commands to generate.