def put(self, ticket_id): if not ticket_id: raise HTTPBadRequest("Ticket id is required") size = self.request.content_length if size is None: raise HTTPBadRequest("Content-Length header is required") if size < 0: raise HTTPBadRequest("Invalid Content-Length header: %r" % size) content_range = web.content_range(self.request) offset = content_range.start or 0 # For backward compatibility, we flush by default. flush = validate.enum(self.request.params, "flush", ("y", "n"), default="y") flush = (flush == "y") ticket = tickets.authorize(ticket_id, "write", offset, size) # TODO: cancel copy if ticket expired or revoked self.log.info( "Writing %d bytes at offset %d flush %s to %s for ticket %s", size, offset, flush, ticket.url.path, ticket_id) op = directio.Receive(ticket.url.path, self.request.body_file_raw, size, offset=offset, flush=flush, buffersize=self.config.daemon.buffer_size, clock=self.clock) try: ticket.run(op) except errors.PartialContent as e: raise HTTPBadRequest(str(e)) return web.response()
def test_receive_no_size(tmpdir, data, offset): dst = tmpdir.join("dst") dst.write("x" * offset) src = io.BytesIO(data) op = directio.Receive(str(dst), src, offset=offset) op.run() assert dst.read()[offset:] == data
def receive_unbuffered(tmpdir, chunks, size, bufsize): dst = tmpdir.join("dst") dst.write("") src = ioutil.UnbufferedStream(chunks) op = directio.Receive(str(dst), src, size, buffersize=bufsize) op.run() return dst.read()
def receive(tmpdir, data, size, offset=0): dst = tmpdir.join("dst") dst.write("x" * offset) src = io.BytesIO(data) op = directio.Receive(str(dst), src, size, offset=offset) op.run() with open(str(dst), "rb") as f: f.seek(offset) return f.read()
def test_receive_no_size(tmpfile, data, offset): with open(tmpfile, "wb") as f: f.write(b"x" * offset) src = io.BytesIO(data) op = directio.Receive(tmpfile, src, offset=offset) op.run() with io.open(tmpfile, "rb") as f: f.seek(offset) assert f.read(len(data)) == data
def receive(tmpfile, data, size, offset=0): with open(tmpfile, "wb") as f: f.write(b"x" * offset) src = io.BytesIO(data) op = directio.Receive(tmpfile, src, size, offset=offset) op.run() with open(tmpfile, "rb") as f: f.seek(offset) return f.read(size)
def test_receive_padd_to_block_size(tmpfile): with open(tmpfile, "wb") as f: f.write(b"x" * 400) size = 200 offset = 300 padding = BLOCKSIZE - size - offset src = io.BytesIO(b"y" * size) op = directio.Receive(tmpfile, src, size, offset=offset) op.run() with open(tmpfile, "rb") as f: # Data before offset is not modified. assert f.read(300) == b"x" * offset # Data after offset is modifed, flie extended. assert f.read(200) == b"y" * size # File padded to block size with zeroes. assert f.read() == b"\0" * padding
def test_receive_flush(tmpfile, monkeypatch, extra, calls): # This would be much cleaner when we add backend object implementing flush. fsync = os.fsync fsync_calls = [0] def counted_fsync(fd): fsync_calls[0] += 1 fsync(fd) monkeypatch.setattr("os.fsync", counted_fsync) data = b"x" * ops.BUFFERSIZE * 2 with open(tmpfile, "wb") as f: f.write(data) size = len(data) src = io.BytesIO(b"X" * size) op = directio.Receive(tmpfile, src, size, **extra) op.run() with io.open(tmpfile, "rb") as f: assert f.read() == src.getvalue() assert fsync_calls[0] == calls
def put(self, ticket_id): if not ticket_id: raise HTTPBadRequest("Ticket id is required") size = self.request.content_length if size is None: raise HTTPBadRequest("Content-Length header is required") if size < 0: raise HTTPBadRequest("Invalid Content-Length header: %r" % size) content_range = web.content_range(self.request) offset = content_range.start or 0 ticket = tickets.authorize(ticket_id, "write", offset + size) # TODO: cancel copy if ticket expired or revoked self.log.info("Writing %d bytes at offset %d to %s for ticket %s", size, offset, ticket["url"].path, ticket_id) op = directio.Receive(ticket["url"].path, self.request.body_file_raw, size, offset=offset, buffersize=self.config.daemon.buffer_size) op.run() return response()
def download_disk(adapter, estimated_size, size, dest, bufsize): op = directio.Receive(dest, adapter, size=size, buffersize=bufsize) with progress(op, estimated_size): op.run() adapter.finish()
def test_receive_busy(tmpfile): src = io.BytesIO(b"x" * directio.BLOCKSIZE) op = directio.Receive(str(tmpfile), src, directio.BLOCKSIZE) assert op.active
def extract_disk(ova_path, pos, disk_size, image_path): send = directio.Send(ova_path, None, offset=pos, size=disk_size, buffersize=BUF_SIZE) op = directio.Receive(image_path, SendAdapter(send), size=disk_size, buffersize=BUF_SIZE) op.run()
def test_receive_close_on_error(tmpfile): src = io.BytesIO(b"x" * directio.BLOCKSIZE) op = directio.Receive(str(tmpfile), src, directio.BLOCKSIZE + 1) with pytest.raises(errors.PartialContent): op.run() assert not op.active
def test_receive_close_on_success(tmpfile): src = io.BytesIO(b"x" * directio.BLOCKSIZE) op = directio.Receive(str(tmpfile), src, directio.BLOCKSIZE) op.run() assert not op.active
def test_receive_close_twice(tmpfile): src = io.BytesIO(b"x" * directio.BLOCKSIZE) op = directio.Receive(str(tmpfile), src, directio.BLOCKSIZE) op.run() op.close() # should do nothing assert not op.active
def receive_unbuffered(tmpfile, chunks, size, bufsize): src = util.UnbufferedStream(chunks) op = directio.Receive(tmpfile, src, size, buffersize=bufsize) op.run() with open(tmpfile, "rb") as f: return f.read()
def test_recv_repr(tmpfile): op = directio.Receive(tmpfile, None, 100, offset=42) rep = repr(op) assert "Receive" in rep assert "size=100 offset=42 buffersize=4096 done=0" in rep
def test_recv_repr_active(): op = directio.Receive("/path", None) op.close() assert "active" not in repr(op)
def test_recv_repr(): op = directio.Receive("/path", None, 100, offset=42) rep = repr(op) assert "Receive" in rep assert "path='/path' size=100 offset=42 buffersize=512 done=0" in rep