Пример #1
0
def test_transfered_ongoing_overlapping_ops():
    ticket = Ticket(testutil.create_ticket(ops=["read"]))

    # Start 2 ongoing operations.
    # ongoing: 0-0, 80-80
    # completed:
    op1 = Operation(0, 120)
    op2 = Operation(80, 120)
    ticket._add_operation(op1)
    ticket._add_operation(op2)
    assert ticket.transferred() == 0
    assert ticket.active()

    # Consume op1 data:
    # ongoing: 0-120, 80-80
    # completed:
    op1.run()
    ticket._remove_operation(op1)
    assert ticket.transferred() == 120
    assert ticket.active()

    # Consume op2 data:
    # ongoing: 0-120, 80-200
    # completed:
    op2.run()
    ticket._remove_operation(op2)
    assert ticket.transferred() == 200
    assert not ticket.active()
Пример #2
0
def test_transfered_ongoing_non_continues_ops():
    ticket = Ticket(testutil.create_ticket(ops=["read"]))

    # Start 2 ongoing operations.
    # ongoing: 0-0, 200-200
    # completed:
    op1 = Operation(0, 100)
    op2 = Operation(200, 100)
    ticket._add_operation(op1)
    ticket._add_operation(op2)
    assert ticket.transferred() == 0
    assert ticket.active()

    # Consume op1 data:
    # ongoing: 0-100, 200-200
    # completed:
    op1.run()
    ticket._remove_operation(op1)
    assert ticket.transferred() == 100

    # Consume op2 data:
    # ongoing: 0-100, 200-300
    # completed:
    op2.run()
    ticket._remove_operation(op2)
    assert ticket.transferred() == 200
Пример #3
0
def test_cancel_timeout(cfg):
    ticket = Ticket(testutil.create_ticket(ops=["read"]), cfg)

    # Add conection - having connections does not block cancelation, but we
    # cannot have ongoing operations without a connection.
    ctx = Context()
    ticket.add_context(1, ctx)

    # Ongoing operation blocks cancel.
    ticket._add_operation(Operation(0, 100))

    # Canceling will time out.
    with pytest.raises(errors.TransferCancelTimeout):
        ticket.cancel(timeout=0.001)

    # Ticket is marked as canceled, but the context was not closed.
    assert ticket.canceled
    assert not ctx.closed

    # Caller can poll ticket "active" property and remove the ticket when the
    # ticket is inactive.
    info = ticket.info()
    assert info["canceled"]
    assert info["active"]
    assert info["connections"] == 1
Пример #4
0
def test_transfered_ongoing_concurrent_ops(cfg):
    ticket = Ticket(testutil.create_ticket(ops=["read"]), cfg)

    # Start 2 ongoing operations:
    # ongoing: 0-0, 100-100
    # completed:
    op1 = Operation(0, 100)
    ticket._add_operation(op1)
    assert ticket.transferred() == 0
    assert ticket.active()

    op2 = Operation(100, 100)
    ticket._add_operation(op2)
    assert ticket.transferred() == 0
    assert ticket.active()

    # Consume op1 data:
    # ongoing: 0-100, 100-100
    # completed:
    op1.run()
    ticket._remove_operation(op1)
    assert ticket.transferred() == 100
    assert ticket.active()

    # Consume op2 data:
    # ongoing: 0-100, 100-200
    # completed:
    op2.run()
    ticket._remove_operation(op2)
    assert ticket.transferred() == 200
    assert not ticket.active()
Пример #5
0
def test_cancel_async(cfg):
    ticket = Ticket(testutil.create_ticket(ops=["read"]), cfg)
    ctx = Context()
    ticket.add_context(1, ctx)
    ticket._add_operation(Operation(0, 100))
    ticket.cancel(timeout=0)

    # Ticket is marked as canceled, but the context was not closed.
    assert ticket.canceled
    assert not ctx.closed

    info = ticket.info()
    assert info["canceled"]
    assert info["active"]
    assert info["connections"] == 1
Пример #6
0
def test_cancel_ongoing_operations():
    ticket = Ticket(testutil.create_ticket(ops=["read"]))

    # Few connections are using this ticket. Each running an operation.
    ops = []
    for i in range(4):
        ctx = Context()
        op = Operation()
        ticket.add_context(i, ctx)
        ticket._add_operation(op)
        ops.append(op)

    ticket.cancel(timeout=0)

    # All ongoing operations are canceled.
    assert all(op.canceled for op in ops)
Пример #7
0
def test_cancel_wait(cfg):
    ticket = Ticket(testutil.create_ticket(ops=["read"]), cfg)

    # Add connections using this ticket.
    users = []
    for cid in range(4):
        ctx = Context()
        op = Operation(cid * 1024**2, 1024**2)
        ticket.add_context(cid, ctx)
        ticket._add_operation(op)
        users.append((cid, ctx, op))

    # Add idle connection.
    idle_ctx = Context()
    ticket.add_context(4, idle_ctx)

    def finish_operations():
        time.sleep(0.1)
        for cid, ctx, op in users:
            # Removing operation from a canceled ticket raises, send and error
            # and close the connection.
            try:
                ticket._remove_operation(op)
            except errors.AuthorizationError:
                ticket.remove_context(cid)

    info = ticket.info()
    assert not info["canceled"]
    assert info["connections"] == 5
    assert info["active"]

    t = util.start_thread(finish_operations)
    try:
        ticket.cancel(timeout=10)
    finally:
        t.join()

    info = ticket.info()

    # After the ticket was canceled, ticket is inactive, and all ongoging
    # connnections removed from ticket. The idle connection is left, but its
    # context is closed.

    assert not info["active"]
    assert info["connections"] == 1
    assert all(ctx.closed for cid, ctx, op in users)
    assert idle_ctx.closed
Пример #8
0
def test_transferred_benchmark(concurrent):
    # Time trransferred call with multiple ongoing and completed operations.
    ticket = Ticket(testutil.create_ticket(ops=["read"]))

    calls = 10000

    # Add some completed ranges - assume worst case when ranges are not
    # continues.
    for i in range(concurrent):
        ticket.run(Operation(i * 1000, 100))

    # Add some ongoing operations - assume worst case when ranges are not
    # continues.
    for i in range(concurrent):
        ticket._add_operation(Operation(i * 1000 + 200, 100))

    # Time transferred call - merging ongoing and completed ranges.
    start = time.monotonic()
    for i in range(calls):
        ticket.transferred()
    elapsed = time.monotonic() - start

    print("%d concurrent operations, %d calls in %.3f seconds (%d nsec/op)"
          % (concurrent, calls, elapsed, elapsed * 10**9 // calls))
Пример #9
0
def test_transferred_benchmark(cfg, workers):
    # Time trransferred call with multiple ongoing and completed operations.
    ticket = Ticket(testutil.create_ticket(ops=["read"]), cfg)

    ops = 10000

    # Add some completed ranges - assume worst case when ranges are not
    # continues.
    for i in range(workers):
        ticket.run(Operation(i * 1000, 100))

    # Add some ongoing operations - assume worst case when ranges are not
    # continues.
    for i in range(workers):
        ticket._add_operation(Operation(i * 1000 + 200, 100))

    # Time transferred call - merging ongoing and completed ranges.
    start = time.monotonic()
    for i in range(ops):
        ticket.transferred()
    elapsed = time.monotonic() - start

    print("%d workers, %d ops, %.3f s, %.2f ops/s" %
          (workers, ops, elapsed, ops / elapsed))