Remove unused testing files from keystoneclient

This commit is contained in:
Morgan Fainberg
2014-06-19 17:23:33 -07:00
parent 7f431a4598
commit 30ddecdd93
61 changed files with 0 additions and 10644 deletions

View File

@@ -1,68 +0,0 @@
# 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 six
from keystoneclient.apiclient import exceptions
from keystoneclient.tests import utils
class FakeResponse(object):
json_data = {}
def __init__(self, **kwargs):
for key, value in six.iteritems(kwargs):
setattr(self, key, value)
def json(self):
return self.json_data
class ExceptionsArgsTest(utils.TestCase):
def assert_exception(self, ex_cls, method, url, status_code, json_data):
ex = exceptions.from_response(
FakeResponse(status_code=status_code,
headers={"Content-Type": "application/json"},
json_data=json_data),
method,
url)
self.assertIsInstance(ex, ex_cls)
self.assertEqual(ex.message, json_data["error"]["message"])
self.assertEqual(ex.details, json_data["error"]["details"])
self.assertEqual(ex.method, method)
self.assertEqual(ex.url, url)
self.assertEqual(ex.http_status, status_code)
def test_from_response_known(self):
method = "GET"
url = "/fake"
status_code = 400
json_data = {"error": {"message": "fake message",
"details": "fake details"}}
self.assert_exception(
exceptions.BadRequest, method, url, status_code, json_data)
def test_from_response_unknown(self):
method = "POST"
url = "/fake-unknown"
status_code = 499
json_data = {"error": {"message": "fake unknown message",
"details": "fake unknown details"}}
self.assert_exception(
exceptions.HTTPClientError, method, url, status_code, json_data)
status_code = 600
self.assert_exception(
exceptions.HTTPError, method, url, status_code, json_data)

View File

@@ -1,257 +0,0 @@
# 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 copy
import httpretty
from six.moves import urllib
from keystoneclient.auth.identity import v2
from keystoneclient import exceptions
from keystoneclient.openstack.common import jsonutils
from keystoneclient import session
from keystoneclient.tests import utils
class V2IdentityPlugin(utils.TestCase):
TEST_ROOT_URL = 'http://127.0.0.1:5000/'
TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v2.0')
TEST_ROOT_ADMIN_URL = 'http://127.0.0.1:35357/'
TEST_ADMIN_URL = '%s%s' % (TEST_ROOT_ADMIN_URL, 'v2.0')
TEST_PASS = 'password'
TEST_SERVICE_CATALOG = [{
"endpoints": [{
"adminURL": "http://cdn.admin-nets.local:8774/v1.0",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:8774/v1.0",
"publicURL": "http://cdn.admin-nets.local:8774/v1.0/"
}],
"type": "nova_compat",
"name": "nova_compat"
}, {
"endpoints": [{
"adminURL": "http://nova/novapi/admin",
"region": "RegionOne",
"internalURL": "http://nova/novapi/internal",
"publicURL": "http://nova/novapi/public"
}],
"type": "compute",
"name": "nova"
}, {
"endpoints": [{
"adminURL": "http://glance/glanceapi/admin",
"region": "RegionOne",
"internalURL": "http://glance/glanceapi/internal",
"publicURL": "http://glance/glanceapi/public"
}],
"type": "image",
"name": "glance"
}, {
"endpoints": [{
"adminURL": TEST_ADMIN_URL,
"region": "RegionOne",
"internalURL": "http://127.0.0.1:5000/v2.0",
"publicURL": "http://127.0.0.1:5000/v2.0"
}],
"type": "identity",
"name": "keystone"
}, {
"endpoints": [{
"adminURL": "http://swift/swiftapi/admin",
"region": "RegionOne",
"internalURL": "http://swift/swiftapi/internal",
"publicURL": "http://swift/swiftapi/public"
}],
"type": "object-store",
"name": "swift"
}]
def setUp(self):
super(V2IdentityPlugin, self).setUp()
self.TEST_RESPONSE_DICT = {
"access": {
"token": {
"expires": "2020-01-01T00:00:10.000123Z",
"id": self.TEST_TOKEN,
"tenant": {
"id": self.TEST_TENANT_ID
},
},
"user": {
"id": self.TEST_USER
},
"serviceCatalog": self.TEST_SERVICE_CATALOG,
},
}
def stub_auth(self, **kwargs):
self.stub_url(httpretty.POST, ['tokens'], **kwargs)
@httpretty.activate
def test_authenticate_with_username_password(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(a)
s.get_token()
req = {'auth': {'passwordCredentials': {'username': self.TEST_USER,
'password': self.TEST_PASS}}}
self.assertRequestBodyIs(json=req)
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_authenticate_with_username_password_scoped(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS, tenant_id=self.TEST_TENANT_ID)
s = session.Session(a)
s.get_token()
req = {'auth': {'passwordCredentials': {'username': self.TEST_USER,
'password': self.TEST_PASS},
'tenantId': self.TEST_TENANT_ID}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_authenticate_with_token(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v2.Token(self.TEST_URL, 'foo')
s = session.Session(a)
s.get_token()
req = {'auth': {'token': {'id': 'foo'}}}
self.assertRequestBodyIs(json=req)
self.assertRequestHeaderEqual('x-Auth-Token', 'foo')
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_with_trust_id(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS, trust_id='trust')
s = session.Session(a)
s.get_token()
req = {'auth': {'passwordCredentials': {'username': self.TEST_USER,
'password': self.TEST_PASS},
'trust_id': 'trust'}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def _do_service_url_test(self, base_url, endpoint_filter):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url(httpretty.GET, ['path'],
base_url=base_url,
body='SUCCESS', status=200)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
resp = s.get('/path', endpoint_filter=endpoint_filter)
self.assertEqual(resp.status_code, 200)
path = "%s/%s" % (urllib.parse.urlparse(base_url).path, 'path')
self.assertEqual(httpretty.last_request().path, path)
def test_service_url(self):
endpoint_filter = {'service_type': 'compute',
'interface': 'admin',
'service_name': 'nova'}
self._do_service_url_test('http://nova/novapi/admin', endpoint_filter)
def test_service_url_defaults_to_public(self):
endpoint_filter = {'service_type': 'compute'}
self._do_service_url_test('http://nova/novapi/public', endpoint_filter)
@httpretty.activate
def test_endpoint_filter_without_service_type_fails(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.EndpointNotFound, s.get, '/path',
endpoint_filter={'interface': 'admin'})
@httpretty.activate
def test_full_url_overrides_endpoint_filter(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url(httpretty.GET, [],
base_url='http://testurl/',
body='SUCCESS', status=200)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
resp = s.get('http://testurl/',
endpoint_filter={'service_type': 'compute'})
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.text, 'SUCCESS')
@httpretty.activate
def test_invalid_auth_response_dict(self):
self.stub_auth(json={'hello': 'world'})
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.InvalidResponse, s.get, 'http://any',
authenticated=True)
@httpretty.activate
def test_invalid_auth_response_type(self):
self.stub_url(httpretty.POST, ['tokens'], body='testdata')
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.InvalidResponse, s.get, 'http://any',
authenticated=True)
@httpretty.activate
def test_invalidate_response(self):
resp_data1 = copy.deepcopy(self.TEST_RESPONSE_DICT)
resp_data2 = copy.deepcopy(self.TEST_RESPONSE_DICT)
resp_data1['access']['token']['id'] = 'token1'
resp_data2['access']['token']['id'] = 'token2'
auth_responses = [httpretty.Response(body=jsonutils.dumps(resp_data1),
status=200),
httpretty.Response(body=jsonutils.dumps(resp_data2),
status=200)]
self.stub_auth(responses=auth_responses)
a = v2.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertEqual('token1', s.get_token())
a.invalidate()
self.assertEqual('token2', s.get_token())

View File

@@ -1,410 +0,0 @@
# 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 copy
import httpretty
from six.moves import urllib
from keystoneclient import access
from keystoneclient.auth.identity import v3
from keystoneclient import exceptions
from keystoneclient.openstack.common import jsonutils
from keystoneclient import session
from keystoneclient.tests import utils
class V3IdentityPlugin(utils.TestCase):
TEST_ROOT_URL = 'http://127.0.0.1:5000/'
TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v3')
TEST_ROOT_ADMIN_URL = 'http://127.0.0.1:35357/'
TEST_ADMIN_URL = '%s%s' % (TEST_ROOT_ADMIN_URL, 'v3')
TEST_PASS = 'password'
TEST_SERVICE_CATALOG = [{
"endpoints": [{
"url": "http://cdn.admin-nets.local:8774/v1.0/",
"region": "RegionOne",
"interface": "public"
}, {
"url": "http://127.0.0.1:8774/v1.0",
"region": "RegionOne",
"interface": "internal"
}, {
"url": "http://cdn.admin-nets.local:8774/v1.0",
"region": "RegionOne",
"interface": "admin"
}],
"type": "nova_compat"
}, {
"endpoints": [{
"url": "http://nova/novapi/public",
"region": "RegionOne",
"interface": "public"
}, {
"url": "http://nova/novapi/internal",
"region": "RegionOne",
"interface": "internal"
}, {
"url": "http://nova/novapi/admin",
"region": "RegionOne",
"interface": "admin"
}],
"type": "compute",
"name": "nova",
}, {
"endpoints": [{
"url": "http://glance/glanceapi/public",
"region": "RegionOne",
"interface": "public"
}, {
"url": "http://glance/glanceapi/internal",
"region": "RegionOne",
"interface": "internal"
}, {
"url": "http://glance/glanceapi/admin",
"region": "RegionOne",
"interface": "admin"
}],
"type": "image",
"name": "glance"
}, {
"endpoints": [{
"url": "http://127.0.0.1:5000/v3",
"region": "RegionOne",
"interface": "public"
}, {
"url": "http://127.0.0.1:5000/v3",
"region": "RegionOne",
"interface": "internal"
}, {
"url": TEST_ADMIN_URL,
"region": "RegionOne",
"interface": "admin"
}],
"type": "identity"
}, {
"endpoints": [{
"url": "http://swift/swiftapi/public",
"region": "RegionOne",
"interface": "public"
}, {
"url": "http://swift/swiftapi/internal",
"region": "RegionOne",
"interface": "internal"
}, {
"url": "http://swift/swiftapi/admin",
"region": "RegionOne",
"interface": "admin"
}],
"type": "object-store"
}]
def setUp(self):
super(V3IdentityPlugin, self).setUp()
self.TEST_RESPONSE_DICT = {
"token": {
"methods": [
"token",
"password"
],
"expires_at": "2020-01-01T00:00:10.000123Z",
"project": {
"domain": {
"id": self.TEST_DOMAIN_ID,
"name": self.TEST_DOMAIN_NAME
},
"id": self.TEST_TENANT_ID,
"name": self.TEST_TENANT_NAME
},
"user": {
"domain": {
"id": self.TEST_DOMAIN_ID,
"name": self.TEST_DOMAIN_NAME
},
"id": self.TEST_USER,
"name": self.TEST_USER
},
"issued_at": "2013-05-29T16:55:21.468960Z",
"catalog": self.TEST_SERVICE_CATALOG
},
}
def stub_auth(self, subject_token=None, **kwargs):
if not subject_token:
subject_token = self.TEST_TOKEN
self.stub_url(httpretty.POST, ['auth', 'tokens'],
X_Subject_Token=subject_token, **kwargs)
@httpretty.activate
def test_authenticate_with_username_password(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL,
username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}}}}}
self.assertRequestBodyIs(json=req)
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_authenticate_with_username_password_domain_scoped(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS, domain_id=self.TEST_DOMAIN_ID)
s = session.Session(a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}}},
'scope': {'domain': {'id': self.TEST_DOMAIN_ID}}}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_authenticate_with_username_password_project_scoped(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS,
project_id=self.TEST_DOMAIN_ID)
s = session.Session(a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}}},
'scope': {'project': {'id': self.TEST_DOMAIN_ID}}}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
self.assertEqual(s.auth.auth_ref.project_id, self.TEST_DOMAIN_ID)
@httpretty.activate
def test_authenticate_with_token(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Token(self.TEST_URL, self.TEST_TOKEN)
s = session.Session(auth=a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['token'],
'token': {'id': self.TEST_TOKEN}}}}
self.assertRequestBodyIs(json=req)
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_with_expired(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
d = copy.deepcopy(self.TEST_RESPONSE_DICT)
d['token']['expires_at'] = '2000-01-01T00:00:10.000123Z'
a = v3.Password(self.TEST_URL, username='username',
password='password')
a.auth_ref = access.AccessInfo.factory(body=d)
s = session.Session(auth=a)
s.get_token()
self.assertEqual(a.auth_ref['expires_at'],
self.TEST_RESPONSE_DICT['token']['expires_at'])
def test_with_domain_and_project_scoping(self):
a = v3.Password(self.TEST_URL, username='username',
password='password', project_id='project',
domain_id='domain')
self.assertRaises(exceptions.AuthorizationFailure,
a.get_token, None)
@httpretty.activate
def test_with_trust_id(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS, trust_id='trust')
s = session.Session(a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}}},
'scope': {'OS-TRUST:trust': {'id': 'trust'}}}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_with_multiple_mechanisms_factory(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
p = v3.PasswordMethod(username=self.TEST_USER, password=self.TEST_PASS)
t = v3.TokenMethod(token='foo')
a = v3.Auth(self.TEST_URL, [p, t], trust_id='trust')
s = session.Session(a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password', 'token'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}},
'token': {'id': 'foo'}},
'scope': {'OS-TRUST:trust': {'id': 'trust'}}}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
@httpretty.activate
def test_with_multiple_mechanisms(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
p = v3.PasswordMethod(username=self.TEST_USER,
password=self.TEST_PASS)
t = v3.TokenMethod(token='foo')
a = v3.Auth(self.TEST_URL, [p, t], trust_id='trust')
s = session.Session(auth=a)
s.get_token()
req = {'auth': {'identity':
{'methods': ['password', 'token'],
'password': {'user': {'name': self.TEST_USER,
'password': self.TEST_PASS}},
'token': {'id': 'foo'}},
'scope': {'OS-TRUST:trust': {'id': 'trust'}}}}
self.assertRequestBodyIs(json=req)
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
def test_with_multiple_scopes(self):
s = session.Session()
a = v3.Password(self.TEST_URL,
username=self.TEST_USER, password=self.TEST_PASS,
domain_id='x', project_id='x')
self.assertRaises(exceptions.AuthorizationFailure, a.get_auth_ref, s)
a = v3.Password(self.TEST_URL,
username=self.TEST_USER, password=self.TEST_PASS,
domain_id='x', trust_id='x')
self.assertRaises(exceptions.AuthorizationFailure, a.get_auth_ref, s)
@httpretty.activate
def _do_service_url_test(self, base_url, endpoint_filter):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url(httpretty.GET, ['path'],
base_url=base_url,
body='SUCCESS', status=200)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
resp = s.get('/path', endpoint_filter=endpoint_filter)
self.assertEqual(resp.status_code, 200)
path = "%s/%s" % (urllib.parse.urlparse(base_url).path, 'path')
self.assertEqual(httpretty.last_request().path, path)
def test_service_url(self):
endpoint_filter = {'service_type': 'compute',
'interface': 'admin',
'service_name': 'nova'}
self._do_service_url_test('http://nova/novapi/admin', endpoint_filter)
def test_service_url_defaults_to_public(self):
endpoint_filter = {'service_type': 'compute'}
self._do_service_url_test('http://nova/novapi/public', endpoint_filter)
@httpretty.activate
def test_endpoint_filter_without_service_type_fails(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.EndpointNotFound, s.get, '/path',
endpoint_filter={'interface': 'admin'})
@httpretty.activate
def test_full_url_overrides_endpoint_filter(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url(httpretty.GET, [],
base_url='http://testurl/',
body='SUCCESS', status=200)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
resp = s.get('http://testurl/',
endpoint_filter={'service_type': 'compute'})
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.text, 'SUCCESS')
@httpretty.activate
def test_invalid_auth_response_dict(self):
self.stub_auth(json={'hello': 'world'})
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.InvalidResponse, s.get, 'http://any',
authenticated=True)
@httpretty.activate
def test_invalid_auth_response_type(self):
self.stub_url(httpretty.POST, ['auth', 'tokens'], body='testdata')
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertRaises(exceptions.InvalidResponse, s.get, 'http://any',
authenticated=True)
@httpretty.activate
def test_invalidate_response(self):
body = jsonutils.dumps(self.TEST_RESPONSE_DICT)
auth_responses = [httpretty.Response(body=body,
X_Subject_Token='token1',
status=200),
httpretty.Response(body=body,
X_Subject_Token='token2',
status=200)]
httpretty.register_uri(httpretty.POST,
'%s/auth/tokens' % self.TEST_URL,
responses=auth_responses)
a = v3.Password(self.TEST_URL, username=self.TEST_USER,
password=self.TEST_PASS)
s = session.Session(auth=a)
self.assertEqual('token1', s.get_token())
a.invalidate()
self.assertEqual('token2', s.get_token())

View File

@@ -1,49 +0,0 @@
# 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 httpretty
from keystoneclient.auth import token_endpoint
from keystoneclient import session
from keystoneclient.tests import utils
class TokenEndpointTest(utils.TestCase):
TEST_TOKEN = 'aToken'
TEST_URL = 'http://server/prefix'
@httpretty.activate
def test_basic_case(self):
httpretty.register_uri(httpretty.GET, self.TEST_URL, body='body')
a = token_endpoint.Token(self.TEST_URL, self.TEST_TOKEN)
s = session.Session(auth=a)
data = s.get(self.TEST_URL, authenticated=True)
self.assertEqual(data.text, 'body')
self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)
@httpretty.activate
def test_basic_endpoint_case(self):
self.stub_url(httpretty.GET, ['p'], body='body')
a = token_endpoint.Token(self.TEST_URL, self.TEST_TOKEN)
s = session.Session(auth=a)
data = s.get('/p',
authenticated=True,
endpoint_filter={'service': 'identity'})
self.assertEqual(self.TEST_URL, a.get_endpoint(s))
self.assertEqual('body', data.text)
self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)

View File

@@ -1,118 +0,0 @@
# 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.
"""
A fake server that "responds" to API methods with pre-canned responses.
All of these responses come from the spec, so if for some reason the spec's
wrong the tests might raise AssertionError. I've indicated in comments the
places where actual behavior differs from the spec.
"""
from keystoneclient import access
def assert_has_keys(dict, required=[], optional=[]):
keys = dict.keys()
for k in required:
try:
assert k in keys
except AssertionError:
extra_keys = set(keys).difference(set(required + optional))
raise AssertionError("found unexpected keys: %s" %
list(extra_keys))
class FakeClient(object):
def assert_called(self, method, url, body=None, pos=-1):
"""Assert than an API method was just called."""
expected = (method, url)
called = self.callstack[pos][0:2]
assert self.callstack, ("Expected %s %s but no calls were made." %
expected)
assert expected == called, ("Expected %s %s; got %s %s" %
(expected + called))
if body is not None:
assert self.callstack[pos][2] == body
def assert_called_anytime(self, method, url, body=None):
"""Assert than an API method was called anytime in the test."""
expected = (method, url)
assert self.callstack, ("Expected %s %s but no calls were made." %
expected)
found = False
for entry in self.callstack:
if expected == entry[0:2]:
found = True
break
assert found, ('Expected %s; got %s' %
(expected, self.callstack))
if body is not None:
if entry[2] != body:
raise AssertionError('%s != %s' % (entry[2], body))
self.callstack = []
def clear_callstack(self):
self.callstack = []
def authenticate(self, cl_obj):
cl_obj.user_id = '1'
cl_obj.auth_user_id = '1'
cl_obj.project_id = '1'
cl_obj.auth_tenant_id = '1'
cl_obj.auth_ref = access.AccessInfo.factory(None, {
"access": {
"token": {
"expires": "2012-02-05T00:00:00",
"id": "887665443383838",
"tenant": {
"id": "1",
"name": "customer-x"
}
},
"serviceCatalog": [{
"endpoints": [{
"adminURL": "http://swift.admin-nets.local:8080/",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:8080/v1/AUTH_1",
"publicURL":
"http://swift.publicinternets.com/v1/AUTH_1"
}],
"type": "object-store",
"name": "swift"
}, {
"endpoints": [{
"adminURL": "http://cdn.admin-nets.local/v1.1/1",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:7777/v1.1/1",
"publicURL": "http://cdn.publicinternets.com/v1.1/1"
}],
"type": "object-store",
"name": "cdn"
}],
"user": {
"id": "1",
"roles": [{
"tenantId": "1",
"id": "3",
"name": "Member"
}],
"name": "joeuser"
}
}
})

View File

@@ -1,67 +0,0 @@
# Copyright 2014 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 httpretty
from keystoneclient.generic import client
from keystoneclient.openstack.common import jsonutils
from keystoneclient.tests import utils
BASE_HOST = 'http://keystone.example.com'
BASE_URL = "%s:5000/" % BASE_HOST
V2_URL = "%sv2.0" % BASE_URL
EXTENSION_NAMESPACE = "http://docs.openstack.org/identity/api/ext/OS-FAKE/v1.0"
EXTENSION_DESCRIBED = {"href": "https://github.com/openstack/identity-api",
"rel": "describedby",
"type": "text/html"}
EXTENSION_ALIAS_FOO = "OS-FAKE-FOO"
EXTENSION_NAME_FOO = "OpenStack Keystone Fake Extension Foo"
EXTENSION_FOO = {"alias": EXTENSION_ALIAS_FOO,
"description": "Fake Foo extension to V2.0 API.",
"links": [EXTENSION_DESCRIBED],
"name": EXTENSION_NAME_FOO,
"namespace": EXTENSION_NAMESPACE,
"updated": '2014-01-08T00:00:00Z'}
EXTENSION_ALIAS_BAR = "OS-FAKE-BAR"
EXTENSION_NAME_BAR = "OpenStack Keystone Fake Extension Bar"
EXTENSION_BAR = {"alias": EXTENSION_ALIAS_BAR,
"description": "Fake Bar extension to V2.0 API.",
"links": [EXTENSION_DESCRIBED],
"name": EXTENSION_NAME_BAR,
"namespace": EXTENSION_NAMESPACE,
"updated": '2014-01-08T00:00:00Z'}
def _create_extension_list(extensions):
return jsonutils.dumps({'extensions': {'values': extensions}})
EXTENSION_LIST = _create_extension_list([EXTENSION_FOO, EXTENSION_BAR])
@httpretty.activate
class ClientDiscoveryTests(utils.TestCase):
def test_discover_extensions_v2(self):
httpretty.register_uri(httpretty.GET, "%s/extensions" % V2_URL,
body=EXTENSION_LIST)
extensions = client.Client().discover_extensions(url=V2_URL)
self.assertIn(EXTENSION_ALIAS_FOO, extensions)
self.assertEqual(extensions[EXTENSION_ALIAS_FOO], EXTENSION_NAME_FOO)
self.assertIn(EXTENSION_ALIAS_BAR, extensions)
self.assertEqual(extensions[EXTENSION_ALIAS_BAR], EXTENSION_NAME_BAR)

View File

