More PEP8 fixes

This commit is contained in:
Cory Wright 2011-01-04 17:00:37 -05:00
parent eff29fca5d
commit 386b42c176
10 changed files with 221 additions and 201 deletions

View File

@ -18,7 +18,8 @@
# Glance documentation build configuration file, created by # Glance documentation build configuration file, created by
# sphinx-quickstart on Tue May 18 13:50:15 2010. # sphinx-quickstart on Tue May 18 13:50:15 2010.
# #
# This file is execfile()d with the current directory set to its containing dir. # This file is execfile()'d with the current directory set to it's containing
# dir.
# #
# Note that not all possible configuration values are present in this # Note that not all possible configuration values are present in this
# autogenerated file. # autogenerated file.
@ -26,7 +27,8 @@
# All configuration values have a default; values that are commented out # All configuration values have a default; values that are commented out
# serve to show the default. # serve to show the default.
import sys, os import os
import sys
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
@ -36,19 +38,25 @@ sys.path.append([os.path.abspath('../glance'),
os.path.abspath('../bin') os.path.abspath('../bin')
]) ])
# -- General configuration ----------------------------------------------------- # -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.intersphinx',
'sphinx.ext.pngmath',
'sphinx.ext.todo']
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig']
todo_include_todos = True todo_include_todos = True
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = [] templates_path = []
if os.getenv('HUDSON_PUBLISH_DOCS'): if os.getenv('HUDSON_PUBLISH_DOCS'):
templates_path = ['_ga', '_templates'] templates_path = ['_ga', '_templates']
else: else:
templates_path = ['_templates'] templates_path = ['_templates']
# The suffix of source filenames. # The suffix of source filenames.
source_suffix = '.rst' source_suffix = '.rst'
@ -89,7 +97,7 @@ release = '1.0.2'
# for source files. # for source files.
exclude_trees = [] exclude_trees = []
# The reST default role (used for this markup: `text`) to use for all documents. # The reST default role (for this markup: `text`) to use for all documents.
#default_role = None #default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text. # If true, '()' will be appended to :func: etc. cross-reference text.
@ -110,7 +118,7 @@ pygments_style = 'sphinx'
modindex_common_prefix = ['glance.'] modindex_common_prefix = ['glance.']
# -- Options for HTML output --------------------------------------------------- # -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with # The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'. # Sphinx are currently 'default' and 'sphinxdoc'.
@ -185,7 +193,7 @@ html_static_path = ['_static']
htmlhelp_basename = 'glancedoc' htmlhelp_basename = 'glancedoc'
# -- Options for LaTeX output -------------------------------------------------- # -- Options for LaTeX output ------------------------------------------------
# The paper size ('letter' or 'a4'). # The paper size ('letter' or 'a4').
#latex_paper_size = 'letter' #latex_paper_size = 'letter'
@ -194,7 +202,8 @@ htmlhelp_basename = 'glancedoc'
#latex_font_size = '10pt' #latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]). # (source start file, target name, title, author,
# documentclass [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'Glance.tex', u'Glance Documentation', ('index', 'Glance.tex', u'Glance Documentation',
u'Glance Team', 'manual'), u'Glance Team', 'manual'),
@ -221,4 +230,3 @@ latex_documents = [
intersphinx_mapping = {'python': ('http://docs.python.org/', None), intersphinx_mapping = {'python': ('http://docs.python.org/', None),
'nova': ('http://nova.openstack.org', None), 'nova': ('http://nova.openstack.org', None),
'swift': ('http://swift.openstack.org', None)} 'swift': ('http://swift.openstack.org', None)}

View File

@ -56,6 +56,6 @@ setup(
'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.6',
'Environment :: No Input/Output (Daemon)', 'Environment :: No Input/Output (Daemon)',
], ],
install_requires=[], # removed for better compat install_requires=[], # removed for better compat
scripts=['bin/glance-api', scripts=['bin/glance-api',
'bin/glance-registry']) 'bin/glance-registry'])

View File

