pytest-embedded 2.2.1__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-embedded
3
- Version: 2.2.1
3
+ Version: 2.4.0
4
4
  Summary: A pytest plugin that designed for embedded testing.
5
5
  Author-email: Fu Hanxi <fuhanxi@espressif.com>
6
6
  Requires-Python: >=3.10
@@ -6,4 +6,4 @@ from .dut_factory import DutFactory
6
6
 
7
7
  __all__ = ['App', 'Dut', 'DutFactory']
8
8
 
9
- __version__ = '2.2.1'
9
+ __version__ = '2.4.0'
@@ -153,6 +153,10 @@ def pytest_addoption(parser):
153
153
  base_group.addoption(
154
154
  '--logfile-extension', default='.log', help='set the extension format of the log files. (Default: ".log")'
155
155
  )
156
+ base_group.addoption(
157
+ '--metric-path',
158
+ help='Path to openmetrics txt file to log metrics. (Default: None)',
159
+ )
156
160
 
157
161
  serial_group = parser.getgroup('embedded-serial')
158
162
  serial_group.addoption('--port', help='serial port. (Env: "ESPPORT" if service "esp" specified, Default: "None")')
@@ -634,6 +638,55 @@ def port_app_cache() -> dict[str, str]:
634
638
  return {}
635
639
 
636
640
 
641
+ @pytest.fixture(scope='session')
642
+ def metric_path(request: FixtureRequest) -> str | None:
643
+ """
644
+ Get the metric file path from the command line option.
645
+
646
+ :param request: pytest request object
647
+ :return: The path to the metric file, or None if not provided.
648
+ """
649
+ return request.config.getoption('metric_path', None)
650
+
651
+
652
+ @pytest.fixture(scope='session')
653
+ def log_metric(metric_path: str | None) -> t.Callable[..., None]:
654
+ """
655
+ Provides a function to log metrics in OpenMetrics format.
656
+
657
+ The file is cleared at the beginning of the test session.
658
+
659
+ :param metric_path: Path to the metric file, from the ``--metric-path`` option.
660
+ :return: A function to log metrics, or a no-op function if the path is not provided.
661
+ """
662
+ if not metric_path:
663
+
664
+ def no_op(key: str, value: t.Any, **kwargs: t.Any) -> None: # noqa: ARG001
665
+ warnings.warn('`--metric-path` is not specified, `log_metric` does nothing.')
666
+
667
+ return no_op
668
+
669
+ if os.path.exists(metric_path):
670
+ os.remove(metric_path)
671
+ elif os.path.dirname(metric_path):
672
+ os.makedirs(os.path.dirname(metric_path), exist_ok=True)
673
+
674
+ def _log_metric_impl(key: str, value: t.Any, **kwargs: t.Any) -> None:
675
+ labels = ''
676
+ if kwargs:
677
+ label_str = ','.join(f'{k}="{v}"' for k, v in kwargs.items())
678
+ labels = f'{{{label_str}}}'
679
+
680
+ line = f'{key}{labels} {value}\n'
681
+
682
+ lock = filelock.FileLock(f'{metric_path}.lock')
683
+ with lock:
684
+ with open(metric_path, 'a') as f:
685
+ f.write(line)
686
+
687
+ return _log_metric_impl
688
+
689
+
637
690
  @pytest.fixture(scope='session', autouse=True)
638
691
  def _mp_manager():
639
692
  manager = MessageQueueManager()
@@ -792,3 +792,32 @@ class TestTargetMarkers:
792
792
 
793
793
  result.assert_outcomes(passed=1)
794
794
  assert 'Unknown pytest.mark.esp32 - is this a typo?' not in result.stdout.str()
795
+
796
+
797
+ def test_log_metric_with_path(pytester):
798
+ metric_file = pytester.path / 'metrics.txt'
799
+ pytester.makepyfile("""
800
+ def test_metric(log_metric):
801
+ log_metric('my_metric', 123.45, label1='value1', target='esp32')
802
+ """)
803
+
804
+ result = pytester.runpytest(f'--metric-path={metric_file}')
805
+ result.assert_outcomes(passed=1)
806
+
807
+ with open(metric_file) as f:
808
+ content = f.read()
809
+
810
+ assert content == 'my_metric{label1="value1",target="esp32"} 123.45\n'
811
+
812
+
813
+ def test_log_metric_without_path(pytester):
814
+ pytester.makepyfile("""
815
+ import pytest
816
+
817
+ def test_metric_no_path(log_metric):
818
+ with pytest.warns(UserWarning, match='`--metric-path` is not specified, `log_metric` does nothing.'):
819
+ log_metric('my_metric', 123.45)
820
+ """)
821
+
822
+ result = pytester.runpytest()
823
+ result.assert_outcomes(passed=1)
File without changes