From 5cd9216d5a62f0668f0e42b4f144a2e283671a20 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 9 Mar 2026 17:16:53 +0100 Subject: [PATCH 1/2] Add message to ease debugging --- bin/test-fastly-vcl.py | 133 +++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 30 deletions(-) diff --git a/bin/test-fastly-vcl.py b/bin/test-fastly-vcl.py index b4281528..156d8e29 100644 --- a/bin/test-fastly-vcl.py +++ b/bin/test-fastly-vcl.py @@ -9,131 +9,204 @@ NOW_EPOCH_MS = int(time.time() * 1000) OLD_EPOCH_MS = NOW_EPOCH_MS - 30 * 86400 * 1000 # 30 days ago +print(f"Testing {SERVER_URL} with User-Agent: {USER_AGENT}") +print("Current time (epoch ms):", NOW_EPOCH_MS) +print("Old time (epoch ms):", OLD_EPOCH_MS) + @pytest.mark.parametrize( - ("url", "expected"), + ("url", "expected", "message"), [ - ("/", 307), - ("/v1", 307), - ("/v1/", 200), - ("/v2", 307), - ("/v2/", 200), - ("/v1/boo", 406), - ("/v1/cert-chains", 406), - ("/v1/buckets", 200), - ("/v1/buckets/main", 200), - ("/v1/buckets/main/collections", 200), - ("/v1/buckets/main/collections/regions", 200), - ("/v1/buckets/main/collections/regions/records", 200), - ("/v1/buckets/main/collections/regions/changeset", 400), - ("/v1/buckets/main/collections/regions/changeset?_expected=0", 200), - ("/v1/buckets/main/collections/regions/changeset?_expected=0&_since=0", 200), + ("/", 307, "Root URL redirects to /v1/"), + ("/v1", 307, "Trailing slash is required for /v1/"), + ("/v1/", 200, "Base API URL should be accessible"), + ("/v2", 307, "Trailing slash is required for /v2/"), + ("/v2/", 200, "Base API URL should be accessible"), + ("/v1/boo", 406, "Unknown endpoint should return 406"), + ("/v1/cert-chains", 406, "Unknown endpoint should return 406"), + ("/v1/buckets", 200, "Buckets list"), + ("/v1/buckets/main", 200, "Main bucket"), + ("/v1/buckets/main/collections", 200, "Collections list"), + ("/v1/buckets/main/collections/regions", 200, "Collection metadata"), + ("/v1/buckets/main/collections/regions/records", 200, "Collection records"), + ( + "/v1/buckets/main/collections/regions/changeset", + 400, + "Missing _expected should return 400", + ), + ( + "/v1/buckets/main/collections/regions/changeset?_expected=0", + 200, + "Changeset with expected=0", + ), + ( + "/v1/buckets/main/collections/regions/changeset?_expected=0&_since=0", + 200, + "Changeset with expected=0 and since=0", + ), ( f"/v1/buckets/main/collections/regions/changeset?_expected={NOW_EPOCH_MS}", 200, + "Changeset with current timestamp as _expected should return 200", ), ( f'/v1/buckets/main/collections/regions/changeset?_expected="{NOW_EPOCH_MS}"', 200, + "Changeset with current timestamp as _expected (quoted) should return 200", ), ( f'/v1/buckets/main/collections/regions/changeset?_expected={NOW_EPOCH_MS}&_since="123"', 200, + "Changeset with current timestamp as _expected and quoted _since should return 200", ), ( f"/v1/buckets/main/collections/regions/changeset?_expected={NOW_EPOCH_MS}&_since=123", 200, + "Changeset with current timestamp as _expected and unquoted _since should return 200", ), ( f'/v1/buckets/main/collections/regions/changeset?_expected="{NOW_EPOCH_MS}"&_since="123"', 200, + "Changeset with current timestamp as quoted _expected and quoted _since should return 200", ), ( f'/v1/buckets/main/collections/regions/changeset?_expected="{NOW_EPOCH_MS}"&_since=123', 200, + "Changeset with current timestamp as quoted _expected and unquoted _since should return 200", ), ( '/v1/buckets/main/collections/regions/changeset?_expected="abc"', 200, - ), # TODO: should be 400 + "TODO: should be 400", + ), ( f'/v1/buckets/main/collections/regions/changeset?_expected="{OLD_EPOCH_MS}"', 200, + "Changeset with old timestamp as quoted _expected should return 307", + ), + ( + "/v1/buckets/monitor/collections/changes/records", + 406, + "Decommissioned monitor/changes records", + ), + ( + "/v1/buckets/monitor/collections/changes/changeset", + 400, + "Missing _expected should return 400 for monitor/changes changeset", + ), + ( + "/v1/buckets/monitor/collections/changes/changeset?_expected=abc", + 400, + "Non-numeric _expected should return 400 for monitor/changes changeset", + ), + ( + "/v1/buckets/monitor/collections/changes/changeset?_expected=0", + 200, + "Changeset with expected=0 should return 200 for monitor/changes changeset", ), - ("/v1/buckets/monitor/collections/changes/records", 406), - ("/v1/buckets/monitor/collections/changes/changeset", 400), - ("/v1/buckets/monitor/collections/changes/changeset?_expected=abc", 400), - ("/v1/buckets/monitor/collections/changes/changeset?_expected=0", 200), ( f"/v1/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}", 200, + "Changeset with current timestamp as _expected should return 200 for monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"', 200, + "Changeset with current timestamp as quoted _expected should return 200 for monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"&_since="{OLD_EPOCH_MS}"', 307, + "Changeset with current timestamp as quoted _expected and old timestamp as quoted _since should return 307 for monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since="{NOW_EPOCH_MS}"', 200, + "Changeset with current timestamp as _expected and quoted current timestamp as _since should return 200 for monitor/changes changeset", ), ( f"/v1/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since={NOW_EPOCH_MS}", 200, + "Changeset with current timestamp as _expected and current timestamp as _since should return 200 for monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"&_since="{NOW_EPOCH_MS}"', 200, + "Changeset with current timestamp as quoted _expected and quoted current timestamp as _since should return 200 for monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"&_since={NOW_EPOCH_MS}', 200, + "Changeset with current timestamp as quoted _expected and current timestamp as _since should return 200 for monitor/changes changeset", + ), + ("/v2/boo", 406, "Unknown endpoint should return 406"), + ("/v2/buckets", 404, "Buckets endpoint should return 404 in v2"), + ("/v2/buckets/main", 404, "Main bucket should return 404 in v2"), + ( + "/v2/buckets/main/collections", + 404, + "Collections endpoint should return 404 in v2", + ), + ( + "/v2/buckets/main/collections/regions", + 404, + "Collection metadata endpoint should return 404 in v2", + ), + ( + "/v2/buckets/main/collections/regions/records", + 404, + "Records endpoint should return 404 in v2", ), - ("/v2/boo", 406), - ("/v2/buckets", 404), - ("/v2/buckets/main", 404), - ("/v2/buckets/main/collections", 404), - ("/v2/buckets/main/collections/regions", 404), - ("/v2/buckets/main/collections/regions/records", 404), ( "/v2/buckets/main/collections/regions/changeset", 400, + "Missing _expected should return 400 for v2 changeset", + ), + ( + "/v2/buckets/main/collections/regions/changeset?_expected=0", + 200, + "Changeset with expected=0 should return 200 for v2 changeset", ), - ("/v2/buckets/main/collections/regions/changeset?_expected=0", 200), ( f'/v2/buckets/main/collections/regions/changeset?_expected="{NOW_EPOCH_MS}"', 422, + "Quoted _expected should return 422 for v2 changeset", ), ( f"/v2/buckets/main/collections/regions/changeset?_expected={NOW_EPOCH_MS}", 200, + "Unquoted _expected should return 200 for v2 changeset", ), ( f'/v2/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"', 422, + "Quoted _expected should return 422 for monitor/changes changeset in v2", ), ( f"/v2/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}", 200, + "Unquoted _expected should return 200 for monitor/changes changeset in v2", ), ( f'/v2/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since="{OLD_EPOCH_MS}"', 422, + "Quoted _since should return 422 for monitor/changes changeset in v2", ), ( f"/v2/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since={OLD_EPOCH_MS}", 200, + "Unquoted _since should return 200 for monitor/changes changeset in v2", ), ], ) -def test_fastly_vcl_responses(url, expected): +def test_fastly_vcl_responses(url, expected, message): url = f"{SERVER_URL}{url}" resp = requests.head(url, headers={"User-Agent": USER_AGENT}, allow_redirects=False) assert resp.status_code == expected, ( - url + f" returned {resp.status_code}, expected {expected}" + message + + "\n" + + url + + f" returned {resp.status_code}, expected {expected} (Location: {resp.headers.get('Location', '')})" ) From 1df171b6e9f6ee17ccdb844c855859860eaf8ae4 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 9 Mar 2026 17:28:13 +0100 Subject: [PATCH 2/2] Adjust VCL tests with current behaviour --- bin/test-fastly-vcl.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/bin/test-fastly-vcl.py b/bin/test-fastly-vcl.py index 156d8e29..3c6bd62b 100644 --- a/bin/test-fastly-vcl.py +++ b/bin/test-fastly-vcl.py @@ -84,6 +84,11 @@ 200, "Changeset with old timestamp as quoted _expected should return 307", ), + ( + f"/v1/buckets/main/collections/regions/changeset?_expected={OLD_EPOCH_MS}", + 200, + "Changeset with old timestamp as _expected should return return 200", + ), ( "/v1/buckets/monitor/collections/changes/records", 406, @@ -111,7 +116,7 @@ ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"', - 200, + 307, "Changeset with current timestamp as quoted _expected should return 200 for monitor/changes changeset", ), ( @@ -131,13 +136,13 @@ ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"&_since="{NOW_EPOCH_MS}"', - 200, - "Changeset with current timestamp as quoted _expected and quoted current timestamp as _since should return 200 for monitor/changes changeset", + 307, + "Changeset with current timestamp as quoted _expected redirects to unquoted in monitor/changes changeset", ), ( f'/v1/buckets/monitor/collections/changes/changeset?_expected="{NOW_EPOCH_MS}"&_since={NOW_EPOCH_MS}', - 200, - "Changeset with current timestamp as quoted _expected and current timestamp as _since should return 200 for monitor/changes changeset", + 307, + "Changeset with current timestamp as quoted _expected redirects to unquoted in monitor/changes changeset", ), ("/v2/boo", 406, "Unknown endpoint should return 406"), ("/v2/buckets", 404, "Buckets endpoint should return 404 in v2"), @@ -159,8 +164,8 @@ ), ( "/v2/buckets/main/collections/regions/changeset", - 400, - "Missing _expected should return 400 for v2 changeset", + 422, + "Missing _expected should return 422 for v2 changeset", ), ( "/v2/buckets/main/collections/regions/changeset?_expected=0", @@ -189,13 +194,13 @@ ), ( f'/v2/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since="{OLD_EPOCH_MS}"', - 422, - "Quoted _since should return 422 for monitor/changes changeset in v2", + 307, + "Quoted old _since should redirect to unfiltered monitor/changes changeset in v2", ), ( f"/v2/buckets/monitor/collections/changes/changeset?_expected={NOW_EPOCH_MS}&_since={OLD_EPOCH_MS}", - 200, - "Unquoted _since should return 200 for monitor/changes changeset in v2", + 307, + "Unquoted old _since should redirect to unfiltered monitor/changes changeset in v2", ), ], )