tests for wsgi/daemon config parsing
Change-Id: Ibb82555830b88962cc765fc88281ca42a9ce9d9c
This commit is contained in:
parent
8e875df65a
commit
c95f8e6c05
@ -315,7 +315,9 @@ def run_daemon(klass, conf_file, section_name='', once=False, **kwargs):
|
|||||||
|
|
||||||
logger.notice('Starting %s', os.getpid())
|
logger.notice('Starting %s', os.getpid())
|
||||||
try:
|
try:
|
||||||
DaemonStrategy(klass(conf), logger).run(once=once, **kwargs)
|
d = klass(conf)
|
||||||
|
DaemonStrategy(d, logger).run(once=once, **kwargs)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logger.info('User quit')
|
logger.info('User quit')
|
||||||
logger.notice('Exited %s', os.getpid())
|
logger.notice('Exited %s', os.getpid())
|
||||||
|
return d
|
||||||
|
@ -1408,3 +1408,36 @@ def generate_db_path(tempdir, server_type):
|
|||||||
return os.path.join(
|
return os.path.join(
|
||||||
tempdir, '%ss' % server_type, 'part', 'suffix', 'hash',
|
tempdir, '%ss' % server_type, 'part', 'suffix', 'hash',
|
||||||
'%s-%s.db' % (server_type, uuid4()))
|
'%s-%s.db' % (server_type, uuid4()))
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigAssertMixin(object):
|
||||||
|
"""
|
||||||
|
Use this with a TestCase to get py2/3 compatible assert for DuplicateOption
|
||||||
|
"""
|
||||||
|
def assertDuplicateOption(self, app_config, option_name, option_value):
|
||||||
|
"""
|
||||||
|
PY3 added a DuplicateOptionError, PY2 didn't seem to care
|
||||||
|
"""
|
||||||
|
if six.PY3:
|
||||||
|
self.assertDuplicateOptionError(app_config, option_name)
|
||||||
|
else:
|
||||||
|
self.assertDuplicateOptionOK(app_config, option_name, option_value)
|
||||||
|
|
||||||
|
def assertDuplicateOptionError(self, app_config, option_name):
|
||||||
|
with self.assertRaises(
|
||||||
|
utils.configparser.DuplicateOptionError) as ctx:
|
||||||
|
app_config()
|
||||||
|
msg = str(ctx.exception)
|
||||||
|
self.assertIn(option_name, msg)
|
||||||
|
self.assertIn('already exists', msg)
|
||||||
|
|
||||||
|
def assertDuplicateOptionOK(self, app_config, option_name, option_value):
|
||||||
|
app = app_config()
|
||||||
|
if hasattr(app, 'conf'):
|
||||||
|
found_value = app.conf[option_name]
|
||||||
|
else:
|
||||||
|
if hasattr(app, '_pipeline_final_app'):
|
||||||
|
# special case for proxy app!
|
||||||
|
app = app._pipeline_final_app
|
||||||
|
found_value = getattr(app, option_name)
|
||||||
|
self.assertEqual(found_value, option_value)
|
||||||
|
@ -14,18 +14,19 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from six import StringIO
|
import six
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from getpass import getuser
|
from getpass import getuser
|
||||||
import logging
|
import logging
|
||||||
from test.unit import tmpfile
|
from test.unit import tmpfile, with_tempdir, ConfigAssertMixin
|
||||||
import mock
|
import mock
|
||||||
import signal
|
import signal
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import itertools
|
import itertools
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import errno
|
import errno
|
||||||
|
from textwrap import dedent
|
||||||
|
|
||||||
from swift.common import daemon, utils
|
from swift.common import daemon, utils
|
||||||
from test.debug_logger import debug_logger
|
from test.debug_logger import debug_logger
|
||||||
@ -106,7 +107,7 @@ class TestWorkerDaemon(unittest.TestCase):
|
|||||||
self.assertTrue(d.is_healthy())
|
self.assertTrue(d.is_healthy())
|
||||||
|
|
||||||
|
|
||||||
class TestRunDaemon(unittest.TestCase):
|
class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
for patcher in [
|
for patcher in [
|
||||||
@ -167,7 +168,7 @@ class TestRunDaemon(unittest.TestCase):
|
|||||||
conf_file, once=True)
|
conf_file, once=True)
|
||||||
|
|
||||||
# test user quit
|
# test user quit
|
||||||
sio = StringIO()
|
sio = six.StringIO()
|
||||||
logger = logging.getLogger('server')
|
logger = logging.getLogger('server')
|
||||||
logger.addHandler(logging.StreamHandler(sio))
|
logger.addHandler(logging.StreamHandler(sio))
|
||||||
logger = utils.get_logger(None, 'server', log_route='server')
|
logger = utils.get_logger(None, 'server', log_route='server')
|
||||||
@ -207,6 +208,91 @@ class TestRunDaemon(unittest.TestCase):
|
|||||||
os.environ['TZ'] = old_tz
|
os.environ['TZ'] = old_tz
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_run_deamon_from_conf_file(self, tempdir):
|
||||||
|
conf_path = os.path.join(tempdir, 'test-daemon.conf')
|
||||||
|
conf_body = """
|
||||||
|
[DEFAULT]
|
||||||
|
conn_timeout = 5
|
||||||
|
client_timeout = 1
|
||||||
|
[my-daemon]
|
||||||
|
CONN_timeout = 10
|
||||||
|
client_timeout = 2
|
||||||
|
"""
|
||||||
|
contents = dedent(conf_body)
|
||||||
|
with open(conf_path, 'w') as f:
|
||||||
|
f.write(contents)
|
||||||
|
with mock.patch('swift.common.daemon.use_hub'):
|
||||||
|
d = daemon.run_daemon(MyDaemon, conf_path)
|
||||||
|
# my-daemon section takes priority (!?)
|
||||||
|
self.assertEqual('2', d.conf['client_timeout'])
|
||||||
|
self.assertEqual('10', d.conf['conn_timeout'])
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_run_daemon_from_conf_file_with_duplicate_var(self, tempdir):
|
||||||
|
conf_path = os.path.join(tempdir, 'test-daemon.conf')
|
||||||
|
conf_body = """
|
||||||
|
[DEFAULT]
|
||||||
|
client_timeout = 3
|
||||||
|
[my-daemon]
|
||||||
|
CLIENT_TIMEOUT = 2
|
||||||
|
client_timeout = 1
|
||||||
|
"""
|
||||||
|
contents = dedent(conf_body)
|
||||||
|
with open(conf_path, 'w') as f:
|
||||||
|
f.write(contents)
|
||||||
|
with mock.patch('swift.common.daemon.use_hub'):
|
||||||
|
app_config = lambda: daemon.run_daemon(MyDaemon, tempdir)
|
||||||
|
self.assertDuplicateOption(app_config, 'client_timeout', '1')
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_run_deamon_from_conf_dir(self, tempdir):
|
||||||
|
conf_files = {
|
||||||
|
'default': """
|
||||||
|
[DEFAULT]
|
||||||
|
conn_timeout = 5
|
||||||
|
client_timeout = 1
|
||||||
|
""",
|
||||||
|
'daemon': """
|
||||||
|
[DEFAULT]
|
||||||
|
CONN_timeout = 3
|
||||||
|
CLIENT_TIMEOUT = 4
|
||||||
|
[my-daemon]
|
||||||
|
CONN_timeout = 10
|
||||||
|
client_timeout = 2
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
for filename, conf_body in conf_files.items():
|
||||||
|
path = os.path.join(tempdir, filename + '.conf')
|
||||||
|
with open(path, 'wt') as fd:
|
||||||
|
fd.write(dedent(conf_body))
|
||||||
|
with mock.patch('swift.common.daemon.use_hub'):
|
||||||
|
d = daemon.run_daemon(MyDaemon, tempdir)
|
||||||
|
# my-daemon section takes priority (!?)
|
||||||
|
self.assertEqual('2', d.conf['client_timeout'])
|
||||||
|
self.assertEqual('10', d.conf['conn_timeout'])
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_run_daemon_from_conf_dir_with_duplicate_var(self, tempdir):
|
||||||
|
conf_files = {
|
||||||
|
'default': """
|
||||||
|
[DEFAULT]
|
||||||
|
client_timeout = 3
|
||||||
|
""",
|
||||||
|
'daemon': """
|
||||||
|
[my-daemon]
|
||||||
|
client_timeout = 2
|
||||||
|
CLIENT_TIMEOUT = 4
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
for filename, conf_body in conf_files.items():
|
||||||
|
path = os.path.join(tempdir, filename + '.conf')
|
||||||
|
with open(path, 'wt') as fd:
|
||||||
|
fd.write(dedent(conf_body))
|
||||||
|
with mock.patch('swift.common.daemon.use_hub'):
|
||||||
|
app_config = lambda: daemon.run_daemon(MyDaemon, tempdir)
|
||||||
|
self.assertDuplicateOption(app_config, 'client_timeout', '4')
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def mock_os(self, child_worker_cycles=3):
|
def mock_os(self, child_worker_cycles=3):
|
||||||
self.waitpid_calls = defaultdict(int)
|
self.waitpid_calls = defaultdict(int)
|
||||||
|
@ -43,7 +43,7 @@ from swift.common.storage_policy import POLICIES
|
|||||||
from test import listen_zero
|
from test import listen_zero
|
||||||
from test.debug_logger import debug_logger
|
from test.debug_logger import debug_logger
|
||||||
from test.unit import (
|
from test.unit import (
|
||||||
temptree, with_tempdir, write_fake_ring, patch_policies)
|
temptree, with_tempdir, write_fake_ring, patch_policies, ConfigAssertMixin)
|
||||||
|
|
||||||
from paste.deploy import loadwsgi
|
from paste.deploy import loadwsgi
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ def _fake_rings(tmpdir):
|
|||||||
|
|
||||||
|
|
||||||
@patch_policies
|
@patch_policies
|
||||||
class TestWSGI(unittest.TestCase):
|
class TestWSGI(unittest.TestCase, ConfigAssertMixin):
|
||||||
"""Tests for swift.common.wsgi"""
|
"""Tests for swift.common.wsgi"""
|
||||||
|
|
||||||
def test_init_request_processor(self):
|
def test_init_request_processor(self):
|
||||||
@ -133,14 +133,38 @@ class TestWSGI(unittest.TestCase):
|
|||||||
def test_loadapp_from_file(self, tempdir):
|
def test_loadapp_from_file(self, tempdir):
|
||||||
conf_path = os.path.join(tempdir, 'object-server.conf')
|
conf_path = os.path.join(tempdir, 'object-server.conf')
|
||||||
conf_body = """
|
conf_body = """
|
||||||
|
[DEFAULT]
|
||||||
|
CONN_timeout = 10
|
||||||
|
client_timeout = 1
|
||||||
[app:main]
|
[app:main]
|
||||||
use = egg:swift#object
|
use = egg:swift#object
|
||||||
|
conn_timeout = 5
|
||||||
|
client_timeout = 2
|
||||||
|
CLIENT_TIMEOUT = 3
|
||||||
"""
|
"""
|
||||||
contents = dedent(conf_body)
|
contents = dedent(conf_body)
|
||||||
with open(conf_path, 'w') as f:
|
with open(conf_path, 'w') as f:
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
app = wsgi.loadapp(conf_path)
|
app = wsgi.loadapp(conf_path)
|
||||||
self.assertIsInstance(app, obj_server.ObjectController)
|
self.assertIsInstance(app, obj_server.ObjectController)
|
||||||
|
self.assertTrue(isinstance(app, obj_server.ObjectController))
|
||||||
|
self.assertEqual(1, app.client_timeout)
|
||||||
|
self.assertEqual(5, app.conn_timeout)
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_loadapp_from_file_with_duplicate_var(self, tempdir):
|
||||||
|
conf_path = os.path.join(tempdir, 'object-server.conf')
|
||||||
|
conf_body = """
|
||||||
|
[app:main]
|
||||||
|
use = egg:swift#object
|
||||||
|
client_timeout = 2
|
||||||
|
client_timeout = 3
|
||||||
|
"""
|
||||||
|
contents = dedent(conf_body)
|
||||||
|
with open(conf_path, 'w') as f:
|
||||||
|
f.write(contents)
|
||||||
|
app_config = lambda: wsgi.loadapp(conf_path)
|
||||||
|
self.assertDuplicateOption(app_config, 'client_timeout', 3.0)
|
||||||
|
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_loadapp_from_file_with_global_conf(self, tempdir):
|
def test_loadapp_from_file_with_global_conf(self, tempdir):
|
||||||
@ -204,11 +228,85 @@ class TestWSGI(unittest.TestCase):
|
|||||||
|
|
||||||
def test_loadapp_from_string(self):
|
def test_loadapp_from_string(self):
|
||||||
conf_body = """
|
conf_body = """
|
||||||
|
[DEFAULT]
|
||||||
|
CONN_timeout = 10
|
||||||
|
client_timeout = 1
|
||||||
[app:main]
|
[app:main]
|
||||||
use = egg:swift#object
|
use = egg:swift#object
|
||||||
|
conn_timeout = 5
|
||||||
|
client_timeout = 2
|
||||||
"""
|
"""
|
||||||
app = wsgi.loadapp(wsgi.ConfigString(conf_body))
|
app = wsgi.loadapp(wsgi.ConfigString(conf_body))
|
||||||
self.assertTrue(isinstance(app, obj_server.ObjectController))
|
self.assertTrue(isinstance(app, obj_server.ObjectController))
|
||||||
|
self.assertEqual(1, app.client_timeout)
|
||||||
|
self.assertEqual(5, app.conn_timeout)
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_loadapp_from_dir(self, tempdir):
|
||||||
|
conf_files = {
|
||||||
|
'pipeline': """
|
||||||
|
[pipeline:main]
|
||||||
|
pipeline = tempauth proxy-server
|
||||||
|
""",
|
||||||
|
'tempauth': """
|
||||||
|
[DEFAULT]
|
||||||
|
swift_dir = %s
|
||||||
|
random_VAR = foo
|
||||||
|
[filter:tempauth]
|
||||||
|
use = egg:swift#tempauth
|
||||||
|
random_var = bar
|
||||||
|
""" % tempdir,
|
||||||
|
'proxy': """
|
||||||
|
[DEFAULT]
|
||||||
|
conn_timeout = 5
|
||||||
|
client_timeout = 1
|
||||||
|
[app:proxy-server]
|
||||||
|
use = egg:swift#proxy
|
||||||
|
CONN_timeout = 10
|
||||||
|
client_timeout = 2
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
_fake_rings(tempdir)
|
||||||
|
for filename, conf_body in conf_files.items():
|
||||||
|
path = os.path.join(tempdir, filename + '.conf')
|
||||||
|
with open(path, 'wt') as fd:
|
||||||
|
fd.write(dedent(conf_body))
|
||||||
|
app = wsgi.loadapp(tempdir)
|
||||||
|
# DEFAULT takes priority (!?)
|
||||||
|
self.assertEqual(5, app._pipeline_final_app.conn_timeout)
|
||||||
|
self.assertEqual(1, app._pipeline_final_app.client_timeout)
|
||||||
|
self.assertEqual('foo', app.app.app.app.conf['random_VAR'])
|
||||||
|
self.assertEqual('bar', app.app.app.app.conf['random_var'])
|
||||||
|
|
||||||
|
@with_tempdir
|
||||||
|
def test_loadapp_from_dir_with_duplicate_var(self, tempdir):
|
||||||
|
conf_files = {
|
||||||
|
'pipeline': """
|
||||||
|
[pipeline:main]
|
||||||
|
pipeline = tempauth proxy-server
|
||||||
|
""",
|
||||||
|
'tempauth': """
|
||||||
|
[DEFAULT]
|
||||||
|
swift_dir = %s
|
||||||
|
random_VAR = foo
|
||||||
|
[filter:tempauth]
|
||||||
|
use = egg:swift#tempauth
|
||||||
|
random_var = bar
|
||||||
|
""" % tempdir,
|
||||||
|
'proxy': """
|
||||||
|
[app:proxy-server]
|
||||||
|
use = egg:swift#proxy
|
||||||
|
client_timeout = 2
|
||||||
|
CLIENT_TIMEOUT = 1
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
_fake_rings(tempdir)
|
||||||
|
for filename, conf_body in conf_files.items():
|
||||||
|
path = os.path.join(tempdir, filename + '.conf')
|
||||||
|
with open(path, 'wt') as fd:
|
||||||
|
fd.write(dedent(conf_body))
|
||||||
|
app_config = lambda: wsgi.loadapp(tempdir)
|
||||||
|
self.assertDuplicateOption(app_config, 'client_timeout', 2.0)
|
||||||
|
|
||||||
@with_tempdir
|
@with_tempdir
|
||||||
def test_load_app_config(self, tempdir):
|
def test_load_app_config(self, tempdir):
|
||||||
|
Loading…
Reference in New Issue
Block a user