Exemplo n.º 1
0
 def test_set_label(self):
     m = MethodMeta("test_description")
     m.process = Mock()
     m.set_label("new_label")
     self.assertEquals("new_label", m.label)
     m.process.report_changes.assert_called_once_with([["label"],
                                                       "new_label"])
Exemplo n.º 2
0
    def test_recreate(self):
        @method_takes(
            "arg1",
            StringMeta("Arg1"),
            REQUIRED,
            "extra",
            StringMeta(),
            REQUIRED,
        )
        def method1():
            pass

        @method_takes(
            "arg8",
            StringMeta("Arg8"),
            REQUIRED,
            "arg3",
            StringMeta("Arg3"),
            "32",
            "arg4",
            StringMeta("Arg4"),
            OPTIONAL,
        )
        def method2():
            pass

        @method_takes(
            "arg8",
            StringMeta("Arg8"),
            "2",
            "arg3",
            StringMeta("Arg3"),
            "33",
        )
        def method3():
            pass

        m = MethodMeta("Test")
        m.recreate_from_others(
            [method1.MethodMeta, method2.MethodMeta, method3.MethodMeta],
            without=["extra"])

        itakes = MapMeta()
        elements = OrderedDict()
        elements["arg1"] = StringMeta("Arg1")
        elements["arg8"] = StringMeta("Arg8")
        elements["arg3"] = StringMeta("Arg3")
        elements["arg4"] = StringMeta("Arg4")
        itakes.set_elements(ElementMap(elements))
        itakes.set_required(["arg1"])
        defaults = OrderedDict()
        defaults["arg8"] = "2"
        defaults["arg3"] = "33"
        self.assertEqual(m.takes.to_dict(), itakes.to_dict())
        self.assertEqual(m.returns.to_dict(), MapMeta().to_dict())
        self.assertEqual(m.defaults, defaults)
Exemplo n.º 3
0
    def __call__(self, func):
        """
        Decorator function to add a Hook to a Part's function

        Args:
            func: Function to decorate with Hook

        Returns:
            Decorated function
        """

        func.Hook = self
        MethodMeta.wrap_method(func)
        return func
Exemplo n.º 4
0
 def __init__(self, hook_queue, part, func_name, task, *args, **params):
     self.set_logger_name("HookRunner(%s)" % part.name)
     self.hook_queue = hook_queue
     self.part = part
     self.task = task
     self.args = args
     self.func = getattr(part, func_name)
     self.filtered_params = {}
     self.method_meta = part.method_metas.get(func_name, None)
     if self.method_meta is None:
         self.method_meta = MethodMeta()
         self.method_meta.set_logger_name("MethodMeta")
     for k, v in params.items():
         if k in self.method_meta.takes.elements:
             self.filtered_params[k] = v
Exemplo n.º 5
0
 def test_from_dict(self):
     m = MethodMeta.from_dict(self.serialized.copy())
     self.assertEqual(m.takes.to_dict(), self.takes.to_dict())
     self.assertEqual(m.defaults, self.serialized["defaults"])
     self.assertEqual(m.tags, ())
     self.assertEqual(m.writeable, True)
     self.assertEqual(m.label, "")
     self.assertEqual(m.returns.to_dict(), MapMeta().to_dict())
Exemplo n.º 6
0
    def __call__(self, func):
        """
        Decorator function to add a Hook to a Part's function

        Args:
            func: Function to decorate with Hook

        Returns:
            Decorated function
        """

        if not hasattr(func, "Hooked"):
            func.Hooked = []
        func.Hooked.append(self)
        # TODO: is this needed?
        MethodMeta.wrap_method(func)
        return func
Exemplo n.º 7
0
 def setUp(self):
     self.callback_result = 0
     self.callback_value = ''
     meta = VMeta("meta for unit tests")
     self.proc = MagicMock(q=queue.Queue())
     self.proc.create_queue = MagicMock(side_effect=queue.Queue)
     self.block = Block()
     self.block.set_parent(self.proc, "testBlock")
     self.attr = meta.make_attribute()
     self.attr.set_parent(self.block, "testAttr")
     self.attr2 = meta.make_attribute()
     self.attr2.set_parent(self.block, "testAttr2")
     self.method = MethodMeta("method for unit tests")
     self.method.set_parent(self.block, "testFunc")
     self.method2 = MethodMeta("method for unit tests")
     self.method2.set_parent(self.block, "testFunc")
     self.bad_called_back = False
