pytest-timing 0.1.0__py3-none-any.whl
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.
- pytest_timing/__init__.py +5 -0
- pytest_timing/cli.py +150 -0
- pytest_timing/collector.py +210 -0
- pytest_timing/model.py +522 -0
- pytest_timing/outputs.py +54 -0
- pytest_timing/plugin.py +382 -0
- pytest_timing/render/__init__.py +1 -0
- pytest_timing/render/ascii.py +283 -0
- pytest_timing/render/html.py +32 -0
- pytest_timing/render/trace.py +126 -0
- pytest_timing/static/__init__.py +0 -0
- pytest_timing/static/report.html +653 -0
- pytest_timing/xdist_compat.py +158 -0
- pytest_timing-0.1.0.dist-info/METADATA +161 -0
- pytest_timing-0.1.0.dist-info/RECORD +18 -0
- pytest_timing-0.1.0.dist-info/WHEEL +4 -0
- pytest_timing-0.1.0.dist-info/entry_points.txt +5 -0
- pytest_timing-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Chrome Trace Event renderer, viewable in Perfetto (https://ui.perfetto.dev) or chrome://tracing."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pytest_timing import __version__
|
|
9
|
+
from pytest_timing.model import Run, _round
|
|
10
|
+
|
|
11
|
+
PID = 1
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def trace_events(run: Run) -> list[dict[str, Any]]:
|
|
15
|
+
events: list[dict[str, Any]] = [
|
|
16
|
+
{"ph": "M", "pid": PID, "tid": 0, "name": "process_name", "args": {"name": "pytest"}},
|
|
17
|
+
]
|
|
18
|
+
tids = {wid: i + 1 for i, wid in enumerate(run.worker_ids())}
|
|
19
|
+
for wid, tid in tids.items():
|
|
20
|
+
events.append(
|
|
21
|
+
{"ph": "M", "pid": PID, "tid": tid, "name": "thread_name", "args": {"name": wid}}
|
|
22
|
+
)
|
|
23
|
+
events.append(
|
|
24
|
+
{
|
|
25
|
+
"ph": "M",
|
|
26
|
+
"pid": PID,
|
|
27
|
+
"tid": tid,
|
|
28
|
+
"name": "thread_sort_index",
|
|
29
|
+
"args": {"sort_index": tid},
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def us(seconds: float) -> int:
|
|
34
|
+
return int(round(seconds * 1_000_000))
|
|
35
|
+
|
|
36
|
+
for worker in run.workers:
|
|
37
|
+
tid = tids[worker.id]
|
|
38
|
+
if worker.ready is not None:
|
|
39
|
+
if worker.start is not None:
|
|
40
|
+
events.append(
|
|
41
|
+
{
|
|
42
|
+
"ph": "X",
|
|
43
|
+
"pid": PID,
|
|
44
|
+
"tid": tid,
|
|
45
|
+
"name": "boot",
|
|
46
|
+
"cat": "worker",
|
|
47
|
+
"ts": us(worker.start),
|
|
48
|
+
"dur": us(worker.ready - worker.start),
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
if worker.collected is not None:
|
|
52
|
+
events.append(
|
|
53
|
+
{
|
|
54
|
+
"ph": "X",
|
|
55
|
+
"pid": PID,
|
|
56
|
+
"tid": tid,
|
|
57
|
+
"name": "collect",
|
|
58
|
+
"cat": "worker",
|
|
59
|
+
"ts": us(worker.ready),
|
|
60
|
+
"dur": us(worker.collected - worker.ready),
|
|
61
|
+
"args": {"items": worker.items},
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
if worker.error:
|
|
65
|
+
events.append(
|
|
66
|
+
{
|
|
67
|
+
"ph": "i",
|
|
68
|
+
"pid": PID,
|
|
69
|
+
"tid": tid,
|
|
70
|
+
"name": "worker error",
|
|
71
|
+
"cat": "worker",
|
|
72
|
+
"ts": us(worker.down or run.wall),
|
|
73
|
+
"s": "t",
|
|
74
|
+
"args": {"error": worker.error},
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
for test in run.tests:
|
|
79
|
+
tid = tids[test.worker]
|
|
80
|
+
args = {
|
|
81
|
+
"nodeid": test.nodeid,
|
|
82
|
+
"outcome": test.outcome,
|
|
83
|
+
"worker": test.worker,
|
|
84
|
+
"attempt": test.attempt,
|
|
85
|
+
"duration": _round(test.duration),
|
|
86
|
+
}
|
|
87
|
+
events.append(
|
|
88
|
+
{
|
|
89
|
+
"ph": "X",
|
|
90
|
+
"pid": PID,
|
|
91
|
+
"tid": tid,
|
|
92
|
+
"name": test.nodeid,
|
|
93
|
+
"cat": "test",
|
|
94
|
+
"ts": us(test.start),
|
|
95
|
+
"dur": us(test.duration),
|
|
96
|
+
"args": args,
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
for name, phase in test.phases.items():
|
|
100
|
+
events.append(
|
|
101
|
+
{
|
|
102
|
+
"ph": "X",
|
|
103
|
+
"pid": PID,
|
|
104
|
+
"tid": tid,
|
|
105
|
+
"name": name,
|
|
106
|
+
"cat": "phase",
|
|
107
|
+
"ts": us(phase.start),
|
|
108
|
+
"dur": us(phase.stop - phase.start),
|
|
109
|
+
"args": {"nodeid": test.nodeid, "duration": _round(phase.duration)},
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
return events
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def render_trace(run: Run) -> str:
|
|
116
|
+
return json.dumps(
|
|
117
|
+
{
|
|
118
|
+
"traceEvents": trace_events(run),
|
|
119
|
+
"displayTimeUnit": "ms",
|
|
120
|
+
"metadata": {
|
|
121
|
+
"pytest-timing": __version__,
|
|
122
|
+
"run": run.run.to_dict(),
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
separators=(",", ":"),
|
|
126
|
+
)
|
|
File without changes
|