Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix application tester re-run failure #7859

Merged
merged 2 commits into from
Jan 29, 2024
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
1 change: 1 addition & 0 deletions scripts/application_tester/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
executor_kwargs['check_process_started_interval'] = 1

executor = Executor(args, **executor_kwargs)
executor.set_core_api_port()

loop = get_event_loop()
coro = executor.start()
Expand Down
24 changes: 23 additions & 1 deletion scripts/application_tester/tribler_apptester/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from typing import Dict, Optional

from tribler.core.config.tribler_config import TriblerConfig
from tribler.core.utilities.network_utils import default_network_utils, FreePortNotFoundError
from tribler_apptester.action_selector import ActionSelector
from tribler_apptester.actions.shutdown_action import ShutdownAction
from tribler_apptester.monitors.download_monitor import DownloadMonitor
Expand All @@ -32,6 +33,8 @@

SHUTDOWN_TIMEOUT = 30

DEFAULT_CORE_API_PORT = 20100


class Executor(object):

Expand All @@ -42,7 +45,7 @@ def __init__(self, args, read_config_delay=2, read_config_attempts=10, check_pro
self.check_process_started_interval = check_process_started_interval
self.read_config_attempts = read_config_attempts
self.code_port = args.codeport
self.api_port = int(os.environ.get('CORE_API_PORT'))
self.api_port = None
self._logger = logging.getLogger(self.__class__.__name__)
self.allow_plain_downloads = args.plain
self.pending_tasks: Dict[bytes, Future] = {} # Dictionary of pending tasks
Expand All @@ -65,6 +68,25 @@ def __init__(self, args, read_config_delay=2, read_config_attempts=10, check_pro
self.request_manager = None
self.action_selector = ActionSelector()

def set_core_api_port(self) -> None:
"""
Set the core API port to a free port.
Prefer the port specified in the environment variable CORE_API_PORT.
Then update the environment variable CORE_API_PORT to match the port that was chosen.
"""
base_api_port = int(os.environ.get('CORE_API_PORT', f"{DEFAULT_CORE_API_PORT}"))

try:
self.api_port = default_network_utils.get_first_free_port(start=base_api_port)
self._logger.info(f"Setting the Core API port to {self.api_port}")
except FreePortNotFoundError:
self._logger.error("Could not find a free port to use as Core API port.")
raise

# Update the environment variable CORE_API_PORT to the port that was chosen
# so that the Tribler process can use the correct port.
os.environ['CORE_API_PORT'] = str(self.api_port)

async def start(self):
await self.start_tribler()

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import argparse
import os
import random
from unittest.mock import MagicMock, patch

import pytest

from tribler_apptester.executor import DEFAULT_CORE_API_PORT, Executor
from tribler.core.utilities.network_utils import FreePortNotFoundError


@pytest.fixture(name='executor')
def fixture_executor() -> Executor:
args = argparse.Namespace(
tribler_executable='python ./src/run_tribler.py',
plain=False,
duration=120,
silent=False,
codeport=5500,
monitordownloads=None,
monitorresources=None,
monitoripv8=None,
fragile=True
)
return Executor(args)


@patch('os.environ', new={})
@patch('tribler.core.utilities.network_utils.default_network_utils.get_first_free_port')
@pytest.mark.parametrize("initial_core_api_port", [DEFAULT_CORE_API_PORT, 8085])
def test_set_core_api_port_(mock_get_first_free_port: MagicMock, executor: Executor, initial_core_api_port):
assert executor.api_port is None

os.environ['CORE_API_PORT'] = str(initial_core_api_port)
next_available_free_port = initial_core_api_port + random.randint(0, 100)
mock_get_first_free_port.return_value = next_available_free_port

executor.set_core_api_port()

assert os.environ.get('CORE_API_PORT') == str(next_available_free_port)
assert executor.api_port == next_available_free_port


@patch('os.environ', new={})
@patch('tribler.core.utilities.network_utils.default_network_utils.get_first_free_port')
def test_set_core_api_port_not_found(mock_get_first_free_port: MagicMock, executor: Executor):
assert executor.api_port is None

os.environ['CORE_API_PORT'] = str(DEFAULT_CORE_API_PORT)
mock_get_first_free_port.side_effect = FreePortNotFoundError('Free port not found')

with pytest.raises(FreePortNotFoundError):
executor.set_core_api_port()
Loading