def start(self, *args, **kwargs): """ Start the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if self.started: return self.started = True self.start_count += 1 if self.start_count != self.stop_count + 1: raise AssertionError( 'Start/stop count mismatch during start()') self.watcher = ProcRunner(self.cmd, shell=self.shell, spawn_hooks=self.spawn_hooks, respawn=self.respawn) self.watcher.start()
def run_procedure(): name = request.get_json()['name'] file_name = "weber/data/procedures/" file_name += sanitize_filename(name, file_ending=".json") proc = json.load(open(file_name, 'r')) assert proc['name'] == name assert not proc['items'] == [] app.runner = ProcRunner(proc['items']) return "True"
def test_it_can_run_steps(self): items = [{ "type": "binary", "name": "hlt", "state": 0, "icon": "camera", "stateVerbage": { "1": "open", "0": "closed" }, "method": "hlt", "position": "0", "class": "Controller", "prettyName": "HLT Valve", "value": 0 }] self.runner = ProcRunner(items) self.runner.con.hlt(1) assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 1 self.runner.next_step() assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 0
def start(self, *args, **kwargs): """ Start the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if self.started: return self.started = True self.start_count += 1 if self.start_count != self.stop_count + 1: raise AssertionError('Start/stop count mismatch during start()') self.watcher = ProcRunner(self.cmd, shell=self.shell, spawn_hooks=self.spawn_hooks, respawn=self.respawn) self.watcher.start()
class ProcController(BaseController): """ The purpose of ProcController is to start and stop ProcRunners with guarantees of thread safety and no waifs. """ def __init__(self, cmd, shell=False, spawn_hooks=[], respawn=True): """ respawn handles whether or not the application shall be automatically respawned at all, default is True. """ self.lock = threading.Lock() self.cmd = cmd self.shell = shell self.started = False self.watcher = None self.spawn_hooks = spawn_hooks self.respawn = respawn self.start_count = 0 self.stop_count = 0 def start(self, *args, **kwargs): """ Start the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if self.started: return self.started = True self.start_count += 1 if self.start_count != self.stop_count + 1: raise AssertionError('Start/stop count mismatch during start()') self.watcher = ProcRunner(self.cmd, shell=self.shell, spawn_hooks=self.spawn_hooks, respawn=self.respawn) self.watcher.start() def stop(self, *args, **kwargs): """ Stop the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if not self.started: return self.started = False self.stop_count += 1 if self.stop_count != self.start_count: raise AssertionError('Start/stop count mismatch during stop()') self.watcher.shutdown() self.watcher = None def close(self): """ End the process immediately without blocking. """ try: self.watcher.shutdown() except AttributeError: pass finally: self.spawn_hooks = self.watcher = None def __del__(self): self.close() def add_spawn_hook(self, spawn_hook): """ Adds a spawn hook to the current list of spawn hooks If there is already a watcher, also calls down to that object to add the new spawn hook as well """ self.spawn_hooks.append(spawn_hook) if self.watcher: self.watcher.add_spawn_hook(spawn_hook) def get_pid(self): """ Return process id, or 0 to signify error """ if self.watcher: return self.watcher.get_pid() return None def handle_soft_relaunch(self, *args, **kwargs): self.watcher.handle_soft_relaunch()
class ProcController(BaseController): """ The purpose of ProcController is to start and stop ProcRunners with guarantees of thread safety and no waifs. """ def __init__(self, cmd, shell=False, spawn_hooks=[], respawn=True): """ respawn handles whether or not the application shall be automatically respawned at all, default is True. """ self.lock = threading.Lock() self.cmd = cmd self.shell = shell self.started = False self.watcher = None self.spawn_hooks = spawn_hooks self.respawn = respawn self.start_count = 0 self.stop_count = 0 def start(self, *args, **kwargs): """ Start the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if self.started: return self.started = True self.start_count += 1 if self.start_count != self.stop_count + 1: raise AssertionError( 'Start/stop count mismatch during start()') self.watcher = ProcRunner(self.cmd, shell=self.shell, spawn_hooks=self.spawn_hooks, respawn=self.respawn) self.watcher.start() def stop(self, *args, **kwargs): """ Stop the process. This method is thread-safe and can be called redundantly without error or effect. """ with self.lock: if not self.started: return self.started = False self.stop_count += 1 if self.stop_count != self.start_count: raise AssertionError('Start/stop count mismatch during stop()') self.watcher.shutdown() self.watcher = None def close(self): """ End the process immediately without blocking. """ try: self.watcher.shutdown() except AttributeError: pass finally: self.spawn_hooks = self.watcher = None def __del__(self): self.close() def add_spawn_hook(self, spawn_hook): """ Adds a spawn hook to the current list of spawn hooks If there is already a watcher, also calls down to that object to add the new spawn hook as well """ self.spawn_hooks.append(spawn_hook) if self.watcher: self.watcher.add_spawn_hook(spawn_hook) def get_pid(self): """ Return process id, or 0 to signify error """ if self.watcher: return self.watcher.get_pid() return None def handle_soft_relaunch(self, *args, **kwargs): self.watcher.handle_soft_relaunch()
def setUp(self): proc_file_name = os.path.dirname(os.path.abspath(__file__)) proc_file_name += '/data/procedures/testingprocedure.json' proc = json.load(open(proc_file_name, 'r')) self.runner = ProcRunner(proc['items'])
class TestProcRunner(unittest.TestCase): def setUp(self): proc_file_name = os.path.dirname(os.path.abspath(__file__)) proc_file_name += '/data/procedures/testingprocedure.json' proc = json.load(open(proc_file_name, 'r')) self.runner = ProcRunner(proc['items']) def test_it_pops_off_a_step_when_it_runs_it(self): old_len = len(self.runner.proc) assert old_len > 2 self.runner.next_step() assert len(self.runner.proc) == (old_len - 1) def test_assert_see_con_changes(self): assert isinstance(self.runner.con, (FakeController, Controller)) self.runner.con.hlt(0) # So many nested modules... I do apologize # Gets the relay status of the hlt assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 0 self.runner.con.hlt(1) assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 1 self.runner.con.pid(1) assert self.runner.con.pid_status()['pid_running'] self.runner.con.pid(0) assert not self.runner.con.pid_status()['pid_running'] def test_it_can_run_steps(self): items = [{ "type": "binary", "name": "hlt", "state": 0, "icon": "camera", "stateVerbage": { "1": "open", "0": "closed" }, "method": "hlt", "position": "0", "class": "Controller", "prettyName": "HLT Valve", "value": 0 }] self.runner = ProcRunner(items) self.runner.con.hlt(1) assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 1 self.runner.next_step() assert self.runner.con.relay_status( self.runner.con.settings.relays['hlt']) == 0 def test_full_proc(self): for i in range(len(self.runner.proc)): self.runner.next_step() def test_find_args(self): # This is the only relevant info item = {'type': 'binary', 'name': 'hlt', 'value': 1} assert self.runner.find_args(item) == item['value'] item = {'type': 'binary', 'name': 'hlt', 'value': '1'} assert self.runner.find_args(item) == 1 assert not self.runner.find_args(item) == '1' item = {'type': 'divert', 'name': 'rimsDivert', 'value': 1} assert self.runner.find_args(item) == 'boil' item = {'type': 'method', 'name': 'watch'} assert self.runner.find_args(item) == None item = {'type': 'method', 'name': 'slack', 'value': 790} assert self.runner.find_args(item) == '790' assert not self.runner.find_args(item) == 790 item = {'type': 'method', 'name': 'sleep', 'value': "14"} assert not self.runner.find_args(item) == "14" item = {'type': 'method', 'name': 'watch', 'value': None} assert self.runner.find_args(item) == None @pytest.mark.thisone def test_find_method(self): assert True