Пример #1
0
def test_put(service, tmpdir):
    image = testutils.create_tempfile(tmpdir, "image", "-------|after")
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.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() == "content|after"
Пример #2
0
def test_images_upload_max_size(tmpdir):
    image_size = 100
    content = "b" * image_size
    image = testutils.create_tempfile(tmpdir, "image", "")
    ticket = testutils.create_ticket(url="file://" + str(image),
                                     size=image_size)
    tickets.add(ticket)
    res = http.put("/images/" + ticket["uuid"], content)
    assert res.status == 200
    assert image.read() == content
Пример #3
0
def test_images_options_write():
    ticket = testutils.create_ticket(ops=["write"])
    tickets.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
Пример #4
0
def test_tickets_idle_time_inactive(fake_time):
    ticket = testutils.create_ticket()
    tickets.add(ticket)

    # Ticket idle time starts with ticket is added.
    assert tickets.get(ticket["uuid"]).idle_time == 0

    # Simulate time passing without any request.
    fake_time.now += 200
    assert tickets.get(ticket["uuid"]).idle_time == 200
Пример #5
0
def test_tickets_extend_invalid_timeout(fake_time):
    ticket = testutils.create_ticket()
    tickets.add(ticket)
    prev_ticket = tickets.get(ticket["uuid"]).info()
    body = json.dumps({"timeout": "invalid"})
    res = http.unix_request(config.tickets.socket, "PATCH",
                            "/tickets/%(uuid)s" % ticket, body)
    cur_ticket = tickets.get(ticket["uuid"]).info()
    assert res.status == 400
    assert cur_ticket == prev_ticket
Пример #6
0
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)
        tickets.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, tickets.get, ticket["uuid"])
Пример #7
0
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)
    tickets.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
Пример #8
0
def test_images_upload(tmpdir, flush):
    image = testutils.create_tempfile(tmpdir, "image", "-------|after")
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.add(ticket)
    uri = "/images/" + ticket["uuid"]
    if flush:
        uri += "?flush=" + flush
    res = http.put(uri, "content")
    assert image.read() == "content|after"
    assert res.status == 200
    assert res.getheader("content-length") == "0"
Пример #9
0
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)
    tickets.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
Пример #10
0
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))
    tickets.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
Пример #11
0
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))
    tickets.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 tickets.get(ticket["uuid"]).idle_time == 0
Пример #12
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)
    tickets.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
Пример #13
0
def test_tickets_extend_expired_ticket(fake_time):
    ticket = testutils.create_ticket()
    tickets.add(ticket)
    # Make the ticket expire.
    fake_time.now += 500
    server_ticket = tickets.get(ticket["uuid"]).info()
    # Extend the expired ticket.
    body = json.dumps({"timeout": 300})
    res = http.unix_request(config.tickets.socket, "PATCH",
                            "/tickets/%(uuid)s" % ticket, body)
    assert res.status == 200
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 800
Пример #14
0
def test_images_options_ticket_expired(fake_time):
    ticket = testutils.create_ticket(timeout=300)
    tickets.add(ticket)
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300

    # Make the ticket expire
    fake_time.now += 300
    res = http.options("/images/" + ticket["uuid"])
    assert res.status == 403

    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300
Пример #15
0
def test_images_options_extends_ticket(fake_time):
    ticket = testutils.create_ticket()
    tickets.add(ticket)
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300

    fake_time.now += 200
    res = http.options("/images/" + ticket["uuid"])
    assert res.status == 200

    res.read()
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 500
Пример #16
0
def test_tickets_get(fake_time):
    ticket = testutils.create_ticket(ops=["read"], sparse=False)
    tickets.add(ticket)
    fake_time.now += 200
    res = http.unix_request(config.tickets.socket, "GET",
                            "/tickets/%(uuid)s" % ticket)
    assert res.status == 200
    server_ticket = json.loads(res.read())
    # The server adds an expires key
    del server_ticket["expires"]
    ticket["active"] = False
    ticket["transferred"] = 0
    ticket["idle_time"] = 200
    assert server_ticket == ticket
Пример #17
0
def test_images_upload_extends_ticket(tmpdir, fake_time):
    image = testutils.create_tempfile(tmpdir, "image", "before")
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.add(ticket)
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300

    fake_time.now += 200
    res = http.put("/images/" + ticket["uuid"], "")
    assert res.status == 200

    res.read()
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 500
Пример #18
0
def test_images_download_extends_ticket(tmpdir, fake_time):
    size = 1024
    image = testutils.create_tempfile(tmpdir, "image", size=size)
    ticket = testutils.create_ticket(url="file://" + str(image), size=size)
    tickets.add(ticket)
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300

    fake_time.now += 200
    res = http.get("/images/" + ticket["uuid"])
    assert res.status == 200

    res.read()
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 500
Пример #19
0
def test_tickets_extend(fake_time):
    ticket = testutils.create_ticket(sparse=False)
    tickets.add(ticket)
    patch = {"timeout": 300}
    body = json.dumps(patch)
    fake_time.now += 240
    res = http.unix_request(config.tickets.socket, "PATCH",
                            "/tickets/%(uuid)s" % ticket, body)
    ticket["expires"] = int(fake_time.now + ticket["timeout"])
    ticket["active"] = False
    ticket["idle_time"] = 240
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert res.status == 200
    assert res.getheader("content-length") == "0"
    assert server_ticket == ticket