@@ -1,129 +0,0 @@
# Copyright 2014 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 mock
from six import moves
from keystoneclient.generic import shell
from keystoneclient.tests import utils
class DoDiscoverTest(utils.TestCase):
"""Unit tests for do_discover function."""
foo_version = {
'id': 'foo_id',
'status': 'foo_status',
'url': 'http://foo/url',
}
bar_version = {
'id': 'bar_id',
'status': 'bar_status',
'url': 'http://bar/url',
}
foo_extension = {
'foo': 'foo_extension',
'message': 'extension_message',
'bar': 'bar_extension',
}
stub_message = 'This is a stub message'
def setUp(self):
super(DoDiscoverTest, self).setUp()
self.client_mock = mock.Mock()
self.client_mock.discover.return_value = {}
def _execute_discover(self):
"""Call do_discover function and capture output
:return: captured output is returned
"""
with mock.patch('sys.stdout',
new_callable=moves.StringIO) as mock_stdout:
shell.do_discover(self.client_mock, args=None)
output = mock_stdout.getvalue()
return output
def _check_version_print(self, output, version):
"""Checks all api version's parameters are present in output."""
self.assertIn(version['id'], output)
self.assertIn(version['status'], output)
self.assertIn(version['url'], output)
def test_no_keystones(self):
# No servers configured for client,
# corresponding message should be printed
output = self._execute_discover()
self.assertIn('No Keystone-compatible endpoint found', output)
def test_endpoint(self):
# Endpoint is configured for client,
# client's discover method should be called with that value
self.client_mock.endpoint = 'Some non-empty value'
shell.do_discover(self.client_mock, args=None)
self.client_mock.discover.assert_called_with(self.client_mock.endpoint)
def test_auth_url(self):
# No endpoint provided for client, but there is an auth_url
# client's discover method should be called with auth_url value
self.client_mock.endpoint = False
self.client_mock.auth_url = 'Some non-empty value'
shell.do_discover(self.client_mock, args=None)
self.client_mock.discover.assert_called_with(self.client_mock.auth_url)
def test_empty(self):
# No endpoint or auth_url is configured for client.
# client.discover() should be called without parameters
self.client_mock.endpoint = False
self.client_mock.auth_url = False
shell.do_discover(self.client_mock, args=None)
self.client_mock.discover.assert_called_with()
def test_message(self):
# If client.discover() result contains message - it should be printed
self.client_mock.discover.return_value = {'message': self.stub_message}
output = self._execute_discover()
self.assertIn(self.stub_message, output)
def test_versions(self):
# Every version in client.discover() result should be printed
# and client.discover_extension() should be called on its url
self.client_mock.discover.return_value = {
'foo': self.foo_version,
'bar': self.bar_version,
}
self.client_mock.discover_extensions.return_value = {}
output = self._execute_discover()
self._check_version_print(output, self.foo_version)
self._check_version_print(output, self.bar_version)
discover_extension_calls = [
mock.call(self.foo_version['url']),
mock.call(self.bar_version['url']),
]
self.client_mock.discover_extensions.assert_has_calls(
discover_extension_calls,
any_order=True)
def test_extensions(self):
# Every extension's parameters should be printed
# Extension's message should be omitted
self.client_mock.discover.return_value = {'foo': self.foo_version}
self.client_mock.discover_extensions.return_value = self.foo_extension
output = self._execute_discover()
self.assertIn(self.foo_extension['foo'], output)
self.assertIn(self.foo_extension['bar'], output)
self.assertNotIn(self.foo_extension['message'], output)

View File

@@ -1,161 +0,0 @@
# 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.
from keystoneclient import base
from keystoneclient.tests import utils
from keystoneclient.v2_0 import client
from keystoneclient.v2_0 import roles
class HumanReadable(base.Resource):
HUMAN_ID = True
class BaseTest(utils.TestCase):
def test_resource_repr(self):
r = base.Resource(None, dict(foo="bar", baz="spam"))
self.assertEqual(repr(r), "<Resource baz=spam, foo=bar>")
def test_getid(self):
self.assertEqual(base.getid(4), 4)
class TmpObject(object):
id = 4
self.assertEqual(base.getid(TmpObject), 4)
def test_resource_lazy_getattr(self):
self.client = client.Client(username=self.TEST_USER,
token=self.TEST_TOKEN,
tenant_name=self.TEST_TENANT_NAME,
auth_url='http://127.0.0.1:5000',
endpoint='http://127.0.0.1:5000')
self.client.get = self.mox.CreateMockAnything()
self.client.get('/OS-KSADM/roles/1').AndRaise(AttributeError)
self.mox.ReplayAll()
f = roles.Role(self.client.roles, {'id': 1, 'name': 'Member'})
self.assertEqual(f.name, 'Member')
# Missing stuff still fails after a second get
self.assertRaises(AttributeError, getattr, f, 'blahblah')
def test_eq(self):
# Two resources of the same type with the same id: equal
r1 = base.Resource(None, {'id': 1, 'name': 'hi'})
r2 = base.Resource(None, {'id': 1, 'name': 'hello'})
self.assertEqual(r1, r2)
# Two resoruces of different types: never equal
r1 = base.Resource(None, {'id': 1})
r2 = roles.Role(None, {'id': 1})
self.assertNotEqual(r1, r2)
# Two resources with no ID: equal if their info is equal
r1 = base.Resource(None, {'name': 'joe', 'age': 12})
r2 = base.Resource(None, {'name': 'joe', 'age': 12})
self.assertEqual(r1, r2)
r1 = base.Resource(None, {'id': 1})
self.assertNotEqual(r1, object())
self.assertNotEqual(r1, {'id': 1})
def test_human_id(self):
r = base.Resource(None, {"name": "1 of !"})
self.assertIsNone(r.human_id)
r = HumanReadable(None, {"name": "1 of !"})
self.assertEqual(r.human_id, "1-of")
class ManagerTest(utils.TestCase):
body = {"hello": {"hi": 1}}
url = "/test-url"
def setUp(self):
super(ManagerTest, self).setUp()
self.client = client.Client(username=self.TEST_USER,
token=self.TEST_TOKEN,
tenant_name=self.TEST_TENANT_NAME,
auth_url='http://127.0.0.1:5000',
endpoint='http://127.0.0.1:5000')
self.mgr = base.Manager(self.client)
self.mgr.resource_class = base.Resource
def test_api(self):
self.assertEqual(self.mgr.api, self.client)
def test_get(self):
self.client.get = self.mox.CreateMockAnything()
self.client.get(self.url).AndReturn((None, self.body))
self.mox.ReplayAll()
rsrc = self.mgr._get(self.url, "hello")
self.assertEqual(rsrc.hi, 1)
def test_post(self):
self.client.post = self.mox.CreateMockAnything()
self.client.post(self.url, body=self.body).AndReturn((None, self.body))
self.client.post(self.url, body=self.body).AndReturn((None, self.body))
self.mox.ReplayAll()
rsrc = self.mgr._post(self.url, self.body, "hello")
self.assertEqual(rsrc.hi, 1)
rsrc = self.mgr._post(self.url, self.body, "hello", return_raw=True)
self.assertEqual(rsrc["hi"], 1)
def test_put(self):
self.client.put = self.mox.CreateMockAnything()
self.client.put(self.url, body=self.body).AndReturn((None, self.body))
self.client.put(self.url, body=self.body).AndReturn((None, self.body))
self.mox.ReplayAll()
rsrc = self.mgr._put(self.url, self.body, "hello")
self.assertEqual(rsrc.hi, 1)
rsrc = self.mgr._put(self.url, self.body)
self.assertEqual(rsrc.hello["hi"], 1)
def test_patch(self):
self.client.patch = self.mox.CreateMockAnything()
self.client.patch(self.url, body=self.body).AndReturn(
(None, self.body))
self.client.patch(self.url, body=self.body).AndReturn(
(None, self.body))
self.mox.ReplayAll()
rsrc = self.mgr._patch(self.url, self.body, "hello")
self.assertEqual(rsrc.hi, 1)
rsrc = self.mgr._patch(self.url, self.body)
self.assertEqual(rsrc.hello["hi"], 1)
def test_update(self):
self.client.patch = self.mox.CreateMockAnything()
self.client.put = self.mox.CreateMockAnything()
self.client.patch(
self.url, body=self.body, management=False).AndReturn((None,
self.body))
self.client.put(self.url, body=None, management=True).AndReturn(
(None, self.body))
self.mox.ReplayAll()
rsrc = self.mgr._update(
self.url, body=self.body, response_key="hello", method="PATCH",
management=False)
self.assertEqual(rsrc.hi, 1)
rsrc = self.mgr._update(
self.url, body=None, response_key="hello", method="PUT",
management=True)
self.assertEqual(rsrc.hi, 1)

View File

@@ -1,149 +0,0 @@
# 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 os
import subprocess
import mock
import testresources
from testtools import matchers
from keystoneclient.common import cms
from keystoneclient import exceptions
from keystoneclient.tests import client_fixtures
from keystoneclient.tests import utils
class CMSTest(utils.TestCase, testresources.ResourcedTestCase):
"""Unit tests for the keystoneclient.common.cms module."""
resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)]
def test_cms_verify(self):
self.assertRaises(exceptions.CertificateConfigError,
cms.cms_verify,
'data',
'no_exist_cert_file',
'no_exist_ca_file')
def test_token_tocms_to_token(self):
with open(os.path.join(client_fixtures.CMSDIR,
'auth_token_scoped.pem')) as f:
AUTH_TOKEN_SCOPED_CMS = f.read()
self.assertEqual(cms.token_to_cms(self.examples.SIGNED_TOKEN_SCOPED),
AUTH_TOKEN_SCOPED_CMS)
tok = cms.cms_to_token(cms.token_to_cms(
self.examples.SIGNED_TOKEN_SCOPED))
self.assertEqual(tok, self.examples.SIGNED_TOKEN_SCOPED)
def test_asn1_token(self):
self.assertTrue(cms.is_asn1_token(self.examples.SIGNED_TOKEN_SCOPED))
self.assertFalse(cms.is_asn1_token('FOOBAR'))
def test_cms_sign_token_no_files(self):
self.assertRaises(subprocess.CalledProcessError,
cms.cms_sign_token,
self.examples.TOKEN_SCOPED_DATA,
'/no/such/file', '/no/such/key')
def test_cms_sign_token_no_files_pkiz(self):
self.assertRaises(subprocess.CalledProcessError,
cms.pkiz_sign,
self.examples.TOKEN_SCOPED_DATA,
'/no/such/file', '/no/such/key')
def test_cms_sign_token_success(self):
self.assertTrue(
cms.pkiz_sign(self.examples.TOKEN_SCOPED_DATA,
self.examples.SIGNING_CERT_FILE,
self.examples.SIGNING_KEY_FILE))
def test_cms_verify_token_no_files(self):
self.assertRaises(exceptions.CertificateConfigError,
cms.cms_verify,
self.examples.SIGNED_TOKEN_SCOPED,
'/no/such/file', '/no/such/key')
def test_cms_verify_token_no_oserror(self):
import errno
def raise_OSError(*args):
e = OSError()
e.errno = errno.EPIPE
raise e
with mock.patch('subprocess.Popen.communicate', new=raise_OSError):
try:
cms.cms_verify("x", '/no/such/file', '/no/such/key')
except subprocess.CalledProcessError as e:
self.assertIn('/no/such/file', e.output)
self.assertIn('Hit OSError ', e.output)
else:
self.fail('Expected subprocess.CalledProcessError')
def test_cms_verify_token_scoped(self):
cms_content = cms.token_to_cms(self.examples.SIGNED_TOKEN_SCOPED)
self.assertTrue(cms.cms_verify(cms_content,
self.examples.SIGNING_CERT_FILE,
self.examples.SIGNING_CA_FILE))
def test_cms_verify_token_scoped_expired(self):
cms_content = cms.token_to_cms(
self.examples.SIGNED_TOKEN_SCOPED_EXPIRED)
self.assertTrue(cms.cms_verify(cms_content,
self.examples.SIGNING_CERT_FILE,
self.examples.SIGNING_CA_FILE))
def test_cms_verify_token_unscoped(self):
cms_content = cms.token_to_cms(self.examples.SIGNED_TOKEN_UNSCOPED)
self.assertTrue(cms.cms_verify(cms_content,
self.examples.SIGNING_CERT_FILE,
self.examples.SIGNING_CA_FILE))
def test_cms_verify_token_v3_scoped(self):
cms_content = cms.token_to_cms(self.examples.SIGNED_v3_TOKEN_SCOPED)
self.assertTrue(cms.cms_verify(cms_content,
self.examples.SIGNING_CERT_FILE,
self.examples.SIGNING_CA_FILE))
def test_cms_hash_token_no_token_id(self):
token_id = None
self.assertThat(cms.cms_hash_token(token_id), matchers.Is(None))
def test_cms_hash_token_not_pki(self):
"""If the token_id is not a PKI token then it returns the token_id."""
token = 'something'
self.assertFalse(cms.is_asn1_token(token))
self.assertThat(cms.cms_hash_token(token), matchers.Is(token))
def test_cms_hash_token_default_md5(self):
"""The default hash method is md5."""
token = self.examples.SIGNED_TOKEN_SCOPED
token_id_default = cms.cms_hash_token(token)
token_id_md5 = cms.cms_hash_token(token, mode='md5')
self.assertThat(token_id_default, matchers.Equals(token_id_md5))
# md5 hash is 32 chars.
self.assertThat(token_id_default, matchers.HasLength(32))
def test_cms_hash_token_sha256(self):
"""Can also hash with sha256."""
token = self.examples.SIGNED_TOKEN_SCOPED
token_id = cms.cms_hash_token(token, mode='sha256')
# sha256 hash is 64 chars.
self.assertThat(token_id, matchers.HasLength(64))
def load_tests(loader, tests, pattern):
return testresources.OptimisingTestSuite(tests)

View File

