This fixes the spell fix by; $ tox -e codespell -- -q 2 -S '*.csv,*.po,*.yaml' -w Change-Id: I11a3142d6eef40bec2324b98bfe4b0d871779f64
288 lines
12 KiB
Python
288 lines
12 KiB
Python
# Copyright (c) 2010-2015 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 unittest
|
|
from unittest import mock
|
|
|
|
from swift.common.swob import Request, HTTPOk, HTTPCreated
|
|
from storlets.swift_middleware.handlers import StorletObjectHandler
|
|
|
|
from tests.unit.swift_middleware.handlers import \
|
|
BaseTestStorletMiddleware, create_handler_config
|
|
|
|
|
|
class TestStorletMiddlewareObject(BaseTestStorletMiddleware):
|
|
def setUp(self):
|
|
super(TestStorletMiddlewareObject, self).setUp(exec_server='object')
|
|
|
|
def test_load_app(self):
|
|
try:
|
|
self.get_app(self.base_app, self.conf)
|
|
except Exception:
|
|
self.fail('Application loading got an error')
|
|
|
|
def test_call_unsupported_method(self):
|
|
def call(method):
|
|
path = '/sda1/p/AUTH_a/c/o'
|
|
headers = {'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'}
|
|
req = Request.blank(path, environ={'REQUEST_METHOD': method},
|
|
headers=headers)
|
|
resp = self.get_response(req)
|
|
self.assertEqual('405 Method Not Allowed', resp.status)
|
|
|
|
for method in ('POST', 'PUT', 'DELETE'):
|
|
call(method)
|
|
|
|
def test_PUT_objet_into_storlets_container(self):
|
|
target = '/sda1/p/AUTH_a/storlet/storlet-1.0.jar'
|
|
self.base_app.register('PUT', target, HTTPCreated)
|
|
|
|
sheaders = {'X-Object-Meta-Storlet-Language': 'Java',
|
|
'X-Object-Meta-Storlet-Interface-Version': '1.0',
|
|
'X-Object-Meta-Storlet-Dependency': 'dependency',
|
|
'X-Object-Meta-Storlet-Main':
|
|
'org.openstack.storlet.Storlet'}
|
|
req = Request.blank(target, environ={'REQUEST_METHOD': 'PUT'},
|
|
headers=sheaders)
|
|
resp = self.get_response(req)
|
|
self.assertEqual('201 Created', resp.status)
|
|
|
|
def test_GET_without_storlets(self):
|
|
def basic_get(path):
|
|
req = Request.blank(
|
|
path, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0'})
|
|
self.base_app.register('GET', path, HTTPOk, body=b'FAKE APP')
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'FAKE APP', resp.body)
|
|
self.base_app.reset_all()
|
|
|
|
for target in ('/sda1/p/AUTH_a', '/sda1/p/AUTH_a/c',
|
|
'/sda1/p/AUTH_a/c/o'):
|
|
basic_get(target)
|
|
|
|
def test_GET_with_storlets(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk, body=b'FAKE APP')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'FAKE APP', resp.body)
|
|
|
|
def test_GET_with_storlets_and_http_range(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk, body=b'FAKE APP')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'Range': 'bytes=10-20'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('416 Requested Range Not Satisfiable',
|
|
resp.status)
|
|
|
|
def test_GET_with_storlets_and_storlet_range(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk, body=b'FAKE APP')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'X-Storlet-Range': 'bytes=1-6',
|
|
'Range': 'bytes=1-6'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'AKE AP', resp.body)
|
|
self.assertEqual('bytes 1-6/8',
|
|
resp.headers.get('Storlet-Input-Range'))
|
|
|
|
def test_GET_with_storlets_and_storlet_proxy_range(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk, body=b'FAKE APP')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'X-Storlet-Range': 'bytes=1-6',
|
|
'Range': 'bytes=1-6',
|
|
'X-Storlet-Run-On-Proxy': ''})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('206 Partial Content', resp.status)
|
|
self.assertEqual(b'AKE AP', resp.body)
|
|
self.assertEqual('bytes 1-6/8',
|
|
resp.headers.get('Content-Range'))
|
|
|
|
def test_GET_slo_manifest_with_storlets(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk,
|
|
headers={'X-Static-Large-Object': 'True'},
|
|
body=b'FAKE MANIFEST')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'FAKE MANIFEST', resp.body)
|
|
|
|
def test_GET_slo_segment_with_storlets(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register('GET', target, HTTPOk,
|
|
headers={'X-Static-Large-Object': 'True'},
|
|
body=b'FAKE SEGMENT')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'multipart-manifest': 'get',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'FAKE SEGMENT', resp.body)
|
|
|
|
def test_GET_symlink_with_storlets(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
self.base_app.register(
|
|
'GET', target, HTTPOk,
|
|
headers={'X-Object-Sysmeta-Symlink-Target': 'c/o2'},
|
|
body=b'FAKE CONTENT')
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('200 OK', resp.status)
|
|
self.assertEqual(b'FAKE CONTENT', resp.body)
|
|
|
|
def test_storlets_with_invalid_method(self):
|
|
target = '/sda1/p/AUTH_a/c/o'
|
|
|
|
req = Request.blank(
|
|
target, environ={'REQUEST_METHOD': '_parse_vaco'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
resp = self.get_response(req)
|
|
self.assertEqual('405 Method Not Allowed', resp.status)
|
|
|
|
|
|
class TestStorletObjectHandler(unittest.TestCase):
|
|
def setUp(self):
|
|
self.handler_class = StorletObjectHandler
|
|
self.conf = create_handler_config('object')
|
|
self.gateway_conf = {}
|
|
|
|
def test_init_handler(self):
|
|
req = Request.blank(
|
|
'/dev/part/acc/cont/obj', environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
handler = self.handler_class(
|
|
req, self.conf, self.gateway_conf, mock.MagicMock(),
|
|
mock.MagicMock())
|
|
# FIXME: still hold api version 0 at ObjectHandler but will be
|
|
# deprecated if it's never used.
|
|
self.assertEqual('0', handler.api_version)
|
|
self.assertEqual('acc', handler.account)
|
|
self.assertEqual('cont', handler.container)
|
|
self.assertEqual('obj', handler.obj)
|
|
|
|
req = Request.blank(
|
|
'/dev/part/acc2/cont2/obj2', environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar'})
|
|
handler.request = req
|
|
self.assertEqual('/dev/part/acc2/cont2/obj2', handler.request.path)
|
|
self.assertEqual('0', handler.api_version)
|
|
self.assertEqual('acc2', handler.account)
|
|
self.assertEqual('cont2', handler.container)
|
|
self.assertEqual('obj2', handler.obj)
|
|
|
|
# no direct assignment allowed
|
|
with self.assertRaises(AttributeError):
|
|
handler.api_version = '1'
|
|
|
|
with self.assertRaises(AttributeError):
|
|
handler.account = 'acc'
|
|
|
|
with self.assertRaises(AttributeError):
|
|
handler.container = 'cont'
|
|
|
|
with self.assertRaises(AttributeError):
|
|
handler.obj = 'obj'
|
|
|
|
def test_get_storlet_invocation_options(self):
|
|
req = Request.blank(
|
|
'/dev/part/acc/cont/obj',
|
|
environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'X-Storlet-Foo': 'baa'})
|
|
handler = self.handler_class(
|
|
req, self.conf, self.gateway_conf, mock.MagicMock(),
|
|
mock.MagicMock())
|
|
|
|
options = handler._get_storlet_invocation_options(req)
|
|
self.assertEqual('baa', options['storlet_foo'])
|
|
self.assertFalse(options['generate_log'])
|
|
|
|
req = Request.blank(
|
|
'/dev/part/acc/cont/obj',
|
|
environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'X-Storlet-Foo': 'baa',
|
|
'X-Storlet-Generate-Log': 'True'})
|
|
handler = self.handler_class(
|
|
req, self.conf, self.gateway_conf, mock.MagicMock(),
|
|
mock.MagicMock())
|
|
|
|
options = handler._get_storlet_invocation_options(req)
|
|
self.assertEqual('baa', options['storlet_foo'])
|
|
self.assertTrue(options['generate_log'])
|
|
|
|
req = Request.blank(
|
|
'/dev/part/acc/cont/obj',
|
|
environ={'REQUEST_METHOD': 'GET'},
|
|
headers={'X-Backend-Storage-Policy-Index': '0',
|
|
'X-Run-Storlet': 'Storlet-1.0.jar',
|
|
'X-Storlet-Foo': 'baa',
|
|
'X-Storlet-Range': 'bytes=1-6',
|
|
'Range': 'bytes=1-6'})
|
|
handler = self.handler_class(
|
|
req, self.conf, self.gateway_conf, mock.MagicMock(),
|
|
mock.MagicMock())
|
|
|
|
options = handler._get_storlet_invocation_options(req)
|
|
self.assertEqual('baa', options['storlet_foo'])
|
|
self.assertFalse(options['generate_log'])
|
|
self.assertNotIn('storlet_range', options)
|
|
self.assertEqual(1, options['range_start'])
|
|
self.assertEqual(7, options['range_end'])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|