Store api_version object in one place

Currently we store api_version in two places: client and
HTTPClient/SessionClient instances.

It would be nice to store it in one place, so it would be easier
to change api_version without recreating novaclient object.

Change-Id: I36369a126c20de5922141e8725834ca93d6b0a1a
This commit is contained in:
Andrey Kurilin 2016-08-18 18:34:08 +03:00
parent 38073cab51
commit 65c1fbae70
12 changed files with 77 additions and 67 deletions

View File

@ -14,6 +14,7 @@
from requests import Response from requests import Response
import six import six
from novaclient import api_versions
from novaclient import base from novaclient import base
from novaclient import exceptions from novaclient import exceptions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
@ -21,9 +22,6 @@ from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import flavors from novaclient.v2 import flavors
cs = fakes.FakeClient()
def create_response_obj_with_header(): def create_response_obj_with_header():
resp = Response() resp = Response()
resp.headers['x-openstack-request-id'] = fakes.FAKE_REQUEST_ID resp.headers['x-openstack-request-id'] = fakes.FAKE_REQUEST_ID
@ -37,7 +35,6 @@ def create_response_obj_with_compute_header():
class BaseTest(utils.TestCase): class BaseTest(utils.TestCase):
def test_resource_repr(self): def test_resource_repr(self):
r = base.Resource(None, dict(foo="bar", baz="spam")) r = base.Resource(None, dict(foo="bar", baz="spam"))
self.assertEqual("<Resource baz=spam, foo=bar>", repr(r)) self.assertEqual("<Resource baz=spam, foo=bar>", repr(r))
@ -50,6 +47,7 @@ class BaseTest(utils.TestCase):
self.assertEqual(4, base.getid(TmpObject)) self.assertEqual(4, base.getid(TmpObject))
def test_resource_lazy_getattr(self): def test_resource_lazy_getattr(self):
cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
f = flavors.Flavor(cs.flavors, {'id': 1}) f = flavors.Flavor(cs.flavors, {'id': 1})
self.assertEqual('256 MB Server', f.name) self.assertEqual('256 MB Server', f.name)
cs.assert_called('GET', '/flavors/1') cs.assert_called('GET', '/flavors/1')
@ -74,6 +72,7 @@ class BaseTest(utils.TestCase):
self.assertEqual(r1, r2) self.assertEqual(r1, r2)
def test_findall_invalid_attribute(self): def test_findall_invalid_attribute(self):
cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
# Make sure findall with an invalid attribute doesn't cause errors. # Make sure findall with an invalid attribute doesn't cause errors.
# The following should not raise an exception. # The following should not raise an exception.
cs.flavors.findall(vegetable='carrot') cs.flavors.findall(vegetable='carrot')

View File

@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from novaclient import api_versions
from novaclient import extension from novaclient import extension
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes from novaclient.tests.unit.v2 import fakes
@ -24,7 +25,8 @@ class ListExtensionsTests(utils.TestCase):
extension.Extension(list_extensions.__name__.split(".")[-1], extension.Extension(list_extensions.__name__.split(".")[-1],
list_extensions), list_extensions),
] ]
self.cs = fakes.FakeClient(extensions=extensions) self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"),
extensions=extensions)
def test_list_extensions(self): def test_list_extensions(self):
all_exts = self.cs.list_extensions.show_all() all_exts = self.cs.list_extensions.show_all()

View File

@ -24,7 +24,8 @@ class MigrationsTest(utils.TestCase):
extension.Extension(migrations.__name__.split(".")[-1], extension.Extension(migrations.__name__.split(".")[-1],
migrations), migrations),
] ]
self.cs = fakes.FakeClient(extensions=self.extensions) self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"),
extensions=self.extensions)
def test_list_migrations(self): def test_list_migrations(self):
ml = self.cs.migrations.list() ml = self.cs.migrations.list()

View File

@ -56,13 +56,12 @@ FAKE_RESPONSE_HEADERS = {'x-openstack-request-id': FAKE_REQUEST_ID}
class FakeClient(fakes.FakeClient, client.Client): class FakeClient(fakes.FakeClient, client.Client):
def __init__(self, api_version=None, *args, **kwargs): def __init__(self, api_version, *args, **kwargs):
client.Client.__init__(self, 'username', 'password', client.Client.__init__(self, 'username', 'password',
'project_id', 'auth_url', 'project_id', 'auth_url',
extensions=kwargs.get('extensions'), extensions=kwargs.get('extensions'),
direct_use=False) direct_use=False)
self.api_version = api_version or api_versions.APIVersion("2.1") kwargs["api_version"] = api_version
kwargs["api_version"] = self.api_version
self.client = FakeHTTPClient(**kwargs) self.client = FakeHTTPClient(**kwargs)
@ -2368,8 +2367,8 @@ class FakeSessionClient(fakes.FakeClient, client.Client):
client.Client.__init__(self, 'username', 'password', client.Client.__init__(self, 'username', 'password',
'project_id', 'auth_url', 'project_id', 'auth_url',
extensions=kwargs.get('extensions'), extensions=kwargs.get('extensions'),
api_version=api_version, direct_use=False) direct_use=False)
kwargs['api_version'] = api_version kwargs["api_version"] = api_version
self.client = FakeSessionMockClient(**kwargs) self.client = FakeSessionMockClient(**kwargs)