@ -44,7 +44,7 @@ def stub_out_http_backend(stubs):
"""Stubs out the httplib.HTTPRequest.getresponse to return """Stubs out the httplib.HTTPRequest.getresponse to return
faked-out data instead of grabbing actual contents of a resource faked-out data instead of grabbing actual contents of a resource
The stubbed getresponse() returns an iterator over The stubbed getresponse() returns an iterator over
the data "I am a teapot, short and stout\n" the data "I am a teapot, short and stout\n"
:param stubs: Set of stubout stubs :param stubs: Set of stubout stubs
@ -117,6 +117,7 @@ def stub_out_swift_backend(stubs):
""" """
class FakeSwiftAuth(object): class FakeSwiftAuth(object):
pass pass
class FakeSwiftConnection(object): class FakeSwiftConnection(object):
pass pass
@ -135,8 +136,8 @@ def stub_out_swift_backend(stubs):
def chunk_it(): def chunk_it():
for i in xrange(0, len(cls.DATA), cls.CHUNK_SIZE): for i in xrange(0, len(cls.DATA), cls.CHUNK_SIZE):
yield cls.DATA[i:i+cls.CHUNK_SIZE] yield cls.DATA[i:i + cls.CHUNK_SIZE]
return chunk_it() return chunk_it()
fake_swift_backend = FakeSwiftBackend() fake_swift_backend = FakeSwiftBackend()
@ -324,25 +325,25 @@ def stub_out_registry_db_image_api(stubs):
values['deleted'] = False values['deleted'] = False
values['properties'] = values.get('properties', {}) values['properties'] = values.get('properties', {})
values['created_at'] = datetime.datetime.utcnow() values['created_at'] = datetime.datetime.utcnow()
values['updated_at'] = datetime.datetime.utcnow() values['updated_at'] = datetime.datetime.utcnow()
values['deleted_at'] = None values['deleted_at'] = None
props = [] props = []
if 'properties' in values.keys(): if 'properties' in values.keys():
for k,v in values['properties'].iteritems(): for k, v in values['properties'].iteritems():
p = {} p = {}
p['key'] = k p['key'] = k
p['value'] = v p['value'] = v
p['deleted'] = False p['deleted'] = False
p['created_at'] = datetime.datetime.utcnow() p['created_at'] = datetime.datetime.utcnow()
p['updated_at'] = datetime.datetime.utcnow() p['updated_at'] = datetime.datetime.utcnow()
p['deleted_at'] = None p['deleted_at'] = None
props.append(p) props.append(p)
values['properties'] = props values['properties'] = props
self.next_id += 1 self.next_id += 1
self.images.append(values) self.images.append(values)
return values return values
@ -352,12 +353,12 @@ def stub_out_registry_db_image_api(stubs):
props = [] props = []
if 'properties' in values.keys(): if 'properties' in values.keys():
for k,v in values['properties'].iteritems(): for k, v in values['properties'].iteritems():
p = {} p = {}
p['key'] = k p['key'] = k
p['value'] = v p['value'] = v
p['deleted'] = False p['deleted'] = False
p['created_at'] = datetime.datetime.utcnow() p['created_at'] = datetime.datetime.utcnow()
p['updated_at'] = datetime.datetime.utcnow() p['updated_at'] = datetime.datetime.utcnow()
p['deleted_at'] = None p['deleted_at'] = None
props.append(p) props.append(p)

View File

@ -23,7 +23,7 @@ def make_swift_image():
# TODO(sirp): Create a testing account, and define gflags for # TODO(sirp): Create a testing account, and define gflags for
# test_swift_username and test_swift_api_key # test_swift_username and test_swift_api_key
USERNAME = "your user name here" # fill these out for testing USERNAME = "your user name here" # fill these out for testing
API_KEY = "your api key here" API_KEY = "your api key here"
#IMAGE_CHUNKS = [("filename", 123)] # filename, size in bytes #IMAGE_CHUNKS = [("filename", 123)] # filename, size in bytes
IMAGE_CHUNKS = [("your test chunk here", 12345)] IMAGE_CHUNKS = [("your test chunk here", 12345)]
@ -40,8 +40,8 @@ def make_swift_image():
"swift://%s:%s@auth.api.rackspacecloud.com/v1.0/cloudservers/%s" "swift://%s:%s@auth.api.rackspacecloud.com/v1.0/cloudservers/%s"
) % (USERNAME, API_KEY, obj) ) % (USERNAME, API_KEY, obj)
db.image_file_create(None, db.image_file_create(None,
dict(image_id=image.id, location=location, size=size)) dict(image_id=image.id, location=location, size=size))
if __name__ == "__main__": if __name__ == "__main__":
make_swift_image() # NOTE: uncomment if you have a username and api_key make_swift_image() # NOTE: uncomment if you have a username and api_key

View File

