Skip to content

test(guardrails): Add request logging integration tests#760

Open
JashG wants to merge 1 commit into
mainfrom
jgulabrai/test-request-logging
Open

test(guardrails): Add request logging integration tests#760
JashG wants to merge 1 commit into
mainfrom
jgulabrai/test-request-logging

Conversation

@JashG

@JashG JashG commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Adds integration tests to validate the Guardrails plugin request-logging behavior

Summary by CodeRabbit

  • Tests
    • Added comprehensive integration coverage for request logging options.
    • Verified selective, complete, and omitted log data behavior.
    • Confirmed logging captures input and output rail activity.
    • Verified log data placement when returning choices.
    • Added validation coverage for unsupported logging options.

Signed-off-by: Jash Gulabrai <jgulabrai@nvidia.com>
@JashG
JashG requested review from a team as code owners July 17, 2026 16:22
@github-actions github-actions Bot added the test conventional-commit type label Jul 17, 2026
@JashG
JashG requested a review from albcui July 17, 2026 16:25
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds integration tests for VirtualModel guardrail request logging, covering field selection, populated structures, merged rail data, response placement, omission, and invalid options.

Changes

Request logging integration coverage

Layer / File(s) Summary
Logging assertions and test contract
plugins/nemo-guardrails/tests/integration/test_request_logging.py
Defines supported log fields and reusable assertions for validating returned logging structures.
VirtualModel request setup
plugins/nemo-guardrails/tests/integration/test_request_logging.py
Constructs guarded VirtualModel requests with mocked completions, inline configuration, optional logging flags, and optional return_choice.
Logging behavior scenarios
plugins/nemo-guardrails/tests/integration/test_request_logging.py
Tests individual and combined fields, omitted logs, merged input/output entries, embedded choice data, and rejection of unsupported fields.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly matches the main change: adding request logging integration tests for Guardrails.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jgulabrai/test-request-logging

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-guardrails/tests/integration/test_request_logging.py`:
- Around line 264-277: Update test_input_and_output_logs_merged_for_list_fields
to inspect log["internal_events"] by phase, asserting that both input and output
internal-event entries are present rather than only checking the total length.
Preserve the existing activated_rails phase assertions and other log-option
coverage.
- Around line 304-342: The test test_unknown_log_field_rejected should catch
nemo_platform.APIStatusError instead of a generic Exception, then assert the 422
error detail identifies options.log.unknown and states “Extra inputs are not
permitted.”
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e0477730-f774-4abe-9c9d-0376b4a70839

📥 Commits

Reviewing files that changed from the base of the PR and between b7ab493 and e048e47.

📒 Files selected for processing (1)
  • plugins/nemo-guardrails/tests/integration/test_request_logging.py

Comment on lines +264 to +277
def test_input_and_output_logs_merged_for_list_fields(self, igw_plugin_harness: IGWPluginHarness) -> None:
"""List-shaped log fields should concatenate input-rail and output-rail entries."""
response, _ = self._invoke_all_safe_request(
igw_plugin_harness,
log_options={"activated_rails": True, "llm_calls": True, "internal_events": True},
)

log = self._log_dict(response)

activated_rail_types = {rail["type"] for rail in log["activated_rails"]}
assert "input" in activated_rail_types
assert "output" in activated_rail_types
assert len(log["llm_calls"]) >= 2
assert len(log["internal_events"]) >= 2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Verify internal_events came from both middleware phases.

len(...) >= 2 cannot prove merging: one rail may emit multiple internal events. Assert phase-specific input and output events, as already done for activated_rails.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-guardrails/tests/integration/test_request_logging.py` around
lines 264 - 277, Update test_input_and_output_logs_merged_for_list_fields to
inspect log["internal_events"] by phase, asserting that both input and output
internal-event entries are present rather than only checking the total length.
Preserve the existing activated_rails phase assertions and other log-option
coverage.

Comment on lines +304 to +342
def test_unknown_log_field_rejected(self, igw_plugin_harness: IGWPluginHarness) -> None:
"""Unsupported log options should fail request validation."""
harness = igw_plugin_harness
test_data_names = make_guardrails_test_data_names(workspace=harness.workspace)