@@ -1,790 +0,0 @@
# 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 httpretty
import six
from testtools import matchers
from keystoneclient import _discover
from keystoneclient import client
from keystoneclient import discover
from keystoneclient import exceptions
from keystoneclient.openstack.common import jsonutils
from keystoneclient.tests import utils
from keystoneclient.v2_0 import client as v2_client
from keystoneclient.v3 import client as v3_client
BASE_HOST = 'http://keystone.example.com'
BASE_URL = "%s:5000/" % BASE_HOST
UPDATED = '2013-03-06T00:00:00Z'
TEST_SERVICE_CATALOG = [{
"endpoints": [{
"adminURL": "%s:8774/v1.0" % BASE_HOST,
"region": "RegionOne",
"internalURL": "%s://127.0.0.1:8774/v1.0" % BASE_HOST,
"publicURL": "%s:8774/v1.0/" % BASE_HOST
}],
"type": "nova_compat",
"name": "nova_compat"
}, {
"endpoints": [{
"adminURL": "http://nova/novapi/admin",
"region": "RegionOne",
"internalURL": "http://nova/novapi/internal",
"publicURL": "http://nova/novapi/public"
}],
"type": "compute",
"name": "nova"
}, {
"endpoints": [{
"adminURL": "http://glance/glanceapi/admin",
"region": "RegionOne",
"internalURL": "http://glance/glanceapi/internal",
"publicURL": "http://glance/glanceapi/public"
}],
"type": "image",
"name": "glance"
}, {
"endpoints": [{
"adminURL": "%s:35357/v2.0" % BASE_HOST,
"region": "RegionOne",
"internalURL": "%s:5000/v2.0" % BASE_HOST,
"publicURL": "%s:5000/v2.0" % BASE_HOST
}],
"type": "identity",
"name": "keystone"
}, {
"endpoints": [{
"adminURL": "http://swift/swiftapi/admin",
"region": "RegionOne",
"internalURL": "http://swift/swiftapi/internal",
"publicURL": "http://swift/swiftapi/public"
}],
"type": "object-store",
"name": "swift"
}]
V2_URL = "%sv2.0" % BASE_URL
V2_DESCRIBED_BY_HTML = {'href': 'http://docs.openstack.org/api/'
'openstack-identity-service/2.0/content/',
'rel': 'describedby',
'type': 'text/html'}
V2_DESCRIBED_BY_PDF = {'href': 'http://docs.openstack.org/api/openstack-ident'
'ity-service/2.0/identity-dev-guide-2.0.pdf',
'rel': 'describedby',
'type': 'application/pdf'}
V2_VERSION = {'id': 'v2.0',
'links': [{'href': V2_URL, 'rel': 'self'},
V2_DESCRIBED_BY_HTML, V2_DESCRIBED_BY_PDF],
'status': 'stable',
'updated': UPDATED}
V2_AUTH_RESPONSE = jsonutils.dumps({
"access": {
"token": {
"expires": "2020-01-01T00:00:10.000123Z",
"id": 'fakeToken',
"tenant": {
"id": '1'
},
},
"user": {
"id": 'test'
},
"serviceCatalog": TEST_SERVICE_CATALOG,
},
})
V3_URL = "%sv3" % BASE_URL
V3_MEDIA_TYPES = [{'base': 'application/json',
'type': 'application/vnd.openstack.identity-v3+json'},
{'base': 'application/xml',
'type': 'application/vnd.openstack.identity-v3+xml'}]
V3_VERSION = {'id': 'v3.0',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED}
V3_TOKEN = six.u('3e2813b7ba0b4006840c3825860b86ed'),
V3_AUTH_RESPONSE = jsonutils.dumps({
"token": {
"methods": [
"token",
"password"
],
"expires_at": "2020-01-01T00:00:10.000123Z",
"project": {
"domain": {
"id": '1',
"name": 'test-domain'
},
"id": '1',
"name": 'test-project'
},
"user": {
"domain": {
"id": '1',
"name": 'test-domain'
},
"id": '1',
"name": 'test-user'
},
"issued_at": "2013-05-29T16:55:21.468960Z",
},
})
CINDER_EXAMPLES = {
"versions": [
{
"status": "CURRENT",
"updated": "2012-01-04T11:33:21Z",
"id": "v1.0",
"links": [
{
"href": "%sv1/" % BASE_URL,
"rel": "self"
}
]
},
{
"status": "CURRENT",
"updated": "2012-11-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "%sv2/" % BASE_URL,
"rel": "self"
}
]
}
]
}
GLANCE_EXAMPLES = {
"versions": [
{
"status": "CURRENT",
"id": "v2.2",
"links": [
{
"href": "%sv2/" % BASE_URL,
"rel": "self"
}
]
},
{
"status": "SUPPORTED",
"id": "v2.1",
"links": [
{
"href": "%sv2/" % BASE_URL,
"rel": "self"
}
]
},
{
"status": "SUPPORTED",
"id": "v2.0",
"links": [
{
"href": "%sv2/" % BASE_URL,
"rel": "self"
}
]
},
{
"status": "CURRENT",
"id": "v1.1",
"links": [
{
"href": "%sv1/" % BASE_URL,
"rel": "self"
}
]
},
{
"status": "SUPPORTED",
"id": "v1.0",
"links": [
{
"href": "%sv1/" % BASE_URL,
"rel": "self"
}
]
}
]
}
def _create_version_list(versions):
return jsonutils.dumps({'versions': {'values': versions}})
def _create_single_version(version):
return jsonutils.dumps({'version': version})
V3_VERSION_LIST = _create_version_list([V3_VERSION, V2_VERSION])
V2_VERSION_LIST = _create_version_list([V2_VERSION])
V3_VERSION_ENTRY = _create_single_version(V3_VERSION)
V2_VERSION_ENTRY = _create_single_version(V2_VERSION)
@httpretty.activate
class AvailableVersionsTests(utils.TestCase):
def test_available_versions_basics(self):
examples = {'keystone': V3_VERSION_LIST,
'cinder': jsonutils.dumps(CINDER_EXAMPLES),
'glance': jsonutils.dumps(GLANCE_EXAMPLES)}
for path, ex in six.iteritems(examples):
url = "%s%s" % (BASE_URL, path)
httpretty.register_uri(httpretty.GET, url, status=300, body=ex)
versions = discover.available_versions(url)
for v in versions:
for n in ('id', 'status', 'links'):
msg = '%s missing from %s version data' % (n, path)
self.assertThat(v, matchers.Annotate(msg,
matchers.Contains(n)))
def test_available_versions_individual(self):
httpretty.register_uri(httpretty.GET, V3_URL, status=200,
body=V3_VERSION_ENTRY)
versions = discover.available_versions(V3_URL)
for v in versions:
self.assertEqual(v['id'], 'v3.0')
self.assertEqual(v['status'], 'stable')
self.assertIn('media-types', v)
self.assertIn('links', v)
def test_available_keystone_data(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
versions = discover.available_versions(BASE_URL)
self.assertEqual(2, len(versions))
for v in versions:
self.assertIn(v['id'], ('v2.0', 'v3.0'))
self.assertEqual(v['updated'], UPDATED)
self.assertEqual(v['status'], 'stable')
if v['id'] == 'v3.0':
self.assertEqual(v['media-types'], V3_MEDIA_TYPES)
def test_available_cinder_data(self):
body = jsonutils.dumps(CINDER_EXAMPLES)
httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body)
versions = discover.available_versions(BASE_URL)
self.assertEqual(2, len(versions))
for v in versions:
self.assertEqual(v['status'], 'CURRENT')
if v['id'] == 'v1.0':
self.assertEqual(v['updated'], '2012-01-04T11:33:21Z')
elif v['id'] == 'v2.0':
self.assertEqual(v['updated'], '2012-11-21T11:33:21Z')
else:
self.fail("Invalid version found")
def test_available_glance_data(self):
body = jsonutils.dumps(GLANCE_EXAMPLES)
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
versions = discover.available_versions(BASE_URL)
self.assertEqual(5, len(versions))
for v in versions:
if v['id'] in ('v2.2', 'v1.1'):
self.assertEqual(v['status'], 'CURRENT')
elif v['id'] in ('v2.1', 'v2.0', 'v1.0'):
self.assertEqual(v['status'], 'SUPPORTED')
else:
self.fail("Invalid version found")
@httpretty.activate
class ClientDiscoveryTests(utils.TestCase):
def assertCreatesV3(self, **kwargs):
httpretty.register_uri(httpretty.POST, "%s/auth/tokens" % V3_URL,
body=V3_AUTH_RESPONSE, X_Subject_Token=V3_TOKEN)
kwargs.setdefault('username', 'foo')
kwargs.setdefault('password', 'bar')
keystone = client.Client(**kwargs)
self.assertIsInstance(keystone, v3_client.Client)
return keystone
def assertCreatesV2(self, **kwargs):
httpretty.register_uri(httpretty.POST, "%s/tokens" % V2_URL,
body=V2_AUTH_RESPONSE)
kwargs.setdefault('username', 'foo')
kwargs.setdefault('password', 'bar')
keystone = client.Client(**kwargs)
self.assertIsInstance(keystone, v2_client.Client)
return keystone
def assertVersionNotAvailable(self, **kwargs):
kwargs.setdefault('username', 'foo')
kwargs.setdefault('password', 'bar')
self.assertRaises(exceptions.VersionNotAvailable,
client.Client, **kwargs)
def assertDiscoveryFailure(self, **kwargs):
kwargs.setdefault('username', 'foo')
kwargs.setdefault('password', 'bar')
self.assertRaises(exceptions.DiscoveryFailure,
client.Client, **kwargs)
def test_discover_v3(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
self.assertCreatesV3(auth_url=BASE_URL)
def test_discover_v2(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V2_VERSION_LIST)
httpretty.register_uri(httpretty.POST, "%s/tokens" % V2_URL,
body=V2_AUTH_RESPONSE)
self.assertCreatesV2(auth_url=BASE_URL)
def test_discover_endpoint_v2(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V2_VERSION_LIST)
self.assertCreatesV2(endpoint=BASE_URL, token='fake-token')
def test_discover_endpoint_v3(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
self.assertCreatesV3(endpoint=BASE_URL, token='fake-token')
def test_discover_invalid_major_version(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
self.assertVersionNotAvailable(auth_url=BASE_URL, version=5)
def test_discover_200_response_fails(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body='ok')
self.assertDiscoveryFailure(auth_url=BASE_URL)
def test_discover_minor_greater_than_available_fails(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
self.assertVersionNotAvailable(endpoint=BASE_URL, version=3.4)
def test_discover_individual_version_v2(self):
httpretty.register_uri(httpretty.GET, V2_URL, status=200,
body=V2_VERSION_ENTRY)
self.assertCreatesV2(auth_url=V2_URL)
def test_discover_individual_version_v3(self):
httpretty.register_uri(httpretty.GET, V3_URL, status=200,
body=V3_VERSION_ENTRY)
self.assertCreatesV3(auth_url=V3_URL)
def test_discover_individual_endpoint_v2(self):
httpretty.register_uri(httpretty.GET, V2_URL, status=200,
body=V2_VERSION_ENTRY)
self.assertCreatesV2(endpoint=V2_URL, token='fake-token')
def test_discover_individual_endpoint_v3(self):
httpretty.register_uri(httpretty.GET, V3_URL, status=200,
body=V3_VERSION_ENTRY)
self.assertCreatesV3(endpoint=V3_URL, token='fake-token')
def test_discover_fail_to_create_bad_individual_version(self):
httpretty.register_uri(httpretty.GET, V2_URL, status=200,
body=V2_VERSION_ENTRY)
httpretty.register_uri(httpretty.GET, V3_URL, status=200,
body=V3_VERSION_ENTRY)
self.assertVersionNotAvailable(auth_url=V2_URL, version=3)
self.assertVersionNotAvailable(auth_url=V3_URL, version=2)
def test_discover_unstable_versions(self):
v3_unstable_version = V3_VERSION.copy()
v3_unstable_version['status'] = 'beta'
version_list = _create_version_list([v3_unstable_version, V2_VERSION])
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=version_list)
self.assertCreatesV2(auth_url=BASE_URL)
self.assertVersionNotAvailable(auth_url=BASE_URL, version=3)
self.assertCreatesV3(auth_url=BASE_URL, unstable=True)
def test_discover_forwards_original_ip(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
ip = '192.168.1.1'
self.assertCreatesV3(auth_url=BASE_URL, original_ip=ip)
self.assertThat(httpretty.last_request().headers['forwarded'],
matchers.Contains(ip))
def test_discover_bad_args(self):
self.assertRaises(exceptions.DiscoveryFailure,
client.Client)
def test_discover_bad_response(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=jsonutils.dumps({'FOO': 'BAR'}))
self.assertDiscoveryFailure(auth_url=BASE_URL)
def test_discovery_ignore_invalid(self):
resp = [{'id': 'v3.0',
'links': [1, 2, 3, 4], # invalid links
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED}]
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=_create_version_list(resp))
self.assertDiscoveryFailure(auth_url=BASE_URL)
def test_ignore_entry_without_links(self):
v3 = V3_VERSION.copy()
v3['links'] = []
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=_create_version_list([v3, V2_VERSION]))
self.assertCreatesV2(auth_url=BASE_URL)
def test_ignore_entry_without_status(self):
v3 = V3_VERSION.copy()
del v3['status']
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=_create_version_list([v3, V2_VERSION]))
self.assertCreatesV2(auth_url=BASE_URL)
def test_greater_version_than_required(self):
resp = [{'id': 'v3.6',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED}]
httpretty.register_uri(httpretty.GET, BASE_URL, status=200,
body=_create_version_list(resp))
self.assertCreatesV3(auth_url=BASE_URL, version=(3, 4))
def test_lesser_version_than_required(self):
resp = [{'id': 'v3.4',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED}]
httpretty.register_uri(httpretty.GET, BASE_URL, status=200,
body=_create_version_list(resp))
self.assertVersionNotAvailable(auth_url=BASE_URL, version=(3, 6))
def test_bad_response(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body="Ugly Duckling")
self.assertDiscoveryFailure(auth_url=BASE_URL)
def test_pass_client_arguments(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V2_VERSION_LIST)
kwargs = {'original_ip': '100', 'use_keyring': False,
'stale_duration': 15}
cl = self.assertCreatesV2(auth_url=BASE_URL, **kwargs)
self.assertEqual(cl.original_ip, '100')
self.assertEqual(cl.stale_duration, 15)
self.assertFalse(cl.use_keyring)
def test_overriding_stored_kwargs(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
httpretty.register_uri(httpretty.POST, "%s/auth/tokens" % V3_URL,
body=V3_AUTH_RESPONSE, X_Subject_Token=V3_TOKEN)
disc = discover.Discover(auth_url=BASE_URL, debug=False,
username='foo')
client = disc.create_client(debug=True, password='bar')
self.assertIsInstance(client, v3_client.Client)
self.assertTrue(client.debug_log)
self.assertFalse(disc._client_kwargs['debug'])
self.assertEqual(client.username, 'foo')
self.assertEqual(client.password, 'bar')
def test_available_versions(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_ENTRY)
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.available_versions()
self.assertEqual(1, len(versions))
self.assertEqual(V3_VERSION, versions[0])
def test_unknown_client_version(self):
V4_VERSION = {'id': 'v4.0',
'links': [{'href': 'http://url', 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED}
body = _create_version_list([V4_VERSION, V3_VERSION, V2_VERSION])
httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body)
disc = discover.Discover(auth_url=BASE_URL)
self.assertRaises(exceptions.DiscoveryFailure,
disc.create_client, version=4)
@httpretty.activate
class DiscoverQueryTests(utils.TestCase):
def test_available_keystone_data(self):
httpretty.register_uri(httpretty.GET, BASE_URL, status=300,
body=V3_VERSION_LIST)
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.version_data()
self.assertEqual((2, 0), versions[0]['version'])
self.assertEqual('stable', versions[0]['raw_status'])
self.assertEqual(V2_URL, versions[0]['url'])
self.assertEqual((3, 0), versions[1]['version'])
self.assertEqual('stable', versions[1]['raw_status'])
self.assertEqual(V3_URL, versions[1]['url'])
version = disc.data_for('v3.0')
self.assertEqual((3, 0), version['version'])
self.assertEqual('stable', version['raw_status'])
self.assertEqual(V3_URL, version['url'])
version = disc.data_for(2)
self.assertEqual((2, 0), version['version'])
self.assertEqual('stable', version['raw_status'])
self.assertEqual(V2_URL, version['url'])
self.assertIsNone(disc.url_for('v4'))
self.assertEqual(V3_URL, disc.url_for('v3'))
self.assertEqual(V2_URL, disc.url_for('v2'))
def test_available_cinder_data(self):
body = jsonutils.dumps(CINDER_EXAMPLES)
httpretty.register_uri(httpretty.GET, BASE_URL, status=300, body=body)
v1_url = "%sv1/" % BASE_URL
v2_url = "%sv2/" % BASE_URL
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.version_data()
self.assertEqual((1, 0), versions[0]['version'])
self.assertEqual('CURRENT', versions[0]['raw_status'])
self.assertEqual(v1_url, versions[0]['url'])
self.assertEqual((2, 0), versions[1]['version'])
self.assertEqual('CURRENT', versions[1]['raw_status'])
self.assertEqual(v2_url, versions[1]['url'])
version = disc.data_for('v2.0')
self.assertEqual((2, 0), version['version'])
self.assertEqual('CURRENT', version['raw_status'])
self.assertEqual(v2_url, version['url'])
version = disc.data_for(1)
self.assertEqual((1, 0), version['version'])
self.assertEqual('CURRENT', version['raw_status'])
self.assertEqual(v1_url, version['url'])
self.assertIsNone(disc.url_for('v3'))
self.assertEqual(v2_url, disc.url_for('v2'))
self.assertEqual(v1_url, disc.url_for('v1'))
def test_available_glance_data(self):
body = jsonutils.dumps(GLANCE_EXAMPLES)
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
v1_url = "%sv1/" % BASE_URL
v2_url = "%sv2/" % BASE_URL
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.version_data()
self.assertEqual((1, 0), versions[0]['version'])
self.assertEqual('SUPPORTED', versions[0]['raw_status'])
self.assertEqual(v1_url, versions[0]['url'])
self.assertEqual((1, 1), versions[1]['version'])
self.assertEqual('CURRENT', versions[1]['raw_status'])
self.assertEqual(v1_url, versions[1]['url'])
self.assertEqual((2, 0), versions[2]['version'])
self.assertEqual('SUPPORTED', versions[2]['raw_status'])
self.assertEqual(v2_url, versions[2]['url'])
self.assertEqual((2, 1), versions[3]['version'])
self.assertEqual('SUPPORTED', versions[3]['raw_status'])
self.assertEqual(v2_url, versions[3]['url'])
self.assertEqual((2, 2), versions[4]['version'])
self.assertEqual('CURRENT', versions[4]['raw_status'])
self.assertEqual(v2_url, versions[4]['url'])
for ver in (2, 2.1, 2.2):
version = disc.data_for(ver)
self.assertEqual((2, 2), version['version'])
self.assertEqual('CURRENT', version['raw_status'])
self.assertEqual(v2_url, version['url'])
self.assertEqual(v2_url, disc.url_for(ver))
for ver in (1, 1.1):
version = disc.data_for(ver)
self.assertEqual((1, 1), version['version'])
self.assertEqual('CURRENT', version['raw_status'])
self.assertEqual(v1_url, version['url'])
self.assertEqual(v1_url, disc.url_for(ver))
self.assertIsNone(disc.url_for('v3'))
self.assertIsNone(disc.url_for('v2.3'))
def test_allow_deprecated(self):
status = 'deprecated'
version_list = [{'id': 'v3.0',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': status,
'updated': UPDATED}]
body = jsonutils.dumps({'versions': version_list})
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
disc = discover.Discover(auth_url=BASE_URL)
# deprecated is allowed by default
versions = disc.version_data(allow_deprecated=False)
self.assertEqual(0, len(versions))
versions = disc.version_data(allow_deprecated=True)
self.assertEqual(1, len(versions))
self.assertEqual(status, versions[0]['raw_status'])
self.assertEqual(V3_URL, versions[0]['url'])
self.assertEqual((3, 0), versions[0]['version'])
def test_allow_experimental(self):
status = 'experimental'
version_list = [{'id': 'v3.0',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': status,
'updated': UPDATED}]
body = jsonutils.dumps({'versions': version_list})
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.version_data()
self.assertEqual(0, len(versions))
versions = disc.version_data(allow_experimental=True)
self.assertEqual(1, len(versions))
self.assertEqual(status, versions[0]['raw_status'])
self.assertEqual(V3_URL, versions[0]['url'])
self.assertEqual((3, 0), versions[0]['version'])
def test_allow_unknown(self):
status = 'abcdef'
version_list = [{'id': 'v3.0',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': status,
'updated': UPDATED}]
body = jsonutils.dumps({'versions': version_list})
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
disc = discover.Discover(auth_url=BASE_URL)
versions = disc.version_data()
self.assertEqual(0, len(versions))
versions = disc.version_data(allow_unknown=True)
self.assertEqual(1, len(versions))
self.assertEqual(status, versions[0]['raw_status'])
self.assertEqual(V3_URL, versions[0]['url'])
self.assertEqual((3, 0), versions[0]['version'])
def test_ignoring_invalid_lnks(self):
version_list = [{'id': 'v3.0',
'links': [{'href': V3_URL, 'rel': 'self'}],
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED},
{'id': 'v3.1',
'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED},
{'media-types': V3_MEDIA_TYPES,
'status': 'stable',
'updated': UPDATED,
'links': [{'href': V3_URL, 'rel': 'self'}],
}]
body = jsonutils.dumps({'versions': version_list})
httpretty.register_uri(httpretty.GET, BASE_URL, status=200, body=body)
disc = discover.Discover(auth_url=BASE_URL)
# raw_version_data will return all choices, even invalid ones
versions = disc.raw_version_data()
self.assertEqual(3, len(versions))
# only the version with both id and links will be actually returned
versions = disc.version_data()
self.assertEqual(1, len(versions))
class DiscoverUtils(utils.TestCase):
def test_version_number(self):
def assertVersion(inp, out):
self.assertEqual(out, _discover.normalize_version_number(inp))
def versionRaises(inp):
self.assertRaises(TypeError,
_discover.normalize_version_number,
inp)
assertVersion('v1.2', (1, 2))
assertVersion('v11', (11, 0))
assertVersion('1.2', (1, 2))
assertVersion('1.5.1', (1, 5, 1))
assertVersion('1', (1, 0))
assertVersion(1, (1, 0))
assertVersion(5.2, (5, 2))
assertVersion((6, 1), (6, 1))
assertVersion([1, 4], (1, 4))
versionRaises('hello')
versionRaises('1.a')
versionRaises('vacuum')

View File

@@ -1,252 +0,0 @@
# Copyright 2012 OpenStack Foundation
#
# 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.
from __future__ import unicode_literals
import testtools
from keystoneclient.contrib.ec2 import utils
class Ec2SignerTest(testtools.TestCase):
def setUp(self):
super(Ec2SignerTest, self).setUp()
self.access = '966afbde20b84200ae4e62e09acf46b2'
self.secret = '89cdf9e94e2643cab35b8b8ac5a51f83'
self.signer = utils.Ec2Signer(self.secret)
def test_v4_creds_header(self):
auth_str = 'AWS4-HMAC-SHA256 blah'
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {},
'headers': {'Authorization': auth_str}}
self.assertTrue(self.signer._v4_creds(credentials))
def test_v4_creds_param(self):
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'X-Amz-Algorithm': 'AWS4-HMAC-SHA256'},
'headers': {}}
self.assertTrue(self.signer._v4_creds(credentials))
def test_v4_creds_false(self):
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'SignatureVersion': '0',
'AWSAccessKeyId': self.access,
'Timestamp': '2012-11-27T11:47:02Z',
'Action': 'Foo'}}
self.assertFalse(self.signer._v4_creds(credentials))
def test_generate_0(self):
"""Test generate function for v0 signature."""
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'SignatureVersion': '0',
'AWSAccessKeyId': self.access,
'Timestamp': '2012-11-27T11:47:02Z',
'Action': 'Foo'}}
signature = self.signer.generate(credentials)
expected = 'SmXQEZAUdQw5glv5mX8mmixBtas='
self.assertEqual(signature, expected)
def test_generate_1(self):
"""Test generate function for v1 signature."""
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'SignatureVersion': '1',
'AWSAccessKeyId': self.access}}
signature = self.signer.generate(credentials)
expected = 'VRnoQH/EhVTTLhwRLfuL7jmFW9c='
self.assertEqual(signature, expected)
def test_generate_v2_SHA256(self):
"""Test generate function for v2 signature, SHA256."""
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'SignatureVersion': '2',
'AWSAccessKeyId': self.access}}
signature = self.signer.generate(credentials)
expected = 'odsGmT811GffUO0Eu13Pq+xTzKNIjJ6NhgZU74tYX/w='
self.assertEqual(signature, expected)
def test_generate_v2_SHA1(self):
"""Test generate function for v2 signature, SHA1."""
credentials = {'host': '127.0.0.1',
'verb': 'GET',
'path': '/v1/',
'params': {'SignatureVersion': '2',
'AWSAccessKeyId': self.access}}
self.signer.hmac_256 = None
signature = self.signer.generate(credentials)
expected = 'ZqCxMI4ZtTXWI175743mJ0hy/Gc='
self.assertEqual(signature, expected)
def test_generate_v4(self):
"""Test v4 generator with data from AWS docs example.
see:
http://docs.aws.amazon.com/general/latest/gr/
sigv4-create-canonical-request.html
and
http://docs.aws.amazon.com/general/latest/gr/
sigv4-signed-request-examples.html
"""
# Create a new signer object with the AWS example key
secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
signer = utils.Ec2Signer(secret)
body_hash = ('b6359072c78d70ebee1e81adcbab4f0'
'1bf2c23245fa365ef83fe8f1f955085e2')
auth_str = ('AWS4-HMAC-SHA256 '
'Credential=AKIAIOSFODNN7EXAMPLE/20110909/'
'us-east-1/iam/aws4_request,'
'SignedHeaders=content-type;host;x-amz-date,')
headers = {'Content-type':
'application/x-www-form-urlencoded; charset=utf-8',
'X-Amz-Date': '20110909T233600Z',
'Host': 'iam.amazonaws.com',
'Authorization': auth_str}
# Note the example in the AWS docs is inconsistent, previous
# examples specify no query string, but the final POST example
# does, apparently incorrectly since an empty parameter list
# aligns all steps and the final signature with the examples
params = {}
credentials = {'host': 'iam.amazonaws.com',
'verb': 'POST',
'path': '/',
'params': params,
'headers': headers,
'body_hash': body_hash}
signature = signer.generate(credentials)
expected = ('ced6826de92d2bdeed8f846f0bf508e8'
'559e98e4b0199114b84c54174deb456c')
self.assertEqual(signature, expected)
def test_generate_v4_port(self):
"""Test v4 generator with host:port format."""
# Create a new signer object with the AWS example key
secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
signer = utils.Ec2Signer(secret)
body_hash = ('b6359072c78d70ebee1e81adcbab4f0'
'1bf2c23245fa365ef83fe8f1f955085e2')
auth_str = ('AWS4-HMAC-SHA256 '
'Credential=AKIAIOSFODNN7EXAMPLE/20110909/'
'us-east-1/iam/aws4_request,'
'SignedHeaders=content-type;host;x-amz-date,')
headers = {'Content-type':
'application/x-www-form-urlencoded; charset=utf-8',
'X-Amz-Date': '20110909T233600Z',
'Host': 'foo:8000',
'Authorization': auth_str}
# Note the example in the AWS docs is inconsistent, previous
# examples specify no query string, but the final POST example
# does, apparently incorrectly since an empty parameter list
# aligns all steps and the final signature with the examples
params = {}
credentials = {'host': 'foo:8000',
'verb': 'POST',
'path': '/',
'params': params,
'headers': headers,
'body_hash': body_hash}
signature = signer.generate(credentials)
expected = ('26dd92ea79aaa49f533d13b1055acdc'
'd7d7321460d64621f96cc79c4f4d4ab2b')
self.assertEqual(signature, expected)
def test_generate_v4_port_strip(self):
"""Test v4 generator with host:port format, but for an old
(<2.9.3) version of boto, where the port should be stripped
to match boto behavior.
"""
# Create a new signer object with the AWS example key
secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
signer = utils.Ec2Signer(secret)
body_hash = ('b6359072c78d70ebee1e81adcbab4f0'
'1bf2c23245fa365ef83fe8f1f955085e2')
auth_str = ('AWS4-HMAC-SHA256 '
'Credential=AKIAIOSFODNN7EXAMPLE/20110909/'
'us-east-1/iam/aws4_request,'
'SignedHeaders=content-type;host;x-amz-date,')
headers = {'Content-type':
'application/x-www-form-urlencoded; charset=utf-8',
'X-Amz-Date': '20110909T233600Z',
'Host': 'foo:8000',
'Authorization': auth_str,
'User-Agent': 'Boto/2.9.2 (linux2)'}
# Note the example in the AWS docs is inconsistent, previous
# examples specify no query string, but the final POST example
# does, apparently incorrectly since an empty parameter list
# aligns all steps and the final signature with the examples
params = {}
credentials = {'host': 'foo:8000',
'verb': 'POST',
'path': '/',
'params': params,
'headers': headers,
'body_hash': body_hash}
signature = signer.generate(credentials)
expected = ('9a4b2276a5039ada3b90f72ea8ec1745'
'14b92b909fb106b22ad910c5d75a54f4')
self.assertEqual(expected, signature)
def test_generate_v4_port_nostrip(self):
"""Test v4 generator with host:port format, but for an new
(>=2.9.3) version of boto, where the port should not be stripped.
"""
# Create a new signer object with the AWS example key
secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
signer = utils.Ec2Signer(secret)
body_hash = ('b6359072c78d70ebee1e81adcbab4f0'
'1bf2c23245fa365ef83fe8f1f955085e2')
auth_str = ('AWS4-HMAC-SHA256 '
'Credential=AKIAIOSFODNN7EXAMPLE/20110909/'
'us-east-1/iam/aws4_request,'
'SignedHeaders=content-type;host;x-amz-date,')
headers = {'Content-type':
'application/x-www-form-urlencoded; charset=utf-8',
'X-Amz-Date': '20110909T233600Z',
'Host': 'foo:8000',
'Authorization': auth_str,
'User-Agent': 'Boto/2.9.3 (linux2)'}
# Note the example in the AWS docs is inconsistent, previous
# examples specify no query string, but the final POST example
# does, apparently incorrectly since an empty parameter list
# aligns all steps and the final signature with the examples
params = {}
credentials = {'host': 'foo:8000',
'verb': 'POST',
'path': '/',
'params': params,
'headers': headers,
'body_hash': body_hash}
signature = signer.generate(credentials)
expected = ('26dd92ea79aaa49f533d13b1055acdc'
'd7d7321460d64621f96cc79c4f4d4ab2b')
self.assertEqual(expected, signature)

View File

@@ -1,216 +0,0 @@
# Copyright 2013 OpenStack Foundation
#
# 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 logging
import httpretty
import six
from testtools import matchers
from keystoneclient import exceptions
from keystoneclient import httpclient
from keystoneclient import session
from keystoneclient.tests import utils
RESPONSE_BODY = '{"hi": "there"}'
def get_client():
cl = httpclient.HTTPClient(username="username", password="password",
tenant_id="tenant", auth_url="auth_test")
return cl
def get_authed_client():
cl = get_client()
cl.management_url = "http://127.0.0.1:5000"
cl.auth_token = "token"
return cl
class FakeLog(object):
def __init__(self):
self.warn_log = str()
self.debug_log = str()
def warn(self, msg=None, *args, **kwargs):
self.warn_log = "%s\n%s" % (self.warn_log, (msg % args))
def debug(self, msg=None, *args, **kwargs):
self.debug_log = "%s\n%s" % (self.debug_log, (msg % args))
class ClientTest(utils.TestCase):
TEST_URL = 'http://127.0.0.1:5000/hi'
def test_unauthorized_client_requests(self):
cl = get_client()
self.assertRaises(exceptions.AuthorizationFailure, cl.get, '/hi')
self.assertRaises(exceptions.AuthorizationFailure, cl.post, '/hi')
self.assertRaises(exceptions.AuthorizationFailure, cl.put, '/hi')
self.assertRaises(exceptions.AuthorizationFailure, cl.delete, '/hi')
@httpretty.activate
def test_get(self):
cl = get_authed_client()
self.stub_url(httpretty.GET, body=RESPONSE_BODY)
resp, body = cl.get("/hi")
self.assertEqual(httpretty.last_request().method, 'GET')
self.assertEqual(httpretty.last_request().path, '/hi')
self.assertRequestHeaderEqual('X-Auth-Token', 'token')
self.assertRequestHeaderEqual('User-Agent', httpclient.USER_AGENT)
# Automatic JSON parsing
self.assertEqual(body, {"hi": "there"})
@httpretty.activate
def test_get_error_with_plaintext_resp(self):
cl = get_authed_client()
self.stub_url(httpretty.GET, status=400,
body='Some evil plaintext string')
self.assertRaises(exceptions.BadRequest, cl.get, '/hi')
@httpretty.activate
def test_get_error_with_json_resp(self):
cl = get_authed_client()
err_response = {
"error": {
"code": 400,
"title": "Error title",
"message": "Error message string"
}
}
self.stub_url(httpretty.GET, status=400, json=err_response)
exc_raised = False
try:
cl.get('/hi')
except exceptions.BadRequest as exc:
exc_raised = True
self.assertEqual(exc.message, "Error message string")
self.assertTrue(exc_raised, 'Exception not raised.')
@httpretty.activate
def test_post(self):
cl = get_authed_client()
self.stub_url(httpretty.POST)
cl.post("/hi", body=[1, 2, 3])
self.assertEqual(httpretty.last_request().method, 'POST')
self.assertEqual(httpretty.last_request().body, b'[1, 2, 3]')
self.assertRequestHeaderEqual('X-Auth-Token', 'token')
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('User-Agent', httpclient.USER_AGENT)
@httpretty.activate
def test_forwarded_for(self):
ORIGINAL_IP = "10.100.100.1"
cl = httpclient.HTTPClient(username="username", password="password",
tenant_id="tenant", auth_url="auth_test",
original_ip=ORIGINAL_IP)
self.stub_url(httpretty.GET)
cl.request(self.TEST_URL, 'GET')
forwarded = "for=%s;by=%s" % (ORIGINAL_IP, httpclient.USER_AGENT)
self.assertRequestHeaderEqual('Forwarded', forwarded)
def test_client_deprecated(self):
# Can resolve symbols from the keystoneclient.client module.
# keystoneclient.client was deprecated and renamed to
# keystoneclient.httpclient. This tests that keystoneclient.client
# can still be used.
from keystoneclient import client
# These statements will raise an AttributeError if the symbol isn't
# defined in the module.
client.HTTPClient
class BasicRequestTests(utils.TestCase):
url = 'http://keystone.test.com/'
def setUp(self):
super(BasicRequestTests, self).setUp()
self.logger_message = six.moves.cStringIO()
handler = logging.StreamHandler(self.logger_message)
handler.setLevel(logging.DEBUG)
self.logger = logging.getLogger(session.__name__)
level = self.logger.getEffectiveLevel()
self.logger.setLevel(logging.DEBUG)
self.logger.addHandler(handler)
self.addCleanup(self.logger.removeHandler, handler)
self.addCleanup(self.logger.setLevel, level)
def request(self, method='GET', response='Test Response', status=200,
url=None, **kwargs):
if not url:
url = self.url
httpretty.register_uri(method, url, body=response, status=status)
return httpclient.request(url, method, **kwargs)
@httpretty.activate
def test_basic_params(self):
method = 'GET'
response = 'Test Response'
status = 200
self.request(method=method, status=status, response=response)
self.assertEqual(httpretty.last_request().method, method)
logger_message = self.logger_message.getvalue()
self.assertThat(logger_message, matchers.Contains('curl'))
self.assertThat(logger_message, matchers.Contains('-X %s' %
method))
self.assertThat(logger_message, matchers.Contains(self.url))
self.assertThat(logger_message, matchers.Contains(str(status)))
self.assertThat(logger_message, matchers.Contains(response))
@httpretty.activate
def test_headers(self):
headers = {'key': 'val', 'test': 'other'}
self.request(headers=headers)
for k, v in six.iteritems(headers):
self.assertRequestHeaderEqual(k, v)
for header in six.iteritems(headers):
self.assertThat(self.logger_message.getvalue(),
matchers.Contains('-H "%s: %s"' % header))
@httpretty.activate
def test_body(self):
data = "BODY DATA"
self.request(response=data)
logger_message = self.logger_message.getvalue()
self.assertThat(logger_message, matchers.Contains('BODY:'))
self.assertThat(logger_message, matchers.Contains(data))

