Пример #1
0
 def test_set_value(self):
     value = "test_value"
     a = Attribute("test", Mock())
     a.on_changed = Mock(a.on_changed)
     a.set_value(value)
     self.assertEquals("test_value", a.value)
     a.on_changed.assert_called_once_with([['value'], value])
Пример #2
0
 def test_set_value(self):
     value = "test_value"
     a = Attribute(self.meta)
     a.on_changed = Mock(wrap=a.on_changed)
     a.set_value(value)
     self.assertEquals(a.value, value)
     a.on_changed.assert_called_once_with([['value'], value], True)
Пример #3
0
 def test_put(self):
     func = Mock()
     value = "test_value"
     a = Attribute("test", Mock())
     a.set_put_function(func)
     a.put(value)
     func.assert_called_once_with(value)
Пример #4
0
 def test_set_value(self):
     value = "test_value"
     a = Attribute("test", Mock())
     a.on_changed = Mock(a.on_changed)
     a.set_value(value)
     self.assertEquals("test_value", a.value)
     a.on_changed.assert_called_once_with([['value'], value])
Пример #5
0
class TestAttribute(unittest.TestCase):
    def setUp(self):
        self.data = NTScalar(StringMeta())
        self.data.set_notifier_path(Mock(), ["block", "attr"])
        self.controller = Mock()
        self.context = Mock()
        self.o = Attribute(self.controller, self.context, self.data)

    def test_init(self):
        self.assertIsInstance(self.o, Attribute)
        assert hasattr(self.o, "meta")
        assert hasattr(self.o, "subscribe_meta")
        assert hasattr(self.o, "value")
        assert hasattr(self.o, "subscribe_value")

    def test_put(self):
        self.o.put_value(32)
        self.context.put.assert_called_once_with(["block", "attr", "value"],
                                                 32,
                                                 timeout=None)

    def test_put_async(self):
        f = self.o.put_value_async(32)
        self.context.put_async.assert_called_once_with(
            ["block", "attr", "value"], 32)
        assert f == self.context.put_async.return_value

    def test_repr(self):
        self.controller.make_view.return_value = "foo"
        assert repr(self.o) == "<Attribute value='foo'>"
        self.controller.make_view.assert_called_once_with(
            self.context, self.o, "value")
Пример #6
0
 def test_to_dict(self):
     meta = Mock()
     meta.to_dict = Mock(return_value={"test_meta": "dict"})
     expected = OrderedDict()
     expected["value"] = "test_value"
     expected["meta"] = {"test_meta": "dict"}
     a = Attribute("test", meta)
     a.set_value("test_value")
     self.assertEquals(expected, a.to_dict())
Пример #7
0
 def test_to_dict(self):
     meta = Mock()
     meta.to_dict = Mock(return_value = {"test_meta":"dict"})
     expected = OrderedDict()
     expected["value"] = "test_value"
     expected["meta"] = {"test_meta":"dict"}
     a = Attribute("test", meta)
     a.set_value("test_value")
     self.assertEquals(expected, a.to_dict())
Пример #8
0
 def create_process_block(self):
     self.process_block = Block()
     a = Attribute(
         StringArrayMeta(description="Blocks hosted by this Process"))
     self.process_block.add_attribute("blocks", a)
     a = Attribute(
         StringArrayMeta(description="Blocks reachable via ClientComms"))
     self.process_block.add_attribute("remoteBlocks", a)
     self.add_block(self.name, self.process_block)
Пример #9
0
 def _create_default_attributes(self):
     self.state = Attribute(ChoiceMeta(description="State of Block",
                         choices=self.stateMachine.possible_states))
     self.state.set_parent(self.block,'state')
     self.state.set_value(self.stateMachine.DISABLED)
     yield ('state', self.state)
     self.status = Attribute(StringMeta(description="Status of Block"))
     self.status.set_value("Disabled")
     yield ('status', self.status)
     self.busy = Attribute(BooleanMeta(
         description="Whether Block busy or not"))
     self.busy.set_value(False)
     yield ('busy', self.busy)