harness.mock_chat_completions(
test_data_names.main_model_entity_ref,
responses=[ChatCompletion(body=chat_completion(content="No"))],
)
harness.add_provider(
workspace=harness.workspace,
name=test_data_names.model_provider_name,
served_models={test_data_names.main_model_served_name: test_data_names.main_model_served_name},
)

guardrail_config = make_guardrail_config(
harness.workspace,
test_data_names.guardrail_config_name,
data=self._config_data(main_base_url=harness.nim_base_url),
)

with harness.load_plugin(GUARDRAILS_PLUGIN_NAME):
harness.add_virtual_model(
workspace=harness.workspace,
name=test_data_names.request_virtual_model_name,
default_model_entity=test_data_names.main_model_entity_ref,
request_middleware=[make_middleware_call(guardrail_config)],
)
with pytest.raises(Exception) as exc_info:
harness.chat_completions(
workspace=harness.workspace,
body={
"model": test_data_names.request_virtual_model_name,
"messages": [{"role": "user", "content": self.USER_INPUT}],
"guardrails": {"options": {"log": {"unknown": True}}},
},
)

assert "422" in str(exc_info.value)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C4 'pytest\.raises\(' plugins/nemo-guardrails/tests/integration
rg -n -C4 'def chat_completions\(' --type=py

Repository: NVIDIA-NeMo/nemo-platform

Length of output: 4464


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '300,350p' plugins/nemo-guardrails/tests/integration/test_request_logging.py

printf '\n--- middleware caching pattern ---\n'
sed -n '110,150p' plugins/nemo-guardrails/tests/integration/test_middleware_config_caching.py

printf '\n--- upstream error surfacing pattern ---\n'
sed -n '180,240p' plugins/nemo-guardrails/tests/integration/test_upstream_error_surfacing.py

printf '\n--- search validation exception uses ---\n'
rg -n 'APIStatusError|422|unknown' plugins/nemo-guardrails/tests/integration plugins/nemo-guardrails -g '*.py'

Repository: NVIDIA-NeMo/nemo-platform

Length of output: 10809


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,120p' plugins/nemo-guardrails/src/nemo_guardrails_plugin/requests.py

printf '\n--- unit rails validation cases ---\n'
sed -n '90,140p' plugins/nemo-guardrails/tests/unit/test_rails.py

printf '\n--- middleware validation cases ---\n'
sed -n '620,690p' plugins/nemo-guardrails/tests/unit/test_middleware.py

Repository: NVIDIA-NeMo/nemo-platform

Length of output: 8217


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the harness implementation and relevant exception handling.
rg -n -C3 'def chat_completions\(' plugins/nemo-guardrails -g '*.py'
rg -n -C3 'InferenceMiddlewareError|APIStatusError|BadRequestError' plugins/nemo-guardrails -g '*.py'

# Inspect the harness method if present in repo files.
fd -a '.*harness.*\.py|.*plugin.*harness.*\.py' plugins/nemo-guardrails

Repository: NVIDIA-NeMo/nemo-platform

Length of output: 163


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C4 'class .*Harness|chat_completions\(' plugins/nemo-guardrails -g '*.py'
rg -n -C4 'APIStatusError' plugins/nemo-guardrails/tests -g '*.py'

Repository: NVIDIA-NeMo/nemo-platform

Length of output: 50381


Assert the specific 422 detail plugins/nemo-guardrails/tests/integration/test_request_logging.py:332-342 should catch nemo_platform.APIStatusError and match options.log.unknown / Extra inputs are not permitted, not just any 422.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-guardrails/tests/integration/test_request_logging.py` around
lines 304 - 342, The test test_unknown_log_field_rejected should catch
nemo_platform.APIStatusError instead of a generic Exception, then assert the 422
error detail identifies options.log.unknown and states “Extra inputs are not
permitted.”

@github-actions

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 25531/32732 78.0% 62.7%
Integration Tests 14731/31381 46.9% 19.3%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test conventional-commit type

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant