Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
maresb committed Oct 27, 2024
1 parent 2f67dc4 commit aff4acf
Showing 1 changed file with 70 additions and 6 deletions.
76 changes: 70 additions & 6 deletions tests/test_lookup_cache.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os
import queue
import threading
import time

from pathlib import Path
from typing import Optional
from unittest.mock import MagicMock, patch

import pytest
Expand Down Expand Up @@ -250,9 +251,72 @@ def wrapped_get(*args, **kwargs):
assert result == result2 == result3


# @patch("conda_lock.lookup_cache.FileLock")
# def test_cached_download_file_timeout(mock_file_lock):
# mock_file_lock.side_effect = Timeout("Lock timeout")
def test_concurrent_cached_download_file(tmp_path):
"""Test concurrent access to cached_download_file with 5 threads."""
url = "https://example.com/test.json"
results: queue.Queue[bytes] = queue.Queue()
thread_names_emitting_lock_warnings: queue.Queue[str] = queue.Queue()
thread_names_calling_requests_get: queue.Queue[str] = queue.Queue()

def mock_get(*args, **kwargs):
time.sleep(5.2)
response = MagicMock()
response.content = b"content"
response.status_code = 200
thread_name = threading.current_thread().name
thread_names_calling_requests_get.put(thread_name)
return response

def download_file(result_queue):
"""Download the file in a thread and store the result in a queue."""
import random

# with pytest.raises(Exception):
# cached_download_file("https://example.com/test", cache_subdir_name="test_cache")
# Randomize which thread calls cached_download_file first
time.sleep(random.uniform(0, 0.1))
result = cached_download_file(
url, cache_subdir_name="test_cache", cache_root=tmp_path
)
result_queue.put(result)

with patch("requests.get", side_effect=mock_get) as mock_get, patch(
"conda_lock.lookup_cache.logger"
) as mock_logger:
# Set up the logger to record which threads emit warnings
def mock_warning(msg, *args, **kwargs):
if "Failed to acquire lock" in msg:
thread_names_emitting_lock_warnings.put(threading.current_thread().name)

mock_logger.warning.side_effect = mock_warning

# Create and start 5 threads
thread_names = [f"CachedDownloadFileThread-{i}" for i in range(5)]
threads = [
threading.Thread(target=download_file, args=(results,), name=thread_name)
for thread_name in thread_names
]
for thread in threads:
thread.start()
for thread in threads:
thread.join()

# Collect results from the queue
assert results.qsize() == len(threads)
assert all(result == b"content" for result in results.queue)

# We expect one thread to have made the request and the other four
# to have emitted warnings.
assert (
thread_names_calling_requests_get.qsize()
== 1
== len(set(thread_names_calling_requests_get.queue))
== mock_get.call_count
)
assert (
thread_names_emitting_lock_warnings.qsize()
== 4
== len(set(thread_names_emitting_lock_warnings.queue))
)
assert set(thread_names) == set(
thread_names_calling_requests_get.queue
+ thread_names_emitting_lock_warnings.queue
)

0 comments on commit aff4acf

Please sign in to comment.