From 4f7db40587578ac92489b44ee8d35727f6217948 Mon Sep 17 00:00:00 2001 From: Yucheng Zhu Date: Fri, 28 Aug 2026 17:03:08 -0700 Subject: [PATCH] test(e2e): exempt the guardrail config echo from the post_call leak assertion --- .../guardrails/test_bedrock_guardrail_e2e.py | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/e2e/guardrails/test_bedrock_guardrail_e2e.py b/tests/e2e/guardrails/test_bedrock_guardrail_e2e.py index f80abdefd29..449803f3c80 100644 --- a/tests/e2e/guardrails/test_bedrock_guardrail_e2e.py +++ b/tests/e2e/guardrails/test_bedrock_guardrail_e2e.py @@ -15,10 +15,11 @@ env vars are deliberately absent from the gateway (they hijack RDS IAM auth). from __future__ import annotations +import json import os +from typing import Final import pytest - from e2e_config import unique_marker from e2e_http import UnknownApiError from guardrails_client import ( @@ -27,9 +28,24 @@ from guardrails_client import ( poll_until_blocked, ) from lifecycle import ResourceManager +from pydantic import JsonValue, TypeAdapter pytestmark = pytest.mark.e2e +_JSON: Final[TypeAdapter[JsonValue]] = TypeAdapter(JsonValue) + + +def _without_assessments(value: JsonValue) -> JsonValue: + """The assessments echo guardrail CONFIG, not content: the stage guardrail's + topic policy is itself named after the denied word, so its label lands in + every assessment listing and would trip a leak check aimed at model output.""" + if isinstance(value, dict): + return {key: _without_assessments(child) for key, child in value.items() if key != "assessments"} + if isinstance(value, list): + return [_without_assessments(item) for item in value] + return value + + MODEL = "gemini-2.5-flash" # Matches the word/topic policy the guardrail this suite points at actually denies. # Content filters are not assumed: the guardrail resource carries no contentPolicy, @@ -114,7 +130,7 @@ class TestBedrockGuardrail: assert any(token in body_lower for token in ("violated", "blocked", "intervened")), ( f"block body should name the guardrail verdict; got: {body[:400]}" ) - assert blocked_word not in body, ( + assert blocked_word not in json.dumps(_without_assessments(_JSON.validate_json(body))), ( f"the blocked model output must not leak into the error body; got: {body[:400]}" ) case _: