Skip to content

Commit 496ed8b

Browse files
authored
Add performance testing + test SDK Span Creation (#1443)
1 parent 6aa09b6 commit 496ed8b

File tree

4 files changed

+108
-15
lines changed

4 files changed

+108
-15
lines changed

.github/workflows/test.yml

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
py38: 3.8
2323
py39: 3.9
2424
pypy3: pypy3
25+
RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }}
2526
runs-on: ${{ matrix.os }}
2627
strategy:
2728
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
@@ -30,15 +31,6 @@ jobs:
3031
package: ["instrumentation", "core", "exporter"]
3132
os: [ ubuntu-latest ]
3233
include:
33-
- python-version: py39
34-
package: "tracecontext"
35-
os: ubuntu-latest
36-
- python-version: py39
37-
package: "mypy"
38-
os: ubuntu-latest
39-
- python-version: py39
40-
package: "mypyinstalled"
41-
os: ubuntu-latest
4234
# py35-instrumentation segfaults on 18.04 so we instead run on 20.04
4335
- python-version: py35
4436
package: instrumentation
@@ -67,14 +59,38 @@ jobs:
6759
uses: actions/cache@v2
6860
with:
6961
path: .tox
70-
key: tox-cache-${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core
62+
key: tox-cache-${{ env.RUN_MATRIX_COMBINATION }}-${{ hashFiles('tox.ini', 'dev-requirements.txt') }}-core
7163
- name: run tox
72-
run: tox -f ${{ matrix.python-version }}-${{ matrix.package }}
64+
run: tox -f ${{ matrix.python-version }}-${{ matrix.package }} -- --benchmark-json=${{ env.RUN_MATRIX_COMBINATION }}-benchmark.json
65+
- name: Find and merge benchmarks
66+
# TODO: Add at least one benchmark to every package type to remove this
67+
if: matrix.package == 'core'
68+
run: >-
69+
jq -s '.[0].benchmarks = ([.[].benchmarks] | add)
70+
| if .[0].benchmarks == null then null else .[0] end'
71+
opentelemetry-*/tests/*${{ matrix.package }}*-benchmark.json > output.json
72+
- name: Report on benchmark results
73+
# TODO: Add at least one benchmark to every package type to remove this
74+
if: matrix.package == 'core'
75+
uses: rhysd/github-action-benchmark@v1
76+
with:
77+
name: OpenTelemetry Python Benchmarks - Python ${{ env[matrix.python-version ]}} - ${{ matrix.package-group }}
78+
tool: pytest
79+
output-file-path: output.json
80+
github-token: ${{ secrets.GITHUB_TOKEN }}
81+
# Alert with a commit comment on possible performance regression
82+
alert-threshold: 200%
83+
comment-always: true
84+
fail-on-alert: true
85+
# Make a commit on `gh-pages` with benchmarks from previous step
86+
auto-push: ${{ github.ref == 'refs/heads/master' }}
87+
gh-pages-branch: master
88+
benchmark-data-dir-path: benchmarks
7389
misc:
7490
strategy:
7591
fail-fast: false
7692
matrix:
77-
tox-environment: [ "docker-tests", "lint", "docs" ]
93+
tox-environment: [ "docker-tests", "lint", "docs", "mypy", "mypyinstalled", "tracecontext" ]
7894
name: ${{ matrix.tox-environment }}
7995
runs-on: ubuntu-latest
8096
steps:

CONTRIBUTING.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,31 @@ See
6666
[`tox.ini`](https://github.com/open-telemetry/opentelemetry-python/blob/master/tox.ini)
6767
for more detail on available tox commands.
6868

69+
### Benchmarks
70+
71+
Performance progression of benchmarks for packages distributed by OpenTelemetry Python can be viewed as a [graph of throughput vs commit history](https://opentelemetry-python.readthedocs.io/en/latest/benchmarks/index.html). From this page, you can download a JSON file with the performance results.
72+
73+
Running the `tox` tests also runs the performance tests if any are available. Benchmarking tests are done with `pytest-benchmark` and they output a table with results to the console.
74+
75+
To write benchmarks, simply use the [pytest benchmark fixture](https://pytest-benchmark.readthedocs.io/en/latest/usage.html#usage) like the following:
76+
77+
```python
78+
def test_simple_start_span(benchmark):
79+
def benchmark_start_as_current_span(span_name, attribute_num):
80+
span = tracer.start_span(
81+
span_name,
82+
attributes={"count": attribute_num},
83+
)
84+
span.end()
85+
86+
benchmark(benchmark_start_as_current_span, "benchmarkedSpan", 42)
87+
```
88+
89+
Make sure the test file is under the `tests/performance/benchmarks/` folder of
90+
the package it is benchmarking and further has a path that corresponds to the
91+
file in the package it is testing. Make sure that the file name begins with
92+
`test_benchmark_`. (e.g. `opentelemetry-sdk/tests/performance/benchmarks/trace/propagation/test_benchmark_b3_format.py`)
93+
6994
## Pull Requests
7095

7196
### How to Send Pull Requests
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import opentelemetry.sdk.trace as trace
16+
from opentelemetry.sdk.resources import Resource
17+
from opentelemetry.sdk.trace import sampling
18+
19+
tracer = trace.TracerProvider(
20+
sampler=sampling.DEFAULT_ON,
21+
resource=Resource(
22+
{
23+
"service.name": "A123456789",
24+
"service.version": "1.34567890",
25+
"service.instance.id": "123ab456-a123-12ab-12ab-12340a1abc12",
26+
}
27+
),
28+
).get_tracer("sdk_tracer_provider")
29+
30+
31+
def test_simple_start_span(benchmark):
32+
def benchmark_start_as_current_span():
33+
span = tracer.start_span(
34+
"benchmarkedSpan",
35+
attributes={"long.attribute": -10000000001000000000},
36+
)
37+
span.add_event("benchmarkEvent")
38+
span.end()
39+
40+
benchmark(benchmark_start_as_current_span)
41+
42+
43+
def test_simple_start_as_current_span(benchmark):
44+
def benchmark_start_as_current_span():
45+
with tracer.start_as_current_span(
46+
"benchmarkedSpan",
47+
attributes={"long.attribute": -10000000001000000000},
48+
) as span:
49+
span.add_event("benchmarkEvent")
50+
51+
benchmark(benchmark_start_as_current_span)

tox.ini

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@ envlist =
4949
pypy3-test-core-opentracing-shim
5050

5151
lint
52-
py39-tracecontext
53-
py39-{mypy,mypyinstalled}
52+
tracecontext
53+
mypy,mypyinstalled
5454
docs
5555
docker-tests
5656

5757
[testenv]
5858
deps =
5959
-c dev-requirements.txt
6060
test: pytest
61+
test: pytest-benchmark
6162
coverage: pytest
6263
coverage: pytest-cov
6364
mypy,mypyinstalled: mypy
@@ -164,7 +165,7 @@ changedir = docs
164165
commands =
165166
sphinx-build -E -a -W -b html -T . _build/html
166167

167-
[testenv:py39-tracecontext]
168+
[testenv:tracecontext]
168169
basepython: python3.9
169170
deps =
170171
# needed for tracecontext

0 commit comments

Comments
 (0)