summaryrefslogtreecommitdiff
path: root/nova/tests/unit/test_wsgi.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests/unit/test_wsgi.py')
-rw-r--r--nova/tests/unit/test_wsgi.py263
1 files changed, 263 insertions, 0 deletions
diff --git a/nova/tests/unit/test_wsgi.py b/nova/tests/unit/test_wsgi.py
new file mode 100644
index 0000000000..0a08a7651f
--- /dev/null
+++ b/nova/tests/unit/test_wsgi.py
@@ -0,0 +1,263 @@
+# Copyright 2011 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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 `nova.wsgi`."""
+
+import os.path
+import tempfile
+import urllib2
+
+import eventlet
+import eventlet.wsgi
+import mock
+from oslo.config import cfg
+import requests
+import testtools
+import webob
+
+import nova.exception
+from nova import test
+from nova.tests.unit import utils
+import nova.wsgi
+
+SSL_CERT_DIR = os.path.normpath(os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ 'ssl_cert'))
+CONF = cfg.CONF
+
+
+class TestLoaderNothingExists(test.NoDBTestCase):
+ """Loader tests where os.path.exists always returns False."""
+
+ def setUp(self):
+ super(TestLoaderNothingExists, self).setUp()
+ self.stubs.Set(os.path, 'exists', lambda _: False)
+
+ def test_relpath_config_not_found(self):
+ self.flags(api_paste_config='api-paste.ini')
+ self.assertRaises(
+ nova.exception.ConfigNotFound,
+ nova.wsgi.Loader,
+ )
+
+ def test_asbpath_config_not_found(self):
+ self.flags(api_paste_config='/etc/nova/api-paste.ini')
+ self.assertRaises(
+ nova.exception.ConfigNotFound,
+ nova.wsgi.Loader,
+ )
+
+
+class TestLoaderNormalFilesystem(test.NoDBTestCase):
+ """Loader tests with normal filesystem (unmodified os.path module)."""
+
+ _paste_config = """
+[app:test_app]
+use = egg:Paste#static
+document_root = /tmp
+ """
+
+ def setUp(self):
+ super(TestLoaderNormalFilesystem, self).setUp()
+ self.config = tempfile.NamedTemporaryFile(mode="w+t")
+ self.config.write(self._paste_config.lstrip())
+ self.config.seek(0)
+ self.config.flush()
+ self.loader = nova.wsgi.Loader(self.config.name)
+
+ def test_config_found(self):
+ self.assertEqual(self.config.name, self.loader.config_path)
+
+ def test_app_not_found(self):
+ self.assertRaises(
+ nova.exception.PasteAppNotFound,
+ self.loader.load_app,
+ "nonexistent app",
+ )
+
+ def test_app_found(self):
+ url_parser = self.loader.load_app("test_app")
+ self.assertEqual("/tmp", url_parser.directory)
+
+ def tearDown(self):
+ self.config.close()
+ super(TestLoaderNormalFilesystem, self).tearDown()
+
+
+class TestWSGIServer(test.NoDBTestCase):
+ """WSGI server tests."""
+
+ def test_no_app(self):
+ server = nova.wsgi.Server("test_app", None)
+ self.assertEqual("test_app", server.name)
+
+ def test_custom_max_header_line(self):
+ self.flags(max_header_line=4096) # Default value is 16384.
+ nova.wsgi.Server("test_custom_max_header_line", None)
+ self.assertEqual(CONF.max_header_line, eventlet.wsgi.MAX_HEADER_LINE)
+
+ def test_start_random_port(self):
+ server = nova.wsgi.Server("test_random_port", None,
+ host="127.0.0.1", port=0)
+ server.start()
+ self.assertNotEqual(0, server.port)
+ server.stop()
+ server.wait()
+
+ @testtools.skipIf(not utils.is_ipv6_supported(), "no ipv6 support")
+ def test_start_random_port_with_ipv6(self):
+ server = nova.wsgi.Server("test_random_port", None,
+ host="::1", port=0)
+ server.start()
+ self.assertEqual("::1", server.host)
+ self.assertNotEqual(0, server.port)
+ server.stop()
+ server.wait()
+
+ def test_server_pool_waitall(self):
+ # test pools waitall method gets called while stopping server
+ server = nova.wsgi.Server("test_server", None,
+ host="127.0.0.1", port=4444)
+ server.start()
+ with mock.patch.object(server._pool,
+ 'waitall') as mock_waitall:
+ server.stop()
+ server.wait()
+ mock_waitall.assert_called_once_with()
+
+ def test_uri_length_limit(self):
+ server = nova.wsgi.Server("test_uri_length_limit", None,
+ host="127.0.0.1", max_url_len=16384)
+ server.start()
+
+ uri = "http://127.0.0.1:%d/%s" % (server.port, 10000 * 'x')
+ resp = requests.get(uri, proxies={"http": ""})
+ eventlet.sleep(0)
+ self.assertNotEqual(resp.status_code,
+ requests.codes.REQUEST_URI_TOO_LARGE)
+
+ uri = "http://127.0.0.1:%d/%s" % (server.port, 20000 * 'x')
+ resp = requests.get(uri, proxies={"http": ""})
+ eventlet.sleep(0)
+ self.assertEqual(resp.status_code,
+ requests.codes.REQUEST_URI_TOO_LARGE)
+ server.stop()
+ server.wait()
+
+ def test_reset_pool_size_to_default(self):
+ server = nova.wsgi.Server("test_resize", None,
+ host="127.0.0.1", max_url_len=16384)
+ server.start()
+
+ # Stopping the server, which in turn sets pool size to 0
+ server.stop()
+ self.assertEqual(server._pool.size, 0)
+
+ # Resetting pool size to default
+ server.reset()
+ server.start()
+ self.assertEqual(server._pool.size, CONF.wsgi_default_pool_size)
+
+
+class TestWSGIServerWithSSL(test.NoDBTestCase):
+ """WSGI server with SSL tests."""
+
+ def setUp(self):
+ super(TestWSGIServerWithSSL, self).setUp()
+ self.flags(enabled_ssl_apis=['fake_ssl'],
+ ssl_cert_file=os.path.join(SSL_CERT_DIR, 'certificate.crt'),
+ ssl_key_file=os.path.join(SSL_CERT_DIR, 'privatekey.key'))
+
+ def test_ssl_server(self):
+
+ def test_app(env, start_response):
+ start_response('200 OK', {})
+ return ['PONG']
+
+ fake_ssl_server = nova.wsgi.Server("fake_ssl", test_app,
+ host="127.0.0.1", port=0,
+ use_ssl=True)
+ fake_ssl_server.start()
+ self.assertNotEqual(0, fake_ssl_server.port)
+
+ cli = eventlet.connect(("localhost", fake_ssl_server.port))
+ cli = eventlet.wrap_ssl(cli,
+ ca_certs=os.path.join(SSL_CERT_DIR, 'ca.crt'))
+
+ cli.write('POST / HTTP/1.1\r\nHost: localhost\r\n'
+ 'Connection: close\r\nContent-length:4\r\n\r\nPING')
+ response = cli.read(8192)
+ self.assertEqual(response[-4:], "PONG")
+
+ fake_ssl_server.stop()
+ fake_ssl_server.wait()
+
+ def test_two_servers(self):
+
+ def test_app(env, start_response):
+ start_response('200 OK', {})
+ return ['PONG']
+
+ fake_ssl_server = nova.wsgi.Server("fake_ssl", test_app,
+ host="127.0.0.1", port=0, use_ssl=True)
+ fake_ssl_server.start()
+ self.assertNotEqual(0, fake_ssl_server.port)
+
+ fake_server = nova.wsgi.Server("fake", test_app,
+ host="127.0.0.1", port=0)
+ fake_server.start()
+ self.assertNotEqual(0, fake_server.port)
+
+ cli = eventlet.connect(("localhost", fake_ssl_server.port))
+ cli = eventlet.wrap_ssl(cli,
+ ca_certs=os.path.join(SSL_CERT_DIR, 'ca.crt'))
+
+ cli.write('POST / HTTP/1.1\r\nHost: localhost\r\n'
+ 'Connection: close\r\nContent-length:4\r\n\r\nPING')
+ response = cli.read(8192)
+ self.assertEqual(response[-4:], "PONG")
+
+ cli = eventlet.connect(("localhost", fake_server.port))
+
+ cli.sendall('POST / HTTP/1.1\r\nHost: localhost\r\n'
+ 'Connection: close\r\nContent-length:4\r\n\r\nPING')
+ response = cli.recv(8192)
+ self.assertEqual(response[-4:], "PONG")
+
+ fake_ssl_server.stop()
+ fake_ssl_server.wait()
+
+ @testtools.skipIf(not utils.is_ipv6_supported(), "no ipv6 support")
+ def test_app_using_ipv6_and_ssl(self):
+ greetings = 'Hello, World!!!'
+
+ @webob.dec.wsgify
+ def hello_world(req):
+ return greetings
+
+ server = nova.wsgi.Server("fake_ssl",
+ hello_world,
+ host="::1",
+ port=0,
+ use_ssl=True)
+
+ server.start()
+
+ response = urllib2.urlopen('https://[::1]:%d/' % server.port)
+ self.assertEqual(greetings, response.read())
+
+ server.stop()
+ server.wait()