Migrate server snapshot tests to requests_mock
Change-Id: Ic6a489ac25688b7666a6a130f7daf43841909f30
This commit is contained in:
parent
cf54ef6b92
commit
413965c331
@ -3314,7 +3314,7 @@ class OpenStackCloud(_normalize.Normalizer):
|
||||
" could not be snapshotted.".format(server=server))
|
||||
server = server_obj
|
||||
image_id = str(self.manager.submit_task(_tasks.ImageSnapshotCreate(
|
||||
image_name=name, server=server, metadata=metadata)))
|
||||
image_name=name, server=server['id'], metadata=metadata)))
|
||||
self.list_images.invalidate(self)
|
||||
image = self.get_image(image_id)
|
||||
|
||||
|
@ -28,6 +28,8 @@ STRAWBERRY_FLAVOR_ID = u'0c1d9008-f546-4608-9e8f-f8bdaec8dddf'
|
||||
COMPUTE_ENDPOINT = 'https://compute.example.com/v2.1'
|
||||
ORCHESTRATION_ENDPOINT = 'https://orchestration.example.com/v1/{p}'.format(
|
||||
p=PROJECT_ID)
|
||||
NO_MD5 = '93b885adfe0da089cdf634904fd59f71'
|
||||
NO_SHA256 = '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d'
|
||||
|
||||
|
||||
def make_fake_flavor(flavor_id, name, ram=100, disk=1600, vcpus=24):
|
||||
@ -177,6 +179,37 @@ def make_fake_stack_event(
|
||||
}
|
||||
|
||||
|
||||
def make_fake_image(
|
||||
image_id=None, md5=NO_MD5, sha256=NO_SHA256, status='active'):
|
||||
return {
|
||||
u'image_state': u'available',
|
||||
u'container_format': u'bare',
|
||||
u'min_ram': 0,
|
||||
u'ramdisk_id': None,
|
||||
u'updated_at': u'2016-02-10T05:05:02Z',
|
||||
u'file': '/v2/images/' + image_id + '/file',
|
||||
u'size': 3402170368,
|
||||
u'image_type': u'snapshot',
|
||||
u'disk_format': u'qcow2',
|
||||
u'id': image_id,
|
||||
u'schema': u'/v2/schemas/image',
|
||||
u'status': status,
|
||||
u'tags': [],
|
||||
u'visibility': u'private',
|
||||
u'locations': [{
|
||||
u'url': u'http://127.0.0.1/images/' + image_id,
|
||||
u'metadata': {}}],
|
||||
u'min_disk': 40,
|
||||
u'virtual_size': None,
|
||||
u'name': u'fake_image',
|
||||
u'checksum': u'ee36e35a297980dee1b514de9803ec6d',
|
||||
u'created_at': u'2016-02-10T05:03:11Z',
|
||||
u'owner_specified.shade.md5': NO_MD5,
|
||||
u'owner_specified.shade.sha256': NO_SHA256,
|
||||
u'owner_specified.shade.object': 'images/fake_image',
|
||||
u'protected': False}
|
||||
|
||||
|
||||
class FakeEndpoint(object):
|
||||
def __init__(self, id, service_id, region, publicurl, internalurl=None,
|
||||
adminurl=None):
|
||||
|
@ -550,7 +550,7 @@ class RequestsMockTestCase(BaseTestCase):
|
||||
mock_method, mock_uri, params['response_list'],
|
||||
**params['kw_params'])
|
||||
|
||||
def assert_calls(self, stop_after=None):
|
||||
def assert_calls(self, stop_after=None, do_count=True):
|
||||
for (x, (call, history)) in enumerate(
|
||||
zip(self.calls, self.adapter.request_history)):
|
||||
if stop_after and x > stop_after:
|
||||
@ -571,4 +571,6 @@ class RequestsMockTestCase(BaseTestCase):
|
||||
self.assertEqual(
|
||||
value, history.headers[key],
|
||||
'header mismatch in call {index}'.format(index=x))
|
||||
self.assertEqual(len(self.calls), len(self.adapter.request_history))
|
||||
if do_count:
|
||||
self.assertEqual(
|
||||
len(self.calls), len(self.adapter.request_history))
|
||||
|
@ -24,11 +24,10 @@ import six
|
||||
import shade
|
||||
from shade import exc
|
||||
from shade import meta
|
||||
from shade.tests import fakes
|
||||
from shade.tests.unit import base
|
||||
|
||||
|
||||
NO_MD5 = '93b885adfe0da089cdf634904fd59f71'
|
||||
NO_SHA256 = '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d'
|
||||
CINDER_URL = 'https://volume.example.com/v2/1c36b64c840a42cd9e9b931a369337f0'
|
||||
|
||||
|
||||
@ -40,33 +39,7 @@ class BaseTestImage(base.RequestsMockTestCase):
|
||||
self.imagefile = tempfile.NamedTemporaryFile(delete=False)
|
||||
self.imagefile.write(b'\0')
|
||||
self.imagefile.close()
|
||||
self.fake_image_dict = {
|
||||
u'image_state': u'available',
|
||||
u'container_format': u'bare',
|
||||
u'min_ram': 0,
|
||||
u'ramdisk_id': None,
|
||||
u'updated_at': u'2016-02-10T05:05:02Z',
|
||||
u'file': '/v2/images/' + self.image_id + '/file',
|
||||
u'size': 3402170368,
|
||||
u'image_type': u'snapshot',
|
||||
u'disk_format': u'qcow2',
|
||||
u'id': self.image_id,
|
||||
u'schema': u'/v2/schemas/image',
|
||||
u'status': u'active',
|
||||
u'tags': [],
|
||||
u'visibility': u'private',
|
||||
u'locations': [{
|
||||
u'url': u'http://127.0.0.1/images/' + self.image_id,
|
||||
u'metadata': {}}],
|
||||
u'min_disk': 40,
|
||||
u'virtual_size': None,
|
||||
u'name': u'fake_image',
|
||||
u'checksum': u'ee36e35a297980dee1b514de9803ec6d',
|
||||
u'created_at': u'2016-02-10T05:03:11Z',
|
||||
u'owner_specified.shade.md5': NO_MD5,
|
||||
u'owner_specified.shade.sha256': NO_SHA256,
|
||||
u'owner_specified.shade.object': 'images/fake_image',
|
||||
u'protected': False}
|
||||
self.fake_image_dict = fakes.make_fake_image(image_id=self.image_id)
|
||||
self.fake_search_return = {'images': [self.fake_image_dict]}
|
||||
self.output = uuid.uuid4().bytes
|
||||
|
||||
@ -193,9 +166,9 @@ class TestImage(BaseTestImage):
|
||||
json={u'container_format': u'bare',
|
||||
u'disk_format': u'qcow2',
|
||||
u'name': u'fake_image',
|
||||
u'owner_specified.shade.md5': NO_MD5,
|
||||
u'owner_specified.shade.md5': fakes.NO_MD5,
|
||||
u'owner_specified.shade.object': u'images/fake_image', # noqa
|
||||
u'owner_specified.shade.sha256': NO_SHA256,
|
||||
u'owner_specified.shade.sha256': fakes.NO_SHA256,
|
||||
u'visibility': u'private'})
|
||||
),
|
||||
dict(method='PUT',
|
||||
@ -275,8 +248,8 @@ class TestImage(BaseTestImage):
|
||||
object=image_name),
|
||||
status_code=201,
|
||||
validate=dict(
|
||||
headers={'x-object-meta-x-shade-md5': NO_MD5,
|
||||
'x-object-meta-x-shade-sha256': NO_SHA256})
|
||||
headers={'x-object-meta-x-shade-md5': fakes.NO_MD5,
|
||||
'x-object-meta-x-shade-sha256': fakes.NO_SHA256})
|
||||
),
|
||||
dict(method='GET', uri='https://image.example.com/v2/images',
|
||||
json={'images': []}),
|
||||
@ -308,9 +281,9 @@ class TestImage(BaseTestImage):
|
||||
container=container_name,
|
||||
object=image_name),
|
||||
u'path': u'/owner_specified.shade.object'},
|
||||
{u'op': u'add', u'value': NO_MD5,
|
||||
{u'op': u'add', u'value': fakes.NO_MD5,
|
||||
u'path': u'/owner_specified.shade.md5'},
|
||||
{u'op': u'add', u'value': NO_SHA256,
|
||||
{u'op': u'add', u'value': fakes.NO_SHA256,
|
||||
u'path': u'/owner_specified.shade.sha256'}],
|
||||
key=operator.itemgetter('value')),
|
||||
headers={
|
||||
|
@ -14,51 +14,100 @@
|
||||
|
||||
import uuid
|
||||
|
||||
import mock
|
||||
|
||||
import shade
|
||||
from shade import exc
|
||||
from shade.tests import fakes
|
||||
from shade.tests.unit import base
|
||||
|
||||
|
||||
class TestImageSnapshot(base.TestCase):
|
||||
class TestImageSnapshot(base.RequestsMockTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestImageSnapshot, self).setUp()
|
||||
self.server_id = str(uuid.uuid4())
|
||||
self.image_id = str(uuid.uuid4())
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_image')
|
||||
def test_create_image_snapshot_wait_until_active_never_active(self,
|
||||
mock_get,
|
||||
mock_nova):
|
||||
mock_nova.servers.create_image.return_value = {
|
||||
'status': 'queued',
|
||||
'id': self.image_id,
|
||||
}
|
||||
mock_get.return_value = {'status': 'saving', 'id': self.image_id}
|
||||
self.assertRaises(exc.OpenStackCloudTimeout,
|
||||
self.cloud.create_image_snapshot,
|
||||
'test-snapshot', dict(id='fake-server'),
|
||||
wait=True, timeout=0.01)
|
||||
def test_create_image_snapshot_wait_until_active_never_active(self):
|
||||
snapshot_name = 'test-snapshot'
|
||||
fake_image = fakes.make_fake_image(self.image_id, status='pending')
|
||||
self.register_uris([
|
||||
dict(
|
||||
method='POST',
|
||||
uri='{endpoint}/servers/{server_id}/action'.format(
|
||||
endpoint=fakes.COMPUTE_ENDPOINT,
|
||||
server_id=self.server_id),
|
||||
headers=dict(
|
||||
Location='{endpoint}/images/{image_id}'.format(
|
||||
endpoint='https://images.example.com',
|
||||
image_id=self.image_id)),
|
||||
validate=dict(
|
||||
json={
|
||||
"createImage": {
|
||||
"name": snapshot_name,
|
||||
"metadata": {},
|
||||
}})),
|
||||
self.get_glance_discovery_mock_dict(),
|
||||
dict(
|
||||
method='GET',
|
||||
uri='https://image.example.com/v2/images',
|
||||
json=dict(images=[fake_image])),
|
||||
])
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_image')
|
||||
def test_create_image_snapshot_wait_active(self, mock_get, mock_nova):
|
||||
mock_nova.servers.create_image.return_value = {
|
||||
'status': 'queued',
|
||||
'id': self.image_id,
|
||||
}
|
||||
mock_get.return_value = {'status': 'active', 'id': self.image_id}
|
||||
self.assertRaises(
|
||||
exc.OpenStackCloudTimeout,
|
||||
self.cloud.create_image_snapshot,
|
||||
snapshot_name, dict(id=self.server_id),
|
||||
wait=True, timeout=0.01)
|
||||
|
||||
# After the fifth call, we just keep polling get images for status.
|
||||
# Due to mocking sleep, we have no clue how many times we'll call it.
|
||||
self.assert_calls(stop_after=5, do_count=False)
|
||||
|
||||
def test_create_image_snapshot_wait_active(self):
|
||||
snapshot_name = 'test-snapshot'
|
||||
pending_image = fakes.make_fake_image(self.image_id, status='pending')
|
||||
fake_image = fakes.make_fake_image(self.image_id)
|
||||
self.register_uris([
|
||||
dict(
|
||||
method='POST',
|
||||
uri='{endpoint}/servers/{server_id}/action'.format(
|
||||
endpoint=fakes.COMPUTE_ENDPOINT,
|
||||
server_id=self.server_id),
|
||||
headers=dict(
|
||||
Location='{endpoint}/images/{image_id}'.format(
|
||||
endpoint='https://images.example.com',
|
||||
image_id=self.image_id)),
|
||||
validate=dict(
|
||||
json={
|
||||
"createImage": {
|
||||
"name": snapshot_name,
|
||||
"metadata": {},
|
||||
}})),
|
||||
self.get_glance_discovery_mock_dict(),
|
||||
dict(
|
||||
method='GET',
|
||||
uri='https://image.example.com/v2/images',
|
||||
json=dict(images=[pending_image])),
|
||||
dict(
|
||||
method='GET',
|
||||
uri='https://image.example.com/v2/images',
|
||||
json=dict(images=[fake_image])),
|
||||
])
|
||||
image = self.cloud.create_image_snapshot(
|
||||
'test-snapshot', dict(id='fake-server'), wait=True, timeout=2)
|
||||
'test-snapshot', dict(id=self.server_id), wait=True, timeout=2)
|
||||
self.assertEqual(image['id'], self.image_id)
|
||||
|
||||
@mock.patch.object(shade.OpenStackCloud, 'get_server')
|
||||
def test_create_image_snapshot_bad_name_exception(
|
||||
self, mock_get_server):
|
||||
mock_get_server.return_value = None
|
||||
self.assert_calls()
|
||||
|
||||
def test_create_image_snapshot_bad_name_exception(self):
|
||||
self.register_uris([
|
||||
dict(
|
||||
method='POST',
|
||||
uri='{endpoint}/servers/{server_id}/action'.format(
|
||||
endpoint=fakes.COMPUTE_ENDPOINT,
|
||||
server_id=self.server_id),
|
||||
json=dict(servers=[])),
|
||||
])
|
||||
self.assertRaises(
|
||||
exc.OpenStackCloudException,
|
||||
self.cloud.create_image_snapshot,
|
||||
'test-snapshot', 'missing-server')
|
||||
'test-snapshot', self.server_id)
|
||||
|
Loading…
Reference in New Issue
Block a user