manila/manila/tests/share/drivers/nexenta/ns5/test_jsonrpc.py

1179 lines
42 KiB
Python

# Copyright 2019 Nexenta by DDN, Inc.
# 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.
"""
Unit tests for NexentaStor 5 REST API helper
"""
import copy
import hashlib
import json
import posixpath
from unittest import mock
from urllib import parse as urlparse
import uuid
import requests
from manila.share import configuration as conf
from manila.share.drivers.nexenta.ns5 import jsonrpc
from manila import test
class FakeNefProxy(object):
def __init__(self):
self.scheme = 'https'
self.port = 8443
self.hosts = ['1.1.1.1', '2.2.2.2']
self.host = self.hosts[0]
self.root = 'pool/share'
self.username = 'username'
self.password = 'password'
self.retries = 3
self.timeout = 5
self.session = mock.Mock()
self.session.headers = {}
def __getattr__(self, name):
pass
def delay(self, interval):
pass
def delete_bearer(self):
pass
def update_lock(self):
pass
def update_token(self, token):
pass
def update_host(self, host):
pass
def url(self, path):
return '%s://%s:%s/%s' % (self.scheme, self.host, self.port, path)
class TestNefException(test.TestCase):
def test_message(self):
message = 'test message 1'
result = jsonrpc.NefException(message)
self.assertIn(message, result.msg)
def test_message_kwargs(self):
code = 'EAGAIN'
message = 'test message 2'
result = jsonrpc.NefException(message, code=code)
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
def test_no_message_kwargs(self):
code = 'ESRCH'
message = 'test message 3'
result = jsonrpc.NefException(None, code=code, message=message)
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
def test_message_plus_kwargs(self):
code = 'ENODEV'
message1 = 'test message 4'
message2 = 'test message 5'
result = jsonrpc.NefException(message1, code=code, message=message2)
self.assertEqual(code, result.code)
self.assertIn(message2, result.msg)
def test_dict(self):
code = 'ENOENT'
message = 'test message 4'
result = jsonrpc.NefException({'code': code, 'message': message})
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
def test_kwargs(self):
code = 'EPERM'
message = 'test message 5'
result = jsonrpc.NefException(code=code, message=message)
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
def test_dict_kwargs(self):
code = 'EINVAL'
message = 'test message 6'
result = jsonrpc.NefException({'code': code}, message=message)
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
def test_defaults(self):
code = 'EBADMSG'
message = 'NexentaError'
result = jsonrpc.NefException()
self.assertEqual(code, result.code)
self.assertIn(message, result.msg)
class TestNefRequest(test.TestCase):
def setUp(self):
super(TestNefRequest, self).setUp()
self.proxy = FakeNefProxy()
def fake_response(self, method, path, payload, code, content):
request = requests.PreparedRequest()
request.method = method
request.url = self.proxy.url(path)
request.headers = {'Content-Type': 'application/json'}
request.body = None
if method in ['get', 'delete']:
request.params = payload
elif method in ['put', 'post']:
request.data = json.dumps(payload)
response = requests.Response()
response.request = request
response.status_code = code
response._content = json.dumps(content) if content else ''
return response
def test___call___invalid_method(self):
method = 'unsupported'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
self.assertRaises(jsonrpc.NefException, instance, path)
def test___call___none_path(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
self.assertRaises(jsonrpc.NefException, instance, None)
def test___call___empty_path(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
self.assertRaises(jsonrpc.NefException, instance, '')
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___get(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {}
content = {'name': 'snapshot'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
request.assert_called_with(method, path)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___get_payload(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'name': 'snapshot'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
params = {'params': payload}
request.assert_called_with(method, path, **params)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___get_data_payload(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
data = [
{
'name': 'fs1',
'path': 'pool/fs1'
},
{
'name': 'fs2',
'path': 'pool/fs2'
}
]
content = {'data': data}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
instance.data = data
result = instance(path, payload)
params = {'params': payload}
request.assert_called_with(method, path, **params)
self.assertEqual(data, result)
def test___call___get_invalid_payload(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = 'bad data'
self.assertRaises(jsonrpc.NefException, instance, path, payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___delete(self, request):
method = 'delete'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {}
content = {'name': 'snapshot'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
request.assert_called_with(method, path)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___delete_payload(self, request):
method = 'delete'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'name': 'snapshot'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
params = {'params': payload}
request.assert_called_with(method, path, **params)
self.assertEqual(content, result)
def test___call___delete_invalid_payload(self):
method = 'delete'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = 'bad data'
self.assertRaises(jsonrpc.NefException, instance, path, payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___post(self, request):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {}
content = None
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
request.assert_called_with(method, path)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___post_payload(self, request):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = None
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
params = {'data': json.dumps(payload)}
request.assert_called_with(method, path, **params)
self.assertEqual(content, result)
def test___call___post_invalid_payload(self):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = 'bad data'
self.assertRaises(jsonrpc.NefException, instance, path, payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___put(self, request):
method = 'put'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {}
content = None
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
request.assert_called_with(method, path)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___put_payload(self, request):
method = 'put'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = None
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance(path, payload)
params = {'data': json.dumps(payload)}
request.assert_called_with(method, path, **params)
self.assertEqual(content, result)
def test___call___put_invalid_payload(self):
method = 'put'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = 'bad data'
self.assertRaises(jsonrpc.NefException, instance, path, payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___non_ok_response(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'ENOENT', 'message': 'error'}
response = self.fake_response(method, path, payload, 500, content)
request.return_value = response
self.assertRaises(jsonrpc.NefException, instance, path, payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.failover')
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___request_after_failover(self, request, failover):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = None
response = self.fake_response(method, path, payload, 200, content)
request.side_effect = [requests.exceptions.Timeout, response]
failover.return_value = True
result = instance(path, payload)
params = {'data': json.dumps(payload)}
request.assert_called_with(method, path, **params)
self.assertEqual(content, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.failover')
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test___call___request_failover_error(self, request, failover):
method = 'put'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
request.side_effect = requests.exceptions.Timeout
failover.return_value = False
self.assertRaises(requests.exceptions.Timeout, instance, path, payload)
def test_hook_default(self):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'name': 'dataset'}
response = self.fake_response(method, path, payload, 303, content)
result = instance.hook(response)
self.assertEqual(response, result)
def test_hook_200_empty(self):
method = 'delete'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'storage/filesystems'
payload = {'force': True}
content = None
response = self.fake_response(method, path, payload, 200, content)
result = instance.hook(response)
self.assertEqual(response, result)
def test_hook_201_empty(self):
method = 'post'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'storage/snapshots'
payload = {'path': 'parent/child@name'}
content = None
response = self.fake_response(method, path, payload, 201, content)
result = instance.hook(response)
self.assertEqual(response, result)
def test_hook_500_empty(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'storage/pools'
payload = {'poolName': 'tank'}
content = None
response = self.fake_response(method, path, payload, 500, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
def test_hook_200_bad_content(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'storage/volumes'
payload = {'name': 'test'}
content = None
response = self.fake_response(method, path, payload, 200, content)
response._content = 'bad_content'
self.assertRaises(jsonrpc.NefException, instance.hook, response)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.auth')
def test_hook_401(self, auth, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'EAUTH'}
response = self.fake_response(method, path, payload, 401, content)
auth.return_value = True
content2 = {'name': 'test'}
response2 = self.fake_response(method, path, payload, 200, content2)
request.return_value = response2
self.proxy.session.send.return_value = content2
result = instance.hook(response)
self.assertEqual(content2, result)
def test_hook_401_max_retries(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
instance.stat[401] = self.proxy.retries
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'EAUTH'}
response = self.fake_response(method, path, payload, 401, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
def test_hook_404_nested(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
instance.lock = True
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'ENOENT'}
response = self.fake_response(method, path, payload, 404, content)
result = instance.hook(response)
self.assertEqual(response, result)
def test_hook_404_max_retries(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
instance.stat[404] = self.proxy.retries
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'ENOENT'}
response = self.fake_response(method, path, payload, 404, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.failover')
def test_hook_404_failover_error(self, failover):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'ENOENT'}
response = self.fake_response(method, path, payload, 404, content)
failover.return_value = False
result = instance.hook(response)
self.assertEqual(response, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.failover')
def test_hook_404_failover_ok(self, failover, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'ENOENT'}
response = self.fake_response(method, path, payload, 404, content)
failover.return_value = True
content2 = {'name': 'test'}
response2 = self.fake_response(method, path, payload, 200, content2)
request.return_value = response2
result = instance.hook(response)
self.assertEqual(response2, result)
def test_hook_500_permanent(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'EINVAL'}
response = self.fake_response(method, path, payload, 500, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
def test_hook_500_busy_max_retries(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
instance.stat[500] = self.proxy.retries
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'EBUSY'}
response = self.fake_response(method, path, payload, 500, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_hook_500_busy_ok(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'code': 'EBUSY'}
response = self.fake_response(method, path, payload, 500, content)
content2 = {'name': 'test'}
response2 = self.fake_response(method, path, payload, 200, content2)
request.return_value = response2
result = instance.hook(response)
self.assertEqual(response2, result)
def test_hook_201_no_monitor(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'monitor': 'unknown'}
response = self.fake_response(method, path, payload, 202, content)
self.assertRaises(jsonrpc.NefException, instance.hook, response)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_hook_201_ok(self, request):
method = 'delete'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {
'links': [{
'rel': 'monitor',
'href': '/jobStatus/jobID'
}]
}
response = self.fake_response(method, path, payload, 202, content)
content2 = None
response2 = self.fake_response(method, path, payload, 201, content2)
request.return_value = response2
result = instance.hook(response)
self.assertEqual(response2, result)
def test_200_no_data(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'name': 'test'}
response = self.fake_response(method, path, payload, 200, content)
result = instance.hook(response)
self.assertEqual(response, result)
def test_200_pagination_end(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {'data': 'value'}
response = self.fake_response(method, path, payload, 200, content)
result = instance.hook(response)
self.assertEqual(response, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_200_pagination_next(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
content = {
'data': [{
'name': 'test'
}],
'links': [{
'rel': 'next',
'href': path
}]
}
response = self.fake_response(method, path, payload, 200, content)
response2 = self.fake_response(method, path, payload, 200, content)
request.return_value = response2
result = instance.hook(response)
self.assertEqual(response2, result)
def test_request(self):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = 'parent/child'
payload = {'key': 'value'}
expected = {'name': 'dataset'}
url = self.proxy.url(path)
kwargs = payload.copy()
kwargs['timeout'] = self.proxy.timeout
kwargs['hooks'] = {'response': instance.hook}
self.proxy.session.request.return_value = expected
result = instance.request(method, path, **payload)
self.proxy.session.request.assert_called_with(method, url, **kwargs)
self.assertEqual(expected, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_auth(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
method = 'post'
path = 'auth/login'
payload = {
'data': json.dumps({
'username': self.proxy.username,
'password': self.proxy.password
})
}
content = {'token': 'test'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
instance.auth()
request.assert_called_once_with(method, path, **payload)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_auth_error(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
method = 'post'
path = 'auth/login'
payload = {
'data': json.dumps({
'username': self.proxy.username,
'password': self.proxy.password
})
}
content = {'data': 'noauth'}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
self.assertRaises(jsonrpc.NefException, instance.auth)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_failover(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = self.proxy.root
payload = {}
content = {'path': path}
response = self.fake_response(method, path, payload, 200, content)
request.return_value = response
result = instance.failover()
request.assert_called_once_with(method, path)
expected = True
self.assertEqual(expected, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_failover_timeout(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = self.proxy.root
payload = {}
content = {'path': path}
response = self.fake_response(method, path, payload, 200, content)
request.side_effect = [requests.exceptions.Timeout, response]
result = instance.failover()
request.assert_called_once_with(method, path)
expected = False
self.assertEqual(expected, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_failover_404(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = self.proxy.root
payload = {}
content = {}
response = self.fake_response(method, path, payload, 404, content)
request.side_effect = [response, response]
result = instance.failover()
request.assert_called_once_with(method, path)
expected = False
self.assertEqual(expected, result)
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefRequest.request')
def test_failover_error(self, request):
method = 'get'
instance = jsonrpc.NefRequest(self.proxy, method)
path = self.proxy.root
request.side_effect = [
requests.exceptions.Timeout,
requests.exceptions.ConnectionError
]
result = instance.failover()
request.assert_called_with(method, path)
expected = False
self.assertEqual(expected, result)
def test_getpath(self):
method = 'get'
rel = 'monitor'
href = 'jobStatus/jobID'
content = {
'links': [
[1, 2],
'bad link',
{
'rel': 'next',
'href': href
},
{
'rel': rel,
'href': href
}
]
}
instance = jsonrpc.NefRequest(self.proxy, method)
result = instance.getpath(content, rel)
expected = href
self.assertEqual(expected, result)
def test_getpath_no_content(self):
method = 'get'
rel = 'next'
content = None
instance = jsonrpc.NefRequest(self.proxy, method)
result = instance.getpath(content, rel)
self.assertIsNone(result)
def test_getpath_no_links(self):
method = 'get'
rel = 'next'
content = {'a': 'b'}
instance = jsonrpc.NefRequest(self.proxy, method)
result = instance.getpath(content, rel)
self.assertIsNone(result)
def test_getpath_no_rel(self):
method = 'get'
rel = 'next'
content = {
'links': [
{
'rel': 'monitor',
'href': '/jobs/jobID'
}
]
}
instance = jsonrpc.NefRequest(self.proxy, method)
result = instance.getpath(content, rel)
self.assertIsNone(result)
def test_getpath_no_href(self):
method = 'get'
rel = 'next'
content = {
'links': [
{
'rel': rel
}
]
}
instance = jsonrpc.NefRequest(self.proxy, method)
result = instance.getpath(content, rel)
self.assertIsNone(result)
class TestNefCollections(test.TestCase):
def setUp(self):
super(TestNefCollections, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefCollections(self.proxy)
def test_path(self):
path = 'path/to/item name + - & # $ = 0'
result = self.instance.path(path)
quoted_path = urlparse.quote_plus(path)
expected = posixpath.join(self.instance.root, quoted_path)
self.assertEqual(expected, result)
def test_get(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = {'name': 'dataset'}
path = self.instance.path(name)
self.proxy.get.return_value = expected
result = self.instance.get(name, payload)
self.proxy.get.assert_called_with(path, payload)
self.assertEqual(expected, result)
def test_set(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
self.proxy.put.return_value = expected
result = self.instance.set(name, payload)
self.proxy.put.assert_called_with(path, payload)
self.assertIsNone(result)
def test_list(self):
payload = {'key': 'value'}
expected = [{'name': 'dataset'}]
self.proxy.get.return_value = expected
result = self.instance.list(payload)
self.proxy.get.assert_called_with(self.instance.root, payload)
self.assertEqual(expected, result)
def test_create(self):
payload = {'key': 'value'}
expected = None
self.proxy.post.return_value = expected
result = self.instance.create(payload)
self.proxy.post.assert_called_with(self.instance.root, payload)
self.assertIsNone(result)
def test_create_exist(self):
payload = {'key': 'value'}
self.proxy.post.side_effect = jsonrpc.NefException(code='EEXIST')
result = self.instance.create(payload)
self.proxy.post.assert_called_with(self.instance.root, payload)
self.assertIsNone(result)
def test_create_error(self):
payload = {'key': 'value'}
self.proxy.post.side_effect = jsonrpc.NefException(code='EBUSY')
self.assertRaises(jsonrpc.NefException, self.instance.create, payload)
self.proxy.post.assert_called_with(self.instance.root, payload)
def test_delete(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
self.proxy.delete.return_value = expected
result = self.instance.delete(name, payload)
self.proxy.delete.assert_called_with(path, payload)
self.assertIsNone(result)
def test_delete_not_found(self):
name = 'parent/child'
payload = {'key': 'value'}
path = self.instance.path(name)
self.proxy.delete.side_effect = jsonrpc.NefException(code='ENOENT')
result = self.instance.delete(name, payload)
self.proxy.delete.assert_called_with(path, payload)
self.assertIsNone(result)
def test_delete_error(self):
name = 'parent/child'
payload = {'key': 'value'}
path = self.instance.path(name)
self.proxy.delete.side_effect = jsonrpc.NefException(code='EINVAL')
self.assertRaises(jsonrpc.NefException, self.instance.delete, name,
payload)
self.proxy.delete.assert_called_with(path, payload)
class TestNefSettings(test.TestCase):
def setUp(self):
super(TestNefSettings, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefSettings(self.proxy)
def test_create(self):
payload = {'key': 'value'}
result = self.instance.create(payload)
expected = NotImplemented
self.assertEqual(expected, result)
def test_delete(self):
name = 'parent/child'
payload = {'key': 'value'}
result = self.instance.delete(name, payload)
expected = NotImplemented
self.assertEqual(expected, result)
class TestNefDatasets(test.TestCase):
def setUp(self):
super(TestNefDatasets, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefDatasets(self.proxy)
def test_rename(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'rename')
self.proxy.post.return_value = expected
result = self.instance.rename(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
class TestNefSnapshots(test.TestCase):
def setUp(self):
super(TestNefSnapshots, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefSnapshots(self.proxy)
def test_clone(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'clone')
self.proxy.post.return_value = expected
result = self.instance.clone(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
class TestNefFilesystems(test.TestCase):
def setUp(self):
super(TestNefFilesystems, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefFilesystems(self.proxy)
def test_mount(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'mount')
self.proxy.post.return_value = expected
result = self.instance.mount(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
def test_unmount(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'unmount')
self.proxy.post.return_value = expected
result = self.instance.unmount(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
def test_acl(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'acl')
self.proxy.post.return_value = expected
result = self.instance.acl(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
def test_promote(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'promote')
self.proxy.post.return_value = expected
result = self.instance.promote(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
def test_rollback(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = self.instance.path(name)
path = posixpath.join(path, 'rollback')
self.proxy.post.return_value = expected
result = self.instance.rollback(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
class TestNefHpr(test.TestCase):
def setUp(self):
super(TestNefHpr, self).setUp()
self.proxy = mock.Mock()
self.instance = jsonrpc.NefHpr(self.proxy)
def test_activate(self):
payload = {'key': 'value'}
expected = None
path = posixpath.join(self.instance.root, 'activate')
self.proxy.post.return_value = expected
result = self.instance.activate(payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
def test_start(self):
name = 'parent/child'
payload = {'key': 'value'}
expected = None
path = posixpath.join(self.instance.path(name), 'start')
self.proxy.post.return_value = expected
result = self.instance.start(name, payload)
self.proxy.post.assert_called_with(path, payload)
self.assertIsNone(result)
class TestNefProxy(test.TestCase):
def setUp(self):
super(TestNefProxy, self).setUp()
self.cfg = mock.Mock(spec=conf.Configuration)
self.cfg.nexenta_use_https = True
self.cfg.nexenta_ssl_cert_verify = True
self.cfg.nexenta_user = 'user'
self.cfg.nexenta_password = 'pass'
self.cfg.nexenta_rest_addresses = ['1.1.1.1', '2.2.2.2']
self.cfg.nexenta_rest_port = 8443
self.cfg.nexenta_rest_backoff_factor = 1
self.cfg.nexenta_rest_retry_count = 3
self.cfg.nexenta_rest_connect_timeout = 1
self.cfg.nexenta_rest_read_timeout = 1
self.cfg.nexenta_nas_host = '3.3.3.3'
self.cfg.nexenta_folder = 'pool/path/to/share'
self.nef_mock = mock.Mock()
self.mock_object(jsonrpc, 'NefRequest')
self.proto = 'nfs'
self.proxy = jsonrpc.NefProxy(self.proto,
self.cfg.nexenta_folder,
self.cfg)
def test___init___http(self):
proto = 'nfs'
cfg = copy.copy(self.cfg)
cfg.nexenta_use_https = False
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
def test___init___no_rest_port_http(self):
proto = 'nfs'
cfg = copy.copy(self.cfg)
cfg.nexenta_rest_port = 0
cfg.nexenta_use_https = False
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
def test___init___no_rest_port_https(self):
proto = 'nfs'
cfg = copy.copy(self.cfg)
cfg.nexenta_rest_port = 0
cfg.nexenta_use_https = True
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
def test___init___iscsi(self):
proto = 'iscsi'
cfg = copy.copy(self.cfg)
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
def test___init___nfs_no_rest_address(self):
proto = 'nfs'
cfg = copy.copy(self.cfg)
cfg.nexenta_rest_addresses = ''
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
def test___init___iscsi_no_rest_address(self):
proto = 'iscsi'
cfg = copy.copy(self.cfg)
cfg.nexenta_rest_addresses = ''
cfg.nexenta_nas_host = '4.4.4.4'
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
self.assertIsInstance(result, jsonrpc.NefProxy)
@mock.patch('requests.packages.urllib3.disable_warnings')
def test___init___no_ssl_cert_verify(self, disable_warnings):
proto = 'nfs'
cfg = copy.copy(self.cfg)
cfg.nexenta_ssl_cert_verify = False
disable_warnings.return_value = None
result = jsonrpc.NefProxy(proto, cfg.nexenta_folder, cfg)
disable_warnings.assert_called()
self.assertIsInstance(result, jsonrpc.NefProxy)
def test_delete_bearer(self):
self.assertIsNone(self.proxy.delete_bearer())
self.assertNotIn('Authorization', self.proxy.session.headers)
self.proxy.session.headers['Authorization'] = 'Bearer token'
self.assertIsNone(self.proxy.delete_bearer())
self.assertNotIn('Authorization', self.proxy.session.headers)
def test_update_bearer(self):
token = 'token'
bearer = 'Bearer %s' % token
self.assertNotIn('Authorization', self.proxy.session.headers)
self.assertIsNone(self.proxy.update_bearer(token))
self.assertIn('Authorization', self.proxy.session.headers)
self.assertEqual(self.proxy.session.headers['Authorization'], bearer)
def test_update_token(self):
token = 'token'
bearer = 'Bearer %s' % token
self.assertIsNone(self.proxy.update_token(token))
self.assertEqual(self.proxy.tokens[self.proxy.host], token)
self.assertEqual(self.proxy.session.headers['Authorization'], bearer)
def test_update_host(self):
token = 'token'
bearer = 'Bearer %s' % token
host = self.cfg.nexenta_rest_addresses[0]
self.proxy.tokens[host] = token
self.assertIsNone(self.proxy.update_host(host))
self.assertEqual(self.proxy.session.headers['Authorization'], bearer)
def test_skip_update_host(self):
host = 'nonexistent'
self.assertIsNone(self.proxy.update_host(host))
@mock.patch('manila.share.drivers.nexenta.ns5.'
'jsonrpc.NefSettings.get')
def test_update_lock(self, get_settings):
guid = uuid.uuid4().hex
settings = {'value': guid}
get_settings.return_value = settings
self.assertIsNone(self.proxy.update_lock())
path = '%s:%s' % (guid, self.proxy.path)
if isinstance(path, str):
path = path.encode('utf-8')
expected = hashlib.md5(path).hexdigest()
self.assertEqual(expected, self.proxy.lock)
def test_url(self):
path = '/path/to/api'
result = self.proxy.url(path)
expected = '%s://%s:%s%s' % (self.proxy.scheme,
self.proxy.host,
self.proxy.port,
path)
self.assertEqual(expected, result)
@mock.patch('eventlet.greenthread.sleep')
def test_delay(self, sleep):
sleep.return_value = None
for attempt in range(0, 10):
expected = int(self.proxy.backoff_factor * (2 ** (attempt - 1)))
self.assertIsNone(self.proxy.delay(attempt))
sleep.assert_called_with(expected)