16
16
>>> get_controller("User")
17
17
18
18
"""
19
+ import time
19
20
import unittest
20
21
22
+ from tenacity import retry , retry_if_exception_type , stop_after_attempt , wait_fixed
23
+
21
24
import frappe
25
+ from frappe .frappeclient import FrappeClient
22
26
from frappe .model .base_document import get_controller
27
+ from frappe .query_builder .utils import db_type_is
28
+ from frappe .tests .test_query_builder import run_only_if
23
29
from frappe .tests .utils import FrappeTestCase
24
30
from frappe .website .path_resolver import PathResolver
25
31
26
32
33
+ @run_only_if (db_type_is .MARIADB )
27
34
class TestPerformance (FrappeTestCase ):
28
35
def reset_request_specific_caches (self ):
29
36
# To simulate close to request level of handling
@@ -33,6 +40,8 @@ def reset_request_specific_caches(self):
33
40
frappe .clear_cache ()
34
41
35
42
def setUp (self ) -> None :
43
+ self .HOST = frappe .utils .get_site_url (frappe .local .site )
44
+
36
45
self .reset_request_specific_caches ()
37
46
38
47
def test_meta_caching (self ):
@@ -55,6 +64,36 @@ def test_db_value_cache(self):
55
64
with self .assertQueryCount (0 ):
56
65
doc .get_invalid_links ()
57
66
67
+ @retry (
68
+ retry = retry_if_exception_type (AssertionError ),
69
+ stop = stop_after_attempt (3 ),
70
+ wait = wait_fixed (0.5 ),
71
+ reraise = True ,
72
+ )
73
+ def test_req_per_seconds_basic (self ):
74
+ """Ideally should be ran against gunicorn worker, though I have not seen any difference
75
+ when using werkzeug's run_simple for synchronous requests."""
76
+
77
+ EXPECTED_RPS = 55 # measured on GHA
78
+ FAILURE_THREASHOLD = 0.1
79
+
80
+ req_count = 1000
81
+ client = FrappeClient (self .HOST , "Administrator" , self .ADMIN_PASSWORD )
82
+
83
+ start = time .perf_counter ()
84
+ for _ in range (req_count ):
85
+ client .get_list ("ToDo" , limit_page_length = 1 )
86
+ end = time .perf_counter ()
87
+
88
+ rps = req_count / (end - start )
89
+
90
+ print (f"Completed { req_count } in { end - start } @ { rps } requests per seconds" )
91
+ self .assertGreaterEqual (
92
+ rps ,
93
+ EXPECTED_RPS * (1 - FAILURE_THREASHOLD ),
94
+ f"Possible performance regression in basic /api/Resource list requests" ,
95
+ )
96
+
58
97
@unittest .skip ("Not implemented" )
59
98
def test_homepage_resolver (self ):
60
99
paths = ["/" , "/app" ]
0 commit comments