Tests: select_poll_epoll: Add support for _time64
[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
d40c2620 12import json
4c4634e3
FD
13
14from collections import defaultdict
a0b1f42c 15
a0b1f42c 16try:
53f8be7a 17 import bt2
a0b1f42c
JD
18except 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))
53f8be7a 22 import bt2
a0b1f42c 23
53f8be7a 24NSEC_PER_SEC = 1000000000
a0b1f42c
JD
25
26class TraceParser:
53f8be7a
FD
27 def __init__(self, trace_msg_iter, pid):
28 self.trace = trace_msg_iter
a0b1f42c 29 self.pid = pid
4c4634e3
FD
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 = {}
a0b1f42c
JD
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
53f8be7a
FD
54 for msg in self.trace:
55 if type(msg) is not bt2._EventMessageConst:
a0b1f42c
JD
56 continue
57
53f8be7a
FD
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(
a0b1f42c
JD
62 "+", "_")
63 # call the function to handle each event individually
64 if hasattr(TraceParser, method_name):
65 func = getattr(TraceParser, method_name)
53f8be7a 66 func(self, msg.event)
a0b1f42c
JD
67
68 ret = 0
4c4634e3
FD
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
a0b1f42c
JD
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):
d40c2620 114 self.epoll_pwait_entry(event)
a0b1f42c
JD
115
116 def handle_compat_syscall_exit_epoll_pwait(self, event):
d40c2620 117 self.epoll_pwait_exit(event)
a0b1f42c
JD
118
119 def handle_syscall_entry_epoll_pwait(self, event):
d40c2620 120 self.epoll_pwait_entry(event)
a0b1f42c
JD
121
122 def handle_syscall_exit_epoll_pwait(self, event):
d40c2620 123 self.epoll_pwait_exit(event)
a0b1f42c
JD
124
125 def epoll_wait_entry(self, event):
126 pass
127
128 def epoll_wait_exit(self, event):
129 pass
130
d40c2620
JG
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
a0b1f42c
JD
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
2a2ac572 231class WorkingCases(TraceParser):
d40c2620
JG
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
4c4634e3
FD
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
d40c2620
JG
249 self.expect["epoll_pwait_entry"]["epoll_pwait_in_ok"] = 0
250 self.expect["epoll_pwait_exit"]["epoll_pwait_out_fd0"] = 0
a0b1f42c
JD
251
252 def select_entry(self, event):
a0b1f42c
JD
253 n = event["n"]
254 overflow = event["overflow"]
4c4634e3 255 readfd_0 = event["readfds"][0]
a0b1f42c
JD
256
257 # check that the FD 0 is actually set in the readfds
4c4634e3
FD
258 if n == 1 and readfd_0 == 1:
259 self.expect["select_entry"]["select_in_fd0"] = 1
a0b1f42c 260 if n == 1023:
4c4634e3
FD
261 readfd_127 = event["readfds"][127]
262 writefd_127 = event["writefds"][127]
263 exceptfd_127 = event["exceptfds"][127]
264
a0b1f42c 265 # check that the FD 1023 is actually set in the readfds
4c4634e3
FD
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()
a0b1f42c
JD
272
273 def select_exit(self, event):
a0b1f42c 274 ret = event["ret"]
a0b1f42c 275 tvp = event["tvp"]
4c4634e3 276 overflow = event["overflow"]
a0b1f42c 277 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
278
279 if ret == 1:
280 # check that the FD 0 is actually set in the readfds
4c4634e3
FD
281 readfd_0 = event["readfds"][0]
282
283 if readfd_0 == 1:
284 self.expect["select_exit"]["select_out_fd0"] = 1
a0b1f42c 285 # check that the FD 1023 is actually set in the readfds
4c4634e3
FD
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()
a0b1f42c
JD
296
297 def poll_entry(self, event):
a0b1f42c
JD
298 nfds = event["nfds"]
299 fds_length = event["fds_length"]
300 overflow = event["overflow"]
a0b1f42c
JD
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.
4c4634e3
FD
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()
a0b1f42c
JD
312
313 def poll_exit(self, event):
a0b1f42c 314 ret = event["ret"]
a0b1f42c 315 fds_length = event["fds_length"]
a0b1f42c
JD
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.
4c4634e3
FD
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()
a0b1f42c
JD
327
328 def epoll_ctl_entry(self, event):
a0b1f42c
JD
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
d40c2620 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 \
a0b1f42c
JD
337 _event["data_union"]["fd"] == 0 and \
338 _event["events"]["EPOLLIN"] == 1 and \
339 _event["events"]["EPOLLPRI"] == 1:
4c4634e3
FD
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()
a0b1f42c
JD
344
345 def epoll_ctl_exit(self, event):
a0b1f42c
JD
346 ret = event["ret"]
347
348 if ret == 0:
4c4634e3
FD
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()
a0b1f42c
JD
353
354 def epoll_wait_entry(self, event):
a0b1f42c
JD
355 epfd = event["epfd"]
356 maxevents = event["maxevents"]
357 timeout = event["timeout"]
358
d40c2620 359 if epfd == self.epoll_wait_fd and maxevents == 1 and timeout == -1:
4c4634e3
FD
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()
a0b1f42c
JD
364
365 def epoll_wait_exit(self, event):
a0b1f42c
JD
366 ret = event["ret"]
367 fds_length = event["fds_length"]
368 overflow = event["overflow"]
a0b1f42c
JD
369
370 # check that FD 0 returned with EPOLLIN and the right data.fd
4c4634e3
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()
a0b1f42c 379
d40c2620
JG
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()
a0b1f42c 405
2a2ac572 406class WorkingCasesTimeout(TraceParser):
d40c2620
JG
407 def __init__(self, trace, validation_args):
408 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
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
a0b1f42c
JD
418
419 def select_entry(self, event):
a0b1f42c 420 n = event["n"]
a0b1f42c 421 tvp = event["tvp"]
a0b1f42c
JD
422
423 if n == 1 and tvp != 0:
4c4634e3 424 self.expect["select_entry"]["select_timeout_in_fd0"] = 1
a0b1f42c 425 if n == 1023:
4c4634e3
FD
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()
a0b1f42c
JD
436
437 def select_exit(self, event):
a0b1f42c 438 ret = event["ret"]
a0b1f42c 439 tvp = event["tvp"]
a0b1f42c
JD
440
441 if ret == 0 and tvp != 0:
4c4634e3
FD
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()
a0b1f42c
JD
446
447 def poll_entry(self, event):
a0b1f42c
JD
448 nfds = event["nfds"]
449 fds_length = event["fds_length"]
a0b1f42c
JD
450
451 # check that we wait on FD 0 for POLLIN and that the raw_events
452 # field matches the value of POLLIN
4c4634e3
FD
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()
a0b1f42c
JD
462
463 def poll_exit(self, event):
a0b1f42c
JD
464 ret = event["ret"]
465 nfds = event["nfds"]
466 fds_length = event["fds_length"]
a0b1f42c
JD
467
468 if ret == 0 and nfds == 1 and fds_length == 0:
4c4634e3
FD
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()
a0b1f42c
JD
473
474 def epoll_ctl_entry(self, event):
a0b1f42c 475 op_enum = event["op_enum"]
a0b1f42c
JD
476 _event = event["event"]
477
478 # make sure we see a EPOLLIN|EPOLLPRI
53f8be7a 479 if 'EPOLL_CTL_ADD' in op_enum.labels and \
a0b1f42c
JD
480 _event["events"]["EPOLLIN"] == 1 and \
481 _event["events"]["EPOLLPRI"] == 1:
4c4634e3
FD
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()
a0b1f42c
JD
486
487 def epoll_ctl_exit(self, event):
a0b1f42c
JD
488 ret = event["ret"]
489
490 if ret == 0:
4c4634e3
FD
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()
a0b1f42c
JD
495
496 def epoll_wait_entry(self, event):
a0b1f42c
JD
497 maxevents = event["maxevents"]
498 timeout = event["timeout"]
499
500 if maxevents == 1 and timeout == 1:
4c4634e3
FD
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()
a0b1f42c
JD
505
506 def epoll_wait_exit(self, event):
a0b1f42c
JD
507 ret = event["ret"]
508 fds_length = event["fds_length"]
509 overflow = event["overflow"]
a0b1f42c
JD
510
511 if ret == 0 and fds_length == 0 and overflow == 0:
4c4634e3
FD
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()
a0b1f42c
JD
516
517
2a2ac572 518class PselectInvalidFd(TraceParser):
d40c2620
JG
519 def __init__(self, trace, validation_args):
520 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
521 self.expect["select_entry"]["select_invalid_fd_in"] = 0
522 self.expect["select_exit"]["select_invalid_fd_out"] = 0
a0b1f42c
JD
523
524 def select_entry(self, event):
a0b1f42c
JD
525 n = event["n"]
526 overflow = event["overflow"]
a0b1f42c 527
8b3b99e2 528 if n > 0 and overflow == 0:
4c4634e3
FD
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()
a0b1f42c
JD
533
534 def select_exit(self, event):
a0b1f42c
JD
535 ret = event["ret"]
536 overflow = event["overflow"]
a0b1f42c 537 _readfds_length = event["_readfds_length"]
a0b1f42c 538
8b3b99e2 539 # make sure the event has a ret field equal to -EBADF
a0b1f42c 540 if ret == -9 and overflow == 0 and _readfds_length == 0:
4c4634e3
FD
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()
a0b1f42c
JD
545
546
2a2ac572 547class PpollBig(TraceParser):
d40c2620
JG
548 def __init__(self, trace, validation_args):
549 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
550 self.expect["poll_entry"]["big_poll_in"] = 0
551 self.expect["poll_exit"]["big_poll_out"] = 0
a0b1f42c
JD
552
553 def poll_entry(self, event):
a0b1f42c
JD
554 nfds = event["nfds"]
555 fds_length = event["fds_length"]
556 overflow = event["overflow"]
a0b1f42c
JD
557
558 # test of big list of FDs and the behaviour of the overflow
4c4634e3
FD
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()
a0b1f42c
JD
570
571 def poll_exit(self, event):
a0b1f42c
JD
572 ret = event["ret"]
573 nfds = event["nfds"]
574 fds_length = event["fds_length"]
575 overflow = event["overflow"]
a0b1f42c
JD
576
577 # test of big list of FDs and the behaviour of the overflow
4c4634e3
FD
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
a0b1f42c 583
4c4634e3
FD
584 # Save values of local variables to print in case of test failure
585 self.recorded_values["poll_exit"] = locals()
a0b1f42c 586
2a2ac572 587class PpollFdsBufferOverflow(TraceParser):
d40c2620
JG
588 def __init__(self, trace, validation_args):
589 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
590 self.expect["poll_entry"]["poll_overflow_in"] = 0
591 self.expect["poll_exit"]["poll_overflow_out"] = 0
a0b1f42c
JD
592
593 def poll_entry(self, event):
a0b1f42c
JD
594 nfds = event["nfds"]
595 fds_length = event["fds_length"]
596 overflow = event["overflow"]
a0b1f42c
JD
597
598 # test that event in valid even though the target buffer is too small
599 # and the program segfaults
4c4634e3
FD
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()
a0b1f42c
JD
607
608 def poll_exit(self, event):
a0b1f42c 609 nfds = event["nfds"]
a0b1f42c 610 overflow = event["overflow"]
a0b1f42c
JD
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:
4c4634e3
FD
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()
a0b1f42c
JD
619
620
2a2ac572 621class PselectInvalidPointer(TraceParser):
d40c2620
JG
622 def __init__(self, trace, validation_args):
623 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
624 self.expect["select_entry"]["pselect_invalid_in"] = 0
625 self.expect["select_exit"]["pselect_invalid_out"] = 0
a0b1f42c
JD
626
627 def select_entry(self, event):
a0b1f42c
JD
628 n = event["n"]
629 overflow = event["overflow"]
a0b1f42c 630 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
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:
4c4634e3
FD
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()
a0b1f42c
JD
639
640 def select_exit(self, event):
a0b1f42c
JD
641 ret = event["ret"]
642 overflow = event["overflow"]
a0b1f42c 643 _readfds_length = event["_readfds_length"]
a0b1f42c
JD
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:
4c4634e3
FD
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()
a0b1f42c
JD
652
653
2a2ac572 654class PpollFdsULongMax(TraceParser):
d40c2620
JG
655 def __init__(self, trace, validation_args):
656 super().__init__(trace, validation_args['pid'])
4c4634e3
FD
657 self.expect["poll_entry"]["poll_max_in"] = 0
658 self.expect["poll_exit"]["poll_max_out"] = 0
a0b1f42c
JD
659
660 def poll_entry(self, event):
a0b1f42c 661 nfds = event["nfds"]
a0b1f42c 662 overflow = event["overflow"]
a0b1f42c
JD
663
664 # check the proper working of INT_MAX maxevent value
665 if nfds == 4294967295 and overflow == 1:
4c4634e3
FD
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
a0b1f42c
JD
671
672 def poll_exit(self, event):
a0b1f42c
JD
673 ret = event["ret"]
674 nfds = event["nfds"]
a0b1f42c 675 overflow = event["overflow"]
a0b1f42c
JD
676
677 # check the proper working of UINT_MAX maxevent value
678 if ret == -22 and nfds == 4294967295 and overflow == 0:
4c4634e3
FD
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()
a0b1f42c
JD
683
684
2a2ac572 685class EpollPwaitInvalidPointer(TraceParser):
d40c2620
JG
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
4c4634e3
FD
692 self.expect["epoll_wait_entry"]["epoll_wait_invalid_in"] = 0
693 self.expect["epoll_wait_exit"]["epoll_wait_invalid_out"] = 0
a0b1f42c
JD
694
695 def epoll_wait_entry(self, event):
a0b1f42c
JD
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
d40c2620 702 if epfd == self.epoll_fd and maxevents == 1 and timeout == -1:
4c4634e3
FD
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()
a0b1f42c
JD
707
708 def epoll_wait_exit(self, event):
a0b1f42c
JD
709 ret = event["ret"]
710 fds_length = event["fds_length"]
711 overflow = event["overflow"]
a0b1f42c
JD
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:
4c4634e3
FD
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()
a0b1f42c
JD
720
721
2a2ac572 722class EpollPwaitIntMax(TraceParser):
d40c2620
JG
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
4c4634e3
FD
729 self.expect["epoll_wait_entry"]["epoll_wait_max_in"] = 0
730 self.expect["epoll_wait_exit"]["epoll_wait_max_out"] = 0
a0b1f42c
JD
731
732 def epoll_wait_entry(self, event):
a0b1f42c
JD
733 epfd = event["epfd"]
734 maxevents = event["maxevents"]
735 timeout = event["timeout"]
736
737 # check the proper working of INT_MAX maxevent value
d40c2620 738 if epfd == self.epoll_fd and maxevents == 2147483647 and timeout == -1:
4c4634e3
FD
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()
a0b1f42c
JD
743
744 def epoll_wait_exit(self, event):
a0b1f42c
JD
745 ret = event["ret"]
746 fds_length = event["fds_length"]
747 overflow = event["overflow"]
a0b1f42c
JD
748
749 # check the proper working of INT_MAX maxevent value
750 if ret == -22 and fds_length == 0 and overflow == 0:
4c4634e3
FD
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()
a0b1f42c
JD
755
756
757if __name__ == "__main__":
758 parser = argparse.ArgumentParser(description='Trace parser')
759 parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
2a2ac572 760 parser.add_argument('-t', '--test', type=str, help='Test to validate')
d40c2620 761 parser.add_argument('-o', '--validation-file', type=str, help='Validation file path')
a0b1f42c
JD
762 args = parser.parse_args()
763
764 if not args.test:
d40c2620 765 print("Need to pass a test to validate (--test/-t)")
a0b1f42c
JD
766 sys.exit(1)
767
d40c2620
JG
768 if not args.validation_file:
769 print("Need to pass the test validation file (--validation-file/-o)")
a0b1f42c
JD
770 sys.exit(1)
771
53f8be7a 772 traces = bt2.TraceCollectionMessageIterator(args.path)
a0b1f42c 773
d40c2620
JG
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
a0b1f42c
JD
781 t = None
782
2a2ac572
JG
783 if args.test == "working_cases":
784 t = WorkingCases(traces, test_validation_args)
785 elif args.test == "working_cases_timeout":
786 t = WorkingCasesTimeout(traces, test_validation_args)
787 elif args.test == "pselect_invalid_fd":
788 t = PselectInvalidFd(traces, test_validation_args)
789 elif args.test == "ppoll_big":
790 t = PpollBig(traces, test_validation_args)
791 elif args.test == "ppoll_fds_buffer_overflow":
792 t = PpollFdsBufferOverflow(traces, test_validation_args)
793 elif args.test == "pselect_invalid_pointer":
794 t = PselectInvalidPointer(traces, test_validation_args)
795 elif args.test == "ppoll_fds_ulong_max":
796 t = PpollFdsULongMax(traces, test_validation_args)
797 elif args.test == "epoll_pwait_invalid_pointer":
798 t = EpollPwaitInvalidPointer(traces, test_validation_args)
799 elif args.test == "epoll_pwait_int_max":
800 t = EpollPwaitIntMax(traces, test_validation_args)
801 elif args.test == "ppoll_concurrent_write":
a0b1f42c
JD
802 # stress test, nothing reliable to check
803 ret = 0
2a2ac572 804 elif args.test == "epoll_pwait_concurrent_munmap":
a0b1f42c
JD
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
a0b1f42c 814 sys.exit(ret)
This page took 0.078553 seconds and 4 git commands to generate.