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"])
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)
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
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 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())
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
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_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())
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()
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
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)
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)
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)
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)
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)