def uhttpserver(request): tmp = tempfile.NamedTemporaryFile() server = uhttp.Server(tmp.name, uhttp.Connection) util.start_thread(server.serve_forever, kwargs={"poll_interval": 0.1}) request.addfinalizer(server.shutdown) request.addfinalizer(tmp.close) return server
def test_start_thread_args(): result = [] def f(*a): result.extend(a) util.start_thread(f, args=(1, 2)).join() assert result == [1, 2]
def test_start_thread_kwargs(): result = {} def f(k=None): result["k"] = k util.start_thread(f, kwargs={"k": "v"}).join() assert result == {"k": "v"}
def test_cancel_wait(): ticket = Ticket(testutil.create_ticket(ops=["read"])) # Add connections using this ticket. connections = [] for i in range(4): ctx = Context() ticket.add_context(i, ctx) connections.append(ctx) def close_connections(): time.sleep(0.1) for i in range(4): ticket.remove_context(i) info = ticket.info() assert not info["canceled"] assert info["connections"] == 4 t = util.start_thread(close_connections) try: ticket.cancel(timeout=10) # After the ticket was canceled, number of connections must be zero. info = ticket.info() assert info["connections"] == 0 # And all contexts must be closed. assert all(ctx.closed for ctx in connections) finally: t.join()
def test_run_operation_benchmark(): # Run 1000000 operations with 4 concurrent threads. ticket = Ticket(testutil.create_ticket(ops=["read"])) operations = 10**6 workers = 4 chunk = 10**9 step = chunk * workers // operations def worker(offset, size): while offset < size: ticket.run(Operation(offset, step)) offset += step start = time.monotonic() threads = [] try: for i in range(workers): t = util.start_thread(worker, args=(i * chunk, chunk)) threads.append(t) finally: for t in threads: t.join() elapsed = time.monotonic() - start print("%d operations, %d concurrent threads in %.3f seconds (%d nsec/op)" % (operations, workers, elapsed, elapsed * 10**9 // operations))
def run(self): start = time.monotonic() threads = [] try: for i in range(self.workers): t = util.start_thread(self._worker, name=f"{self.name}/{i}") threads.append(t) finally: for t in threads: t.join() return time.monotonic() - start
def uhttp_server(tmp_pki): server = uhttp.Server("", uhttp.Connection) log.info("Server listening on %r", server.server_address) server.app = http.Router([]) t = util.start_thread(server.serve_forever, kwargs={"poll_interval": 0.1}) yield server server.shutdown() t.join()
def test_uninterruptible_interrupt(): r, w = os.pipe() signo = signal.SIGUSR1 prev = signal.signal(signo, lambda s, f: True) try: def read(): return os.read(r, 1) def write(): time.sleep(0.1) os.kill(os.getpid(), signo) time.sleep(0.1) os.write(w, b'a') util.start_thread(write) assert util.uninterruptible(read) == b'a' finally: signal.signal(signo, prev) os.close(r) os.close(w)
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
def http_server(tmp_pki): server = http.Server(("localhost", 0), http.Connection) log.info("Server listening on %r", server.server_address) ctx = ssl.server_context(tmp_pki.certfile, tmp_pki.keyfile, cafile=tmp_pki.cafile) server.socket = ctx.wrap_socket(server.socket, server_side=True) server.url = urlparse("https://localhost:{}/".format(server.server_port)) server.cafile = tmp_pki.cafile server.app = http.Router([]) t = util.start_thread(server.serve_forever, kwargs={"poll_interval": 0.1}) yield server server.shutdown() t.join()
def test_start_thread_non_daemon(): t = util.start_thread(lambda: None, daemon=False) t.join() assert not t.daemon
def test_start_thread_daemon(): t = util.start_thread(lambda: None) t.join() assert t.daemon
def test_start_thread_name(): t = util.start_thread(lambda: None, name="foo") t.join() assert t.name == "foo"