234 lines
10 KiB
Python
234 lines
10 KiB
Python
# Copyright 2014
|
|
# The Cloudscaling Group, Inc.
|
|
#
|
|
# 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 mock
|
|
from novaclient import exceptions as nova_exception
|
|
|
|
from ec2api import exception
|
|
from ec2api.metadata import api
|
|
from ec2api.tests.unit import base
|
|
from ec2api.tests.unit import fakes
|
|
from ec2api.tests.unit import matchers
|
|
|
|
|
|
class MetadataApiTestCase(base.ApiTestCase):
|
|
# TODO(ft): 'execute' feature isn't used here, but some mocks and
|
|
# fake context are. ApiTestCase should be split to some classes to use
|
|
# its feature optimally
|
|
|
|
def setUp(self):
|
|
super(MetadataApiTestCase, self).setUp()
|
|
|
|
instance_api_patcher = mock.patch('ec2api.metadata.api.instance_api')
|
|
self.instance_api = instance_api_patcher.start()
|
|
self.addCleanup(instance_api_patcher.stop)
|
|
|
|
self.set_mock_db_items(fakes.DB_INSTANCE_1)
|
|
self.instance_api.describe_instances.return_value = {
|
|
'reservationSet': [fakes.EC2_RESERVATION_1]}
|
|
self.instance_api.describe_instance_attribute.return_value = {
|
|
'instanceId': fakes.ID_EC2_INSTANCE_1,
|
|
'userData': {'value': 'fake_user_data'}}
|
|
|
|
self.fake_context = self._create_context()
|
|
|
|
def test_get_version_list(self):
|
|
retval = api.get_version_list()
|
|
self.assertEqual('\n'.join(api.VERSIONS + ['latest']), retval)
|
|
|
|
def test_get_instance_and_project_id(self):
|
|
self.nova.servers.list.return_value = [
|
|
fakes.OSInstance(fakes.OS_INSTANCE_1),
|
|
fakes.OSInstance(fakes.OS_INSTANCE_2)]
|
|
self.nova.fixed_ips.get.return_value = mock.Mock(hostname='fake_name')
|
|
self.assertEqual(
|
|
(fakes.ID_OS_INSTANCE_1, fakes.ID_OS_PROJECT),
|
|
api.get_os_instance_and_project_id(self.fake_context,
|
|
fakes.IP_NETWORK_INTERFACE_2))
|
|
self.nova.fixed_ips.get.assert_called_with(
|
|
fakes.IP_NETWORK_INTERFACE_2)
|
|
self.nova.servers.list.assert_called_with(
|
|
search_opts={'hostname': 'fake_name',
|
|
'all_tenants': True})
|
|
|
|
def check_raise():
|
|
self.assertRaises(exception.EC2MetadataNotFound,
|
|
api.get_os_instance_and_project_id,
|
|
self.fake_context,
|
|
fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
self.nova.servers.list.return_value = [
|
|
fakes.OSInstance(fakes.OS_INSTANCE_2)]
|
|
check_raise()
|
|
|
|
self.nova.fixed_ips.get.side_effect = nova_exception.NotFound('fake')
|
|
self.nova.servers.list.return_value = [
|
|
fakes.OSInstance(fakes.OS_INSTANCE_1),
|
|
fakes.OSInstance(fakes.OS_INSTANCE_2)]
|
|
check_raise()
|
|
|
|
def test_get_version_root(self):
|
|
retval = api.get_metadata_item(self.fake_context, ['2009-04-04'],
|
|
fakes.ID_OS_INSTANCE_1,
|
|
fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual('meta-data/\nuser-data', retval)
|
|
|
|
self.assertRaises(
|
|
exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context, ['9999-99-99'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
self.db_api.get_item_ids.assert_called_with(
|
|
self.fake_context, 'i', (fakes.ID_OS_INSTANCE_1,))
|
|
self.instance_api.describe_instances.assert_called_with(
|
|
self.fake_context, [fakes.ID_EC2_INSTANCE_1])
|
|
self.instance_api.describe_instance_attribute.assert_called_with(
|
|
self.fake_context, fakes.ID_EC2_INSTANCE_1, 'userData')
|
|
|
|
def test_invalid_path(self):
|
|
self.assertRaises(exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context,
|
|
['9999-99-99', 'user-data-invalid'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
def test_mismatch_project_id(self):
|
|
self.fake_context.project_id = fakes.random_os_id()
|
|
self.assertRaises(
|
|
exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context, ['2009-04-04'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
def test_non_existing_instance(self):
|
|
self.instance_api.describe_instances.return_value = {
|
|
'reservationSet': []}
|
|
self.assertRaises(
|
|
exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context, ['2009-04-04'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
def test_user_data(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context, ['2009-04-04', 'user-data'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual('fake_user_data', retval)
|
|
|
|
def test_no_user_data(self):
|
|
self.instance_api.describe_instance_attribute.return_value = {
|
|
'instanceId': fakes.ID_EC2_INSTANCE_1}
|
|
self.assertRaises(
|
|
exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context,
|
|
['2009-04-04', 'user-data'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
def test_security_groups(self):
|
|
self.instance_api.describe_instances.return_value = {
|
|
'reservationSet': [fakes.EC2_RESERVATION_2]}
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'security-groups'],
|
|
fakes.ID_OS_INSTANCE_2, fakes.IP_NETWORK_INTERFACE_1)
|
|
self.assertEqual('\n'.join([fakes.NAME_DEFAULT_OS_SECURITY_GROUP,
|
|
fakes.NAME_OTHER_OS_SECURITY_GROUP]),
|
|
retval)
|
|
|
|
def test_local_hostname(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'local-hostname'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual(fakes.EC2_INSTANCE_1['privateDnsName'], retval)
|
|
|
|
def test_local_ipv4(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'local-ipv4'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual(fakes.IP_NETWORK_INTERFACE_2, retval)
|
|
|
|
def test_local_ipv4_from_address(self):
|
|
self.instance_api.describe_instances.return_value = {
|
|
'reservationSet': [fakes.EC2_RESERVATION_2]}
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'local-ipv4'],
|
|
fakes.ID_OS_INSTANCE_2, fakes.IP_NETWORK_INTERFACE_1)
|
|
self.assertEqual(fakes.IP_NETWORK_INTERFACE_1, retval)
|
|
|
|
@mock.patch('novaclient.client.Client')
|
|
def test_pubkey(self, nova):
|
|
keypair = mock.Mock(public_key=fakes.PUBLIC_KEY_KEY_PAIR)
|
|
keypair.configure_mock(name=fakes.NAME_KEY_PAIR)
|
|
nova.return_value.keypairs.get.return_value = keypair
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'public-keys'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual('0=%s' % fakes.NAME_KEY_PAIR, retval)
|
|
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'public-keys', '0', 'openssh-key'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual(fakes.PUBLIC_KEY_KEY_PAIR, retval)
|
|
|
|
def test_image_type_ramdisk(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'ramdisk-id'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual(fakes.ID_EC2_IMAGE_ARI_1, retval)
|
|
|
|
def test_image_type_kernel(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'kernel-id'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertEqual(fakes.ID_EC2_IMAGE_AKI_1, retval)
|
|
|
|
def test_check_version(self):
|
|
retval = api.get_metadata_item(
|
|
self.fake_context,
|
|
['2009-04-04', 'meta-data', 'block-device-mapping'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
self.assertIsNotNone(retval)
|
|
|
|
self.assertRaises(
|
|
exception.EC2MetadataNotFound,
|
|
api.get_metadata_item, self.fake_context,
|
|
['2007-08-29', 'meta-data', 'block-device-mapping'],
|
|
fakes.ID_OS_INSTANCE_1, fakes.IP_NETWORK_INTERFACE_2)
|
|
|
|
def test_format_instance_mapping(self):
|
|
self.instance_api._block_device_strip_dev.return_value = 'vda'
|
|
retval = api._build_block_device_mappings(
|
|
'fake_context', fakes.EC2_INSTANCE_1, fakes.ID_OS_INSTANCE_1)
|
|
self.assertThat(retval,
|
|
matchers.DictMatches(
|
|
{'ami': 'vda',
|
|
'root': fakes.ROOT_DEVICE_NAME_INSTANCE_1}))
|
|
self.instance_api._block_device_strip_dev.assert_called_with(
|
|
fakes.EC2_INSTANCE_1['rootDeviceName'])
|
|
|
|
self.instance_api._block_device_strip_dev.return_value = 'sdb1'
|
|
retval = api._build_block_device_mappings(
|
|
'fake_context', fakes.EC2_INSTANCE_2, fakes.ID_OS_INSTANCE_2)
|
|
expected = {'ami': 'sdb1',
|
|
'root': fakes.ROOT_DEVICE_NAME_INSTANCE_2}
|
|
expected.update(fakes.EC2_BDM_METADATA_INSTANCE_2)
|
|
self.assertThat(retval,
|
|
matchers.DictMatches(expected))
|
|
self.instance_api._block_device_strip_dev.assert_called_with(
|
|
fakes.EC2_INSTANCE_2['rootDeviceName'])
|