import ctypes import multiprocessing import threading import gc from time import sleep from db import Page id_conn_child = None def test_thread_pooling(db): id_conn_parent = id(db._connection) def f(): global id_conn_child assert len(db[Page]) > 0 # connect automatically id_conn_child = id(db._connection) sleep(0.2) thread = threading.Thread(target=f) thread.start() sleep(0.1) assert len(db._db.pool.all) - len(db._db.pool.available) == 2 thread.join() # Threadlocals die only when another thread accesses them db._root sleep(0.3) gc.collect() # TODO: close connection when thread dies assert len(db._db.pool.all) - len(db._db.pool.available) == 1 # Test that child used connection other than parent assert id_conn_child != id_conn_parent assert id_conn_child is not None def test_forking(db): id_conn_parent = id(db._connection) id_conn_child = multiprocessing.Value(ctypes.c_int64) def f(): assert len(db[Page]) > 0 # Check that DB is functional in the subprocess id_conn_child.value = id(db._connection) p = multiprocessing.Process(target=f) p.daemon = True p.start() p.join(10) # Test that child used connection other than parent assert id_conn_child.value != 0 assert id_conn_child.value != id_conn_parent