Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add codspeed benchmarks #9534

Merged
merged 9 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,47 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}

benchmark:
name: Benchmark
needs: gen_llhttp

runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout project
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python 3.12
id: python-install
uses: actions/setup-python@v5
with:
python-version: 3.12
cache: pip
cache-dependency-path: requirements/*.txt
- name: Update pip, wheel, setuptools, build, twine
run: |
python -m pip install -U pip wheel setuptools build twine
- name: Install dependencies
run: |
python -m pip install -r requirements/test.in -c requirements/test.txt
- name: Restore llhttp generated files
uses: actions/download-artifact@v3
with:
name: llhttp
path: vendor/llhttp/build/
- name: Cythonize
run: |
make cythonize
- name: Install self
run: python -m pip install -e .
- name: Run benchmarks
uses: CodSpeedHQ/action@v3
with:
token: ${{ secrets.CODSPEED_TOKEN }}
run: python -Im pytest --no-cov -vvvvv --codspeed


check: # This job does nothing and is only used for the branch protection
if: always()

Expand Down
14 changes: 14 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,17 @@ ignore_missing_imports = True

[mypy-gunicorn.*]
ignore_missing_imports = True

# Benchmark configuration is because pytest_codspeed is missing
# a py.typed file. Can be removed once the following PR is merged
# and released:
# https://github.com/CodSpeedHQ/pytest-codspeed/pull/53
[mypy-test_benchmarks_client_request]
disable_error_code =
no-any-unimported,
misc

[mypy-test_benchmarks_cookiejar]
disable_error_code =
no-any-unimported,
misc
bdraco marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions requirements/lint.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pre-commit
proxy.py
pytest
pytest-mock
pytest_codspeed
python-on-whales
slotscheck
trustme
Expand Down
8 changes: 7 additions & 1 deletion requirements/lint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cffi==1.17.1
# via
# cryptography
# pycares
# pytest-codspeed
cfgv==3.4.0
# via pre-commit
charset-normalizer==3.4.0
Expand All @@ -31,7 +32,9 @@ distlib==0.3.9
exceptiongroup==1.2.2
# via pytest
filelock==3.16.1
# via virtualenv
# via
# pytest-codspeed
# virtualenv
freezegun==1.5.1
# via -r requirements/lint.in
identify==2.6.1
Expand Down Expand Up @@ -75,7 +78,10 @@ pygments==2.18.0
pytest==8.1.1
# via
# -r requirements/lint.in
# pytest-codspeed
# pytest-mock
pytest-codspeed==2.2.1
# via -r requirements/lint.in
pytest-mock==3.14.0
# via -r requirements/lint.in
python-dateutil==2.9.0.post0
Expand Down
1 change: 1 addition & 0 deletions requirements/test.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ proxy.py >= 2.4.4rc4
pytest
pytest-cov
pytest-mock
pytest_codspeed
python-on-whales
setuptools-git
trustme; platform_machine != "i686" # no 32-bit wheels
Expand Down
6 changes: 6 additions & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cffi==1.17.1
# via
# cryptography
# pycares
# pytest-codspeed
charset-normalizer==3.4.0
# via requests
click==8.1.7
Expand All @@ -36,6 +37,8 @@ cryptography==43.0.3
# via trustme
exceptiongroup==1.2.2
# via pytest
filelock==3.16.1
# via pytest-codspeed
freezegun==1.5.1
# via -r requirements/test.in
frozenlist==1.5.0
Expand Down Expand Up @@ -88,8 +91,11 @@ pygments==2.18.0
pytest==8.1.1
# via
# -r requirements/test.in
# pytest-codspeed
# pytest-cov
# pytest-mock
pytest-codspeed==2.2.1
# via -r requirements/test.in
pytest-cov==5.0.0
# via -r requirements/test.in
pytest-mock==3.14.0
Expand Down
22 changes: 22 additions & 0 deletions tests/test_benchmarks_client_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""codspeed benchmarks for client requests."""

import asyncio
from http.cookies import Morsel

from pytest_codspeed import BenchmarkFixture # type: ignore[import-untyped]
bdraco marked this conversation as resolved.
Show resolved Hide resolved
from yarl import URL

from aiohttp.client_reqrep import ClientRequest


def test_client_request_update_cookies(
loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture
) -> None:
req = ClientRequest("get", URL("http://python.org"), loop=loop)
morsel: "Morsel[str]" = Morsel()
morsel.set(key="string", val="Another string", coded_val="really")
morsel_cookie = {"str": morsel}

@benchmark
def _run() -> None:
req.update_cookies(cookies=morsel_cookie)
26 changes: 26 additions & 0 deletions tests/test_benchmarks_cookiejar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""codspeed benchmarks for cookies."""

from http.cookies import BaseCookie

from pytest_codspeed import BenchmarkFixture # type: ignore[import-untyped]
from yarl import URL

from aiohttp.cookiejar import CookieJar


async def test_load_cookies_into_temp_cookiejar(benchmark: BenchmarkFixture) -> None:
"""Benchmark for creating a temp CookieJar and filtering by URL.

This benchmark matches what the client request does when cookies
are passed to the request.
"""
all_cookies: BaseCookie[str] = BaseCookie()
url = URL("http://example.com")
cookies = {"cookie1": "value1", "cookie2": "value2"}

@benchmark
def _run() -> None:
tmp_cookie_jar = CookieJar()
tmp_cookie_jar.update_cookies(cookies)
req_cookies = tmp_cookie_jar.filter_cookies(url)
all_cookies.load(req_cookies)
Loading