Example #1
0
 def test_acquire(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     fs.add_lockspace("lockspace", 1, "path")
     fd = fs.register()
     fs.acquire("lockspace", "resource", [("path", 1048576)], slkfd=fd)
     res = fs.read_resource("path", 1048576)
     self.assertTrue(res["acquired"], "resource is not acquired")
Example #2
0
def fake_sanlock(monkeypatch):
    fs = FakeSanlock()
    monkeypatch.setattr(clusterlock, "sanlock", fs)
    # FakeSanlock does not implement the depracated init_resource, so we will
    # create the resource using write_resource, so we can test acquire and
    # release.
    fs.write_resource(LS_NAME, LEASE.name, [(LEASE.path, LEASE.offset)])
    return fs
Example #3
0
 def test_write_read_resource(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     info = fs.read_resource("path", 1048576)
     expected = {"resource": "resource",
                 "lockspace": "lockspace",
                 "version": 0}
     self.assertEqual(info, expected)
Example #4
0
 def test_add_lockspace_sync(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     ls = fs.spaces["lockspace"]
     self.assertEqual(ls["host_id"], 1)
     self.assertEqual(ls["path"], "path")
     self.assertEqual(ls["offset"], 0)
     self.assertEqual(ls["iotimeout"], 0)
     self.assertTrue(ls["ready"].is_set(), "lockspace is not ready")
Example #5
0
 def test_write_read_resource(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     info = fs.read_resource("path", 1048576)
     expected = {
         "resource": "resource",
         "lockspace": "lockspace",
         "version": 0
     }
     self.assertEqual(info, expected)
Example #6
0
    def test_inq_lockspace_acquiring_wait(self):
        fs = FakeSanlock()
        fs.add_lockspace("lockspace", 1, "path", async=True)

        t = concurrent.thread(fs.complete_async, args=("lockspace", ))
        t.start()
        try:
            acquired = fs.inq_lockspace("lockspace", 1, "path", wait=True)
        finally:
            t.join()
        self.assertTrue(acquired, "lockspace not acquired")
Example #7
0
 def test_release_not_acquired(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     fs.add_lockspace("lockspace", 1, "path")
     fd = fs.register()
     with self.assertRaises(fs.SanlockException) as e:
         fs.release("lockspace", "resource", [("path", 1048576)], slkfd=fd)
     self.assertEqual(e.exception.errno, errno.EPERM)
Example #8
0
 def test_write_resource_failure(self):
     fs = FakeSanlock()
     fs.errors["write_resource"] = ExpectedError
     with self.assertRaises(ExpectedError):
         fs.write_resource("lockspace", "resource", [("path", 1048576)])
     with self.assertRaises(fs.SanlockException) as e:
         fs.read_resource("path", 1048576)
     self.assertEqual(e.exception.errno, fs.SANLK_LEADER_MAGIC)
Example #9
0
 def test_acquire_lockspace_adding(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     fs.add_lockspace("lockspace", 1, "path", async=True)
     fd = fs.register()
     with self.assertRaises(fs.SanlockException) as e:
         fs.acquire("lockspace", "resource", [("path", 1048576)], slkfd=fd)
     self.assertEqual(e.exception.errno, errno.ENOSPC)
Example #10
0
 def test_write_resource_failure(self):
     fs = FakeSanlock()
     fs.errors["write_resource"] = ExpectedError
     with self.assertRaises(ExpectedError):
         fs.write_resource("lockspace", "resource", [("path", 1048576)])
     with self.assertRaises(fs.SanlockException) as e:
         fs.read_resource("path", 1048576)
     self.assertEqual(e.exception.errno, fs.SANLK_LEADER_MAGIC)
Example #11
0
class TestIndex(VdsmTestCase):
    def test_format(self):
        with make_volume() as vol:
            self.assertEqual(vol.leases(), {})

    def test_create_read_failure(self):
        with make_leases() as path:
            file = FailingReader(path)
            with utils.closing(file):
                with self.assertRaises(ReadError):
                    xlease.LeasesVolume("lockspace", file)

    def test_lookup_missing(self):
        with make_volume() as vol:
            with self.assertRaises(xlease.NoSuchLease):
                vol.lookup(make_uuid())

    def test_lookup_stale(self):
        record = xlease.Record(make_uuid(), xlease.RECORD_STALE)
        with make_volume((42, record)) as vol:
            leases = vol.leases()
            self.assertEqual(leases[record.resource]["state"], "STALE")
            with self.assertRaises(xlease.StaleLease):
                vol.lookup(record.resource)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            start_time = int(time.time())
            lease = vol.add(lease_id)
            self.assertEqual(lease.lockspace, vol.lockspace)
            self.assertEqual(lease.resource, lease_id)
            self.assertEqual(lease.path, vol.path)
            self.assertTrue(start_time <= lease.modified <= start_time + 1)
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            self.assertEqual(res["lockspace"], lease.lockspace)
            self.assertEqual(res["resource"], lease.resource)

    def test_add_write_failure(self):
        with make_volume() as base:
            file = FailingWriter(base.path)
            with utils.closing(file):
                vol = xlease.LeasesVolume(base.lockspace, file)
                with utils.closing(vol):
                    lease_id = make_uuid()
                    with self.assertRaises(WriteError):
                        vol.add(lease_id)
                    # Must succeed becuase writng to storage failed
                    self.assertNotIn(lease_id, vol.leases())

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_sanlock_failure(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            sanlock = xlease.sanlock
            # Make sanlock fail to write a resource
            sanlock.errors["write_resource"] = sanlock.SanlockException
            with self.assertRaises(sanlock.SanlockException):
                vol.add(lease_id)
            # We should have a stale lease record
            lease = vol.leases()[lease_id]
            self.assertEqual(lease["state"], "STALE")
            # There should be no lease on storage
            with self.assertRaises(sanlock.SanlockException) as e:
                sanlock.read_resource(vol.path, lease["offset"])
            self.assertEqual(e.exception.errno, sanlock.SANLK_LEADER_MAGIC)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_leases(self):
        with make_volume() as vol:
            uuid = make_uuid()
            lease_info = vol.add(uuid)
            leases = vol.leases()
            self.assertEqual(len(leases), 1)
            self.assertEqual(leases[uuid]["offset"], xlease.LEASE_BASE)
            self.assertEqual(leases[uuid]["state"], "USED")
            self.assertEqual(leases[uuid]["modified"], lease_info.modified)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_exists(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            lease = vol.add(lease_id)
            with self.assertRaises(xlease.LeaseExists):
                vol.add(lease_id)
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            self.assertEqual(res["lockspace"], lease.lockspace)
            self.assertEqual(res["resource"], lease.resource)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_lookup_exists(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            add_info = vol.add(lease_id)
            lookup_info = vol.lookup(lease_id)
            self.assertEqual(add_info, lookup_info)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_remove_exists(self):
        with make_volume() as vol:
            leases = [make_uuid() for i in range(3)]
            for lease in leases:
                vol.add(lease)
            lease = vol.lookup(leases[1])
            vol.remove(lease.resource)
            self.assertNotIn(lease.resource, vol.leases())
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            # There is no sanlock api for removing a resource, so we mark a
            # removed resource with empty (invalid) lockspace and lease id.
            self.assertEqual(res["lockspace"], "")
            self.assertEqual(res["resource"], "")

    def test_remove_missing(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            with self.assertRaises(xlease.NoSuchLease):
                vol.remove(lease_id)

    def test_remove_write_failure(self):
        record = xlease.Record(make_uuid(), xlease.RECORD_STALE)
        with make_volume((42, record)) as base:
            file = FailingWriter(base.path)
            with utils.closing(file):
                vol = xlease.LeasesVolume(base.lockspace, file)
                with utils.closing(vol):
                    with self.assertRaises(WriteError):
                        vol.remove(record.resource)
                    # Must succeed becuase writng to storage failed
                    self.assertIn(record.resource, vol.leases())

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_remove_sanlock_failure(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            vol.add(lease_id)
            sanlock = xlease.sanlock
            # Make sanlock fail to remove a resource (currnently removing a
            # resouce by writing invalid lockspace and resoruce name).
            sanlock.errors["write_resource"] = sanlock.SanlockException
            with self.assertRaises(sanlock.SanlockException):
                vol.remove(lease_id)
            # We should have a stale lease record
            lease = vol.leases()[lease_id]
            self.assertEqual(lease["state"], "STALE")
            # There lease should still be on storage
            res = sanlock.read_resource(vol.path, lease["offset"])
            self.assertEqual(res["lockspace"], vol.lockspace)
            self.assertEqual(res["resource"], lease_id)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_first_free_slot(self):
        with make_volume() as vol:
            uuids = [make_uuid() for i in range(4)]
            for uuid in uuids[:3]:
                vol.add(uuid)
            vol.remove(uuids[1])
            vol.add(uuids[3])
            leases = vol.leases()
            # The first lease in the first slot
            self.assertEqual(leases[uuids[0]]["offset"], xlease.LEASE_BASE)
            # The forth lease was added in the second slot after the second
            # lease was removed.
            self.assertEqual(leases[uuids[3]]["offset"],
                             xlease.LEASE_BASE + xlease.LEASE_SIZE)
            # The third lease in the third slot
            self.assertEqual(leases[uuids[2]]["offset"],
                             xlease.LEASE_BASE + xlease.LEASE_SIZE * 2)

    @slowtest
    def test_time_lookup(self):
        setup = """
import os
from testlib import make_uuid
from vdsm import utils
from vdsm.storage import xlease

path = "%s"
lockspace = os.path.basename(os.path.dirname(path))
lease_id = make_uuid()

def bench():
    file = xlease.DirectFile(path)
    with utils.closing(file):
        vol = xlease.LeasesVolume(lockspace, file)
        with utils.closing(vol, log="test"):
            try:
                vol.lookup(lease_id)
            except xlease.NoSuchLease:
                pass
"""
        with make_volume() as vol:
            count = 1000
            elapsed = timeit.timeit("bench()",
                                    setup=setup % vol.path,
                                    number=count)
            print("%d lookups in %.6f seconds (%.6f seconds per lookup)" %
                  (count, elapsed, elapsed / count))

    @slowtest
    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_time_add(self):
        setup = """
import os
from testlib import make_uuid
from vdsm import utils
from vdsm.storage import xlease

path = "%s"
lockspace = os.path.basename(os.path.dirname(path))

def bench():
    lease_id = make_uuid()
    file = xlease.DirectFile(path)
    with utils.closing(file):
        vol = xlease.LeasesVolume(lockspace, file)
        with utils.closing(vol, log="test"):
            vol.add(lease_id)
"""
        with make_volume() as vol:
            count = 100
            elapsed = timeit.timeit("bench()",
                                    setup=setup % vol.path,
                                    number=count)
            # Note: this does not include the time to create the real sanlock
            # resource.
            print("%d adds in %.6f seconds (%.6f seconds per add)" %
                  (count, elapsed, elapsed / count))
Example #12
0
 def test_inq_lockspace_released(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     fs.rem_lockspace("lockspace", 1, "path")
     acquired = fs.inq_lockspace("lockspace", 1, "path")
     self.assertFalse(acquired, "lockspace not released")
Example #13
0
 def test_register(self):
     fs = FakeSanlock()
     self.assertEqual(fs.register(), 42)
Example #14
0
 def test_add_lockspace_async(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path", async=True)
     ls = fs.spaces["lockspace"]
     self.assertEqual(ls["iotimeout"], 0)
     self.assertFalse(ls["ready"].is_set(), "lockspace is ready")
Example #15
0
 def test_add_lockspace_options(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path", offset=42, iotimeout=10)
     ls = fs.spaces["lockspace"]
     self.assertEqual(ls["offset"], 42)
     self.assertEqual(ls["iotimeout"], 10)
Example #16
0
 def test_acquire_an_acquired_resource(self):
     fs = FakeSanlock()
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     fs.add_lockspace("lockspace", 1, "path")
     fd = fs.register()
     fs.acquire("lockspace", "resource", [("path", 1048576)], slkfd=fd)
     with self.assertRaises(fs.SanlockException) as e:
         fs.acquire("lockspace", "resource", [("path", 1048576)], slkfd=fd)
     self.assertEqual(e.exception.errno, errno.EEXIST)
     res = fs.read_resource("path", 1048576)
     self.assertTrue(res["acquired"], "resource is not acquired")
Example #17
0
 def test_non_existing_resource(self):
     fs = FakeSanlock()
     with self.assertRaises(fs.SanlockException) as e:
         fs.read_resource("path", 1048576)
     self.assertEqual(e.exception.errno, fs.SANLK_LEADER_MAGIC)
Example #18
0
 def test_rem_lockspace_sync(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     fs.rem_lockspace("lockspace", 1, "path")
     self.assertNotIn("lockspace", fs.spaces)
Example #19
0
 def test_read_resource_failure(self):
     fs = FakeSanlock()
     fs.errors["read_resource"] = ExpectedError
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     with self.assertRaises(ExpectedError):
         fs.read_resource("path", 1048576)
Example #20
0
 def test_rem_lockspace_async(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     fs.rem_lockspace("lockspace", 1, "path", async=True)
     ls = fs.spaces["lockspace"]
     self.assertFalse(ls["ready"].is_set(), "lockspace is ready")
Example #21
0
 def test_non_existing_resource(self):
     fs = FakeSanlock()
     with self.assertRaises(fs.SanlockException) as e:
         fs.read_resource("path", 1048576)
     self.assertEqual(e.exception.errno, fs.SANLK_LEADER_MAGIC)
Example #22
0
 def test_inq_lockspace_acquired(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     acquired = fs.inq_lockspace("lockspace", 1, "path")
     self.assertTrue(acquired, "lockspace not acquired")
Example #23
0
 def test_read_resource_failure(self):
     fs = FakeSanlock()
     fs.errors["read_resource"] = ExpectedError
     fs.write_resource("lockspace", "resource", [("path", 1048576)])
     with self.assertRaises(ExpectedError):
         fs.read_resource("path", 1048576)
Example #24
0
 def test_inq_lockspace_acquring_no_wait(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path", async=True)
     acquired = fs.inq_lockspace("lockspace", 1, "path")
     self.assertIsNone(acquired, "lockspace is ready")
Example #25
0
class TestIndex(VdsmTestCase):

    @MonkeyPatch(time, 'time', lambda: 123456789)
    def test_metadata(self):
        with make_volume() as vol:
            lockspace = os.path.basename(os.path.dirname(vol.path))
            self.assertEqual(vol.version, 1)
            self.assertEqual(vol.lockspace, lockspace)
            self.assertEqual(vol.mtime, 123456789)

    def test_magic_big_endian(self):
        with make_volume() as vol:
            with io.open(vol.path, "rb") as f:
                f.seek(xlease.INDEX_BASE)
                self.assertEqual(f.read(4), b"\x12\x15\x20\x16")

    def test_bad_magic(self):
        with make_leases() as path:
            self.check_invalid_index(path)

    def test_bad_version(self):
        with make_volume() as vol:
            with io.open(vol.path, "r+b") as f:
                f.seek(xlease.INDEX_BASE + 5)
                f.write(b"blah")
            self.check_invalid_index(vol.path)

    def test_unsupported_version(self):
        with make_volume() as vol:
            md = xlease.IndexMetadata(2, "lockspace")
            with io.open(vol.path, "r+b") as f:
                f.seek(xlease.INDEX_BASE)
                f.write(md.bytes())
            self.check_invalid_index(vol.path)

    def test_bad_lockspace(self):
        with make_volume() as vol:
            with io.open(vol.path, "r+b") as f:
                f.seek(xlease.INDEX_BASE + 10)
                f.write(b"\xf0")
            self.check_invalid_index(vol.path)

    def test_bad_mtime(self):
        with make_volume() as vol:
            with io.open(vol.path, "r+b") as f:
                f.seek(xlease.INDEX_BASE + 59)
                f.write(b"not a number")
            self.check_invalid_index(vol.path)

    def test_updating(self):
        with make_volume() as vol:
            md = xlease.IndexMetadata(xlease.INDEX_VERSION, "lockspace",
                                      updating=True)
            with io.open(vol.path, "r+b") as f:
                f.seek(xlease.INDEX_BASE)
                f.write(md.bytes())
            self.check_invalid_index(vol.path)

    def test_truncated_index(self):
        with make_volume() as vol:
            # Truncate index, reading it should fail.
            with io.open(vol.path, "r+b") as f:
                f.truncate(
                    xlease.INDEX_BASE + xlease.INDEX_SIZE - xlease.BLOCK_SIZE)
            self.check_invalid_index(vol.path)

    def check_invalid_index(self, path):
        file = xlease.DirectFile(path)
        with utils.closing(file):
            with self.assertRaises(xlease.InvalidIndex):
                vol = xlease.LeasesVolume(file)
                vol.close()

    def test_format(self):
        with make_volume() as vol:
            self.assertEqual(vol.leases(), {})

    def test_create_read_failure(self):
        with make_leases() as path:
            file = FailingReader(path)
            with utils.closing(file):
                with self.assertRaises(ReadError):
                    xlease.LeasesVolume(file)

    def test_lookup_missing(self):
        with make_volume() as vol:
            with self.assertRaises(xlease.NoSuchLease):
                vol.lookup(make_uuid())

    def test_lookup_updating(self):
        record = xlease.Record(make_uuid(), 0, updating=True)
        with make_volume((42, record)) as vol:
            leases = vol.leases()
            self.assertTrue(leases[record.resource]["updating"])
            with self.assertRaises(xlease.LeaseUpdating):
                vol.lookup(record.resource)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            lease = vol.add(lease_id)
            self.assertEqual(lease.lockspace, vol.lockspace)
            self.assertEqual(lease.resource, lease_id)
            self.assertEqual(lease.path, vol.path)
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            self.assertEqual(res["lockspace"], lease.lockspace)
            self.assertEqual(res["resource"], lease.resource)

    def test_add_write_failure(self):
        with make_volume() as base:
            file = FailingWriter(base.path)
            with utils.closing(file):
                vol = xlease.LeasesVolume(file)
                with utils.closing(vol):
                    lease_id = make_uuid()
                    with self.assertRaises(WriteError):
                        vol.add(lease_id)
                    # Must succeed becuase writng to storage failed
                    self.assertNotIn(lease_id, vol.leases())

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_sanlock_failure(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            sanlock = xlease.sanlock
            # Make sanlock fail to write a resource
            sanlock.errors["write_resource"] = sanlock.SanlockException
            with self.assertRaises(sanlock.SanlockException):
                vol.add(lease_id)
            # We should have an updating lease record
            lease = vol.leases()[lease_id]
            self.assertTrue(lease["updating"])
            # There should be no lease on storage
            with self.assertRaises(sanlock.SanlockException) as e:
                sanlock.read_resource(vol.path, lease["offset"])
            self.assertEqual(e.exception.errno, sanlock.SANLK_LEADER_MAGIC)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_leases(self):
        with make_volume() as vol:
            uuid = make_uuid()
            lease_info = vol.add(uuid)
            leases = vol.leases()
            expected = {
                uuid: {
                    "offset": lease_info.offset,
                    "updating": False,
                }
            }
            self.assertEqual(leases, expected)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_exists(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            lease = vol.add(lease_id)
            with self.assertRaises(xlease.LeaseExists):
                vol.add(lease_id)
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            self.assertEqual(res["lockspace"], lease.lockspace)
            self.assertEqual(res["resource"], lease.resource)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_lookup_exists(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            add_info = vol.add(lease_id)
            lookup_info = vol.lookup(lease_id)
            self.assertEqual(add_info, lookup_info)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_remove_exists(self):
        with make_volume() as vol:
            leases = [make_uuid() for i in range(3)]
            for lease in leases:
                vol.add(lease)
            lease = vol.lookup(leases[1])
            vol.remove(lease.resource)
            self.assertNotIn(lease.resource, vol.leases())
            sanlock = xlease.sanlock
            res = sanlock.read_resource(lease.path, lease.offset)
            # There is no sanlock api for removing a resource, so we mark a
            # removed resource with empty (invalid) lockspace and lease id.
            self.assertEqual(res["lockspace"], "")
            self.assertEqual(res["resource"], "")

    def test_remove_missing(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            with self.assertRaises(xlease.NoSuchLease):
                vol.remove(lease_id)

    def test_remove_write_failure(self):
        record = xlease.Record(make_uuid(), 0, updating=True)
        with make_volume((42, record)) as base:
            file = FailingWriter(base.path)
            with utils.closing(file):
                vol = xlease.LeasesVolume(file)
                with utils.closing(vol):
                    with self.assertRaises(WriteError):
                        vol.remove(record.resource)
                    # Must succeed becuase writng to storage failed
                    self.assertIn(record.resource, vol.leases())

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_remove_sanlock_failure(self):
        with make_volume() as vol:
            lease_id = make_uuid()
            vol.add(lease_id)
            sanlock = xlease.sanlock
            # Make sanlock fail to remove a resource (currnently removing a
            # resouce by writing invalid lockspace and resoruce name).
            sanlock.errors["write_resource"] = sanlock.SanlockException
            with self.assertRaises(sanlock.SanlockException):
                vol.remove(lease_id)
            # We should have an updating lease record
            lease = vol.leases()[lease_id]
            self.assertTrue(lease["updating"])
            # There lease should still be on storage
            res = sanlock.read_resource(vol.path, lease["offset"])
            self.assertEqual(res["lockspace"], vol.lockspace)
            self.assertEqual(res["resource"], lease_id)

    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_add_first_free_slot(self):
        with make_volume() as vol:
            uuids = [make_uuid() for i in range(4)]
            for uuid in uuids[:3]:
                vol.add(uuid)
            vol.remove(uuids[1])
            vol.add(uuids[3])
            leases = vol.leases()
            # The first lease in the first slot
            self.assertEqual(leases[uuids[0]]["offset"],
                             xlease.USER_RESOURCE_BASE)
            # The forth lease was added in the second slot after the second
            # lease was removed.
            self.assertEqual(leases[uuids[3]]["offset"],
                             xlease.USER_RESOURCE_BASE + xlease.SLOT_SIZE)
            # The third lease in the third slot
            self.assertEqual(leases[uuids[2]]["offset"],
                             xlease.USER_RESOURCE_BASE + xlease.SLOT_SIZE * 2)

    @pytest.mark.slow
    def test_time_lookup(self):
        setup = """
import os
from testlib import make_uuid
from vdsm import utils
from vdsm.storage import xlease

path = "%s"
lockspace = os.path.basename(os.path.dirname(path))
lease_id = make_uuid()

def bench():
    file = xlease.DirectFile(path)
    with utils.closing(file):
        vol = xlease.LeasesVolume(file)
        with utils.closing(vol, log="test"):
            try:
                vol.lookup(lease_id)
            except xlease.NoSuchLease:
                pass
"""
        with make_volume() as vol:
            count = 100
            elapsed = timeit.timeit("bench()", setup=setup % vol.path,
                                    number=count)
            print("%d lookups in %.6f seconds (%.6f seconds per lookup)"
                  % (count, elapsed, elapsed / count))

    @pytest.mark.slow
    @MonkeyPatch(xlease, "sanlock", FakeSanlock())
    def test_time_add(self):
        setup = """
import os
from testlib import make_uuid
from vdsm import utils
from vdsm.storage import xlease

path = "%s"
lockspace = os.path.basename(os.path.dirname(path))

def bench():
    lease_id = make_uuid()
    file = xlease.DirectFile(path)
    with utils.closing(file):
        vol = xlease.LeasesVolume(file)
        with utils.closing(vol, log="test"):
            vol.add(lease_id)
"""
        with make_volume() as vol:
            count = 100
            elapsed = timeit.timeit("bench()", setup=setup % vol.path,
                                    number=count)
            # Note: this does not include the time to create the real sanlock
            # resource.
            print("%d adds in %.6f seconds (%.6f seconds per add)"
                  % (count, elapsed, elapsed / count))
Example #26
0
 def test_inq_lockspace_releasing_no_wait(self):
     fs = FakeSanlock()
     fs.add_lockspace("lockspace", 1, "path")
     fs.rem_lockspace("lockspace", 1, "path", async=True)
     acquired = fs.inq_lockspace("lockspace", 1, "path")
     self.assertFalse(acquired, "lockspace not released")