def test_not_writeable_stops_call(self): m = Method("test_description") m.set_function(Mock()) m.set_writeable(False) with self.assertRaises(ValueError, msg="Cannot call a method that is not writeable"): m()
def test_defaults(self): func = Mock(return_value={"first_out": "test"}) m = Method("test_method", "test_description") arg_meta = Mock() arg_meta.elements = {"first": Mock(), "second": Mock()} m.set_function_takes(arg_meta, {"second": "default"}) m.set_function(func) self.assertEquals({"first_out": "test"}, m(first="test")) func.assert_called_with({"first": "test", "second": "default"})
def test_simple_function(self): func = Mock(return_value={"first_out": "test"}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() args_meta.elements = {"first": Mock()} m.set_function_takes(args_meta) result = m(first="test") self.assertEquals({"first_out": "test"}, result) func.assert_called_with({"first": "test"})
def test_handle_request(self, call_function_mock): call_function_mock.return_value = {"output": 1} m = Method("test_description") m.set_logger_name("mname") request = Mock( id=(123, Mock()), type="Post", parameters={"first": 2}, respond_with_return=Mock()) response = m.get_response(request) call_function_mock.assert_called_with({"first": 2}) self.assertEquals({"output": 1}, response.value)
def test_handle_request(self, call_function_mock): call_function_mock.return_value = {"output": 1} m = Method("test_description") m.set_logger_name("mname") request = Mock(id=(123, Mock()), type="Post", parameters={"first": 2}, respond_with_return=Mock()) response = m.get_response(request) call_function_mock.assert_called_with({"first": 2}) self.assertEquals({"output": 1}, response.value)
def test_positional_args(self): func = Mock(return_value={"output": 2}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() validator = Mock(return_value=True) args_meta.elements = OrderedDict() args_meta.elements["first"] = Mock(validate=validator) args_meta.elements["second"] = Mock(validate=validator) args_meta.elements["third"] = Mock(validate=validator) args_meta.elements["fourth"] = Mock(validate=validator) args_meta.required = ["first", "third"] m.set_function_takes(args_meta) self.assertEquals({"output": 2}, m(2, 3, third=1, fourth=4)) func.assert_called_with({"first": 2, "second": 3, "third": 1, "fourth": 4})
def test_handle_request(self): func = Mock(return_value={"output": 1}) args_meta = Mock(elements={"first": Mock()}) return_meta = Mock(elements={"output": Mock()}) m = Method("test_method", "test_description") m.set_function(func) m.set_function_takes(args_meta) m.set_function_returns(return_meta) request = Mock(id=(123, Mock()), type="Post", parameters={"first": 2}, respond_with_return=Mock()) m.handle_request(request) func.assert_called_with({"first": 2}) request.respond_with_return.assert_called_with({"output": 1})
def test_get_response_no_parameters(self): m = Method("test_description") m.set_logger_name("mname") call_func_mock = MagicMock() m.call_function = call_func_mock func = Mock(return_value={"first_out": "test"}) m.set_function(func) args_meta = Mock(spec=MapMeta) args_meta.elements = {"first": Mock()} m.set_takes(args_meta) request = MagicMock() del request.parameters # Make sure mock doesn't have `parameters` m.get_response(request) call_func_mock.assert_called_once_with(dict())
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_defaults(self): func = Mock(return_value={"first_out": "test"}) m = Method("test_description", writeable=True) m.set_parent(Mock(), "test_method") s = StringMeta(description='desc') args_meta = MapMeta() args_meta.elements = {"first": s, "second": s} m.set_takes(args_meta) m.set_defaults({"second": "default"}) m.set_function(func) self.assertEquals({"first_out": "test"}, m.call_function(dict(first="test"))) call_arg = func.call_args[0][0] self.assertEqual("test", call_arg.first) self.assertEqual("default", call_arg.second) self.assertEqual(args_meta, call_arg.meta)
def test_from_dict(self): m = Method.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 test_get_response_raises(self): func = MagicMock() func.side_effect = ValueError("Test error") m = Method("test_description") m.set_parent(Mock(), "test_method") m.set_function(func) m.takes = MagicMock() m.returns = MagicMock() request = MagicMock() response = m.get_response(request) self.assertEquals("malcolm:core/Error:1.0", response.typeid) self.assertEquals("Method test_method raised an error: Test error", response.message)
def test_handle_request(self): func = Mock(return_value={"output": 1}) args_meta = Mock(elements={"first": Mock()}) return_meta = Mock(elements={"output": Mock()}) m = Method("test_method", "test_description") m.set_function(func) m.set_function_takes(args_meta) m.set_function_returns(return_meta) request = Mock( id=(123, Mock()), type="Post", parameters={"first": 2}, respond_with_return=Mock()) m.handle_request(request) func.assert_called_with({"first": 2}) request.respond_with_return.assert_called_with({"output": 1})
def create_methods(self): """Create a Method wrapper for say_hello and return it""" method = Method("say_hello", "says hello") method.set_function(self.say_hello) takes = MapMeta("takes") takes.add_element(StringMeta("name", "a name")) method.set_function_takes(takes) returns = MapMeta("returns") returns.add_element(StringMeta("greeting", "a greeting")) method.set_function_returns(returns) yield method
def wrap_method(self, method_name, method_map): """Take the serialized method map and create a Method from it Args: method_map (dict): Serialized Method """ method = Method.from_dict(method_name, method_map) method.set_function( functools.partial(self.call_server_method, method_name)) self.log_debug("Wrapping method %s", method_name) return method
def test_handle_request_error(self): func = MagicMock() func.side_effect = ValueError("Test error") m = Method("test_method", "test_description") m.set_function(func) m.takes = MagicMock() m.returns = MagicMock() request = MagicMock() m.handle_request(request) request.respond_with_error.assert_called_once_with( "Method test_method raised an error: Test error")
def test_required(self): func = Mock(return_value={"first_out": "test"}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() args_meta.elements = {"first": Mock(), "second": Mock()} args_meta.required = ["first"] m.set_function_takes(args_meta, {"first": "default"}) self.assertEquals({"first_out": "test"}, m()) func.assert_called_with({"first": "default"}) m.set_function_takes(args_meta, {"second": "default"}) self.assertRaises(ValueError, m)
def test_incomplete_return(self): func = Mock(return_value={"output1": 2}) m = Method("test_description", writeable=True) m.name = "test_method" m.set_function(func) s = StringMeta(description='desc') args_meta = MapMeta() args_meta.set_elements({"first": s, "second": s}) return_meta = MapMeta() return_meta.set_elements({"output1": s, "output2": s}) return_meta.set_required(["output2"]) m.set_takes(args_meta) m.set_returns(return_meta) with self.assertRaises(KeyError): m.call_function(dict(first=1, second=2)) call_arg1, call_arg2 = func.call_args_list[0][0] self.assertEqual('1', call_arg1.first) self.assertEqual('2', call_arg1.second) self.assertEqual(args_meta, call_arg1.meta) self.assertEqual(return_meta, call_arg2.meta)
def test_not_writeable_stops_call(self): m = Method("test_description") m.set_function(Mock()) m.set_writeable(False) with self.assertRaises( ValueError, msg="Cannot call a method that is not writeable"): m()
def test_get_response_raises(self): func = MagicMock() func.side_effect = ValueError("Test error") m = Method("test_description") m.set_parent(Mock(), "test_method") m.set_function(func) m.takes = MagicMock() m.returns = MagicMock() request = MagicMock() response = m.get_response(request) self.assertEquals("malcolm:core/Error:1.0", response.typeid) self.assertEquals( "Method test_method raised an error: Test error", response.message)
def test_incomplete_return(self): func = Mock(return_value={"output1": 2}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() args_meta.elements = {"first": Mock(), "second": Mock()} return_meta = Mock() return_meta.elements = {"output1": Mock(), "output2": Mock()} validator = Mock(return_value=True) return_meta.elements["output1"].validate = validator return_meta.elements["output2"].validate = validator m.set_function_takes(args_meta) m.set_function_returns(return_meta) self.assertRaises(ValueError, m, first=1, second=2) func.assert_called_with({"first": 1, "second": 2})
def test_to_dict_serialization(self): func = Mock(return_value={"out": "dummy"}) defaults = {"in_attr": "default"} args_meta = Mock( elements={"first": Mock()}, to_dict=Mock(return_value=OrderedDict({"dict": "args"}))) return_meta = Mock( elements={"out": Mock()}, to_dict=Mock(return_value=OrderedDict({"dict": "return"}))) m = Method("test_method", "test_description") m.set_function(func) m.set_function_takes(args_meta, defaults) m.set_function_returns(return_meta) expected = OrderedDict() expected["description"] = "test_description" expected["takes"] = OrderedDict({"dict": "args"}) expected["defaults"] = OrderedDict({"in_attr": "default"}) expected["returns"] = OrderedDict({"dict": "return"}) self.assertEquals(expected, m.to_dict())
def test_from_dict_deserialize(self, mock_mapmeta): name = "foo" description = "dummy description" takes = dict(a=object(), b=object()) returns = dict(c=object()) defaults = dict(a=43) d = dict(description=description, takes=takes, returns=returns, defaults=defaults) m = Method.from_dict(name, d) self.assertEqual(mock_mapmeta.from_dict.call_args_list, [ call("takes", takes), call("returns", returns)]) self.assertEqual(m.name, name) self.assertEqual(m.takes, mock_mapmeta.from_dict.return_value) self.assertEqual(m.returns, mock_mapmeta.from_dict.return_value) self.assertEqual(m.defaults, defaults)
def test_invalid_return(self): func = Mock(return_value={"output1": 2, "output2": 4}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() args_meta.elements = {"first": Mock(), "second": Mock()} return_meta = Mock() return_meta.elements = {"output1": Mock(), "output2": Mock()} validator1 = Mock(return_value=True) validator2 = Mock(side_effect=TypeError("Fake type error")) return_meta.elements["output1"].validate = validator1 return_meta.elements["output2"].validate = validator2 m.set_function_takes(args_meta) m.set_function_returns(return_meta) self.assertRaises(TypeError, m, first=1, second=2) func.assert_called_with({"first": 1, "second": 2}) validator2.assert_called_with(4)
def test_call_calls_call_function(self): m = Method("test_description") call_func_mock = MagicMock() call_func_mock.return_value = {"output": 2} m.call_function = call_func_mock func = Mock(return_value={"first_out": "test"}) m.set_function(func) args_meta = Mock(spec=MapMeta) args_meta.elements = {"first": Mock()} m.set_takes(args_meta) response = m(first="test") call_func_mock.assert_called_once_with(dict(first="test")) self.assertEqual(response, {"output": 2})
def test_valid_return(self): func = Mock(return_value={"output1": 2, "output2": 4}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() args_meta.elements = {"first": Mock(), "second": Mock()} args_meta.required = ["first", "second"] return_meta = Mock() return_meta.elements = {"output1": Mock(), "output2": Mock()} validator1 = Mock(return_value=True) validator2 = Mock(return_value=True) return_meta.elements["output1"].validate = validator1 return_meta.elements["output2"].validate = validator2 m.set_function_takes(args_meta) m.set_function_returns(return_meta) self.assertEquals({"output1": 2, "output2": 4}, m(first=1, second=2)) func.assert_called_with({"first": 1, "second": 2}) validator1.assert_called_with(2) validator2.assert_called_with(4)
def test_to_dict_serialization(self): func = Mock(return_value={"out": "dummy"}) defaults = {"in_attr": "default"} args_meta = Mock(elements={"first": Mock()}, to_dict=Mock( return_value=OrderedDict({"dict": "args"}))) return_meta = Mock(elements={"out": Mock()}, to_dict=Mock( return_value=OrderedDict({"dict": "return"}))) m = Method("test_method", "test_description") m.set_function(func) m.set_function_takes(args_meta, defaults) m.set_function_returns(return_meta) expected = OrderedDict() expected["description"] = "test_description" expected["takes"] = OrderedDict({"dict": "args"}) expected["defaults"] = OrderedDict({"in_attr": "default"}) expected["returns"] = OrderedDict({"dict": "return"}) self.assertEquals(expected, m.to_dict())
def test_from_dict_deserialize(self, mock_mapmeta): name = "foo" description = "dummy description" takes = dict(a=object(), b=object()) returns = dict(c=object()) defaults = dict(a=43) d = dict(description=description, takes=takes, returns=returns, defaults=defaults) m = Method.from_dict(name, d) self.assertEqual(mock_mapmeta.from_dict.call_args_list, [call("takes", takes), call("returns", returns)]) self.assertEqual(m.name, name) self.assertEqual(m.takes, mock_mapmeta.from_dict.return_value) self.assertEqual(m.returns, mock_mapmeta.from_dict.return_value) self.assertEqual(m.defaults, defaults)
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"))
def test_positional_args(self): func = Mock(return_value={"output": 2}) m = Method("test_method", "test_description") m.set_function(func) args_meta = Mock() validator = Mock(return_value=True) args_meta.elements = OrderedDict() args_meta.elements["first"] = Mock(validate=validator) args_meta.elements["second"] = Mock(validate=validator) args_meta.elements["third"] = Mock(validate=validator) args_meta.elements["fourth"] = Mock(validate=validator) args_meta.required = ["first", "third"] m.set_function_takes(args_meta) self.assertEquals({"output": 2}, m(2, 3, third=1, fourth=4)) func.assert_called_with({ "first": 2, "second": 3, "third": 1, "fourth": 4 })
def test_call_with_positional_args(self): func = Mock(return_value={"output": 2}) m = Method("test_description") call_func_mock = MagicMock() m.call_function = call_func_mock m.set_function(func) args_meta = Mock(spec=MapMeta) validator = Mock(return_value=True) args_meta.elements = OrderedDict() args_meta.elements["first"] = Mock(validate=validator) args_meta.elements["second"] = Mock(validate=validator) args_meta.elements["third"] = Mock(validate=validator) args_meta.elements["fourth"] = Mock(validate=validator) args_meta.required = ["first", "third"] m.set_takes(args_meta) m(2, 3, third=1, fourth=4) call_func_mock.assert_called_once_with({'second': 3, 'fourth': 4, 'third': 1, 'first': 2})
def test_call_with_positional_args(self): func = Mock(return_value={"output": 2}) m = Method("test_description") call_func_mock = MagicMock() m.call_function = call_func_mock m.set_function(func) args_meta = Mock(spec=MapMeta) validator = Mock(return_value=True) args_meta.elements = OrderedDict() args_meta.elements["first"] = Mock(validate=validator) args_meta.elements["second"] = Mock(validate=validator) args_meta.elements["third"] = Mock(validate=validator) args_meta.elements["fourth"] = Mock(validate=validator) args_meta.required = ["first", "third"] m.set_takes(args_meta) m(2, 3, third=1, fourth=4) call_func_mock.assert_called_once_with({ 'second': 3, 'fourth': 4, 'third': 1, 'first': 2 })
def test_set_label(self): m = Method("test_description") m.on_changed = Mock(wrap=m.on_changed) m.set_label("new_label") self.assertEquals("new_label", m.label) m.on_changed.assert_called_once_with([["label"], "new_label"], True)
def test_to_dict(self): m = Method("test_description") m.set_takes(self.takes) m.set_defaults(self.serialized["defaults"]) self.assertEqual(m.to_dict(), self.serialized)
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)
def test_init(self): m = Method("test_description") self.assertEquals("test_description", m.description) self.assertEquals("malcolm:core/Method:1.0", m.typeid) self.assertEquals("", m.label)
def test_init(self): m = Method("test_method", "test_description") self.assertEquals("test_method", m.name) self.assertEquals("test_description", m.description)
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)