Switch from optparse to argparse

Change-Id: Ie56dc0cdcc56577570e13e48732d7d72c63820e4
This commit is contained in:
Tim Burke 2023-02-17 15:33:50 -08:00
parent 5f803ae8fd
commit a395f37489
4 changed files with 119 additions and 113 deletions

View File

@ -13,19 +13,19 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import argparse
import copy import copy
import logging import logging
import os import os
import sys import sys
import signal import signal
import uuid import uuid
from optparse import OptionParser
from six.moves import range from six.moves import range
from swiftbench.bench import (BenchController, DistributedBenchController, from swiftbench.bench import (BenchController, DistributedBenchController,
create_containers, delete_containers) create_containers, delete_containers)
from swiftbench.utils import readconf, config_true_value from swiftbench.utils import readconf, config_true_value, get_size_bytes
# The defaults should be sufficient to run swift-bench on a SAIO # The defaults should be sufficient to run swift-bench on a SAIO
CONF_DEFAULTS = { CONF_DEFAULTS = {
@ -34,25 +34,24 @@ CONF_DEFAULTS = {
'key': os.environ.get('ST_KEY', ''), 'key': os.environ.get('ST_KEY', ''),
'auth_version': '1.0', 'auth_version': '1.0',
'use_proxy': 'yes', 'use_proxy': 'yes',
'put_concurrency': '10', 'put_concurrency': 10,
'get_concurrency': '10', 'get_concurrency': 10,
'del_concurrency': '10', 'del_concurrency': 10,
'concurrency': '', # set all 3 in one shot
'object_sources': '', # set of file contents to read and use for PUTs 'object_sources': '', # set of file contents to read and use for PUTs
'lower_object_size': '10', # bounded random size used if these differ 'lower_object_size': 10, # bounded random size used if these differ
'upper_object_size': '10', 'upper_object_size': 10,
'object_size': '1', # only if not object_sources and lower == upper 'object_size': 1, # only if not object_sources and lower == upper
'num_objects': '1000', 'num_objects': 1000,
'num_gets': '10000', 'num_gets': 10000,
'delete': 'yes', 'delete': 'yes',
'container_name': uuid.uuid4().hex, # really "container name base" 'container_name': uuid.uuid4().hex, # really "container name base"
'num_containers': '20', 'num_containers': 20,
'url': '', # used when use_proxy = no or overrides auth X-Storage-Url 'url': '', # used when use_proxy = no or overrides auth X-Storage-Url
'account': '', # used when use_proxy = no 'account': '', # used when use_proxy = no
'devices': 'sdb1', # space-sep list 'devices': 'sdb1', # space-sep list
'log_level': 'INFO', 'log_level': 'INFO',
'timeout': '10', 'timeout': 10,
'delay': '0', 'delay': 0,
'bench_clients': [], 'bench_clients': [],
} }
@ -64,7 +63,7 @@ SAIO_DEFAULTS = {
def main(argv): def main(argv):
usage = "usage: %prog [OPTIONS] [CONF_FILE]" usage = "usage: %(prog)s [OPTIONS] [CONF_FILE]"
usage += """\n\nConf file with SAIO defaults: usage += """\n\nConf file with SAIO defaults:
[bench] [bench]
@ -79,78 +78,82 @@ def main(argv):
auth_version = 1.0 auth_version = 1.0
policy_name = gold policy_name = gold
""" """
parser = OptionParser(usage=usage) parser = argparse.ArgumentParser(usage=usage)
parser.add_option('', '--saio', dest='saio', action='store_true', parser.add_argument('--saio', action='store_true',
default=False, help='Run benchmark with SAIO defaults') help='Run benchmark with SAIO defaults')
parser.add_option('-A', '--auth', dest='auth', parser.add_argument('-A', '--auth',
help='URL for obtaining an auth token') help='URL for obtaining an auth token')
parser.add_option('-U', '--user', dest='user', parser.add_argument('-U', '--user',
help='User name for obtaining an auth token') help='User name for obtaining an auth token')
parser.add_option('-K', '--key', dest='key', parser.add_argument('-K', '--key',
help='Key for obtaining an auth token') help='Key for obtaining an auth token')
parser.add_option('-b', '--bench-clients', action='append', parser.add_argument('-b', '--bench-clients', action='append',
metavar='<ip>:<port>', metavar='<ip>:<port>',
help=('A string of the form "<ip>:<port>" which matches ' help=('A string of the form "<ip>:<port>" which '
'the arguments supplied to a swift-bench-client ' 'matches the arguments supplied to a '
'process. This argument must be specified ' 'swift-bench-client process. This argument '
'once per swift-bench-client you want to ' 'must be specified once per swift-bench-client '
'utilize.')) 'you want to utilize.'))
parser.add_option('-u', '--url', dest='url', parser.add_argument('-u', '--url',
help='Storage URL') help='Storage URL')
parser.add_option('-c', '--concurrency', dest='concurrency', parser.add_argument('-c', '--concurrency', type=int,
help=('Number of concurrent connections to use. For ' help=('Number of concurrent connections to use. For '
'finer-grained control, see --get-concurrency, ' 'finer-grained control, see --get-concurrency, '
'--put-concurrency, and --delete-concurrency.')) '--put-concurrency, and --delete-concurrency.'))
parser.add_option('--get-concurrency', dest='get_concurrency', parser.add_argument('--get-concurrency', type=int,
help='Number of concurrent GET requests') help='Number of concurrent GET requests')
parser.add_option('--put-concurrency', dest='put_concurrency', parser.add_argument('--put-concurrency', type=int,
help='Number of concurrent PUT requests') help='Number of concurrent PUT requests')
parser.add_option('--delete-concurrency', dest='del_concurrency', parser.add_argument('--delete-concurrency', type=int,
help='Number of concurrent DELETE requests') dest="del_concurrency",
parser.add_option('-s', '--object-size', dest='object_size', help='Number of concurrent DELETE requests')
help='Size of objects to PUT (in bytes)') parser.add_argument('-s', '--object-size', type=get_size_bytes,
parser.add_option('-l', '--lower-object-size', dest='lower_object_size', help='Size of objects to PUT (in bytes)')
help=('Lower size of objects (in bytes); ' parser.add_argument('-l', '--lower-object-size', type=get_size_bytes,
'--object-size will be upper-object-size')) help=('Lower size of objects (in bytes); '
parser.add_option('-n', '--num-objects', dest='num_objects', '--object-size will be upper-object-size'))
help='Number of objects to PUT') parser.add_argument('-n', '--num-objects', type=int,
parser.add_option('-g', '--num-gets', dest='num_gets', help='Number of objects to PUT')
help='Number of GET operations to perform') parser.add_argument('-g', '--num-gets', type=int,
parser.add_option('-C', '--num-containers', dest='num_containers', help='Number of GET operations to perform')
help='Number of containers to distribute objects among') parser.add_argument('-C', '--num-containers', type=int,
parser.add_option('-x', '--no-delete', dest='delete', action='store_false', help='Number of containers to distribute objects '
help='If set, will not delete the objects created') 'among')
parser.add_option('-V', '--auth_version', dest='auth_version', parser.add_argument('-x', '--no-delete',
help='Authentication version') dest='delete', action='store_false',
parser.add_option('-d', '--delay', dest='delay', help='If set, will not delete the objects created')
help='Delay before delete requests in seconds') parser.add_argument('-V', '--auth_version',
parser.add_option('-P', '--policy-name', dest='policy_name', help='Authentication version')
help='Specify which policy to use when creating ' parser.add_argument('-d', '--delay', type=int,
'containers') help='Delay before delete requests in seconds')
parser.add_argument('-P', '--policy-name',
help='Specify which policy to use when creating '
'containers')
parser.add_argument('conf_file', nargs="?",
help='config file')
options, args = parser.parse_args(argv) args = parser.parse_args(argv)
parser_defaults = copy.deepcopy(CONF_DEFAULTS) parser_defaults = copy.deepcopy(CONF_DEFAULTS)
if options.saio: if args.saio:
parser_defaults.update(SAIO_DEFAULTS) parser_defaults.update(SAIO_DEFAULTS)
if getattr(options, 'lower_object_size', None): if getattr(args, 'lower_object_size', None):
if options.object_size <= options.lower_object_size: if args.object_size <= args.lower_object_size:
raise ValueError('--lower-object-size (%s) must be ' raise ValueError('--lower-object-size (%s) must be '
'< --object-size (%s)' % '< --object-size (%s)' %
(options.lower_object_size, options.object_size)) (args.lower_object_size, args.object_size))
parser_defaults['upper_object_size'] = options.object_size parser_defaults['upper_object_size'] = args.object_size
if args: if args.conf_file:
conf = args[0] if not os.path.exists(args.conf_file):
if not os.path.exists(conf): sys.exit("No such conf file: %s" % args.conf_file)
sys.exit("No such conf file: %s" % conf) conf = readconf(args.conf_file, 'bench', log_name='swift-bench',
conf = readconf(conf, 'bench', log_name='swift-bench',
defaults=parser_defaults) defaults=parser_defaults)
conf['bench_clients'] = [] conf['bench_clients'] = []
else: else:
conf = parser_defaults conf = parser_defaults
parser.set_defaults(**conf) parser.set_defaults(**conf)
options, _junk = parser.parse_args(argv) options = parser.parse_args(argv)
if options.concurrency != '': if options.concurrency:
options.put_concurrency = options.concurrency options.put_concurrency = options.concurrency
options.get_concurrency = options.concurrency options.get_concurrency = options.concurrency
options.del_concurrency = options.concurrency options.del_concurrency = options.concurrency

View File

@ -97,6 +97,8 @@ def get_size_bytes(value):
For example, '10k' becomes 10240, and '2M' becomes 2097152. For example, '10k' becomes 10240, and '2M' becomes 2097152.
""" """
if isinstance(value, int):
return value
if not isinstance(value, six.string_types): if not isinstance(value, six.string_types):
raise TypeError raise TypeError
value = value.strip() value = value.strip()

View File

@ -51,27 +51,27 @@ class TestCli(unittest.TestCase):
self.assertEqual(controller_opts.user, '') self.assertEqual(controller_opts.user, '')
self.assertEqual(controller_opts.key, '') self.assertEqual(controller_opts.key, '')
self.assertEqual(controller_opts.url, '') self.assertEqual(controller_opts.url, '')
self.assertEqual(controller_opts.concurrency, '') self.assertIsNone(controller_opts.concurrency)
self.assertEqual(controller_opts.get_concurrency, '10') self.assertEqual(controller_opts.get_concurrency, 10)
self.assertEqual(controller_opts.put_concurrency, '10') self.assertEqual(controller_opts.put_concurrency, 10)
self.assertEqual(controller_opts.lower_object_size, '10') self.assertEqual(controller_opts.lower_object_size, 10)
self.assertEqual(controller_opts.upper_object_size, '10') self.assertEqual(controller_opts.upper_object_size, 10)
self.assertEqual(controller_opts.num_objects, '1000') self.assertEqual(controller_opts.num_objects, 1000)
self.assertEqual(controller_opts.num_gets, '10000') self.assertEqual(controller_opts.num_gets, 10000)
self.assertEqual(controller_opts.num_containers, '20') self.assertEqual(controller_opts.num_containers, 20)
self.assertEqual(len(controller_opts.containers), 20) self.assertEqual(len(controller_opts.containers), 20)
self.assertTrue(controller_opts.delete) self.assertTrue(controller_opts.delete)
self.assertEqual(controller_opts.auth_version, '1.0') self.assertEqual(controller_opts.auth_version, '1.0')
self.assertEqual(controller_opts.delay, '0') self.assertEqual(controller_opts.delay, 0)
self.assertIsNone(controller_opts.policy_name) self.assertIsNone(controller_opts.policy_name)
self.assertTrue(controller_opts.use_proxy) self.assertTrue(controller_opts.use_proxy)
self.assertEqual(controller_opts.del_concurrency, '10') self.assertEqual(controller_opts.del_concurrency, 10)
self.assertEqual(controller_opts.object_sources, '') self.assertEqual(controller_opts.object_sources, '')
self.assertEqual(controller_opts.account, '') self.assertEqual(controller_opts.account, '')
self.assertEqual(controller_opts.container_name, mock.ANY) self.assertEqual(controller_opts.container_name, mock.ANY)
self.assertEqual(controller_opts.devices, 'sdb1') self.assertEqual(controller_opts.devices, 'sdb1')
self.assertEqual(controller_opts.log_level, 'INFO') self.assertEqual(controller_opts.log_level, 'INFO')
self.assertEqual(controller_opts.timeout, '10') self.assertEqual(controller_opts.timeout, 10)
self.assertEqual(controller_opts.bench_clients, []) self.assertEqual(controller_opts.bench_clients, [])
self.assertTrue(controller_opts.containers) self.assertTrue(controller_opts.containers)
@ -83,27 +83,27 @@ class TestCli(unittest.TestCase):
self.assertEqual(controller_opts.user, 'test:tester') self.assertEqual(controller_opts.user, 'test:tester')
self.assertEqual(controller_opts.key, 'testing') self.assertEqual(controller_opts.key, 'testing')
self.assertEqual(controller_opts.url, '') self.assertEqual(controller_opts.url, '')
self.assertEqual(controller_opts.concurrency, '') self.assertIsNone(controller_opts.concurrency)
self.assertEqual(controller_opts.get_concurrency, '10') self.assertEqual(controller_opts.get_concurrency, 10)
self.assertEqual(controller_opts.put_concurrency, '10') self.assertEqual(controller_opts.put_concurrency, 10)
self.assertEqual(controller_opts.lower_object_size, '10') self.assertEqual(controller_opts.lower_object_size, 10)
self.assertEqual(controller_opts.upper_object_size, '10') self.assertEqual(controller_opts.upper_object_size, 10)
self.assertEqual(controller_opts.num_objects, '1000') self.assertEqual(controller_opts.num_objects, 1000)
self.assertEqual(controller_opts.num_gets, '10000') self.assertEqual(controller_opts.num_gets, 10000)
self.assertEqual(controller_opts.num_containers, '20') self.assertEqual(controller_opts.num_containers, 20)
self.assertEqual(len(controller_opts.containers), 20) self.assertEqual(len(controller_opts.containers), 20)
self.assertTrue(controller_opts.delete) self.assertTrue(controller_opts.delete)
self.assertEqual(controller_opts.auth_version, '1.0') self.assertEqual(controller_opts.auth_version, '1.0')
self.assertEqual(controller_opts.delay, '0') self.assertEqual(controller_opts.delay, 0)
self.assertIsNone(controller_opts.policy_name) self.assertIsNone(controller_opts.policy_name)
self.assertTrue(controller_opts.use_proxy) self.assertTrue(controller_opts.use_proxy)
self.assertEqual(controller_opts.del_concurrency, '10') self.assertEqual(controller_opts.del_concurrency, 10)
self.assertEqual(controller_opts.object_sources, '') self.assertEqual(controller_opts.object_sources, '')
self.assertEqual(controller_opts.account, '') self.assertEqual(controller_opts.account, '')
self.assertEqual(controller_opts.container_name, mock.ANY) self.assertEqual(controller_opts.container_name, mock.ANY)
self.assertEqual(controller_opts.devices, 'sdb1') self.assertEqual(controller_opts.devices, 'sdb1')
self.assertEqual(controller_opts.log_level, 'INFO') self.assertEqual(controller_opts.log_level, 'INFO')
self.assertEqual(controller_opts.timeout, '10') self.assertEqual(controller_opts.timeout, 10)
self.assertEqual(controller_opts.bench_clients, []) self.assertEqual(controller_opts.bench_clients, [])
self.assertTrue(controller_opts.containers) self.assertTrue(controller_opts.containers)
@ -134,18 +134,18 @@ class TestCli(unittest.TestCase):
self.assertEqual(controller_opts.bench_clients, ['1.2.3.4:1234']) self.assertEqual(controller_opts.bench_clients, ['1.2.3.4:1234'])
self.assertEqual(controller_opts.url, self.assertEqual(controller_opts.url,
'http://storage.url/v1/AUTH_user') 'http://storage.url/v1/AUTH_user')
self.assertEqual(controller_opts.get_concurrency, '9') self.assertEqual(controller_opts.get_concurrency, 9)
self.assertEqual(controller_opts.put_concurrency, '8') self.assertEqual(controller_opts.put_concurrency, 8)
self.assertEqual(controller_opts.del_concurrency, '7') self.assertEqual(controller_opts.del_concurrency, 7)
self.assertEqual(controller_opts.object_size, '999') self.assertEqual(controller_opts.object_size, 999)
self.assertEqual(controller_opts.lower_object_size, '1') self.assertEqual(controller_opts.lower_object_size, 1)
self.assertEqual(controller_opts.num_objects, '5000') self.assertEqual(controller_opts.num_objects, 5000)
self.assertEqual(controller_opts.num_gets, '4000') self.assertEqual(controller_opts.num_gets, 4000)
self.assertEqual(controller_opts.num_containers, '4') self.assertEqual(controller_opts.num_containers, 4)
self.assertEqual(len(controller_opts.containers), 4) self.assertEqual(len(controller_opts.containers), 4)
self.assertFalse(controller_opts.delete) self.assertFalse(controller_opts.delete)
self.assertEqual(controller_opts.auth_version, '2.0') self.assertEqual(controller_opts.auth_version, '2.0')
self.assertEqual(controller_opts.delay, '10') self.assertEqual(controller_opts.delay, 10)
self.assertEqual(controller_opts.policy_name, 'gold') self.assertEqual(controller_opts.policy_name, 'gold')
self.assertTrue(controller_opts.use_proxy) self.assertTrue(controller_opts.use_proxy)
self.assertEqual(controller_opts.object_sources, '') self.assertEqual(controller_opts.object_sources, '')
@ -153,7 +153,7 @@ class TestCli(unittest.TestCase):
self.assertEqual(controller_opts.container_name, mock.ANY) self.assertEqual(controller_opts.container_name, mock.ANY)
self.assertEqual(controller_opts.devices, 'sdb1') self.assertEqual(controller_opts.devices, 'sdb1')
self.assertEqual(controller_opts.log_level, 'INFO') self.assertEqual(controller_opts.log_level, 'INFO')
self.assertEqual(controller_opts.timeout, '10') self.assertEqual(controller_opts.timeout, 10)
self.assertTrue(controller_opts.containers) self.assertTrue(controller_opts.containers)
def test_concurrency_overrides_get_put_delete(self): def test_concurrency_overrides_get_put_delete(self):
@ -163,7 +163,7 @@ class TestCli(unittest.TestCase):
'--get-concurrency', '9', '--get-concurrency', '9',
'--put-concurrency', '8', '--put-concurrency', '8',
'--delete-concurrency', '7']) '--delete-concurrency', '7'])
self.assertEqual(controller_opts.concurrency, '5') self.assertEqual(controller_opts.concurrency, 5)
self.assertEqual(controller_opts.get_concurrency, '5') self.assertEqual(controller_opts.get_concurrency, 5)
self.assertEqual(controller_opts.put_concurrency, '5') self.assertEqual(controller_opts.put_concurrency, 5)
self.assertEqual(controller_opts.del_concurrency, '5') self.assertEqual(controller_opts.del_concurrency, 5)

View File

@ -152,8 +152,9 @@ log_name = %(yarr)s'''
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
utils.get_size_bytes('asdf') utils.get_size_bytes('asdf')
self.assertEqual(utils.get_size_bytes(1), 1)
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
utils.get_size_bytes(1) utils.get_size_bytes(1.0)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()