Example #1
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()
Example #2
0
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"
Example #3
0
 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
Example #4
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()
Example #5
0
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()
Example #6
0
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()
Example #7
0
 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'])
Example #8
0
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