Exemplo n.º 8
0
    def __call__(self, func):
        """
        Decorator function to add a Hook to a Part's function

        Args:
            func: Function to decorate with Hook

        Returns:
            Decorated function
        """

        if not hasattr(func, "Hooked"):
            func.Hooked = []
        func.Hooked.append(self)
        # TODO: is this needed?
        MethodMeta.wrap_method(func)
        return func
Exemplo n.º 9
0
 def test_from_dict(self):
     m = MethodMeta.from_dict(self.serialized.copy())
     self.assertEqual(m.takes.to_dict(), self.takes.to_dict())
     self.assertEqual(m.defaults, self.serialized["defaults"])
     self.assertEqual(m.tags, [])
     self.assertEqual(m.writeable, True)
     self.assertEqual(m.label, "")
     self.assertEqual(m.returns.to_dict(), MapMeta().to_dict())
Exemplo n.º 10
0
class HookRunner(Loggable):
    def __init__(self, hook_queue, part, func_name, task, *args, **params):
        self.set_logger_name("HookRunner(%s)" % part.name)
        self.hook_queue = hook_queue
        self.part = part
        self.task = task
        self.args = args
        self.func = getattr(part, func_name)
        self.filtered_params = {}
        self.method_meta = part.method_metas.get(func_name, None)
        if self.method_meta is None:
            self.method_meta = MethodMeta()
            self.method_meta.set_logger_name("MethodMeta")
        for k, v in params.items():
            if k in self.method_meta.takes.elements:
                self.filtered_params[k] = v

    def task_return(self):
        try:
            result = self.method_meta.call_post_function(
                self.func, self.filtered_params, self.task, *self.args)
        except AbortedError as e:
            self.log_info("%s has been aborted", self.func)
            result = e
        except Exception as e:  # pylint:disable=broad-except
            self.log_exception("%s %s raised exception", self.func,
                               self.filtered_params)
            result = e
        self.log_debug("Putting %r on queue", result)
        self.hook_queue.put((self.part, result))

    def start(self):
        self.task.define_spawn_function(self.task_return)
        sentinel_stop = object()
        self.task.sentinel_stop = sentinel_stop
        # Say that we should only listen to stops after this point
        self.task.q.put(sentinel_stop)
        self.task.start()

    def stop(self):
        self.task.stop()

    def wait(self):
        self.task.wait()
Exemplo n.º 11
0
 def setUp(self):
     self.callback_result = 0
     self.callback_value = ''
     meta = StringMeta("meta for unit tests")
     self.proc = MagicMock(q=queue.Queue())
     self.proc.create_queue = MagicMock(side_effect=queue.Queue)
     self.block = Block()
     self.block.set_process_path(self.proc, ("testBlock", ))
     self.attr = meta.make_attribute()
     self.attr2 = meta.make_attribute()
     self.method = MethodMeta("method for unit tests")
     self.method.returns.set_elements(ElementMap(dict(ret=StringMeta())))
     self.method2 = MethodMeta("method for unit tests")
     self.block.replace_endpoints(
         dict(testFunc=self.method,
              testFunc2=self.method2,
              testAttr=self.attr,
              testAttr2=self.attr2))
     self.bad_called_back = False
Exemplo n.º 12
0
    def test_recreate(self):
        @method_takes(
            "arg1", StringMeta("Arg1"), REQUIRED,
            "extra", StringMeta(), REQUIRED,
        )
        def method1():
            pass

        @method_takes(
            "arg8", StringMeta("Arg8"), REQUIRED,
            "arg3", StringMeta("Arg3"), "32",
            "arg4", StringMeta("Arg4"), OPTIONAL,
        )
        def method2():
            pass

        @method_takes(
            "arg8", StringMeta("Arg8"), "2",
            "arg3", StringMeta("Arg3"), "33",
        )
        def method3():
            pass

        m = MethodMeta("Test")
        m.recreate_from_others([
            method1.MethodMeta, method2.MethodMeta, method3.MethodMeta],
            without=["extra"])

        itakes = MapMeta()
        elements = OrderedDict()
        elements["arg1"] = StringMeta("Arg1")
        elements["arg8"] = StringMeta("Arg8")
        elements["arg3"] = StringMeta("Arg3")
        elements["arg4"] = StringMeta("Arg4")
        itakes.set_elements(ElementMap(elements))
        itakes.set_required(["arg1"])
        defaults = OrderedDict()
        defaults["arg8"] = "2"
        defaults["arg3"] = "33"
        self.assertEqual(m.takes.to_dict(), itakes.to_dict())
        self.assertEqual(m.returns.to_dict(), MapMeta().to_dict())
        self.assertEqual(m.defaults, defaults)
