image-download: tests to catch stray output
Add unit tests to ensure that any stray output (eg print statements) during image-download cause a test failure. Regression test for bug 1488914. Change-Id: Ic19ba5693d059bf7c283702e7c333672a878a1a1 Partial-bug: 1488914
This commit is contained in:
parent
8a584d5938
commit
7ed22a91d3
glanceclient
@ -283,10 +283,8 @@ def save_image(data, path):
|
||||
:param path: path to save the image to
|
||||
"""
|
||||
if path is None:
|
||||
if six.PY3:
|
||||
image = sys.stdout.buffer
|
||||
else:
|
||||
image = sys.stdout
|
||||
image = getattr(sys.stdout, 'buffer',
|
||||
sys.stdout)
|
||||
else:
|
||||
image = open(path, 'wb')
|
||||
try:
|
||||
|
@ -36,6 +36,8 @@ import six
|
||||
from glanceclient.common import utils
|
||||
from glanceclient import exc
|
||||
from glanceclient import shell as openstack_shell
|
||||
from glanceclient.tests.unit.v2.fixtures import image_show_fixture
|
||||
from glanceclient.tests.unit.v2.fixtures import image_versions_fixture
|
||||
from glanceclient.tests import utils as testutils
|
||||
|
||||
# NOTE (esheffield) Used for the schema caching tests
|
||||
@ -844,3 +846,115 @@ class ShellCacheSchemaTest(testutils.TestCase):
|
||||
client,
|
||||
home_dir=self.cache_dir)
|
||||
self.assertEqual(True, switch_version)
|
||||
|
||||
|
||||
class ShellTestRequests(testutils.TestCase):
|
||||
"""Shell tests using the requests mock library."""
|
||||
def _make_args(self, args):
|
||||
# NOTE(venkatesh): this conversion from a dict to an object
|
||||
# is required because the test_shell.do_xxx(gc, args) methods
|
||||
# expects the args to be attributes of an object. If passed as
|
||||
# dict directly, it throws an AttributeError.
|
||||
class Args(object):
|
||||
def __init__(self, entries):
|
||||
self.__dict__.update(entries)
|
||||
|
||||
return Args(args)
|
||||
|
||||
def setUp(self):
|
||||
super(ShellTestRequests, self).setUp()
|
||||
self._old_env = os.environ
|
||||
os.environ = {}
|
||||
|
||||
def tearDown(self):
|
||||
super(ShellTestRequests, self).tearDown()
|
||||
os.environ = self._old_env
|
||||
|
||||
def test_download_has_no_stray_output_to_stdout(self):
|
||||
"""Regression test for bug 1488914"""
|
||||
saved_stdout = sys.stdout
|
||||
try:
|
||||
sys.stdout = output = testutils.FakeNoTTYStdout()
|
||||
id = image_show_fixture['id']
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
self.requests.get('http://example.com/versions',
|
||||
json=image_versions_fixture)
|
||||
|
||||
headers = {'Content-Length': '4',
|
||||
'Content-type': 'application/octet-stream'}
|
||||
fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
|
||||
self.requests.get('http://example.com/v1/images/%s' % id,
|
||||
raw=fake)
|
||||
|
||||
self.requests.get('http://example.com/v1/images/detail'
|
||||
'?sort_key=name&sort_dir=asc&limit=20')
|
||||
|
||||
headers = {'X-Image-Meta-Id': id}
|
||||
self.requests.head('http://example.com/v1/images/%s' % id,
|
||||
headers=headers)
|
||||
|
||||
with mock.patch.object(openstack_shell.OpenStackImagesShell,
|
||||
'_cache_schemas') as mocked_cache_schema:
|
||||
mocked_cache_schema.return_value = True
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
argstr = ('--os-auth-token faketoken '
|
||||
'--os-image-url http://example.com '
|
||||
'image-download %s' % id)
|
||||
shell.main(argstr.split())
|
||||
self.assertTrue(mocked_cache_schema.called)
|
||||
# Ensure we have *only* image data
|
||||
self.assertEqual('DATA', output.getvalue())
|
||||
finally:
|
||||
sys.stdout = saved_stdout
|
||||
|
||||
def test_v1_download_has_no_stray_output_to_stdout(self):
|
||||
"""Ensure no stray print statements corrupt the image"""
|
||||
saved_stdout = sys.stdout
|
||||
try:
|
||||
sys.stdout = output = testutils.FakeNoTTYStdout()
|
||||
id = image_show_fixture['id']
|
||||
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
headers = {'X-Image-Meta-Id': id}
|
||||
self.requests.head('http://example.com/v1/images/%s' % id,
|
||||
headers=headers)
|
||||
|
||||
headers = {'Content-Length': '4',
|
||||
'Content-type': 'application/octet-stream'}
|
||||
fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
|
||||
self.requests.get('http://example.com/v1/images/%s' % id,
|
||||
headers=headers, raw=fake)
|
||||
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
argstr = ('--os-image-api-version 1 --os-auth-token faketoken '
|
||||
'--os-image-url http://example.com '
|
||||
'image-download %s' % id)
|
||||
shell.main(argstr.split())
|
||||
# Ensure we have *only* image data
|
||||
self.assertEqual('DATA', output.getvalue())
|
||||
finally:
|
||||
sys.stdout = saved_stdout
|
||||
|
||||
def test_v2_download_has_no_stray_output_to_stdout(self):
|
||||
"""Ensure no stray print statements corrupt the image"""
|
||||
saved_stdout = sys.stdout
|
||||
try:
|
||||
sys.stdout = output = testutils.FakeNoTTYStdout()
|
||||
id = image_show_fixture['id']
|
||||
headers = {'Content-Length': '4',
|
||||
'Content-type': 'application/octet-stream'}
|
||||
fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
|
||||
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
self.requests.get('http://example.com/v2/images/%s/file' % id,
|
||||
headers=headers, raw=fake)
|
||||
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
argstr = ('--os-image-api-version 2 --os-auth-token faketoken '
|
||||
'--os-image-url http://example.com '
|
||||
'image-download %s' % id)
|
||||
shell.main(argstr.split())
|
||||
# Ensure we have *only* image data
|
||||
self.assertEqual('DATA', output.getvalue())
|
||||
finally:
|
||||
sys.stdout = saved_stdout
|
||||
|
@ -319,3 +319,68 @@ schema_fixture = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image_versions_fixture = {
|
||||
"versions": [
|
||||
{
|
||||
"id": "v2.3",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v2/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "CURRENT"
|
||||
},
|
||||
{
|
||||
"id": "v2.2",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v2/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "SUPPORTED"
|
||||
},
|
||||
{
|
||||
"id": "v2.1",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v2/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "SUPPORTED"
|
||||
},
|
||||
{
|
||||
"id": "v2.0",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v2/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "SUPPORTED"
|
||||
},
|
||||
{
|
||||
"id": "v1.1",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v1/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "SUPPORTED"
|
||||
},
|
||||
{
|
||||
"id": "v1.0",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://localhost:9292/v1/",
|
||||
"rel": "self"
|
||||
}
|
||||
],
|
||||
"status": "SUPPORTED"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -117,6 +117,10 @@ class FakeResponse(object):
|
||||
self.raw = RawRequest(headers, body=body, reason=reason,
|
||||
version=version, status=status_code)
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
return self.status_code
|
||||
|
||||
@property
|
||||
def ok(self):
|
||||
return (self.status_code < 400 or
|
||||
@ -151,6 +155,9 @@ class FakeResponse(object):
|
||||
break
|
||||
yield chunk
|
||||
|
||||
def release_conn(self, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
TEST_REQUEST_BASE = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user