Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions tests/test_edge_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ class TestEdgeCases(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
cwd = os.path.dirname(os.path.realpath(__file__))
self.config_path = os.path.join(cwd, "test.conf")
self.fq_instance = None

async def asyncTearDown(self):
"""Clean up Redis state and close connections after each test."""
# If a test initialized FQ with real Redis, clean up
if self.fq_instance is not None:
try:
if self.fq_instance._r is not None:
await self.fq_instance._r.flushdb()
Comment on lines +122 to +126
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new asyncTearDown is intended to flush Redis and close connections after each test, but the current pattern of setting self.fq_instance = None inside tests (e.g., lines 176-185, 189-196, 270-276) means that on successful test runs this teardown block is skipped, so Redis state is not actually cleaned between tests. To ensure the cleanup described in the PR, consider relying on asyncTearDown as the single place that closes and resets fq_instance (and avoid resetting it to None in the tests themselves), or at least avoid clearing self.fq_instance before teardown runs.

Copilot uses AI. Check for mistakes.
await self.fq_instance.close()
except Exception:
# Ignore errors during cleanup - tests may have mocked or closed connections
# This prevents tearDown failures from masking test failures
pass
self.fq_instance = None

def test_missing_config_file_raises(self):
with self.assertRaisesRegex(FQException, "Config file not found"):
Expand Down Expand Up @@ -159,22 +174,22 @@ async def test_cluster_initialization(self):
async def test_dequeue_payload_none(self):
"""Covers dequeue branch where payload is None (queue.py line 212)."""
fq = FQ(self.config_path)
self.fq_instance = fq
await fq._initialize()
fake_dequeue = FakeLuaDequeue()
fq._lua_dequeue = fake_dequeue
result = await fq.dequeue()
self.assertEqual(result["status"], "failure")
self.assertTrue(fake_dequeue.called)
await fq.close()

async def test_clear_queue_delete_only(self):
"""Covers clear_queue else branch (queue.py lines 499, 502)."""
fq = FQ(self.config_path)
self.fq_instance = fq
await fq._initialize()
await fq._r.flushdb()
response = await fq.clear_queue(queue_type="noqueue", queue_id="missing")
self.assertEqual(response["status"], "Failure")
await fq.close()

async def test_close_fallback_paths(self):
"""Covers close() fallback paths (queue.py lines 528-549)."""
Expand Down Expand Up @@ -249,10 +264,10 @@ async def test_get_queue_length_invalid_params(self):
async def test_deep_status_real_redis(self):
"""Covers deep_status with real redis (queue.py line 420)."""
fq = FQ(self.config_path)
self.fq_instance = fq
await fq._initialize()
result = await fq.deep_status()
self.assertTrue(result)
await fq.close()


if __name__ == "__main__":
Expand Down
35 changes: 25 additions & 10 deletions tests/test_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import unittest
import msgpack
import tempfile
from unittest.mock import patch, AsyncMock
from unittest.mock import AsyncMock, MagicMock
from fq import FQ
from fq.exceptions import FQException
from fq.utils import generate_epoch, deserialize_payload
Expand Down Expand Up @@ -1816,7 +1816,7 @@ async def test_close_with_none_client(self):
self.assertIsNone(fq._r)

async def test_initialize_unix_socket_connection(self):
"""Test initialization with unix socket connection - tests line 59."""
"""Test initialization with Unix socket connection - tests line 59."""
# Create a temporary config with unix_sock
with tempfile.NamedTemporaryFile(mode='w', suffix='.conf', delete=False) as f:
f.write("""[fq]
Expand All @@ -1833,14 +1833,29 @@ async def test_initialize_unix_socket_connection(self):
config_path = f.name

try:
fq = FQ(config_path)
# Mock the Redis ping to avoid actual connection attempt
mock_redis = AsyncMock()
mock_redis.ping = AsyncMock(return_value=True)
fq._r = mock_redis
# This tests the unix_sock path was configured (line 59)
self.assertIsNotNone(fq._r)
await fq.close()
# Create a mock Redis class to capture initialization parameters
mock_redis_instance = MagicMock()
mock_redis_instance.ping = AsyncMock(return_value=True)
mock_redis_instance.register_script = MagicMock(return_value=MagicMock())
mock_redis_instance.aclose = AsyncMock()

redis_init_kwargs = {}

def mock_redis_constructor(**kwargs):
redis_init_kwargs.update(kwargs)
return mock_redis_instance

# Patch Redis to intercept the initialization
with unittest.mock.patch('fq.queue.Redis', side_effect=mock_redis_constructor):
fq = FQ(config_path)
await fq._initialize()

# Verify that Redis was initialized with unix_socket_path
self.assertIn('unix_socket_path', redis_init_kwargs)
self.assertEqual(redis_init_kwargs['unix_socket_path'], '/tmp/redis_nonexistent.sock')
self.assertEqual(int(redis_init_kwargs['db']), 0)

await fq.close()
finally:
os.unlink(config_path)

Expand Down