Skip to content

Commit e79b2d5

Browse files
authored
Add url dispatcher benchmark for resolving root route for github simulated routes tree (#10018)
1 parent f3f15c5 commit e79b2d5

File tree

1 file changed

+55
-23
lines changed

1 file changed

+55
-23
lines changed

tests/test_benchmarks_web_urldispatcher.py

+55-23
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import random
77
import string
88
from pathlib import Path
9-
from typing import NoReturn, Optional
9+
from typing import NoReturn, Optional, cast
1010
from unittest import mock
1111

12+
import pytest
1213
from multidict import CIMultiDict, CIMultiDictProxy
1314
from pytest_codspeed import BenchmarkFixture
1415
from yarl import URL
@@ -18,6 +19,20 @@
1819
from aiohttp.http import HttpVersion, RawRequestMessage
1920

2021

22+
@pytest.fixture
23+
def github_urls() -> list[str]:
24+
"""GitHub api urls."""
25+
# The fixture provides OpenAPI generated info for github.
26+
# To update the local data file please run the following command:
27+
# $ 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
28+
29+
here = Path(__file__).parent
30+
with (here / "github-urls.json").open() as f:
31+
urls = json.load(f)
32+
33+
return cast(list[str], urls)
34+
35+
2136
def _mock_request(method: str, path: str) -> web.Request:
2237
message = RawRequestMessage(
2338
method,
@@ -366,23 +381,15 @@ def _run() -> None:
366381
def test_resolve_gitapi(
367382
loop: asyncio.AbstractEventLoop,
368383
benchmark: BenchmarkFixture,
384+
github_urls: list[str],
369385
) -> None:
370-
"""Resolve DynamicResource for simulated github API.
371-
372-
The benchmark uses OpenAPI generated info for github.
373-
To update the local data file please run the following command:
374-
$ 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
375-
"""
386+
"""Resolve DynamicResource for simulated github API."""
376387

377388
async def handler(request: web.Request) -> NoReturn:
378389
assert False
379390

380-
here = Path(__file__).parent
381-
with (here / "github-urls.json").open() as f:
382-
urls = json.load(f)
383-
384391
app = web.Application()
385-
for url in urls:
392+
for url in github_urls:
386393
app.router.add_get(url, handler)
387394
app.freeze()
388395
router = app.router
@@ -425,21 +432,13 @@ def _run() -> None:
425432
def test_resolve_gitapi_subapps(
426433
loop: asyncio.AbstractEventLoop,
427434
benchmark: BenchmarkFixture,
435+
github_urls: list[str],
428436
) -> None:
429-
"""Resolve DynamicResource for simulated github API, grouped in subapps.
430-
431-
The benchmark uses OpenAPI generated info for github.
432-
To update the local data file please run the following command:
433-
$ 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
434-
"""
437+
"""Resolve DynamicResource for simulated github API, grouped in subapps."""
435438

436439
async def handler(request: web.Request) -> NoReturn:
437440
assert False
438441

439-
here = Path(__file__).parent
440-
with (here / "github-urls.json").open() as f:
441-
urls = json.load(f)
442-
443442
subapps = {
444443
"gists": web.Application(),
445444
"orgs": web.Application(),
@@ -451,7 +450,7 @@ async def handler(request: web.Request) -> NoReturn:
451450
}
452451

453452
app = web.Application()
454-
for url in urls:
453+
for url in github_urls:
455454
parts = url.split("/")
456455
subapp = subapps.get(parts[1])
457456
if subapp is not None:
@@ -501,6 +500,39 @@ def _run() -> None:
501500
loop.run_until_complete(run_url_dispatcher_benchmark())
502501

503502

503+
def test_resolve_gitapi_root(
504+
loop: asyncio.AbstractEventLoop,
505+
benchmark: BenchmarkFixture,
506+
github_urls: list[str],
507+
) -> None:
508+
"""Resolve the plain root for simulated github API."""
509+
510+
async def handler(request: web.Request) -> NoReturn:
511+
assert False
512+
513+
app = web.Application()
514+
for url in github_urls:
515+
app.router.add_get(url, handler)
516+
app.freeze()
517+
router = app.router
518+
519+
request = _mock_request(method="GET", path="/")
520+
521+
async def run_url_dispatcher_benchmark() -> Optional[web.UrlMappingMatchInfo]:
522+
ret = None
523+
for i in range(250):
524+
ret = await router.resolve(request)
525+
return ret
526+
527+
ret = loop.run_until_complete(run_url_dispatcher_benchmark())
528+
assert ret is not None
529+
assert ret.get_info()["path"] == "/", ret.get_info()
530+
531+
@benchmark
532+
def _run() -> None:
533+
loop.run_until_complete(run_url_dispatcher_benchmark())
534+
535+
504536
def test_resolve_prefix_resources_many_prefix_many_plain(
505537
loop: asyncio.AbstractEventLoop,
506538
benchmark: BenchmarkFixture,

0 commit comments

Comments
 (0)