View File

@ -13,28 +13,29 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from novaclient import api_versions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import flavor_access from novaclient.v2 import flavor_access
cs = fakes.FakeClient()
class FlavorAccessTest(utils.TestCase): class FlavorAccessTest(utils.TestCase):
def setUp(self):
super(FlavorAccessTest, self).setUp()
self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
def test_list_access_by_flavor_private(self): def test_list_access_by_flavor_private(self):
kwargs = {'flavor': cs.flavors.get(2)} kwargs = {'flavor': self.cs.flavors.get(2)}
r = cs.flavor_access.list(**kwargs) r = self.cs.flavor_access.list(**kwargs)
self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/flavors/2/os-flavor-access') self.cs.assert_called('GET', '/flavors/2/os-flavor-access')
for a in r: for a in r:
self.assertIsInstance(a, flavor_access.FlavorAccess) self.assertIsInstance(a, flavor_access.FlavorAccess)
def test_add_tenant_access(self): def test_add_tenant_access(self):
flavor = cs.flavors.get(2) flavor = self.cs.flavors.get(2)
tenant = 'proj2' tenant = 'proj2'
r = cs.flavor_access.add_tenant_access(flavor, tenant) r = self.cs.flavor_access.add_tenant_access(flavor, tenant)
self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST)
body = { body = {
@ -43,14 +44,14 @@ class FlavorAccessTest(utils.TestCase):
} }
} }
cs.assert_called('POST', '/flavors/2/action', body) self.cs.assert_called('POST', '/flavors/2/action', body)
for a in r: for a in r:
self.assertIsInstance(a, flavor_access.FlavorAccess) self.assertIsInstance(a, flavor_access.FlavorAccess)
def test_remove_tenant_access(self): def test_remove_tenant_access(self):
flavor = cs.flavors.get(2) flavor = self.cs.flavors.get(2)
tenant = 'proj2' tenant = 'proj2'
r = cs.flavor_access.remove_tenant_access(flavor, tenant) r = self.cs.flavor_access.remove_tenant_access(flavor, tenant)
self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(r, fakes.FAKE_REQUEST_ID_LIST)
body = { body = {
@ -59,14 +60,14 @@ class FlavorAccessTest(utils.TestCase):
} }
} }
cs.assert_called('POST', '/flavors/2/action', body) self.cs.assert_called('POST', '/flavors/2/action', body)
for a in r: for a in r:
self.assertIsInstance(a, flavor_access.FlavorAccess) self.assertIsInstance(a, flavor_access.FlavorAccess)
def test_repr_flavor_access(self): def test_repr_flavor_access(self):
flavor = cs.flavors.get(2) flavor = self.cs.flavors.get(2)
tenant = 'proj3' tenant = 'proj3'
r = cs.flavor_access.add_tenant_access(flavor, tenant) r = self.cs.flavor_access.add_tenant_access(flavor, tenant)
def get_expected(flavor_access): def get_expected(flavor_access):
return ("<FlavorAccess flavor id: %s, tenant id: %s>" % return ("<FlavorAccess flavor id: %s, tenant id: %s>" %

View File

@ -15,6 +15,7 @@
import mock import mock
from novaclient import api_versions
from novaclient import base from novaclient import base
from novaclient import exceptions from novaclient import exceptions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
@ -25,12 +26,9 @@ from novaclient.v2 import flavors
class FlavorsTest(utils.TestCase): class FlavorsTest(utils.TestCase):
def setUp(self): def setUp(self):
super(FlavorsTest, self).setUp() super(FlavorsTest, self).setUp()
self.cs = self._get_fake_client() self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
self.flavor_type = self._get_flavor_type() self.flavor_type = self._get_flavor_type()
def _get_fake_client(self):
return fakes.FakeClient()
def _get_flavor_type(self): def _get_flavor_type(self):
return flavors.Flavor return flavors.Flavor

View File

@ -13,30 +13,31 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from novaclient import api_versions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes from novaclient.tests.unit.v2 import fakes
cs = fakes.FakeClient()
class QuotaClassSetsTest(utils.TestCase): class QuotaClassSetsTest(utils.TestCase):
def setUp(self):
super(QuotaClassSetsTest, self).setUp()
self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
def test_class_quotas_get(self): def test_class_quotas_get(self):
class_name = 'test' class_name = 'test'
q = cs.quota_classes.get(class_name) q = self.cs.quota_classes.get(class_name)
self.assert_request_id(q, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(q, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/os-quota-class-sets/%s' % class_name) self.cs.assert_called('GET', '/os-quota-class-sets/%s' % class_name)
def test_update_quota(self): def test_update_quota(self):
q = cs.quota_classes.get('test') q = self.cs.quota_classes.get('test')
self.assert_request_id(q, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(q, fakes.FAKE_REQUEST_ID_LIST)
q.update(cores=2) q.update(cores=2)
cs.assert_called('PUT', '/os-quota-class-sets/test') self.cs.assert_called('PUT', '/os-quota-class-sets/test')
def test_refresh_quota(self): def test_refresh_quota(self):
q = cs.quota_classes.get('test') q = self.cs.quota_classes.get('test')
q2 = cs.quota_classes.get('test') q2 = self.cs.quota_classes.get('test')
self.assertEqual(q.cores, q2.cores) self.assertEqual(q.cores, q2.cores)
q2.cores = 0 q2.cores = 0
self.assertNotEqual(q.cores, q2.cores) self.assertNotEqual(q.cores, q2.cores)

View File

@ -20,14 +20,13 @@ from novaclient.v2 import services
class ServicesTest(utils.TestCase): class ServicesTest(utils.TestCase):
api_version = "2.0"
def setUp(self): def setUp(self):
super(ServicesTest, self).setUp() super(ServicesTest, self).setUp()
self.cs = self._get_fake_client() self.cs = fakes.FakeClient(api_versions.APIVersion(self.api_version))
self.service_type = self._get_service_type() self.service_type = self._get_service_type()
def _get_fake_client(self):
return fakes.FakeClient()
def _get_service_type(self): def _get_service_type(self):
return services.Service return services.Service
@ -109,9 +108,7 @@ class ServicesTest(utils.TestCase):
class ServicesV211TestCase(ServicesTest): class ServicesV211TestCase(ServicesTest):
def setUp(self): api_version = "2.11"
super(ServicesV211TestCase, self).setUp()
self.cs.api_version = api_versions.APIVersion("2.11")
def _update_body(self, host, binary, disabled_reason=None, def _update_body(self, host, binary, disabled_reason=None,
force_down=None): force_down=None):

View File

@ -15,6 +15,7 @@ import datetime
import six import six
from novaclient import api_versions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import usage from novaclient.v2 import usage
@ -23,12 +24,9 @@ from novaclient.v2 import usage
class UsageTest(utils.TestCase): class UsageTest(utils.TestCase):
def setUp(self): def setUp(self):
super(UsageTest, self).setUp() super(UsageTest, self).setUp()
self.cs = self._get_fake_client() self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
self.usage_type = self._get_usage_type() self.usage_type = self._get_usage_type()
def _get_fake_client(self):
return fakes.FakeClient()
def _get_usage_type(self): def _get_usage_type(self):
return usage.Usage return usage.Usage

View File

@ -14,6 +14,7 @@
import mock import mock
from novaclient import api_versions
from novaclient import base from novaclient import base
from novaclient import exceptions as exc from novaclient import exceptions as exc
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
@ -24,7 +25,7 @@ from novaclient.v2 import versions
class VersionsTest(utils.TestCase): class VersionsTest(utils.TestCase):
def setUp(self): def setUp(self):
super(VersionsTest, self).setUp() super(VersionsTest, self).setUp()
self.cs = fakes.FakeClient() self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
self.service_type = versions.Version self.service_type = versions.Version
@mock.patch.object(versions.VersionManager, '_is_session_client', @mock.patch.object(versions.VersionManager, '_is_session_client',
@ -98,7 +99,8 @@ class VersionsTest(utils.TestCase):
# doesn't return uuid in url # doesn't return uuid in url
endpoint_type = 'v2.1' endpoint_type = 'v2.1'
expected_endpoint = 'http://nova-api:8774/v2.1/' expected_endpoint = 'http://nova-api:8774/v2.1/'
cs_2_1 = fakes.FakeClient(endpoint_type=endpoint_type) cs_2_1 = fakes.FakeClient(api_versions.APIVersion("2.0"),
endpoint_type=endpoint_type)
result = cs_2_1.versions.get_current() result = cs_2_1.versions.get_current()
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
@ -117,7 +119,8 @@ class VersionsTest(utils.TestCase):
# doesn't return uuid in url # doesn't return uuid in url
endpoint_type = 'v2' endpoint_type = 'v2'
expected_endpoint = 'http://nova-api:8774/v2/' expected_endpoint = 'http://nova-api:8774/v2/'
cs_2 = fakes.FakeClient(endpoint_type=endpoint_type) cs_2 = fakes.FakeClient(api_versions.APIVersion("2.0"),
endpoint_type=endpoint_type)
result = cs_2.versions.get_current() result = cs_2.versions.get_current()
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)

View File

@ -13,51 +13,56 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from novaclient import api_versions
from novaclient.tests.unit import utils from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import volumes from novaclient.v2 import volumes
cs = fakes.FakeClient()
class VolumesTest(utils.TestCase): class VolumesTest(utils.TestCase):
def setUp(self):
super(VolumesTest, self).setUp()
self.cs = fakes.FakeClient(api_versions.APIVersion("2.0"))
def test_create_server_volume(self): def test_create_server_volume(self):
v = cs.volumes.create_server_volume( v = self.cs.volumes.create_server_volume(
server_id=1234, server_id=1234,
volume_id='15e59938-07d5-11e1-90e3-e3dffe0c5983', volume_id='15e59938-07d5-11e1-90e3-e3dffe0c5983',
device='/dev/vdb' device='/dev/vdb'
) )
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('POST', '/servers/1234/os-volume_attachments') self.cs.assert_called('POST', '/servers/1234/os-volume_attachments')
self.assertIsInstance(v, volumes.Volume) self.assertIsInstance(v, volumes.Volume)
def test_update_server_volume(self): def test_update_server_volume(self):
vol_id = '15e59938-07d5-11e1-90e3-e3dffe0c5983' vol_id = '15e59938-07d5-11e1-90e3-e3dffe0c5983'
v = cs.volumes.update_server_volume( v = self.cs.volumes.update_server_volume(
server_id=1234, server_id=1234,
attachment_id='Work', attachment_id='Work',
new_volume_id=vol_id new_volume_id=vol_id
) )
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('PUT', '/servers/1234/os-volume_attachments/Work') self.cs.assert_called('PUT',
'/servers/1234/os-volume_attachments/Work')
self.assertIsInstance(v, volumes.Volume) self.assertIsInstance(v, volumes.Volume)
def test_get_server_volume(self): def test_get_server_volume(self):
v = cs.volumes.get_server_volume(1234, 'Work') v = self.cs.volumes.get_server_volume(1234, 'Work')
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/servers/1234/os-volume_attachments/Work') self.cs.assert_called('GET',
'/servers/1234/os-volume_attachments/Work')
self.assertIsInstance(v, volumes.Volume) self.assertIsInstance(v, volumes.Volume)
def test_list_server_volumes(self): def test_list_server_volumes(self):
vl = cs.volumes.get_server_volumes(1234) vl = self.cs.volumes.get_server_volumes(1234)
self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/servers/1234/os-volume_attachments') self.cs.assert_called('GET',
'/servers/1234/os-volume_attachments')
for v in vl: for v in vl:
self.assertIsInstance(v, volumes.Volume) self.assertIsInstance(v, volumes.Volume)
def test_delete_server_volume(self): def test_delete_server_volume(self):
ret = cs.volumes.delete_server_volume(1234, 'Work') ret = self.cs.volumes.delete_server_volume(1234, 'Work')
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST) self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('DELETE', '/servers/1234/os-volume_attachments/Work') self.cs.assert_called('DELETE',
'/servers/1234/os-volume_attachments/Work')

View File

@ -17,7 +17,6 @@ import logging
from keystoneauth1.exceptions import catalog as key_ex from keystoneauth1.exceptions import catalog as key_ex
from novaclient import api_versions
from novaclient import client from novaclient import client
from novaclient import exceptions from novaclient import exceptions
from novaclient.i18n import _LE from novaclient.i18n import _LE
@ -137,7 +136,6 @@ class Client(object):
self.limits = limits.LimitsManager(self) self.limits = limits.LimitsManager(self)
self.servers = servers.ServerManager(self) self.servers = servers.ServerManager(self)
self.versions = versions.VersionManager(self) self.versions = versions.VersionManager(self)
self.api_version = api_version or api_versions.APIVersion("2.1")
# extensions # extensions
self.agents = agents.AgentsManager(self) self.agents = agents.AgentsManager(self)
@ -217,6 +215,14 @@ class Client(object):
logger=logger, logger=logger,
**kwargs) **kwargs)
@property
def api_version(self):
return self.client.api_version
@api_version.setter
def api_version(self, value):
self.client.api_version = value
@client._original_only @client._original_only
def __enter__(self): def __enter__(self):
self.client.open_session() self.client.open_session()