Send update of properties from controller only for controller stuffs

Fix #566
This commit is contained in:
Julien Duponchelle 2016-06-13 18:46:30 +02:00
parent 2bde02d459
commit 70431a5fa6
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
2 changed files with 44 additions and 7 deletions

View File

@ -84,6 +84,7 @@ class Node:
@name.setter
def name(self, new_name):
self._project.update_node_name(self, new_name)
self._name = new_name
# The text in label need to be always the node name
self._label["text"] = new_name
@ -205,19 +206,22 @@ class Node:
# When updating properties used only on controller we don't need to call the compute
update_compute = False
# update the node name if present
self._project.update_node_name(self, kwargs.get("name"))
compute_properties = None
# Update node properties with additional elements
for prop in kwargs:
if getattr(self, prop) != kwargs[prop]:
if prop not in self.CONTROLLER_ONLY_PROPERTIES:
update_compute = True
setattr(self, prop, kwargs[prop])
# We update properties on the compute and wait for the anwser from the compute node
if prop == "properties":
compute_properties = kwargs[prop]
else:
setattr(self, prop, kwargs[prop])
self.project.controller.notification.emit("node.updated", self.__json__())
if update_compute:
data = self._node_data()
data = self._node_data(properties=compute_properties)
response = yield from self.put(None, data=data)
self.parse_node_response(response.json)
@ -243,11 +247,16 @@ class Node:
else:
self._properties[key] = value
def _node_data(self):
def _node_data(self, properties=None):
"""
Prepare node data to send to the remote controller
:param properties: If properties is None use actual property otherwise use the parameter
"""
data = copy.copy(self._properties)
if properties:
data = copy.copy(properties)
else:
data = copy.copy(self._properties)
data["name"] = self._name
if self._console:
# console is optional for builtin nodes

View File

@ -138,6 +138,34 @@ def test_update(node, compute, project, async_run, controller):
controller._notification.emit.assert_called_with("node.updated", node.__json__())
def test_update_properties(node, compute, project, async_run, controller):
"""
properties will be updated by the answer from compute
"""
response = MagicMock()
response.json = {"console": 2048}
compute.put = AsyncioMagicMock(return_value=response)
controller._notification = AsyncioMagicMock()
async_run(node.update(x=42, console=2048, console_type="vnc", properties={"startup_script": "hello world"}, name="demo"))
data = {
"console": 2048,
"console_type": "vnc",
"startup_script": "hello world",
"name": "demo"
}
compute.put.assert_called_with("/projects/{}/vpcs/nodes/{}".format(node.project.id, node.id), data=data)
assert node._console == 2048
assert node.x == 42
assert node._properties == {"startup_script": "echo test"}
# The notif should contain the old properties because it's the compute that will emit
# the correct info
node_notif = node.__json__()
node_notif["properties"]["startup_config"] = "echo test"
controller._notification.emit.assert_called_with("node.updated", node_notif)
def test_update_only_controller(node, compute, project, async_run):
"""
When updating property used only on controller we don't need to