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