Exemplo n.º 13
0
    def _set_block_children(self):
        # reconfigure block with new children
        child_list = [self.create_meta()]
        child_list += list(self._create_default_attributes())
        child_list += list(self.create_attributes())
        child_list += list(self.create_methods())
        for part in self.parts.values():
            child_list += list(part.create_attributes())
            child_list += list(part.create_methods())

        self.methods_writeable = {}
        writeable_functions = {}
        children = OrderedDict()

        for name, child, writeable_func in child_list:
            if isinstance(child, MethodMeta):
                # Set if the method is writeable
                if child.only_in is None:
                    states = [
                        state for state in self.stateMachine.possible_states
                        if state not in (sm.DISABLING, sm.DISABLED)
                    ]
                else:
                    states = child.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)
                # Make a copy otherwise all instances will own the same one
                child = MethodMeta.from_dict(child.to_dict())
                self.register_method_writeable(child, states)
            elif isinstance(child, Attribute):
                child.meta.set_writeable(writeable_func is not None)
            children[name] = child
            if writeable_func:
                writeable_functions[name] = functools.partial(
                    self.call_writeable_function, writeable_func)

        self.block.replace_endpoints(children)
        self.block.set_writeable_functions(writeable_functions)
Exemplo n.º 14
0
 def test_set_label(self):
     m = MethodMeta("test_description")
     m.process = Mock()
     m.set_label("new_label")
     self.assertEquals("new_label", m.label)
     m.process.report_changes.assert_called_once_with([["label"], "new_label"])
Exemplo n.º 15
0
 def test_init(self):
     m = MethodMeta("test_description")
     self.assertEquals("test_description", m.description)
     self.assertEquals("malcolm:core/MethodMeta:1.0", m.typeid)
     self.assertEquals("", m.label)
Exemplo n.º 16
0
class TestTask(unittest.TestCase):
    def setUp(self):
        self.callback_result = 0
        self.callback_value = ''
        meta = VMeta("meta for unit tests")
        self.proc = MagicMock(q=queue.Queue())
        self.proc.create_queue = MagicMock(side_effect=queue.Queue)
        self.block = Block()
        self.block.set_parent(self.proc, "testBlock")
        self.attr = meta.make_attribute()
        self.attr.set_parent(self.block, "testAttr")
        self.attr2 = meta.make_attribute()
        self.attr2.set_parent(self.block, "testAttr2")
        self.method = MethodMeta("method for unit tests")
        self.method.set_parent(self.block, "testFunc")
        self.method2 = MethodMeta("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, ['testBlock', '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, {"a": "testParm"})
        self.assertRaises(ValueError, t.post, self.method, {"a": "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)
        self.assertRaises(ValueError, 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(StopIteration, 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(Spawnable.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(Spawnable.STOP)
        self.assertRaises(StopIteration, 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(Spawnable.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(StopIteration, 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(StopIteration, t.wait_all, f1, 0)
        self.assertEquals(self.bad_called_back, True)

    def test_sleep(self):
        t = Task("testTask", self.proc)
        start = time.time()
        t.sleep(0.05)
        end = time.time()
        self.assertAlmostEqual(end - start, 0.05, delta=0.005)

    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(StopIteration, f[0].result)

    def test_start_default_raises(self):
        t = Task("t", self.proc)
        self.assertRaises(AssertionError, t.start)

    def test_clear_spawn_functions(self):
        t = Task("testTask", self.proc)
        f = MagicMock()
        t.define_spawn_function(None)
        self.assertEquals([(None, (), ANY)], t._spawn_functions)

    def test_clear_raises_if_running(self):
        proc = Process("proc", SyncFactory("sync"))
        t = Task("testTask", proc)
        import time

        def f():
            time.sleep(0.05)

        t.define_spawn_function(f)
        start = time.time()
        t.start()
        self.assertRaises(AssertionError, t.define_spawn_function, None)
        t.wait()
        end = time.time()
        self.assertAlmostEqual(end - start, 0.05, delta=0.005)
        t.define_spawn_function(None)
Exemplo n.º 17
0
 def test_to_dict(self):
     m = MethodMeta("test_description")
     m.set_takes(self.takes)
     m.set_defaults(self.serialized["defaults"])
     self.assertEqual(m.to_dict(), self.serialized)
Exemplo n.º 18
0
 def test_to_dict(self):
     m = MethodMeta("test_description")
     m.set_takes(self.takes)
     m.set_defaults(self.serialized["defaults"])
     self.assertEqual(m.to_dict(), self.serialized)