summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChmouel Boudjnah <chmouel@chmouel.com>2013-11-23 00:49:37 +0100
committerChmouel Boudjnah <chmouel@enovance.com>2013-11-24 15:35:49 +0100
commitb207aaca07733b1c5719e182c244906d20bf28b9 (patch)
treea86a8c61965329435b1701a476a9f8857b1f9623
parent64b976e139ecfeafa83889a9c6d6615d30ba5635 (diff)
downloadswift-bench-b207aaca07733b1c5719e182c244906d20bf28b9.tar.gz
Make swift-bench not depending on swift.
Remove the dependence on swift, import the only needed functions from swift.common.utils to swiftbench.utils Add tests for utils using mock instead. Change-Id: I1b69dce750b55f3ee0e999fb5a7100cf811f7ebe
-rwxr-xr-x.unittests2
-rwxr-xr-xbin/swift-bench3
-rwxr-xr-xbin/swift-bench-client4
-rw-r--r--swiftbench/bench.py23
-rw-r--r--swiftbench/utils.py79
-rw-r--r--tests/test_bench.py2
-rw-r--r--tests/test_utils.py109
7 files changed, 210 insertions, 12 deletions
diff --git a/.unittests b/.unittests
index bf5b027..d533d6b 100755
--- a/.unittests
+++ b/.unittests
@@ -3,6 +3,6 @@ set -e
python setup.py testr --coverage
RET=$?
-coverage report -m
+coverage report -mswiftbench
rm -f .coverage
exit $RET
diff --git a/bin/swift-bench b/bin/swift-bench
index d2c41d0..b3a22e0 100755
--- a/bin/swift-bench
+++ b/bin/swift-bench
@@ -23,7 +23,7 @@ from optparse import OptionParser
from swiftbench.bench import (BenchController, DistributedBenchController,
create_containers, delete_containers)
-from swiftbench.utils import readconf, LogAdapter, config_true_value
+from swiftbench.utils import readconf, config_true_value
# The defaults should be sufficient to run swift-bench on a SAIO
CONF_DEFAULTS = {
@@ -172,7 +172,6 @@ if __name__ == '__main__':
options.log_level.lower(), logging.INFO))
loghandler = logging.StreamHandler()
logger.addHandler(loghandler)
- logger = LogAdapter(logger, 'swift-bench')
logformat = logging.Formatter('%(server)s %(asctime)s %(levelname)s '
'%(message)s')
loghandler.setFormatter(logformat)
diff --git a/bin/swift-bench-client b/bin/swift-bench-client
index d003fd8..5d3bcb6 100755
--- a/bin/swift-bench-client
+++ b/bin/swift-bench-client
@@ -19,8 +19,7 @@ import sys
import signal
from optparse import OptionParser
-from swift.common.bench import BenchServer
-from swift.common.utils import LogAdapter
+from swiftbench.bench import BenchServer
if __name__ == '__main__':
usage = "usage: %prog <ip> <port>"
@@ -45,7 +44,6 @@ if __name__ == '__main__':
options.log_level.lower(), logging.INFO))
loghandler = logging.StreamHandler()
logger.addHandler(loghandler)
- logger = LogAdapter(logger, 'swift-bench-client')
logformat = logging.Formatter('%(server)s %(asctime)s %(levelname)s '
'%(message)s')
loghandler.setFormatter(logformat)
diff --git a/swiftbench/bench.py b/swiftbench/bench.py
index b588343..c1a5314 100644
--- a/swiftbench/bench.py
+++ b/swiftbench/bench.py
@@ -29,11 +29,21 @@ import eventlet
import eventlet.pools
from eventlet.green.httplib import CannotSendRequest
-from swift.common.utils import config_true_value, LogAdapter
import swiftclient as client
-from swift.common import direct_client
-from swift.common.http import HTTP_CONFLICT
-from swift.common.utils import json
+
+from swiftbench.utils import config_true_value
+
+try:
+ import simplejson as json
+except ImportError:
+ import json
+
+try:
+ from swift.common import direct_client
+except ImportError:
+ direct_client = None
+
+HTTP_CONFLICT = 409
def _func_on_containers(logger, conf, concurrency_key, func):
@@ -152,7 +162,6 @@ class BenchServer(object):
'%(server)s %(asctime)s %(levelname)s %(message)s')
loghandler.setFormatter(logformat)
logger.addHandler(loghandler)
- logger = LogAdapter(logger, 'swift-bench-server')
controller = BenchController(logger, conf)
try:
@@ -176,6 +185,10 @@ class Bench(object):
self.key = conf.key
self.auth_url = conf.auth
self.use_proxy = config_true_value(conf.use_proxy)
+ if not self.use_proxy and direct_client is None:
+ self.logger.critical("You need to have swift installed if you are "
+ "not using the proxy")
+ sys.exit(1)
self.auth_version = conf.auth_version
self.logger.info("Auth version: %s" % self.auth_version)
if self.use_proxy:
diff --git a/swiftbench/utils.py b/swiftbench/utils.py
new file mode 100644
index 0000000..14611d9
--- /dev/null
+++ b/swiftbench/utils.py
@@ -0,0 +1,79 @@
+# Copyright (c) 2010-2013 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 sys
+from ConfigParser import ConfigParser, RawConfigParser
+
+# Used when reading config values
+TRUE_VALUES = set(('true', '1', 'yes', 'on', 't', 'y'))
+
+
+# NOTE(chmouel): Imported from swift without the modular directory feature.
+def readconf(conf_path, section_name=None, log_name=None, defaults=None,
+ raw=False):
+ """
+ Read config file(s) and return config items as a dict
+
+ :param conf_path: path to config file, or a file-like object
+ (hasattr readline)
+ :param section_name: config section to read (will return all sections if
+ not defined)
+ :param log_name: name to be used with logging (will use section_name if
+ not defined)
+ :param defaults: dict of default values to pre-populate the config with
+ :returns: dict of config items
+ """
+ if defaults is None:
+ defaults = {}
+ if raw:
+ c = RawConfigParser(defaults)
+ else:
+ c = ConfigParser(defaults)
+ if hasattr(conf_path, 'readline'):
+ c.readfp(conf_path)
+ else:
+ success = c.read(conf_path)
+ if not success:
+ print "Unable to read config from %s" % conf_path
+ sys.exit(1)
+ if section_name:
+ if c.has_section(section_name):
+ conf = dict(c.items(section_name))
+ else:
+ print "Unable to find %s config section in %s" % \
+ (section_name, conf_path)
+ sys.exit(1)
+ if "log_name" not in conf:
+ if log_name is not None:
+ conf['log_name'] = log_name
+ else:
+ conf['log_name'] = section_name
+ else:
+ conf = {}
+ for s in c.sections():
+ conf.update({s: dict(c.items(s))})
+ if 'log_name' not in conf:
+ conf['log_name'] = log_name
+ conf['__file__'] = conf_path
+ return conf
+
+
+def config_true_value(value):
+ """
+ Returns True if the value is either True or a string in TRUE_VALUES.
+ Returns False otherwise.
+ """
+ return value is True or \
+ (isinstance(value, basestring) and value.lower() in TRUE_VALUES)
diff --git a/tests/test_bench.py b/tests/test_bench.py
index 8aba673..502cca5 100644
--- a/tests/test_bench.py
+++ b/tests/test_bench.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2012 OpenStack Foundation
+# Copyright (c) 2010-2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/tests/test_utils.py b/tests/test_utils.py
new file mode 100644
index 0000000..295d795
--- /dev/null
+++ b/tests/test_utils.py
@@ -0,0 +1,109 @@
+# Copyright (c) 2010-2013 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 mock
+import os
+import tempfile
+import unittest
+
+from StringIO import StringIO
+
+from swiftbench import utils
+
+
+class TestUtils(unittest.TestCase):
+
+ @mock.patch.object(utils, "TRUE_VALUES")
+ def test_config_true_value(self, mocked):
+ utils.TRUE_VALUES = 'hello world'.split()
+ for val in 'hello world HELLO WORLD'.split():
+ self.assertTrue(utils.config_true_value(val) is True)
+ self.assertTrue(utils.config_true_value(True) is True)
+ self.assertTrue(utils.config_true_value('foo') is False)
+ self.assertTrue(utils.config_true_value(False) is False)
+
+ def test_readconf(self):
+ conf = '''[section1]
+foo = bar
+
+[section2]
+log_name = yarr'''
+ # setup a real file
+ fd, temppath = tempfile.mkstemp(dir='/tmp')
+ with os.fdopen(fd, 'wb') as f:
+ f.write(conf)
+ make_filename = lambda: temppath
+ # setup a file stream
+ make_fp = lambda: StringIO(conf)
+ for conf_object_maker in (make_filename, make_fp):
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile)
+ expected = {'__file__': conffile,
+ 'log_name': None,
+ 'section1': {'foo': 'bar'},
+ 'section2': {'log_name': 'yarr'}}
+ self.assertEquals(result, expected)
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile, 'section1')
+ expected = {'__file__': conffile, 'log_name': 'section1',
+ 'foo': 'bar'}
+ self.assertEquals(result, expected)
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile,
+ 'section2').get('log_name')
+ expected = 'yarr'
+ self.assertEquals(result, expected)
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile, 'section1',
+ log_name='foo').get('log_name')
+ expected = 'foo'
+ self.assertEquals(result, expected)
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile, 'section1',
+ defaults={'bar': 'baz'})
+ expected = {'__file__': conffile, 'log_name': 'section1',
+ 'foo': 'bar', 'bar': 'baz'}
+ self.assertEquals(result, expected)
+ self.assertRaises(SystemExit, utils.readconf, temppath, 'section3')
+ os.unlink(temppath)
+ self.assertRaises(SystemExit, utils.readconf, temppath)
+
+ def test_readconf_raw(self):
+ conf = '''[section1]
+foo = bar
+
+[section2]
+log_name = %(yarr)s'''
+ # setup a real file
+ fd, temppath = tempfile.mkstemp(dir='/tmp')
+ with os.fdopen(fd, 'wb') as f:
+ f.write(conf)
+ make_filename = lambda: temppath
+ # setup a file stream
+ make_fp = lambda: StringIO(conf)
+ for conf_object_maker in (make_filename, make_fp):
+ conffile = conf_object_maker()
+ result = utils.readconf(conffile, raw=True)
+ expected = {'__file__': conffile,
+ 'log_name': None,
+ 'section1': {'foo': 'bar'},
+ 'section2': {'log_name': '%(yarr)s'}}
+ self.assertEquals(result, expected)
+ os.unlink(temppath)
+ self.assertRaises(SystemExit, utils.readconf, temppath)
+
+
+if __name__ == '__main__':
+ unittest.main()