Пример #10
0
 def setUp(self):
     self.callback_result = 0
     self.callback_value = ''
     meta = VMeta("meta for unit tests")
     self.block = MagicMock()
     self.proc = MagicMock(q=queue.Queue())
     self.proc.create_queue = MagicMock(side_effect=queue.Queue)
     self.attr = Attribute(meta)
     self.attr.set_parent(self.block, "testAttr")
     self.attr2 = Attribute(meta)
     self.attr2.set_parent(self.block, "testAttr2")
     self.method = Method("method for unit tests")
     self.method.set_parent(self.block, "testFunc")
     self.method2 = Method("method for unit tests")
     self.method2.set_parent(self.block, "testFunc")
     self.bad_called_back = False
Пример #11
0
 def setUp(self):
     self.callback_result = 0
     self.callback_value = ''
     meta = VMeta("meta for unit tests")
     self.block = MagicMock()
     self.proc = MagicMock(q=queue.Queue())
     self.proc.create_queue = MagicMock(side_effect=queue.Queue)
     self.attr = Attribute(meta)
     self.attr.set_parent(self.block, "testAttr")
     self.attr2 = Attribute(meta)
     self.attr2.set_parent(self.block, "testAttr2")
     self.method = Method("method for unit tests")
     self.method.set_parent(self.block, "testFunc")
     self.method2 = Method("method for unit tests")
     self.method2.set_parent(self.block, "testFunc")
     self.bad_called_back = False
Пример #12
0
 def test_from_dict(self, am_from_dict):
     meta = Mock()
     am_from_dict.return_value = meta
     d = {"value":"test_value", "meta":{"meta":"dict"}}
     a = Attribute.from_dict("test", d)
     self.assertEquals("test", a.name)
     self.assertEquals("test_value", a.value)
     self.assertIs(meta, a.meta)
Пример #13
0
 def test_from_dict(self, am_from_dict):
     meta = Mock()
     am_from_dict.return_value = meta
     d = {"value": "test_value", "meta": {"meta": "dict"}}
     a = Attribute.from_dict("test", d)
     self.assertEquals("test", a.name)
     self.assertEquals("test_value", a.value)
     self.assertIs(meta, a.meta)
Пример #14
0
 def test_put(self):
     func = Mock()
     value = "test_value"
     a = Attribute("test", Mock())
     a.set_put_function(func)
     a.put(value)
     func.assert_called_once_with(value)
Пример #15
0
 def test_compare_vtables(self):
     a = Attribute(VTable, "Positions")
     a.notify_listeners = MagicMock()
     t1 = [("x", VLong, numpy.arange(5, dtype=numpy.int64), ''), 
           ("y", VLong, numpy.arange(5, dtype=numpy.int64) + 2, 'mm')]
     a.update(t1, None, 1.0)
     a.notify_listeners.assert_called_with(
         dict(value=t1, alarm=Alarm.ok(), timeStamp=1.0))
     a.update(t1, None, 1.0)
     a.notify_listeners.assert_called_with(dict())
     t2 = [("x", VLong, numpy.arange(5, dtype=numpy.int64) + 3, ''),
           ("y", VLong, numpy.arange(5, dtype=numpy.int64) + 2, '')]
     a.update(t2, None, 1.0)
     a.notify_listeners.assert_called_with(dict(value=t2))
Пример #16
0
 def test_replace_children(self):
     b = Block()
     b.name = "blockname"
     b.methods["m1"] = 2
     b.attributes["a1"] = 3
     setattr(b, "m1", 2)
     setattr(b, "a1", 3)
     attr_meta = StringMeta(description="desc")
     attr = Attribute(attr_meta)
     b.add_attribute('attr', attr)
     method = Method(description="desc")
     b.add_method('method', method)
     b.on_changed = MagicMock(wrap=b.on_changed)
     b.replace_children({'attr': attr, 'method': method})
     self.assertEqual(b.attributes, dict(attr=attr))
     self.assertEqual(b.methods, dict(method=method))
     b.on_changed.assert_called_once_with([[], b.to_dict()], True)
     self.assertFalse(hasattr(b, "m1"))
     self.assertFalse(hasattr(b, "a1"))
Пример #17
0
 def _create_default_attributes(self):
     self.state = Attribute(
         ChoiceMeta(description="State of Block",
                    choices=self.stateMachine.possible_states))
     self.state.set_parent(self.block, 'state')
     self.state.set_value(self.stateMachine.DISABLED)
     yield ('state', self.state)
     self.status = Attribute(StringMeta(description="Status of Block"))
     self.status.set_value("Disabled")
     yield ('status', self.status)
     self.busy = Attribute(
         BooleanMeta(description="Whether Block busy or not"))
     self.busy.set_value(False)
     yield ('busy', self.busy)
Пример #18
0
 def test_lists(self):
     a = Attribute(VStringArray, "List of strings")
     a.update(["c", "b"])
     self.assertEqual(a.value, ["c", "b"])
     self.assertRaises(AssertionError, a.update, "c")
Пример #19
0
class Controller(Loggable):
    """Implement the logic that takes a Block through its statemachine"""

    Resetting = Hook()

    def __init__(self, process, block, block_name):
        """
        Args:
            process (Process): The process this should run under
            block (Block): Block instance to add Methods and Attributes to
        """
        process.add_block(block_name, block)
        self.set_logger_name("%s.controller" % block_name)

        # dictionary of dictionaries
        # {state (str): {Method: writeable (bool)}
        self.methods_writeable = {}
        self.process = process
        self.parts = []
        self.block = block
        for name, attribute in self._create_default_attributes():
            block.add_attribute(name, attribute)
        for name, attribute in self.create_attributes():
            block.add_attribute(name, attribute)
        for name, method in self.create_methods():
            block.add_method(name, method)
            # Set if the method is writeable
            if method.only_in is None:
                states = [
                    state for state in self.stateMachine.possible_states
                    if state != sm.DISABLED
                ]
            else:
                states = method.only_in
                for state in states:
                    assert state in self.stateMachine.possible_states, \
                        "State %s is not one of the valid states %s" % \
                        (state, self.stateMachine.possible_states)
            self.set_method_writeable_in(method, states)

    def create_methods(self):
        """Abstract method that should provide Method instances for Block

        Yields:
            Method: Each one will be attached to the Block by calling
            block.add_method(method)
        """

        for name, member in inspect.getmembers(self, inspect.ismethod):
            if hasattr(member, "Method"):
                member.Method.set_function(member)
                yield (name, member.Method)

    def create_attributes(self):
        """Abstract method that should provide Attribute instances for Block

        Yields:
            Attribute: Each one will be attached to the Block by calling
            block.add_attribute(attribute)
        """
        return iter(())

    def _create_default_attributes(self):
        self.state = Attribute(
            ChoiceMeta(description="State of Block",
                       choices=self.stateMachine.possible_states))
        self.state.set_parent(self.block, 'state')
        self.state.set_value(self.stateMachine.DISABLED)
        yield ('state', self.state)
        self.status = Attribute(StringMeta(description="Status of Block"))
        self.status.set_value("Disabled")
        yield ('status', self.status)
        self.busy = Attribute(
            BooleanMeta(description="Whether Block busy or not"))
        self.busy.set_value(False)
        yield ('busy', self.busy)

    @takes()
    @only_in(sm.DISABLED, sm.FAULT)
    def reset(self):
        try:
            self.transition(sm.RESETTING, "Resetting")
            self.Resetting.run(self)
            self.transition(sm.AFTER_RESETTING, "Done resetting")
        except Exception as e:
            self.log_exception("Fault occurred while Resetting")
            self.transition(sm.FAULT, str(e))

    @takes()
    def disable(self):
        self.transition(sm.DISABLED, "Disabled")

    def add_parts(self, parts):
        self.parts.extend(parts)

    def transition(self, state, message):
        """
        Change to a new state if the transition is allowed

        Args:
            state(str): State to transition to
            message(str): Status message
        """

        if self.stateMachine.is_allowed(initial_state=self.state.value,
                                        target_state=state):

            self.state.set_value(state)

            if state in self.stateMachine.busy_states:
                self.busy.set_value(True)
            else:
                self.busy.set_value(False)

            self.status.set_value(message)

            for method in self.block.methods.values():
                writeable = self.methods_writeable[state][method.name]
                method.set_writeable(writeable)

            self.block.notify_subscribers()

        else:
            raise TypeError("Cannot transition from %s to %s" %
                            (self.state.value, state))

    def set_method_writeable_in(self, method, states):
        """
        Set the states that the given method can be called in

        Args:
            method(Method): Method that will be set writeable or not
            states(list[str]): List of states where method is writeable
        """
        for state in self.stateMachine.possible_states:
            writeable_dict = self.methods_writeable.setdefault(state, {})
            is_writeable = state in states
            writeable_dict[method.name] = is_writeable
Пример #20
0
class TestTask(unittest.TestCase):

    def setUp(self):
        self.callback_result = 0
        self.callback_value = ''
        meta = VMeta("meta for unit tests")
        self.block = MagicMock()
        self.proc = MagicMock(q=queue.Queue())
        self.proc.create_queue = MagicMock(side_effect=queue.Queue)
        self.attr = Attribute(meta)
        self.attr.set_parent(self.block, "testAttr")
        self.attr2 = Attribute(meta)
        self.attr2.set_parent(self.block, "testAttr2")
        self.method = Method("method for unit tests")
        self.method.set_parent(self.block, "testFunc")
        self.method2 = Method("method for unit tests")
        self.method2.set_parent(self.block, "testFunc")
        self.bad_called_back = False

    def test_init(self):
        t = Task("testTask", self.proc)
        self.assertIsInstance(t._logger, logging.Logger)
        self.assertIsInstance(t.q, queue.Queue)
        self.assertEqual(t.process, self.proc)

    def test_put_async(self):
        t = Task("testTask", self.proc)
        t.put_async(self.attr, "testValue")
        req = self.proc.q.get(timeout=0)
        self.assertIsInstance(req, Request)
        self.assertEqual(req.endpoint,
                         [self.block.name, 'testAttr', 'value'])
        self.assertEqual(len(t._futures), 1)

        d = {self.attr: "testValue", self.attr2: "testValue2"}
        t.put_async(d)
        self.proc.q.get(timeout=0)
        req2 = self.proc.q.get(timeout=0)
        self.assertEqual(self.proc.q.qsize(), 0)
        self.assertIsInstance(req2, Request)
        self.assertEqual(len(t._futures), 3)

    def test_put(self):
        # single attribute
        t = Task("testTask", self.proc)
        resp = Return(0, None, None)
        resp.set_value('testVal')
        # cheat and add the response before the blocking call to put
        t.q.put(resp)
        t.stop()
        t.put(self.attr, "testValue")
        self.assertEqual(len(t._futures), 0)
        self.assertEqual(self.proc.q.qsize(), 1)

    def test_post(self):
        t = Task("testTask", self.proc)
        resp1 = Return(0, None, None)
        resp1.set_value('testVal')
        resp2 = Error(1, None, None)
        # cheat and add the responses before the blocking call to put
        t.q.put(resp1)
        t.q.put(resp2)
        t.stop()
        t.post(self.method, "testParm")
        t.post(self.method, "testParm2")
        self.assertEqual(len(t._futures), 0)
        self.assertEqual(self.proc.q.qsize(), 2)

    def test_wait_all(self):
        t = Task("testTask", self.proc)
        f1 = Future(t)
        f2 = Future(t)
        f3 = Future(t)
        f0 = Future(t)
        t._futures = {0: f0, 1: f1, 2: f2, 3: f3}
        f_wait1 = [f2, f0]
        self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0)

        resp0 = Return(0, None, None)
        resp0.set_value('testVal')
        resp2 = Error(2, None, None)
        t.q.put(resp0)
        t.q.put(resp2)
        t.wait_all( f_wait1, 0)
        self.assertEqual(t._futures, {1: f1, 3: f3})
        self.assertEqual(f0.done(), True)
        self.assertEqual(f1.done(), False)
        self.assertEqual(f2.done(), True)
        self.assertEqual(f3.done(), False)
        self.assertEqual(self.proc.q.qsize(), 0)

        resp3 = Delta(3, None, None)
        t.q.put(resp3)
        f_wait1 = [f3]
        self.assertRaises(ValueError, t.wait_all, f_wait1, 0.01)
        t.stop()
        self.assertRaises(RuntimeWarning, t.wait_all, f_wait1, 0.01)

        resp1 = Return(1, None, None)
        resp1.set_value('testVal')
        t.q.put(resp1)
        self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0.01)
        self.assertEqual(t._futures, {})

        t._futures = {0: f0, 1: f1, 2: f2}
        t.q.put(resp1)
        t.q.put(Task.TASK_STOP)
        self.assertEqual(f1.result(), 'testVal')

    def test_wait_all_missing_futures(self):
        # unsolicited response
        t = Task("testTask", self.proc)
        f1 = Future(t)
        resp10 = Return(10, None, None)
        t.q.put(resp10)
        t.q.put(Task.TASK_STOP)
        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)

        # same future twice
        f2 = Future(t)
        t._futures = {1: f2}
        resp1 = Return(1, None, None)
        t.q.put(resp1)
        t.q.put(Task.TASK_STOP)
        t.wait_all(f2,0)
        t.wait_all(f2,0)


    def _callback(self, value, a, b):
        self.callback_result = a+b
        self.callback_value = value

    def test_subscribe(self):
        t = Task("testTask", self.proc)
        resp = Update(0, None, None)
        resp.set_value('changedVal')
        t.q.put(resp)
        t.stop()

        new_id = t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}

        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)
        self.assertEqual(self.callback_value, 'changedVal')
        self.assertEqual(self.callback_result, 8)
        t.unsubscribe(new_id)

    def test_callback_error(self):
        t = Task("testTask", self.proc)
        resp = Error(0, None, None)
        resp.set_message('error')
        t.q.put(resp)
        t.stop()

        t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(RuntimeError, t.wait_all, f1, 0)

    def test_callback_unexpected(self):
        t = Task("testTask", self.proc)
        resp = Delta(0, None, None)
        t.q.put(resp)
        t.stop()
        t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(ValueError, t.wait_all, f1, 0)


    def _bad_callback(self, value):
        self.bad_called_back = True
        raise TestWarning()

    def test_callback_crash(self):
        t = Task("testTask", self.proc)
        resp = Update(0, None, None)
        resp.set_value('changedVal')
        t.q.put(resp)
        t.stop()

        t.subscribe(self.attr, self._bad_callback)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)
        self.assertEquals(self.bad_called_back, True)

    def test_when_matches(self):
        t = Task("testTask", self.proc)
        f = t.when_matches(self.attr, "matchTest")

        # match (response goes to the subscription at id 1,
        # not the future at id 0)
        resp = Update(1, None, None)
        resp.set_value('matchTest')
        t.q.put(resp)
        t.stop()
        self.assertEqual(f[0].result(0),'matchTest')

    def test_not_when_matches(self):
        t = Task("testTask", self.proc)
        f = t.when_matches(self.attr, "matchTest")

        # match (response goes to the subscription at id 1,
        # not the future at id 0)
        resp = Update(1, None, None)
        resp.set_value('NOTmatchTest')
        t.q.put(resp)
        t.stop()

        # this will abort the task because f[0] never gets filled
        self.assertRaises(RuntimeWarning, f[0].result)
