diff --git a/tests/test_benchmarks_web_urldispatcher.py b/tests/test_benchmarks_web_urldispatcher.py index 5d151d984af..936ed6320ed 100644 --- a/tests/test_benchmarks_web_urldispatcher.py +++ b/tests/test_benchmarks_web_urldispatcher.py @@ -6,9 +6,10 @@ import random import string from pathlib import Path -from typing import NoReturn, Optional +from typing import NoReturn, Optional, cast from unittest import mock +import pytest from multidict import CIMultiDict, CIMultiDictProxy from pytest_codspeed import BenchmarkFixture from yarl import URL @@ -18,6 +19,20 @@ from aiohttp.http import HttpVersion, RawRequestMessage +@pytest.fixture +def github_urls() -> list[str]: + """GitHub api urls.""" + # The fixture provides OpenAPI generated info for github. + # To update the local data file please run the following command: + # $ curl https://raw.githubusercontent.com/github/rest-api-description/refs/heads/main/descriptions/api.github.com/api.github.com.json | jq ".paths | keys" > github-urls.json + + here = Path(__file__).parent + with (here / "github-urls.json").open() as f: + urls = json.load(f) + + return cast(list[str], urls) + + def _mock_request(method: str, path: str) -> web.Request: message = RawRequestMessage( method, @@ -366,23 +381,15 @@ def _run() -> None: def test_resolve_gitapi( loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture, + github_urls: list[str], ) -> None: - """Resolve DynamicResource for simulated github API. - - The benchmark uses OpenAPI generated info for github. - To update the local data file please run the following command: - $ curl https://raw.githubusercontent.com/github/rest-api-description/refs/heads/main/descriptions/api.github.com/api.github.com.json | jq ".paths | keys" > github-urls.json - """ + """Resolve DynamicResource for simulated github API.""" async def handler(request: web.Request) -> NoReturn: assert False - here = Path(__file__).parent - with (here / "github-urls.json").open() as f: - urls = json.load(f) - app = web.Application() - for url in urls: + for url in github_urls: app.router.add_get(url, handler) app.freeze() router = app.router @@ -425,21 +432,13 @@ def _run() -> None: def test_resolve_gitapi_subapps( loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture, + github_urls: list[str], ) -> None: - """Resolve DynamicResource for simulated github API, grouped in subapps. - - The benchmark uses OpenAPI generated info for github. - To update the local data file please run the following command: - $ curl https://raw.githubusercontent.com/github/rest-api-description/refs/heads/main/descriptions/api.github.com/api.github.com.json | jq ".paths | keys" > github-urls.json - """ + """Resolve DynamicResource for simulated github API, grouped in subapps.""" async def handler(request: web.Request) -> NoReturn: assert False - here = Path(__file__).parent - with (here / "github-urls.json").open() as f: - urls = json.load(f) - subapps = { "gists": web.Application(), "orgs": web.Application(), @@ -451,7 +450,7 @@ async def handler(request: web.Request) -> NoReturn: } app = web.Application() - for url in urls: + for url in github_urls: parts = url.split("/") subapp = subapps.get(parts[1]) if subapp is not None: @@ -501,6 +500,39 @@ def _run() -> None: loop.run_until_complete(run_url_dispatcher_benchmark()) +def test_resolve_gitapi_root( + loop: asyncio.AbstractEventLoop, + benchmark: BenchmarkFixture, + github_urls: list[str], +) -> None: + """Resolve the plain root for simulated github API.""" + + async def handler(request: web.Request) -> NoReturn: + assert False + + app = web.Application() + for url in github_urls: + app.router.add_get(url, handler) + app.freeze() + router = app.router + + request = _mock_request(method="GET", path="/") + + async def run_url_dispatcher_benchmark() -> Optional[web.UrlMappingMatchInfo]: + ret = None + for i in range(250): + ret = await router.resolve(request) + return ret + + ret = loop.run_until_complete(run_url_dispatcher_benchmark()) + assert ret is not None + assert ret.get_info()["path"] == "/", ret.get_info() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_url_dispatcher_benchmark()) + + def test_resolve_prefix_resources_many_prefix_many_plain( loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture,