Coverage for nurin/network.py: 74%

36 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-02-07 20:24 +0200

1import dataclasses 

2import logging 

3import shlex 

4import subprocess 

5import sys 

6import time 

7 

8log = logging.getLogger(__name__) 

9 

10 

11@dataclasses.dataclass 

12class PingResult: 

13 target: str 

14 count: int 

15 packet_timeout: float 

16 duration: float 

17 success: bool 

18 

19 

20def ping( 

21 ping_target: str, *, packet_timeout: float = 0.5, count: int = 2 

22) -> PingResult: 

23 if sys.platform == "win32": 23 ↛ 24line 23 didn't jump to line 24

24 ping_cmd = [ 

25 "ping", 

26 "/n", 

27 str(count), 

28 # TODO: implement timeout? 

29 ping_target, 

30 ] 

31 elif sys.platform == "linux": 31 ↛ 32line 31 didn't jump to line 32

32 ping_cmd = [ 

33 "ping", 

34 "-c", 

35 str(count), 

36 "-W", 

37 str( 

38 packet_timeout 

39 ), # Time to wait for a response, in seconds. Real number allowed with dot... 

40 ping_target, 

41 ] 

42 elif sys.platform == "darwin": 42 ↛ 54line 42 didn't jump to line 54, because the condition on line 42 was never false

43 ping_cmd = [ 

44 "ping", 

45 "-c", 

46 str(count), 

47 "-W", 

48 str( 

49 packet_timeout * 1000 

50 ), # "Time in milliseconds to wait for a reply for each packet sent." 

51 ping_target, 

52 ] 

53 else: 

54 raise NotImplementedError(f"Unsupported platform: {sys.platform}") 

55 log.debug("Running %s", shlex.join(ping_cmd)) 

56 t0 = time.time() 

57 try: 

58 proc = subprocess.run( 

59 ping_cmd, 

60 stdout=subprocess.PIPE, 

61 stderr=subprocess.STDOUT, 

62 encoding="utf-8", 

63 errors="replace", 

64 timeout=packet_timeout * (count + 2), 

65 ) 

66 except subprocess.TimeoutExpired as te: 

67 t1 = time.time() 

68 success = False 

69 log.warning("Ping timed out; output: %s", te.stdout) 

70 else: 

71 t1 = time.time() 

72 success = proc.returncode == 0 

73 if not success: 73 ↛ 74line 73 didn't jump to line 74, because the condition on line 73 was never true

74 log.warning("Ping failed; output: %s", proc.stdout) 

75 else: 

76 log.debug("Pinging %s succeeded", ping_target) 

77 return PingResult( 

78 count=count, 

79 duration=t1 - t0, 

80 packet_timeout=packet_timeout, 

81 success=success, 

82 target=ping_target, 

83 )