Sync trunk

This commit is contained in:
Donal Lafferty
2011-08-07 21:42:46 +01:00
6 changed files with 233 additions and 9 deletions

View File

@@ -592,6 +592,31 @@ class FixedIpCommands(object):
fixed_ip['address'],
mac_address, hostname, host)
@args('--address', dest="address", metavar='<ip address>',
help='IP address')
def reserve(self, address):
"""Mark fixed ip as reserved
arguments: address"""
self._set_reserved(address, True)
@args('--address', dest="address", metavar='<ip address>',
help='IP address')
def unreserve(self, address):
"""Mark fixed ip as free to use
arguments: address"""
self._set_reserved(address, False)
def _set_reserved(self, address, reserved):
ctxt = context.get_admin_context()
try:
fixed_ip = db.fixed_ip_get_by_address(ctxt, address)
db.fixed_ip_update(ctxt, fixed_ip['address'],
{'reserved': reserved})
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
class FloatingIpCommands(object):
"""Class for managing floating ip."""
@@ -1235,11 +1260,12 @@ class ImageCommands(object):
is_public, architecture)
def _lookup(self, old_image_id):
elevated = context.get_admin_context()
try:
internal_id = ec2utils.ec2_id_to_id(old_image_id)
image = self.image_service.show(context, internal_id)
image = self.image_service.show(elevated, internal_id)
except (exception.InvalidEc2Id, exception.ImageNotFound):
image = self.image_service.show_by_name(context, old_image_id)
image = self.image_service.show_by_name(elevated, old_image_id)
return image['id']
def _old_to_new(self, old):

View File

@@ -58,12 +58,13 @@ class ZoneAwareScheduler(driver.Scheduler):
"""Create the requested resource in this Zone."""
host = build_plan_item['hostname']
base_options = request_spec['instance_properties']
image = request_spec['image']
# TODO(sandy): I guess someone needs to add block_device_mapping
# support at some point? Also, OS API has no concept of security
# groups.
instance = compute_api.API().create_db_entry_for_new_instance(context,
base_options, None, [])
image, base_options, None, [])
instance_id = instance['id']
kwargs['instance_id'] = instance_id

View File