@ -19,13 +19,13 @@
fakehttp/socket implementation fakehttp/socket implementation
- TrackerSocket: an object which masquerades as a socket and responds to - TrackerSocket: an object which masquerades as a socket and responds to
requests in a manner consistent with a *very* stupid CloudFS tracker. requests in a manner consistent with a *very* stupid CloudFS tracker.
- CustomHTTPConnection: an object which subclasses httplib.HTTPConnection - CustomHTTPConnection: an object which subclasses httplib.HTTPConnection
in order to replace it's socket with a TrackerSocket instance. in order to replace it's socket with a TrackerSocket instance.
The unittests each have setup methods which create freerange connection The unittests each have setup methods which create freerange connection
instances that have had their HTTPConnection instances replaced by instances that have had their HTTPConnection instances replaced by
intances of CustomHTTPConnection. intances of CustomHTTPConnection.
""" """
@ -54,21 +54,23 @@ class FakeSocket(object):
def makefile(self, mode, flags): def makefile(self, mode, flags):
return self._wbuffer return self._wbuffer
class TrackerSocket(FakeSocket): class TrackerSocket(FakeSocket):
def write(self, data): def write(self, data):
self._wbuffer.write(data) self._wbuffer.write(data)
def read(self, length=-1): def read(self, length=-1):
return self._rbuffer.read(length) return self._rbuffer.read(length)
def _create_GET_account_content(self, path, args): def _create_GET_account_content(self, path, args):
if args.has_key('format') and args['format'] == 'json': if 'format' in args and args['format'] == 'json':
containers = [] containers = []
containers.append('[\n'); containers.append('[\n')
containers.append('{"name":"container1","count":2,"bytes":78},\n') containers.append('{"name":"container1","count":2,"bytes":78},\n')
containers.append('{"name":"container2","count":1,"bytes":39},\n') containers.append('{"name":"container2","count":1,"bytes":39},\n')
containers.append('{"name":"container3","count":3,"bytes":117}\n') containers.append('{"name":"container3","count":3,"bytes":117}\n')
containers.append(']\n') containers.append(']\n')
elif args.has_key('format') and args['format'] == 'xml': elif 'format' in args and args['format'] == 'xml':
containers = [] containers = []
containers.append('<?xml version="1.0" encoding="UTF-8"?>\n') containers.append('<?xml version="1.0" encoding="UTF-8"?>\n')
containers.append('<account name="FakeAccount">\n') containers.append('<account name="FakeAccount">\n')
@ -83,18 +85,18 @@ class TrackerSocket(FakeSocket):
'<bytes>117</bytes></container>\n') '<bytes>117</bytes></container>\n')
containers.append('</account>\n') containers.append('</account>\n')
else: else:
containers = ['container%s\n' % i for i in range(1,4)] containers = ['container%s\n' % i for i in range(1, 4)]
return ''.join(containers) return ''.join(containers)
def _create_GET_container_content(self, path, args): def _create_GET_container_content(self, path, args):
left = 0 left = 0
right = 9 right = 9
if args.has_key('offset'): if 'offset' in args:
left = int(args['offset']) left = int(args['offset'])
if args.has_key('limit'): if 'limit' in args:
right = left + int(args['limit']) right = left + int(args['limit'])
if args.has_key('format') and args['format'] == 'json': if 'format' in args and args['format'] == 'json':
objects = [] objects = []
objects.append('{"name":"object1",' objects.append('{"name":"object1",'
'"hash":"4281c348eaf83e70ddce0e07221c3d28",' '"hash":"4281c348eaf83e70ddce0e07221c3d28",'
@ -137,68 +139,68 @@ class TrackerSocket(FakeSocket):
'"content_type":"application\/octet-stream",' '"content_type":"application\/octet-stream",'
'"last_modified":"2007-03-04 20:32:17"}') '"last_modified":"2007-03-04 20:32:17"}')
output = '[\n%s\n]\n' % (',\n'.join(objects[left:right])) output = '[\n%s\n]\n' % (',\n'.join(objects[left:right]))
elif args.has_key('format') and args['format'] == 'xml': elif 'format' in args and args['format'] == 'xml':
objects = [] objects = []
objects.append('<object><name>object1</name>' objects.append('<object><name>object1</name>'
'<hash>4281c348eaf83e70ddce0e07221c3d28</hash>' '<hash>4281c348eaf83e70ddce0e07221c3d28</hash>'
'<bytes>14</bytes>' '<bytes>14</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object2</name>' objects.append('<object><name>object2</name>'
'<hash>b039efe731ad111bc1b0ef221c3849d0</hash>' '<hash>b039efe731ad111bc1b0ef221c3849d0</hash>'
'<bytes>64</bytes>' '<bytes>64</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object3</name>' objects.append('<object><name>object3</name>'
'<hash>4281c348eaf83e70ddce0e07221c3d28</hash>' '<hash>4281c348eaf83e70ddce0e07221c3d28</hash>'
'<bytes>14</bytes>' '<bytes>14</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object4</name>' objects.append('<object><name>object4</name>'
'<hash>b039efe731ad111bc1b0ef221c3849d0</hash>' '<hash>b039efe731ad111bc1b0ef221c3849d0</hash>'
'<bytes>64</bytes>' '<bytes>64</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object5</name>' objects.append('<object><name>object5</name>'
'<hash>4281c348eaf83e70ddce0e07221c3d28</hash>' '<hash>4281c348eaf83e70ddce0e07221c3d28</hash>'
'<bytes>14</bytes>' '<bytes>14</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object6</name>' objects.append('<object><name>object6</name>'
'<hash>b039efe731ad111bc1b0ef221c3849d0</hash>' '<hash>b039efe731ad111bc1b0ef221c3849d0</hash>'
'<bytes>64</bytes>' '<bytes>64</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object7</name>' objects.append('<object><name>object7</name>'
'<hash>4281c348eaf83e70ddce0e07221c3d28</hash>' '<hash>4281c348eaf83e70ddce0e07221c3d28</hash>'
'<bytes>14</bytes>' '<bytes>14</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects.append('<object><name>object8</name>' objects.append('<object><name>object8</name>'
'<hash>b039efe731ad111bc1b0ef221c3849d0</hash>' '<hash>b039efe731ad111bc1b0ef221c3849d0</hash>'
'<bytes>64</bytes>' '<bytes>64</bytes>'
'<content_type>application/octet-stream</content_type>' '<content_type>application/octet-stream</content_type>'
'<last_modified>2007-03-04 20:32:17</last_modified>' '<last_modified>2007-03-04 20:32:17</last_modified>'
'</object>\n') '</object>\n')
objects = objects[left:right] objects = objects[left:right]
objects.insert(0, '<?xml version="1.0" encoding="UTF-8"?>\n') objects.insert(0, '<?xml version="1.0" encoding="UTF-8"?>\n')
objects.insert(1, '<container name="test_container_1"\n') objects.insert(1, '<container name="test_container_1"\n')
objects.append('</container>\n') objects.append('</container>\n')
output = ''.join(objects) output = ''.join(objects)
else: else:
objects = ['object%s\n' % i for i in range(1,9)] objects = ['object%s\n' % i for i in range(1, 9)]
objects = objects[left:right] objects = objects[left:right]
output = ''.join(objects) output = ''.join(objects)
# prefix/path don't make much sense given our test data # prefix/path don't make much sense given our test data
if args.has_key('prefix') or args.has_key('path'): if 'prefix' in args or 'path' in args:
pass pass
return output return output

View File

@ -45,7 +45,7 @@ class TestRegistryAPI(unittest.TestCase):
def test_get_root(self): def test_get_root(self):
"""Tests that the root registry API returns "index", """Tests that the root registry API returns "index",
which is a list of public images which is a list of public images
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2'} 'name': 'fake image #2'}
@ -57,13 +57,13 @@ class TestRegistryAPI(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_index(self): def test_get_index(self):
"""Tests that the /images registry API returns list of """Tests that the /images registry API returns list of
public images public images
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2'} 'name': 'fake image #2'}
@ -75,13 +75,13 @@ class TestRegistryAPI(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_details(self): def test_get_details(self):
"""Tests that the /images/detail registry API returns """Tests that the /images/detail registry API returns
a mapping containing a list of detailed image information a mapping containing a list of detailed image information
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2', 'name': 'fake image #2',
@ -97,7 +97,7 @@ class TestRegistryAPI(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_create_image(self): def test_create_image(self):
@ -108,7 +108,7 @@ class TestRegistryAPI(unittest.TestCase):
} }
req = webob.Request.blank('/images') req = webob.Request.blank('/images')
req.method = 'POST' req.method = 'POST'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -118,7 +118,7 @@ class TestRegistryAPI(unittest.TestCase):
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, res_dict['image'][k]) self.assertEquals(v, res_dict['image'][k])
# Test ID auto-assigned properly # Test ID auto-assigned properly
@ -137,7 +137,7 @@ class TestRegistryAPI(unittest.TestCase):
} }
req = webob.Request.blank('/images') req = webob.Request.blank('/images')
req.method = 'POST' req.method = 'POST'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -154,7 +154,7 @@ class TestRegistryAPI(unittest.TestCase):
} }
req = webob.Request.blank('/images/2') req = webob.Request.blank('/images/2')
req.method = 'PUT' req.method = 'PUT'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -164,7 +164,7 @@ class TestRegistryAPI(unittest.TestCase):
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, res_dict['image'][k]) self.assertEquals(v, res_dict['image'][k])
def test_update_image_not_existing(self): def test_update_image_not_existing(self):
@ -178,7 +178,7 @@ class TestRegistryAPI(unittest.TestCase):
} }
req = webob.Request.blank('/images/3') req = webob.Request.blank('/images/3')
req.method = 'PUT' req.method = 'PUT'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -202,7 +202,7 @@ class TestRegistryAPI(unittest.TestCase):
# Delete image #2 # Delete image #2
req = webob.Request.blank('/images/2') req = webob.Request.blank('/images/2')
req.method = 'DELETE' req.method = 'DELETE'
res = req.get_response(rserver.API()) res = req.get_response(rserver.API())
@ -223,7 +223,7 @@ class TestRegistryAPI(unittest.TestCase):
image""" image"""
req = webob.Request.blank('/images/3') req = webob.Request.blank('/images/3')
req.method = 'DELETE' req.method = 'DELETE'
# TODO(jaypipes): Port Nova's Fault infrastructure # TODO(jaypipes): Port Nova's Fault infrastructure
@ -257,7 +257,7 @@ class TestGlanceAPI(unittest.TestCase):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.method = 'POST' req.method = 'POST'
for k,v in fixture_headers.iteritems(): for k, v in fixture_headers.iteritems():
req.headers[k] = v req.headers[k] = v
res = req.get_response(server.API()) res = req.get_response(server.API())
self.assertEquals(res.status_int, webob.exc.HTTPBadRequest.code) self.assertEquals(res.status_int, webob.exc.HTTPBadRequest.code)
@ -269,7 +269,7 @@ class TestGlanceAPI(unittest.TestCase):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.method = 'POST' req.method = 'POST'
for k,v in fixture_headers.iteritems(): for k, v in fixture_headers.iteritems():
req.headers[k] = v req.headers[k] = v
req.headers['Content-Type'] = 'application/octet-stream' req.headers['Content-Type'] = 'application/octet-stream'
@ -284,7 +284,7 @@ class TestGlanceAPI(unittest.TestCase):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.method = 'POST' req.method = 'POST'
for k,v in fixture_headers.iteritems(): for k, v in fixture_headers.iteritems():
req.headers[k] = v req.headers[k] = v
req.headers['Content-Type'] = 'application/octet-stream' req.headers['Content-Type'] = 'application/octet-stream'
@ -327,7 +327,8 @@ class TestGlanceAPI(unittest.TestCase):
req = webob.Request.blank("/images/2") req = webob.Request.blank("/images/2")
req.method = 'GET' req.method = 'GET'
res = req.get_response(server.API()) res = req.get_response(server.API())
self.assertEquals(res.status_int, webob.exc.HTTPNotFound.code, res.body) self.assertEquals(res.status_int, webob.exc.HTTPNotFound.code,
res.body)
def test_delete_non_exists_image(self): def test_delete_non_exists_image(self):
req = webob.Request.blank("/images/42") req = webob.Request.blank("/images/42")

