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