diff --git a/src/tribler/core/components/conftest.py b/src/tribler/core/components/conftest.py index a49a42befa8..35a57027b10 100644 --- a/src/tribler/core/components/conftest.py +++ b/src/tribler/core/components/conftest.py @@ -1,7 +1,6 @@ from unittest.mock import MagicMock import pytest -from aiohttp.abc import Application from ipv8.keyvault.private.libnaclkey import LibNaCLSK from ipv8.util import succeed @@ -11,7 +10,6 @@ from tribler.core.components.libtorrent.settings import LibtorrentSettings from tribler.core.components.libtorrent.torrentdef import TorrentDef from tribler.core.components.metadata_store.db.store import MetadataStore -from tribler.core.components.restapi.rest.rest_manager import error_middleware from tribler.core.config.tribler_config import TriblerConfig from tribler.core.tests.tools.common import TESTS_DATA_DIR from tribler.core.utilities.path_util import Path @@ -132,10 +130,3 @@ async def download_manager(tmp_path_factory): yield download_manager await download_manager.shutdown() - - -@pytest.fixture(name='web_app') -async def web_app_fixture(): - app = Application(middlewares=[error_middleware]) - yield app - await app.shutdown() diff --git a/src/tribler/core/components/knowledge/restapi/tests/test_knowledge_endpoint.py b/src/tribler/core/components/knowledge/restapi/tests/test_knowledge_endpoint.py index 0087183392a..7e77c7d5570 100644 --- a/src/tribler/core/components/knowledge/restapi/tests/test_knowledge_endpoint.py +++ b/src/tribler/core/components/knowledge/restapi/tests/test_knowledge_endpoint.py @@ -27,9 +27,13 @@ def knowledge_endpoint(knowledge_db): @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, knowledge_endpoint): - web_app.add_subapp('/knowledge', knowledge_endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) +async def rest_api(aiohttp_client, knowledge_endpoint): + app = Application() + app.add_subapp('/knowledge', knowledge_endpoint.app) + + yield await aiohttp_client(app) + + await app.shutdown() def tag_to_statement(tag: str) -> Dict: diff --git a/src/tribler/core/components/libtorrent/restapi/tests/test_downloads_endpoint.py b/src/tribler/core/components/libtorrent/restapi/tests/test_downloads_endpoint.py index 4c87e6a880d..ddb98b0a11b 100644 --- a/src/tribler/core/components/libtorrent/restapi/tests/test_downloads_endpoint.py +++ b/src/tribler/core/components/libtorrent/restapi/tests/test_downloads_endpoint.py @@ -19,10 +19,15 @@ @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, mock_dlmgr, metadata_store): +async def rest_api(aiohttp_client, mock_dlmgr, metadata_store): endpoint = DownloadsEndpoint(mock_dlmgr, metadata_store=metadata_store) - web_app.add_subapp('/downloads', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/downloads', endpoint.app) + + yield await aiohttp_client(app) + + await endpoint.shutdown() + await app.shutdown() def get_hex_infohash(tdef): @@ -144,12 +149,12 @@ def test_get_extended_status_circuits(mock_extended_status): @unittest.mock.patch("tribler.core.components.libtorrent.restapi.downloads_endpoint.ensure_unicode", - Mock(side_effect=UnicodeDecodeError("", b"", 0, 0, ""))) + Mock(side_effect=UnicodeDecodeError("", b"", 0, 0, ""))) def test_safe_extended_peer_info(): """ Test that we return the string mapped by `chr` in the case of `UnicodeDecodeError` """ - extended_peer_info = download_endpoint._safe_extended_peer_info(b"abcd") # pylint: disable=protected-access + extended_peer_info = download_endpoint._safe_extended_peer_info(b"abcd") # pylint: disable=protected-access assert extended_peer_info == "abcd" diff --git a/src/tribler/core/components/libtorrent/restapi/tests/test_libtorrent_endpoint.py b/src/tribler/core/components/libtorrent/restapi/tests/test_libtorrent_endpoint.py index a6ebd4687eb..086cbf6e177 100644 --- a/src/tribler/core/components/libtorrent/restapi/tests/test_libtorrent_endpoint.py +++ b/src/tribler/core/components/libtorrent/restapi/tests/test_libtorrent_endpoint.py @@ -10,14 +10,15 @@ @pytest.fixture -def endpoint(mock_dlmgr, mock_lt_session): - return LibTorrentEndpoint(mock_dlmgr) +async def rest_api(aiohttp_client, mock_dlmgr, mock_lt_session): + endpoint = LibTorrentEndpoint(mock_dlmgr) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/libtorrent', endpoint.app) + yield await aiohttp_client(app) -@pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/libtorrent', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + await endpoint.shutdown() + await app.shutdown() @pytest.fixture diff --git a/src/tribler/core/components/libtorrent/restapi/tests/test_torrentinfo_endpoint.py b/src/tribler/core/components/libtorrent/restapi/tests/test_torrentinfo_endpoint.py index 3b1b1d6206a..4bda6f5e48b 100644 --- a/src/tribler/core/components/libtorrent/restapi/tests/test_torrentinfo_endpoint.py +++ b/src/tribler/core/components/libtorrent/restapi/tests/test_torrentinfo_endpoint.py @@ -1,7 +1,7 @@ import json import shutil from binascii import unhexlify -from unittest.mock import MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, patch from urllib.parse import quote_plus, unquote_plus import pytest @@ -9,6 +9,7 @@ from ipv8.util import succeed from tribler.core import notifications +from tribler.core.components.libtorrent.download_manager.download_manager import DownloadManager from tribler.core.components.libtorrent.restapi.torrentinfo_endpoint import TorrentInfoEndpoint from tribler.core.components.libtorrent.settings import DownloadDefaultsSettings, LibtorrentSettings from tribler.core.components.libtorrent.torrentdef import TorrentDef @@ -25,7 +26,6 @@ # pylint: disable=redefined-outer-name - @pytest.fixture def download_manager(state_dir): dlmgr = MagicMock() @@ -46,14 +46,15 @@ def download_manager(state_dir): @pytest.fixture -def endpoint(download_manager): - return TorrentInfoEndpoint(download_manager) +async def rest_api(aiohttp_client, download_manager: DownloadManager): + endpoint = TorrentInfoEndpoint(download_manager) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/torrentinfo', endpoint.app) + yield await aiohttp_client(app) -@pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/torrentinfo', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + await endpoint.shutdown() + await app.shutdown() async def test_get_torrentinfo_escaped_characters(tmp_path, rest_api): @@ -67,7 +68,7 @@ async def test_get_torrentinfo_escaped_characters(tmp_path, rest_api): assert 'metainfo' in response -async def test_get_torrentinfo(tmp_path, rest_api, endpoint: TorrentInfoEndpoint): +async def test_get_torrentinfo(tmp_path, rest_api, download_manager: DownloadManager): """ Testing whether the API returns a correct dictionary with torrent info. """ @@ -113,27 +114,27 @@ async def mock_http_query(*_): tdef = TorrentDef.load_from_memory(torrent_data) metainfo_dict = tdef_to_metadata_dict(TorrentDef.load_from_memory(torrent_data)) - def get_metainfo(infohash, timeout=20, hops=None, url=None): + async def get_metainfo(infohash, timeout=20, hops=None, url=None): # pylint: disable=unused-argument if hops is not None: hops_list.append(hops) assert url assert url == unquote_plus(path) - return succeed(tdef.get_metainfo()) + return tdef.get_metainfo() - endpoint.download_manager.get_metainfo = get_metainfo + download_manager.get_metainfo = get_metainfo verify_valid_dict(await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=200)) path = 'magnet:?xt=urn:ed2k:354B15E68FB8F36D7CD88FF94116CDC1' # No infohash await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=400) path = quote_plus(f"magnet:?xt=urn:btih:{'a' * 40}&dn=test torrent") - endpoint.download_manager.get_metainfo = lambda *_, **__: succeed(None) + download_manager.get_metainfo = lambda *_, **__: succeed(None) await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=500) # Ensure that correct torrent metadata was sent through notifier (to MetadataStore) - endpoint.download_manager.notifier[notifications.torrent_metadata_added].assert_called_with(metainfo_dict) + download_manager.notifier[notifications.torrent_metadata_added].assert_called_with(metainfo_dict) - endpoint.download_manager.get_metainfo = get_metainfo + download_manager.get_metainfo = get_metainfo verify_valid_dict(await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=200)) await do_request(rest_api, f'torrentinfo?uri={path}&hops=0', expected_code=200) @@ -144,22 +145,25 @@ def get_metainfo(infohash, timeout=20, hops=None, url=None): path = 'http://fdsafksdlafdslkdksdlfjs9fsafasdf7lkdzz32.n38/324.torrent' await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=500) - mock_download = MagicMock() + mock_download = MagicMock( + stop=AsyncMock(), + shutdown=AsyncMock() + ) path = quote_plus(f'magnet:?xt=urn:btih:{hexlify(UBUNTU_1504_INFOHASH)}&dn=test torrent') - endpoint.download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} + download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} result = await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=200) assert result["download_exists"] # Check that we do not return "downloads_exists" if the download is metainfo only download - endpoint.download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} - endpoint.download_manager.metainfo_requests = {UBUNTU_1504_INFOHASH: [mock_download]} + download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} + download_manager.metainfo_requests = {UBUNTU_1504_INFOHASH: [mock_download]} result = await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=200) assert not result["download_exists"] # Check that we return "downloads_exists" if there is a metainfo download for the infohash, # but there is also a regular download for the same infohash - endpoint.download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} - endpoint.download_manager.metainfo_requests = {UBUNTU_1504_INFOHASH: [MagicMock()]} + download_manager.downloads = {UBUNTU_1504_INFOHASH: mock_download} + download_manager.metainfo_requests = {UBUNTU_1504_INFOHASH: [MagicMock()]} result = await do_request(rest_api, f'torrentinfo?uri={path}', expected_code=200) assert result["download_exists"] diff --git a/src/tribler/core/components/metadata_store/restapi/tests/test_channels_endpoint.py b/src/tribler/core/components/metadata_store/restapi/tests/test_channels_endpoint.py index 87adf460de8..097d0e42764 100644 --- a/src/tribler/core/components/metadata_store/restapi/tests/test_channels_endpoint.py +++ b/src/tribler/core/components/metadata_store/restapi/tests/test_channels_endpoint.py @@ -36,7 +36,7 @@ @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, mock_dlmgr, metadata_store, knowledge_db): +async def rest_api(aiohttp_client, mock_dlmgr, metadata_store, knowledge_db): mock_gigachannel_manager = Mock() mock_gigachannel_community = Mock() @@ -51,9 +51,15 @@ def return_exc(*args, **kwargs): collections_endpoint = ChannelsEndpoint(*ep_args, **ep_kwargs) channels_endpoint = ChannelsEndpoint(*ep_args, **ep_kwargs) - web_app.add_subapp('/channels', channels_endpoint.app) - web_app.add_subapp('/collections', collections_endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/channels', channels_endpoint.app) + app.add_subapp('/collections', collections_endpoint.app) + + yield await aiohttp_client(app) + + await collections_endpoint.shutdown() + await channels_endpoint.shutdown() + await app.shutdown() async def test_get_channels(rest_api, add_fake_torrents_channels, add_subscribed_and_not_downloaded_channel, mock_dlmgr, diff --git a/src/tribler/core/components/metadata_store/restapi/tests/test_metadata_endpoint.py b/src/tribler/core/components/metadata_store/restapi/tests/test_metadata_endpoint.py index 062c0e5e46a..1873278a231 100644 --- a/src/tribler/core/components/metadata_store/restapi/tests/test_metadata_endpoint.py +++ b/src/tribler/core/components/metadata_store/restapi/tests/test_metadata_endpoint.py @@ -39,11 +39,15 @@ async def torrent_checker(mock_dlmgr, metadata_store): @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, torrent_checker, metadata_store): +async def rest_api(aiohttp_client, torrent_checker, metadata_store): endpoint = MetadataEndpoint(torrent_checker, metadata_store) - web_app.add_subapp('/metadata', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/metadata', endpoint.app) + yield await aiohttp_client(app) + + await endpoint.shutdown() + await app.shutdown() async def test_update_multiple_metadata_entries(metadata_store, add_fake_torrents_channels, rest_api): diff --git a/src/tribler/core/components/metadata_store/restapi/tests/test_remote_query_endpoint.py b/src/tribler/core/components/metadata_store/restapi/tests/test_remote_query_endpoint.py index 0be36a73a30..fd4b4b8700a 100644 --- a/src/tribler/core/components/metadata_store/restapi/tests/test_remote_query_endpoint.py +++ b/src/tribler/core/components/metadata_store/restapi/tests/test_remote_query_endpoint.py @@ -24,19 +24,18 @@ def mock_gigachannel_community(): @pytest.fixture -def endpoint(mock_gigachannel_community, metadata_store): - return RemoteQueryEndpoint(mock_gigachannel_community, metadata_store) - - -@pytest.fixture -def rest_api(event_loop, aiohttp_client, endpoint): +async def rest_api(aiohttp_client, metadata_store, mock_gigachannel_community): + endpoint = RemoteQueryEndpoint(mock_gigachannel_community, metadata_store) app = Application(middlewares=[error_middleware]) app.add_subapp('/remote_query', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(app)) - app.shutdown() + + yield await aiohttp_client(app) + + await endpoint.shutdown() + await app.shutdown() -async def test_create_remote_search_request(rest_api, endpoint, mock_gigachannel_community): +async def test_create_remote_search_request(rest_api, mock_gigachannel_community): """ Test that remote search call is sent on a REST API search request """ @@ -69,7 +68,7 @@ def mock_send(**kwargs): assert hexlify(sent['channel_pk']) == channel_pk -async def test_get_channels_peers(rest_api, endpoint, metadata_store, mock_gigachannel_community): +async def test_get_channels_peers(rest_api, metadata_store, mock_gigachannel_community): """ Test getting debug info about the state of channels to peers mapping """ diff --git a/src/tribler/core/components/metadata_store/restapi/tests/test_search_endpoint.py b/src/tribler/core/components/metadata_store/restapi/tests/test_search_endpoint.py index 898625eb107..87eca10788e 100644 --- a/src/tribler/core/components/metadata_store/restapi/tests/test_search_endpoint.py +++ b/src/tribler/core/components/metadata_store/restapi/tests/test_search_endpoint.py @@ -31,10 +31,15 @@ def needle_in_haystack_mds(metadata_store): @pytest.fixture -def rest_api(web_app, event_loop, needle_in_haystack_mds, aiohttp_client, knowledge_db): +async def rest_api(needle_in_haystack_mds, aiohttp_client, knowledge_db): channels_endpoint = SearchEndpoint(needle_in_haystack_mds, knowledge_db=knowledge_db) - web_app.add_subapp('/search', channels_endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + app = Application() + app.add_subapp('/search', channels_endpoint.app) + + yield await aiohttp_client(app) + + await channels_endpoint.shutdown() + await app.shutdown() async def test_search_wrong_mdtype(rest_api): diff --git a/src/tribler/core/components/metadata_store/tests/test_channel_download.py b/src/tribler/core/components/metadata_store/tests/test_channel_download.py index aa9b165a805..4bb991c8e1d 100644 --- a/src/tribler/core/components/metadata_store/tests/test_channel_download.py +++ b/src/tribler/core/components/metadata_store/tests/test_channel_download.py @@ -20,13 +20,15 @@ CHANNEL_METADATA_UPDATED = CHANNEL_DIR / 'channel_upd.mdblob' +# pylint: disable=redefined-outer-name + @pytest.fixture def channel_tdef(): return TorrentDef.load(TESTS_DATA_DIR / 'sample_channel' / 'channel_upd.torrent') @pytest.fixture -async def channel_seeder(channel_tdef, tmp_path_factory): # pylint: disable=unused-argument, redefined-outer-name +async def channel_seeder(channel_tdef, tmp_path_factory): # pylint: disable=unused-argument config = LibtorrentSettings() config.dht = False config.upnp = False @@ -45,20 +47,20 @@ async def channel_seeder(channel_tdef, tmp_path_factory): # pylint: disable=unu @pytest.fixture -async def gigachannel_manager(metadata_store, download_manager): - gigachannel_manager = GigaChannelManager( +async def gigachannel_manager(metadata_store, download_manager: DownloadManager): + manager = GigaChannelManager( state_dir=metadata_store.channels_dir.parent, download_manager=download_manager, metadata_store=metadata_store, notifier=MagicMock(), ) - yield gigachannel_manager - await gigachannel_manager.shutdown() + yield manager + await manager.shutdown() -async def test_channel_update_and_download( - channel_tdef, channel_seeder, metadata_store, download_manager, gigachannel_manager -): +async def test_channel_update_and_download(channel_tdef, channel_seeder, metadata_store, + download_manager: DownloadManager, + gigachannel_manager: GigaChannelManager): """ Test whether we can successfully update a channel and download the new version """ diff --git a/src/tribler/core/components/resource_monitor/implementation/base.py b/src/tribler/core/components/resource_monitor/implementation/base.py index c4bf4af0b1a..a564c561f9b 100644 --- a/src/tribler/core/components/resource_monitor/implementation/base.py +++ b/src/tribler/core/components/resource_monitor/implementation/base.py @@ -1,6 +1,7 @@ import logging import time from collections import deque +from typing import Optional import psutil @@ -25,6 +26,7 @@ def __init__(self, history_size=1000): self.cpu_data = deque(maxlen=history_size) self.memory_data = deque(maxlen=history_size) + self.profiler: Optional = None self.process = psutil.Process() self.last_error = None diff --git a/src/tribler/core/components/restapi/rest/debug_endpoint.py b/src/tribler/core/components/restapi/rest/debug_endpoint.py index 2d8f91d8d44..c52d3dbb5a1 100644 --- a/src/tribler/core/components/restapi/rest/debug_endpoint.py +++ b/src/tribler/core/components/restapi/rest/debug_endpoint.py @@ -340,6 +340,8 @@ async def start_profiler(self, _): } ) async def stop_profiler(self, _): + if not self.resource_monitor.profiler: + return file_path = self.resource_monitor.profiler.stop() return RESTResponse({"success": True, "profiler_file": str(file_path)}) diff --git a/src/tribler/core/components/restapi/rest/tests/test_create_torrent_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_create_torrent_endpoint.py index c0c61a91b5f..604b742cbd7 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_create_torrent_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_create_torrent_endpoint.py @@ -11,18 +11,22 @@ from tribler.core.tests.tools.common import TESTS_DATA_DIR -@pytest.fixture -def endpoint(): - return CreateTorrentEndpoint(Mock()) +# pylint: disable=redefined-outer-name @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/createtorrent', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) +async def rest_api(aiohttp_client, download_manager): + endpoint = CreateTorrentEndpoint(download_manager) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/createtorrent', endpoint.app) + + yield await aiohttp_client(app) + + await endpoint.shutdown() + await app.shutdown() -async def test_create_torrent(rest_api, tmp_path, endpoint): +async def test_create_torrent(rest_api, tmp_path, download_manager): """ Testing whether the API returns a proper base64 encoded torrent """ @@ -32,9 +36,9 @@ def fake_create_torrent_file(*_, **__): encoded_metainfo = torrent_file.read() return succeed({"metainfo": encoded_metainfo, "base_dir": str(tmp_path)}) - endpoint.download_manager.download_defaults = DownloadDefaultsSettings() - endpoint.download_manager.create_torrent_file = fake_create_torrent_file - endpoint.download_manager.start_download = start_download = Mock() + download_manager.download_defaults = DownloadDefaultsSettings() + download_manager.create_torrent_file = fake_create_torrent_file + download_manager.start_download = start_download = Mock() torrent_path = tmp_path / "video.avi.torrent" post_data = { @@ -52,7 +56,7 @@ def fake_create_torrent_file(*_, **__): ).number_hops # pylint: disable=unsubscriptable-object -async def test_create_torrent_io_error(rest_api, endpoint): +async def test_create_torrent_io_error(rest_api, download_manager): """ Testing whether the API returns a formatted 500 error if IOError is raised """ @@ -60,7 +64,7 @@ async def test_create_torrent_io_error(rest_api, endpoint): def fake_create_torrent_file(*_, **__): raise OSError("test") - endpoint.download_manager.create_torrent_file = fake_create_torrent_file + download_manager.create_torrent_file = fake_create_torrent_file post_data = { "files": ["non_existing_file.avi"] diff --git a/src/tribler/core/components/restapi/rest/tests/test_debug_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_debug_endpoint.py index 08fb4a56063..6ce2a7fc90b 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_debug_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_debug_endpoint.py @@ -20,13 +20,6 @@ def mock_tunnel_community(): return MagicMock() -@pytest.fixture -def endpoint(tmp_path, mock_tunnel_community, core_resource_monitor): - return DebugEndpoint(tmp_path, tmp_path / 'logs', - tunnel_community=mock_tunnel_community, - resource_monitor=core_resource_monitor) - - @pytest.fixture async def core_resource_monitor(tmp_path): resource_monitor = CoreResourceMonitor(notifier=MagicMock(), @@ -39,10 +32,20 @@ async def core_resource_monitor(tmp_path): @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, mock_tunnel_community, endpoint): +async def rest_api(aiohttp_client, mock_tunnel_community, tmp_path, core_resource_monitor): + endpoint = DebugEndpoint(tmp_path, tmp_path / 'logs', + tunnel_community=mock_tunnel_community, + resource_monitor=core_resource_monitor) + endpoint.tunnel_community = mock_tunnel_community - web_app.add_subapp('/debug', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + + app = Application(middlewares=[error_middleware]) + app.add_subapp('/debug', endpoint.app) + + yield await aiohttp_client(app) + + await endpoint.shutdown() + await app.shutdown() async def test_get_slots(rest_api, mock_tunnel_community): @@ -81,7 +84,7 @@ async def test_get_threads(rest_api): assert len(response_json['threads']) >= 1 -async def test_get_cpu_history(rest_api, endpoint, core_resource_monitor): +async def test_get_cpu_history(rest_api): """ Test whether the API returns the cpu history """ @@ -89,17 +92,16 @@ async def test_get_cpu_history(rest_api, endpoint, core_resource_monitor): assert len(response_json['cpu_history']) >= 1 -async def test_get_memory_history(rest_api, endpoint, core_resource_monitor): +async def test_get_memory_history(rest_api): """ Test whether the API returns the memory history """ - core_resource_monitor.check_resources() response_json = await do_request(rest_api, 'debug/memory/history', expected_code=200) assert len(response_json['memory_history']) >= 1 @pytest.mark.skip -async def test_dump_memory(rest_api, tmp_path, endpoint): +async def test_dump_memory(rest_api, tmp_path): """ Test whether the API returns a memory dump """ @@ -127,16 +129,15 @@ def create_dummy_logs(log_dir: Path, process: str = 'core', log_message: str = N info_log_file.write(f"{log_message} {log_index}\n") -async def test_debug_pane_core_logs(rest_api, endpoint, tmp_path): +async def test_debug_pane_core_logs(rest_api, tmp_path): """ Test whether the API returns the logs """ - log_dir = tmp_path / 'logs' process = 'core' test_core_log_message = "This is the core test log message" num_logs = 100 - create_dummy_logs(log_dir, process='core', log_message=test_core_log_message, num_logs=num_logs) + create_dummy_logs(tmp_path / 'logs', process='core', log_message=test_core_log_message, num_logs=num_logs) json_response = await do_request(rest_api, f'debug/log?process={process}&max_lines={num_logs}', expected_code=200) logs = json_response['content'].strip().split("\n") @@ -149,31 +150,26 @@ async def test_debug_pane_core_logs(rest_api, endpoint, tmp_path): assert log_exists, "Test log not found in the debug log response" -async def test_debug_pane_core_logs_in_root_dir(rest_api, tmp_path, endpoint): +async def test_debug_pane_core_logs_in_root_dir(rest_api, tmp_path): """ Test whether the API returns the logs when logs are present in the root directory. """ # Tribler logs are by default set to root state directory. Here we define the # root state directory by updating 'TSTATEDIR' environment variable. - root_state_dir = tmp_path - endpoint.log_dir = root_state_dir / 'some_version' / 'log_dir' - process = 'foobar' num_logs = 100 - create_dummy_logs(root_state_dir, process=process, num_logs=num_logs) - with patch('tribler.core.components.restapi.rest.debug_endpoint.get_root_state_directory', - new=lambda: root_state_dir): - json_response = await do_request(rest_api, f'debug/log?process={process}&max_lines={num_logs}', - expected_code=200) + create_dummy_logs(tmp_path / 'logs', process=process, num_logs=num_logs) + json_response = await do_request(rest_api, f'debug/log?process={process}&max_lines={num_logs}', + expected_code=200) logs = json_response['content'].strip().split("\n") # Check number of logs returned is correct assert len(logs) == num_logs -async def test_debug_pane_default_num_logs(rest_api, endpoint, tmp_path): +async def test_debug_pane_default_num_logs(rest_api, tmp_path): """ Test whether the API returns the last 100 logs when no max_lines parameter is not provided """ @@ -190,7 +186,7 @@ async def test_debug_pane_default_num_logs(rest_api, endpoint, tmp_path): assert len(logs) == default_num_logs_returned -async def test_debug_pane_no_logs(rest_api, endpoint, tmp_path): +async def test_debug_pane_no_logs(rest_api, tmp_path): """ Test whether the API returns the default response when no log files are found. """ @@ -203,7 +199,7 @@ async def test_debug_pane_no_logs(rest_api, endpoint, tmp_path): assert json_response['max_lines'] == 0 -async def test_get_profiler_state(rest_api, endpoint, core_resource_monitor): +async def test_get_profiler_state(rest_api): """ Test getting the state of the profiler """ @@ -211,25 +207,17 @@ async def test_get_profiler_state(rest_api, endpoint, core_resource_monitor): assert 'state' in json_response -async def test_start_stop_profiler(rest_api, endpoint, core_resource_monitor): +async def test_start_stop_profiler(rest_api, core_resource_monitor): """ Test starting and stopping the profiler using the API Note that we mock the start/stop profiler methods since actually starting the profiler could influence the tests. """ - - def mocked_start_profiler(): - endpoint.resource_monitor.profiler._is_running = True - - def mocked_stop_profiler(): - endpoint.resource_monitor.profiler._is_running = False - return 'yappi_1611750286.stats' - - endpoint.resource_monitor.profiler.start = mocked_start_profiler - endpoint.resource_monitor.profiler.stop = mocked_stop_profiler + core_resource_monitor.profiler.start = MagicMock() + core_resource_monitor.profiler.stop = MagicMock() await do_request(rest_api, 'debug/profiler', expected_code=200, request_type='PUT') - assert endpoint.resource_monitor.profiler.is_running() + assert core_resource_monitor.profiler.start.called await do_request(rest_api, 'debug/profiler', expected_code=200, request_type='DELETE') - assert not endpoint.resource_monitor.profiler.is_running() + assert core_resource_monitor.profiler.stop.called diff --git a/src/tribler/core/components/restapi/rest/tests/test_settings_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_settings_endpoint.py index 5ccbe602e2c..79625efc395 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_settings_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_settings_endpoint.py @@ -18,14 +18,15 @@ def tribler_config(tmp_path): @pytest.fixture -def endpoint(tribler_config): - return SettingsEndpoint(tribler_config) +async def rest_api(aiohttp_client, tribler_config): + endpoint = SettingsEndpoint(tribler_config) + app = Application(middlewares=[error_middleware]) + app.add_subapp('/settings', endpoint.app) + yield await aiohttp_client(app) -@pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/settings', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + await endpoint.shutdown() + await app.shutdown() def verify_settings(settings_dict): diff --git a/src/tribler/core/components/restapi/rest/tests/test_shutdown_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_shutdown_endpoint.py index b93b37633a9..3c03b5785c4 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_shutdown_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_shutdown_endpoint.py @@ -8,15 +8,25 @@ from tribler.core.components.restapi.rest.shutdown_endpoint import ShutdownEndpoint +# pylint: disable=redefined-outer-name + + @pytest.fixture -def endpoint(): - return ShutdownEndpoint(Mock()) +async def endpoint(): + endpoint = ShutdownEndpoint(Mock()) + yield endpoint + + await endpoint.shutdown() @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/shutdown', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) +async def rest_api(aiohttp_client, endpoint): + app = Application(middlewares=[error_middleware]) + app.add_subapp('/shutdown', endpoint.app) + + yield await aiohttp_client(app) + + await app.shutdown() async def test_shutdown(rest_api, endpoint): diff --git a/src/tribler/core/components/restapi/rest/tests/test_statistics_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_statistics_endpoint.py index b67d8d953de..c800662219b 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_statistics_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_statistics_endpoint.py @@ -12,52 +12,57 @@ from tribler.core.components.restapi.rest.statistics_endpoint import StatisticsEndpoint +# pylint: disable=redefined-outer-name + + @pytest.fixture -async def mock_ipv8(): +async def endpoint(metadata_store): ipv8 = MockIPv8("low", BandwidthAccountingCommunity, database=Mock(), settings=BandwidthAccountingSettings()) ipv8.overlays = [ipv8.overlay] ipv8.endpoint.bytes_up = 100 ipv8.endpoint.bytes_down = 20 - yield ipv8 + + endpoint = StatisticsEndpoint(ipv8, metadata_store) + + yield endpoint + await ipv8.stop() + await endpoint.shutdown() @pytest.fixture -def endpoint(): - endpoint = StatisticsEndpoint() - return endpoint +async def rest_api(aiohttp_client, endpoint): + app = Application(middlewares=[error_middleware]) + app.add_subapp('/statistics', endpoint.app) + yield await aiohttp_client(app) -@pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/statistics', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) + await app.shutdown() -async def test_get_tribler_statistics(rest_api, endpoint, metadata_store): +async def test_get_tribler_statistics(rest_api): """ Testing whether the API returns a correct Tribler statistics dictionary when requested """ - endpoint.mds = metadata_store stats = (await do_request(rest_api, 'statistics/tribler', expected_code=200))['tribler_statistics'] assert 'db_size' in stats assert 'num_channels' in stats assert 'num_channels' in stats -async def test_get_ipv8_statistics(mock_ipv8, rest_api, endpoint): +async def test_get_ipv8_statistics(rest_api): """ Testing whether the API returns a correct IPv8 statistics dictionary when requested """ - endpoint.ipv8 = mock_ipv8 json_data = await do_request(rest_api, 'statistics/ipv8', expected_code=200) assert json_data["ipv8_statistics"] -async def test_get_ipv8_statistics_unavailable(rest_api): +async def test_get_ipv8_statistics_unavailable(rest_api, endpoint: StatisticsEndpoint): """ Testing whether the API returns error 500 if IPv8 is not available """ + endpoint.ipv8 = None json_data = await do_request(rest_api, 'statistics/ipv8', expected_code=200) assert not json_data["ipv8_statistics"] diff --git a/src/tribler/core/components/restapi/rest/tests/test_trustview_endpoint.py b/src/tribler/core/components/restapi/rest/tests/test_trustview_endpoint.py index 1933e1c9248..71c6ebe9f2c 100644 --- a/src/tribler/core/components/restapi/rest/tests/test_trustview_endpoint.py +++ b/src/tribler/core/components/restapi/rest/tests/test_trustview_endpoint.py @@ -16,15 +16,23 @@ from tribler.core.utilities.utilities import MEMORY_DB +# pylint: disable=redefined-outer-name + @pytest.fixture -def endpoint(bandwidth_db): # pylint: disable=W0621 - return TrustViewEndpoint(bandwidth_db) +async def endpoint(bandwidth_db): + endpoint = TrustViewEndpoint(bandwidth_db) + yield endpoint + await endpoint.shutdown() @pytest.fixture -def rest_api(web_app, event_loop, aiohttp_client, endpoint): - web_app.add_subapp('/trustview', endpoint.app) - yield event_loop.run_until_complete(aiohttp_client(web_app)) +async def rest_api(aiohttp_client, endpoint): + app = Application(middlewares=[error_middleware]) + app.add_subapp('/trustview', endpoint.app) + + yield await aiohttp_client(app) + + await app.shutdown() @pytest.fixture @@ -38,8 +46,10 @@ def mock_bandwidth_community(mock_ipv8, rest_api): @pytest.fixture -async def bandwidth_db(root_key): - return BandwidthDatabase(MEMORY_DB, root_key) +def bandwidth_db(root_key): + database = BandwidthDatabase(MEMORY_DB, root_key) + yield database + database.shutdown() @pytest.fixture @@ -128,7 +138,7 @@ def test_add_bandwidth_transactions(trust_graph): assert False, "Expected to fail but did not." -async def test_trustview_response(rest_api, root_key, bandwidth_db, endpoint): +async def test_trustview_response(rest_api, root_key, bandwidth_db): """ Test whether the trust graph response is correctly returned. diff --git a/src/tribler/core/conftest.py b/src/tribler/core/conftest.py index 12907b73a09..545d5c501ff 100644 --- a/src/tribler/core/conftest.py +++ b/src/tribler/core/conftest.py @@ -1,6 +1,4 @@ -import asyncio import logging -import platform import sys from datetime import datetime from typing import Optional @@ -64,15 +62,3 @@ def pytest_runtest_protocol(item: Function, log=True, nextitem=None): @pytest.fixture def free_port(): return default_network_utils.get_random_free_port(start=1024, stop=50000) - - -@pytest.fixture -def event_loop(): - if platform.system() == 'Windows': - # to prevent the "Loop is closed" error - asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) - - policy = asyncio.get_event_loop_policy() - loop = policy.new_event_loop() - yield loop - loop.close()