twister: harness: pytest: list available fixtures in device config

Pass the list of supported twister fixtures for a given platform to pytest
via DeviceConfig. This allows for the pytest suites to use knowledge of the
fixtures for test suite configuration.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py
index 6053760..e484cb8 100644
--- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py
+++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py
@@ -117,6 +117,10 @@
         choices=('function', 'class', 'module', 'package', 'session'),
         help='The scope for which `dut` and `shell` fixtures are shared.'
     )
+    twister_harness_group.addoption(
+        '--twister-fixture', action='append', dest='fixtures', metavar='FIXTURE', default=[],
+        help='Twister fixture supported by this platform. May be given multiple times.'
+    )
 
 
 def pytest_configure(config: pytest.Config):
diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py
index 08087a9..a4b0b74 100644
--- a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py
+++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py
@@ -33,6 +33,7 @@
     pre_script: Path | None = None
     post_script: Path | None = None
     post_flash_script: Path | None = None
+    fixtures: list[str] = None
     app_build_dir: Path | None = None
 
     def __post_init__(self):
@@ -77,6 +78,7 @@
             pre_script=_cast_to_path(config.option.pre_script),
             post_script=_cast_to_path(config.option.post_script),
             post_flash_script=_cast_to_path(config.option.post_flash_script),
+            fixtures=config.option.fixtures,
         )
 
         devices.append(device_from_cli)
diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py
index 8f4f47a..dc800a0 100644
--- a/scripts/pylib/twister/twisterlib/harness.py
+++ b/scripts/pylib/twister/twisterlib/harness.py
@@ -353,6 +353,10 @@
         else:
             raise PytestHarnessException(f'Support for handler {handler.type_str} not implemented yet')
 
+        if handler.type_str != 'device':
+            for fixture in handler.options.fixture:
+                command.append(f'--twister-fixture={fixture}')
+
         if handler.options.pytest_args:
             command.extend(handler.options.pytest_args)
             if pytest_args_yaml:
@@ -410,6 +414,9 @@
         if hardware.flash_before:
             command.append(f'--flash-before={hardware.flash_before}')
 
+        for fixture in hardware.fixtures:
+            command.append(f'--twister-fixture={fixture}')
+
         return command
 
     def run_command(self, cmd, timeout):
diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py
index befd384..898f7e5 100644
--- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py
+++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py
@@ -25,6 +25,7 @@
     testinstance.handler = mock.Mock()
     testinstance.handler.options = mock.Mock()
     testinstance.handler.options.verbose = 1
+    testinstance.handler.options.fixture = ['fixture1:option1', 'fixture2']
     testinstance.handler.options.pytest_args = None
     testinstance.handler.type_str = 'native'
     return testinstance
@@ -41,7 +42,9 @@
         'samples/hello/pytest',
         f'--build-dir={testinstance.build_dir}',
         f'--junit-xml={testinstance.build_dir}/report.xml',
-        f'--device-type={device_type}'
+        f'--device-type={device_type}',
+        '--twister-fixture=fixture1:option1',
+        '--twister-fixture=fixture2'
     ]
 
     command = pytest_harness.generate_command()
diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py
index 6a92a4f..0195598 100644
--- a/scripts/tests/twister/test_harness.py
+++ b/scripts/tests/twister/test_harness.py
@@ -345,6 +345,7 @@
     hardware.baud = 115200
     hardware.runner = "runner"
     hardware.runner_params = ["--runner-param1", "runner-param2"]
+    hardware.fixtures = ['fixture1:option1', 'fixture2']
 
     options = handler.options
     options.west_flash = "args"
@@ -386,6 +387,8 @@
         assert '--pre-script=pre_script' in command
         assert '--post-flash-script=post_flash_script' in command
         assert '--post-script=post_script' in command
+        assert '--twister-fixture=fixture1:option1' in command
+        assert '--twister-fixture=fixture2' in command
 
 
 def test__update_command_with_env_dependencies():