def test_base_allocation_some_data(nbd_server, user_file, fmt, zero_flags): size = 1024**3 create_image(user_file.path, fmt, size) nbd_server.image = user_file.path nbd_server.fmt = fmt nbd_server.start() # Use qcow2 cluster size to avoid inconsistent results on CentOS and # Fedora. data_length = 64 * 1024 zero_length = size // 2 - data_length with nbd.open(nbd_server.url) as c: # Create 4 extents: data, zero, data, zero. c.write(0, b"x" * data_length) c.write(size // 2, b"x" * data_length) extents = list(nbdutil.extents(c)) assert extents == [ nbd.Extent(length=data_length, flags=0), nbd.Extent(length=zero_length, flags=zero_flags), nbd.Extent(length=data_length, flags=0), nbd.Extent(length=zero_length, flags=zero_flags), ]
def test_some_data_offset(dirty): c = SomeData(1, dirty) extents = list(nbdutil.extents(c, offset=0, dirty=dirty)) assert extents == [ nbd.Extent(c.extent_size, 0), nbd.Extent(c.extent_size, 1), nbd.Extent(c.extent_size, 0), ]
def test_some_data_offset_unaligned(dirty): c = SomeData(1, dirty) extents = list( nbdutil.extents(c, offset=c.extent_size // 2 * 3, dirty=dirty)) assert extents == [ nbd.Extent(c.extent_size // 2, 1), nbd.Extent(c.extent_size, 0), ]
def test_extent_dirty_bitmap(): # Clean area. ext = nbd.Extent(4096, 0) assert not ext.dirty assert ext.flags == 0 # Dirty area. ext = nbd.Extent(4096, nbd.STATE_DIRTY) assert ext.dirty assert ext.flags == nbd.STATE_DIRTY
def reply(self, offset, length): extra = 128 * 1024**2 if offset + length + extra < self.export_size and length > extra: return [ nbd.Extent(length - extra, self.flags), nbd.Extent(2 * extra, self.flags), ] else: return [nbd.Extent(length, self.flags)]
def reply(self, offset, length): max_extent = 128 * 1024**2 if length > max_extent: length -= max_extent extents = [] while length > max_extent: extents.append(nbd.Extent(max_extent, self.flags)) length -= max_extent extents.append(nbd.Extent(length, self.flags)) return extents
def test_extent_base_allocation(): # Allocated aread with data. ext = nbd.Extent(4096, 0) assert not ext.zero assert ext.flags == 0 # Allocated aread that reads as zero. ext = nbd.Extent(4096, nbd.STATE_ZERO) assert ext.zero assert ext.flags == nbd.STATE_ZERO # Unallocated aread that reads as zero. ext = nbd.Extent(4096, nbd.STATE_ZERO | nbd.STATE_HOLE) assert ext.zero assert ext.flags == nbd.STATE_ZERO | nbd.STATE_HOLE
def reply(self, offset, length): index = offset // self.extent_size flags = self.flags if index % 2 else 0 max_length = self.extent_size - (offset % self.extent_size) length = min(length, max_length) return [nbd.Extent(length, flags)]
def test_base_allocation_full(nbd_server, user_file, fmt): size = 1024**2 create_image(user_file.path, fmt, size) nbd_server.image = user_file.path nbd_server.fmt = fmt nbd_server.start() with nbd.open(nbd_server.url) as c: c.write(0, b"x" * size) # Entire image. extents = c.extents(0, size)["base:allocation"] assert extents == [nbd.Extent(length=size, flags=0)] # First block. extents = c.extents(0, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=0)] # Last block. extents = c.extents(size - 4096, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=0)] # Some block. extents = c.extents(4096, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=0)] # Unaligned start. extents = c.extents(4096 - 1, 4096 + 1)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 1, flags=0)] # Unaligned end. extents = c.extents(4096, 4096 + 1)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 1, flags=0)] # Unaligned start and end. extents = c.extents(4096 - 1, 4096 + 2)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 2, flags=0)]
def test_base_allocation_empty(nbd_server, user_file, fmt, zero_flags): size = nbd.MAX_LENGTH create_image(user_file.path, fmt, size) nbd_server.image = user_file.path nbd_server.fmt = fmt nbd_server.start() with nbd.open(nbd_server.url) as c: # Entire image. extents = c.extents(0, size)["base:allocation"] assert extents == [nbd.Extent(length=size, flags=zero_flags)] # First block. extents = c.extents(0, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=zero_flags)] # Last block. extents = c.extents(size - 4096, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=zero_flags)] # Some block. extents = c.extents(4096, 4096)["base:allocation"] assert extents == [nbd.Extent(length=4096, flags=zero_flags)] # Unaligned start. extents = c.extents(4096 - 1, 4096 + 1)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 1, flags=zero_flags)] # Unaligned end. extents = c.extents(4096, 4096 + 1)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 1, flags=zero_flags)] # Unaligned start and end. extents = c.extents(4096 - 1, 4096 + 2)["base:allocation"] assert extents == [nbd.Extent(length=4096 + 2, flags=zero_flags)]
def test_base_allocation_some_data_unaligned(nbd_server, user_file, fmt, zero_flags): size = 1024**2 create_image(user_file.path, fmt, size) nbd_server.image = user_file.path nbd_server.fmt = fmt nbd_server.start() data_length = 64 * 1024 data_offset = 2 * data_length with nbd.open(nbd_server.url) as c: # Create 3 extents: zero, data, zero. c.write(data_offset, b"x" * data_length) # Unaligned part from first extent and last extent. extents = list(nbdutil.extents(c, data_offset - 1, data_length + 2)) assert extents == [ nbd.Extent(length=1, flags=zero_flags), nbd.Extent(length=data_length, flags=0), nbd.Extent(length=1, flags=zero_flags), ] # Unaligned part from second extent. extents = list(nbdutil.extents(c, data_offset + 1, data_length - 2)) assert extents == [ nbd.Extent(length=data_length - 2, flags=0), ] # Unaligned part from second and last extents. extents = list(nbdutil.extents(c, data_offset + 1, data_length)) assert extents == [ nbd.Extent(length=data_length - 1, flags=0), nbd.Extent(length=1, flags=zero_flags), ]
def test_single_extent(dirty): c = SingleExtent(1, dirty) extents = list(nbdutil.extents(c, dirty=dirty)) assert extents == [nbd.Extent(c.export_size, 1)]
def test_short_reply(dirty): c = ShortReply(1, dirty) extents = list(nbdutil.extents(c, dirty=dirty)) assert extents == [nbd.Extent(c.export_size, 1)]
def reply(self, offset, length): return [nbd.Extent(length, self.flags)]
def test_complete_reply(dirty): c = CompleteReply(1, dirty) extents = list(nbdutil.extents(c, dirty=dirty)) assert extents == [nbd.Extent(c.export_size, 1)]
def test_single_extent_offset(dirty, offset): c = SingleExtent(1, dirty) extents = list(nbdutil.extents(c, offset=offset, dirty=dirty)) assert extents == [nbd.Extent(c.export_size - offset, 1)]
def test_last_extent_exceeds_length(dirty, offset, length): c = ExcceedsLength(1, dirty) extents = list( nbdutil.extents(c, offset=offset, length=length, dirty=dirty)) assert extents == [nbd.Extent(length, 1)]
def test_short_reply_offset_length(dirty, offset, length): c = ShortReply(1, dirty) extents = list( nbdutil.extents(c, offset=offset, length=length, dirty=dirty)) assert extents == [nbd.Extent(length, 1)]
def test_short_reply_offset(dirty, offset): c = ShortReply(1, dirty) extents = list(nbdutil.extents(c, offset=offset, dirty=dirty)) assert extents == [nbd.Extent(c.export_size - offset, 1)]
def reply(self, offset, length): length = min(length, 128 * 1024**2) return [nbd.Extent(length, self.flags)]
def test_single_extent_offset_length(dirty, offset, length): c = SingleExtent(1, dirty) extents = list( nbdutil.extents(c, offset=offset, length=length, dirty=dirty)) assert extents == [nbd.Extent(length, 1)]