@@ -218,6 +218,19 @@ def forward_persisted_get_status(hash_value):
218218 error.read()
219219 return error.code
220220
221+ # The sandbox may resolve policy binary symlinks shortly after the entrypoint
222+ # starts, bumping the policy generation during the first forward request.
223+ # Retry expected-allowed forward requests so the test still targets L7 behavior.
224+ def retry_forward_allowed(label, request_fn):
225+ last_status = None
226+ for attempt in range(6):
227+ last_status = request_fn()
228+ if last_status != 403:
229+ return last_status
230+ DETAILS[f"{{label}}_transient_403_attempts"] = attempt + 1
231+ time.sleep(0.3)
232+ return last_status
233+
221234def proxy_parts(*names):
222235 proxy_url = next((os.environ.get(name) for name in names if os.environ.get(name)), None)
223236 parsed = urllib.parse.urlparse(proxy_url)
@@ -379,14 +392,14 @@ def connect_chunked_status(query):
379392 return connect_http_status("connect_chunked_query_allowed", request)
380393
381394results = {{
382- "forward_query_allowed": forward_status(QUERY_VIEWER),
383- "forward_get_query_allowed": forward_get_status(QUERY_VIEWER),
395+ "forward_query_allowed": retry_forward_allowed("forward_query_allowed", lambda: forward_status(QUERY_VIEWER) ),
396+ "forward_get_query_allowed": retry_forward_allowed("forward_get_query_allowed", lambda: forward_get_status(QUERY_VIEWER) ),
384397 "forward_duplicate_get_denied": forward_duplicate_get_status(),
385- "forward_persisted_get_allowed": forward_persisted_get_status("abc123"),
398+ "forward_persisted_get_allowed": retry_forward_allowed("forward_persisted_get_allowed", lambda: forward_persisted_get_status("abc123") ),
386399 "forward_unregistered_persisted_get_denied": forward_persisted_get_status("missing"),
387- "forward_chunked_query_allowed": forward_chunked_status(QUERY_VIEWER),
400+ "forward_chunked_query_allowed": retry_forward_allowed("forward_chunked_query_allowed", lambda: forward_chunked_status(QUERY_VIEWER) ),
388401 "forward_unlisted_field_denied": forward_status(QUERY_REPOSITORY),
389- "forward_mutation_allowed": forward_status(MUTATION_CREATE),
402+ "forward_mutation_allowed": retry_forward_allowed("forward_mutation_allowed", lambda: forward_status(MUTATION_CREATE) ),
390403 "forward_deny_rule_denied": forward_status(MUTATION_DELETE),
391404 "connect_query_allowed": connect_status(QUERY_VIEWER, "connect_query_allowed"),
392405 "connect_get_query_allowed": connect_get_status(QUERY_VIEWER, "connect_get_query_allowed"),
0 commit comments