def test_get_forbidden(service): ticket = testutils.create_ticket( url="file:///no/such/image", ops=[]) auth.add(ticket) res = http.unix_request( service.address, "GET", "/images/" + ticket["uuid"], "content") assert res.status == http_client.FORBIDDEN
def test_images_response_version_success(tmpdir): image = testutils.create_tempfile(tmpdir, "image", "old") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "new") assert res.status == 200 assert res.version == 11
def test_images_upload_content_length_negative(tmpdir): image = testutils.create_tempfile(tmpdir, "image", "before") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.raw_request("PUT", "/images/" + ticket["uuid"], headers={"content-length": "-1"}) assert res.status == 400
def test_images_upload_content_length_negative(tmpdir): image = testutils.create_tempfile(tmpdir, "image", b"before") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.raw_request("PUT", "/images/" + ticket["uuid"], headers={"content-length": "-1"}) assert res.status == 400
def test_images_upload_no_content(tmpdir): # This is a pointless request, but valid image = testutils.create_tempfile(tmpdir, "image", b"before") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "") assert res.status == 200
def test_images_download_ticket_size_gt_image_size(tmpdir): image = testutils.create_tempfile(tmpdir, "image", size=4096) ticket = testutils.create_ticket(url="file://" + str(image), size=8192) auth.add(ticket) res = http.get("/images/" + ticket["uuid"]) assert res.status == 200 assert len(res.read()) == 4096
def test_images_response_version_success(tmpdir): image = testutils.create_tempfile(tmpdir, "image", b"old") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "new") assert res.status == 200 assert res.version == 11
def test_images_zero_ticket_readonly(tmpdir): ticket = testutils.create_ticket( url="file:///no/such/image", ops=["read"]) auth.add(ticket) body = json.dumps({"op": "zero", "size": 1}).encode("ascii") res = http.patch("/images/" + ticket["uuid"], body) assert res.status == 403
def test_images_flush_ticket_readonly(tmpdir): ticket = testutils.create_ticket( url="file:///no/such/image", ops=["read"]) auth.add(ticket) body = json.dumps({"op": "flush"}).encode("ascii") res = http.patch("/images/" + ticket["uuid"], body) assert res.status == 403
def test_images_upload_no_content(tmpdir): # This is a pointless request, but valid image = testutils.create_tempfile(tmpdir, "image", "before") ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "") assert res.status == 200
def test_tickets_idle_time_options(fake_time): ticket = testutils.create_ticket(url="file:///no/such/file") auth.add(ticket) # Request must reset idle time. fake_time.now += 200 http.options("/images/" + ticket["uuid"]) assert auth.get(ticket["uuid"]).idle_time == 0
def test_images_download_range_unavailable(tmpdir): image = testutils.create_tempfile(tmpdir, "image", size=8192) ticket = testutils.create_ticket(url="file://" + str(image), size=4096) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": "bytes=0-4096"}) assert res.status == 416 assert res.getheader("Content-Range") == "bytes */4096"
def test_tickets_extend_negative_timeout(): ticket = testutils.create_ticket(sparse=False) auth.add(ticket) patch = {"timeout": -1} body = json.dumps(patch) res = http.unix_request( config.tickets.socket, "PATCH", "/tickets/%(uuid)s" % ticket, body) assert res.status == 400
def test_tickets_get_expired_ticket(fake_time): ticket = testutils.create_ticket() auth.add(ticket) # Make the ticket expire. fake_time.now += 500 res = http.unix_request( config.tickets.socket, "GET", "/tickets/%(uuid)s" % ticket) assert res.status == 200
def test_images_download_empty(tmpdir): # Stupid edge case, but it should work, returning empty file :-) image = testutils.create_tempfile(tmpdir, "image") # Empty image ticket = testutils.create_ticket(url="file://" + str(image), size=0) auth.add(ticket) res = http.get("/images/" + ticket["uuid"]) assert res.status == 200 data = res.read() assert data == b""
def test_images_download_no_range(tmpdir): size = 1024 image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size) auth.add(ticket) res = http.get("/images/" + ticket["uuid"]) assert res.status == 200 received = res.read() assert received == "\0" * size
def test_tickets_idle_time_get(fake_time, tmpdir): image = testutils.create_tempfile(tmpdir, "image", "a" * 8192) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) # Request must reset idle time. fake_time.now += 200 http.get("/images/" + ticket["uuid"]) assert auth.get(ticket["uuid"]).idle_time == 0
def test_images_upload_too_big(tmpdir): image_size = 100 image = testutils.create_tempfile(tmpdir, "image", "") ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "b" * (image_size + 1)) assert res.status == 403 assert image.read() == ""
def test_images_upload_with_range(tmpdir, crange, before, after): image = testutils.create_tempfile(tmpdir, "image", before) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "content", headers={"Content-Range": crange}) with io.open(str(image), "rb") as f: assert f.read(len(after)) == after assert res.status == 200
def test_tickets_delete_one(): ticket = testutils.create_ticket() auth.add(ticket) res = http.unix_request( config.tickets.socket, "DELETE", "/tickets/%(uuid)s" % ticket) assert res.status == 204 # Note: incorrect according to RFC, but required for vdsm. assert res.getheader("content-length") == "0" pytest.raises(KeyError, auth.get, ticket["uuid"])
def test_images_options_read(): ticket = testutils.create_ticket(ops=["read"]) auth.add(ticket) res = http.options("/images/" + ticket["uuid"]) allows = {"OPTIONS", "GET"} features = set() assert res.status == 200 assert set(res.getheader("allow").split(',')) == allows assert set(json.loads(res.read())["features"]) == features
def test_images_download_out_of_range(tmpdir, rng, end): data = "a" * 512 + "b" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image), size=end) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": rng}) res.read() assert res.status == 403
def test_tickets_idle_time_get(fake_time, tmpdir): image = testutils.create_tempfile(tmpdir, "image", b"a" * 8192) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) # Request must reset idle time. fake_time.now += 200 http.get("/images/" + ticket["uuid"]) assert auth.get(ticket["uuid"]).idle_time == 0
def test_images_upload_too_big(tmpdir): image_size = 100 image = testutils.create_tempfile(tmpdir, "image", b"") ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "b" * (image_size + 1)) assert res.status == 416 assert image.read() == ""
def test_images_download_no_range(tmpdir): size = 1024 image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size) auth.add(ticket) res = http.get("/images/" + ticket["uuid"]) assert res.status == 200 received = res.read() assert received == b"\0" * size
def test_tickets_extend_no_ticket_id(fake_time): ticket = testutils.create_ticket() auth.add(ticket) prev_ticket = auth.get(ticket["uuid"]).info() body = json.dumps({"timeout": 300}) res = http.unix_request(config.tickets.socket, "PATCH", "/tickets/", body) cur_ticket = auth.get(ticket["uuid"]).info() assert res.status == 400 assert cur_ticket == prev_ticket
def test_images_download_out_of_range(tmpdir, rng, end): data = b"a" * 512 + b"b" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image), size=end) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": rng}) res.read() assert res.status == 416
def test_images_options_read_write(): ticket = testutils.create_ticket(ops=["read", "write"]) auth.add(ticket) res = http.options("/images/" + ticket["uuid"]) allows = {"OPTIONS", "GET", "PUT", "PATCH"} features = {"zero", "flush"} assert res.status == 200 assert set(res.getheader("allow").split(',')) == allows assert set(json.loads(res.read())["features"]) == features
def test_images_options_write(): ticket = testutils.create_ticket(ops=["write"]) auth.add(ticket) res = http.options("/images/" + ticket["uuid"]) # Having "write" imply also "read". allows = {"OPTIONS", "GET", "PUT", "PATCH"} features = {"zero", "flush"} assert res.status == 200 assert set(res.getheader("allow").split(',')) == allows assert set(json.loads(res.read())["features"]) == features
def test_tickets_idle_time_inactive(fake_time): ticket = testutils.create_ticket() auth.add(ticket) # Ticket idle time starts with ticket is added. assert auth.get(ticket["uuid"]).idle_time == 0 # Simulate time passing without any request. fake_time.now += 200 assert auth.get(ticket["uuid"]).idle_time == 200
def test_tickets_extend_invalid_json(fake_time): ticket = testutils.create_ticket() auth.add(ticket) prev_ticket = auth.get(ticket["uuid"]).info() res = http.unix_request( config.tickets.socket, "PATCH", "/tickets/%(uuid)s" % ticket, "{invalid}") cur_ticket = auth.get(ticket["uuid"]).info() assert res.status == 400 assert cur_ticket == prev_ticket
def test_images_upload_after_last_byte(tmpdir): image_size = 100 image = testutils.create_tempfile(tmpdir, "image", "a" * image_size) ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "b", headers={"Content-Range": "bytes 100-101/*"}) assert res.status == 403 assert image.read() == "a" * image_size
def test_images_download_partial_no_range_empty(tmpdir): # Image is empty, no range, should return an empty file - we return invalid # http response that fail on the client side with BadStatusLine: ''. # See https://bugzilla.redhat.com/1512312 image = testutils.create_tempfile(tmpdir, "image") # Empty image ticket = testutils.create_ticket(url="file://" + str(image), size=1024) auth.add(ticket) res = http.get("/images/" + ticket["uuid"]) assert res.status == http_client.OK assert res.length == 0
def test_images_flush(tmpdir, msg): data = "x" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) body = json.dumps(msg).encode("ascii") res = http.patch("/images/" + ticket["uuid"], body) assert res.status == 200 assert res.getheader("content-length") == "0"
def test_images_download_holes(tmpdir): size = 1024 image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": "bytes=0-1023"}) assert res.status == 206 received = res.read() assert received == "\0" * size
def test_images_flush(tmpdir, msg): data = b"x" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) body = json.dumps(msg).encode("ascii") res = http.patch("/images/" + ticket["uuid"], body) assert res.status == 200 assert res.getheader("content-length") == "0"
def test_images_download_holes(tmpdir): size = 1024 image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": "bytes=0-1023"}) assert res.status == 206 received = res.read() assert received == b"\0" * size
def test_images_upload_after_last_byte(tmpdir): image_size = 100 image = testutils.create_tempfile(tmpdir, "image", b"a" * image_size) ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "b", headers={"Content-Range": "bytes 100-101/*"}) assert res.status == 416 assert image.read() == "a" * image_size
def test_get(service, tmpdir): data = b"a" * 512 + b"b" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket( url="file://" + str(image), size=1024) auth.add(ticket) res = http.unix_request( service.address, "GET", "/images/" + ticket["uuid"]) assert res.status == http_client.OK assert res.read() == data
def test_images_download_filename_in_ticket(tmpdir): size = 1024 filename = u"\u05d0.raw" # hebrew aleph image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size, filename=filename) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": "bytes=0-1023"}) expected = "attachment; filename=\xd7\x90.raw" assert res.getheader("Content-Disposition") == expected
def test_images_upload_last_byte(tmpdir): image_size = 100 image = testutils.create_tempfile(tmpdir, "image", b"a" * image_size) ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], "b", headers={"Content-Range": "bytes 99-100/*"}) assert res.status == 200 with io.open(str(image), "rb") as f: assert f.read(image_size) == b"a" * 99 + b"b"
def test_tickets_idle_time_patch(fake_time, tmpdir, msg): image = testutils.create_tempfile(tmpdir, "image", "a" * 8192) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) # Request must reset idle time. fake_time.now += 200 body = json.dumps(msg).encode('ascii') http.patch("/images/" + ticket["uuid"], body, headers={"content-type": "application/json"}) assert auth.get(ticket["uuid"]).idle_time == 0
def test_images_upload_max_size(tmpdir): image_size = 100 content = b"b" * image_size image = testutils.create_tempfile(tmpdir, "image", "") ticket = testutils.create_ticket( url="file://" + str(image), size=image_size) auth.add(ticket) res = http.put("/images/" + ticket["uuid"], content) assert res.status == 200 with io.open(str(image), "rb") as f: assert f.read(len(content)) == content
def test_tickets_delete_all(): # Example usage: move host to maintenance for i in range(5): ticket = testutils.create_ticket( url="file:///var/run/vdsm/storage/foo%s" % i) auth.add(ticket) res = http.unix_request(config.tickets.socket, "DELETE", "/tickets/") assert res.status == 204 # Note: incorrect according to RFC, but required for vdsm. assert res.getheader("content-length") == "0" pytest.raises(KeyError, auth.get, ticket["uuid"])
def test_put(service, tmpdir): data = b"-------|after" image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) uri = "/images/" + ticket["uuid"] res = http.unix_request(service.address, "PUT", uri, "content") assert res.status == http_client.OK assert res.getheader("content-length") == "0" with io.open(str(image)) as f: assert f.read(len(data)) == "content|after"
def test_images_download(tmpdir, rng, start, end): data = "a" * 512 + "b" * 512 + "c" * 512 image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket( url="file://" + str(image), size=len(data)) auth.add(ticket) res = http.get("/images/" + ticket["uuid"], headers={"Range": rng}) assert res.status == 206 received = res.read() assert received == data[start:end] content_range = 'bytes %d-%d/%d' % (start, end-1, len(data)) assert res.getheader("Content-Range") == content_range
def test_images_upload(tmpdir, flush): data = b"-------|after" image = testutils.create_tempfile(tmpdir, "image", data) ticket = testutils.create_ticket(url="file://" + str(image)) auth.add(ticket) uri = "/images/" + ticket["uuid"] if flush: uri += "?flush=" + flush res = http.put(uri, "content") with io.open(str(image), "rb") as f: assert f.read(len(data)) == b"content|after" assert res.status == 200 assert res.getheader("content-length") == "0"
def test_images_download_partial_not_satistieble(tmpdir): # Image is smaller than ticket size - may happen if engine failed to detect # actual image size reported by vdsm - one byte difference is enough to # cause a failure. # See https://bugzilla.redhat.com/1512315. size = 1024 image = testutils.create_tempfile(tmpdir, "image", size=size) ticket = testutils.create_ticket(url="file://" + str(image), size=size + 1) auth.add(ticket) unsatisfiable_range = "bytes=0-%d" % size # Max is size - 1 res = http.get("/images/" + ticket["uuid"], headers={"Range": unsatisfiable_range}) assert res.status == http_client.REQUESTED_RANGE_NOT_SATISFIABLE