Merge trunk and fix test.
This commit is contained in:
@@ -135,15 +135,48 @@ class VpnCommands(object):
|
||||
|
||||
|
||||
class ShellCommands(object):
|
||||
def run(self):
|
||||
"Runs a Python interactive interpreter. Tries to use IPython, if it's available."
|
||||
try:
|
||||
import IPython
|
||||
# Explicitly pass an empty list as arguments, because otherwise IPython
|
||||
# would use sys.argv from this script.
|
||||
shell = IPython.Shell.IPShell(argv=[])
|
||||
shell.mainloop()
|
||||
except ImportError:
|
||||
def bpython(self):
|
||||
"""Runs a bpython shell.
|
||||
|
||||
Falls back to Ipython/python shell if unavailable"""
|
||||
self.run('bpython')
|
||||
|
||||
def ipython(self):
|
||||
"""Runs an Ipython shell.
|
||||
|
||||
Falls back to Python shell if unavailable"""
|
||||
self.run('ipython')
|
||||
|
||||
def python(self):
|
||||
"""Runs a python shell.
|
||||
|
||||
Falls back to Python shell if unavailable"""
|
||||
self.run('python')
|
||||
|
||||
def run(self, shell=None):
|
||||
"""Runs a Python interactive interpreter.
|
||||
|
||||
args: [shell=bpython]"""
|
||||
if not shell:
|
||||
shell = 'bpython'
|
||||
|
||||
if shell == 'bpython':
|
||||
try:
|
||||
import bpython
|
||||
bpython.embed()
|
||||
except ImportError:
|
||||
shell = 'ipython'
|
||||
if shell == 'ipython':
|
||||
try:
|
||||
import IPython
|
||||
# Explicitly pass an empty list as arguments, because otherwise IPython
|
||||
# would use sys.argv from this script.
|
||||
shell = IPython.Shell.IPShell(argv=[])
|
||||
shell.mainloop()
|
||||
except ImportError:
|
||||
shell = 'python'
|
||||
|
||||
if shell == 'python':
|
||||
import code
|
||||
try: # Try activating rlcompleter, because it's handy.
|
||||
import readline
|
||||
@@ -156,6 +189,11 @@ class ShellCommands(object):
|
||||
readline.parse_and_bind("tab:complete")
|
||||
code.interact()
|
||||
|
||||
def script(self, path):
|
||||
"""Runs the script from the specifed path with flags set properly.
|
||||
arguments: path"""
|
||||
exec(compile(open(path).read(), path, 'exec'), locals(), globals())
|
||||
|
||||
|
||||
class RoleCommands(object):
|
||||
"""Class for managing roles."""
|
||||
@@ -253,7 +291,7 @@ class ProjectCommands(object):
|
||||
def environment(self, project_id, user_id, filename='novarc'):
|
||||
"""Exports environment variables to an sourcable file
|
||||
arguments: project_id user_id [filename='novarc]"""
|
||||
rc = self.manager.get_environment_rc(project_id, user_id)
|
||||
rc = self.manager.get_environment_rc(user_id, project_id)
|
||||
with open(filename, 'w') as f:
|
||||
f.write(rc)
|
||||
|
||||
@@ -316,7 +354,7 @@ class FloatingIpCommands(object):
|
||||
for floating_ip in floating_ips:
|
||||
instance = None
|
||||
if floating_ip['fixed_ip']:
|
||||
instance = floating_ip['fixed_ip']['instance']['str_id']
|
||||
instance = floating_ip['fixed_ip']['instance']['ec2_id']
|
||||
print "%s\t%s\t%s" % (floating_ip['host'],
|
||||
floating_ip['address'],
|
||||
instance)
|
||||
|
||||
@@ -188,6 +188,8 @@ DEFINE_string('rabbit_userid', 'guest', 'rabbit userid')
|
||||
DEFINE_string('rabbit_password', 'guest', 'rabbit password')
|
||||
DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host')
|
||||
DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to')
|
||||
DEFINE_string('cc_host', '127.0.0.1', 'ip of api server')
|
||||
DEFINE_integer('cc_port', 8773, 'cloud controller port')
|
||||
DEFINE_string('ec2_url', 'http://127.0.0.1:8773/services/Cloud',
|
||||
'Url to ec2 api server')
|
||||
|
||||
|
||||
45
nova/rpc.py
45
nova/rpc.py
@@ -84,19 +84,6 @@ class Consumer(messaging.Consumer):
|
||||
self.failed_connection = False
|
||||
super(Consumer, self).__init__(*args, **kwargs)
|
||||
|
||||
# TODO(termie): it would be nice to give these some way of automatically
|
||||
# cleaning up after themselves
|
||||
def attach_to_tornado(self, io_inst=None):
|
||||
"""Attach a callback to tornado that fires 10 times a second"""
|
||||
from tornado import ioloop
|
||||
if io_inst is None:
|
||||
io_inst = ioloop.IOLoop.instance()
|
||||
|
||||
injected = ioloop.PeriodicCallback(
|
||||
lambda: self.fetch(enable_callbacks=True), 100, io_loop=io_inst)
|
||||
injected.start()
|
||||
return injected
|
||||
|
||||
def fetch(self, no_ack=None, auto_ack=None, enable_callbacks=False):
|
||||
"""Wraps the parent fetch with some logic for failed connections"""
|
||||
# TODO(vish): the logic for failed connections and logging should be
|
||||
@@ -124,6 +111,7 @@ class Consumer(messaging.Consumer):
|
||||
"""Attach a callback to twisted that fires 10 times a second"""
|
||||
loop = task.LoopingCall(self.fetch, enable_callbacks=True)
|
||||
loop.start(interval=0.1)
|
||||
return loop
|
||||
|
||||
|
||||
class Publisher(messaging.Publisher):
|
||||
@@ -294,6 +282,37 @@ def call(topic, msg):
|
||||
return wait_msg.result
|
||||
|
||||
|
||||
def call_twisted(topic, msg):
|
||||
"""Sends a message on a topic and wait for a response"""
|
||||
LOG.debug("Making asynchronous call...")
|
||||
msg_id = uuid.uuid4().hex
|
||||
msg.update({'_msg_id': msg_id})
|
||||
LOG.debug("MSG_ID is %s" % (msg_id))
|
||||
|
||||
conn = Connection.instance()
|
||||
d = defer.Deferred()
|
||||
consumer = DirectConsumer(connection=conn, msg_id=msg_id)
|
||||
|
||||
def deferred_receive(data, message):
|
||||
"""Acks message and callbacks or errbacks"""
|
||||
message.ack()
|
||||
if data['failure']:
|
||||
return d.errback(RemoteError(*data['failure']))
|
||||
else:
|
||||
return d.callback(data['result'])
|
||||
|
||||
consumer.register_callback(deferred_receive)
|
||||
injected = consumer.attach_to_twisted()
|
||||
|
||||
# clean up after the injected listened and return x
|
||||
d.addCallback(lambda x: injected.stop() and x or x)
|
||||
|
||||
publisher = TopicPublisher(connection=conn, topic=topic)
|
||||
publisher.send(msg)
|
||||
publisher.close()
|
||||
return d
|
||||
|
||||
|
||||
def cast(topic, msg):
|
||||
"""Sends a message on a topic without waiting for a response"""
|
||||
LOG.debug("Making asynchronous cast...")
|
||||
|
||||
@@ -31,7 +31,7 @@ FLAGS = flags.FLAGS
|
||||
class Context(object):
|
||||
pass
|
||||
|
||||
class AccessTestCase(test.BaseTestCase):
|
||||
class AccessTestCase(test.TrialTestCase):
|
||||
def setUp(self):
|
||||
super(AccessTestCase, self).setUp()
|
||||
um = manager.AuthManager()
|
||||
|
||||
@@ -29,7 +29,8 @@ from nova.api.ec2 import cloud
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class AuthTestCase(test.BaseTestCase):
|
||||
class AuthTestCase(test.TrialTestCase):
|
||||
flush_db = False
|
||||
def setUp(self):
|
||||
super(AuthTestCase, self).setUp()
|
||||
self.flags(connection_type='fake')
|
||||
|
||||
@@ -51,7 +51,7 @@ OSS_TEMPDIR = tempfile.mkdtemp(prefix='test_oss-')
|
||||
IMAGES_PATH = os.path.join(OSS_TEMPDIR, 'images')
|
||||
os.makedirs(IMAGES_PATH)
|
||||
|
||||
class CloudTestCase(test.BaseTestCase):
|
||||
class CloudTestCase(test.TrialTestCase):
|
||||
def setUp(self):
|
||||
super(CloudTestCase, self).setUp()
|
||||
self.flags(connection_type='fake', images_path=IMAGES_PATH)
|
||||
@@ -65,9 +65,9 @@ class CloudTestCase(test.BaseTestCase):
|
||||
# set up a service
|
||||
self.compute = utils.import_class(FLAGS.compute_manager)
|
||||
self.compute_consumer = rpc.AdapterConsumer(connection=self.conn,
|
||||
topic=FLAGS.compute_topic,
|
||||
proxy=self.compute)
|
||||
self.injected.append(self.compute_consumer.attach_to_tornado(self.ioloop))
|
||||
topic=FLAGS.compute_topic,
|
||||
proxy=self.compute)
|
||||
self.compute_consumer.attach_to_twisted()
|
||||
|
||||
self.manager = manager.AuthManager()
|
||||
self.user = self.manager.create_user('admin', 'admin', 'admin', True)
|
||||
@@ -78,7 +78,7 @@ class CloudTestCase(test.BaseTestCase):
|
||||
def tearDown(self):
|
||||
self.manager.delete_project(self.project)
|
||||
self.manager.delete_user(self.user)
|
||||
super(CloudTestCase, self).setUp()
|
||||
super(CloudTestCase, self).tearDown()
|
||||
|
||||
def _create_key(self, name):
|
||||
# NOTE(vish): create depends on pool, so just call helper directly
|
||||
@@ -236,7 +236,7 @@ class CloudTestCase(test.BaseTestCase):
|
||||
|
||||
def test_update_of_instance_display_fields(self):
|
||||
inst = db.instance_create({}, {})
|
||||
self.cloud.update_instance(self.context, inst['str_id'],
|
||||
self.cloud.update_instance(self.context, inst['ec2_id'],
|
||||
display_name='c00l 1m4g3')
|
||||
inst = db.instance_get({}, inst['id'])
|
||||
self.assertEqual('c00l 1m4g3', inst['display_name'])
|
||||
|
||||
@@ -53,7 +53,7 @@ os.makedirs(os.path.join(OSS_TEMPDIR, 'images'))
|
||||
os.makedirs(os.path.join(OSS_TEMPDIR, 'buckets'))
|
||||
|
||||
|
||||
class ObjectStoreTestCase(test.BaseTestCase):
|
||||
class ObjectStoreTestCase(test.TrialTestCase):
|
||||
"""Test objectstore API directly."""
|
||||
|
||||
def setUp(self): # pylint: disable-msg=C0103
|
||||
|
||||
@@ -30,7 +30,7 @@ from nova import test
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class RpcTestCase(test.BaseTestCase):
|
||||
class RpcTestCase(test.TrialTestCase):
|
||||
"""Test cases for rpc"""
|
||||
def setUp(self): # pylint: disable-msg=C0103
|
||||
super(RpcTestCase, self).setUp()
|
||||
@@ -39,14 +39,13 @@ class RpcTestCase(test.BaseTestCase):
|
||||
self.consumer = rpc.AdapterConsumer(connection=self.conn,
|
||||
topic='test',
|
||||
proxy=self.receiver)
|
||||
|
||||
self.injected.append(self.consumer.attach_to_tornado(self.ioloop))
|
||||
self.consumer.attach_to_twisted()
|
||||
|
||||
def test_call_succeed(self):
|
||||
"""Get a value through rpc call"""
|
||||
value = 42
|
||||
result = yield rpc.call('test', {"method": "echo",
|
||||
"args": {"value": value}})
|
||||
result = yield rpc.call_twisted('test', {"method": "echo",
|
||||
"args": {"value": value}})
|
||||
self.assertEqual(value, result)
|
||||
|
||||
def test_call_exception(self):
|
||||
@@ -57,12 +56,12 @@ class RpcTestCase(test.BaseTestCase):
|
||||
to an int in the test.
|
||||
"""
|
||||
value = 42
|
||||
self.assertFailure(rpc.call('test', {"method": "fail",
|
||||
"args": {"value": value}}),
|
||||
self.assertFailure(rpc.call_twisted('test', {"method": "fail",
|
||||
"args": {"value": value}}),
|
||||
rpc.RemoteError)
|
||||
try:
|
||||
yield rpc.call('test', {"method": "fail",
|
||||
"args": {"value": value}})
|
||||
yield rpc.call_twisted('test', {"method": "fail",
|
||||
"args": {"value": value}})
|
||||
self.fail("should have thrown rpc.RemoteError")
|
||||
except rpc.RemoteError as exc:
|
||||
self.assertEqual(int(exc.value), value)
|
||||
|
||||
Reference in New Issue
Block a user