View File

@@ -1,107 +0,0 @@
# 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 mock
import requests
from keystoneclient import httpclient
from keystoneclient.tests import utils
FAKE_RESPONSE = utils.TestResponse({
"status_code": 200,
"text": '{"hi": "there"}',
})
REQUEST_URL = 'https://127.0.0.1:5000/hi'
RESPONSE_BODY = '{"hi": "there"}'
def get_client():
cl = httpclient.HTTPClient(username="username", password="password",
tenant_id="tenant", auth_url="auth_test",
cacert="ca.pem", key="key.pem", cert="cert.pem")
return cl
def get_authed_client():
cl = get_client()
cl.management_url = "https://127.0.0.1:5000"
cl.auth_token = "token"
return cl
class ClientTest(utils.TestCase):
def setUp(self):
super(ClientTest, self).setUp()
self.request_patcher = mock.patch.object(requests, 'request',
self.mox.CreateMockAnything())
self.request_patcher.start()
self.addCleanup(self.request_patcher.stop)
@mock.patch.object(requests, 'request')
def test_get(self, MOCK_REQUEST):
MOCK_REQUEST.return_value = FAKE_RESPONSE
cl = get_authed_client()
resp, body = cl.get("/hi")
# this may become too tightly couple later
mock_args, mock_kwargs = MOCK_REQUEST.call_args
self.assertEqual(mock_args[0], 'GET')
self.assertEqual(mock_args[1], REQUEST_URL)
self.assertEqual(mock_kwargs['headers']['X-Auth-Token'], 'token')
self.assertEqual(mock_kwargs['cert'], ('cert.pem', 'key.pem'))
self.assertEqual(mock_kwargs['verify'], 'ca.pem')
# Automatic JSON parsing
self.assertEqual(body, {"hi": "there"})
@mock.patch.object(requests, 'request')
def test_post(self, MOCK_REQUEST):
MOCK_REQUEST.return_value = FAKE_RESPONSE
cl = get_authed_client()
cl.post("/hi", body=[1, 2, 3])
# this may become too tightly couple later
mock_args, mock_kwargs = MOCK_REQUEST.call_args
self.assertEqual(mock_args[0], 'POST')
self.assertEqual(mock_args[1], REQUEST_URL)
self.assertEqual(mock_kwargs['data'], '[1, 2, 3]')
self.assertEqual(mock_kwargs['headers']['X-Auth-Token'], 'token')
self.assertEqual(mock_kwargs['cert'], ('cert.pem', 'key.pem'))
self.assertEqual(mock_kwargs['verify'], 'ca.pem')
@mock.patch.object(requests, 'request')
def test_post_auth(self, MOCK_REQUEST):
MOCK_REQUEST.return_value = FAKE_RESPONSE
cl = httpclient.HTTPClient(
username="username", password="password", tenant_id="tenant",
auth_url="auth_test", cacert="ca.pem", key="key.pem",
cert="cert.pem")
cl.management_url = "https://127.0.0.1:5000"
cl.auth_token = "token"
cl.post("/hi", body=[1, 2, 3])
# this may become too tightly couple later
mock_args, mock_kwargs = MOCK_REQUEST.call_args
self.assertEqual(mock_args[0], 'POST')
self.assertEqual(mock_args[1], REQUEST_URL)
self.assertEqual(mock_kwargs['data'], '[1, 2, 3]')
self.assertEqual(mock_kwargs['headers']['X-Auth-Token'], 'token')
self.assertEqual(mock_kwargs['cert'], ('cert.pem', 'key.pem'))
self.assertEqual(mock_kwargs['verify'], 'ca.pem')

View File

@@ -1,187 +0,0 @@
# 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 datetime
import mock
from keystoneclient import access
from keystoneclient import httpclient
from keystoneclient.openstack.common import timeutils
from keystoneclient.tests import utils
from keystoneclient.tests.v2_0 import client_fixtures
try:
import keyring # noqa
import pickle # noqa
except ImportError:
keyring = None
PROJECT_SCOPED_TOKEN = client_fixtures.project_scoped_token()
# These mirror values from PROJECT_SCOPED_TOKEN
USERNAME = 'exampleuser'
AUTH_URL = 'http://public.com:5000/v2.0'
TOKEN = '04c7d5ffaeef485f9dc69c06db285bdb'
PASSWORD = 'password'
TENANT = 'tenant'
TENANT_ID = 'tenant_id'
class KeyringTest(utils.TestCase):
def setUp(self):
if keyring is None:
self.skipTest(
'optional package keyring or pickle is not installed')
class MemoryKeyring(keyring.backend.KeyringBackend):
"""A Simple testing keyring.
This class supports stubbing an initial password to be returned by
setting password, and allows easy password and key retrieval. Also
records if a password was retrieved.
"""
def __init__(self):
self.key = None
self.password = None
self.fetched = False
self.get_password_called = False
self.set_password_called = False
def supported(self):
return 1
def get_password(self, service, username):
self.get_password_called = True
key = username + '@' + service
# make sure we don't get passwords crossed if one is enforced.
if self.key and self.key != key:
return None
if self.password:
self.fetched = True
return self.password
def set_password(self, service, username, password):
self.set_password_called = True
self.key = username + '@' + service
self.password = password
super(KeyringTest, self).setUp()
self.memory_keyring = MemoryKeyring()
keyring.set_keyring(self.memory_keyring)
def test_no_keyring_key(self):
"""Ensure that if we don't have use_keyring set in the client that
the keyring is never accessed.
"""
cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
tenant_id=TENANT_ID, auth_url=AUTH_URL)
# stub and check that a new token is received
with mock.patch.object(cl, 'get_raw_token_from_identity_service') \
as meth:
meth.return_value = (True, PROJECT_SCOPED_TOKEN)
self.assertTrue(cl.authenticate())
self.assertEqual(1, meth.call_count)
# make sure that we never touched the keyring
self.assertFalse(self.memory_keyring.get_password_called)
self.assertFalse(self.memory_keyring.set_password_called)
def test_build_keyring_key(self):
cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
tenant_id=TENANT_ID, auth_url=AUTH_URL)
keyring_key = cl._build_keyring_key(auth_url=AUTH_URL,
username=USERNAME,
tenant_name=TENANT,
tenant_id=TENANT_ID,
token=TOKEN)
self.assertEqual(keyring_key,
'%s/%s/%s/%s/%s' %
(AUTH_URL, TENANT_ID, TENANT, TOKEN, USERNAME))
def test_set_and_get_keyring_expired(self):
cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
tenant_id=TENANT_ID, auth_url=AUTH_URL,
use_keyring=True)
# set an expired token into the keyring
auth_ref = access.AccessInfo.factory(body=PROJECT_SCOPED_TOKEN)
expired = timeutils.utcnow() - datetime.timedelta(minutes=30)
auth_ref['token']['expires'] = timeutils.isotime(expired)
self.memory_keyring.password = pickle.dumps(auth_ref)
# stub and check that a new token is received, so not using expired
with mock.patch.object(cl, 'get_raw_token_from_identity_service') \
as meth:
meth.return_value = (True, PROJECT_SCOPED_TOKEN)
self.assertTrue(cl.authenticate())
self.assertEqual(1, meth.call_count)
# check that a value was returned from the keyring
self.assertTrue(self.memory_keyring.fetched)
# check that the new token has been loaded into the keyring
new_auth_ref = pickle.loads(self.memory_keyring.password)
self.assertEqual(new_auth_ref['token']['expires'],
PROJECT_SCOPED_TOKEN['access']['token']['expires'])
def test_get_keyring(self):
cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
tenant_id=TENANT_ID, auth_url=AUTH_URL,
use_keyring=True)
# set an token into the keyring
auth_ref = access.AccessInfo.factory(body=PROJECT_SCOPED_TOKEN)
future = timeutils.utcnow() + datetime.timedelta(minutes=30)
auth_ref['token']['expires'] = timeutils.isotime(future)
self.memory_keyring.password = pickle.dumps(auth_ref)
# don't stub get_raw_token so will fail if authenticate happens
self.assertTrue(cl.authenticate())
self.assertTrue(self.memory_keyring.fetched)
def test_set_keyring(self):
cl = httpclient.HTTPClient(username=USERNAME, password=PASSWORD,
tenant_id=TENANT_ID, auth_url=AUTH_URL,
use_keyring=True)
# stub and check that a new token is received
with mock.patch.object(cl, 'get_raw_token_from_identity_service') \
as meth:
meth.return_value = (True, PROJECT_SCOPED_TOKEN)
self.assertTrue(cl.authenticate())
self.assertEqual(1, meth.call_count)
# we checked the keyring, but we didn't find anything
self.assertTrue(self.memory_keyring.get_password_called)
self.assertFalse(self.memory_keyring.fetched)
# check that the new token has been loaded into the keyring
self.assertTrue(self.memory_keyring.set_password_called)
new_auth_ref = pickle.loads(self.memory_keyring.password)
self.assertEqual(new_auth_ref.auth_token, TOKEN)
self.assertEqual(new_auth_ref['token'],
PROJECT_SCOPED_TOKEN['access']['token'])
self.assertEqual(new_auth_ref.username, USERNAME)

View File

@@ -1,508 +0,0 @@
# 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 httpretty
import mock
import requests
import six
from keystoneclient.auth import base
from keystoneclient import exceptions
from keystoneclient import session as client_session
from keystoneclient.tests import utils
class SessionTests(utils.TestCase):
TEST_URL = 'http://127.0.0.1:5000/'
@httpretty.activate
def test_get(self):
session = client_session.Session()
self.stub_url(httpretty.GET, body='response')
resp = session.get(self.TEST_URL)
self.assertEqual(httpretty.GET, httpretty.last_request().method)
self.assertEqual(resp.text, 'response')
self.assertTrue(resp.ok)
@httpretty.activate
def test_post(self):
session = client_session.Session()
self.stub_url(httpretty.POST, body='response')
resp = session.post(self.TEST_URL, json={'hello': 'world'})
self.assertEqual(httpretty.POST, httpretty.last_request().method)
self.assertEqual(resp.text, 'response')
self.assertTrue(resp.ok)
self.assertRequestBodyIs(json={'hello': 'world'})
@httpretty.activate
def test_head(self):
session = client_session.Session()
self.stub_url(httpretty.HEAD)
resp = session.head(self.TEST_URL)
self.assertEqual(httpretty.HEAD, httpretty.last_request().method)
self.assertTrue(resp.ok)
self.assertRequestBodyIs('')
@httpretty.activate
def test_put(self):
session = client_session.Session()
self.stub_url(httpretty.PUT, body='response')
resp = session.put(self.TEST_URL, json={'hello': 'world'})
self.assertEqual(httpretty.PUT, httpretty.last_request().method)
self.assertEqual(resp.text, 'response')
self.assertTrue(resp.ok)
self.assertRequestBodyIs(json={'hello': 'world'})
@httpretty.activate
def test_delete(self):
session = client_session.Session()
self.stub_url(httpretty.DELETE, body='response')
resp = session.delete(self.TEST_URL)
self.assertEqual(httpretty.DELETE, httpretty.last_request().method)
self.assertTrue(resp.ok)
self.assertEqual(resp.text, 'response')
@httpretty.activate
def test_patch(self):
session = client_session.Session()
self.stub_url(httpretty.PATCH, body='response')
resp = session.patch(self.TEST_URL, json={'hello': 'world'})
self.assertEqual(httpretty.PATCH, httpretty.last_request().method)
self.assertTrue(resp.ok)
self.assertEqual(resp.text, 'response')
self.assertRequestBodyIs(json={'hello': 'world'})
@httpretty.activate
def test_user_agent(self):
session = client_session.Session(user_agent='test-agent')
self.stub_url(httpretty.GET, body='response')
resp = session.get(self.TEST_URL)
self.assertTrue(resp.ok)
self.assertRequestHeaderEqual('User-Agent', 'test-agent')
resp = session.get(self.TEST_URL, headers={'User-Agent': 'new-agent'})
self.assertTrue(resp.ok)
self.assertRequestHeaderEqual('User-Agent', 'new-agent')
resp = session.get(self.TEST_URL, headers={'User-Agent': 'new-agent'},
user_agent='overrides-agent')
self.assertTrue(resp.ok)
self.assertRequestHeaderEqual('User-Agent', 'overrides-agent')
@httpretty.activate
def test_http_session_opts(self):
session = client_session.Session(cert='cert.pem', timeout=5,
verify='certs')
FAKE_RESP = utils.TestResponse({'status_code': 200, 'text': 'resp'})
RESP = mock.Mock(return_value=FAKE_RESP)
with mock.patch.object(session.session, 'request', RESP) as mocked:
session.post(self.TEST_URL, data='value')
mock_args, mock_kwargs = mocked.call_args
self.assertEqual(mock_args[0], 'POST')
self.assertEqual(mock_args[1], self.TEST_URL)
self.assertEqual(mock_kwargs['data'], 'value')
self.assertEqual(mock_kwargs['cert'], 'cert.pem')
self.assertEqual(mock_kwargs['verify'], 'certs')
self.assertEqual(mock_kwargs['timeout'], 5)
@httpretty.activate
def test_not_found(self):
session = client_session.Session()
self.stub_url(httpretty.GET, status=404)
self.assertRaises(exceptions.NotFound, session.get, self.TEST_URL)
@httpretty.activate
def test_server_error(self):
session = client_session.Session()
self.stub_url(httpretty.GET, status=500)
self.assertRaises(exceptions.InternalServerError,
session.get, self.TEST_URL)
@httpretty.activate
def test_session_debug_output(self):
session = client_session.Session(verify=False)
headers = {'HEADERA': 'HEADERVALB'}
body = 'BODYRESPONSE'
data = 'BODYDATA'
self.stub_url(httpretty.POST, body=body)
session.post(self.TEST_URL, headers=headers, data=data)
self.assertIn('curl', self.logger.output)
self.assertIn('POST', self.logger.output)
self.assertIn('--insecure', self.logger.output)
self.assertIn(body, self.logger.output)
self.assertIn("'%s'" % data, self.logger.output)
for k, v in six.iteritems(headers):
self.assertIn(k, self.logger.output)
self.assertIn(v, self.logger.output)
class RedirectTests(utils.TestCase):
REDIRECT_CHAIN = ['http://myhost:3445/',
'http://anotherhost:6555/',
'http://thirdhost/',
'http://finaldestination:55/']
DEFAULT_REDIRECT_BODY = 'Redirect'
DEFAULT_RESP_BODY = 'Found'
def setup_redirects(self, method=httpretty.GET, status=305,
redirect_kwargs={}, final_kwargs={}):
redirect_kwargs.setdefault('body', self.DEFAULT_REDIRECT_BODY)
for s, d in zip(self.REDIRECT_CHAIN, self.REDIRECT_CHAIN[1:]):
httpretty.register_uri(method, s, status=status, location=d,
**redirect_kwargs)
final_kwargs.setdefault('status', 200)
final_kwargs.setdefault('body', self.DEFAULT_RESP_BODY)
httpretty.register_uri(method, self.REDIRECT_CHAIN[-1], **final_kwargs)
def assertResponse(self, resp):
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.text, self.DEFAULT_RESP_BODY)
@httpretty.activate
def test_basic_get(self):
session = client_session.Session()
self.setup_redirects()
resp = session.get(self.REDIRECT_CHAIN[-2])
self.assertResponse(resp)
@httpretty.activate
def test_basic_post_keeps_correct_method(self):
session = client_session.Session()
self.setup_redirects(method=httpretty.POST, status=301)
resp = session.post(self.REDIRECT_CHAIN[-2])
self.assertResponse(resp)
@httpretty.activate
def test_redirect_forever(self):
session = client_session.Session(redirect=True)
self.setup_redirects()
resp = session.get(self.REDIRECT_CHAIN[0])
self.assertResponse(resp)
self.assertTrue(len(resp.history), len(self.REDIRECT_CHAIN))
@httpretty.activate
def test_no_redirect(self):
session = client_session.Session(redirect=False)
self.setup_redirects()
resp = session.get(self.REDIRECT_CHAIN[0])
self.assertEqual(resp.status_code, 305)
self.assertEqual(resp.url, self.REDIRECT_CHAIN[0])
@httpretty.activate
def test_redirect_limit(self):
self.setup_redirects()
for i in (1, 2):
session = client_session.Session(redirect=i)
resp = session.get(self.REDIRECT_CHAIN[0])
self.assertEqual(resp.status_code, 305)
self.assertEqual(resp.url, self.REDIRECT_CHAIN[i])
self.assertEqual(resp.text, self.DEFAULT_REDIRECT_BODY)
@httpretty.activate
def test_history_matches_requests(self):
self.setup_redirects(status=301)
session = client_session.Session(redirect=True)
req_resp = requests.get(self.REDIRECT_CHAIN[0],
allow_redirects=True)
ses_resp = session.get(self.REDIRECT_CHAIN[0])
self.assertEqual(len(req_resp.history), len(ses_resp.history))
for r, s in zip(req_resp.history, ses_resp.history):
self.assertEqual(r.url, s.url)
self.assertEqual(r.status_code, s.status_code)
class ConstructSessionFromArgsTests(utils.TestCase):
KEY = 'keyfile'
CERT = 'certfile'
CACERT = 'cacert-path'
def _s(self, k=None, **kwargs):
k = k or kwargs
return client_session.Session.construct(k)
def test_verify(self):
self.assertFalse(self._s(insecure=True).verify)
self.assertTrue(self._s(verify=True, insecure=True).verify)
self.assertFalse(self._s(verify=False, insecure=True).verify)
self.assertEqual(self._s(cacert=self.CACERT).verify, self.CACERT)
def test_cert(self):
tup = (self.CERT, self.KEY)
self.assertEqual(self._s(cert=tup).cert, tup)
self.assertEqual(self._s(cert=self.CERT, key=self.KEY).cert, tup)
self.assertIsNone(self._s(key=self.KEY).cert)
def test_pass_through(self):
value = 42 # only a number because timeout needs to be
for key in ['timeout', 'session', 'original_ip', 'user_agent']:
args = {key: value}
self.assertEqual(getattr(self._s(args), key), value)
self.assertNotIn(key, args)
class AuthPlugin(base.BaseAuthPlugin):
"""Very simple debug authentication plugin.
Takes Parameters such that it can throw exceptions at the right times.
"""
TEST_TOKEN = 'aToken'
SERVICE_URLS = {
'identity': {'public': 'http://identity-public:1111/v2.0',
'admin': 'http://identity-admin:1111/v2.0'},
'compute': {'public': 'http://compute-public:2222/v1.0',
'admin': 'http://compute-admin:2222/v1.0'},
'image': {'public': 'http://image-public:3333/v2.0',
'admin': 'http://image-admin:3333/v2.0'}
}
def __init__(self, token=TEST_TOKEN, invalidate=True):
self.token = token
self._invalidate = invalidate
def get_token(self, session):
return self.token
def get_endpoint(self, session, service_type=None, interface=None,
**kwargs):
try:
return self.SERVICE_URLS[service_type][interface]
except (KeyError, AttributeError):
return None
def invalidate(self):
return self._invalidate
class CalledAuthPlugin(base.BaseAuthPlugin):
ENDPOINT = 'http://fakeendpoint/'
def __init__(self, invalidate=True):
self.get_token_called = False
self.get_endpoint_called = False
self.invalidate_called = False
self._invalidate = invalidate
def get_token(self, session):
self.get_token_called = True
return 'aToken'
def get_endpoint(self, session, **kwargs):
self.get_endpoint_called = True
return self.ENDPOINT
def invalidate(self):
self.invalidate_called = True
return self._invalidate
class SessionAuthTests(utils.TestCase):
TEST_URL = 'http://127.0.0.1:5000/'
TEST_JSON = {'hello': 'world'}
def stub_service_url(self, service_type, interface, path,
method=httpretty.GET, **kwargs):
base_url = AuthPlugin.SERVICE_URLS[service_type][interface]
uri = "%s/%s" % (base_url.rstrip('/'), path.lstrip('/'))
httpretty.register_uri(method, uri, **kwargs)
@httpretty.activate
def test_auth_plugin_default_with_plugin(self):
self.stub_url('GET', base_url=self.TEST_URL, json=self.TEST_JSON)
# if there is an auth_plugin then it should default to authenticated
auth = AuthPlugin()
sess = client_session.Session(auth=auth)
resp = sess.get(self.TEST_URL)
self.assertDictEqual(resp.json(), self.TEST_JSON)
self.assertRequestHeaderEqual('X-Auth-Token', AuthPlugin.TEST_TOKEN)
@httpretty.activate
def test_auth_plugin_disable(self):
self.stub_url('GET', base_url=self.TEST_URL, json=self.TEST_JSON)
auth = AuthPlugin()
sess = client_session.Session(auth=auth)
resp = sess.get(self.TEST_URL, authenticated=False)
self.assertDictEqual(resp.json(), self.TEST_JSON)
self.assertRequestHeaderEqual('X-Auth-Token', None)
@httpretty.activate
def test_service_type_urls(self):
service_type = 'compute'
interface = 'public'
path = '/instances'
status = 200
body = 'SUCCESS'
self.stub_service_url(service_type=service_type,
interface=interface,
path=path,
status=status,
body=body)
sess = client_session.Session(auth=AuthPlugin())
resp = sess.get(path,
endpoint_filter={'service_type': service_type,
'interface': interface})
self.assertEqual(httpretty.last_request().path, '/v1.0/instances')
self.assertEqual(resp.text, body)
self.assertEqual(resp.status_code, status)
def test_service_url_raises_if_no_auth_plugin(self):
sess = client_session.Session()
self.assertRaises(exceptions.MissingAuthPlugin,
sess.get, '/path',
endpoint_filter={'service_type': 'compute',
'interface': 'public'})
def test_service_url_raises_if_no_url_returned(self):
sess = client_session.Session(auth=AuthPlugin())
self.assertRaises(exceptions.EndpointNotFound,
sess.get, '/path',
endpoint_filter={'service_type': 'unknown',
'interface': 'public'})
@httpretty.activate
def test_raises_exc_only_when_asked(self):
# A request that returns a HTTP error should by default raise an
# exception by default, if you specify raise_exc=False then it will not
self.stub_url(httpretty.GET, status=401)
sess = client_session.Session()
self.assertRaises(exceptions.Unauthorized, sess.get, self.TEST_URL)
resp = sess.get(self.TEST_URL, raise_exc=False)
self.assertEqual(401, resp.status_code)
@httpretty.activate
def test_passed_auth_plugin(self):
passed = CalledAuthPlugin()
sess = client_session.Session()
httpretty.register_uri(httpretty.GET,
CalledAuthPlugin.ENDPOINT + 'path',
status=200)
endpoint_filter = {'service_type': 'identity'}
# no plugin with authenticated won't work
self.assertRaises(exceptions.MissingAuthPlugin, sess.get, 'path',
authenticated=True)
# no plugin with an endpoint filter won't work
self.assertRaises(exceptions.MissingAuthPlugin, sess.get, 'path',
authenticated=False, endpoint_filter=endpoint_filter)
resp = sess.get('path', auth=passed, endpoint_filter=endpoint_filter)
self.assertEqual(200, resp.status_code)
self.assertTrue(passed.get_endpoint_called)
self.assertTrue(passed.get_token_called)
@httpretty.activate
def test_passed_auth_plugin_overrides(self):
fixed = CalledAuthPlugin()
passed = CalledAuthPlugin()
sess = client_session.Session(fixed)
httpretty.register_uri(httpretty.GET,
CalledAuthPlugin.ENDPOINT + 'path',
status=200)
resp = sess.get('path', auth=passed,
endpoint_filter={'service_type': 'identity'})
self.assertEqual(200, resp.status_code)
self.assertTrue(passed.get_endpoint_called)
self.assertTrue(passed.get_token_called)
self.assertFalse(fixed.get_endpoint_called)
self.assertFalse(fixed.get_token_called)
def test_requests_auth_plugin(self):
sess = client_session.Session()
requests_auth = object()
FAKE_RESP = utils.TestResponse({'status_code': 200, 'text': 'resp'})
RESP = mock.Mock(return_value=FAKE_RESP)
with mock.patch.object(sess.session, 'request', RESP) as mocked:
sess.get(self.TEST_URL, requests_auth=requests_auth)
mocked.assert_called_once_with('GET', self.TEST_URL,
headers=mock.ANY,
allow_redirects=mock.ANY,
auth=requests_auth,
verify=mock.ANY)
@httpretty.activate
def test_reauth_called(self):
auth = CalledAuthPlugin(invalidate=True)
sess = client_session.Session(auth=auth)
responses = [httpretty.Response(body='Failed', status=401),
httpretty.Response(body='Hello', status=200)]
httpretty.register_uri(httpretty.GET, self.TEST_URL,
responses=responses)
# allow_reauth=True is the default
resp = sess.get(self.TEST_URL, authenticated=True)
self.assertEqual(200, resp.status_code)
self.assertEqual('Hello', resp.text)
self.assertTrue(auth.invalidate_called)
@httpretty.activate
def test_reauth_not_called(self):
auth = CalledAuthPlugin(invalidate=True)
sess = client_session.Session(auth=auth)
responses = [httpretty.Response(body='Failed', status=401),
httpretty.Response(body='Hello', status=200)]
httpretty.register_uri(httpretty.GET, self.TEST_URL,
responses=responses)
self.assertRaises(exceptions.Unauthorized, sess.get, self.TEST_URL,
authenticated=True, allow_reauth=False)
self.assertFalse(auth.invalidate_called)

View File

@@ -1,517 +0,0 @@
# 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 argparse
import json
import logging
import os
import sys
import uuid
import fixtures
import mock
import six
import testtools
from testtools import matchers
from keystoneclient import exceptions
from keystoneclient import session
from keystoneclient import shell as openstack_shell
from keystoneclient.tests import utils
from keystoneclient.v2_0 import shell as shell_v2_0
DEFAULT_USERNAME = 'username'
DEFAULT_PASSWORD = 'password'
DEFAULT_TENANT_ID = 'tenant_id'
DEFAULT_TENANT_NAME = 'tenant_name'
DEFAULT_AUTH_URL = 'http://127.0.0.1:5000/v2.0/'
class NoExitArgumentParser(argparse.ArgumentParser):
def error(self, message):
raise exceptions.CommandError(message)
class ShellTest(utils.TestCase):
FAKE_ENV = {
'OS_USERNAME': DEFAULT_USERNAME,
'OS_PASSWORD': DEFAULT_PASSWORD,
'OS_TENANT_ID': DEFAULT_TENANT_ID,
'OS_TENANT_NAME': DEFAULT_TENANT_NAME,
'OS_AUTH_URL': DEFAULT_AUTH_URL,
}
def _tolerant_shell(self, cmd):
t_shell = openstack_shell.OpenStackIdentityShell(NoExitArgumentParser)
t_shell.main(cmd.split())
# Patch os.environ to avoid required auth info.
def setUp(self):
super(ShellTest, self).setUp()
for var in os.environ:
if var.startswith("OS_"):
self.useFixture(fixtures.EnvironmentVariable(var, ""))
for var in self.FAKE_ENV:
self.useFixture(fixtures.EnvironmentVariable(var,
self.FAKE_ENV[var]))
# Make a fake shell object, a helping wrapper to call it, and a quick
# way of asserting that certain API calls were made.
global shell, _shell, assert_called, assert_called_anytime
_shell = openstack_shell.OpenStackIdentityShell()
shell = lambda cmd: _shell.main(cmd.split())
def test_help_unknown_command(self):
self.assertRaises(exceptions.CommandError, shell, 'help %s'
% uuid.uuid4().hex)
def shell(self, argstr):
orig = sys.stdout
clean_env = {}
_old_env, os.environ = os.environ, clean_env.copy()
try:
sys.stdout = six.StringIO()
_shell = openstack_shell.OpenStackIdentityShell()
_shell.main(argstr.split())
except SystemExit:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.assertEqual(exc_value.code, 0)
finally:
out = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = orig
os.environ = _old_env
return out
def test_help_no_args(self):
do_tenant_mock = mock.MagicMock()
with mock.patch('keystoneclient.shell.OpenStackIdentityShell.do_help',
do_tenant_mock):
self.shell('')
assert do_tenant_mock.called
def test_help(self):
required = 'usage:'
help_text = self.shell('help')
self.assertThat(help_text,
matchers.MatchesRegex(required))
def test_help_command(self):
required = 'usage: keystone user-create'
help_text = self.shell('help user-create')
self.assertThat(help_text,
matchers.MatchesRegex(required))
def test_auth_no_credentials(self):
with testtools.ExpectedException(
exceptions.CommandError, 'Expecting'):
self.shell('user-list')
def test_debug(self):
logging_mock = mock.MagicMock()
with mock.patch('logging.basicConfig', logging_mock):
self.assertRaises(exceptions.CommandError,
self.shell, '--debug user-list')
self.assertTrue(logging_mock.called)
self.assertEqual([(), {'level': logging.DEBUG}],
list(logging_mock.call_args))
def test_auth_password_authurl_no_username(self):
with testtools.ExpectedException(
exceptions.CommandError,
'Expecting a username provided via either'):
self.shell('--os-password=%s --os-auth-url=%s user-list'
% (uuid.uuid4().hex, uuid.uuid4().hex))
def test_auth_username_password_no_authurl(self):
with testtools.ExpectedException(
exceptions.CommandError, 'Expecting an auth URL via either'):
self.shell('--os-password=%s --os-username=%s user-list'
% (uuid.uuid4().hex, uuid.uuid4().hex))
def test_token_no_endpoint(self):
with testtools.ExpectedException(
exceptions.CommandError, 'Expecting an endpoint provided'):
self.shell('--os-token=%s user-list' % uuid.uuid4().hex)
def test_endpoint_no_token(self):
with testtools.ExpectedException(
exceptions.CommandError, 'Expecting a token provided'):
self.shell('--os-endpoint=http://10.0.0.1:5000/v2.0/ user-list')
def test_shell_args(self):
do_tenant_mock = mock.MagicMock()
with mock.patch('keystoneclient.v2_0.shell.do_user_list',
do_tenant_mock):
shell('user-list')
assert do_tenant_mock.called
((a, b), c) = do_tenant_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# Old_style options
shell('--os_auth_url http://0.0.0.0:5000/ --os_password xyzpdq '
'--os_tenant_id 1234 --os_tenant_name fred '
'--os_username barney '
'--os_identity_api_version 2.0 user-list')
assert do_tenant_mock.called
((a, b), c) = do_tenant_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = ('http://0.0.0.0:5000/', 'xyzpdq', '1234',
'fred', 'barney', '2.0')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
shell('--os-auth-url http://1.1.1.1:5000/ --os-password xyzpdq '
'--os-tenant-id 4321 --os-tenant-name wilma '
'--os-username betty '
'--os-identity-api-version 2.0 user-list')
assert do_tenant_mock.called
((a, b), c) = do_tenant_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = ('http://1.1.1.1:5000/', 'xyzpdq', '4321',
'wilma', 'betty', '2.0')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# Test keyring options
shell('--os-auth-url http://1.1.1.1:5000/ --os-password xyzpdq '
'--os-tenant-id 4321 --os-tenant-name wilma '
'--os-username betty '
'--os-identity-api-version 2.0 '
'--os-cache '
'--stale-duration 500 '
'--force-new-token user-list')
assert do_tenant_mock.called
((a, b), c) = do_tenant_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version, b.os_cache,
b.stale_duration, b.force_new_token)
expect = ('http://1.1.1.1:5000/', 'xyzpdq', '4321',
'wilma', 'betty', '2.0', True, '500', True)
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# Test os-identity-api-version fall back to 2.0
shell('--os-identity-api-version 3.0 user-list')
assert do_tenant_mock.called
self.assertTrue(b.os_identity_api_version, '2.0')
def test_shell_user_create_args(self):
"""Test user-create args."""
do_uc_mock = mock.MagicMock()
# grab the decorators for do_user_create
uc_func = getattr(shell_v2_0, 'do_user_create')
do_uc_mock.arguments = getattr(uc_func, 'arguments', [])
with mock.patch('keystoneclient.v2_0.shell.do_user_create',
do_uc_mock):
# Old_style options
# Test case with one --tenant_id args present: ec2 creds
shell('user-create --name=FOO '
'--pass=secrete --tenant_id=barrr --enabled=true')
assert do_uc_mock.called
((a, b), c) = do_uc_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.name, b.passwd, b.enabled)
expect = ('barrr', 'FOO', 'secrete', 'true')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test case with one --tenant args present: ec2 creds
shell('user-create --name=foo '
'--pass=secrete --tenant=BARRR --enabled=true')
assert do_uc_mock.called
((a, b), c) = do_uc_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant, b.name, b.passwd, b.enabled)
expect = ('BARRR', 'foo', 'secrete', 'true')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test case with one --tenant-id args present: ec2 creds
shell('user-create --name=foo '
'--pass=secrete --tenant-id=BARRR --enabled=true')
assert do_uc_mock.called
((a, b), c) = do_uc_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant, b.name, b.passwd, b.enabled)
expect = ('BARRR', 'foo', 'secrete', 'true')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# Old_style options
# Test case with --os_tenant_id and --tenant_id args present
shell('--os_tenant_id=os-tenant user-create --name=FOO '
'--pass=secrete --tenant_id=barrr --enabled=true')
assert do_uc_mock.called
((a, b), c) = do_uc_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, 'os-tenant',
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.name, b.passwd, b.enabled)
expect = ('barrr', 'FOO', 'secrete', 'true')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test case with --os-tenant-id and --tenant-id args present
shell('--os-tenant-id=ostenant user-create --name=foo '
'--pass=secrete --tenant-id=BARRR --enabled=true')
assert do_uc_mock.called
((a, b), c) = do_uc_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, 'ostenant',
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant, b.name, b.passwd, b.enabled)
expect = ('BARRR', 'foo', 'secrete', 'true')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
def test_do_tenant_create(self):
do_tenant_mock = mock.MagicMock()
with mock.patch('keystoneclient.v2_0.shell.do_tenant_create',
do_tenant_mock):
shell('tenant-create')
assert do_tenant_mock.called
# FIXME(dtroyer): how do you test the decorators?
#shell('tenant-create --tenant-name wilma '
# '--description "fred\'s wife"')
#assert do_tenant_mock.called
def test_do_tenant_list(self):
do_tenant_mock = mock.MagicMock()
with mock.patch('keystoneclient.v2_0.shell.do_tenant_list',
do_tenant_mock):
shell('tenant-list')
assert do_tenant_mock.called
def test_shell_tenant_id_args(self):
"""Test a corner case where --tenant_id appears on the
command-line twice.
"""
do_ec2_mock = mock.MagicMock()
# grab the decorators for do_ec2_create_credentials
ec2_func = getattr(shell_v2_0, 'do_ec2_credentials_create')
do_ec2_mock.arguments = getattr(ec2_func, 'arguments', [])
with mock.patch('keystoneclient.v2_0.shell.do_ec2_credentials_create',
do_ec2_mock):
# Old_style options
# Test case with one --tenant_id args present: ec2 creds
shell('ec2-credentials-create '
'--tenant_id=ec2-tenant --user_id=ec2-user')
assert do_ec2_mock.called
((a, b), c) = do_ec2_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.user_id)
expect = ('ec2-tenant', 'ec2-user')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test case with one --tenant-id args present: ec2 creds
shell('ec2-credentials-create '
'--tenant-id=dash-tenant --user-id=dash-user')
assert do_ec2_mock.called
((a, b), c) = do_ec2_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.user_id)
expect = ('dash-tenant', 'dash-user')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# Old_style options
# Test case with two --tenant_id args present
shell('--os_tenant_id=os-tenant ec2-credentials-create '
'--tenant_id=ec2-tenant --user_id=ec2-user')
assert do_ec2_mock.called
((a, b), c) = do_ec2_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, 'os-tenant',
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.user_id)
expect = ('ec2-tenant', 'ec2-user')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test case with two --tenant-id args present
shell('--os-tenant-id=ostenant ec2-credentials-create '
'--tenant-id=dash-tenant --user-id=dash-user')
assert do_ec2_mock.called
((a, b), c) = do_ec2_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, 'ostenant',
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.tenant_id, b.user_id)
expect = ('dash-tenant', 'dash-user')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
def test_do_ec2_get(self):
do_shell_mock = mock.MagicMock()
with mock.patch('keystoneclient.v2_0.shell.do_ec2_credentials_create',
do_shell_mock):
shell('ec2-credentials-create')
assert do_shell_mock.called
with mock.patch('keystoneclient.v2_0.shell.do_ec2_credentials_get',
do_shell_mock):
shell('ec2-credentials-get')
assert do_shell_mock.called
with mock.patch('keystoneclient.v2_0.shell.do_ec2_credentials_list',
do_shell_mock):
shell('ec2-credentials-list')
assert do_shell_mock.called
with mock.patch('keystoneclient.v2_0.shell.do_ec2_credentials_delete',
do_shell_mock):
shell('ec2-credentials-delete')
assert do_shell_mock.called
def test_timeout_parse_invalid_type(self):
for f in ['foobar', 'xyz']:
cmd = '--timeout %s endpoint-create' % (f)
self.assertRaises(exceptions.CommandError,
self._tolerant_shell, cmd)
def test_timeout_parse_invalid_number(self):
for f in [-1, 0]:
cmd = '--timeout %s endpoint-create' % (f)
self.assertRaises(exceptions.CommandError,
self._tolerant_shell, cmd)
def test_do_timeout(self):
response_mock = mock.MagicMock()
response_mock.status_code = 200
response_mock.text = json.dumps({
'endpoints': [],
})
request_mock = mock.MagicMock(return_value=response_mock)
with mock.patch.object(session.requests, 'request',
request_mock):
shell(('--timeout 2 --os-token=blah --os-endpoint=blah'
' --os-auth-url=blah.com endpoint-list'))
request_mock.assert_called_with(mock.ANY, mock.ANY,
timeout=2,
allow_redirects=False,
headers=mock.ANY,
verify=mock.ANY)
def test_do_endpoints(self):
do_shell_mock = mock.MagicMock()
# grab the decorators for do_endpoint_create
shell_func = getattr(shell_v2_0, 'do_endpoint_create')
do_shell_mock.arguments = getattr(shell_func, 'arguments', [])
with mock.patch('keystoneclient.v2_0.shell.do_endpoint_create',
do_shell_mock):
# Old_style options
# Test create args
shell('endpoint-create '
'--service_id=2 --publicurl=http://example.com:1234/go '
'--adminurl=http://example.com:9876/adm')
assert do_shell_mock.called
((a, b), c) = do_shell_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.service, b.publicurl, b.adminurl)
expect = ('2',
'http://example.com:1234/go',
'http://example.com:9876/adm')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test create args
shell('endpoint-create '
'--service-id=3 --publicurl=http://example.com:4321/go '
'--adminurl=http://example.com:9876/adm')
assert do_shell_mock.called
((a, b), c) = do_shell_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.service, b.publicurl, b.adminurl)
expect = ('3',
'http://example.com:4321/go',
'http://example.com:9876/adm')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
# New-style options
# Test create args
shell('endpoint-create '
'--service=3 --publicurl=http://example.com:4321/go '
'--adminurl=http://example.com:9876/adm')
assert do_shell_mock.called
((a, b), c) = do_shell_mock.call_args
actual = (b.os_auth_url, b.os_password, b.os_tenant_id,
b.os_tenant_name, b.os_username,
b.os_identity_api_version)
expect = (DEFAULT_AUTH_URL, DEFAULT_PASSWORD, DEFAULT_TENANT_ID,
DEFAULT_TENANT_NAME, DEFAULT_USERNAME, '')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))
actual = (b.service, b.publicurl, b.adminurl)
expect = ('3',
'http://example.com:4321/go',
'http://example.com:9876/adm')
self.assertTrue(all([x == y for x, y in zip(actual, expect)]))

View File

@@ -1,240 +0,0 @@
# 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 logging
import sys
import six
import testresources
from testtools import matchers
from keystoneclient import exceptions
from keystoneclient.tests import client_fixtures
from keystoneclient.tests import utils as test_utils
from keystoneclient import utils
class FakeResource(object):
pass
class FakeManager(object):
resource_class = FakeResource
resources = {
'1234': {'name': 'entity_one'},
'8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0': {'name': 'entity_two'},
'\xe3\x82\xbdtest': {'name': u'\u30bdtest'},
'5678': {'name': '9876'}
}
def get(self, resource_id):
try:
return self.resources[str(resource_id)]
except KeyError:
raise exceptions.NotFound(resource_id)
def find(self, name=None):
if name == '9999':
# NOTE(morganfainberg): special case that raises NoUniqueMatch.
raise exceptions.NoUniqueMatch()
for resource_id, resource in self.resources.items():
if resource['name'] == str(name):
return resource
raise exceptions.NotFound(name)
class FindResourceTestCase(test_utils.TestCase):
def setUp(self):
super(FindResourceTestCase, self).setUp()
self.manager = FakeManager()
def test_find_none(self):
self.assertRaises(exceptions.CommandError,
utils.find_resource,
self.manager,
'asdf')
def test_find_by_integer_id(self):
output = utils.find_resource(self.manager, 1234)
self.assertEqual(output, self.manager.resources['1234'])
def test_find_by_str_id(self):
output = utils.find_resource(self.manager, '1234')
self.assertEqual(output, self.manager.resources['1234'])
def test_find_by_uuid(self):
uuid = '8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0'
output = utils.find_resource(self.manager, uuid)
self.assertEqual(output, self.manager.resources[uuid])
def test_find_by_unicode(self):
name = '\xe3\x82\xbdtest'
output = utils.find_resource(self.manager, name)
self.assertEqual(output, self.manager.resources[name])
def test_find_by_str_name(self):
output = utils.find_resource(self.manager, 'entity_one')
self.assertEqual(output, self.manager.resources['1234'])
def test_find_by_int_name(self):
output = utils.find_resource(self.manager, 9876)
self.assertEqual(output, self.manager.resources['5678'])
def test_find_no_unique_match(self):
self.assertRaises(exceptions.CommandError,
utils.find_resource,
self.manager,
9999)
class FakeObject(object):
def __init__(self, name):
self.name = name
class PrintTestCase(test_utils.TestCase):
def setUp(self):
super(PrintTestCase, self).setUp()
self.old_stdout = sys.stdout
self.stdout = six.moves.cStringIO()
self.addCleanup(setattr, self, 'stdout', None)
sys.stdout = self.stdout
self.addCleanup(setattr, sys, 'stdout', self.old_stdout)
def test_print_list_unicode(self):
name = six.u('\u540d\u5b57')
objs = [FakeObject(name)]
# NOTE(Jeffrey4l) If the text's encode is proper, this method will not
# raise UnicodeEncodeError exceptions
utils.print_list(objs, ['name'])
output = self.stdout.getvalue()
# In Python 2, output will be bytes, while in Python 3, it will not.
# Let's decode the value if needed.
if isinstance(output, six.binary_type):
output = output.decode('utf-8')
self.assertIn(name, output)
def test_print_dict_unicode(self):
name = six.u('\u540d\u5b57')
utils.print_dict({'name': name})
output = self.stdout.getvalue()
# In Python 2, output will be bytes, while in Python 3, it will not.
# Let's decode the value if needed.
if isinstance(output, six.binary_type):
output = output.decode('utf-8')
self.assertIn(name, output)
class TestPositional(test_utils.TestCase):
@utils.positional(1)
def no_vars(self):
# positional doesn't enforce anything here
return True
@utils.positional(3, utils.positional.EXCEPT)
def mixed_except(self, arg, kwarg1=None, kwarg2=None):
# self, arg, and kwarg1 may be passed positionally
return (arg, kwarg1, kwarg2)
@utils.positional(3, utils.positional.WARN)
def mixed_warn(self, arg, kwarg1=None, kwarg2=None):
# self, arg, and kwarg1 may be passed positionally, only a warning
# is emitted
return (arg, kwarg1, kwarg2)
def test_nothing(self):
self.assertTrue(self.no_vars())
def test_mixed_except(self):
self.assertEqual((1, 2, 3), self.mixed_except(1, 2, kwarg2=3))
self.assertEqual((1, 2, 3), self.mixed_except(1, kwarg1=2, kwarg2=3))
self.assertEqual((1, None, None), self.mixed_except(1))
self.assertRaises(TypeError, self.mixed_except, 1, 2, 3)
def test_mixed_warn(self):
logger_message = six.moves.cStringIO()
handler = logging.StreamHandler(logger_message)
handler.setLevel(logging.DEBUG)
logger = logging.getLogger(utils.__name__)
level = logger.getEffectiveLevel()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
self.addCleanup(logger.removeHandler, handler)
self.addCleanup(logger.setLevel, level)
self.mixed_warn(1, 2, 3)
self.assertIn('takes at most 3 positional', logger_message.getvalue())
@utils.positional(enforcement=utils.positional.EXCEPT)
def inspect_func(self, arg, kwarg=None):
return (arg, kwarg)
def test_inspect_positions(self):
self.assertEqual((1, None), self.inspect_func(1))
self.assertEqual((1, 2), self.inspect_func(1, kwarg=2))
self.assertRaises(TypeError, self.inspect_func)
self.assertRaises(TypeError, self.inspect_func, 1, 2)
@utils.positional.classmethod(1)
def class_method(cls, a, b):
return (cls, a, b)
@utils.positional.method(1)
def normal_method(self, a, b):
self.assertIsInstance(self, TestPositional)
return (self, a, b)
def test_class_method(self):
self.assertEqual((TestPositional, 1, 2), self.class_method(1, b=2))
self.assertRaises(TypeError, self.class_method, 1, 2)
def test_normal_method(self):
self.assertEqual((self, 1, 2), self.normal_method(1, b=2))
self.assertRaises(TypeError, self.normal_method, 1, 2)
class HashSignedTokenTestCase(test_utils.TestCase,
testresources.ResourcedTestCase):
"""Unit tests for utils.hash_signed_token()."""
resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)]
def test_default_md5(self):
"""The default hash method is md5."""
token = self.examples.SIGNED_TOKEN_SCOPED
if six.PY3:
token = token.encode('utf-8')
token_id_default = utils.hash_signed_token(token)
token_id_md5 = utils.hash_signed_token(token, mode='md5')
self.assertThat(token_id_default, matchers.Equals(token_id_md5))
# md5 hash is 32 chars.
self.assertThat(token_id_default, matchers.HasLength(32))
def test_sha256(self):
"""Can also hash with sha256."""
token = self.examples.SIGNED_TOKEN_SCOPED
if six.PY3:
token = token.encode('utf-8')
token_id = utils.hash_signed_token(token, mode='sha256')
# sha256 hash is 64 chars.
self.assertThat(token_id, matchers.HasLength(64))
def load_tests(loader, tests, pattern):
return testresources.OptimisingTestSuite(tests)

View File

@@ -1,125 +0,0 @@
# 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.
from __future__ import unicode_literals
from keystoneclient import fixture
def unscoped_token():
return fixture.V2Token(token_id='3e2813b7ba0b4006840c3825860b86ed',
expires='2012-10-03T16:58:01Z',
user_id='c4da488862bd435c9e6c0275a0d0e49a',
user_name='exampleuser')
def project_scoped_token():
_TENANT_ID = '225da22d3ce34b15877ea70b2a575f58'
f = fixture.V2Token(token_id='04c7d5ffaeef485f9dc69c06db285bdb',
expires='2012-10-03T16:53:36Z',
tenant_id='225da22d3ce34b15877ea70b2a575f58',
tenant_name='exampleproject',
user_id='c4da488862bd435c9e6c0275a0d0e49a',
user_name='exampleuser')
f.add_role(id='edc12489faa74ee0aca0b8a0b4d74a74',
name='Member')
s = f.add_service('volume', 'Volume Service')
s.add_endpoint(public='http://public.com:8776/v1/%s' % _TENANT_ID,
admin='http://admin:8776/v1/%s' % _TENANT_ID,
internal='http://internal:8776/v1/%s' % _TENANT_ID,
region='RegionOne')
s = f.add_service('image', 'Image Service')
s.add_endpoint(public='http://public.com:9292/v1',
admin='http://admin:9292/v1',
internal='http://internal:9292/v1',
region='RegionOne')
s = f.add_service('compute', 'Compute Service')
s.add_endpoint(public='http://public.com:8774/v2/%s' % _TENANT_ID,
admin='http://admin:8774/v2/%s' % _TENANT_ID,
internal='http://internal:8774/v2/%s' % _TENANT_ID,
region='RegionOne')
s = f.add_service('ec2', 'EC2 Service')
s.add_endpoint(public='http://public.com:8773/services/Cloud',
admin='http://admin:8773/services/Admin',
internal='http://internal:8773/services/Cloud',
region='RegionOne')
s = f.add_service('identity', 'Identity Service')
s.add_endpoint(public='http://public.com:5000/v2.0',
admin='http://admin:35357/v2.0',
internal='http://internal:5000/v2.0',
region='RegionOne')
return f
def auth_response_body():
f = fixture.V2Token(token_id='ab48a9efdfedb23ty3494',
expires='2010-11-01T03:32:15-05:00',
tenant_id='345',
tenant_name='My Project',
user_id='123',
user_name='jqsmith')
f.add_role(id='234', name='compute:admin')
role = f.add_role(id='235', name='object-store:admin')
role['tenantId'] = '1'
s = f.add_service('compute', 'Cloud Servers')
endpoint = s.add_endpoint(public='https://compute.north.host/v1/1234',
internal='https://compute.north.host/v1/1234',
region='North')
endpoint['tenantId'] = '1'
endpoint['versionId'] = '1.0'
endpoint['versionInfo'] = 'https://compute.north.host/v1.0/'
endpoint['versionList'] = 'https://compute.north.host/'
endpoint = s.add_endpoint(public='https://compute.north.host/v1.1/3456',
internal='https://compute.north.host/v1.1/3456',
region='North')
endpoint['tenantId'] = '2'
endpoint['versionId'] = '1.1'
endpoint['versionInfo'] = 'https://compute.north.host/v1.1/'
endpoint['versionList'] = 'https://compute.north.host/'
s = f.add_service('object-store', 'Cloud Files')
endpoint = s.add_endpoint(public='https://swift.north.host/v1/blah',
internal='https://swift.north.host/v1/blah',
region='South')
endpoint['tenantId'] = '11'
endpoint['versionId'] = '1.0'
endpoint['versionInfo'] = 'uri'
endpoint['versionList'] = 'uri'
endpoint = s.add_endpoint(public='https://swift.north.host/v1.1/blah',
internal='https://compute.north.host/v1.1/blah',
region='South')
endpoint['tenantId'] = '2'
endpoint['versionId'] = '1.1'
endpoint['versionInfo'] = 'https://swift.north.host/v1.1/'
endpoint['versionList'] = 'https://swift.north.host/'
s = f.add_service('image', 'Image Servers')
s.add_endpoint(public='https://image.north.host/v1/',
internal='https://image-internal.north.host/v1/',
region='North')
s.add_endpoint(public='https://image.south.host/v1/',
internal='https://image-internal.south.host/v1/',
region='South')
return f

