From 18d7da01be2454c87527dcc4b08dd759dae2ef5e Mon Sep 17 00:00:00 2001 From: Charles Mita Date: Tue, 21 Jun 2016 16:32:34 +0100 Subject: [PATCH] Fix block to handle Put requests properly Similar to method post requests, push a "to return" message to the process queue so the return is received *after* update to the attribute has been seen. --- malcolm/core/block.py | 24 ++++++++++++------------ tests/test_core/test_block.py | 32 ++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/malcolm/core/block.py b/malcolm/core/block.py index a52cb757a..3e569e126 100644 --- a/malcolm/core/block.py +++ b/malcolm/core/block.py @@ -3,6 +3,8 @@ from malcolm.core.monitorable import Monitorable from malcolm.core.process import BlockRespond +from malcolm.core.request import Request +from malcolm.core.response import Response @contextmanager def dummy_lock(): @@ -59,21 +61,19 @@ def handle_request(self, request): request(Request): Request object specifying action """ self.log_debug("Received request %s", request) + assert request.type_ == Request.POST or request.type_ == Request.PUT, \ + "Expected Post or Put request, received %s" % request.type_ with self.lock: - if request.type_ == request.POST: + if request.type_ == Request.POST: method_name = request.endpoint[-1] response = self._methods[method_name].get_response(request) - response = BlockRespond(response, request.response_queue) - self.parent.q.put(response) - else: - layer = self - for next_link in request.endpoint[1:]: - layer = getattr(layer, next_link) - - if hasattr(layer, "to_dict"): - request.respond_with_return(layer.to_dict()) - else: - request.respond_with_return(layer) + elif request.type_ == Request.PUT: + attr_name = request.endpoint[-1] + self._attributes[attr_name].put(request.value) + self._attributes[attr_name].set_value(request.value) + response = Response.Return(request.id_, request.context) + response = BlockRespond(response, request.response_queue) + self.parent.q.put(response) def to_dict(self): """Convert object attributes into a dictionary""" diff --git a/tests/test_core/test_block.py b/tests/test_core/test_block.py index 24517b3d0..2b6a58bb4 100644 --- a/tests/test_core/test_block.py +++ b/tests/test_core/test_block.py @@ -96,40 +96,44 @@ def setUp(self): self.block.parent = MagicMock() self.method = MagicMock() self.method.name = "get_things" + self.attribute = MagicMock() + self.attribute.name = "test_attribute" self.response = MagicMock() self.block.add_method(self.method) + self.block.add_attribute(self.attribute) def test_given_request_then_pass_to_correct_method(self): request = MagicMock() - request.POST = "Post" request.type_ = "Post" request.endpoint = ["TestBlock", "device", "get_things"] self.block.handle_request(request) self.method.get_response.assert_called_once_with(request) + response = self.block.parent.q.put.call_args[0][0] + self.assertEqual(self.method.get_response.return_value, + response.response) - def test_given_get_then_return_attribute(self): - self.block.state = MagicMock() - self.block.state.value = "Running" + def test_given_put_then_update_attribute(self): + put_value = MagicMock() request = MagicMock() - request.type_ = "Get" - request.endpoint = ["TestBlock", "state", "value"] + request.type_ = "Put" + request.endpoint = ["TestBlock", "test_attribute"] + request.value = put_value self.block.handle_request(request) - request.respond_with_return.assert_called_once_with("Running") + self.attribute.put.assert_called_once_with(put_value) + self.attribute.set_value.assert_called_once_with(put_value) + response = self.block.parent.q.put.call_args[0][0] + self.assertEqual("Return", response.response.type_) + self.assertIsNone(response.response.value) - def test_given_get_block_then_return_self(self): + def test_invalid_request_fails(self): request = MagicMock() request.type_ = "Get" - request.endpoint = ["TestBlock"] - expected_call = self.block.to_dict() - - self.block.handle_request(request) - - request.respond_with_return.assert_called_once_with(expected_call) + self.assertRaises(AssertionError, self.block.handle_request, request) if __name__ == "__main__": unittest.main(verbosity=2)