This commit introduces further test classes and methods for the Create family of methods of the BlockDev subclasses and a few additional minor cosmetic changes.
Signed-off-by: Federico Morg Pareschi <[email protected]> --- lib/storage/base.py | 13 ++ lib/storage/gluster.py | 4 +- test/py/ganeti.storage.bdev_unittest.py | 247 ++++++++++++++++++++++--- test/py/ganeti.storage.drbd_unittest.py | 88 ++++++++- test/py/ganeti.storage.extstorage_unittest.py | 73 ++++++++ test/py/ganeti.storage.filestorage_unittest.py | 56 ++++-- test/py/ganeti.storage.gluster_unittest.py | 41 +++- 7 files changed, 475 insertions(+), 47 deletions(-) create mode 100755 test/py/ganeti.storage.extstorage_unittest.py diff --git a/lib/storage/base.py b/lib/storage/base.py index 588caf2..461fdad 100644 --- a/lib/storage/base.py +++ b/lib/storage/base.py @@ -93,6 +93,19 @@ class BlockDev(object): self.params = params self.dyn_params = dyn_params + def __eq__(self, other): + if not isinstance(self, type(other)): + return False + return (self._children == other._children and + self.dev_path == other.dev_path and + self.unique_id == other.unique_id and + self.major == other.major and + self.minor == other.minor and + self.attached == other.attached and + self.size == other.size and + self.params == other.params and + self.dyn_params == other.dyn_params) + def Assemble(self): """Assemble the device from its components. diff --git a/lib/storage/gluster.py b/lib/storage/gluster.py index f8f5dea..b352d61 100644 --- a/lib/storage/gluster.py +++ b/lib/storage/gluster.py @@ -301,7 +301,7 @@ class GlusterStorage(base.BlockDev): base.ThrowError("Invalid setup for file device") try: - driver, path = unique_id + self.driver, self.path = unique_id except ValueError: # wrong number of arguments raise ValueError("Invalid configuration data %s" % repr(unique_id)) @@ -310,8 +310,6 @@ class GlusterStorage(base.BlockDev): volume = params[constants.GLUSTER_VOLUME] self.volume = GlusterVolume(server_addr, port, volume) - self.path = path - self.driver = driver self.full_path = io.PathJoin(self.volume.mount_point, self.path) self.file = None diff --git a/test/py/ganeti.storage.bdev_unittest.py b/test/py/ganeti.storage.bdev_unittest.py index 89f3b49..d107303 100755 --- a/test/py/ganeti.storage.bdev_unittest.py +++ b/test/py/ganeti.storage.bdev_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2006, 2007, 2010, 2012, 2013 Google Inc. +# Copyright (C) 2006, 2007, 2010, 2012, 2013, 2016 Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -44,11 +44,19 @@ from ganeti.storage import bdev import testutils +def _FakeRunCmd(success, stdout, cmd): + if success: + exit_code = 0 + else: + exit_code = 1 + return utils.RunResult(exit_code, None, stdout, "", cmd, + utils.process._TIMEOUT_NONE, 5) class TestRADOSBlockDevice(testutils.GanetiTestCase): """Tests for bdev.RADOSBlockDevice volumes """ + def setUp(self): """Set up input data""" testutils.GanetiTestCase.setUp(self) @@ -84,7 +92,7 @@ class TestRADOSBlockDevice(testutils.GanetiTestCase): constants.LDP_POOL: "fake_pool" } - def test_ParseRbdShowmappedJson(self): + def testParseRbdShowmappedJson(self): parse_function = bdev.RADOSBlockDevice._ParseRbdShowmappedJson self.assertEqual(parse_function(self.json_output_ok, self.volume_name), @@ -98,7 +106,7 @@ class TestRADOSBlockDevice(testutils.GanetiTestCase): self.assertRaises(errors.BlockDeviceError, parse_function, self.output_invalid, self.volume_name) - def test_ParseRbdShowmappedPlain(self): + def testParseRbdShowmappedPlain(self): parse_function = bdev.RADOSBlockDevice._ParseRbdShowmappedPlain self.assertEqual(parse_function(self.plain_output_new_ok, @@ -127,8 +135,7 @@ class TestRADOSBlockDevice(testutils.GanetiTestCase): """Test for bdev.RADOSBlockDevice.Import()""" # Set up the mock objects return values attach_mock.return_value = True - run_cmd_mock.return_value = \ - utils.RunResult(0, None, "", "", "", utils.process._TIMEOUT_NONE, 0) + run_cmd_mock.return_value = _FakeRunCmd(True, "", "") # Create a fake rbd volume inst = bdev.RADOSBlockDevice(self.test_unique_id, [], 1024, @@ -156,6 +163,34 @@ class TestRADOSBlockDevice(testutils.GanetiTestCase): self.assertEqual(inst.Export(), export_cmd) + @testutils.patch_object(utils, "RunCmd") + @testutils.patch_object(bdev.RADOSBlockDevice, "Attach") + def testRADOSBlockDeviceCreate(self, attach_mock, run_cmd_mock): + """Test for bdev.RADOSBlockDevice.Create() success""" + attach_mock.return_value = True + # This returns a successful RunCmd result + run_cmd_mock.return_value = _FakeRunCmd(True, "", "") + + expect = bdev.RADOSBlockDevice(self.test_unique_id, [], 1024, + self.test_params, {}) + got = bdev.RADOSBlockDevice.Create(self.test_unique_id, [], 1024, None, + self.test_params, False, {}, + test_kwarg="test") + + self.assertEqual(expect, got) + + @testutils.patch_object(bdev.RADOSBlockDevice, "Attach") + def testRADOSBlockDeviceCreateFailure(self, attach_mock): + """Test for bdev.RADOSBlockDevice.Create() failure with exclusive_storage + enabled + + """ + attach_mock.return_value = True + + self.assertRaises(errors.ProgrammerError, bdev.RADOSBlockDevice.Create, + self.test_unique_id, [], 1024, None, self.test_params, + True, {}) + class TestExclusiveStoragePvs(unittest.TestCase): """Test cases for functions dealing with LVM PV and exclusive storage""" @@ -234,8 +269,30 @@ class TestExclusiveStoragePvs(unittest.TestCase): self.assertTrue(len(epvs) == num_req or pvi.free != pvi.size) -class TestLogicalVolume(unittest.TestCase): +class TestLogicalVolume(testutils.GanetiTestCase): """Tests for bdev.LogicalVolume.""" + + def setUp(self): + """Set up test data""" + testutils.GanetiTestCase.setUp(self) + + self.volume_name = "31225655-5775-4356-c212-e8b1e137550a.disk0" + self.test_unique_id = ("ganeti", self.volume_name) + self.test_params = { + constants.LDP_STRIPES: 1 + } + self.pv_info_return = [objects.LvmPvInfo(name="/dev/sda5", vg_name="xenvg", + size=3500000.00, free=5000000.00, + attributes="wz--n-", lv_list=[])] + self.pv_info_invalid = [objects.LvmPvInfo(name="/dev/s:da5", + vg_name="xenvg", + size=3500000.00, free=5000000.00, + attributes="wz--n-", lv_list=[])] + self.pv_info_no_space = [objects.LvmPvInfo(name="/dev/sda5", vg_name="xenvg", + size=3500000.00, free=0.00, + attributes="wz--n-", lv_list=[])] + + def testParseLvInfoLine(self): """Tests for LogicalVolume._ParseLvInfoLine.""" broken_lines = [ @@ -279,14 +336,6 @@ class TestLogicalVolume(unittest.TestCase): parsed = bdev.LogicalVolume._ParseLvInfoLine(lvs_line, sep) self.assertEqual(parsed, exp) - @staticmethod - def _FakeRunCmd(success, stdout): - if success: - exit_code = 0 - else: - exit_code = 1 - return lambda cmd: utils.RunResult(exit_code, None, stdout, "", cmd, - utils.process._TIMEOUT_NONE, 5) def testGetLvGlobalInfo(self): """Tests for LogicalVolume._GetLvGlobalInfo.""" @@ -298,15 +347,19 @@ class TestLogicalVolume(unittest.TestCase): self.assertEqual({}, bdev.LogicalVolume._GetLvGlobalInfo( - _run_cmd=self._FakeRunCmd(False, "Fake error msg"))) + _run_cmd=lambda cmd: _FakeRunCmd(False, + "Fake error msg", + cmd))) self.assertEqual({}, bdev.LogicalVolume._GetLvGlobalInfo( - _run_cmd=self._FakeRunCmd(True, ""))) + _run_cmd=lambda cmd: _FakeRunCmd(True, + "", + cmd))) self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume._GetLvGlobalInfo, - _run_cmd=self._FakeRunCmd(True, "BadStdOut")) + _run_cmd=lambda cmd: _FakeRunCmd(True, "BadStdOut", cmd)) - fake_cmd = self._FakeRunCmd(True, good_lines) + fake_cmd = lambda cmd: _FakeRunCmd(True, good_lines, cmd) good_res = bdev.LogicalVolume._GetLvGlobalInfo(_run_cmd=fake_cmd) self.assertEqual(expected_output, good_res) @@ -317,8 +370,7 @@ class TestLogicalVolume(unittest.TestCase): attach_mock.return_value = True # Create a fake logical volume - test_unique_id = ("ganeti", "31225655-5775-4356-c212-e8b1e137550a.disk0") - inst = bdev.LogicalVolume(test_unique_id, [], 1024, {}, {}) + inst = bdev.LogicalVolume(self.test_unique_id, [], 1024, {}, {}) # Desired output command import_cmd = [constants.DD_CMD, @@ -335,8 +387,7 @@ class TestLogicalVolume(unittest.TestCase): attach_mock.return_value = True # Create a fake logical volume - test_unique_id = ("ganeti", "31225655-5775-4356-c212-e8b1e137550a.disk0") - inst = bdev.LogicalVolume(test_unique_id, [], 1024, {}, {}) + inst = bdev.LogicalVolume(self.test_unique_id, [], 1024, {}, {}) # Desired output command export_cmd = [constants.DD_CMD, @@ -347,20 +398,168 @@ class TestLogicalVolume(unittest.TestCase): self.assertEqual(inst.Export(), export_cmd) + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(utils, "RunCmd") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreate(self, attach_mock, run_cmd_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() success""" + attach_mock.return_value = True + # This returns a successful RunCmd result + run_cmd_mock.return_value = _FakeRunCmd(True, "", "") + pv_info_mock.return_value = self.pv_info_return + + expect = bdev.LogicalVolume(self.test_unique_id, [], 1024, + self.test_params, {}) + got = bdev.LogicalVolume.Create(self.test_unique_id, [], 1024, None, + self.test_params, False, {}, + test_kwarg="test") + + self.assertEqual(expect, got) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailurePvsInfoExclStor(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when pv_info is empty and + exclusive storage is enabled + + """ + attach_mock.return_value = True + pv_info_mock.return_value = [] + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, {}, True, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailurePvsInfoNoExclStor(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when pv_info is empty and + exclusive storage is disabled + + """ + attach_mock.return_value = True + pv_info_mock.return_value = [] + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, {}, False, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailurePvsInvalid(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when pvs_info output is + invalid + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_invalid + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, {}, False, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailureNoSpindles(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when there are no spindles + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_return + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, + self.test_params,True, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailureNotEnoughSpindles(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when there are not enough + spindles + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_return + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, 0, + self.test_params, True, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailureNotEnoughEmptyPvs(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when there are not enough + empty pvs + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_return + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, 2, + self.test_params, True, {}) + + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailureNoFreeSpace(self, attach_mock, pv_info_mock): + """Test for bdev.LogicalVolume.Create() failure when there is no free space + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_no_space + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, + self.test_params, False, {}) + + @testutils.patch_object(utils, "RunCmd") + @testutils.patch_object(bdev.LogicalVolume, "GetPVInfo") + @testutils.patch_object(bdev.LogicalVolume, "Attach") + def testCreateFailureCommand(self, attach_mock, pv_info_mock, run_cmd_mock): + """Test for bdev.LogicalVolume.Create() failure when the runcmd is incorrect + + """ + attach_mock.return_value = True + pv_info_mock.return_value = self.pv_info_return + run_cmd_mock = _FakeRunCmd(False, "", "") + + self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume.Create, + self.test_unique_id, [], 1024, None, + self.test_params, False, {}) + class TestPersistentBlockDevice(testutils.GanetiTestCase): """Tests for bdev.PersistentBlockDevice volumes """ + + def setUp(self): + """Set up test data""" + testutils.GanetiTestCase.setUp(self) + self.test_unique_id = (constants.BLOCKDEV_DRIVER_MANUAL, "/dev/abc") + def testPersistentBlockDeviceImport(self): """Test case for bdev.PersistentBlockDevice.Import()""" # Create a fake block device - test_unique_id = (constants.BLOCKDEV_DRIVER_MANUAL, "/dev/abc") - inst = bdev.PersistentBlockDevice(test_unique_id, [], 1024, {}, {}) + inst = bdev.PersistentBlockDevice(self.test_unique_id, [], 1024, {}, {}) self.assertRaises(errors.BlockDeviceError, bdev.PersistentBlockDevice.Import, inst) + @testutils.patch_object(bdev.PersistentBlockDevice, "Attach") + def testCreate(self, attach_mock): + """Test for bdev.PersostentBlockDevice.Create()""" + attach_mock.return_value = True + + expect = bdev.PersistentBlockDevice(self.test_unique_id, [], 0, {}, {}) + got = bdev.PersistentBlockDevice.Create(self.test_unique_id, [], 1024, None, + {}, False, {}, test_kwarg="test") + + self.assertEqual(expect, got) + + def testCreateFailure(self): + """Test for bdev.PersostentBlockDevice.Create() failure""" + + self.assertRaises(errors.ProgrammerError, bdev.PersistentBlockDevice.Create, + self.test_unique_id, [], 1024, None, {}, True, {}) + if __name__ == "__main__": testutils.GanetiTestProgram() diff --git a/test/py/ganeti.storage.drbd_unittest.py b/test/py/ganeti.storage.drbd_unittest.py index 9a1894f..6ac2876 100755 --- a/test/py/ganeti.storage.drbd_unittest.py +++ b/test/py/ganeti.storage.drbd_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2006, 2007, 2010, 2012, 2013 Google Inc. +# Copyright (C) 2006, 2007, 2010, 2012, 2013, 2016 Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -424,6 +424,7 @@ class TestDRBD8Status(testutils.GanetiTestCase): class TestDRBD8Construction(testutils.GanetiTestCase): + def setUp(self): """Read in txt data""" testutils.GanetiTestCase.setUp(self) @@ -471,5 +472,90 @@ class TestDRBD8Construction(testutils.GanetiTestCase): self.assertTrue(isinstance(inst._cmd_gen, drbd_cmdgen.DRBD84CmdGenerator)) +class TestDRBD8Create(testutils.GanetiTestCase): + + class fake_disk(object): + def __init__(self, dev_path): + self.dev_path = dev_path + + def Assemble(self): + pass + + def Attach(self): + return True + + def setUp(self): + """Set up test data""" + testutils.GanetiTestCase.setUp(self) + self.proc84_info = \ + drbd_info.DRBD8Info.CreateFromFile( + filename=testutils.TestDataFilename("proc_drbd84.txt")) + + self.test_unique_id = ("hosta.com", 123, "host2.com", 123, 0, + serializer.Private("secret")) + self.test_dyn_params = { + constants.DDP_LOCAL_IP: "192.0.2.1", + constants.DDP_LOCAL_MINOR: 0, + constants.DDP_REMOTE_IP: "192.0.2.2", + constants.DDP_REMOTE_MINOR: 0, + } + + fake_child_1 = self.fake_disk("/dev/sda5") + fake_child_2 = self.fake_disk("/dev/sda6") + self.children = [fake_child_1, fake_child_2] + + @testutils.patch_object(drbd.DRBD8Dev, "_InitMeta") + @testutils.patch_object(drbd.DRBD8Dev, "_CheckMetaSize") + @testutils.patch_object(drbd.DRBD8, "GetProcInfo") + def testCreate(self, proc_info, check_meta_size, init_meta): + proc_info.return_value = self.proc84_info + check_meta_size.return_value = None + init_meta.return_value = None + self.test_dyn_params[constants.DDP_LOCAL_MINOR] = 2 + + expected = drbd.DRBD8Dev(self.test_unique_id, [], 123, {}, + self.test_dyn_params) + got = drbd.DRBD8Dev.Create(self.test_unique_id, self.children, 123, + None, {}, False, self.test_dyn_params, + test_kwarg="test") + + self.assertEqual(got, expected) + + def testCreateFailureChildrenLength(self): + self.assertRaises(errors.ProgrammerError, drbd.DRBD8Dev.Create, + self.test_unique_id, [], 123, None, {}, + False, self.test_dyn_params) + + def testCreateFailureExclStorage(self): + self.assertRaises(errors.ProgrammerError, drbd.DRBD8Dev.Create, + self.test_unique_id, self.children, 123, None, {}, + True, self.test_dyn_params) + + def testCreateFailureNoMinor(self): + self.assertRaises(errors.ProgrammerError, drbd.DRBD8Dev.Create, + self.test_unique_id, self.children, 123, None, {}, + False, {}) + + @testutils.patch_object(drbd.DRBD8, "GetProcInfo") + def testCreateFailureInUse(self, proc_info): + # The proc84_info config has a local minor in use, which triggers our + # failure test. + proc_info.return_value = self.proc84_info + + self.assertRaises(errors.BlockDeviceError, drbd.DRBD8Dev.Create, + self.test_unique_id, self.children, 123, None, {}, + False, self.test_dyn_params) + + @testutils.patch_object(drbd.DRBD8, "GetProcInfo") + def testCreateFailureMetaAttach(self, proc_info): + proc_info.return_value = self.proc84_info + self.test_dyn_params[constants.DDP_LOCAL_MINOR] = 2 + self.children[1].Attach = lambda: False + + self.assertRaises(errors.BlockDeviceError, drbd.DRBD8Dev.Create, + self.test_unique_id, self.children, 123, None, {}, + False, self.test_dyn_params) + + if __name__ == "__main__": testutils.GanetiTestProgram() diff --git a/test/py/ganeti.storage.extstorage_unittest.py b/test/py/ganeti.storage.extstorage_unittest.py new file mode 100755 index 0000000..b8d2fd4 --- /dev/null +++ b/test/py/ganeti.storage.extstorage_unittest.py @@ -0,0 +1,73 @@ +#!/usr/bin/python +# + +# Copyright (C) 2016 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +"""Script for unittesting the extstorage module""" + + +from ganeti import errors +from ganeti.storage import extstorage + +import testutils + + +class TestExtStorageDevice(testutils.GanetiTestCase): + """Testing case for extstorage.ExtStorageDevice""" + + def setUp(self): + """Set up test data""" + testutils.GanetiTestCase.setUp(self) + self.name = "testname" + self.uuid = "testuuid" + self.test_unique_id = ("testdriver", "testvolumename") + + @testutils.patch_object(extstorage.ExtStorageDevice, "Attach") + @testutils.patch_object(extstorage, "_ExtStorageAction") + def testCreate(self, action_mock, attach_mock): + action_mock.return_value = None + attach_mock.return_value = True + + expected = extstorage.ExtStorageDevice(self.test_unique_id, [], 123, {}, {}, + name=self.name, uuid=self.uuid) + got = extstorage.ExtStorageDevice.Create(self.test_unique_id, [], 123, + None, {}, False, {}, + name=self.name, uuid=self.uuid) + + self.assertEqual(got, expected) + + def testCreateFailure(self): + self.assertRaises(errors.ProgrammerError, + extstorage.ExtStorageDevice.Create, + self.test_unique_id, [], 123, None, {}, + True, {}, name=self.name, uuid=self.uuid) + + +if __name__ == "__main__": + testutils.GanetiTestProgram() + diff --git a/test/py/ganeti.storage.filestorage_unittest.py b/test/py/ganeti.storage.filestorage_unittest.py index 4ac5743..fd6940d 100755 --- a/test/py/ganeti.storage.filestorage_unittest.py +++ b/test/py/ganeti.storage.filestorage_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2013 Google Inc. +# Copyright (C) 2013, 2016 Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -273,19 +273,18 @@ class TestFileDeviceHelper(testutils.GanetiTestCase): # These should fail horribly. volume.Exists(assert_exists=False) - self.assertRaises(errors.BlockDeviceError, lambda: \ - volume.Exists(assert_exists=True)) - self.assertRaises(errors.BlockDeviceError, lambda: \ - volume.Size()) - self.assertRaises(errors.BlockDeviceError, lambda: \ - volume.Grow(0.020, True, False, None)) + self.assertRaises(errors.BlockDeviceError, volume.Exists, + assert_exists=True) + self.assertRaises(errors.BlockDeviceError, volume.Size) + self.assertRaises(errors.BlockDeviceError, volume.Grow, + 0.020, True, False, None) # Removing however fails silently. volume.Remove() # Make sure we don't create all directories for you unless we ask for it - self.assertRaises(errors.BlockDeviceError, lambda: \ - TestFileDeviceHelper._Make(path, create_with_size=1)) + self.assertRaises(errors.BlockDeviceError, TestFileDeviceHelper._Make, + path, create_with_size=1) def testFileCreation(self): with TestFileDeviceHelper.TempEnvironment() as env: @@ -293,22 +292,22 @@ class TestFileDeviceHelper(testutils.GanetiTestCase): self.assertTrue(env.volume.Exists()) env.volume.Exists(assert_exists=True) - self.assertRaises(errors.BlockDeviceError, lambda: \ - env.volume.Exists(assert_exists=False)) + self.assertRaises(errors.BlockDeviceError, env.volume.Exists, + assert_exists=False) - self.assertRaises(errors.BlockDeviceError, lambda: \ - TestFileDeviceHelper._Make("/enoent", create_with_size=0.042)) + self.assertRaises(errors.BlockDeviceError, TestFileDeviceHelper._Make, + "/enoent", create_with_size=0.042) def testFailSizeDirectory(self): # This should still fail. with TestFileDeviceHelper.TempEnvironment(delete_file=False) as env: - self.assertRaises(errors.BlockDeviceError, lambda: \ - TestFileDeviceHelper._Make(env.subdirectory).Size()) + test_helper = TestFileDeviceHelper._Make(env.subdirectory) + self.assertRaises(errors.BlockDeviceError, test_helper.Size) def testGrowFile(self): with TestFileDeviceHelper.TempEnvironment(create_file=True) as env: - self.assertRaises(errors.BlockDeviceError, lambda: \ - env.volume.Grow(-1, False, True, None)) + self.assertRaises(errors.BlockDeviceError, env.volume.Grow, -1, + False, True, None) env.volume.Grow(2, False, True, None) self.assertEqual(2.0, env.volume.Size() / 1024.0**2) @@ -329,5 +328,28 @@ class TestFileDeviceHelper(testutils.GanetiTestCase): env.path = new_path # update the path for the context manager +class TestFileStorage(testutils.GanetiTestCase): + + @testutils.patch_object(filestorage, "FileDeviceHelper") + @testutils.patch_object(filestorage.FileStorage, "Attach") + def testCreate(self, attach_mock, helper_mock): + attach_mock.return_value = True + helper_mock.return_value = None + test_unique_id = ("test_driver", "/test/file") + + + expect = filestorage.FileStorage(test_unique_id, [], 123, {}, {}) + got = filestorage.FileStorage.Create(test_unique_id, [], 123, None, {}, + False, {}, test_kwarg="test") + + self.assertEqual(expect, got) + + def testCreateFailure(self): + test_unique_id = ("test_driver", "/test/file") + + self.assertRaises(errors.ProgrammerError, filestorage.FileStorage.Create, + test_unique_id, [], 123, None, {}, True, {}) + + if __name__ == "__main__": testutils.GanetiTestProgram() diff --git a/test/py/ganeti.storage.gluster_unittest.py b/test/py/ganeti.storage.gluster_unittest.py index b75bf6d..8204885 100644 --- a/test/py/ganeti.storage.gluster_unittest.py +++ b/test/py/ganeti.storage.gluster_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2013 Google Inc. +# Copyright (C) 2013, 2016 Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,9 +35,10 @@ import tempfile import unittest import mock +from ganeti import constants from ganeti import errors -from ganeti.storage import filestorage from ganeti.storage import gluster +from ganeti import ssconf from ganeti import utils import testutils @@ -141,5 +142,41 @@ class TestGlusterVolume(testutils.GanetiTestCase): msg="%s not testvol on localhost:9001" % (fuseMountString,)) +class TestGlusterStorage(testutils.GanetiTestCase): + + def setUp(self): + """Set up test data""" + testutils.GanetiTestCase.setUp(self) + + self.test_params = { + constants.GLUSTER_HOST: "127.0.0.1", + constants.GLUSTER_PORT: "24007", + constants.GLUSTER_VOLUME: "/testvol" + } + self.test_unique_id = ("testdriver", "testpath") + + + @testutils.patch_object(gluster.FileDeviceHelper, "CreateFile") + @testutils.patch_object(gluster.GlusterVolume, "Mount") + @testutils.patch_object(ssconf.SimpleStore, "GetGlusterStorageDir") + @testutils.patch_object(gluster.GlusterStorage, "Attach") + def testCreate(self, attach_mock, storage_dir_mock, mount_mock, create_file_mock): + attach_mock.return_value = True + storage_dir_mock.return_value = "/testmount" + + expect = gluster.GlusterStorage(self.test_unique_id, [], 123, + self.test_params, {}) + got = gluster.GlusterStorage.Create(self.test_unique_id, [], 123, None, + self.test_params, False, {}, + test_kwarg="test") + + self.assertEqual(expect, got) + + def testCreateFailure(self): + self.assertRaises(errors.ProgrammerError, gluster.GlusterStorage.Create, + self.test_unique_id, [], 123, None, + self.test_params, True, {}) + + if __name__ == "__main__": testutils.GanetiTestProgram() -- 2.8.0.rc3.226.g39d4020
