Added unit tests for ringbuilder command-line utility
Added new unit tests: test_add_device_old_missing_region test_create_ring_number_of_arguments test_add_duplicate_devices test_rebalance_with_seed test_set_overload_number_of_arguments test_main_no_arguments test_main_single_argument test_main_with_safe Modified existing unit tests to create sample ring at start of test. This change was needed to have unit tests run correctly and demonstrate code coverage. test_unknown test_search_device_number_of_arguments test_list_parts_number_of_arguments test_set_weight_number_of_arguments test_set_info_number_of_arguments test_remove_device_number_of_arguments test_set_min_part_hours_number_of_arguments test_set_replicas_number_of_arguments test_set_replicas_invalid_value Updates to handled nested mocks. Updates to handle no exception case when SystemExit is expected. PEP8 corrections. Moved new tests from try blocks to use of assertRaises or call to run_srb using exp_results with specified exit codes. Updated run_srb to accept a dictionary of expected results. Specifically, look for 'valid_exit_codes' to test, default to (0,1). Change-Id: I4cf3f5f055a9babba140c68a9c7ff90b9c50ea62
This commit is contained in:
parent
e75dc8028b
commit
7f4139bc26
@ -29,13 +29,19 @@ from swift.common.ring import RingBuilder
|
||||
|
||||
class RunSwiftRingBuilderMixin(object):
|
||||
|
||||
def run_srb(self, *argv):
|
||||
def run_srb(self, *argv, **kwargs):
|
||||
if len(argv) == 1 and isinstance(argv[0], six.string_types):
|
||||
# convert a single string to a list
|
||||
argv = shlex.split(argv[0])
|
||||
mock_stdout = six.StringIO()
|
||||
mock_stderr = six.StringIO()
|
||||
|
||||
if 'exp_results' in kwargs:
|
||||
exp_results = kwargs['exp_results']
|
||||
argv = argv[:-1]
|
||||
else:
|
||||
exp_results = None
|
||||
|
||||
srb_args = ["", self.tempfile] + [str(s) for s in argv]
|
||||
|
||||
try:
|
||||
@ -43,7 +49,13 @@ class RunSwiftRingBuilderMixin(object):
|
||||
with mock.patch("sys.stderr", mock_stderr):
|
||||
ringbuilder.main(srb_args)
|
||||
except SystemExit as err:
|
||||
if err.code not in (0, 1): # (success, warning)
|
||||
valid_exit_codes = None
|
||||
if exp_results is not None and 'valid_exit_codes' in exp_results:
|
||||
valid_exit_codes = exp_results['valid_exit_codes']
|
||||
else:
|
||||
valid_exit_codes = (0, 1) # (success, warning)
|
||||
|
||||
if err.code not in valid_exit_codes:
|
||||
msg = 'Unexpected exit status %s\n' % err.code
|
||||
msg += 'STDOUT:\n%s\nSTDERR:\n%s\n' % (
|
||||
mock_stdout.getvalue(), mock_stderr.getvalue())
|
||||
@ -282,6 +294,11 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertEqual(ring.replicas, 3.14159265359)
|
||||
self.assertEqual(ring.min_part_hours, 1)
|
||||
|
||||
def test_create_ring_number_of_arguments(self):
|
||||
# Test missing arguments
|
||||
argv = ["", self.tmpfile, "create"]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_add_device_ipv4_old_format(self):
|
||||
self.create_sample_ring()
|
||||
# Test ipv4(old format)
|
||||
@ -302,6 +319,14 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertEqual(dev['replication_port'], 6000)
|
||||
self.assertEqual(dev['meta'], 'some meta data')
|
||||
|
||||
def test_add_duplicate_devices(self):
|
||||
self.create_sample_ring()
|
||||
# Test adding duplicate devices
|
||||
argv = ["", self.tmpfile, "add",
|
||||
"r1z1-127.0.0.1:6000/sda9", "3.14159265359",
|
||||
"r1z1-127.0.0.1:6000/sda9", "2"]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_add_device_ipv6_old_format(self):
|
||||
self.create_sample_ring()
|
||||
# Test ipv6(old format)
|
||||
@ -439,6 +464,18 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
err = e
|
||||
self.assertEqual(err.code, 2)
|
||||
|
||||
def test_add_device_old_missing_region(self):
|
||||
self.create_sample_ring()
|
||||
# Test add device without specifying a region
|
||||
argv = ["", self.tmpfile, "add",
|
||||
"z3-127.0.0.1:6000/sde3_some meta data", "3.14159265359"]
|
||||
exp_results = {'valid_exit_codes': [2]}
|
||||
self.run_srb(*argv, exp_results=exp_results)
|
||||
# Check that ring was created with sane value for region
|
||||
ring = RingBuilder.load(self.tmpfile)
|
||||
dev = ring.devs[-1]
|
||||
self.assertTrue(dev['region'] > 0)
|
||||
|
||||
def test_remove_device(self):
|
||||
for search_value in self.search_values:
|
||||
self.create_sample_ring()
|
||||
@ -700,6 +737,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertTrue(ring.validate())
|
||||
|
||||
def test_remove_device_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "remove"]
|
||||
err = None
|
||||
@ -911,6 +949,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertTrue(ring.validate())
|
||||
|
||||
def test_set_weight_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "set_weight"]
|
||||
err = None
|
||||
@ -1201,6 +1240,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertTrue(ring.validate())
|
||||
|
||||
def test_set_info_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "set_info"]
|
||||
err = None
|
||||
@ -1253,6 +1293,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertEqual(ring.min_part_hours, 24)
|
||||
|
||||
def test_set_min_part_hours_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "set_min_part_hours"]
|
||||
err = None
|
||||
@ -1326,7 +1367,14 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertTrue('1000.00%' in out)
|
||||
self.assertTrue('10.000000' in out)
|
||||
|
||||
def test_set_overload_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test missing arguments
|
||||
argv = ["", self.tmpfile, "set_overload"]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_set_replicas_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "set_replicas"]
|
||||
err = None
|
||||
@ -1337,6 +1385,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertEqual(err.code, 2)
|
||||
|
||||
def test_set_replicas_invalid_value(self):
|
||||
self.create_sample_ring()
|
||||
# Test not a valid number
|
||||
argv = ["", self.tmpfile, "set_replicas", "test"]
|
||||
err = None
|
||||
@ -1516,6 +1565,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_search_device_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "search"]
|
||||
err = None
|
||||
@ -1628,6 +1678,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_list_parts_number_of_arguments(self):
|
||||
self.create_sample_ring()
|
||||
# Test Number of arguments abnormal
|
||||
argv = ["", self.tmpfile, "list_parts"]
|
||||
err = None
|
||||
@ -1650,6 +1701,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertEqual(err.code, 2)
|
||||
|
||||
def test_unknown(self):
|
||||
self.create_sample_ring()
|
||||
argv = ["", self.tmpfile, "unknown"]
|
||||
err = None
|
||||
try:
|
||||
@ -1754,6 +1806,12 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
self.assertTrue(ring.validate())
|
||||
self.assertEqual(ring.devs[3], None)
|
||||
|
||||
def test_rebalance_with_seed(self):
|
||||
self.create_sample_ring()
|
||||
# Test rebalance using explicit seed parameter
|
||||
argv = ["", self.tmpfile, "rebalance", "--seed", "2"]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_write_ring(self):
|
||||
self.create_sample_ring()
|
||||
argv = ["", self.tmpfile, "rebalance"]
|
||||
@ -1768,12 +1826,8 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
argv = ["", self.tmpfile, "rebalance"]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
argv = ["", self.tmpfile, "write_builder"]
|
||||
err = None
|
||||
try:
|
||||
ringbuilder.main(argv)
|
||||
except SystemExit as e:
|
||||
err = e
|
||||
self.assertEqual(err.code, 2)
|
||||
exp_results = {'valid_exit_codes': [2]}
|
||||
self.run_srb(*argv, exp_results=exp_results)
|
||||
|
||||
def test_write_builder_after_device_removal(self):
|
||||
# Test regenerating builder file after having removed a device
|
||||
@ -1896,6 +1950,22 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
"Ring Builder file does not exist: object.builder\n"
|
||||
self.assertEqual(expected, mock_stdout.getvalue())
|
||||
|
||||
def test_main_no_arguments(self):
|
||||
# Test calling main with no arguments
|
||||
argv = []
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_main_single_argument(self):
|
||||
# Test calling main with single argument
|
||||
argv = [""]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
def test_main_with_safe(self):
|
||||
# Test calling main with '-safe' argument
|
||||
self.create_sample_ring()
|
||||
argv = ["-safe", self.tmpfile]
|
||||
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||
|
||||
|
||||
class TestRebalanceCommand(unittest.TestCase, RunSwiftRingBuilderMixin):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user