Skip to content

Commit

Permalink
doc: for profiling
Browse files Browse the repository at this point in the history
  • Loading branch information
Pog3k committed Jan 30, 2025
1 parent d3cdd33 commit a6f3d10
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 60 deletions.
1 change: 1 addition & 0 deletions docs/advanced_usage/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ Advanced Usage
how_to_auxiliary
how_to_connector
how_to_change_logger_class
profiling
73 changes: 71 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 22 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,34 @@ classifiers = [

[tool.poetry.dependencies]
python = "^3.9"
black = { version = "*", optional = true }
brainstem = "*"
PyYAML = "^6.0"
robotframework = "3.2.2"
unittest-xml-reporting = "^3.2.0"
cantools = { version = "^39.4.2", python = ">=3.8,<4.0" }
click = ">=7.0.0,<9.0.0"
tabulate = ">=0.8.9,<0.10.0"
Jinja2 = ">=2.11.0,<4.0.0"
MarkupSafe = "~2.0.1" # Allow support for Jinja2 between 2.11 < x < 3
importlib-metadata = { version = ">=4.12,<7.0", python = "<3.8" }
pyreadline3 = { version = "^3.4.1", python = "^3.5" }
defusedxml = "^0.7.1"
grpcio = { version = "^1.0.0", optional = true }
hidapi = ">=0.12,<0.15"
rich = { version = "^13.2.0", optional = true }
requests = { version = "^2.28.2", optional = true }
importlib-metadata = { version = ">=4.12,<7.0", python = "<3.8" }
isort = { version = ">=5.11.4", optional = true }
black = { version = "*", optional = true }
pylink-square = { version = "~1.2.0", optional = true }
Jinja2 = ">=2.11.0,<4.0.0"
junitparser = "^3.2.0"
MarkupSafe = "~2.0.1" # Allow support for Jinja2 between 2.11 < x < 3
packaging = "*"
protobuf = { version = "^4.24.2", optional = true }
pykiso-python-uds = { version = "~3.2.0", optional = true }
pylink-square = { version = "~1.2.0", optional = true }
pyreadline3 = { version = "^3.4.1", python = "^3.5" }
pyserial = { version = "^3.0", optional = true }
python-can = { version = "~4.4.2", optional = true, extras = ["pcan,vector"] }
PyVISA = { version = "^1.12.0", optional = true }
PyVISA-py = { version = "~0.5.3", optional = true }
python-can = { version = "~4.4.2", optional = true, extras = ["pcan,vector"] }
defusedxml = "^0.7.1"
packaging = "*"
grpcio = { version = "^1.0.0", optional = true }
protobuf = { version = "^4.24.2", optional = true }
cantools = { version = "^39.4.2", python = ">=3.8,<4.0" }
junitparser = "^3.2.0"
PyYAML = "^6.0"
requests = { version = "^2.28.2", optional = true }
rich = { version = "^13.2.0", optional = true }
robotframework = "3.2.2"
tabulate = ">=0.8.9,<0.10.0"
unittest-xml-reporting = "^3.2.0"
viztracer= { version = "^1.0.1", optional = true }

[tool.poetry.extras]
plugins = [
Expand All @@ -75,6 +76,7 @@ serial = ["pyserial"]
grpc = ["grpcio", "protobuf"]
testrail = ["rich", "requests"]
pykitest = ["black", "isort"]
profiling = ["viztracer"]
all = [
"pylink-square",
"pykiso-python-uds",
Expand All @@ -88,6 +90,7 @@ all = [
"black",
"grpcio",
"protobuf",
"viztracer",
]

[tool.poetry.group.dev.dependencies]
Expand Down
22 changes: 20 additions & 2 deletions src/pykiso/profiling.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
##########################################################################
# Copyright (c) 2010-2022 Robert Bosch GmbH
# Copyright (c) 2010-2025 Robert Bosch GmbH
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
##########################################################################

"""
Profiling
*********
:module: profiling
:synopsis: add helper functions for profiling
.. currentmodule:: profiling
"""

import json
from pathlib import Path

from viztracer import VizTracer
from viztracer.vcompressor import VCompressor


# decorator for VizTracer
def profile(filename: str = "result.json", compress: bool = False):
"""
Decorator for VizTracer
:param filename: filename to save the result (default: result.json)
:param compress: compress the result file if True and save it with .cvf extension (default: False)
"""

def decorator(func):
def wrapper(*args, **kwargs):
with VizTracer() as tracer:
Expand Down
51 changes: 14 additions & 37 deletions tests/test_profiling.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import json
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from pykiso.profiling import profile


@pytest.fixture
def MockVizTracer():
with patch('pykiso.profiling.VizTracer') as mock:
yield mock

@patch('pykiso.profiling.VizTracer')
def test_profile_without_compression(MockVizTracer):
mock_tracer = MockVizTracer.return_value.__enter__.return_value
Expand All @@ -25,23 +16,28 @@ def test_profile_without_compression(MockVizTracer):
assert result == "test_result"

@patch('pykiso.profiling.VizTracer')
@patch('pykiso.profiling.VCompressor')
@patch('pykiso.profiling.Path.unlink')
def test_profile_with_compression(mocker,mock_unlink, MockVCompressor, MockVizTracer,tmp_path):
mock_open = mocker.patch("builtins.open")
def test_profile_with_compression(MockVizTracer,mocker,tmp_path):
mock_tracer = MockVizTracer.return_value.__enter__.return_value
mock_compressor = MockVCompressor.return_value
mock_compressor = mocker.patch("pykiso.profiling.VCompressor", autospec=True).return_value
mock_func = MagicMock(return_value="test_result")

mock_json = mocker.patch("json.load", return_value={"key": "value"},autospec=True)
mock_unlink = mocker.patch("pykiso.profiling.Path.unlink")
file_name = tmp_path / "test_result.json"

with open(file_name, 'w+'):
pass

mock_open = mocker.patch("builtins.open")

decorated_func = profile(filename=file_name.as_posix(), compress=True)(mock_func)

result = decorated_func()

mock_func.assert_called_once()
mock_tracer.save.assert_called_once_with("test_result.json")
mock_open.assert_called_once_with("test_result.json")
mock_compressor.compress.assert_called_once_with({"key": "value"}, "test_result.cvf")
mock_json.assert_called_once()
mock_tracer.save.assert_called_once_with(file_name.as_posix())
mock_open.assert_called_once_with(file_name.as_posix())
mock_compressor.compress.assert_called_once()
mock_unlink.assert_called_once()
assert result == "test_result"

Expand All @@ -68,22 +64,3 @@ def test_profile_with_different_filename(MockVizTracer):
mock_func.assert_called_once()
mock_tracer.save.assert_called_once_with("different_result.json")
assert result == "test_result"

@patch('pykiso.profiling.VizTracer')
@patch('pykiso.profiling.VCompressor')
@patch('pykiso.profiling.Path.unlink')
def test_profile_with_empty_data(mocker, mock_unlink, MockVCompressor, MockVizTracer):
mock_open = mocker.patch("builtins.open")
mock_tracer = MockVizTracer.return_value.__enter__.return_value
mock_compressor = MockVCompressor.return_value
mock_func = MagicMock(return_value="test_result")

decorated_func = profile(filename="test_result.json", compress=True)(mock_func)
result = decorated_func()

mock_func.assert_called_once()
mock_tracer.save.assert_called_once_with("test_result.json")
mock_open.assert_called_once_with("test_result.json")
mock_compressor.compress.assert_called_once_with({"key": "value"}, "test_result.cvf")
mock_unlink.assert_called_once()
assert result == "test_result"

0 comments on commit a6f3d10

Please sign in to comment.