Пример #20
0
def test_images_download_partial_no_range(tmpdir):
    # The image is smaller than the tiket size, but we don't request a range,
    # so we should get the existing length of the image, since the ticket size
    # is only an upper limit. Or maybe we should treat the ticket size as the
    # expected size?
    # This is another variant of 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)
    tickets.add(ticket)
    res = http.get("/images/" + ticket["uuid"])
    assert res.status == http_client.OK
    # Should return the available image data, not the ticket size. Reading this
    # response will fail with IncompleteRead.
    assert res.length == 1024
Пример #21
0
def test_images_flush_extends_ticket(tmpdir, fake_time):
    data = "x" * 512
    image = testutils.create_tempfile(tmpdir, "image", data)
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.add(ticket)
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 300

    fake_time.now += 200
    body = json.dumps({"op": "flush"}).encode("ascii")
    res = http.patch("/images/" + ticket["uuid"], body)
    assert res.status == 200

    res.read()
    server_ticket = tickets.get(ticket["uuid"]).info()
    assert server_ticket["expires"] == 500
Пример #22
0
def test_images_zero(tmpdir, msg):
    data = "x" * 512
    image = testutils.create_tempfile(tmpdir, "image", data)
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.add(ticket)
    size = msg["size"]
    offset = msg.get("offset", 0)
    body = json.dumps(msg).encode("ascii")
    res = http.patch("/images/" + ticket["uuid"], body)

    assert res.status == 200
    assert res.getheader("content-length") == "0"
    with io.open(str(image), "rb") as f:
        assert f.read(offset) == data[:offset]
        assert f.read(size) == b"\0" * size
        assert f.read() == data[offset + size:]
Пример #23
0
def test_images_zero(service, tmpdir):
    data = "x" * 512
    image = testutils.create_tempfile(tmpdir, "image", data)
    ticket = testutils.create_ticket(url="file://" + str(image))
    tickets.add(ticket)
    msg = {"op": "zero", "size": 20, "offset": 10, "future": True}
    size = msg["size"]
    offset = msg.get("offset", 0)
    body = json.dumps(msg).encode("ascii")
    res = http.unix_request(
        service.address, "PATCH", "/images/" + ticket["uuid"], body)
    assert res.status == http_client.OK
    assert res.getheader("content-length") == "0"
    with io.open(str(image), "rb") as f:
        assert f.read(offset) == data[:offset]
        assert f.read(size) == b"\0" * size
        assert f.read() == data[offset + size:]
Пример #24
0
def test_keep_alive_connection_on_success(tmpdir, method, body):
    # After successful request the connection should remain open.
    image = testutils.create_tempfile(tmpdir, "image", size=1024)
    ticket = testutils.create_ticket(url="file://" + str(image), size=1024)
    tickets.add(ticket)
    uri = "/images/%(uuid)s" % ticket
    con = http.connection()
    with closing(con):
        # Disabling auto_open so we can test if a connection was closed.
        con.auto_open = False
        con.connect()

        # Send couple of requests - all should succeed.
        for i in range(3):
            con.request(method, uri, body=body)
            r1 = http.response(con)
            r1.read()
            assert r1.status == 200
Пример #25
0
def test_tickets_idle_time_active(fake_time, tmpdir):
    filename = tmpdir.join("image")
    # Note: must be big enough so the request remain active.
    size = 1024**2 * 10
    with open(str(filename), 'wb') as image:
        image.truncate(size)
    ticket = testutils.create_ticket(url="file://" + str(filename),
                                     ops=["read"],
                                     size=size)
    tickets.add(ticket)

    # Start a download, but read only 1 byte to make sure the operation becomes
    # active but do not complete.
    res = http.get("/images/" + ticket["uuid"])
    res.read(1)

    # Active ticket idle time is always 0.
    fake_time.now += 200
    assert tickets.get(ticket["uuid"]).idle_time == 0
Пример #26
0
def test_get_forbidden(service):
    ticket = testutils.create_ticket(url="file:///no/such/image", ops=())
    tickets.add(ticket)
    res = http.unix_request(service.address, "GET",
                            "/images/" + ticket["uuid"], "content")
    assert res.status == http_client.FORBIDDEN
Пример #27
0
def test_images_flush_ticket_readonly(tmpdir):
    ticket = testutils.create_ticket(url="file:///no/such/image", ops=["read"])
    tickets.add(ticket)
    body = json.dumps({"op": "flush"}).encode("ascii")
    res = http.patch("/images/" + ticket["uuid"], body)
    assert res.status == 403
Пример #28
0
def test_images_upload_forbidden(tmpdir):
    ticket = testutils.create_ticket(url="file:///no/such/image", ops=["read"])
    tickets.add(ticket)
    res = http.put("/images/" + ticket["uuid"], "content")
    assert res.status == 403
Пример #29
0
def test_images_upload_content_length_missing(tmpdir):
    ticket = testutils.create_ticket(url="file:///no/such/image")
    tickets.add(ticket)
    res = http.raw_request("PUT", "/images/" + ticket["uuid"])
    assert res.status == 400
Пример #30
0
def test_images_upload_invalid_flush(tmpdir):
    ticket = testutils.create_ticket(url="file:///no/such/image")
    tickets.add(ticket)
    res = http.put("/images/" + ticket["uuid"] + "?flush=invalid", "data")
    assert res.status == 400