b8d28a9816114ebee7f68e202b3f52ea743f9697
[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 NSEC_PER_SEC = 1000000000
17
18 try:
19 from babeltrace import TraceCollection
20 except 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
27 class TraceParser:
28 def __init__(self, trace, pid):
29 self.trace = trace
30 self.pid = pid
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 = {}
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
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
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):
112 self.epoll_pwait_entry(event)
113
114 def handle_compat_syscall_exit_epoll_pwait(self, event):
115 self.epoll_pwait_exit(event)
116
117 def handle_syscall_entry_epoll_pwait(self, event):
118 self.epoll_pwait_entry(event)
119
120 def handle_syscall_exit_epoll_pwait(self, event):
121 self.epoll_pwait_exit(event)
122
123 def epoll_wait_entry(self, event):
124 pass
125
126 def epoll_wait_exit(self, event):
127 pass
128
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
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
229 class Test1(TraceParser):
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
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
247 self.expect["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 0
248 self.expect["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 0
249
250 def select_entry(self, event):
251 n = event["n"]
252 overflow = event["overflow"]
253 readfd_0 = event["readfds"][0]
254
255 # check that the FD 0 is actually set in the readfds
256 if n == 1 and readfd_0 == 1:
257 self.expect["select_entry"]["select_in_fd0"] = 1
258 if n == 1023:
259 readfd_127 = event["readfds"][127]
260 writefd_127 = event["writefds"][127]
261 exceptfd_127 = event["exceptfds"][127]
262
263 # check that the FD 1023 is actually set in the readfds
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()
270
271 def select_exit(self, event):
272 ret = event["ret"]
273 tvp = event["tvp"]
274 overflow = event["overflow"]
275 _readfds_length = event["_readfds_length"]
276
277 if ret == 1:
278 # check that the FD 0 is actually set in the readfds
279 readfd_0 = event["readfds"][0]
280
281 if readfd_0 == 1:
282 self.expect["select_exit"]["select_out_fd0"] = 1
283 # check that the FD 1023 is actually set in the readfds
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()
294
295 def poll_entry(self, event):
296 nfds = event["nfds"]
297 fds_length = event["fds_length"]
298 overflow = event["overflow"]
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.
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()
310
311 def poll_exit(self, event):
312 ret = event["ret"]
313 fds_length = event["fds_length"]
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.
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()
325
326 def epoll_ctl_entry(self, event):
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
334 if (epfd == self.epoll_wait_fd or epfd == self.epoll_pwait_fd) and 'EPOLL_CTL_ADD' in op_enum.labels and fd == 0 and \
335 _event["data_union"]["fd"] == 0 and \
336 _event["events"]["EPOLLIN"] == 1 and \
337 _event["events"]["EPOLLPRI"] == 1:
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()
342
343 def epoll_ctl_exit(self, event):
344 ret = event["ret"]
345
346 if ret == 0:
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()
351
352 def epoll_wait_entry(self, event):
353 epfd = event["epfd"]
354 maxevents = event["maxevents"]
355 timeout = event["timeout"]
356
357 if epfd == self.epoll_wait_fd and maxevents == 1 and timeout == -1:
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()
362
363 def epoll_wait_exit(self, event):
364 ret = event["ret"]
365 fds_length = event["fds_length"]
366 overflow = event["overflow"]
367
368 # check that FD 0 returned with EPOLLIN and the right data.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()
377
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()
403
404 class Test2(TraceParser):
405 def __init__(self, trace, validation_args):
406 super().__init__(trace, validation_args['pid'])
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
416
417 def select_entry(self, event):
418 n = event["n"]
419 tvp = event["tvp"]
420
421 if n == 1 and tvp != 0:
422 self.expect["select_entry"]["select_timeout_in_fd0"] = 1
423 if n == 1023:
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()
434
435 def select_exit(self, event):
436 ret = event["ret"]
437 tvp = event["tvp"]
438
439 if ret == 0 and tvp != 0:
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()
444
445 def poll_entry(self, event):
446 nfds = event["nfds"]
447 fds_length = event["fds_length"]
448
449 # check that we wait on FD 0 for POLLIN and that the raw_events
450 # field matches the value of POLLIN
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()
460
461 def poll_exit(self, event):
462 ret = event["ret"]
463 nfds = event["nfds"]
464 fds_length = event["fds_length"]
465
466 if ret == 0 and nfds == 1 and fds_length == 0:
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()
471
472 def epoll_ctl_entry(self, event):
473 op_enum = event["op_enum"]
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:
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()
484
485 def epoll_ctl_exit(self, event):
486 ret = event["ret"]
487
488 if ret == 0:
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()
493
494 def epoll_wait_entry(self, event):
495 maxevents = event["maxevents"]
496 timeout = event["timeout"]
497
498 if maxevents == 1 and timeout == 1:
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()
503
504 def epoll_wait_exit(self, event):
505 ret = event["ret"]
506 fds_length = event["fds_length"]
507 overflow = event["overflow"]
508
509 if ret == 0 and fds_length == 0 and overflow == 0:
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()
514
515
516 class Test3(TraceParser):
517 def __init__(self, trace, validation_args):
518 super().__init__(trace, validation_args['pid'])
519 self.expect["select_entry"]["select_invalid_fd_in"] = 0
520 self.expect["select_exit"]["select_invalid_fd_out"] = 0
521
522 def select_entry(self, event):
523 n = event["n"]
524 overflow = event["overflow"]
525
526 if n > 0 and overflow == 0:
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()
531
532 def select_exit(self, event):
533 ret = event["ret"]
534 overflow = event["overflow"]
535 _readfds_length = event["_readfds_length"]
536
537 # make sure the event has a ret field equal to -EBADF
538 if ret == -9 and overflow == 0 and _readfds_length == 0:
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()
543
544
545 class Test4(TraceParser):
546 def __init__(self, trace, validation_args):
547 super().__init__(trace, validation_args['pid'])
548 self.expect["poll_entry"]["big_poll_in"] = 0
549 self.expect["poll_exit"]["big_poll_out"] = 0
550
551 def poll_entry(self, event):
552 nfds = event["nfds"]
553 fds_length = event["fds_length"]
554 overflow = event["overflow"]
555
556 # test of big list of FDs and the behaviour of the overflow
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()
568
569 def poll_exit(self, event):
570 ret = event["ret"]
571 nfds = event["nfds"]
572 fds_length = event["fds_length"]
573 overflow = event["overflow"]
574
575 # test of big list of FDs and the behaviour of the overflow
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
581
582 # Save values of local variables to print in case of test failure
583 self.recorded_values["poll_exit"] = locals()
584
585 class Test5(TraceParser):
586 def __init__(self, trace, validation_args):
587 super().__init__(trace, validation_args['pid'])
588 self.expect["poll_entry"]["poll_overflow_in"] = 0
589 self.expect["poll_exit"]["poll_overflow_out"] = 0
590
591 def poll_entry(self, event):
592 nfds = event["nfds"]
593 fds_length = event["fds_length"]
594 overflow = event["overflow"]
595
596 # test that event in valid even though the target buffer is too small
597 # and the program segfaults
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()
605
606 def poll_exit(self, event):
607 nfds = event["nfds"]
608 overflow = event["overflow"]
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:
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()
617
618
619 class Test6(TraceParser):
620 def __init__(self, trace, validation_args):
621 super().__init__(trace, validation_args['pid'])
622 self.expect["select_entry"]["pselect_invalid_in"] = 0
623 self.expect["select_exit"]["pselect_invalid_out"] = 0
624
625 def select_entry(self, event):
626 n = event["n"]
627 overflow = event["overflow"]
628 _readfds_length = event["_readfds_length"]
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:
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()
637
638 def select_exit(self, event):
639 ret = event["ret"]
640 overflow = event["overflow"]
641 _readfds_length = event["_readfds_length"]
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:
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()
650
651
652 class Test7(TraceParser):
653 def __init__(self, trace, validation_args):
654 super().__init__(trace, validation_args['pid'])
655 self.expect["poll_entry"]["poll_max_in"] = 0
656 self.expect["poll_exit"]["poll_max_out"] = 0
657
658 def poll_entry(self, event):
659 nfds = event["nfds"]
660 overflow = event["overflow"]
661
662 # check the proper working of INT_MAX maxevent value
663 if nfds == 4294967295 and overflow == 1:
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
669
670 def poll_exit(self, event):
671 ret = event["ret"]
672 nfds = event["nfds"]
673 overflow = event["overflow"]
674
675 # check the proper working of UINT_MAX maxevent value
676 if ret == -22 and nfds == 4294967295 and overflow == 0:
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()
681
682
683 class Test8(TraceParser):
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
690 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
691 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
692
693 def epoll_wait_entry(self, event):
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
700 if epfd == self.epoll_fd and maxevents == 1 and timeout == -1:
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()
705
706 def epoll_wait_exit(self, event):
707 ret = event["ret"]
708 fds_length = event["fds_length"]
709 overflow = event["overflow"]
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:
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()
718
719
720 class Test9(TraceParser):
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
727 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 0
728 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 0
729
730 def epoll_wait_entry(self, event):
731 epfd = event["epfd"]
732 maxevents = event["maxevents"]
733 timeout = event["timeout"]
734
735 # check the proper working of INT_MAX maxevent value
736 if epfd == self.epoll_fd and maxevents == 2147483647 and timeout == -1:
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()
741
742 def epoll_wait_exit(self, event):
743 ret = event["ret"]
744 fds_length = event["fds_length"]
745 overflow = event["overflow"]
746
747 # check the proper working of INT_MAX maxevent value
748 if ret == -22 and fds_length == 0 and overflow == 0:
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()
753
754
755 if __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')
759 parser.add_argument('-o', '--validation-file', type=str, help='Validation file path')
760 args = parser.parse_args()
761
762 if not args.test:
763 print("Need to pass a test to validate (--test/-t)")
764 sys.exit(1)
765
766 if not args.validation_file:
767 print("Need to pass the test validation file (--validation-file/-o)")
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
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
782 t = None
783
784 if args.test == 1:
785 t = Test1(traces, test_validation_args)
786 elif args.test == 2:
787 t = Test2(traces, test_validation_args)
788 elif args.test == 3:
789 t = Test3(traces, test_validation_args)
790 elif args.test == 4:
791 t = Test4(traces, test_validation_args)
792 elif args.test == 5:
793 t = Test5(traces, test_validation_args)
794 elif args.test == 6:
795 t = Test6(traces, test_validation_args)
796 elif args.test == 7:
797 t = Test7(traces, test_validation_args)
798 elif args.test == 8:
799 t = Test8(traces, test_validation_args)
800 elif args.test == 9:
801 t = Test9(traces, test_validation_args)
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.047158 seconds and 3 git commands to generate.