Skip to content

feat: add --port-serial-number option to filter ports by serial number #360

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

Merged
merged 1 commit into from
Jun 30, 2025
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
2 changes: 1 addition & 1 deletion pytest-embedded-serial-esp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ requires-python = ">=3.7"

dependencies = [
"pytest-embedded-serial~=1.16.1",
"esptool~=4.5",
"esptool~=4.9",
]

[project.urls]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def __init__(
target: Optional[str] = None,
beta_target: Optional[str] = None,
port: Optional[str] = None,
port_serial_number: Optional[str] = None,
port_mac: Optional[str] = None,
baud: int = Serial.DEFAULT_BAUDRATE,
esptool_baud: int = ESPTOOL_DEFAULT_BAUDRATE,
Expand All @@ -66,11 +67,14 @@ def __init__(
**kwargs,
) -> None:
self._meta = meta
filters = {}
if port_serial_number:
filters['serials'] = [s.strip() for s in port_serial_number.split(',') if s.strip()]

esptool_target = beta_target or target or 'auto'
if port is None or port.endswith('*'):
port_filter = port.strip('*') if port else ''
available_ports = [_p for _p in esptool.get_port_list() if port_filter in _p]
available_ports = [_p for _p in esptool.get_port_list(**filters) if port_filter in _p]
ports = list(set(available_ports) - set(self.occupied_ports.keys()) - set(ports_to_occupy))

# sort to make /dev/ttyS* ports before /dev/ttyUSB* ports
Expand Down
5 changes: 5 additions & 0 deletions pytest-embedded/pytest_embedded/dut_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def _fixture_classes_and_options_fn(
app_path,
build_dir,
port,
port_serial_number,
port_location,
port_mac,
target,
Expand Down Expand Up @@ -210,6 +211,7 @@ def _fixture_classes_and_options_fn(
'target': target,
'beta_target': beta_target,
'port': os.getenv('ESPPORT') or port,
'port_serial_number': port_serial_number,
'port_location': port_location,
'port_mac': port_mac,
'baud': int(baud or EspSerial.DEFAULT_BAUDRATE),
Expand Down Expand Up @@ -632,6 +634,7 @@ def create(
app_path: str = '',
build_dir: str = 'build',
port: t.Optional[str] = None,
port_serial_number: t.Optional[str] = None,
port_location: t.Optional[str] = None,
port_mac: t.Optional[str] = None,
target: t.Optional[str] = None,
Expand Down Expand Up @@ -680,6 +683,7 @@ def create(
app_path: Path to the application.
build_dir: Directory for build output (default is 'build').
port: Port configuration.
port_serial_number: Filters the port based on the specified serial number.
port_location: Port location.
port_mac: Port MAC address.
target: Target configuration.
Expand Down Expand Up @@ -744,6 +748,7 @@ def create(
'app_path': app_path,
'build_dir': build_dir,
'port': port,
'port_serial_number': port_serial_number,
'port_location': port_location,
'port_mac': port_mac,
'target': target,
Expand Down
11 changes: 11 additions & 0 deletions pytest-embedded/pytest_embedded/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def pytest_addoption(parser):
'--port-mac',
help='MAC address of the board. (Default: None)',
)
esp_group.addoption(
'--port-serial-number', help='Comma-separated list of serial numbers to filter ports by. (Default: None)'
)
esp_group.addoption(
'--esp-flash-force',
action='store_true',
Expand Down Expand Up @@ -855,6 +858,13 @@ def port_mac(request: FixtureRequest) -> t.Optional[str]:
return _request_param_or_config_option_or_default(request, 'port_mac', None)


@pytest.fixture
@multi_dut_argument
def port_serial_number(request: FixtureRequest) -> t.Optional[str]:
"""Enable parametrization for the same cli option"""
return _request_param_or_config_option_or_default(request, 'port_serial_number', None)


#######
# idf #
#######
Expand Down Expand Up @@ -1044,6 +1054,7 @@ def parametrize_fixtures(
app_path,
build_dir,
port,
port_serial_number,
port_location,
port_mac,
target,
Expand Down
Loading