6
6
import random
7
7
import string
8
8
from pathlib import Path
9
- from typing import NoReturn , Optional
9
+ from typing import NoReturn , Optional , cast
10
10
from unittest import mock
11
11
12
+ import pytest
12
13
from multidict import CIMultiDict , CIMultiDictProxy
13
14
from pytest_codspeed import BenchmarkFixture
14
15
from yarl import URL
18
19
from aiohttp .http import HttpVersion , RawRequestMessage
19
20
20
21
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
+
21
36
def _mock_request (method : str , path : str ) -> web .Request :
22
37
message = RawRequestMessage (
23
38
method ,
@@ -366,23 +381,15 @@ def _run() -> None:
366
381
def test_resolve_gitapi (
367
382
loop : asyncio .AbstractEventLoop ,
368
383
benchmark : BenchmarkFixture ,
384
+ github_urls : list [str ],
369
385
) -> 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."""
376
387
377
388
async def handler (request : web .Request ) -> NoReturn :
378
389
assert False
379
390
380
- here = Path (__file__ ).parent
381
- with (here / "github-urls.json" ).open () as f :
382
- urls = json .load (f )
383
-
384
391
app = web .Application ()
385
- for url in urls :
392
+ for url in github_urls :
386
393
app .router .add_get (url , handler )
387
394
app .freeze ()
388
395
router = app .router
@@ -425,21 +432,13 @@ def _run() -> None:
425
432
def test_resolve_gitapi_subapps (
426
433
loop : asyncio .AbstractEventLoop ,
427
434
benchmark : BenchmarkFixture ,
435
+ github_urls : list [str ],
428
436
) -> 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."""
435
438
436
439
async def handler (request : web .Request ) -> NoReturn :
437
440
assert False
438
441
439
- here = Path (__file__ ).parent
440
- with (here / "github-urls.json" ).open () as f :
441
- urls = json .load (f )
442
-
443
442
subapps = {
444
443
"gists" : web .Application (),
445
444
"orgs" : web .Application (),
@@ -451,7 +450,7 @@ async def handler(request: web.Request) -> NoReturn:
451
450
}
452
451
453
452
app = web .Application ()
454
- for url in urls :
453
+ for url in github_urls :
455
454
parts = url .split ("/" )
456
455
subapp = subapps .get (parts [1 ])
457
456
if subapp is not None :
@@ -501,6 +500,39 @@ def _run() -> None:
501
500
loop .run_until_complete (run_url_dispatcher_benchmark ())
502
501
503
502
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
+
504
536
def test_resolve_prefix_resources_many_prefix_many_plain (
505
537
loop : asyncio .AbstractEventLoop ,
506
538
benchmark : BenchmarkFixture ,
0 commit comments