View File

@@ -1,495 +0,0 @@
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
# Copyright 2011 OpenStack Foundation
#
# 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.
from six.moves.urllib import parse as urlparse
from keystoneclient.tests import fakes
from keystoneclient.tests.v2_0 import utils
class FakeHTTPClient(fakes.FakeClient):
def __init__(self, **kwargs):
self.username = 'username'
self.password = 'password'
self.auth_url = 'auth_url'
self.callstack = []
def _cs_request(self, url, method, **kwargs):
# Check that certain things are called correctly
if method in ['GET', 'DELETE']:
assert 'body' not in kwargs
elif method == 'PUT':
kwargs.setdefault('body', None)
# Call the method
args = urlparse.parse_qsl(urlparse.urlparse(url)[4])
kwargs.update(args)
munged_url = url.rsplit('?', 1)[0]
munged_url = munged_url.strip('/').replace('/', '_').replace('.', '_')
munged_url = munged_url.replace('-', '_')
callback = "%s_%s" % (method.lower(), munged_url)
if not hasattr(self, callback):
raise AssertionError('Called unknown API method: %s %s, '
'expected fakes method name: %s' %
(method, url, callback))
# Note the call
self.callstack.append((method, url, kwargs.get('body')))
if not hasattr(self, callback):
raise AssertionError('Called unknown API method: %s %s, '
'expected fakes method name: %s' %
(method, url, callback))
# Note the call
self.callstack.append((method, url, kwargs.get('body')))
status, body = getattr(self, callback)(**kwargs)
r = utils.TestResponse({
"status_code": status,
"text": body})
return r, body
#
# List all extensions
#
def post_tokens(self, **kw):
body = [
{"access":
{"token":
{"expires": "2012-02-05T00:00:00",
"id": "887665443383838",
"tenant":
{"id": "1",
"name": "customer-x"}},
"serviceCatalog": [
{"endpoints": [
{"adminURL": "http://swift.admin-nets.local:8080/",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:8080/v1/AUTH_1",
"publicURL":
"http://swift.publicinternets.com/v1/AUTH_1"}],
"type": "object-store",
"name": "swift"},
{"endpoints": [
{"adminURL": "http://cdn.admin-nets.local/v1.1/1",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:7777/v1.1/1",
"publicURL":
"http://cdn.publicinternets.com/v1.1/1"}],
"type": "object-store",
"name": "cdn"}],
"user":
{"id": "1",
"roles": [
{"tenantId": "1",
"id": "3",
"name": "Member"}],
"name": "joeuser"}}
}
]
return (200, body)
def get_tokens_887665443383838(self, **kw):
body = [
{"access":
{"token":
{"expires": "2012-02-05T00:00:00",
"id": "887665443383838",
"tenant": {"id": "1",
"name": "customer-x"}},
"user":
{"name": "joeuser",
"tenantName": "customer-x",
"id": "1",
"roles": [{"serviceId": "1",
"id": "3",
"name": "Member"}],
"tenantId": "1"}}
}
]
return (200, body)
def get_tokens_887665443383838_endpoints(self, **kw):
body = [
{"endpoints_links": [
{"href":
"http://127.0.0.1:35357/tokens/887665443383838"
"/endpoints?'marker=5&limit=10'",
"rel": "next"}],
"endpoints": [
{"internalURL": "http://127.0.0.1:8080/v1/AUTH_1",
"name": "swift",
"adminURL": "http://swift.admin-nets.local:8080/",
"region": "RegionOne",
"tenantId": 1,
"type": "object-store",
"id": 1,
"publicURL": "http://swift.publicinternets.com/v1/AUTH_1"},
{"internalURL": "http://localhost:8774/v1.0",
"name": "nova_compat",
"adminURL": "http://127.0.0.1:8774/v1.0",
"region": "RegionOne",
"tenantId": 1,
"type": "compute",
"id": 2,
"publicURL": "http://nova.publicinternets.com/v1.0/"},
{"internalURL": "http://localhost:8774/v1.1",
"name": "nova",
"adminURL": "http://127.0.0.1:8774/v1.1",
"region": "RegionOne",
"tenantId": 1,
"type": "compute",
"id": 3,
"publicURL": "http://nova.publicinternets.com/v1.1/"},
{"internalURL": "http://127.0.0.1:9292/v1.1/",
"name": "glance",
"adminURL": "http://nova.admin-nets.local/v1.1/",
"region": "RegionOne",
"tenantId": 1,
"type": "image",
"id": 4,
"publicURL": "http://glance.publicinternets.com/v1.1/"},
{"internalURL": "http://127.0.0.1:7777/v1.1/1",
"name": "cdn",
"adminURL": "http://cdn.admin-nets.local/v1.1/1",
"region": "RegionOne",
"tenantId": 1,
"versionId": "1.1",
"versionList": "http://127.0.0.1:7777/",
"versionInfo": "http://127.0.0.1:7777/v1.1",
"type": "object-store",
"id": 5,
"publicURL": "http://cdn.publicinternets.com/v1.1/1"}]
}
]
return (200, body)
def get(self, **kw):
body = {
"version": {
"id": "v2.0",
"status": "beta",
"updated": "2011-11-19T00:00:00Z",
"links": [
{"rel": "self",
"href": "http://127.0.0.1:35357/v2.0/"},
{"rel": "describedby",
"type": "text/html",
"href": "http://docs.openstack.org/"
"api/openstack-identity-service/2.0/content/"},
{"rel": "describedby",
"type": "application/pdf",
"href": "http://docs.openstack.org/api/"
"openstack-identity-service/2.0/"
"identity-dev-guide-2.0.pdf"},
{"rel": "describedby",
"type": "application/vnd.sun.wadl+xml",
"href":
"http://127.0.0.1:35357/v2.0/identity-admin.wadl"}],
"media-types": [
{"base": "application/xml",
"type": "application/vnd.openstack.identity-v2.0+xml"},
{"base": "application/json",
"type": "application/vnd.openstack.identity-v2.0+json"}]
}
}
return (200, body)
def get_extensions(self, **kw):
body = {
"extensions": {"values": []}
}
return (200, body)
def post_tenants(self, **kw):
body = {"tenant":
{"enabled": True,
"description": None,
"name": "new-tenant",
"id": "1"}}
return (200, body)
def post_tenants_2(self, **kw):
body = {"tenant":
{"enabled": False,
"description": "desc",
"name": "new-tenant1",
"id": "2"}}
return (200, body)
def get_tenants(self, **kw):
body = {
"tenants_links": [],
"tenants": [
{"enabled": False,
"description": None,
"name": "project-y",
"id": "1"},
{"enabled": True,
"description": None,
"name": "new-tenant",
"id": "2"},
{"enabled": True,
"description": None,
"name": "customer-x",
"id": "1"}]
}
return (200, body)
def get_tenants_1(self, **kw):
body = {"tenant":
{"enabled": True,
"description": None,
"name": "new-tenant",
"id": "1"}}
return (200, body)
def get_tenants_2(self, **kw):
body = {"tenant":
{"enabled": True,
"description": None,
"name": "new-tenant",
"id": "2"}}
return (200, body)
def delete_tenants_2(self, **kw):
body = {}
return (200, body)
def get_tenants_1_users_1_roles(self, **kw):
body = {
"roles": [
{"id": "1",
"name": "Admin"},
{"id": "2",
"name": "Member"},
{"id": "3",
"name": "new-role"}]
}
return (200, body)
def put_users_1_roles_OS_KSADM_1(self, **kw):
body = {
"roles":
{"id": "1",
"name": "Admin"}}
return (200, body)
def delete_users_1_roles_OS_KSADM_1(self, **kw):
body = {}
return (200, body)
def put_tenants_1_users_1_roles_OS_KSADM_1(self, **kw):
body = {
"role":
{"id": "1",
"name": "Admin"}}
return (200, body)
def get_users(self, **kw):
body = {
"users": [
{"name": self.username,
"enabled": "true",
"email": "sdfsdf@sdfsd.sdf",
"id": "1",
"tenantId": "1"},
{"name": "user2",
"enabled": "true",
"email": "sdfsdf@sdfsd.sdf",
"id": "2",
"tenantId": "1"}]
}
return (200, body)
def get_users_1(self, **kw):
body = {
"user": {
"tenantId": "1",
"enabled": "true",
"id": "1",
"name": self.username}
}
return (200, body)
def put_users_1(self, **kw):
body = {
"user": {
"tenantId": "1",
"enabled": "true",
"id": "1",
"name": "new-user1",
"email": "user@email.com"}
}
return (200, body)
def put_users_1_OS_KSADM_password(self, **kw):
body = {
"user": {
"tenantId": "1",
"enabled": "true",
"id": "1",
"name": "new-user1",
"email": "user@email.com"}
}
return (200, body)
def post_users(self, **kw):
body = {
"user": {
"tenantId": "1",
"enabled": "true",
"id": "1",
"name": self.username}
}
return (200, body)
def delete_users_1(self, **kw):
body = []
return (200, body)
def get_users_1_roles(self, **kw):
body = [
{"roles_links": [],
"roles":[
{"id": "2",
"name": "KeystoneServiceAdmin"}]
}
]
return (200, body)
def post_OS_KSADM_roles(self, **kw):
body = {"role":
{"name": "new-role",
"id": "1"}}
return (200, body)
def get_OS_KSADM_roles(self, **kw):
body = {"roles": [
{"id": "10", "name": "admin"},
{"id": "20", "name": "member"},
{"id": "1", "name": "new-role"}]
}
return (200, body)
def get_OS_KSADM_roles_1(self, **kw):
body = {"role":
{"name": "new-role",
"id": "1"}
}
return (200, body)
def delete_OS_KSADM_roles_1(self, **kw):
body = {}
return (200, body)
def post_OS_KSADM_services(self, **kw):
body = {"OS-KSADM:service":
{"id": "1",
"type": "compute",
"name": "service1",
"description": None}
}
return (200, body)
def get_OS_KSADM_services_1(self, **kw):
body = {"OS-KSADM:service":
{"description": None,
"type": "compute",
"id": "1",
"name": "service1"}
}
return (200, body)
def get_OS_KSADM_services(self, **kw):
body = {
"OS-KSADM:services": [
{"description": None,
"type": "compute",
"id": "1",
"name": "service1"},
{"description": None,
"type": "identity",
"id": "2",
"name": "service2"}]
}
return (200, body)
def delete_OS_KSADM_services_1(self, **kw):
body = {}
return (200, body)
def post_users_1_credentials_OS_EC2(self, **kw):
body = {"credential":
{"access": "1",
"tenant_id": "1",
"secret": "1",
"user_id": "1"}
}
return (200, body)
def get_users_1_credentials_OS_EC2(self, **kw):
body = {"credentials": [
{"access": "1",
"tenant_id": "1",
"secret": "1",
"user_id": "1"}]
}
return (200, body)
def get_users_1_credentials_OS_EC2_2(self, **kw):
body = {
"credential":
{"access": "2",
"tenant_id": "1",
"secret": "1",
"user_id": "1"}
}
return (200, body)
def delete_users_1_credentials_OS_EC2_2(self, **kw):
body = {}
return (200, body)
def patch_OS_KSCRUD_users_1(self, **kw):
body = {}
return (200, body)
def get_endpoints(self, **kw):
body = {
'endpoints': [
{'adminURL': 'http://cdn.admin-nets.local/v1.1/1',
'region': 'RegionOne',
'internalURL': 'http://127.0.0.1:7777/v1.1/1',
'publicURL': 'http://cdn.publicinternets.com/v1.1/1'}],
'type': 'compute',
'name': 'nova-compute'
}
return (200, body)
def post_endpoints(self, **kw):
body = {
"endpoint":
{"adminURL": "http://swift.admin-nets.local:8080/",
"region": "RegionOne",
"internalURL": "http://127.0.0.1:8080/v1/AUTH_1",
"publicURL": "http://swift.publicinternets.com/v1/AUTH_1"},
"type": "compute",
"name": "nova-compute"
}
return (200, body)

View File

@@ -1,135 +0,0 @@
# 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 datetime
import testresources
from keystoneclient import access
from keystoneclient.openstack.common import timeutils
from keystoneclient.tests import client_fixtures as token_data
from keystoneclient.tests.v2_0 import client_fixtures
from keystoneclient.tests.v2_0 import utils
class AccessInfoTest(utils.TestCase, testresources.ResourcedTestCase):
resources = [('examples', token_data.EXAMPLES_RESOURCE)]
def test_building_unscoped_accessinfo(self):
token = client_fixtures.unscoped_token()
auth_ref = access.AccessInfo.factory(body=token)
self.assertTrue(auth_ref)
self.assertIn('token', auth_ref)
self.assertEqual(auth_ref.auth_token,
'3e2813b7ba0b4006840c3825860b86ed')
self.assertEqual(auth_ref.username, 'exampleuser')
self.assertEqual(auth_ref.user_id, 'c4da488862bd435c9e6c0275a0d0e49a')
self.assertEqual(auth_ref.role_names, [])
self.assertIsNone(auth_ref.tenant_name)
self.assertIsNone(auth_ref.tenant_id)
self.assertIsNone(auth_ref.auth_url)
self.assertIsNone(auth_ref.management_url)
self.assertFalse(auth_ref.scoped)
self.assertFalse(auth_ref.domain_scoped)
self.assertFalse(auth_ref.project_scoped)
self.assertFalse(auth_ref.trust_scoped)
self.assertIsNone(auth_ref.project_domain_id)
self.assertIsNone(auth_ref.project_domain_name)
self.assertEqual(auth_ref.user_domain_id, 'default')
self.assertEqual(auth_ref.user_domain_name, 'Default')
self.assertEqual(auth_ref.expires, token.expires)
def test_will_expire_soon(self):
token = client_fixtures.unscoped_token()
expires = timeutils.utcnow() + datetime.timedelta(minutes=5)
token.expires = expires
auth_ref = access.AccessInfo.factory(body=token)
self.assertFalse(auth_ref.will_expire_soon(stale_duration=120))
self.assertTrue(auth_ref.will_expire_soon(stale_duration=300))
self.assertFalse(auth_ref.will_expire_soon())
def test_building_scoped_accessinfo(self):
auth_ref = access.AccessInfo.factory(
body=client_fixtures.project_scoped_token())
self.assertTrue(auth_ref)
self.assertIn('token', auth_ref)
self.assertIn('serviceCatalog', auth_ref)
self.assertTrue(auth_ref['serviceCatalog'])
self.assertEqual(auth_ref.auth_token,
'04c7d5ffaeef485f9dc69c06db285bdb')
self.assertEqual(auth_ref.username, 'exampleuser')
self.assertEqual(auth_ref.user_id, 'c4da488862bd435c9e6c0275a0d0e49a')
self.assertEqual(auth_ref.role_names, ['Member'])
self.assertEqual(auth_ref.tenant_name, 'exampleproject')
self.assertEqual(auth_ref.tenant_id,
'225da22d3ce34b15877ea70b2a575f58')
self.assertEqual(auth_ref.tenant_name, auth_ref.project_name)
self.assertEqual(auth_ref.tenant_id, auth_ref.project_id)
self.assertEqual(auth_ref.auth_url, ('http://public.com:5000/v2.0',))
self.assertEqual(auth_ref.management_url, ('http://admin:35357/v2.0',))
self.assertEqual(auth_ref.project_domain_id, 'default')
self.assertEqual(auth_ref.project_domain_name, 'Default')
self.assertEqual(auth_ref.user_domain_id, 'default')
self.assertEqual(auth_ref.user_domain_name, 'Default')
self.assertTrue(auth_ref.scoped)
self.assertTrue(auth_ref.project_scoped)
self.assertFalse(auth_ref.domain_scoped)
def test_diablo_token(self):
diablo_token = self.examples.TOKEN_RESPONSES[
self.examples.VALID_DIABLO_TOKEN]
auth_ref = access.AccessInfo.factory(body=diablo_token)
self.assertTrue(auth_ref)
self.assertEqual(auth_ref.username, 'user_name1')
self.assertEqual(auth_ref.project_id, 'tenant_id1')
self.assertEqual(auth_ref.project_name, 'tenant_id1')
self.assertEqual(auth_ref.project_domain_id, 'default')
self.assertEqual(auth_ref.project_domain_name, 'Default')
self.assertEqual(auth_ref.user_domain_id, 'default')
self.assertEqual(auth_ref.user_domain_name, 'Default')
self.assertEqual(auth_ref.role_names, ['role1', 'role2'])
self.assertFalse(auth_ref.scoped)
def test_grizzly_token(self):
grizzly_token = self.examples.TOKEN_RESPONSES[
self.examples.SIGNED_TOKEN_SCOPED_KEY]
auth_ref = access.AccessInfo.factory(body=grizzly_token)
self.assertEqual(auth_ref.project_id, 'tenant_id1')
self.assertEqual(auth_ref.project_name, 'tenant_name1')
self.assertEqual(auth_ref.project_domain_id, 'default')
self.assertEqual(auth_ref.project_domain_name, 'Default')
self.assertEqual(auth_ref.user_domain_id, 'default')
self.assertEqual(auth_ref.user_domain_name, 'Default')
self.assertEqual(auth_ref.role_names, ['role1', 'role2'])
def load_tests(loader, tests, pattern):
return testresources.OptimisingTestSuite(tests)

View File

@@ -1,274 +0,0 @@
# 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 datetime
import json
import httpretty
import six
from keystoneclient import exceptions
from keystoneclient.openstack.common import jsonutils
from keystoneclient.openstack.common import timeutils
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import client
class AuthenticateAgainstKeystoneTests(utils.TestCase):
def setUp(self):
super(AuthenticateAgainstKeystoneTests, self).setUp()
self.TEST_RESPONSE_DICT = {
"access": {
"token": {
"expires": "2020-01-01T00:00:10.000123Z",
"id": self.TEST_TOKEN,
"tenant": {
"id": self.TEST_TENANT_ID
},
},
"user": {
"id": self.TEST_USER
},
"serviceCatalog": self.TEST_SERVICE_CATALOG,
},
}
self.TEST_REQUEST_BODY = {
"auth": {
"passwordCredentials": {
"username": self.TEST_USER,
"password": self.TEST_TOKEN,
},
"tenantId": self.TEST_TENANT_ID,
},
}
@httpretty.activate
def test_authenticate_success_expired(self):
# Build an expired token
self.TEST_RESPONSE_DICT['access']['token']['expires'] = (
(timeutils.utcnow() - datetime.timedelta(1)).isoformat())
exp_resp = httpretty.Response(body=json.dumps(self.TEST_RESPONSE_DICT),
content_type='application/json')
# Build a new response
TEST_TOKEN = "abcdef"
self.TEST_RESPONSE_DICT['access']['token']['expires'] = (
'2020-01-01T00:00:10.000123Z')
self.TEST_RESPONSE_DICT['access']['token']['id'] = TEST_TOKEN
new_resp = httpretty.Response(body=json.dumps(self.TEST_RESPONSE_DICT),
content_type='application/json')
# return expired first, and then the new response
self.stub_auth(responses=[exp_resp, new_resp])
cs = client.Client(tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL,
username=self.TEST_USER,
password=self.TEST_TOKEN)
self.assertEqual(cs.management_url,
self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3]
['endpoints'][0]["adminURL"])
self.assertEqual(cs.auth_token, TEST_TOKEN)
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_authenticate_failure(self):
_auth = 'auth'
_cred = 'passwordCredentials'
_pass = 'password'
self.TEST_REQUEST_BODY[_auth][_cred][_pass] = 'bad_key'
error = {"unauthorized": {"message": "Unauthorized",
"code": "401"}}
self.stub_auth(status=401, json=error)
# Workaround for issue with assertRaises on python2.6
# where with assertRaises(exceptions.Unauthorized): doesn't work
# right
def client_create_wrapper():
client.Client(username=self.TEST_USER,
password="bad_key",
tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL)
self.assertRaises(exceptions.Unauthorized, client_create_wrapper)
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_auth_redirect(self):
self.stub_auth(status=305, body='Use Proxy',
location=self.TEST_ADMIN_URL + "/tokens")
self.stub_auth(base_url=self.TEST_ADMIN_URL,
json=self.TEST_RESPONSE_DICT)
cs = client.Client(username=self.TEST_USER,
password=self.TEST_TOKEN,
tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL)
self.assertEqual(cs.management_url,
self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3]
['endpoints'][0]["adminURL"])
self.assertEqual(cs.auth_token,
self.TEST_RESPONSE_DICT["access"]["token"]["id"])
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_authenticate_success_password_scoped(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT)
cs = client.Client(username=self.TEST_USER,
password=self.TEST_TOKEN,
tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL)
self.assertEqual(cs.management_url,
self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3]
['endpoints'][0]["adminURL"])
self.assertEqual(cs.auth_token,
self.TEST_RESPONSE_DICT["access"]["token"]["id"])
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_authenticate_success_password_unscoped(self):
del self.TEST_RESPONSE_DICT['access']['serviceCatalog']
del self.TEST_REQUEST_BODY['auth']['tenantId']
self.stub_auth(json=self.TEST_RESPONSE_DICT)
cs = client.Client(username=self.TEST_USER,
password=self.TEST_TOKEN,
auth_url=self.TEST_URL)
self.assertEqual(cs.auth_token,
self.TEST_RESPONSE_DICT["access"]["token"]["id"])
self.assertFalse('serviceCatalog' in cs.service_catalog.catalog)
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_auth_url_token_authentication(self):
fake_token = 'fake_token'
fake_url = '/fake-url'
fake_resp = {'result': True}
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url('GET', [fake_url], json=fake_resp,
base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
cl = client.Client(auth_url=self.TEST_URL,
token=fake_token)
body = httpretty.last_request().body
if six.PY3:
body = body.decode('utf-8')
body = jsonutils.loads(body)
self.assertEqual(body['auth']['token']['id'], fake_token)
resp, body = cl.get(fake_url)
self.assertEqual(fake_resp, body)
self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
self.TEST_TOKEN)
@httpretty.activate
def test_authenticate_success_token_scoped(self):
del self.TEST_REQUEST_BODY['auth']['passwordCredentials']
self.TEST_REQUEST_BODY['auth']['token'] = {'id': self.TEST_TOKEN}
self.stub_auth(json=self.TEST_RESPONSE_DICT)
cs = client.Client(token=self.TEST_TOKEN,
tenant_id=self.TEST_TENANT_ID,
auth_url=self.TEST_URL)
self.assertEqual(cs.management_url,
self.TEST_RESPONSE_DICT["access"]["serviceCatalog"][3]
['endpoints'][0]["adminURL"])
self.assertEqual(cs.auth_token,
self.TEST_RESPONSE_DICT["access"]["token"]["id"])
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_authenticate_success_token_scoped_trust(self):
del self.TEST_REQUEST_BODY['auth']['passwordCredentials']
self.TEST_REQUEST_BODY['auth']['token'] = {'id': self.TEST_TOKEN}
self.TEST_REQUEST_BODY['auth']['trust_id'] = self.TEST_TRUST_ID
response = self.TEST_RESPONSE_DICT.copy()
response['access']['trust'] = {"trustee_user_id": self.TEST_USER,
"id": self.TEST_TRUST_ID}
self.stub_auth(json=response)
cs = client.Client(token=self.TEST_TOKEN,
tenant_id=self.TEST_TENANT_ID,
trust_id=self.TEST_TRUST_ID,
auth_url=self.TEST_URL)
self.assertTrue(cs.auth_ref.trust_scoped)
self.assertEqual(cs.auth_ref.trust_id, self.TEST_TRUST_ID)
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_authenticate_success_token_unscoped(self):
del self.TEST_REQUEST_BODY['auth']['passwordCredentials']
del self.TEST_REQUEST_BODY['auth']['tenantId']
del self.TEST_RESPONSE_DICT['access']['serviceCatalog']
self.TEST_REQUEST_BODY['auth']['token'] = {'id': self.TEST_TOKEN}
self.stub_auth(json=self.TEST_RESPONSE_DICT)
cs = client.Client(token=self.TEST_TOKEN,
auth_url=self.TEST_URL)
self.assertEqual(cs.auth_token,
self.TEST_RESPONSE_DICT["access"]["token"]["id"])
self.assertFalse('serviceCatalog' in cs.service_catalog.catalog)
self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
@httpretty.activate
def test_allow_override_of_auth_token(self):
fake_url = '/fake-url'
fake_token = 'fake_token'
fake_resp = {'result': True}
self.stub_auth(json=self.TEST_RESPONSE_DICT)
self.stub_url('GET', [fake_url], json=fake_resp,
base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL)
self.assertEqual(cl.auth_token, self.TEST_TOKEN)
# the token returned from the authentication will be used
resp, body = cl.get(fake_url)
self.assertEqual(fake_resp, body)
self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
self.TEST_TOKEN)
# then override that token and the new token shall be used
cl.auth_token = fake_token
resp, body = cl.get(fake_url)
self.assertEqual(fake_resp, body)
self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
fake_token)
# if we clear that overridden token then we fall back to the original
del cl.auth_token
resp, body = cl.get(fake_url)
self.assertEqual(fake_resp, body)
self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
self.TEST_TOKEN)