Пример #21
0
class TestTask(unittest.TestCase):
    def setUp(self):
        self.callback_result = 0
        self.callback_value = ''
        meta = VMeta("meta for unit tests")
        self.block = MagicMock()
        self.proc = MagicMock(q=queue.Queue())
        self.proc.create_queue = MagicMock(side_effect=queue.Queue)
        self.attr = Attribute(meta)
        self.attr.set_parent(self.block, "testAttr")
        self.attr2 = Attribute(meta)
        self.attr2.set_parent(self.block, "testAttr2")
        self.method = Method("method for unit tests")
        self.method.set_parent(self.block, "testFunc")
        self.method2 = Method("method for unit tests")
        self.method2.set_parent(self.block, "testFunc")
        self.bad_called_back = False

    def test_init(self):
        t = Task("testTask", self.proc)
        self.assertIsInstance(t._logger, logging.Logger)
        self.assertIsInstance(t.q, queue.Queue)
        self.assertEqual(t.process, self.proc)

    def test_put_async(self):
        t = Task("testTask", self.proc)
        t.put_async(self.attr, "testValue")
        req = self.proc.q.get(timeout=0)
        self.assertIsInstance(req, Request)
        self.assertEqual(req.endpoint, [self.block.name, 'testAttr', 'value'])
        self.assertEqual(len(t._futures), 1)

        d = {self.attr: "testValue", self.attr2: "testValue2"}
        t.put_async(d)
        self.proc.q.get(timeout=0)
        req2 = self.proc.q.get(timeout=0)
        self.assertEqual(self.proc.q.qsize(), 0)
        self.assertIsInstance(req2, Request)
        self.assertEqual(len(t._futures), 3)

    def test_put(self):
        # single attribute
        t = Task("testTask", self.proc)
        resp = Return(0, None, None)
        resp.set_value('testVal')
        # cheat and add the response before the blocking call to put
        t.q.put(resp)
        t.stop()
        t.put(self.attr, "testValue")
        self.assertEqual(len(t._futures), 0)
        self.assertEqual(self.proc.q.qsize(), 1)

    def test_post(self):
        t = Task("testTask", self.proc)
        resp1 = Return(0, None, None)
        resp1.set_value('testVal')
        resp2 = Error(1, None, None)
        # cheat and add the responses before the blocking call to put
        t.q.put(resp1)
        t.q.put(resp2)
        t.stop()
        t.post(self.method, "testParm")
        t.post(self.method, "testParm2")
        self.assertEqual(len(t._futures), 0)
        self.assertEqual(self.proc.q.qsize(), 2)

    def test_wait_all(self):
        t = Task("testTask", self.proc)
        f1 = Future(t)
        f2 = Future(t)
        f3 = Future(t)
        f0 = Future(t)
        t._futures = {0: f0, 1: f1, 2: f2, 3: f3}
        f_wait1 = [f2, f0]
        self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0)

        resp0 = Return(0, None, None)
        resp0.set_value('testVal')
        resp2 = Error(2, None, None)
        t.q.put(resp0)
        t.q.put(resp2)
        t.wait_all(f_wait1, 0)
        self.assertEqual(t._futures, {1: f1, 3: f3})
        self.assertEqual(f0.done(), True)
        self.assertEqual(f1.done(), False)
        self.assertEqual(f2.done(), True)
        self.assertEqual(f3.done(), False)
        self.assertEqual(self.proc.q.qsize(), 0)

        resp3 = Delta(3, None, None)
        t.q.put(resp3)
        f_wait1 = [f3]
        self.assertRaises(ValueError, t.wait_all, f_wait1, 0.01)
        t.stop()
        self.assertRaises(RuntimeWarning, t.wait_all, f_wait1, 0.01)

        resp1 = Return(1, None, None)
        resp1.set_value('testVal')
        t.q.put(resp1)
        self.assertRaises(queue.Empty, t.wait_all, f_wait1, 0.01)
        self.assertEqual(t._futures, {})

        t._futures = {0: f0, 1: f1, 2: f2}
        t.q.put(resp1)
        t.q.put(Task.TASK_STOP)
        self.assertEqual(f1.result(), 'testVal')

    def test_wait_all_missing_futures(self):
        # unsolicited response
        t = Task("testTask", self.proc)
        f1 = Future(t)
        resp10 = Return(10, None, None)
        t.q.put(resp10)
        t.q.put(Task.TASK_STOP)
        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)

        # same future twice
        f2 = Future(t)
        t._futures = {1: f2}
        resp1 = Return(1, None, None)
        t.q.put(resp1)
        t.q.put(Task.TASK_STOP)
        t.wait_all(f2, 0)
        t.wait_all(f2, 0)

    def _callback(self, value, a, b):
        self.callback_result = a + b
        self.callback_value = value

    def test_subscribe(self):
        t = Task("testTask", self.proc)
        resp = Update(0, None, None)
        resp.set_value('changedVal')
        t.q.put(resp)
        t.stop()

        new_id = t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}

        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)
        self.assertEqual(self.callback_value, 'changedVal')
        self.assertEqual(self.callback_result, 8)
        t.unsubscribe(new_id)

    def test_callback_error(self):
        t = Task("testTask", self.proc)
        resp = Error(0, None, None)
        resp.set_message('error')
        t.q.put(resp)
        t.stop()

        t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(RuntimeError, t.wait_all, f1, 0)

    def test_callback_unexpected(self):
        t = Task("testTask", self.proc)
        resp = Delta(0, None, None)
        t.q.put(resp)
        t.stop()
        t.subscribe(self.attr, self._callback, 3, 5)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(ValueError, t.wait_all, f1, 0)

    def _bad_callback(self, value):
        self.bad_called_back = True
        raise TestWarning()

    def test_callback_crash(self):
        t = Task("testTask", self.proc)
        resp = Update(0, None, None)
        resp.set_value('changedVal')
        t.q.put(resp)
        t.stop()

        t.subscribe(self.attr, self._bad_callback)
        f1 = Future(t)
        t._futures = {1: f1}
        self.assertRaises(RuntimeWarning, t.wait_all, f1, 0)
        self.assertEquals(self.bad_called_back, True)

    def test_when_matches(self):
        t = Task("testTask", self.proc)
        f = t.when_matches(self.attr, "matchTest")

        # match (response goes to the subscription at id 1,
        # not the future at id 0)
        resp = Update(1, None, None)
        resp.set_value('matchTest')
        t.q.put(resp)
        t.stop()
        self.assertEqual(f[0].result(0), 'matchTest')

    def test_not_when_matches(self):
        t = Task("testTask", self.proc)
        f = t.when_matches(self.attr, "matchTest")

        # match (response goes to the subscription at id 1,
        # not the future at id 0)
        resp = Update(1, None, None)
        resp.set_value('NOTmatchTest')
        t.q.put(resp)
        t.stop()

        # this will abort the task because f[0] never gets filled
        self.assertRaises(RuntimeWarning, f[0].result)
