Files
python-glanceclient/tests/v1/test_images.py
Chris Buccella f0635ecf39 Return request ID to callers
Currently, calls (create, get, etc.) return only the Image to a
caller. In order to log a mapping the request IDs of both glanceclient
and the caller, the x-openstack-request-id header value is needed on
the server side. This change allows that value to be bubbled up and
returned to the caller so that the appropriate logging can occur.
The return_req_id parameter can be set by services that are logging
request IDs. Glance's request ID will then be returned via the
return_req_id parameter.

This is a prerequisite for Log Request ID Mappings nova-spec to
be completed; Change Ib9b820a0feeb0c0e828ed3e4fab8261f8761ba9a

Change I43be05c351f901cee5509c76cff6d69f060c0b3f is an example of
a caller using this.

Implements: blueprint return-req-id
Change-Id: Ia82aa14db5f0e453010514fffb9a25d7b0fc2fd1
2014-04-25 10:26:40 -04:00

964 lines
31 KiB
Python

# Copyright 2012 OpenStack Foundation
# 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.
import errno
import json
import sys
import testtools
import six
from six.moves.urllib import parse
from glanceclient.v1 import client
from glanceclient.v1 import images
from glanceclient.v1 import legacy_shell
from glanceclient.v1 import shell
from tests import utils
fixtures = {
'/v1/images': {
'POST': (
{
'location': '/v1/images/1',
'x-openstack-request-id': 'req-1234',
},
json.dumps(
{'image': {
'id': '1',
'name': 'image-1',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': '1024',
'min_ram': '512',
'min_disk': '10',
'properties': {'a': 'b', 'c': 'd'},
'is_public': False,
'protected': False,
'deleted': False,
}},
),
),
},
'/v1/images/detail?limit=20': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?is_public=None&limit=20': {
'GET': (
{'x-openstack-request-id': 'req-1234'},
{'images': [
{
'id': 'a',
'owner': 'A',
'is_public': 'True',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'owner': 'B',
'is_public': 'False',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
{
'id': 'c',
'is_public': 'False',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?is_public=None&limit=5': {
'GET': (
{},
{'images': [
{
'id': 'a',
'owner': 'A',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'owner': 'B',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b2',
'owner': 'B',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
{
'id': 'c',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?limit=5': {
'GET': (
{},
{'images': [
{
'id': 'a',
'owner': 'A',
'is_public': 'False',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'owner': 'A',
'is_public': 'False',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b2',
'owner': 'B',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
{
'id': 'c',
'is_public': 'True',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?marker=a&limit=20': {
'GET': (
{},
{'images': [
{
'id': 'b',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'c',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?limit=1': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-0',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?marker=a&limit=1': {
'GET': (
{},
{'images': [
{
'id': 'b',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?limit=2': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?marker=b&limit=2': {
'GET': (
{},
{'images': [
{
'id': 'c',
'name': 'image-3',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?limit=20&name=foo': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?property-ping=pong&limit=20':
{
'GET': (
{},
{'images': [
{
'id': '1',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?sort_dir=desc&limit=20': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/detail?sort_key=name&limit=20': {
'GET': (
{},
{'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]},
),
},
'/v1/images/1': {
'HEAD': (
{
'x-image-meta-id': '1',
'x-image-meta-name': 'image-1',
'x-image-meta-property-arch': 'x86_64',
'x-image-meta-is_public': 'false',
'x-image-meta-protected': 'false',
'x-image-meta-deleted': 'false',
},
None),
'GET': (
{},
'XXX',
),
'PUT': (
{},
json.dumps(
{'image': {
'id': '1',
'name': 'image-2',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': '1024',
'min_ram': '512',
'min_disk': '10',
'properties': {'a': 'b', 'c': 'd'},
'is_public': False,
'protected': False,
}},
),
),
'DELETE': ({}, None),
},
'/v1/images/2': {
'HEAD': (
{
'x-image-meta-id': '2'
},
None,
),
'GET': (
{
'x-image-meta-checksum': 'wrong'
},
'YYY',
),
},
'/v1/images/3': {
'HEAD': (
{
'x-image-meta-id': '3',
'x-image-meta-name': "ni\xc3\xb1o"
},
None,
),
'GET': (
{
'x-image-meta-checksum': '0745064918b49693cca64d6b6a13d28a'
},
'ZZZ',
),
},
'/v1/images/4': {
'HEAD': (
{
'x-image-meta-id': '4',
'x-image-meta-name': 'image-4',
'x-image-meta-property-arch': 'x86_64',
'x-image-meta-is_public': 'false',
'x-image-meta-protected': 'false',
'x-image-meta-deleted': 'false',
'x-openstack-request-id': 'req-1234',
},
None),
'GET': (
{
'x-openstack-request-id': 'req-1234',
},
'XXX',
),
'PUT': (
{
'x-openstack-request-id': 'req-1234',
},
json.dumps(
{'image': {
'id': '4',
'name': 'image-4',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': '1024',
'min_ram': '512',
'min_disk': '10',
'properties': {'a': 'b', 'c': 'd'},
'is_public': False,
'protected': False,
}},
),
),
'DELETE': (
{
'x-openstack-request-id': 'req-1234',
},
None),
},
'/v1/images/v2_created_img': {
'PUT': (
{},
json.dumps({
"image": {
"status": "queued",
"deleted": False,
"container_format": "bare",
"min_ram": 0,
"updated_at": "2013-12-20T01:51:45",
"owner": "foo",
"min_disk": 0,
"is_public": False,
"deleted_at": None,
"id": "v2_created_img",
"size": None,
"name": "bar",
"checksum": None,
"created_at": "2013-12-20T01:50:38",
"disk_format": "qcow2",
"properties": {},
"protected": False
}
})
),
},
}
class ImageManagerTest(testtools.TestCase):
def setUp(self):
super(ImageManagerTest, self).setUp()
self.api = utils.FakeAPI(fixtures)
self.mgr = images.ImageManager(self.api)
def test_paginated_list(self):
images = list(self.mgr.list(page_size=2))
expect = [
('GET', '/v1/images/detail?limit=2', {}, None),
('GET', '/v1/images/detail?marker=b&limit=2', {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertEqual(3, len(images))
self.assertEqual('a', images[0].id)
self.assertEqual('b', images[1].id)
self.assertEqual('c', images[2].id)
def test_list_with_limit_less_than_page_size(self):
results = list(self.mgr.list(page_size=2, limit=1))
expect = [('GET', '/v1/images/detail?limit=2', {}, None)]
self.assertEqual(1, len(results))
self.assertEqual(expect, self.api.calls)
def test_list_with_limit_greater_than_page_size(self):
images = list(self.mgr.list(page_size=1, limit=2))
expect = [
('GET', '/v1/images/detail?limit=1', {}, None),
('GET', '/v1/images/detail?marker=a&limit=1', {}, None),
]
self.assertEqual(2, len(images))
self.assertEqual('a', images[0].id)
self.assertEqual('b', images[1].id)
self.assertEqual(expect, self.api.calls)
def test_list_with_marker(self):
list(self.mgr.list(marker='a'))
url = '/v1/images/detail?marker=a&limit=20'
expect = [('GET', url, {}, None)]
self.assertEqual(expect, self.api.calls)
def test_list_with_filter(self):
list(self.mgr.list(filters={'name': "foo"}))
url = '/v1/images/detail?limit=20&name=foo'
expect = [('GET', url, {}, None)]
self.assertEqual(expect, self.api.calls)
def test_list_with_property_filters(self):
list(self.mgr.list(filters={'properties': {'ping': 'pong'}}))
url = '/v1/images/detail?property-ping=pong&limit=20'
expect = [('GET', url, {}, None)]
self.assertEqual(expect, self.api.calls)
def test_list_with_sort_dir(self):
list(self.mgr.list(sort_dir='desc'))
url = '/v1/images/detail?sort_dir=desc&limit=20'
expect = [('GET', url, {}, None)]
self.assertEqual(expect, self.api.calls)
def test_list_with_sort_key(self):
list(self.mgr.list(sort_key='name'))
url = '/v1/images/detail?sort_key=name&limit=20'
expect = [('GET', url, {}, None)]
self.assertEqual(expect, self.api.calls)
def test_get(self):
image = self.mgr.get('1')
expect = [('HEAD', '/v1/images/1', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('1', image.id)
self.assertEqual('image-1', image.name)
self.assertEqual(False, image.is_public)
self.assertEqual(False, image.protected)
self.assertEqual(False, image.deleted)
self.assertEqual({u'arch': u'x86_64'}, image.properties)
def test_get_int(self):
image = self.mgr.get(1)
expect = [('HEAD', '/v1/images/1', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('1', image.id)
self.assertEqual('image-1', image.name)
self.assertEqual(False, image.is_public)
self.assertEqual(False, image.protected)
self.assertEqual(False, image.deleted)
self.assertEqual({u'arch': u'x86_64'}, image.properties)
def test_get_encoding(self):
image = self.mgr.get('3')
expect = [('HEAD', '/v1/images/3', {}, None)]
self.assertEqual(u"ni\xf1o", image.name)
def test_get_req_id(self):
params = {'return_req_id': []}
image = self.mgr.get('4', **params)
expect_req_id = ['req-1234']
self.assertEqual(expect_req_id, params['return_req_id'])
def test_data(self):
data = ''.join([b for b in self.mgr.data('1', do_checksum=False)])
expect = [('GET', '/v1/images/1', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('XXX', data)
expect += [('GET', '/v1/images/1', {}, None)]
data = ''.join([b for b in self.mgr.data('1')])
self.assertEqual(expect, self.api.calls)
self.assertEqual('XXX', data)
def test_data_with_wrong_checksum(self):
data = ''.join([b for b in self.mgr.data('2', do_checksum=False)])
expect = [('GET', '/v1/images/2', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('YYY', data)
expect += [('GET', '/v1/images/2', {}, None)]
data = self.mgr.data('2')
self.assertEqual(expect, self.api.calls)
try:
data = ''.join([b for b in data])
self.fail('data did not raise an error.')
except IOError as e:
self.assertEqual(errno.EPIPE, e.errno)
msg = 'was fd7c5c4fdaa97163ee4ba8842baa537a expected wrong'
self.assertTrue(msg in str(e))
def test_data_req_id(self):
params = {
'do_checksum': False,
'return_req_id': [],
}
data = ''.join([b for b in self.mgr.data('4', **params)])
expect_req_id = ['req-1234']
self.assertEqual(expect_req_id, params['return_req_id'])
def test_data_with_checksum(self):
data = ''.join([b for b in self.mgr.data('3', do_checksum=False)])
expect = [('GET', '/v1/images/3', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('ZZZ', data)
expect += [('GET', '/v1/images/3', {}, None)]
data = ''.join([b for b in self.mgr.data('3')])
self.assertEqual(expect, self.api.calls)
self.assertEqual('ZZZ', data)
def test_delete(self):
self.mgr.delete('1')
expect = [('DELETE', '/v1/images/1', {}, None)]
self.assertEqual(expect, self.api.calls)
def test_delete_req_id(self):
params = {
'return_req_id': []
}
self.mgr.delete('4', **params)
expect = [('DELETE', '/v1/images/4', {}, None)]
self.assertEqual(self.api.calls, expect)
expect_req_id = ['req-1234']
self.assertEqual(expect_req_id, params['return_req_id'])
def test_create_without_data(self):
params = {
'id': '1',
'name': 'image-1',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': 1024,
'min_ram': 512,
'min_disk': 10,
'copy_from': 'http://example.com',
'properties': {'a': 'b', 'c': 'd'},
}
image = self.mgr.create(**params)
expect_headers = {
'x-image-meta-id': '1',
'x-image-meta-name': 'image-1',
'x-image-meta-container_format': 'ovf',
'x-image-meta-disk_format': 'vhd',
'x-image-meta-owner': 'asdf',
'x-image-meta-size': '1024',
'x-image-meta-min_ram': '512',
'x-image-meta-min_disk': '10',
'x-glance-api-copy-from': 'http://example.com',
'x-image-meta-property-a': 'b',
'x-image-meta-property-c': 'd',
}
expect = [('POST', '/v1/images', expect_headers, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('1', image.id)
self.assertEqual('image-1', image.name)
self.assertEqual('ovf', image.container_format)
self.assertEqual('vhd', image.disk_format)
self.assertEqual('asdf', image.owner)
self.assertEqual(1024, image.size)
self.assertEqual(512, image.min_ram)
self.assertEqual(10, image.min_disk)
self.assertEqual(False, image.is_public)
self.assertEqual(False, image.protected)
self.assertEqual(False, image.deleted)
self.assertEqual({'a': 'b', 'c': 'd'}, image.properties)
def test_create_with_data(self):
image_data = six.StringIO('XXX')
self.mgr.create(data=image_data)
expect_headers = {'x-image-meta-size': '3'}
expect = [('POST', '/v1/images', expect_headers, image_data)]
self.assertEqual(expect, self.api.calls)
def test_create_req_id(self):
params = {
'id': '4',
'name': 'image-4',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': 1024,
'min_ram': 512,
'min_disk': 10,
'copy_from': 'http://example.com',
'properties': {'a': 'b', 'c': 'd'},
'return_req_id': [],
}
image = self.mgr.create(**params)
expect_headers = {
'x-image-meta-id': '4',
'x-image-meta-name': 'image-4',
'x-image-meta-container_format': 'ovf',
'x-image-meta-disk_format': 'vhd',
'x-image-meta-owner': 'asdf',
'x-image-meta-size': '1024',
'x-image-meta-min_ram': '512',
'x-image-meta-min_disk': '10',
'x-glance-api-copy-from': 'http://example.com',
'x-image-meta-property-a': 'b',
'x-image-meta-property-c': 'd',
}
expect = [('POST', '/v1/images', expect_headers, None)]
self.assertEqual(self.api.calls, expect)
self.assertEqual(image.id, '1')
expect_req_id = ['req-1234']
self.assertEqual(expect_req_id, params['return_req_id'])
def test_update(self):
fields = {
'name': 'image-2',
'container_format': 'ovf',
'disk_format': 'vhd',
'owner': 'asdf',
'size': 1024,
'min_ram': 512,
'min_disk': 10,
'copy_from': 'http://example.com',
'properties': {'a': 'b', 'c': 'd'},
'deleted': False,
}
image = self.mgr.update('1', **fields)
expect_hdrs = {
'x-image-meta-name': 'image-2',
'x-image-meta-container_format': 'ovf',
'x-image-meta-disk_format': 'vhd',
'x-image-meta-owner': 'asdf',
'x-image-meta-size': '1024',
'x-image-meta-min_ram': '512',
'x-image-meta-min_disk': '10',
'x-glance-api-copy-from': 'http://example.com',
'x-image-meta-property-a': 'b',
'x-image-meta-property-c': 'd',
'x-image-meta-deleted': 'False',
}
expect = [('PUT', '/v1/images/1', expect_hdrs, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('1', image.id)
self.assertEqual('image-2', image.name)
self.assertEqual(1024, image.size)
self.assertEqual(512, image.min_ram)
self.assertEqual(10, image.min_disk)
def test_update_with_data(self):
image_data = six.StringIO('XXX')
self.mgr.update('1', data=image_data)
expect_headers = {'x-image-meta-size': '3'}
expect = [('PUT', '/v1/images/1', expect_headers, image_data)]
self.assertEqual(expect, self.api.calls)
def test_update_with_purge_props(self):
self.mgr.update('1', purge_props=True)
expect_headers = {'x-glance-registry-purge-props': 'true'}
expect = [('PUT', '/v1/images/1', expect_headers, None)]
self.assertEqual(expect, self.api.calls)
def test_update_req_id(self):
fields = {
'purge_props': True,
'return_req_id': [],
}
self.mgr.update('4', **fields)
expect_headers = {'x-glance-registry-purge-props': 'true'}
expect = [('PUT', '/v1/images/4', expect_headers, None)]
self.assertEqual(self.api.calls, expect)
expect_req_id = ['req-1234']
self.assertEqual(expect_req_id, fields['return_req_id'])
def test_image_meta_from_headers_encoding(self):
fields = {"x-image-meta-name": "ni\xc3\xb1o"}
headers = self.mgr._image_meta_from_headers(fields)
self.assertEqual(u"ni\xf1o", headers["name"])
def test_image_list_with_owner(self):
images = self.mgr.list(owner='A', page_size=20)
image_list = list(images)
self.assertEqual('A', image_list[0].owner)
self.assertEqual('a', image_list[0].id)
self.assertEqual(1, len(image_list))
def test_image_list_with_owner_req_id(self):
fields = {
'owner': 'A',
'return_req_id': [],
}
images = self.mgr.list(**fields)
images.next()
self.assertEqual(fields['return_req_id'], ['req-1234'])
def test_image_list_with_notfound_owner(self):
images = self.mgr.list(owner='X', page_size=20)
self.assertEqual(0, len(list(images)))
def test_image_list_with_empty_string_owner(self):
images = self.mgr.list(owner='', page_size=20)
image_list = list(images)
self.assertRaises(AttributeError, lambda: image_list[0].owner)
self.assertEqual('c', image_list[0].id)
self.assertEqual(1, len(image_list))
def test_image_list_with_unspecified_owner(self):
images = self.mgr.list(owner=None, page_size=5)
image_list = list(images)
self.assertEqual('A', image_list[0].owner)
self.assertEqual('a', image_list[0].id)
self.assertEqual('A', image_list[1].owner)
self.assertEqual('b', image_list[1].id)
self.assertEqual('B', image_list[2].owner)
self.assertEqual('b2', image_list[2].id)
self.assertRaises(AttributeError, lambda: image_list[3].owner)
self.assertEqual('c', image_list[3].id)
self.assertEqual(4, len(image_list))
def test_image_list_with_owner_and_limit(self):
images = self.mgr.list(owner='B', page_size=5, limit=1)
image_list = list(images)
self.assertEqual('B', image_list[0].owner)
self.assertEqual('b', image_list[0].id)
self.assertEqual(1, len(image_list))
def test_image_list_all_tenants(self):
images = self.mgr.list(is_public=None, page_size=5)
image_list = list(images)
self.assertEqual('A', image_list[0].owner)
self.assertEqual('a', image_list[0].id)
self.assertEqual('B', image_list[1].owner)
self.assertEqual('b', image_list[1].id)
self.assertEqual('B', image_list[2].owner)
self.assertEqual('b2', image_list[2].id)
self.assertRaises(AttributeError, lambda: image_list[3].owner)
self.assertEqual('c', image_list[3].id)
self.assertEqual(4, len(image_list))
def test_update_v2_created_image_using_v1(self):
fields_to_update = {
'name': 'bar',
'container_format': 'bare',
'disk_format': 'qcow2',
}
image = self.mgr.update('v2_created_img', **fields_to_update)
expect_hdrs = {
'x-image-meta-name': 'bar',
'x-image-meta-container_format': 'bare',
'x-image-meta-disk_format': 'qcow2',
}
expect = [('PUT', '/v1/images/v2_created_img', expect_hdrs, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('v2_created_img', image.id)
self.assertEqual('bar', image.name)
self.assertEqual(0, image.size)
self.assertEqual('bare', image.container_format)
self.assertEqual('qcow2', image.disk_format)
class ImageTest(testtools.TestCase):
def setUp(self):
super(ImageTest, self).setUp()
self.api = utils.FakeAPI(fixtures)
self.mgr = images.ImageManager(self.api)
def test_delete(self):
image = self.mgr.get('1')
image.delete()
expect = [
('HEAD', '/v1/images/1', {}, None),
('DELETE', '/v1/images/1', {}, None),
]
self.assertEqual(expect, self.api.calls)
def test_update(self):
image = self.mgr.get('1')
image.update(name='image-5')
expect = [
('HEAD', '/v1/images/1', {}, None),
('PUT', '/v1/images/1', {'x-image-meta-name': 'image-5'}, None),
]
self.assertEqual(expect, self.api.calls)
def test_data(self):
image = self.mgr.get('1')
data = ''.join([b for b in image.data()])
expect = [
('HEAD', '/v1/images/1', {}, None),
('GET', '/v1/images/1', {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertEqual('XXX', data)
data = ''.join([b for b in image.data(do_checksum=False)])
expect += [('GET', '/v1/images/1', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('XXX', data)
def test_data_with_wrong_checksum(self):
image = self.mgr.get('2')
data = ''.join([b for b in image.data(do_checksum=False)])
expect = [
('HEAD', '/v1/images/2', {}, None),
('GET', '/v1/images/2', {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertEqual('YYY', data)
data = image.data()
expect += [('GET', '/v1/images/2', {}, None)]
self.assertEqual(expect, self.api.calls)
try:
data = ''.join([b for b in image.data()])
self.fail('data did not raise an error.')
except IOError as e:
self.assertEqual(errno.EPIPE, e.errno)
msg = 'was fd7c5c4fdaa97163ee4ba8842baa537a expected wrong'
self.assertTrue(msg in str(e))
def test_data_with_checksum(self):
image = self.mgr.get('3')
data = ''.join([b for b in image.data(do_checksum=False)])
expect = [
('HEAD', '/v1/images/3', {}, None),
('GET', '/v1/images/3', {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertEqual('ZZZ', data)
data = ''.join([b for b in image.data()])
expect += [('GET', '/v1/images/3', {}, None)]
self.assertEqual(expect, self.api.calls)
self.assertEqual('ZZZ', data)
class ParameterFakeAPI(utils.FakeAPI):
image_list = {'images': [
{
'id': 'a',
'name': 'image-1',
'properties': {'arch': 'x86_64'},
},
{
'id': 'b',
'name': 'image-2',
'properties': {'arch': 'x86_64'},
},
]}
def json_request(self, method, url, **kwargs):
self.url = url
return utils.FakeResponse({}), ParameterFakeAPI.image_list
class FakeArg(object):
def __init__(self, arg_dict):
self.arg_dict = arg_dict
self.fields = arg_dict.keys()
def __getattr__(self, name):
if name in self.arg_dict:
return self.arg_dict[name]
else:
return None
class UrlParameterTest(testtools.TestCase):
def setUp(self):
super(UrlParameterTest, self).setUp()
self.api = ParameterFakeAPI({})
self.gc = client.Client("http://fakeaddress.com")
self.gc.images = images.ImageManager(self.api)
def test_is_public_list(self):
shell.do_image_list(self.gc, FakeArg({"is_public": "True"}))
parts = parse.urlparse(self.api.url)
qs_dict = parse.parse_qs(parts.query)
self.assertTrue('is_public' in qs_dict)
self.assertTrue(qs_dict['is_public'][0].lower() == "true")
def test_copy_from_used(self):
class LegacyFakeArg(object):
def __init__(self, fields):
self.fields = fields
self.dry_run = False
self.verbose = False
def images_create(**kwargs):
class FakeImage():
id = "ThisiSanID"
self.assertNotEqual(kwargs['data'], sys.stdin)
return FakeImage()
self.gc.images.create = images_create
args = LegacyFakeArg(["copy_from=http://somehost.com/notreal.qcow"])
legacy_shell.do_add(self.gc, args)