diff --git a/backend/endpoints/platform.py b/backend/endpoints/platform.py index 507b7b74f..03362c878 100644 --- a/backend/endpoints/platform.py +++ b/backend/endpoints/platform.py @@ -38,7 +38,7 @@ async def add_platform( """Create a platform.""" try: - fs_platform_handler.add_platform(fs_slug=fs_slug) + await fs_platform_handler.add_platform(fs_slug=fs_slug) except PlatformAlreadyExistsException: log.info(f"Detected platform: {hl(fs_slug)}") diff --git a/backend/handler/filesystem/tests/test_base_handler.py b/backend/handler/filesystem/tests/test_base_handler.py index 3069042ad..03a9f984f 100644 --- a/backend/handler/filesystem/tests/test_base_handler.py +++ b/backend/handler/filesystem/tests/test_base_handler.py @@ -1,6 +1,6 @@ +import asyncio import shutil import tempfile -from concurrent.futures import ThreadPoolExecutor from io import BytesIO from pathlib import Path from unittest.mock import Mock, patch @@ -404,23 +404,21 @@ class TestFSHandler: with pytest.raises(FileNotFoundError, match="File not found"): await handler.get_file_size("nonexistent.txt") - async def test_thread_safety(self, handler: FSHandler): - """Test thread safety of file operations""" + async def test_async_concurrency(self, handler: FSHandler): + """Test async concurrency of file operations""" async def write_file(filename, content): await handler.write_file(content, ".", filename) - # Test concurrent file writes - with ThreadPoolExecutor(max_workers=10) as executor: - futures = [] - for i in range(10): - content = f"Content {i}".encode() - future = executor.submit(write_file, f"file_{i}.txt", content) - futures.append(future) + # Test concurrent file writes using asyncio + tasks = [] + for i in range(10): + content = f"Content {i}".encode() + task = write_file(f"file_{i}.txt", content) + tasks.append(task) - # Wait for all to complete - for future in futures: - future.result() + # Wait for all to complete + await asyncio.gather(*tasks) # Verify all files were written correctly for i in range(10): @@ -443,7 +441,7 @@ class TestFSHandler: """Test atomic write rollback on failure""" # Mock a failure during file write - async def failing_move(*args, **kwargs): + def failing_move(*args, **kwargs): raise OSError("Simulated failure") with patch("shutil.move", side_effect=failing_move): @@ -464,16 +462,14 @@ class TestFSHandler: await handler.make_directory(dir_name) await handler.remove_directory(dir_name) - # Test concurrent directory operations - with ThreadPoolExecutor(max_workers=5) as executor: - futures = [] - for i in range(5): - future = executor.submit(create_and_remove_dir, f"test_dir_{i}") - futures.append(future) + # Test concurrent directory operations using asyncio + tasks = [] + for i in range(5): + task = create_and_remove_dir(f"test_dir_{i}") + tasks.append(task) - # Wait for all to complete - for future in futures: - future.result() + # Wait for all to complete + await asyncio.gather(*tasks) # Verify all directories were cleaned up dirs = await handler.list_directories(".") diff --git a/backend/handler/filesystem/tests/test_firmware_handler.py b/backend/handler/filesystem/tests/test_firmware_handler.py index 0b8987c47..9ee1cef26 100644 --- a/backend/handler/filesystem/tests/test_firmware_handler.py +++ b/backend/handler/filesystem/tests/test_firmware_handler.py @@ -74,7 +74,7 @@ class TestFSFirmwareHandler: firmware_path = "n64/bios" file_name = "bios1.bin" - result = handler.calculate_file_hashes(firmware_path, file_name) + result = await handler.calculate_file_hashes(firmware_path, file_name) assert isinstance(result, dict) assert "crc_hash" in result diff --git a/backend/handler/filesystem/tests/test_resources_handler.py b/backend/handler/filesystem/tests/test_resources_handler.py index dfbf2b761..e31739d4a 100644 --- a/backend/handler/filesystem/tests/test_resources_handler.py +++ b/backend/handler/filesystem/tests/test_resources_handler.py @@ -199,7 +199,7 @@ class TestFSResourcesHandler: mock_remove.assert_called_once_with(f"{rom.fs_resources_path}/cover") assert result == {"path_cover_s": "", "path_cover_l": ""} - def test_build_artwork_path(self, handler: FSResourcesHandler, rom: Rom): + async def test_build_artwork_path(self, handler: FSResourcesHandler, rom: Rom): """Test build_artwork_path method""" file_ext = "png" @@ -207,7 +207,7 @@ class TestFSResourcesHandler: with patch.object(handler, "validate_path") as mock_validate: mock_validate.side_effect = lambda x: Path(x) - result = handler.build_artwork_path(rom, file_ext) + result = await handler.build_artwork_path(rom, file_ext) expected_cover_path = f"{rom.fs_resources_path}/cover" expected_big_path = f"{expected_cover_path}/big.{file_ext}"