View File

@ -33,7 +33,7 @@ FLAGS = flags.FLAGS
class TestBadClients(unittest.TestCase): class TestBadClients(unittest.TestCase):
"""Test exceptions raised for bad clients""" """Test exceptions raised for bad clients"""
def test_bad_address(self): def test_bad_address(self):
@ -69,7 +69,7 @@ class TestRegistryClient(unittest.TestCase):
images = self.client.get_images() images = self.client.get_images()
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_image_details(self): def test_get_image_details(self):
@ -95,7 +95,7 @@ class TestRegistryClient(unittest.TestCase):
images = self.client.get_images_detailed() images = self.client.get_images_detailed()
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_image(self): def test_get_image(self):
@ -120,7 +120,7 @@ class TestRegistryClient(unittest.TestCase):
data = self.client.get_image(2) data = self.client.get_image(2)
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
def test_get_image_non_existing(self): def test_get_image_non_existing(self):
@ -138,7 +138,7 @@ class TestRegistryClient(unittest.TestCase):
'size': 19, 'size': 19,
'location': "file:///tmp/glance-tests/acct/3.gz.0", 'location': "file:///tmp/glance-tests/acct/3.gz.0",
} }
new_image = self.client.add_image(fixture) new_image = self.client.add_image(fixture)
# Test ID auto-assigned properly # Test ID auto-assigned properly
@ -147,7 +147,7 @@ class TestRegistryClient(unittest.TestCase):
# Test all other attributes set # Test all other attributes set
data = self.client.get_image(3) data = self.client.get_image(3)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
# Test status was updated properly # Test status was updated properly
@ -170,13 +170,13 @@ class TestRegistryClient(unittest.TestCase):
'location': "file:///tmp/glance-tests/2", 'location': "file:///tmp/glance-tests/2",
'properties': {'distro': 'Ubuntu 10.04 LTS'} 'properties': {'distro': 'Ubuntu 10.04 LTS'}
} }
new_image = self.client.add_image(fixture) new_image = self.client.add_image(fixture)
# Test ID auto-assigned properly # Test ID auto-assigned properly
self.assertEquals(3, new_image['id']) self.assertEquals(3, new_image['id'])
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, new_image[k]) self.assertEquals(v, new_image[k])
# Test status was updated properly # Test status was updated properly
@ -224,7 +224,7 @@ class TestRegistryClient(unittest.TestCase):
# Test all other attributes set # Test all other attributes set
data = self.client.get_image(2) data = self.client.get_image(2)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
def test_update_image_not_existing(self): def test_update_image_not_existing(self):
@ -304,7 +304,7 @@ class TestClient(unittest.TestCase):
image_data += image_chunk image_data += image_chunk
self.assertEquals(expected_image, image_data) self.assertEquals(expected_image, image_data)
for k,v in expected_meta.iteritems(): for k, v in expected_meta.iteritems():
self.assertEquals(v, meta[k]) self.assertEquals(v, meta[k])
def test_get_image_not_existing(self): def test_get_image_not_existing(self):
@ -321,7 +321,7 @@ class TestClient(unittest.TestCase):
images = self.client.get_images() images = self.client.get_images()
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_image_details(self): def test_get_image_details(self):
@ -347,7 +347,7 @@ class TestClient(unittest.TestCase):
images = self.client.get_images_detailed() images = self.client.get_images_detailed()
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_image_meta(self): def test_get_image_meta(self):
@ -372,7 +372,7 @@ class TestClient(unittest.TestCase):
data = self.client.get_image_meta(2) data = self.client.get_image_meta(2)
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
def test_get_image_non_existing(self): def test_get_image_non_existing(self):
@ -388,7 +388,7 @@ class TestClient(unittest.TestCase):
'is_public': True, 'is_public': True,
'type': 'kernel' 'type': 'kernel'
} }
self.assertRaises(exception.Invalid, self.assertRaises(exception.Invalid,
self.client.add_image, self.client.add_image,
fixture) fixture)
@ -401,7 +401,7 @@ class TestClient(unittest.TestCase):
'size': 19, 'size': 19,
'location': "file:///tmp/glance-tests/2", 'location': "file:///tmp/glance-tests/2",
} }
new_id = self.client.add_image(fixture) new_id = self.client.add_image(fixture)
# Test ID auto-assigned properly # Test ID auto-assigned properly
@ -410,7 +410,7 @@ class TestClient(unittest.TestCase):
# Test all other attributes set # Test all other attributes set
data = self.client.get_image_meta(3) data = self.client.get_image_meta(3)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
# Test status was updated properly # Test status was updated properly
@ -433,7 +433,7 @@ class TestClient(unittest.TestCase):
'location': "file:///tmp/glance-tests/2", 'location': "file:///tmp/glance-tests/2",
'properties': {'distro': 'Ubuntu 10.04 LTS'} 'properties': {'distro': 'Ubuntu 10.04 LTS'}
} }
new_id = self.client.add_image(fixture) new_id = self.client.add_image(fixture)
# Test ID auto-assigned properly # Test ID auto-assigned properly
@ -442,7 +442,7 @@ class TestClient(unittest.TestCase):
# Test all other attributes set # Test all other attributes set
data = self.client.get_image_meta(3) data = self.client.get_image_meta(3)
for k,v in expected.iteritems(): for k, v in expected.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
# Test status was updated properly # Test status was updated properly
@ -502,7 +502,7 @@ class TestClient(unittest.TestCase):
new_image_data += image_chunk new_image_data += image_chunk
self.assertEquals(image_data_fixture, new_image_data) self.assertEquals(image_data_fixture, new_image_data)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, new_meta[k]) self.assertEquals(v, new_meta[k])
def test_add_image_with_image_data_as_file(self): def test_add_image_with_image_data_as_file(self):
@ -539,7 +539,7 @@ class TestClient(unittest.TestCase):
new_image_data += image_chunk new_image_data += image_chunk
self.assertEquals(image_data_fixture, new_image_data) self.assertEquals(image_data_fixture, new_image_data)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, new_meta[k]) self.assertEquals(v, new_meta[k])
def test_add_image_with_bad_store(self): def test_add_image_with_bad_store(self):
@ -570,7 +570,7 @@ class TestClient(unittest.TestCase):
# Test all other attributes set # Test all other attributes set
data = self.client.get_image_meta(2) data = self.client.get_image_meta(2)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, data[k]) self.assertEquals(v, data[k])
def test_update_image_not_existing(self): def test_update_image_not_existing(self):