@@ -21,7 +21,9 @@ import json
import nova.db
from nova import exception
from nova import rpc
from nova import test
from nova.compute import api as compute_api
from nova.scheduler import driver
from nova.scheduler import zone_aware_scheduler
from nova.scheduler import zone_manager
@@ -114,7 +116,7 @@ def fake_provision_resource_from_blob(context, item, instance_id,
def fake_decrypt_blob_returns_local_info(blob):
return {'foo': True} # values aren't important.
return {'hostname': 'foooooo'} # values aren't important.
def fake_decrypt_blob_returns_child_info(blob):
@@ -283,14 +285,29 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
global was_called
sched = FakeZoneAwareScheduler()
was_called = False
def fake_create_db_entry_for_new_instance(self, context,
image, base_options, security_group,
block_device_mapping, num=1):
global was_called
was_called = True
# return fake instances
return {'id': 1, 'uuid': 'f874093c-7b17-49c0-89c3-22a5348497f9'}
def fake_rpc_cast(*args, **kwargs):
pass
self.stubs.Set(sched, '_decrypt_blob',
fake_decrypt_blob_returns_local_info)
self.stubs.Set(sched, '_provision_resource_locally',
fake_provision_resource_locally)
self.stubs.Set(compute_api.API,
'create_db_entry_for_new_instance',
fake_create_db_entry_for_new_instance)
self.stubs.Set(rpc, 'cast', fake_rpc_cast)
request_spec = {'blob': "Non-None blob data"}
build_plan_item = {'blob': "Non-None blob data"}
request_spec = {'image': {}, 'instance_properties': {}}
sched._provision_resource_from_blob(None, request_spec, 1,
sched._provision_resource_from_blob(None, build_plan_item, 1,
request_spec, {})
self.assertTrue(was_called)

134
nova/tests/test_image.py Normal file
View File

@@ -0,0 +1,134 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC
# Author: Soren Hansen
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import datetime
from nova import context
from nova import exception
from nova import test
import nova.image
class _ImageTestCase(test.TestCase):
def setUp(self):
super(_ImageTestCase, self).setUp()
self.context = context.get_admin_context()
def test_index(self):
res = self.image_service.index(self.context)
for image in res:
self.assertEquals(set(image.keys()), set(['id', 'name']))
def test_detail(self):
res = self.image_service.detail(self.context)
for image in res:
keys = set(image.keys())
self.assertEquals(keys, set(['id', 'name', 'created_at',
'updated_at', 'deleted_at', 'deleted',
'status', 'is_public', 'properties']))
self.assertTrue(isinstance(image['created_at'], datetime.datetime))
self.assertTrue(isinstance(image['updated_at'], datetime.datetime))
if not (isinstance(image['deleted_at'], datetime.datetime) or
image['deleted_at'] is None):
self.fail('image\'s "deleted_at" attribute was neither a '
'datetime object nor None')
def check_is_bool(image, key):
val = image.get('deleted')
if not isinstance(val, bool):
self.fail('image\'s "%s" attribute wasn\'t '
'a bool: %r' % (key, val))
check_is_bool(image, 'deleted')
check_is_bool(image, 'is_public')
def test_index_and_detail_have_same_results(self):
index = self.image_service.index(self.context)
detail = self.image_service.detail(self.context)
index_set = set([(i['id'], i['name']) for i in index])
detail_set = set([(i['id'], i['name']) for i in detail])
self.assertEqual(index_set, detail_set)
def test_show_raises_imagenotfound_for_invalid_id(self):
self.assertRaises(exception.ImageNotFound,
self.image_service.show,
self.context,
'this image does not exist')
def test_show_by_name(self):
self.assertRaises(exception.ImageNotFound,
self.image_service.show_by_name,
self.context,
'this image does not exist')
def test_create_adds_id(self):
index = self.image_service.index(self.context)
image_count = len(index)
self.image_service.create(self.context, {})
index = self.image_service.index(self.context)
self.assertEquals(len(index), image_count + 1)
self.assertTrue(index[0]['id'])
def test_create_keeps_id(self):
self.image_service.create(self.context, {'id': '34'})
self.image_service.show(self.context, '34')
def test_create_rejects_duplicate_ids(self):
self.image_service.create(self.context, {'id': '34'})
self.assertRaises(exception.Duplicate,
self.image_service.create,
self.context,
{'id': '34'})
# Make sure there's still one left
self.image_service.show(self.context, '34')
def test_update(self):
self.image_service.create(self.context,
{'id': '34', 'foo': 'bar'})
self.image_service.update(self.context, '34',
{'id': '34', 'foo': 'baz'})
img = self.image_service.show(self.context, '34')
self.assertEquals(img['foo'], 'baz')
def test_delete(self):
self.image_service.create(self.context, {'id': '34', 'foo': 'bar'})
self.image_service.delete(self.context, '34')
self.assertRaises(exception.NotFound,
self.image_service.show,
self.context,
'34')
def test_delete_all(self):
self.image_service.create(self.context, {'id': '32', 'foo': 'bar'})
self.image_service.create(self.context, {'id': '33', 'foo': 'bar'})
self.image_service.create(self.context, {'id': '34', 'foo': 'bar'})
self.image_service.delete_all()
index = self.image_service.index(self.context)
self.assertEquals(len(index), 0)
class FakeImageTestCase(_ImageTestCase):
def setUp(self):
super(FakeImageTestCase, self).setUp()
self.image_service = nova.image.fake.FakeImageService()

View File

@@ -0,0 +1,47 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova import test
class ExampleSkipTestCase(test.TestCase):
test_counter = 0
@test.skip_test("Example usage of @test.skip_test()")
def test_skip_test_example(self):
self.fail("skip_test failed to work properly.")
@test.skip_if(True, "Example usage of @test.skip_if()")
def test_skip_if_example(self):
self.fail("skip_if failed to work properly.")
@test.skip_unless(False, "Example usage of @test.skip_unless()")
def test_skip_unless_example(self):
self.fail("skip_unless failed to work properly.")
@test.skip_if(False, "This test case should never be skipped.")
def test_001_increase_test_counter(self):
ExampleSkipTestCase.test_counter += 1
@test.skip_unless(True, "This test case should never be skipped.")
def test_002_increase_test_counter(self):
ExampleSkipTestCase.test_counter += 1
def test_003_verify_test_counter(self):
self.assertEquals(ExampleSkipTestCase.test_counter, 2,
"Tests were not skipped appropriately")

View File

@@ -772,7 +772,6 @@ class XenAPIMigrateInstance(test.TestCase):
conn = xenapi_conn.get_connection(False)
conn.migrate_disk_and_power_off(instance, '127.0.0.1')
def test_revert_migrate(self):
instance = db.instance_create(self.context, self.values)
self.called = False