c90977b4f6
As part of the move towards testr and parallel test running, we start to use testtools and fixtures to make the test suite resilient and more pedantic. Part of blueprint grizzly-testtools Change-Id: I90250de9fe21237db34f6a50b89b15863e270aa5
342 lines
13 KiB
Python
342 lines
13 KiB
Python
# Copyright (C) 2009-2012 Nicira Networks, 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.
|
|
|
|
import httplib
|
|
import logging
|
|
import new
|
|
import random
|
|
|
|
import eventlet
|
|
from eventlet.green import urllib2
|
|
from mock import Mock
|
|
from mock import patch
|
|
import testtools
|
|
|
|
from quantum.plugins.nicira.nicira_nvp_plugin.api_client import (
|
|
client_eventlet as nace,
|
|
request_eventlet as nare,
|
|
)
|
|
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
LOG = logging.getLogger("test_nvp_api_request_eventlet")
|
|
|
|
|
|
REQUEST_TIMEOUT = 1
|
|
|
|
|
|
def fetch(url):
|
|
return urllib2.urlopen(url).read()
|
|
|
|
|
|
class NvpApiRequestEventletTest(testtools.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
super(NvpApiRequestEventletTest, self).setUp()
|
|
self.client = nace.NvpApiClientEventlet(
|
|
[("127.0.0.1", 4401, True)], "admin", "admin")
|
|
self.url = "/ws.v1/_debug"
|
|
self.req = nare.NvpApiRequestEventlet(self.client, self.url)
|
|
|
|
def tearDown(self):
|
|
self.client = None
|
|
self.req = None
|
|
super(NvpApiRequestEventletTest, self).tearDown()
|
|
|
|
def test_construct_eventlet_api_request(self):
|
|
e = nare.NvpApiRequestEventlet(self.client, self.url)
|
|
self.assertTrue(e is not None)
|
|
|
|
def test_apirequest_spawn(self):
|
|
def x(id):
|
|
eventlet.greenthread.sleep(random.random())
|
|
LOG.info('spawned: %d' % id)
|
|
|
|
for i in range(10):
|
|
nare.NvpApiRequestEventlet._spawn(x, i)
|
|
|
|
def test_apirequest_start(self):
|
|
for i in range(10):
|
|
a = nare.NvpApiRequestEventlet(
|
|
self.client, self.url, request_timeout=0.1)
|
|
a._handle_request = Mock()
|
|
a.start()
|
|
eventlet.greenthread.sleep(0.1)
|
|
logging.info('_handle_request called: %s' %
|
|
a._handle_request.called)
|
|
nare.NvpApiRequestEventlet.joinall()
|
|
|
|
def test_join_with_handle_request(self):
|
|
self.req._handle_request = Mock()
|
|
self.req.start()
|
|
self.req.join()
|
|
self.assertTrue(self.req._handle_request.called)
|
|
|
|
def test_join_without_handle_request(self):
|
|
self.req._handle_request = Mock()
|
|
self.req.join()
|
|
self.assertFalse(self.req._handle_request.called)
|
|
|
|
def test_copy(self):
|
|
req = self.req.copy()
|
|
for att in [
|
|
'_api_client', '_url', '_method', '_body', '_headers',
|
|
'_http_timeout', '_request_timeout', '_retries',
|
|
'_redirects', '_auto_login']:
|
|
self.assertTrue(getattr(req, att) is getattr(self.req, att))
|
|
|
|
def test_request_error(self):
|
|
self.assertTrue(self.req.request_error is None)
|
|
|
|
def test_run_and_handle_request(self):
|
|
self.req._request_timeout = None
|
|
self.req._handle_request = Mock()
|
|
self.req.start()
|
|
self.req.join()
|
|
self.assertTrue(self.req._handle_request.called)
|
|
|
|
def test_run_and_timeout(self):
|
|
def my_handle_request(self):
|
|
LOG.info('my_handle_request() self: %s' % self)
|
|
LOG.info('my_handle_request() dir(self): %s' % dir(self))
|
|
eventlet.greenthread.sleep(REQUEST_TIMEOUT * 2)
|
|
|
|
self.req._request_timeout = REQUEST_TIMEOUT
|
|
self.req._handle_request = new.instancemethod(
|
|
my_handle_request, self.req, nare.NvpApiRequestEventlet)
|
|
self.req.start()
|
|
self.assertTrue(self.req.join() is None)
|
|
|
|
def prep_issue_request(self):
|
|
mysock = Mock()
|
|
mysock.gettimeout.return_value = 4242
|
|
|
|
myresponse = Mock()
|
|
myresponse.read.return_value = 'body'
|
|
myresponse.getheaders.return_value = 'headers'
|
|
myresponse.status = httplib.MOVED_PERMANENTLY
|
|
|
|
myconn = Mock()
|
|
myconn.request.return_value = None
|
|
myconn.sock = mysock
|
|
myconn.getresponse.return_value = myresponse
|
|
myconn.__str__ = Mock()
|
|
myconn.__str__.return_value = 'myconn string'
|
|
|
|
req = self.req
|
|
req._redirect_params = Mock()
|
|
req._redirect_params.return_value = (myconn, 'url')
|
|
req._request_str = Mock()
|
|
req._request_str.return_value = 'http://cool/cool'
|
|
|
|
client = self.client
|
|
client.need_login = False
|
|
client._auto_login = False
|
|
client._auth_cookie = False
|
|
client.acquire_connection = Mock()
|
|
client.acquire_connection.return_value = myconn
|
|
client.release_connection = Mock()
|
|
|
|
return (mysock, myresponse, myconn)
|
|
|
|
def test_issue_request_trigger_exception(self):
|
|
(mysock, myresponse, myconn) = self.prep_issue_request()
|
|
self.client.acquire_connection.return_value = None
|
|
|
|
self.req._issue_request()
|
|
LOG.info('request_error: %s' % self.req._request_error)
|
|
self.assertTrue(isinstance(self.req._request_error, Exception))
|
|
self.assertTrue(self.client.acquire_connection.called)
|
|
|
|
def test_issue_request_handle_none_sock(self):
|
|
(mysock, myresponse, myconn) = self.prep_issue_request()
|
|
myconn.sock = None
|
|
self.req.start()
|
|
self.assertTrue(self.req.join() is None)
|
|
self.assertTrue(self.client.acquire_connection.called)
|
|
|
|
def test_issue_request_exceed_maximum_retries(self):
|
|
(mysock, myresponse, myconn) = self.prep_issue_request()
|
|
self.req.start()
|
|
self.assertTrue(self.req.join() is None)
|
|
self.assertTrue(self.client.acquire_connection.called)
|
|
|
|
def test_issue_request_trigger_non_redirect(self):
|
|
(mysock, myresponse, myconn) = self.prep_issue_request()
|
|
myresponse.status = httplib.OK
|
|
self.req.start()
|
|
self.assertTrue(self.req.join() is None)
|
|
self.assertTrue(self.client.acquire_connection.called)
|
|
|
|
def test_issue_request_trigger_internal_server_error(self):
|
|
(mysock, myresponse, myconn) = self.prep_issue_request()
|
|
self.req._redirect_params.return_value = (myconn, None)
|
|
self.req.start()
|
|
self.assertTrue(self.req.join() is None)
|
|
self.assertTrue(self.client.acquire_connection.called)
|
|
|
|
def test_redirect_params_break_on_location(self):
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', None)])
|
|
self.assertTrue(retval is None)
|
|
|
|
def test_redirect_params_parse_a_url(self):
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', '/path/a/b/c')])
|
|
self.assertTrue(retval is not None)
|
|
|
|
def test_redirect_params_invalid_redirect_location(self):
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', '+path/a/b/c')])
|
|
self.assertTrue(retval is None)
|
|
|
|
def test_redirect_params_invalid_scheme(self):
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', 'invalidscheme://hostname:1/path')])
|
|
self.assertTrue(retval is None)
|
|
|
|
def test_redirect_params_setup_https_with_cooki(self):
|
|
with patch('quantum.plugins.nicira.nicira_nvp_plugin.api_client.'
|
|
'client_eventlet.NvpApiClientEventlet') as mock:
|
|
api_client = mock.return_value
|
|
self.req._api_client = api_client
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', 'https://host:1/path')])
|
|
|
|
self.assertTrue(retval is not None)
|
|
self.assertTrue(api_client.acquire_redirect_connection.called)
|
|
|
|
def test_redirect_params_setup_htttps_and_query(self):
|
|
with patch('quantum.plugins.nicira.nicira_nvp_plugin.api_client.'
|
|
'client_eventlet.NvpApiClientEventlet') as mock:
|
|
api_client = mock.return_value
|
|
self.req._api_client = api_client
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(myconn, [
|
|
('location', 'https://host:1/path?q=1')])
|
|
|
|
self.assertTrue(retval is not None)
|
|
self.assertTrue(api_client.acquire_redirect_connection.called)
|
|
|
|
def test_redirect_params_setup_https_connection_no_cookie(self):
|
|
with patch('quantum.plugins.nicira.nicira_nvp_plugin.api_client.'
|
|
'client_eventlet.NvpApiClientEventlet') as mock:
|
|
api_client = mock.return_value
|
|
self.req._api_client = api_client
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(myconn, [
|
|
('location', 'https://host:1/path')])
|
|
|
|
self.assertTrue(retval is not None)
|
|
self.assertTrue(api_client.acquire_redirect_connection.called)
|
|
|
|
def test_redirect_params_setup_https_and_query_no_cookie(self):
|
|
with patch('quantum.plugins.nicira.nicira_nvp_plugin.api_client.'
|
|
'client_eventlet.NvpApiClientEventlet') as mock:
|
|
api_client = mock.return_value
|
|
self.req._api_client = api_client
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(
|
|
myconn, [('location', 'https://host:1/path?q=1')])
|
|
self.assertTrue(retval is not None)
|
|
self.assertTrue(api_client.acquire_redirect_connection.called)
|
|
|
|
def test_redirect_params_path_only_with_query(self):
|
|
with patch('quantum.plugins.nicira.nicira_nvp_plugin.api_client.'
|
|
'client_eventlet.NvpApiClientEventlet') as mock:
|
|
api_client = mock.return_value
|
|
api_client.wait_for_login.return_value = None
|
|
api_client.auth_cookie = None
|
|
api_client.acquire_connection.return_value = True
|
|
myconn = Mock()
|
|
(conn, retval) = self.req._redirect_params(myconn, [
|
|
('location', '/path?q=1')])
|
|
self.assertTrue(retval is not None)
|
|
|
|
def test_handle_request_auto_login(self):
|
|
self.req._auto_login = True
|
|
self.req._api_client = Mock()
|
|
self.req._api_client.need_login = True
|
|
self.req._request_str = Mock()
|
|
self.req._request_str.return_value = 'http://cool/cool'
|
|
self.req.spawn = Mock()
|
|
self.req._handle_request()
|
|
|
|
def test_handle_request_auto_login_unauth(self):
|
|
self.req._auto_login = True
|
|
self.req._api_client = Mock()
|
|
self.req._api_client.need_login = True
|
|
self.req._request_str = Mock()
|
|
self.req._request_str.return_value = 'http://cool/cool'
|
|
|
|
import socket
|
|
resp = httplib.HTTPResponse(socket.socket())
|
|
resp.status = httplib.UNAUTHORIZED
|
|
mywaiter = Mock()
|
|
mywaiter.wait = Mock()
|
|
mywaiter.wait.return_value = resp
|
|
self.req.spawn = Mock(return_value=mywaiter)
|
|
self.req._handle_request()
|
|
|
|
# NvpLoginRequestEventlet tests.
|
|
def test_construct_eventlet_login_request(self):
|
|
r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password')
|
|
self.assertTrue(r is not None)
|
|
|
|
def test_session_cookie_session_cookie_retrieval(self):
|
|
r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password')
|
|
r.successful = Mock()
|
|
r.successful.return_value = True
|
|
r.value = Mock()
|
|
r.value.get_header = Mock()
|
|
r.value.get_header.return_value = 'cool'
|
|
self.assertTrue(r.session_cookie() is not None)
|
|
|
|
def test_session_cookie_not_retrieved(self):
|
|
r = nare.NvpLoginRequestEventlet(self.client, 'user', 'password')
|
|
r.successful = Mock()
|
|
r.successful.return_value = False
|
|
r.value = Mock()
|
|
r.value.get_header = Mock()
|
|
r.value.get_header.return_value = 'cool'
|
|
self.assertTrue(r.session_cookie() is None)
|
|
|
|
# NvpGetApiProvidersRequestEventlet tests.
|
|
def test_construct_eventlet_get_api_providers_request(self):
|
|
r = nare.NvpGetApiProvidersRequestEventlet(self.client)
|
|
self.assertTrue(r is not None)
|
|
|
|
def test_api_providers_none_api_providers(self):
|
|
r = nare.NvpGetApiProvidersRequestEventlet(self.client)
|
|
r.successful = Mock(return_value=False)
|
|
self.assertTrue(r.api_providers() is None)
|
|
|
|
def test_api_providers_non_none_api_providers(self):
|
|
r = nare.NvpGetApiProvidersRequestEventlet(self.client)
|
|
r.value = Mock()
|
|
r.value.body = """{
|
|
"results": [
|
|
{ "roles": [
|
|
{ "role": "api_provider",
|
|
"listen_addr": "pssl:1.1.1.1:1" }]}]}"""
|
|
r.successful = Mock(return_value=True)
|
|
LOG.info('%s' % r.api_providers())
|
|
self.assertTrue(r.api_providers() is not None)
|