View File

@@ -1,162 +0,0 @@
# 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 json
import httpretty
from keystoneclient import exceptions
from keystoneclient import fixture
from keystoneclient.tests.v2_0 import client_fixtures
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import client
class KeystoneClientTest(utils.TestCase):
@httpretty.activate
def test_unscoped_init(self):
self.stub_auth(json=client_fixtures.unscoped_token())
c = client.Client(username='exampleuser',
password='password',
auth_url=self.TEST_URL)
self.assertIsNotNone(c.auth_ref)
self.assertFalse(c.auth_ref.scoped)
self.assertFalse(c.auth_ref.domain_scoped)
self.assertFalse(c.auth_ref.project_scoped)
self.assertIsNone(c.auth_ref.trust_id)
self.assertFalse(c.auth_ref.trust_scoped)
@httpretty.activate
def test_scoped_init(self):
self.stub_auth(json=client_fixtures.project_scoped_token())
c = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL)
self.assertIsNotNone(c.auth_ref)
self.assertTrue(c.auth_ref.scoped)
self.assertTrue(c.auth_ref.project_scoped)
self.assertFalse(c.auth_ref.domain_scoped)
self.assertIsNone(c.auth_ref.trust_id)
self.assertFalse(c.auth_ref.trust_scoped)
@httpretty.activate
def test_auth_ref_load(self):
self.stub_auth(json=client_fixtures.project_scoped_token())
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL)
cache = json.dumps(cl.auth_ref)
new_client = client.Client(auth_ref=json.loads(cache))
self.assertIsNotNone(new_client.auth_ref)
self.assertTrue(new_client.auth_ref.scoped)
self.assertTrue(new_client.auth_ref.project_scoped)
self.assertFalse(new_client.auth_ref.domain_scoped)
self.assertIsNone(new_client.auth_ref.trust_id)
self.assertFalse(new_client.auth_ref.trust_scoped)
self.assertEqual(new_client.username, 'exampleuser')
self.assertIsNone(new_client.password)
self.assertEqual(new_client.management_url,
'http://admin:35357/v2.0')
@httpretty.activate
def test_auth_ref_load_with_overridden_arguments(self):
self.stub_auth(json=client_fixtures.project_scoped_token())
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL)
cache = json.dumps(cl.auth_ref)
new_auth_url = "http://new-public:5000/v2.0"
new_client = client.Client(auth_ref=json.loads(cache),
auth_url=new_auth_url)
self.assertIsNotNone(new_client.auth_ref)
self.assertTrue(new_client.auth_ref.scoped)
self.assertTrue(new_client.auth_ref.scoped)
self.assertTrue(new_client.auth_ref.project_scoped)
self.assertFalse(new_client.auth_ref.domain_scoped)
self.assertIsNone(new_client.auth_ref.trust_id)
self.assertFalse(new_client.auth_ref.trust_scoped)
self.assertEqual(new_client.auth_url, new_auth_url)
self.assertEqual(new_client.username, 'exampleuser')
self.assertIsNone(new_client.password)
self.assertEqual(new_client.management_url,
'http://admin:35357/v2.0')
def test_init_err_no_auth_url(self):
self.assertRaises(exceptions.AuthorizationFailure,
client.Client,
username='exampleuser',
password='password')
@httpretty.activate
def test_management_url_is_updated(self):
first = fixture.V2Token()
first.set_scope()
admin_url = 'http://admin:35357/v2.0'
second_url = 'http://secondurl:35357/v2.0'
s = first.add_service('identity')
s.add_endpoint(public='http://public.com:5000/v2.0',
admin=admin_url)
second = fixture.V2Token()
second.set_scope()
s = second.add_service('identity')
s.add_endpoint(public='http://secondurl:5000/v2.0',
admin=second_url)
self.stub_auth(json=first)
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL)
cl.authenticate()
self.assertEqual(cl.management_url, admin_url)
self.stub_auth(json=second)
cl.authenticate()
self.assertEqual(cl.management_url, second_url)
@httpretty.activate
def test_client_with_region_name_passes_to_service_catalog(self):
# NOTE(jamielennox): this is deprecated behaviour that should be
# removed ASAP, however must remain compatible.
self.stub_auth(json=client_fixtures.auth_response_body())
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL,
region_name='North')
self.assertEqual(cl.service_catalog.url_for(service_type='image'),
'https://image.north.host/v1/')
cl = client.Client(username='exampleuser',
password='password',
tenant_name='exampleproject',
auth_url=self.TEST_URL,
region_name='South')
self.assertEqual(cl.service_catalog.url_for(service_type='image'),
'https://image.south.host/v1/')
def test_client_without_auth_params(self):
self.assertRaises(exceptions.AuthorizationFailure,
client.Client,
tenant_name='exampleproject',
auth_url=self.TEST_URL)

View File

@@ -1,83 +0,0 @@
# 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 httpretty
from keystoneclient.generic import client
from keystoneclient.tests.v2_0 import utils
class DiscoverKeystoneTests(utils.UnauthenticatedTestCase):
def setUp(self):
super(DiscoverKeystoneTests, self).setUp()
self.TEST_RESPONSE_DICT = {
"versions": {
"values": [{
"id": "v2.0",
"status": "beta",
"updated": "2011-11-19T00:00:00Z",
"links": [
{"rel": "self",
"href": "http://127.0.0.1:5000/v2.0/", },
{"rel": "describedby",
"type": "text/html",
"href": "http://docs.openstack.org/api/"
"openstack-identity-service/2.0/content/", },
{"rel": "describedby",
"type": "application/pdf",
"href": "http://docs.openstack.org/api/"
"openstack-identity-service/2.0/"
"identity-dev-guide-2.0.pdf", },
{"rel": "describedby",
"type": "application/vnd.sun.wadl+xml",
"href": "http://127.0.0.1:5000/v2.0/identity.wadl", }
],
"media-types": [{
"base": "application/xml",
"type": "application/vnd.openstack.identity-v2.0+xml",
}, {
"base": "application/json",
"type": "application/vnd.openstack.identity-v2.0+json",
}],
}],
},
}
@httpretty.activate
def test_get_versions(self):
self.stub_url(httpretty.GET, base_url=self.TEST_ROOT_URL,
json=self.TEST_RESPONSE_DICT)
cs = client.Client()
versions = cs.discover(self.TEST_ROOT_URL)
self.assertIsInstance(versions, dict)
self.assertIn('message', versions)
self.assertIn('v2.0', versions)
self.assertEqual(
versions['v2.0']['url'],
self.TEST_RESPONSE_DICT['versions']['values'][0]['links'][0]
['href'])
@httpretty.activate
def test_get_version_local(self):
self.stub_url(httpretty.GET, base_url="http://localhost:35357/",
json=self.TEST_RESPONSE_DICT)
cs = client.Client()
versions = cs.discover()
self.assertIsInstance(versions, dict)
self.assertIn('message', versions)
self.assertIn('v2.0', versions)
self.assertEqual(
versions['v2.0']['url'],
self.TEST_RESPONSE_DICT['versions']['values'][0]['links'][0]
['href'])

View File

@@ -1,113 +0,0 @@
# 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 httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import ec2
class EC2Tests(utils.TestCase):
@httpretty.activate
def test_create(self):
user_id = 'usr'
tenant_id = 'tnt'
req_body = {
"tenant_id": tenant_id,
}
resp_body = {
"credential": {
"access": "access",
"secret": "secret",
"tenant_id": tenant_id,
"created": "12/12/12",
"enabled": True,
}
}
self.stub_url(httpretty.POST, ['users', user_id, 'credentials',
'OS-EC2'], json=resp_body)
cred = self.client.ec2.create(user_id, tenant_id)
self.assertIsInstance(cred, ec2.EC2)
self.assertEqual(cred.tenant_id, tenant_id)
self.assertEqual(cred.enabled, True)
self.assertEqual(cred.access, 'access')
self.assertEqual(cred.secret, 'secret')
self.assertRequestBodyIs(json=req_body)
@httpretty.activate
def test_get(self):
user_id = 'usr'
tenant_id = 'tnt'
resp_body = {
"credential": {
"access": "access",
"secret": "secret",
"tenant_id": tenant_id,
"created": "12/12/12",
"enabled": True,
}
}
self.stub_url(httpretty.GET, ['users', user_id, 'credentials',
'OS-EC2', 'access'], json=resp_body)
cred = self.client.ec2.get(user_id, 'access')
self.assertIsInstance(cred, ec2.EC2)
self.assertEqual(cred.tenant_id, tenant_id)
self.assertEqual(cred.enabled, True)
self.assertEqual(cred.access, 'access')
self.assertEqual(cred.secret, 'secret')
@httpretty.activate
def test_list(self):
user_id = 'usr'
tenant_id = 'tnt'
resp_body = {
"credentials": {
"values": [
{
"access": "access",
"secret": "secret",
"tenant_id": tenant_id,
"created": "12/12/12",
"enabled": True,
},
{
"access": "another",
"secret": "key",
"tenant_id": tenant_id,
"created": "12/12/31",
"enabled": True,
}
]
}
}
self.stub_url(httpretty.GET, ['users', user_id, 'credentials',
'OS-EC2'], json=resp_body)
creds = self.client.ec2.list(user_id)
self.assertEqual(len(creds), 2)
cred = creds[0]
self.assertIsInstance(cred, ec2.EC2)
self.assertEqual(cred.tenant_id, tenant_id)
self.assertEqual(cred.enabled, True)
self.assertEqual(cred.access, 'access')
self.assertEqual(cred.secret, 'secret')
@httpretty.activate
def test_delete(self):
user_id = 'usr'
access = 'access'
self.stub_url(httpretty.DELETE, ['users', user_id, 'credentials',
'OS-EC2', access], status=204)
self.client.ec2.delete(user_id, access)

View File

@@ -1,86 +0,0 @@
# 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 httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import endpoints
class EndpointTests(utils.TestCase):
def setUp(self):
super(EndpointTests, self).setUp()
self.TEST_ENDPOINTS = {
'endpoints': [
{
'adminurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'id': '8f9531231e044e218824b0e58688d262',
'internalurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'publicurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'region': 'RegionOne',
},
{
'adminurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'id': '8f9531231e044e218824b0e58688d263',
'internalurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'publicurl': 'http://host-1:8774/v1.1/$(tenant_id)s',
'region': 'RegionOne',
}
]
}
@httpretty.activate
def test_create(self):
req_body = {
"endpoint": {
"region": "RegionOne",
"publicurl": "http://host-3:8774/v1.1/$(tenant_id)s",
"internalurl": "http://host-3:8774/v1.1/$(tenant_id)s",
"adminurl": "http://host-3:8774/v1.1/$(tenant_id)s",
"service_id": "e044e21",
}
}
resp_body = {
"endpoint": {
"adminurl": "http://host-3:8774/v1.1/$(tenant_id)s",
"region": "RegionOne",
"id": "1fd485b2ffd54f409a5ecd42cba11401",
"internalurl": "http://host-3:8774/v1.1/$(tenant_id)s",
"publicurl": "http://host-3:8774/v1.1/$(tenant_id)s",
}
}
self.stub_url(httpretty.POST, ['endpoints'], json=resp_body)
endpoint = self.client.endpoints.create(
region=req_body['endpoint']['region'],
publicurl=req_body['endpoint']['publicurl'],
adminurl=req_body['endpoint']['adminurl'],
internalurl=req_body['endpoint']['internalurl'],
service_id=req_body['endpoint']['service_id']
)
self.assertIsInstance(endpoint, endpoints.Endpoint)
self.assertRequestBodyIs(json=req_body)
@httpretty.activate
def test_delete(self):
self.stub_url(httpretty.DELETE, ['endpoints', '8f953'], status=204)
self.client.endpoints.delete('8f953')
@httpretty.activate
def test_list(self):
self.stub_url(httpretty.GET, ['endpoints'], json=self.TEST_ENDPOINTS)
endpoint_list = self.client.endpoints.list()
[self.assertIsInstance(r, endpoints.Endpoint)
for r in endpoint_list]

View File

@@ -1,66 +0,0 @@
# 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 httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import extensions
class ExtensionTests(utils.TestCase):
def setUp(self):
super(ExtensionTests, self).setUp()
self.TEST_EXTENSIONS = {
'extensions': {
"values": [
{
'name': 'OpenStack Keystone User CRUD',
'namespace': 'http://docs.openstack.org/'
'identity/api/ext/OS-KSCRUD/v1.0',
'updated': '2013-07-07T12:00:0-00:00',
'alias': 'OS-KSCRUD',
'description':
'OpenStack extensions to Keystone v2.0 API'
' enabling User Operations.',
'links':
'[{"href":'
'"https://github.com/openstack/identity-api", "type":'
' "text/html", "rel": "describedby"}]',
},
{
'name': 'OpenStack EC2 API',
'namespace': 'http://docs.openstack.org/'
'identity/api/ext/OS-EC2/v1.0',
'updated': '2013-09-07T12:00:0-00:00',
'alias': 'OS-EC2',
'description': 'OpenStack EC2 Credentials backend.',
'links': '[{"href":'
'"https://github.com/openstack/identity-api", "type":'
' "text/html", "rel": "describedby"}]',
}
]
}
}
@httpretty.activate
def test_list(self):
self.stub_url(httpretty.GET, ['extensions'], json=self.TEST_EXTENSIONS)
extensions_list = self.client.extensions.list()
self.assertEqual(2, len(extensions_list))
for extension in extensions_list:
self.assertIsInstance(extension, extensions.Extension)
self.assertIsNotNone(extension.alias)
self.assertIsNotNone(extension.description)
self.assertIsNotNone(extension.links)
self.assertIsNotNone(extension.name)
self.assertIsNotNone(extension.namespace)
self.assertIsNotNone(extension.updated)

View File

@@ -1,132 +0,0 @@
# 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 uuid
import httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import roles
class RoleTests(utils.TestCase):
def setUp(self):
super(RoleTests, self).setUp()
self.ADMIN_ROLE_ID = uuid.uuid4().hex
self.MEMBER_ROLE_ID = uuid.uuid4().hex
self.TEST_ROLES = {
"roles": {
"values": [
{
"name": "admin",
"id": self.ADMIN_ROLE_ID,
},
{
"name": "member",
"id": self.MEMBER_ROLE_ID,
}
],
},
}
@httpretty.activate
def test_create(self):
req_body = {
"role": {
"name": "sysadmin",
}
}
role_id = uuid.uuid4().hex
resp_body = {
"role": {
"name": "sysadmin",
"id": role_id,
}
}
self.stub_url(httpretty.POST, ['OS-KSADM', 'roles'], json=resp_body)
role = self.client.roles.create(req_body['role']['name'])
self.assertRequestBodyIs(json=req_body)
self.assertIsInstance(role, roles.Role)
self.assertEqual(role.id, role_id)
self.assertEqual(role.name, req_body['role']['name'])
@httpretty.activate
def test_delete(self):
self.stub_url(httpretty.DELETE,
['OS-KSADM', 'roles', self.ADMIN_ROLE_ID], status=204)
self.client.roles.delete(self.ADMIN_ROLE_ID)
@httpretty.activate
def test_get(self):
self.stub_url(httpretty.GET, ['OS-KSADM', 'roles', self.ADMIN_ROLE_ID],
json={'role': self.TEST_ROLES['roles']['values'][0]})
role = self.client.roles.get(self.ADMIN_ROLE_ID)
self.assertIsInstance(role, roles.Role)
self.assertEqual(role.id, self.ADMIN_ROLE_ID)
self.assertEqual(role.name, 'admin')
@httpretty.activate
def test_list(self):
self.stub_url(httpretty.GET, ['OS-KSADM', 'roles'],
json=self.TEST_ROLES)
role_list = self.client.roles.list()
[self.assertIsInstance(r, roles.Role) for r in role_list]
@httpretty.activate
def test_roles_for_user(self):
self.stub_url(httpretty.GET, ['users', 'foo', 'roles'],
json=self.TEST_ROLES)
role_list = self.client.roles.roles_for_user('foo')
[self.assertIsInstance(r, roles.Role) for r in role_list]
@httpretty.activate
def test_roles_for_user_tenant(self):
self.stub_url(httpretty.GET, ['tenants', 'barrr', 'users', 'foo',
'roles'], json=self.TEST_ROLES)
role_list = self.client.roles.roles_for_user('foo', 'barrr')
[self.assertIsInstance(r, roles.Role) for r in role_list]
@httpretty.activate
def test_add_user_role(self):
self.stub_url(httpretty.PUT, ['users', 'foo', 'roles', 'OS-KSADM',
'barrr'], status=204)
self.client.roles.add_user_role('foo', 'barrr')
@httpretty.activate
def test_add_user_role_tenant(self):
id_ = uuid.uuid4().hex
self.stub_url(httpretty.PUT, ['tenants', id_, 'users', 'foo', 'roles',
'OS-KSADM', 'barrr'], status=204)
self.client.roles.add_user_role('foo', 'barrr', id_)
@httpretty.activate
def test_remove_user_role(self):
self.stub_url(httpretty.DELETE, ['users', 'foo', 'roles', 'OS-KSADM',
'barrr'], status=204)
self.client.roles.remove_user_role('foo', 'barrr')
@httpretty.activate
def test_remove_user_role_tenant(self):
id_ = uuid.uuid4().hex
self.stub_url(httpretty.DELETE, ['tenants', id_, 'users', 'foo',
'roles', 'OS-KSADM', 'barrr'],
status=204)
self.client.roles.remove_user_role('foo', 'barrr', id_)

View File

