|
1 | 1 | #! /usr/bin/env python |
2 | 2 | from __future__ import absolute_import |
3 | 3 | import datetime |
| 4 | +import gc |
| 5 | +import logging |
4 | 6 | import os |
5 | 7 | import re |
6 | 8 | import sys |
| 9 | +import tempfile |
7 | 10 | import time |
8 | 11 | import json |
9 | 12 | import unittest |
10 | 13 | import irods.test.helpers as helpers |
| 14 | +from irods.connection import DESTRUCTOR_MSG |
11 | 15 |
|
12 | 16 | # Regular expression to match common synonyms for localhost. |
13 | 17 | # |
@@ -237,6 +241,76 @@ def test_no_refresh_connection(self): |
237 | 241 | self.assertEqual(0, len(self.sess.pool.active)) |
238 | 242 | self.assertEqual(0, len(self.sess.pool.idle)) |
239 | 243 |
|
| 244 | + # Test to confirm the connection destructor log message is actually |
| 245 | + # logged to file, to confirm the destructor is called |
| 246 | + def test_connection_destructor_called(self): |
| 247 | + # Set 'irods_connection_refresh_time' to '3' (in seconds) in |
| 248 | + # ~/.irods/irods_environment.json file. This means any connection |
| 249 | + # that was created more than 3 seconds ago will be dropped and |
| 250 | + # a new connection is created/returned. This is to avoid |
| 251 | + # issue with idle connections that are dropped. |
| 252 | + conn_obj_id_1 = None |
| 253 | + conn_obj_id_2 = None |
| 254 | + create_time_1 = None |
| 255 | + create_time_2 = None |
| 256 | + last_used_time_1 = None |
| 257 | + last_used_time_2 = None |
| 258 | + |
| 259 | + try: |
| 260 | + |
| 261 | + # Create a temporary log file |
| 262 | + my_log_file = tempfile.NamedTemporaryFile() |
| 263 | + |
| 264 | + logging.getLogger('irods.connection').setLevel(logging.DEBUG) |
| 265 | + file_handler = logging.FileHandler(my_log_file.name, mode='a') |
| 266 | + file_handler.setLevel(logging.DEBUG) |
| 267 | + logging.getLogger('irods.connection').addHandler(file_handler) |
| 268 | + |
| 269 | + with self.sess.pool.get_connection() as conn: |
| 270 | + conn_obj_id_1 = id(conn) |
| 271 | + curr_time = datetime.datetime.now() |
| 272 | + create_time_1 = conn.create_time |
| 273 | + last_used_time_1 = conn.last_used_time |
| 274 | + self.assertTrue(curr_time >= create_time_1) |
| 275 | + self.assertTrue(curr_time >= last_used_time_1) |
| 276 | + self.assertEqual(1, len(self.sess.pool.active)) |
| 277 | + self.assertEqual(0, len(self.sess.pool.idle)) |
| 278 | + |
| 279 | + self.sess.pool.release_connection(conn) |
| 280 | + self.assertEqual(0, len(self.sess.pool.active)) |
| 281 | + self.assertEqual(1, len(self.sess.pool.idle)) |
| 282 | + |
| 283 | + # Wait more than 'irods_connection_refresh_time' seconds, |
| 284 | + # which is set to 3. Connection object should have a different |
| 285 | + # object ID (as a new connection is created) |
| 286 | + time.sleep(5) |
| 287 | + |
| 288 | + # Call garbage collector, so the unreferenced conn object is garbage collected |
| 289 | + gc.collect() |
| 290 | + |
| 291 | + with self.sess.pool.get_connection() as conn: |
| 292 | + conn_obj_id_2 = id(conn) |
| 293 | + curr_time = datetime.datetime.now() |
| 294 | + create_time_2 = conn.create_time |
| 295 | + last_used_time_2 = conn.last_used_time |
| 296 | + self.assertTrue(curr_time >= create_time_2) |
| 297 | + self.assertTrue(curr_time >= last_used_time_2) |
| 298 | + self.assertNotEqual(conn_obj_id_1, conn_obj_id_2) |
| 299 | + self.assertTrue(create_time_2 > create_time_1) |
| 300 | + self.assertEqual(1, len(self.sess.pool.active)) |
| 301 | + self.assertEqual(0, len(self.sess.pool.idle)) |
| 302 | + |
| 303 | + self.sess.pool.release_connection(conn, True) |
| 304 | + self.assertEqual(0, len(self.sess.pool.active)) |
| 305 | + self.assertEqual(0, len(self.sess.pool.idle)) |
| 306 | + |
| 307 | + # Assert that connection destructor called |
| 308 | + with open(my_log_file.name, 'r') as fh: |
| 309 | + lines = fh.read().splitlines() |
| 310 | + self.assertTrue(DESTRUCTOR_MSG in lines) |
| 311 | + finally: |
| 312 | + # Remove irods.connection's file_handler that was added just for this test |
| 313 | + logging.getLogger('irods.connection').removeHandler(file_handler) |
240 | 314 |
|
241 | 315 | def test_get_connection_refresh_time_no_env_file_input_param(self): |
242 | 316 | connection_refresh_time = self.sess.get_connection_refresh_time(first_name="Magic", last_name="Johnson") |
|
0 commit comments