Coverage for nurin/run.py: 56%
45 statements
« prev ^ index » next coverage.py v7.1.0, created at 2023-02-07 20:24 +0200
« 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
6from nurin.helpers import jittered_sleep
7from nurin.models import Config, State
8from nurin.network import ping
10log = logging.getLogger(__name__)
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
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
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
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)