Пример #22
0
 def test_init(self):
     a = Attribute(self.meta)
     self.assertIs(self.meta, a.meta)
     self.assertIs(self.meta.parent, a)
     self.assertIsNone(a.value)
     self.assertEquals("epics:nt/NTAttribute:1.0", a.typeid)
Пример #23
0
 def setUp(self):
     self.data = NTScalar(StringMeta())
     self.data.set_notifier_path(Mock(), ["block", "attr"])
     self.controller = Mock()
     self.context = Mock()
     self.o = Attribute(self.controller, self.context, self.data)
Пример #24
0
 def test_to_dict(self):
     a = Attribute(StringMeta("desc"))
     a.set_value("some string")
     self.assertEqual(a.to_dict(), self.serialized)
Пример #25
0
 def test_init(self):
     meta = Mock()
     a = Attribute("test", meta)
     self.assertEquals("test", a.name)
     self.assertIs(meta, a.meta)
     self.assertIsNone(a.value)
Пример #26
0
 def test_set_put_function(self):
     func = Mock()
     a = Attribute("test", Mock())
     a.set_put_function(func)
     self.assertIs(func, a.put_func)
Пример #27
0
class Controller(Loggable):
    """Implement the logic that takes a Block through its statemachine"""

    Resetting = Hook()

    def __init__(self, process, block, block_name):
        """
        Args:
            process (Process): The process this should run under
            block (Block): Block instance to add Methods and Attributes to
        """
        process.add_block(block_name, block)
        self.set_logger_name("%s.controller" % block_name)

        # dictionary of dictionaries
        # {state (str): {Method: writeable (bool)}
        self.methods_writeable = {}
        self.process = process
        self.parts = []
        self.block = block
        for name, attribute in self._create_default_attributes():
            block.add_attribute(name, attribute)
        for name, attribute in self.create_attributes():
            block.add_attribute(name, attribute)
        for name, method in self.create_methods():
            block.add_method(name, method)
            # Set if the method is writeable
            if method.only_in is None:
                states = [state for state in self.stateMachine.possible_states
                          if state != sm.DISABLED]
            else:
                states = method.only_in
                for state in states:
                    assert state in self.stateMachine.possible_states, \
                        "State %s is not one of the valid states %s" % \
                        (state, self.stateMachine.possible_states)
            self.set_method_writeable_in(method, states)

    def create_methods(self):
        """Abstract method that should provide Method instances for Block

        Yields:
            Method: Each one will be attached to the Block by calling
            block.add_method(method)
        """

        for name, member in inspect.getmembers(self, inspect.ismethod):
            if hasattr(member, "Method"):
                member.Method.set_function(member)
                yield (name, member.Method)

    def create_attributes(self):
        """Abstract method that should provide Attribute instances for Block

        Yields:
            Attribute: Each one will be attached to the Block by calling
            block.add_attribute(attribute)
        """
        return iter(())

    def _create_default_attributes(self):
        self.state = Attribute(ChoiceMeta(description="State of Block",
                            choices=self.stateMachine.possible_states))
        self.state.set_parent(self.block,'state')
        self.state.set_value(self.stateMachine.DISABLED)
        yield ('state', self.state)
        self.status = Attribute(StringMeta(description="Status of Block"))
        self.status.set_value("Disabled")
        yield ('status', self.status)
        self.busy = Attribute(BooleanMeta(
            description="Whether Block busy or not"))
        self.busy.set_value(False)
        yield ('busy', self.busy)

    @takes()
    @only_in(sm.DISABLED, sm.FAULT)
    def reset(self):
        try:
            self.transition(sm.RESETTING, "Resetting")
            self.Resetting.run(self)
            self.transition(sm.AFTER_RESETTING, "Done resetting")
        except Exception as e:
            self.log_exception("Fault occurred while Resetting")
            self.transition(sm.FAULT, str(e))

    @takes()
    def disable(self):
        self.transition(sm.DISABLED, "Disabled")

    def add_parts(self, parts):
        self.parts.extend(parts)

    def transition(self, state, message):
        """
        Change to a new state if the transition is allowed

        Args:
            state(str): State to transition to
            message(str): Status message
        """

        if self.stateMachine.is_allowed(initial_state=self.state.value,
                                        target_state=state):

            self.state.set_value(state)

            if state in self.stateMachine.busy_states:
                self.busy.set_value(True)
            else:
                self.busy.set_value(False)

            self.status.set_value(message)

            for method in self.block.methods.values():
                writeable = self.methods_writeable[state][method.name]
                method.set_writeable(writeable)

            self.block.notify_subscribers()

        else:
            raise TypeError("Cannot transition from %s to %s" %
                            (self.state.value, state))

    def set_method_writeable_in(self, method, states):
        """
        Set the states that the given method can be called in

        Args:
            method(Method): Method that will be set writeable or not
            states(list[str]): List of states where method is writeable
        """
        for state in self.stateMachine.possible_states:
            writeable_dict = self.methods_writeable.setdefault(state, {})
            is_writeable = state in states
            writeable_dict[method.name] = is_writeable
Пример #28
0
 def test_set_put_function(self):
     func = Mock()
     a = Attribute("test", Mock())
     a.set_put_function(func)
     self.assertIs(func, a.put_func)