@@ -1,175 +0,0 @@
# 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.
from keystoneclient import access
from keystoneclient import exceptions
from keystoneclient.tests.v2_0 import client_fixtures
from keystoneclient.tests.v2_0 import utils
class ServiceCatalogTest(utils.TestCase):
def setUp(self):
super(ServiceCatalogTest, self).setUp()
self.AUTH_RESPONSE_BODY = client_fixtures.auth_response_body()
def test_building_a_service_catalog(self):
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
self.assertEqual(sc.url_for(service_type='compute'),
"https://compute.north.host/v1/1234")
self.assertEqual(sc.url_for('tenantId', '1', service_type='compute'),
"https://compute.north.host/v1/1234")
self.assertEqual(sc.url_for('tenantId', '2', service_type='compute'),
"https://compute.north.host/v1.1/3456")
self.assertRaises(exceptions.EndpointNotFound, sc.url_for, "region",
"South", service_type='compute')
def test_service_catalog_endpoints(self):
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
public_ep = sc.get_endpoints(service_type='compute',
endpoint_type='publicURL')
self.assertEqual(public_ep['compute'][1]['tenantId'], '2')
self.assertEqual(public_ep['compute'][1]['versionId'], '1.1')
self.assertEqual(public_ep['compute'][1]['internalURL'],
"https://compute.north.host/v1.1/3456")
def test_service_catalog_regions(self):
self.AUTH_RESPONSE_BODY['access']['region_name'] = "North"
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
url = sc.url_for(service_type='image', endpoint_type='publicURL')
self.assertEqual(url, "https://image.north.host/v1/")
self.AUTH_RESPONSE_BODY['access']['region_name'] = "South"
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
url = sc.url_for(service_type='image', endpoint_type='internalURL')
self.assertEqual(url, "https://image-internal.south.host/v1/")
def test_service_catalog_empty(self):
self.AUTH_RESPONSE_BODY['access']['serviceCatalog'] = []
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
self.assertRaises(exceptions.EmptyCatalog,
auth_ref.service_catalog.url_for,
service_type='image',
endpoint_type='internalURL')
def test_service_catalog_get_endpoints_region_names(self):
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
endpoints = sc.get_endpoints(service_type='image', region_name='North')
self.assertEqual(len(endpoints), 1)
self.assertEqual(endpoints['image'][0]['publicURL'],
'https://image.north.host/v1/')
endpoints = sc.get_endpoints(service_type='image', region_name='South')
self.assertEqual(len(endpoints), 1)
self.assertEqual(endpoints['image'][0]['publicURL'],
'https://image.south.host/v1/')
endpoints = sc.get_endpoints(service_type='compute')
self.assertEqual(len(endpoints['compute']), 2)
endpoints = sc.get_endpoints(service_type='compute',
region_name='North')
self.assertEqual(len(endpoints['compute']), 2)
endpoints = sc.get_endpoints(service_type='compute',
region_name='West')
self.assertEqual(len(endpoints['compute']), 0)
def test_service_catalog_url_for_region_names(self):
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
url = sc.url_for(service_type='image', region_name='North')
self.assertEqual(url, 'https://image.north.host/v1/')
url = sc.url_for(service_type='image', region_name='South')
self.assertEqual(url, 'https://image.south.host/v1/')
url = sc.url_for(service_type='compute',
region_name='North',
attr='versionId',
filter_value='1.1')
self.assertEqual(url, 'https://compute.north.host/v1.1/3456')
self.assertRaises(exceptions.EndpointNotFound, sc.url_for,
service_type='image', region_name='West')
def test_servcie_catalog_get_url_region_names(self):
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
urls = sc.get_urls(service_type='image')
self.assertEqual(len(urls), 2)
urls = sc.get_urls(service_type='image', region_name='North')
self.assertEqual(len(urls), 1)
self.assertEqual(urls[0], 'https://image.north.host/v1/')
urls = sc.get_urls(service_type='image', region_name='South')
self.assertEqual(len(urls), 1)
self.assertEqual(urls[0], 'https://image.south.host/v1/')
urls = sc.get_urls(service_type='image', region_name='West')
self.assertIsNone(urls)
def test_service_catalog_param_overrides_body_region(self):
self.AUTH_RESPONSE_BODY['access']['region_name'] = "North"
auth_ref = access.AccessInfo.factory(None, self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
url = sc.url_for(service_type='image')
self.assertEqual(url, 'https://image.north.host/v1/')
url = sc.url_for(service_type='image', region_name='South')
self.assertEqual(url, 'https://image.south.host/v1/')
endpoints = sc.get_endpoints(service_type='image')
self.assertEqual(len(endpoints['image']), 1)
self.assertEqual(endpoints['image'][0]['publicURL'],
'https://image.north.host/v1/')
endpoints = sc.get_endpoints(service_type='image', region_name='South')
self.assertEqual(len(endpoints['image']), 1)
self.assertEqual(endpoints['image'][0]['publicURL'],
'https://image.south.host/v1/')
def test_service_catalog_service_name(self):
auth_ref = access.AccessInfo.factory(resp=None,
body=self.AUTH_RESPONSE_BODY)
sc = auth_ref.service_catalog
url = sc.url_for(service_name='Image Servers', endpoint_type='public',
service_type='image', region_name='North')
self.assertEqual('https://image.north.host/v1/', url)
self.assertRaises(exceptions.EndpointNotFound, sc.url_for,
service_name='Image Servers', service_type='compute')
urls = sc.get_urls(service_type='image', service_name='Image Servers',
endpoint_type='public')
self.assertIn('https://image.north.host/v1/', urls)
self.assertIn('https://image.south.host/v1/', urls)
urls = sc.get_urls(service_type='image', service_name='Servers',
endpoint_type='public')
self.assertIsNone(urls)

View File

@@ -1,105 +0,0 @@
# 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 uuid
import httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import services
class ServiceTests(utils.TestCase):
def setUp(self):
super(ServiceTests, self).setUp()
self.NOVA_SERVICE_ID = uuid.uuid4().hex
self.KEYSTONE_SERVICE_ID = uuid.uuid4().hex
self.TEST_SERVICES = {
"OS-KSADM:services": {
"values": [
{
"name": "nova",
"type": "compute",
"description": "Nova-compatible service.",
"id": self.NOVA_SERVICE_ID
},
{
"name": "keystone",
"type": "identity",
"description": "Keystone-compatible service.",
"id": self.KEYSTONE_SERVICE_ID
},
],
},
}
@httpretty.activate
def test_create(self):
req_body = {
"OS-KSADM:service": {
"name": "swift",
"type": "object-store",
"description": "Swift-compatible service.",
}
}
service_id = uuid.uuid4().hex
resp_body = {
"OS-KSADM:service": {
"name": "swift",
"type": "object-store",
"description": "Swift-compatible service.",
"id": service_id,
}
}
self.stub_url(httpretty.POST, ['OS-KSADM', 'services'], json=resp_body)
service = self.client.services.create(
req_body['OS-KSADM:service']['name'],
req_body['OS-KSADM:service']['type'],
req_body['OS-KSADM:service']['description'])
self.assertIsInstance(service, services.Service)
self.assertEqual(service.id, service_id)
self.assertEqual(service.name, req_body['OS-KSADM:service']['name'])
self.assertRequestBodyIs(json=req_body)
@httpretty.activate
def test_delete(self):
self.stub_url(httpretty.DELETE,
['OS-KSADM', 'services', self.NOVA_SERVICE_ID],
status=204)
self.client.services.delete(self.NOVA_SERVICE_ID)
@httpretty.activate
def test_get(self):
test_services = self.TEST_SERVICES['OS-KSADM:services']['values'][0]
self.stub_url(httpretty.GET,
['OS-KSADM', 'services', self.NOVA_SERVICE_ID],
json={'OS-KSADM:service': test_services})
service = self.client.services.get(self.NOVA_SERVICE_ID)
self.assertIsInstance(service, services.Service)
self.assertEqual(service.id, self.NOVA_SERVICE_ID)
self.assertEqual(service.name, 'nova')
self.assertEqual(service.type, 'compute')
@httpretty.activate
def test_list(self):
self.stub_url(httpretty.GET, ['OS-KSADM', 'services'],
json=self.TEST_SERVICES)
service_list = self.client.services.list()
[self.assertIsInstance(r, services.Service)
for r in service_list]

View File

@@ -1,361 +0,0 @@
# 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 os
import sys
import mock
from mox3 import stubout
import six
from testtools import matchers
from keystoneclient import httpclient
from keystoneclient.tests.v2_0 import fakes
from keystoneclient.tests.v2_0 import utils
DEFAULT_USERNAME = 'username'
DEFAULT_PASSWORD = 'password'
DEFAULT_TENANT_ID = 'tenant_id'
DEFAULT_TENANT_NAME = 'tenant_name'
DEFAULT_AUTH_URL = 'http://127.0.0.1:5000/v2.0/'
class ShellTests(utils.TestCase):
def setUp(self):
"""Patch os.environ to avoid required auth info."""
super(ShellTests, self).setUp()
self.stubs = stubout.StubOutForTesting()
self.fake_client = fakes.FakeHTTPClient()
self.stubs.Set(
httpclient.HTTPClient, "_cs_request",
lambda ign_self, *args, **kwargs:
self.fake_client._cs_request(*args, **kwargs))
self.stubs.Set(
httpclient.HTTPClient, "authenticate",
lambda cl_obj:
self.fake_client.authenticate(cl_obj))
self.old_environment = os.environ.copy()
os.environ = {
'OS_USERNAME': DEFAULT_USERNAME,
'OS_PASSWORD': DEFAULT_PASSWORD,
'OS_TENANT_ID': DEFAULT_TENANT_ID,
'OS_TENANT_NAME': DEFAULT_TENANT_NAME,
'OS_AUTH_URL': DEFAULT_AUTH_URL,
}
import keystoneclient.shell
self.shell = keystoneclient.shell.OpenStackIdentityShell()
def tearDown(self):
self.stubs.UnsetAll()
self.stubs.SmartUnsetAll()
os.environ = self.old_environment
self.fake_client.clear_callstack()
super(ShellTests, self).tearDown()
def run_command(self, cmd):
orig = sys.stdout
try:
sys.stdout = six.StringIO()
if isinstance(cmd, list):
self.shell.main(cmd)
else:
self.shell.main(cmd.split())
except SystemExit:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.assertEqual(exc_value.code, 0)
finally:
out = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = orig
return out
def assert_called(self, method, url, body=None, **kwargs):
return self.fake_client.assert_called(method, url, body, **kwargs)
def assert_called_anytime(self, method, url, body=None):
return self.fake_client.assert_called_anytime(method, url, body)
def test_user_list(self):
self.run_command('user-list')
self.fake_client.assert_called_anytime('GET', '/users')
def test_user_create(self):
self.run_command('user-create --name new-user')
self.fake_client.assert_called_anytime(
'POST', '/users',
{'user':
{'email': None,
'password': None,
'enabled': True,
'name': 'new-user',
'tenantId': None}})
@mock.patch('sys.stdin', autospec=True)
def test_user_create_password_prompt(self, mock_stdin):
with mock.patch('getpass.getpass') as mock_getpass:
mock_getpass.return_value = 'newpass'
self.run_command('user-create --name new-user --pass')
self.fake_client.assert_called_anytime(
'POST', '/users',
{'user':
{'email': None,
'password': 'newpass',
'enabled': True,
'name': 'new-user',
'tenantId': None}})
def test_user_get(self):
self.run_command('user-get 1')
self.fake_client.assert_called_anytime('GET', '/users/1')
def test_user_delete(self):
self.run_command('user-delete 1')
self.fake_client.assert_called_anytime('DELETE', '/users/1')
def test_user_password_update(self):
self.run_command('user-password-update --pass newpass 1')
self.fake_client.assert_called_anytime(
'PUT', '/users/1/OS-KSADM/password')
def test_user_update(self):
self.run_command('user-update --name new-user1'
' --email user@email.com --enabled true 1')
self.fake_client.assert_called_anytime(
'PUT', '/users/1',
{'user':
{'id': '1',
'email': 'user@email.com',
'enabled': True,
'name': 'new-user1'}
})
required = 'User not updated, no arguments present.'
out = self.run_command('user-update 1')
self.assertThat(out, matchers.MatchesRegex(required))
self.run_command(['user-update', '--email', '', '1'])
self.fake_client.assert_called_anytime(
'PUT', '/users/1',
{'user':
{'id': '1',
'email': ''}
})
def test_role_create(self):
self.run_command('role-create --name new-role')
self.fake_client.assert_called_anytime(
'POST', '/OS-KSADM/roles',
{"role": {"name": "new-role"}})
def test_role_get(self):
self.run_command('role-get 1')
self.fake_client.assert_called_anytime('GET', '/OS-KSADM/roles/1')
def test_role_list(self):
self.run_command('role-list')
self.fake_client.assert_called_anytime('GET', '/OS-KSADM/roles')
def test_role_delete(self):
self.run_command('role-delete 1')
self.fake_client.assert_called_anytime('DELETE', '/OS-KSADM/roles/1')
def test_user_role_add(self):
self.run_command('user-role-add --user_id 1 --role_id 1')
self.fake_client.assert_called_anytime(
'PUT', '/users/1/roles/OS-KSADM/1')
def test_user_role_list(self):
self.run_command('user-role-list --user_id 1 --tenant-id 1')
self.fake_client.assert_called_anytime(
'GET', '/tenants/1/users/1/roles')
self.run_command('user-role-list --user_id 1')
self.fake_client.assert_called_anytime(
'GET', '/tenants/1/users/1/roles')
self.run_command('user-role-list')
self.fake_client.assert_called_anytime(
'GET', '/tenants/1/users/1/roles')
def test_user_role_remove(self):
self.run_command('user-role-remove --user_id 1 --role_id 1')
self.fake_client.assert_called_anytime(
'DELETE', '/users/1/roles/OS-KSADM/1')
def test_tenant_create(self):
self.run_command('tenant-create --name new-tenant')
self.fake_client.assert_called_anytime(
'POST', '/tenants',
{"tenant": {"enabled": True,
"name": "new-tenant",
"description": None}})
def test_tenant_get(self):
self.run_command('tenant-get 2')
self.fake_client.assert_called_anytime('GET', '/tenants/2')
def test_tenant_list(self):
self.run_command('tenant-list')
self.fake_client.assert_called_anytime('GET', '/tenants')
def test_tenant_update(self):
self.run_command('tenant-update'
' --name new-tenant1 --enabled false'
' --description desc 2')
self.fake_client.assert_called_anytime(
'POST', '/tenants/2',
{"tenant":
{"enabled": False,
"id": "2",
"description": "desc",
"name": "new-tenant1"}})
required = 'Tenant not updated, no arguments present.'
out = self.run_command('tenant-update 1')
self.assertThat(out, matchers.MatchesRegex(required))
def test_tenant_delete(self):
self.run_command('tenant-delete 2')
self.fake_client.assert_called_anytime('DELETE', '/tenants/2')
def test_service_create(self):
self.run_command('service-create --name service1 --type compute')
self.fake_client.assert_called_anytime(
'POST', '/OS-KSADM/services',
{"OS-KSADM:service":
{"type": "compute",
"name": "service1",
"description": None}})
def test_service_get(self):
self.run_command('service-get 1')
self.fake_client.assert_called_anytime('GET', '/OS-KSADM/services/1')
def test_service_list(self):
self.run_command('service-list')
self.fake_client.assert_called_anytime('GET', '/OS-KSADM/services')
def test_service_delete(self):
self.run_command('service-delete 1')
self.fake_client.assert_called_anytime(
'DELETE', '/OS-KSADM/services/1')
def test_catalog(self):
self.run_command('catalog')
self.run_command('catalog --service compute')
def test_ec2_credentials_create(self):
self.run_command('ec2-credentials-create'
' --tenant-id 1 --user-id 1')
self.fake_client.assert_called_anytime(
'POST', '/users/1/credentials/OS-EC2',
{'tenant_id': '1'})
self.run_command('ec2-credentials-create --tenant-id 1')
self.fake_client.assert_called_anytime(
'POST', '/users/1/credentials/OS-EC2',
{'tenant_id': '1'})
self.run_command('ec2-credentials-create')
self.fake_client.assert_called_anytime(
'POST', '/users/1/credentials/OS-EC2',
{'tenant_id': '1'})
def test_ec2_credentials_delete(self):
self.run_command('ec2-credentials-delete --access 2 --user-id 1')
self.fake_client.assert_called_anytime(
'DELETE', '/users/1/credentials/OS-EC2/2')
self.run_command('ec2-credentials-delete --access 2')
self.fake_client.assert_called_anytime(
'DELETE', '/users/1/credentials/OS-EC2/2')
def test_ec2_credentials_list(self):
self.run_command('ec2-credentials-list --user-id 1')
self.fake_client.assert_called_anytime(
'GET', '/users/1/credentials/OS-EC2')
self.run_command('ec2-credentials-list')
self.fake_client.assert_called_anytime(
'GET', '/users/1/credentials/OS-EC2')
def test_ec2_credentials_get(self):
self.run_command('ec2-credentials-get --access 2 --user-id 1')
self.fake_client.assert_called_anytime(
'GET', '/users/1/credentials/OS-EC2/2')
def test_bootstrap(self):
self.run_command('bootstrap --user-name new-user'
' --pass 1 --role-name admin'
' --tenant-name new-tenant')
self.fake_client.assert_called_anytime(
'POST', '/users',
{'user':
{'email': None,
'password': '1',
'enabled': True,
'name': 'new-user',
'tenantId': None}})
self.run_command('bootstrap --user-name new-user'
' --pass 1 --role-name admin'
' --tenant-name new-tenant')
self.fake_client.assert_called_anytime(
'POST', '/tenants',
{"tenant": {"enabled": True,
"name": "new-tenant",
"description": None}})
self.run_command('bootstrap --user-name new-user'
' --pass 1 --role-name new-role'
' --tenant-name new-tenant')
self.fake_client.assert_called_anytime(
'POST', '/OS-KSADM/roles',
{"role": {"name": "new-role"}})
self.run_command('bootstrap --user-name'
' new-user --pass 1 --role-name admin'
' --tenant-name new-tenant')
self.fake_client.assert_called_anytime(
'PUT', '/tenants/1/users/1/roles/OS-KSADM/1')
def test_bash_completion(self):
self.run_command('bash-completion')
def test_help(self):
out = self.run_command('help')
required = 'usage: keystone'
self.assertThat(out, matchers.MatchesRegex(required))
def test_password_update(self):
self.run_command('password-update --current-password oldpass'
' --new-password newpass')
self.fake_client.assert_called_anytime(
'PATCH', '/OS-KSCRUD/users/1',
{'user':
{'original_password': 'oldpass',
'password': 'newpass'}})
def test_endpoint_create(self):
self.run_command('endpoint-create --service-id 1 '
'--publicurl=http://example.com:1234/go')
self.fake_client.assert_called_anytime(
'POST', '/endpoints',
{'endpoint':
{'adminurl': None,
'service_id': '1',
'region': 'regionOne',
'internalurl': None,
'publicurl': "http://example.com:1234/go"}})
def test_endpoint_list(self):
self.run_command('endpoint-list')
self.fake_client.assert_called_anytime('GET', '/endpoints')

View File

@@ -1,298 +0,0 @@
# 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 uuid
import httpretty
from keystoneclient import exceptions
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import tenants
class TenantTests(utils.TestCase):
def setUp(self):
super(TenantTests, self).setUp()
self.INVIS_ID = uuid.uuid4().hex
self.DEMO_ID = uuid.uuid4().hex
self.ADMIN_ID = uuid.uuid4().hex
self.EXTRAS_ID = uuid.uuid4().hex
self.TEST_TENANTS = {
"tenants": {
"values": [
{
"enabled": True,
"description": "A description change!",
"name": "invisible_to_admin",
"id": self.INVIS_ID,
},
{
"enabled": True,
"description": "None",
"name": "demo",
"id": self.DEMO_ID,
},
{
"enabled": True,
"description": "None",
"name": "admin",
"id": self.ADMIN_ID,
},
{
"extravalue01": "metadata01",
"enabled": True,
"description": "For testing extras",
"name": "test_extras",
"id": self.EXTRAS_ID,
}
],
"links": [],
},
}
@httpretty.activate
def test_create(self):
req_body = {
"tenant": {
"name": "tenantX",
"description": "Like tenant 9, but better.",
"enabled": True,
"extravalue01": "metadata01",
},
}
id_ = uuid.uuid4().hex
resp_body = {
"tenant": {
"name": "tenantX",
"enabled": True,
"id": id_,
"description": "Like tenant 9, but better.",
"extravalue01": "metadata01",
}
}
self.stub_url(httpretty.POST, ['tenants'], json=resp_body)
tenant = self.client.tenants.create(
req_body['tenant']['name'],
req_body['tenant']['description'],
req_body['tenant']['enabled'],
extravalue01=req_body['tenant']['extravalue01'],
name="don't overwrite priors")
self.assertIsInstance(tenant, tenants.Tenant)
self.assertEqual(tenant.id, id_)
self.assertEqual(tenant.name, "tenantX")
self.assertEqual(tenant.description, "Like tenant 9, but better.")
self.assertEqual(tenant.extravalue01, "metadata01")
self.assertRequestBodyIs(json=req_body)
@httpretty.activate
def test_duplicate_create(self):
req_body = {
"tenant": {
"name": "tenantX",
"description": "The duplicate tenant.",
"enabled": True
},
}
resp_body = {
"error": {
"message": "Conflict occurred attempting to store project.",
"code": 409,
"title": "Conflict",
}
}
self.stub_url(httpretty.POST, ['tenants'], status=409, json=resp_body)
def create_duplicate_tenant():
self.client.tenants.create(req_body['tenant']['name'],
req_body['tenant']['description'],
req_body['tenant']['enabled'])
self.assertRaises(exceptions.Conflict, create_duplicate_tenant)
@httpretty.activate
def test_delete(self):
self.stub_url(httpretty.DELETE, ['tenants', self.ADMIN_ID], status=204)
self.client.tenants.delete(self.ADMIN_ID)
@httpretty.activate
def test_get(self):
resp = {'tenant': self.TEST_TENANTS['tenants']['values'][2]}
self.stub_url(httpretty.GET, ['tenants', self.ADMIN_ID], json=resp)
t = self.client.tenants.get(self.ADMIN_ID)
self.assertIsInstance(t, tenants.Tenant)
self.assertEqual(t.id, self.ADMIN_ID)
self.assertEqual(t.name, 'admin')
@httpretty.activate
def test_list(self):
self.stub_url(httpretty.GET, ['tenants'], json=self.TEST_TENANTS)
tenant_list = self.client.tenants.list()
[self.assertIsInstance(t, tenants.Tenant) for t in tenant_list]
@httpretty.activate
def test_list_limit(self):
self.stub_url(httpretty.GET, ['tenants'], json=self.TEST_TENANTS)
tenant_list = self.client.tenants.list(limit=1)
self.assertQueryStringIs('limit=1')
[self.assertIsInstance(t, tenants.Tenant) for t in tenant_list]
@httpretty.activate
def test_list_marker(self):
self.stub_url(httpretty.GET, ['tenants'], json=self.TEST_TENANTS)
tenant_list = self.client.tenants.list(marker=1)
self.assertQueryStringIs('marker=1')
[self.assertIsInstance(t, tenants.Tenant) for t in tenant_list]
@httpretty.activate
def test_list_limit_marker(self):
self.stub_url(httpretty.GET, ['tenants'], json=self.TEST_TENANTS)
tenant_list = self.client.tenants.list(limit=1, marker=1)
self.assertQueryStringIs('marker=1&limit=1')
[self.assertIsInstance(t, tenants.Tenant) for t in tenant_list]
@httpretty.activate
def test_update(self):
req_body = {
"tenant": {
"id": self.EXTRAS_ID,
"name": "tenantX",
"description": "I changed you!",
"enabled": False,
"extravalue01": "metadataChanged",
#"extraname": "dontoverwrite!",
},
}
resp_body = {
"tenant": {
"name": "tenantX",
"enabled": False,
"id": self.EXTRAS_ID,
"description": "I changed you!",
"extravalue01": "metadataChanged",
},
}
self.stub_url(httpretty.POST, ['tenants', self.EXTRAS_ID],
json=resp_body)
tenant = self.client.tenants.update(
req_body['tenant']['id'],
req_body['tenant']['name'],
req_body['tenant']['description'],
req_body['tenant']['enabled'],
extravalue01=req_body['tenant']['extravalue01'],
name="don't overwrite priors")
self.assertIsInstance(tenant, tenants.Tenant)
self.assertRequestBodyIs(json=req_body)
self.assertEqual(tenant.id, self.EXTRAS_ID)
self.assertEqual(tenant.name, "tenantX")
self.assertEqual(tenant.description, "I changed you!")
self.assertFalse(tenant.enabled)
self.assertEqual(tenant.extravalue01, "metadataChanged")
@httpretty.activate
def test_update_empty_description(self):
req_body = {
"tenant": {
"id": self.EXTRAS_ID,
"name": "tenantX",
"description": "",
"enabled": False,
},
}
resp_body = {
"tenant": {
"name": "tenantX",
"enabled": False,
"id": self.EXTRAS_ID,
"description": "",
},
}
self.stub_url(httpretty.POST, ['tenants', self.EXTRAS_ID],
json=resp_body)
tenant = self.client.tenants.update(req_body['tenant']['id'],
req_body['tenant']['name'],
req_body['tenant']['description'],
req_body['tenant']['enabled'])
self.assertIsInstance(tenant, tenants.Tenant)
self.assertRequestBodyIs(json=req_body)
self.assertEqual(tenant.id, self.EXTRAS_ID)
self.assertEqual(tenant.name, "tenantX")
self.assertEqual(tenant.description, "")
self.assertFalse(tenant.enabled)
@httpretty.activate
def test_add_user(self):
self.stub_url(httpretty.PUT,
['tenants', self.EXTRAS_ID, 'users', 'foo', 'roles',
'OS-KSADM', 'barrr'],
status=204)
self.client.tenants.add_user(self.EXTRAS_ID, 'foo', 'barrr')
@httpretty.activate
def test_remove_user(self):
self.stub_url(httpretty.DELETE, ['tenants', self.EXTRAS_ID, 'users',
'foo', 'roles', 'OS-KSADM', 'barrr'],
status=204)
self.client.tenants.remove_user(self.EXTRAS_ID, 'foo', 'barrr')
@httpretty.activate
def test_tenant_add_user(self):
self.stub_url(httpretty.PUT, ['tenants', self.EXTRAS_ID, 'users',
'foo', 'roles', 'OS-KSADM', 'barrr'],
status=204)
req_body = {
"tenant": {
"id": self.EXTRAS_ID,
"name": "tenantX",
"description": "I changed you!",
"enabled": False,
},
}
# make tenant object with manager
tenant = self.client.tenants.resource_class(self.client.tenants,
req_body['tenant'])
tenant.add_user('foo', 'barrr')
self.assertIsInstance(tenant, tenants.Tenant)
@httpretty.activate
def test_tenant_remove_user(self):
self.stub_url(httpretty.DELETE, ['tenants', self.EXTRAS_ID, 'users',
'foo', 'roles', 'OS-KSADM', 'barrr'],
status=204)
req_body = {
"tenant": {
"id": self.EXTRAS_ID,
"name": "tenantX",
"description": "I changed you!",
"enabled": False,
},
}
# make tenant object with manager
tenant = self.client.tenants.resource_class(self.client.tenants,
req_body['tenant'])
tenant.remove_user('foo', 'barrr')
self.assertIsInstance(tenant, tenants.Tenant)

View File

@@ -1,25 +0,0 @@
# 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 uuid
import httpretty
from keystoneclient.tests.v2_0 import utils
class TokenTests(utils.TestCase):
@httpretty.activate
def test_delete(self):
id_ = uuid.uuid4().hex
self.stub_url(httpretty.DELETE, ['tokens', id_], status=204)
self.client.tokens.delete(id_)

View File

@@ -1,237 +0,0 @@
# 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 uuid
import httpretty
from keystoneclient.tests.v2_0 import utils
from keystoneclient.v2_0 import users
class UserTests(utils.TestCase):
def setUp(self):
super(UserTests, self).setUp()
self.ADMIN_USER_ID = uuid.uuid4().hex
self.DEMO_USER_ID = uuid.uuid4().hex
self.TEST_USERS = {
"users": {
"values": [
{
"email": "None",
"enabled": True,
"id": self.ADMIN_USER_ID,
"name": "admin",
},
{
"email": "None",
"enabled": True,
"id": self.DEMO_USER_ID,
"name": "demo",
},
]
}
}
@httpretty.activate
def test_create(self):
tenant_id = uuid.uuid4().hex
user_id = uuid.uuid4().hex
req_body = {
"user": {
"name": "gabriel",
"password": "test",
"tenantId": tenant_id,
"email": "test@example.com",
"enabled": True,
}
}
resp_body = {
"user": {
"name": "gabriel",
"enabled": True,
"tenantId": tenant_id,
"id": user_id,
"password": "test",
"email": "test@example.com",
}
}
self.stub_url(httpretty.POST, ['users'], json=resp_body)
user = self.client.users.create(req_body['user']['name'],
req_body['user']['password'],
req_body['user']['email'],
tenant_id=req_body['user']['tenantId'],
enabled=req_body['user']['enabled'])
self.assertIsInstance(user, users.User)