Browse Source

Add scope information when getting session from Keystone

Also add some unit tests for creating function from swift.

Change-Id: I05f9e7e36028d7f3b4365a6ced0740dc95b0ce86
Story: 2003012
Task: 23031
changes/20/583420/3
Lingxian Kong 3 years ago
parent
commit
69a61e5b55
7 changed files with 144 additions and 4 deletions
  1. +5
    -0
      qinling/exceptions.py
  2. +40
    -0
      qinling/tests/unit/api/controllers/v1/test_function.py
  3. +0
    -0
      qinling/tests/unit/utils/__init__.py
  4. +0
    -0
      qinling/tests/unit/utils/openstack/__init__.py
  5. +85
    -0
      qinling/tests/unit/utils/openstack/test_swift.py
  6. +2
    -0
      qinling/utils/openstack/keystone.py
  7. +12
    -4
      qinling/utils/openstack/swift.py

+ 5
- 0
qinling/exceptions.py View File

@ -111,3 +111,8 @@ class OrchestratorException(QinlingException):
class TrustFailedException(QinlingException):
http_code = 500
message = "Trust operation failed."
class SwiftException(QinlingException):
http_code = 500
message = "Failed to communicate with Swift."

+ 40
- 0
qinling/tests/unit/api/controllers/v1/test_function.py View File

@ -15,6 +15,7 @@
from datetime import datetime
import json
import tempfile
import uuid
import mock
from oslo_config import cfg
@ -62,6 +63,45 @@ class TestFunctionController(base.APITest):
)
self._assertDictContainsSubset(resp.json, body)
@mock.patch("qinling.utils.openstack.keystone.create_trust")
@mock.patch('qinling.utils.openstack.keystone.get_swiftclient')
@mock.patch('qinling.context.AuthHook.before')
def test_post_from_swift(self, mock_auth, mock_client, mock_trust):
self.override_config('auth_enable', True, group='pecan')
swift_conn = mock.Mock()
mock_client.return_value = swift_conn
swift_conn.head_object.return_value = {
'accept-ranges': 'bytes',
'content-length': str(constants.MAX_PACKAGE_SIZE - 1)
}
mock_trust.return_value.id = str(uuid.uuid4())
body = {
'name': 'swift_function',
'code': json.dumps(
{
"source": "swift",
"swift": {"container": "container", "object": "object"}
}
),
'runtime_id': self.runtime_id,
}
resp = self.app.post('/v1/functions', params=body)
self.assertEqual(201, resp.status_int)
body.update(
{
'entry': 'main.main',
'code': {
"source": "swift",
"swift": {"container": "container", "object": "object"}
}
}
)
self._assertDictContainsSubset(resp.json, body)
@mock.patch('qinling.utils.openstack.keystone.get_swiftclient')
@mock.patch('qinling.context.AuthHook.before')
def test_post_swift_size_exceed(self, mock_auth, mock_client):


+ 0
- 0
qinling/tests/unit/utils/__init__.py View File


+ 0
- 0
qinling/tests/unit/utils/openstack/__init__.py View File


+ 85
- 0
qinling/tests/unit/utils/openstack/test_swift.py View File

@ -0,0 +1,85 @@
# Copyright 2018 Catalyst IT Limited
#
# 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 swiftclient.exceptions import ClientException
from qinling import exceptions as exc
from qinling.tests.unit import base
from qinling.utils import constants
from qinling.utils.openstack import swift
class TestSwift(base.BaseTest):
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_check_object(self, mock_sclient):
length = constants.MAX_PACKAGE_SIZE - 1
mock_sclient.return_value.head_object.return_value = {
"content-length": length
}
ret = swift.check_object("fake_container", "fake_object")
self.assertTrue(ret)
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_check_object_client_exception(self, mock_sclient):
mock_sclient.return_value.head_object.side_effect = ClientException
ret = swift.check_object("fake_container", "fake_object")
self.assertFalse(ret)
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_check_object_other_exception(self, mock_sclient):
mock_sclient.return_value.head_object.side_effect = Exception
ret = swift.check_object("fake_container", "fake_object")
self.assertFalse(ret)
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_check_object_invalid_length(self, mock_sclient):
length = constants.MAX_PACKAGE_SIZE + 1
mock_sclient.return_value.head_object.return_value = {
"content-length": length
}
ret = swift.check_object("fake_container", "fake_object")
self.assertFalse(ret)
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_download_object(self, mock_sclient):
mock_get = mock.MagicMock()
mock_get.return_value = (mock.ANY, mock.ANY)
mock_sclient.return_value.get_object = mock_get
swift.download_object("fake_container", "fake_object")
mock_get.assert_called_once_with(
"fake_container", "fake_object",
resp_chunk_size=65536
)
@mock.patch("qinling.utils.openstack.keystone.get_swiftclient")
def test_download_object_exception(self, mock_sclient):
mock_sclient.return_value.get_object.side_effect = Exception
self.assertRaises(
exc.SwiftException,
swift.download_object,
"fake_container",
"fake_object"
)

+ 2
- 0
qinling/utils/openstack/keystone.py View File

@ -32,6 +32,8 @@ def _get_user_keystone_session():
auth = v3.Token(
auth_url=CONF.keystone_authtoken.www_authenticate_uri,
token=ctx.auth_token,
project_domain_name=CONF.keystone_authtoken.project_domain_name,
project_name=ctx.project_name
)
return session.Session(auth=auth, verify=False)


+ 12
- 4
qinling/utils/openstack/swift.py View File

@ -15,6 +15,7 @@
from oslo_log import log as logging
from swiftclient.exceptions import ClientException
from qinling import exceptions as exc
from qinling.utils import common
from qinling.utils import constants
from qinling.utils.openstack import keystone
@ -42,6 +43,9 @@ def check_object(container, object):
'The object %s in container %s was not found', object, container
)
return False
except Exception:
LOG.exception("Error when communicating with Swift.")
return False
if int(header['content-length']) > constants.MAX_PACKAGE_SIZE:
LOG.error('Object size is greater than %s', constants.MAX_PACKAGE_SIZE)
@ -54,9 +58,13 @@ def check_object(container, object):
def download_object(container, object):
swift_conn = keystone.get_swiftclient()
# Specify 'resp_chunk_size' here to return a file reader.
_, obj_reader = swift_conn.get_object(
container, object, resp_chunk_size=65536
)
try:
# Specify 'resp_chunk_size' here to return a file reader.
_, obj_reader = swift_conn.get_object(
container, object, resp_chunk_size=65536
)
except Exception:
LOG.exception("Error when downloading object from Swift.")
raise exc.SwiftException()
return obj_reader

Loading…
Cancel
Save