View File

@ -38,7 +38,7 @@ class TestImageController(unittest.TestCase):
def test_get_root(self): def test_get_root(self):
"""Tests that the root registry API returns "index", """Tests that the root registry API returns "index",
which is a list of public images which is a list of public images
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2'} 'name': 'fake image #2'}
@ -50,13 +50,13 @@ class TestImageController(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_index(self): def test_get_index(self):
"""Tests that the /images registry API returns list of """Tests that the /images registry API returns list of
public images public images
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2'} 'name': 'fake image #2'}
@ -68,13 +68,13 @@ class TestImageController(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_get_details(self): def test_get_details(self):
"""Tests that the /images/detail registry API returns """Tests that the /images/detail registry API returns
a mapping containing a list of detailed image information a mapping containing a list of detailed image information
""" """
fixture = {'id': 2, fixture = {'id': 2,
'name': 'fake image #2', 'name': 'fake image #2',
@ -90,7 +90,7 @@ class TestImageController(unittest.TestCase):
images = res_dict['images'] images = res_dict['images']
self.assertEquals(len(images), 1) self.assertEquals(len(images), 1)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, images[0][k]) self.assertEquals(v, images[0][k])
def test_create_image(self): def test_create_image(self):
@ -101,7 +101,7 @@ class TestImageController(unittest.TestCase):
} }
req = webob.Request.blank('/images') req = webob.Request.blank('/images')
req.method = 'POST' req.method = 'POST'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -111,7 +111,7 @@ class TestImageController(unittest.TestCase):
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, res_dict['image'][k]) self.assertEquals(v, res_dict['image'][k])
# Test ID auto-assigned properly # Test ID auto-assigned properly
@ -130,7 +130,7 @@ class TestImageController(unittest.TestCase):
} }
req = webob.Request.blank('/images') req = webob.Request.blank('/images')
req.method = 'POST' req.method = 'POST'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -147,7 +147,7 @@ class TestImageController(unittest.TestCase):
} }
req = webob.Request.blank('/images/2') req = webob.Request.blank('/images/2')
req.method = 'PUT' req.method = 'PUT'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -157,7 +157,7 @@ class TestImageController(unittest.TestCase):
res_dict = json.loads(res.body) res_dict = json.loads(res.body)
for k,v in fixture.iteritems(): for k, v in fixture.iteritems():
self.assertEquals(v, res_dict['image'][k]) self.assertEquals(v, res_dict['image'][k])
def test_update_image_not_existing(self): def test_update_image_not_existing(self):
@ -171,7 +171,7 @@ class TestImageController(unittest.TestCase):
} }
req = webob.Request.blank('/images/3') req = webob.Request.blank('/images/3')
req.method = 'PUT' req.method = 'PUT'
req.body = json.dumps(dict(image=fixture)) req.body = json.dumps(dict(image=fixture))
@ -195,7 +195,7 @@ class TestImageController(unittest.TestCase):
# Delete image #2 # Delete image #2
req = webob.Request.blank('/images/2') req = webob.Request.blank('/images/2')
req.method = 'DELETE' req.method = 'DELETE'
res = req.get_response(server.API()) res = req.get_response(server.API())
@ -216,7 +216,7 @@ class TestImageController(unittest.TestCase):
image""" image"""
req = webob.Request.blank('/images/3') req = webob.Request.blank('/images/3')
req.method = 'DELETE' req.method = 'DELETE'
# TODO(jaypipes): Port Nova's Fault infrastructure # TODO(jaypipes): Port Nova's Fault infrastructure

