Coverage for nurin/run.py: 56%

45 statements  

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

1import logging 

2import random 

3import subprocess 

4from typing import Callable 

5 

6from nurin.helpers import jittered_sleep 

7from nurin.models import Config, State 

8from nurin.network import ping 

9 

10log = logging.getLogger(__name__) 

11 

12 

13def default_keep_checking(config: Config, state: State) -> bool: 

14 if not config.max_cycles: 14 ↛ 15line 14 didn't jump to line 15, because the condition on line 14 was never true

15 return True 

16 return state.cycles < config.max_cycles 

17 

18 

19def run( 

20 config: Config, 

21 keep_checking: Callable[[Config, State], bool] = default_keep_checking, 

22) -> None: 

23 state = State() 

24 while keep_checking(config, state): 

25 state.cycles += 1 

26 check_success = run_check_cycle(config, state) 

27 if check_success and state.up_actions_primed: 27 ↛ 28line 27 didn't jump to line 28, because the condition on line 27 was never true

28 state.up_actions_primed = False 

29 log.info("Up again! Running up actions.") 

30 run_action_list(config.up_actions) 

31 if state.down_check_counter >= config.down_count: 31 ↛ 32line 31 didn't jump to line 32, because the condition on line 31 was never true

32 log.info( 

33 "Counter reached %d/%d, running down actions", 

34 state.down_check_counter, 

35 config.down_count, 

36 ) 

37 run_action_list(config.down_actions) 

38 if config.reset_after_down_action: 

39 state.down_check_counter = 0 

40 state.up_actions_primed = True 

41 

42 

43def run_check_cycle(config: Config, state: State) -> bool: 

44 check_interval = ( 

45 config.down_check_interval 

46 if state.down_check_counter > 0 

47 else config.regular_check_interval 

48 ) 

49 jittered_sleep(check_interval, config.sleep_jitter) 

50 result = ping(random.choice(config.ping_targets)) 

51 if not result.success: 51 ↛ 52line 51 didn't jump to line 52, because the condition on line 51 was never true

52 state.down_check_counter += 1 

53 log.info( 

54 "Ping failed to %s, counter %d", 

55 result.target, 

56 state.down_check_counter, 

57 ) 

58 else: 

59 if state.down_check_counter: 59 ↛ 60line 59 didn't jump to line 60, because the condition on line 59 was never true

60 log.info( 

61 "Ping succeeded to %s; counter had been %d", 

62 result.target, 

63 state.down_check_counter, 

64 ) 

65 state.down_check_counter = 0 

66 return result.success 

67 

68 

69def run_action_list(action_list: list[str]) -> None: 

70 for i, action in enumerate(action_list, 1): 

71 log.info( 

72 "Running action %d/%d: %s", 

73 i, 

74 len(action_list), 

75 action, 

76 ) 

77 try: 

78 subprocess.run(action, shell=True, check=True) 

79 except subprocess.CalledProcessError as e: 

80 log.error("Action failed with code %d", e.returncode)