Skip to content

Commit

Permalink
Revert "Fastapi Integration (#5)" (#6)
Browse files Browse the repository at this point in the history
This reverts commit 84272f9.
  • Loading branch information
lucamuscat authored Dec 22, 2024
1 parent 84272f9 commit ceef793
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 460 deletions.
39 changes: 0 additions & 39 deletions perfsephone/fastapi.py

This file was deleted.

5 changes: 2 additions & 3 deletions perfsephone/perfetto_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def remove_pytest_related_frames(root_frame: Frame) -> Sequence[Frame]:
return [root_frame]


def render(session: Session, start_time: float, *, tid: int = 1) -> List[SerializableEvent]:
def render(session: Session, start_time: float) -> List[SerializableEvent]:
renderer = SpeedscopeRenderer()
root_frame = session.root_frame()
if root_frame is None:
Expand Down Expand Up @@ -103,14 +103,13 @@ def render_root_frame(root_frame: Frame) -> List[SerializableEvent]:
cat=Category("runtime"),
ts=timestamp,
args={"file": file or "", "line": str(line or 0), "name": name or ""},
tid=tid,
)
)
elif (
speedscope_event.type == SpeedscopeEventType.CLOSE
and name not in SYNTHETIC_LEAF_IDENTIFIERS
):
result.append(EndDurationEvent(ts=timestamp, tid=tid))
result.append(EndDurationEvent(ts=timestamp))
return result

for root in new_roots:
Expand Down
42 changes: 35 additions & 7 deletions perfsephone/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

import inspect
import json
from contextlib import contextmanager
from dataclasses import asdict
from pathlib import Path
from typing import Any, Dict, Final, Generator, List, Optional, Sequence, Tuple, Union

import pyinstrument
import pytest
from _pytest.config import Notset

Expand All @@ -20,18 +22,40 @@
SerializableEvent,
Timestamp,
)
from perfsephone.fastapi import install_fastapi_hook
from perfsephone.profiler import Profiler
from perfsephone.perfetto_renderer import render

PERFETTO_ARG_NAME: Final[str] = "perfetto_path"


class PytestPerfettoPlugin:
def __init__(self) -> None:
self.events: List[SerializableEvent] = []
self.profiler = Profiler()
self.profiler.subscribe(lambda results: self.events.extend(results))
install_fastapi_hook(self.profiler)

@contextmanager
def __profile(
self,
root_frame_name: str,
is_async: bool = False,
args: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
) -> Generator[List[SerializableEvent], None, None]:
if args is None:
args = {}

result: List[SerializableEvent] = []
start_event = BeginDurationEvent(name=root_frame_name, cat=Category("test"), args=args)

result.append(start_event)
profiler_async_mode = "enabled" if is_async else "disabled"
with pyinstrument.Profiler(async_mode=profiler_async_mode) as profile:
yield result
end_event = EndDurationEvent()
start_rendering_event = BeginDurationEvent(
name="[pytest-perfetto] Dumping frames", cat=Category("pytest")
)
if profile.last_session is not None:
result += render(profile.last_session, start_time=start_event.ts)
end_rendering_event = EndDurationEvent()
result += [end_event, start_rendering_event, end_rendering_event]

@pytest.hookimpl(hookwrapper=True)
def pytest_sessionstart(self) -> Generator[None, None, None]:
Expand Down Expand Up @@ -125,9 +149,11 @@ def pytest_runtest_logreport(self, report: pytest.TestReport) -> None:
def pytest_pyfunc_call(self, pyfuncitem: pytest.Function) -> Generator[None, None, None]:
is_async = inspect.iscoroutinefunction(pyfuncitem.function)

with self.profiler(root_frame_name="call", is_async=is_async):
with self.__profile(root_frame_name="call", is_async=is_async) as events:
yield

self.events += events

@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(self) -> Generator[None, None, None]:
self.events.append(BeginDurationEvent(name="pytest make report", cat=Category("pytest")))
Expand All @@ -148,9 +174,11 @@ def pytest_fixture_setup(
"scope": fixturedef.scope,
}

with self.profiler(root_frame_name=fixturedef.argname, args=args):
with self.__profile(root_frame_name=fixturedef.argname, args=args) as events:
yield

self.events += events


# ===== Initialization hooks =====
def pytest_addoption(parser: pytest.Parser) -> None:
Expand Down
60 changes: 0 additions & 60 deletions perfsephone/profiler.py

This file was deleted.

Loading

0 comments on commit ceef793

Please sign in to comment.