4acd375b3b62198246ec2e6c979f9e992a74b7ac
[tinc] / test / integration / testlib / event.py
1 """Classes for doing data exchange between test and tincd scripts."""
2
3 import os
4 import sys
5 import time
6 import platform
7 import typing as T
8
9 _MONOTONIC_IS_SYSTEMWIDE = not (
10     platform.system() == "Darwin" and sys.version_info < (3, 10)
11 )
12
13
14 def _time_ns() -> int:
15     if sys.version_info <= (3, 7):
16         return int(time.monotonic() * 1e9)
17     return time.monotonic_ns()
18
19
20 class Notification:
21     """Notification about tinc script execution."""
22
23     test: str
24     node: str
25     script: str
26     created_at: T.Optional[int] = None
27     env: T.Dict[str, str]
28     args: T.Dict[str, str]
29     error: T.Optional[Exception]
30
31     def __init__(self) -> None:
32         self.env = dict(os.environ)
33
34         # This field is used to record when the notification was created. On most
35         # operating systems, it uses system-wide monotonic time which is the same
36         # for all processes. Not on macOS, at least not before Python 3.10. So if
37         # we're running such a setup, assign time local to our test process right
38         # when we receive the notification to have a common reference point to
39         # all measurements.
40         if _MONOTONIC_IS_SYSTEMWIDE:
41             self.update_time()
42
43     def update_time(self) -> None:
44         """Update creation time if it was not assigned previously."""
45         if self.created_at is None:
46             self.created_at = _time_ns()