From c8c9a87b240b562d334c6875a1dd7614d4ae58d5 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Thu, 16 Feb 2012 15:52:16 -0500 Subject: Add RPC serialization checking, fix exposed problems. Related to bug 933584. In this bug, I hit a case where some code tried to send a SQLAlchemy model over rpc, which failed since it couldn't be serialized by Qpid. This patch adds a simple serialization check to the fake RPC driver using json. It also fixes problems that were exposed by adding this check. If json can't serialize a message sent through the fake RPC driver, it will raise TypeError, causing unit tests to fail. 18 unit tests failed with the check in place, but it was due to only 2 places in the compute API. Change-Id: I63f3077c0fa35097d4f5d2c485f4e48eede2c751 --- nova/compute/api.py | 20 +++++++++++--------- nova/rpc/impl_fake.py | 11 ++++++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index d93443ea4..78655bed4 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -549,7 +549,7 @@ class API(base.Base): locals()) request_spec = { - 'image': image, + 'image': utils.to_primitive(image), 'instance_properties': base_options, 'instance_type': instance_type, 'num_instances': num_instances, @@ -1384,14 +1384,16 @@ class API(base.Base): if not FLAGS.allow_resize_to_same_host: filter_properties['ignore_hosts'].append(instance['host']) - self._cast_scheduler_message(context, - {"method": "prep_resize", - "args": {"topic": FLAGS.compute_topic, - "instance_uuid": instance['uuid'], - "update_db": False, - "instance_type_id": new_instance_type['id'], - "request_spec": request_spec, - "filter_properties": filter_properties}}) + args = { + "topic": FLAGS.compute_topic, + "instance_uuid": instance['uuid'], + "update_db": False, + "instance_type_id": new_instance_type['id'], + "request_spec": utils.to_primitive(request_spec), + "filter_properties": filter_properties, + } + self._cast_scheduler_message(context, {"method": "prep_resize", + "args": args}) @wrap_check_policy def add_fixed_ip(self, context, instance, network_id): diff --git a/nova/rpc/impl_fake.py b/nova/rpc/impl_fake.py index 44567d6f9..42ed7907d 100644 --- a/nova/rpc/impl_fake.py +++ b/nova/rpc/impl_fake.py @@ -18,6 +18,7 @@ queues. Casts will block, but this is very useful for tests. """ import inspect +import json import signal import sys import time @@ -124,9 +125,16 @@ def create_connection(new=True): return Connection() +def check_serialize(msg): + """Make sure a message intended for rpc can be serialized.""" + json.dumps(msg) + + def multicall(context, topic, msg, timeout=None): """Make a call that returns multiple times.""" + check_serialize(msg) + method = msg.get('method') if not method: return @@ -158,7 +166,7 @@ def cast(context, topic, msg): def notify(context, topic, msg): - pass + check_serialize(msg) def cleanup(): @@ -167,6 +175,7 @@ def cleanup(): def fanout_cast(context, topic, msg): """Cast to all consumers of a topic""" + check_serialize(msg) method = msg.get('method') if not method: return -- cgit