View File

@ -27,7 +27,9 @@ from tests import stubs
Backend.CHUNKSIZE = 2 Backend.CHUNKSIZE = 2
class TestBackend(unittest.TestCase): class TestBackend(unittest.TestCase):
def setUp(self): def setUp(self):
"""Establish a clean test environment""" """Establish a clean test environment"""
self.stubs = stubout.StubOutForTesting() self.stubs = stubout.StubOutForTesting()
@ -66,7 +68,7 @@ class TestHTTPBackend(TestBackend):
def test_http_get(self): def test_http_get(self):
url = "http://netloc/path/to/file.tar.gz" url = "http://netloc/path/to/file.tar.gz"
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
fetcher = get_from_backend(url, fetcher = get_from_backend(url,
expected_size=8) expected_size=8)
@ -76,7 +78,7 @@ class TestHTTPBackend(TestBackend):
def test_https_get(self): def test_https_get(self):
url = "https://netloc/path/to/file.tar.gz" url = "https://netloc/path/to/file.tar.gz"
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
fetcher = get_from_backend(url, fetcher = get_from_backend(url,
expected_size=8) expected_size=8)
@ -93,8 +95,8 @@ class TestSwiftBackend(TestBackend):
def test_get(self): def test_get(self):
swift_uri = "swift://user:password@localhost/container1/file.tar.gz" swift_uri = "swift://user:pass@localhost/container1/file.tar.gz"
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
fetcher = get_from_backend(swift_uri, fetcher = get_from_backend(swift_uri,
@ -109,12 +111,12 @@ class TestSwiftBackend(TestBackend):
swift_url = "swift://localhost/container1/file.tar.gz" swift_url = "swift://localhost/container1/file.tar.gz"
self.assertRaises(BackendException, get_from_backend, self.assertRaises(BackendException, get_from_backend,
swift_url, expected_size=21) swift_url, expected_size=21)
def test_url_parsing(self): def test_url_parsing(self):
swift_uri = "swift://user:password@localhost/v1.0/container1/file.tar.gz" swift_uri = "swift://user:pass@localhost/v1.0/container1/file.tar.gz"
parsed_uri = urlparse.urlparse(swift_uri) parsed_uri = urlparse.urlparse(swift_uri)
@ -122,7 +124,7 @@ class TestSwiftBackend(TestBackend):
SwiftBackend._parse_swift_tokens(parsed_uri) SwiftBackend._parse_swift_tokens(parsed_uri)
self.assertEqual(user, 'user') self.assertEqual(user, 'user')
self.assertEqual(key, 'password') self.assertEqual(key, 'pass')
self.assertEqual(authurl, 'https://localhost/v1.0') self.assertEqual(authurl, 'https://localhost/v1.0')
self.assertEqual(container, 'container1') self.assertEqual(container, 'container1')
self.assertEqual(obj, 'file.tar.gz') self.assertEqual(obj, 'file.tar.gz')

View File

@ -30,82 +30,88 @@ import sys
ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
VENV = os.path.join(ROOT, '.glance-venv') VENV = os.path.join(ROOT, '.glance-venv')
PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires') PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires')
TWISTED_NOVA='http://nova.openstack.org/Twisted-10.0.0Nova.tar.gz' TWISTED_NOVA = 'http://nova.openstack.org/Twisted-10.0.0Nova.tar.gz'
def die(message, *args): def die(message, *args):
print >>sys.stderr, message % args print >>sys.stderr, message % args
sys.exit(1) sys.exit(1)
def run_command(cmd, redirect_output=True, check_exit_code=True): def run_command(cmd, redirect_output=True, check_exit_code=True):
""" """
Runs a command in an out-of-process shell, returning the Runs a command in an out-of-process shell, returning the
output of that command. Working directory is ROOT. output of that command. Working directory is ROOT.
""" """
if redirect_output: if redirect_output:
stdout = subprocess.PIPE stdout = subprocess.PIPE
else: else:
stdout = None stdout = None
proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout) proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout)
output = proc.communicate()[0] output = proc.communicate()[0]
if check_exit_code and proc.returncode != 0: if check_exit_code and proc.returncode != 0:
die('Command "%s" failed.\n%s', ' '.join(cmd), output) die('Command "%s" failed.\n%s', ' '.join(cmd), output)
return output return output
HAS_EASY_INSTALL = bool(run_command(['which', 'easy_install'], check_exit_code=False).strip()) HAS_EASY_INSTALL = bool(run_command(['which', 'easy_install'],
HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'], check_exit_code=False).strip()) check_exit_code=False).strip())
HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'],
check_exit_code=False).strip())
def check_dependencies(): def check_dependencies():
"""Make sure virtualenv is in the path.""" """Make sure virtualenv is in the path."""
if not HAS_VIRTUALENV: if not HAS_VIRTUALENV:
print 'not found.' print 'not found.'
# Try installing it via easy_install... # Try installing it via easy_install...
if HAS_EASY_INSTALL: if HAS_EASY_INSTALL:
print 'Installing virtualenv via easy_install...', print 'Installing virtualenv via easy_install...',
if not run_command(['which', 'easy_install']): if not run_command(['which', 'easy_install']):
die('ERROR: virtualenv not found.\n\nGlance development requires virtualenv,' die('ERROR: virtualenv not found.\n\n'
' please install it using your favorite package management tool') 'Glance development requires virtualenv, please install'
print 'done.' ' it using your favorite package management tool')
print 'done.' print 'done.'
print 'done.'
def create_virtualenv(venv=VENV): def create_virtualenv(venv=VENV):
"""Creates the virtual environment and installs PIP only into the """Creates the virtual environment and installs PIP only into the
virtual environment virtual environment
""" """
print 'Creating venv...', print 'Creating venv...',
run_command(['virtualenv', '-q', '--no-site-packages', VENV]) run_command(['virtualenv', '-q', '--no-site-packages', VENV])
print 'done.' print 'done.'
print 'Installing pip in virtualenv...', print 'Installing pip in virtualenv...',
if not run_command(['tools/with_venv.sh', 'easy_install', 'pip']).strip(): if not run_command(['tools/with_venv.sh', 'easy_install', 'pip']).strip():
die("Failed to install pip.") die("Failed to install pip.")
print 'done.' print 'done.'
def install_dependencies(venv=VENV): def install_dependencies(venv=VENV):
print 'Installing dependencies with pip (this can take a while)...' print 'Installing dependencies with pip (this can take a while)...'
# Install greenlet by hand - just listing it in the requires file does not # Install greenlet by hand - just listing it in the requires file does not
# get it in stalled in the right order # get it in stalled in the right order
run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv, 'greenlet'], venv_tool = 'tools/with_venv.sh'
redirect_output=False) run_command([venv_tool, 'pip', 'install', '-E', venv, 'greenlet'],
run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv, '-r', PIP_REQUIRES], redirect_output=False)
redirect_output=False) run_command([venv_tool, 'pip', 'install', '-E', venv, '-r', PIP_REQUIRES],
run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv, TWISTED_NOVA], redirect_output=False)
redirect_output=False) run_command([venv_tool, 'pip', 'install', '-E', venv, TWISTED_NOVA],
redirect_output=False)
# Tell the virtual env how to "import glance" # Tell the virtual env how to "import glance"
pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", "glance.pth") pthfile = os.path.join(venv, "lib", "python2.6", "site-packages",
f = open(pthfile, 'w') "glance.pth")
f.write("%s\n" % ROOT) f = open(pthfile, 'w')
f.write("%s\n" % ROOT)
def print_help(): def print_help():
help = """ help = """
Glance development environment setup is complete. Glance development environment setup is complete.
Glance development uses virtualenv to track and manage Python dependencies Glance development uses virtualenv to track and manage Python dependencies
@ -114,7 +120,7 @@ def print_help():
To activate the Glance virtualenv for the extent of your current shell session To activate the Glance virtualenv for the extent of your current shell session
you can run: you can run:
$ source .glance-venv/bin/activate $ source .glance-venv/bin/activate
Or, if you prefer, you can run commands in the virtualenv on a case by case Or, if you prefer, you can run commands in the virtualenv on a case by case
basis by running: basis by running:
@ -122,15 +128,15 @@ def print_help():
$ tools/with_venv.sh <your command> $ tools/with_venv.sh <your command>
Also, make test will automatically use the virtualenv. Also, make test will automatically use the virtualenv.
""" """
print help print help
def main(argv): def main(argv):
check_dependencies() check_dependencies()
create_virtualenv() create_virtualenv()
install_dependencies() install_dependencies()
print_help() print_help()
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv) main(sys.argv)