test: Rewrite JWT cache tests
Timing dependent tests in the IO tests don't work too well when the next commit increases the JWT parsing performance. The remaining IO tests are for coverage and basic breakage. Loadtests are adapted so that performance regressions for JWT caching would be detected that way.
This commit is contained in:
committed by
Wolfgang Walther
parent
f69ef6c42d
commit
0948d38863
@@ -55,6 +55,8 @@ let
|
|||||||
export PGRST_DB_POOL="1"
|
export PGRST_DB_POOL="1"
|
||||||
export PGRST_DB_TX_END="rollback-allow-override"
|
export PGRST_DB_TX_END="rollback-allow-override"
|
||||||
export PGRST_LOG_LEVEL="crit"
|
export PGRST_LOG_LEVEL="crit"
|
||||||
|
export PGRST_JWT_SECRET="reallyreallyreallyreallyverysafe"
|
||||||
|
export PGRST_JWT_CACHE_MAX_LIFETIME="86400"
|
||||||
|
|
||||||
mkdir -p "$(dirname "$_arg_output")"
|
mkdir -p "$(dirname "$_arg_output")"
|
||||||
abs_output="$(realpath "$_arg_output")"
|
abs_output="$(realpath "$_arg_output")"
|
||||||
|
|||||||
+34
-70
@@ -1310,14 +1310,14 @@ def test_fail_with_automatic_recovery_disabled_and_terminated_using_query(defaul
|
|||||||
assert exitCode == 1
|
assert exitCode == 1
|
||||||
|
|
||||||
|
|
||||||
def test_server_timing_jwt_should_decrease_on_subsequent_requests(defaultenv):
|
def test_jwt_cache_server_timing(defaultenv):
|
||||||
"assert that server-timing duration for JWT should decrease on subsequent requests"
|
"server-timing duration is exposed for JWT with expiry"
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
**defaultenv,
|
**defaultenv,
|
||||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||||
"PGRST_JWT_SECRET": "@/dev/stdin",
|
"PGRST_JWT_SECRET": SECRET,
|
||||||
"PGRST_DB_CONFIG": "false",
|
"PGRST_DB_CONFIG": "false",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1331,102 +1331,66 @@ def test_server_timing_jwt_should_decrease_on_subsequent_requests(defaultenv):
|
|||||||
SECRET,
|
SECRET,
|
||||||
)
|
)
|
||||||
|
|
||||||
with run(stdin=SECRET.encode(), env=env) as postgrest:
|
with run(env=env) as postgrest:
|
||||||
first_timings = postgrest.session.get("/authors_only", headers=headers).headers[
|
first = postgrest.session.get("/authors_only", headers=headers)
|
||||||
"Server-Timing"
|
second = postgrest.session.get("/authors_only", headers=headers)
|
||||||
]
|
|
||||||
second_timings = postgrest.session.get(
|
|
||||||
"/authors_only", headers=headers
|
|
||||||
).headers["Server-Timing"]
|
|
||||||
|
|
||||||
first_dur = parse_server_timings_header(first_timings)["jwt"]
|
assert first.status_code == 200
|
||||||
second_dur = parse_server_timings_header(second_timings)["jwt"]
|
assert second.status_code == 200
|
||||||
|
|
||||||
# their difference should be atleast 0.3ms, implying
|
first_dur = parse_server_timings_header(first.headers["Server-Timing"])["jwt"]
|
||||||
# that JWT Caching is working as expected
|
second_dur = parse_server_timings_header(second.headers["Server-Timing"])["jwt"]
|
||||||
assert (first_dur - second_dur) > 0.3
|
|
||||||
|
assert first_dur >= 0
|
||||||
|
assert second_dur >= 0
|
||||||
|
|
||||||
|
|
||||||
# just added to complete code coverage
|
def test_jwt_cache_without_server_timing(defaultenv):
|
||||||
def test_jwt_caching_works_with_db_plan_disabled(defaultenv):
|
"JWT cache does not break requests without server-timing enabled"
|
||||||
"assert that JWT caching words even when Server-Timing header is not returned"
|
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
**defaultenv,
|
**defaultenv,
|
||||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||||
"PGRST_JWT_SECRET": "@/dev/stdin",
|
"PGRST_JWT_SECRET": SECRET,
|
||||||
"PGRST_DB_CONFIG": "false",
|
"PGRST_DB_CONFIG": "false",
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
|
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
|
||||||
|
|
||||||
with run(stdin=SECRET.encode(), env=env) as postgrest:
|
with run(env=env) as postgrest:
|
||||||
first_request = postgrest.session.get("/authors_only", headers=headers)
|
first = postgrest.session.get("/authors_only", headers=headers)
|
||||||
second_request = postgrest.session.get("/authors_only", headers=headers)
|
second = postgrest.session.get("/authors_only", headers=headers)
|
||||||
|
|
||||||
# in this case we don't get server-timing in response headers
|
assert first.status_code == 200
|
||||||
# so we can't compare durations, we just check if request succeeds
|
assert second.status_code == 200
|
||||||
assert first_request.status_code == 200 and second_request.status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_server_timing_jwt_should_not_decrease_when_caching_disabled(defaultenv):
|
def test_jwt_cache_without_exp_claim(defaultenv):
|
||||||
"assert than jwt duration should not decrease when disabled"
|
"server-timing duration is exposed for JWT without expiry"
|
||||||
|
|
||||||
env = {
|
|
||||||
**defaultenv,
|
|
||||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
|
||||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "0", # cache disabled
|
|
||||||
"PGRST_JWT_SECRET": "@/dev/stdin",
|
|
||||||
"PGRST_DB_CONFIG": "false",
|
|
||||||
}
|
|
||||||
|
|
||||||
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET)
|
|
||||||
|
|
||||||
with run(stdin=SECRET.encode(), env=env) as postgrest:
|
|
||||||
warmup_req = postgrest.session.get("/authors_only", headers=headers)
|
|
||||||
first_timings = postgrest.session.get("/authors_only", headers=headers).headers[
|
|
||||||
"Server-Timing"
|
|
||||||
]
|
|
||||||
second_timings = postgrest.session.get(
|
|
||||||
"/authors_only", headers=headers
|
|
||||||
).headers["Server-Timing"]
|
|
||||||
|
|
||||||
first_dur = parse_server_timings_header(first_timings)["jwt"]
|
|
||||||
second_dur = parse_server_timings_header(second_timings)["jwt"]
|
|
||||||
|
|
||||||
# their difference should be less than 150
|
|
||||||
# implying that token is not cached
|
|
||||||
assert (first_dur - second_dur) < 150.0
|
|
||||||
|
|
||||||
|
|
||||||
def test_jwt_cache_with_no_exp_claim(defaultenv):
|
|
||||||
"assert than jwt duration should decrease"
|
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
**defaultenv,
|
**defaultenv,
|
||||||
"PGRST_SERVER_TIMING_ENABLED": "true",
|
"PGRST_SERVER_TIMING_ENABLED": "true",
|
||||||
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
"PGRST_JWT_CACHE_MAX_LIFETIME": "86400",
|
||||||
"PGRST_JWT_SECRET": "@/dev/stdin",
|
"PGRST_JWT_SECRET": SECRET,
|
||||||
"PGRST_DB_CONFIG": "false",
|
"PGRST_DB_CONFIG": "false",
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET) # no exp
|
headers = jwtauthheader({"role": "postgrest_test_author"}, SECRET) # no exp
|
||||||
|
|
||||||
with run(stdin=SECRET.encode(), env=env) as postgrest:
|
with run(env=env) as postgrest:
|
||||||
first_timings = postgrest.session.get("/authors_only", headers=headers).headers[
|
first = postgrest.session.get("/authors_only", headers=headers)
|
||||||
"Server-Timing"
|
second = postgrest.session.get("/authors_only", headers=headers)
|
||||||
]
|
|
||||||
second_timings = postgrest.session.get(
|
|
||||||
"/authors_only", headers=headers
|
|
||||||
).headers["Server-Timing"]
|
|
||||||
|
|
||||||
first_dur = parse_server_timings_header(first_timings)["jwt"]
|
assert first.status_code == 200
|
||||||
second_dur = parse_server_timings_header(second_timings)["jwt"]
|
assert second.status_code == 200
|
||||||
|
|
||||||
# their difference should be atleast 0.3ms, implying
|
first_dur = parse_server_timings_header(first.headers["Server-Timing"])["jwt"]
|
||||||
# that JWT Caching is working as expected
|
second_dur = parse_server_timings_header(second.headers["Server-Timing"])["jwt"]
|
||||||
assert (first_dur - second_dur) > 0.3
|
|
||||||
|
assert first_dur >= 0
|
||||||
|
assert second_dur >= 0
|
||||||
|
|
||||||
|
|
||||||
def test_preflight_request_with_cors_allowed_origin_config(defaultenv):
|
def test_preflight_request_with_cors_allowed_origin_config(defaultenv):
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
GET http://postgrest/
|
GET http://postgrest/
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
Prefer: tx=commit
|
Prefer: tx=commit
|
||||||
|
|
||||||
HEAD http://postgrest/actors?actor=eq.1
|
HEAD http://postgrest/actors?actor=eq.1
|
||||||
Prefer: tx=commit
|
Prefer: tx=commit
|
||||||
|
|
||||||
GET http://postgrest/actors?select=*,roles(*,films(*))
|
GET http://postgrest/actors?select=*,roles(*,films(*))
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
Prefer: tx=commit
|
Prefer: tx=commit
|
||||||
|
|
||||||
POST http://postgrest/films?columns=id,title
|
POST http://postgrest/films?columns=id,title
|
||||||
@@ -12,6 +14,7 @@ Prefer: tx=rollback
|
|||||||
@post.json
|
@post.json
|
||||||
|
|
||||||
POST http://postgrest/films?columns=id,title,year,runtime,genres,director,actors,plot,posterUrl
|
POST http://postgrest/films?columns=id,title,year,runtime,genres,director,actors,plot,posterUrl
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
Prefer: tx=rollback
|
Prefer: tx=rollback
|
||||||
# this bulk.json was obtained from https://github.com/erik-sytnyk/movies-list/blob/master/db.json
|
# this bulk.json was obtained from https://github.com/erik-sytnyk/movies-list/blob/master/db.json
|
||||||
@bulk.json
|
@bulk.json
|
||||||
@@ -21,6 +24,7 @@ Prefer: tx=rollback
|
|||||||
@put.json
|
@put.json
|
||||||
|
|
||||||
PATCH http://postgrest/actors?actor=eq.1
|
PATCH http://postgrest/actors?actor=eq.1
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
Prefer: tx=rollback
|
Prefer: tx=rollback
|
||||||
@patch.json
|
@patch.json
|
||||||
|
|
||||||
@@ -28,8 +32,10 @@ DELETE http://postgrest/roles
|
|||||||
Prefer: tx=rollback
|
Prefer: tx=rollback
|
||||||
|
|
||||||
GET http://postgrest/rpc/call_me?name=John
|
GET http://postgrest/rpc/call_me?name=John
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
|
|
||||||
POST http://postgrest/rpc/call_me
|
POST http://postgrest/rpc/call_me
|
||||||
@rpc.json
|
@rpc.json
|
||||||
|
|
||||||
OPTIONS http://postgrest/actors
|
OPTIONS http://postgrest/actors
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CUIP5V9thWsGGFsFyGijSZf1fJMfarLHI9CEJL-TGNk
|
||||||
|
|||||||
Reference in New Issue
Block a user