diff --git a/test/__init__.py b/test/__init__.py index b2906481e9..c432b26098 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -286,13 +286,8 @@ def hello(self): return self._hello def _connect(self, host, port, **kwargs): - # Jython takes a long time to connect. - if sys.platform.startswith("java"): - timeout_ms = 10000 - else: - timeout_ms = 5000 kwargs.update(self.default_client_options) - client = pymongo.MongoClient(host, port, serverSelectionTimeoutMS=timeout_ms, **kwargs) + client = pymongo.MongoClient(host, port, serverSelectionTimeoutMS=5000, **kwargs) try: try: client.admin.command(HelloCompat.LEGACY_CMD) # Can we connect? @@ -1037,21 +1032,26 @@ def _get_executors(topology): return [e for e in executors if e is not None] -def all_executors_stopped(topology): +def print_running_topology(topology): running = [e for e in _get_executors(topology) if not e._stopped] if running: print( - " Topology %s has THREADS RUNNING: %s, created at: %s" - % (topology, running, topology._settings._stack) + "WARNING: found Topology with running threads:\n" + " Threads: %s\n" + " Topology: %s\n" + " Creation traceback:\n%s" % (running, topology, topology._settings._stack) ) - return False - return True -def print_unclosed_clients(): +def print_running_clients(): from pymongo.topology import Topology processed = set() + # Avoid false positives on the main test client. + # XXX: Can be removed after PYTHON-1634 or PYTHON-1896. + c = client_context.client + if c: + processed.add(c._topology._topology_id) # Call collect to manually cleanup any would-be gc'd clients to avoid # false positives. gc.collect() @@ -1061,7 +1061,7 @@ def print_unclosed_clients(): # Avoid printing the same Topology multiple times. if obj._topology_id in processed: continue - all_executors_stopped(obj) + print_running_topology(obj) processed.add(obj._topology_id) except ReferenceError: pass @@ -1086,9 +1086,7 @@ def teardown(): c.drop_database("pymongo_test_bernie") c.close() - # Jython does not support gc.get_objects. - if not sys.platform.startswith("java"): - print_unclosed_clients() + print_running_clients() class PymongoTestRunner(unittest.TextTestRunner): diff --git a/test/test_client.py b/test/test_client.py index 29a5b0f1d5..a0d6e22d53 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -759,6 +759,7 @@ def test_list_databases(self): for doc in helper_docs: self.assertIs(type(doc), dict) client = rs_or_single_client(document_class=SON) + self.addCleanup(client.close) for doc in client.list_databases(): self.assertIs(type(doc), dict) @@ -979,6 +980,7 @@ def test_unix_socket(self): uri = "mongodb://%s" % encoded_socket # Confirm we can do operations via the socket. client = rs_or_single_client(uri) + self.addCleanup(client.close) client.pymongo_test.test.insert_one({"dummy": "object"}) dbs = client.list_database_names() self.assertTrue("pymongo_test" in dbs) @@ -1002,6 +1004,7 @@ def test_document_class(self): self.assertFalse(isinstance(db.test.find_one(), SON)) c = rs_or_single_client(document_class=SON) + self.addCleanup(c.close) db = c.pymongo_test self.assertEqual(SON, c.codec_options.document_class) @@ -1040,6 +1043,7 @@ def test_socket_timeout(self): no_timeout = self.client timeout_sec = 1 timeout = rs_or_single_client(socketTimeoutMS=1000 * timeout_sec) + self.addCleanup(timeout.close) no_timeout.pymongo_test.drop_collection("test") no_timeout.pymongo_test.test.insert_one({"x": 1}) @@ -1095,6 +1099,7 @@ def test_tz_aware(self): self.assertRaises(ValueError, MongoClient, tz_aware="foo") aware = rs_or_single_client(tz_aware=True) + self.addCleanup(aware.close) naive = self.client aware.pymongo_test.drop_collection("test") @@ -1124,6 +1129,7 @@ def test_ipv6(self): uri += "/?replicaSet=" + (client_context.replica_set_name or "") client = rs_or_single_client_noauth(uri) + self.addCleanup(client.close) client.pymongo_test.test.insert_one({"dummy": "object"}) client.pymongo_test_bernie.test.insert_one({"dummy": "object"}) @@ -1222,6 +1228,7 @@ def test_operation_failure(self): # to avoid race conditions caused by replica set failover or idle # socket reaping. client = single_client() + self.addCleanup(client.close) client.pymongo_test.test.find_one() pool = get_pool(client) socket_count = len(pool.sockets) @@ -1245,18 +1252,21 @@ def test_lazy_connect_w0(self): self.addCleanup(client_context.client.drop_database, "test_lazy_connect_w0") client = rs_or_single_client(connect=False, w=0) + self.addCleanup(client.close) client.test_lazy_connect_w0.test.insert_one({}) wait_until( lambda: client.test_lazy_connect_w0.test.count_documents({}) == 1, "find one document" ) client = rs_or_single_client(connect=False, w=0) + self.addCleanup(client.close) client.test_lazy_connect_w0.test.update_one({}, {"$set": {"x": 1}}) wait_until( lambda: client.test_lazy_connect_w0.test.find_one().get("x") == 1, "update one document" ) client = rs_or_single_client(connect=False, w=0) + self.addCleanup(client.close) client.test_lazy_connect_w0.test.delete_one({}) wait_until( lambda: client.test_lazy_connect_w0.test.count_documents({}) == 0, "delete one document" @@ -1267,6 +1277,7 @@ def test_exhaust_network_error(self): # When doing an exhaust query, the socket stays checked out on success # but must be checked in on error to avoid semaphore leaks. client = rs_or_single_client(maxPoolSize=1, retryReads=False) + self.addCleanup(client.close) collection = client.pymongo_test.test pool = get_pool(client) pool._check_interval_seconds = None # Never check.