Skip to content

Commit 7679002

Browse files
committed
test(llmrails): characterize public compatibility behavior
Pin public LLMRails state, sync wrappers, update_llm binding behavior, and pickle behavior before extracting internals.
1 parent 3fc828b commit 7679002

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import pytest
17+
18+
from nemoguardrails import LLMRails, RailsConfig
19+
from tests.utils import FakeLLMModel
20+
21+
22+
def _config() -> RailsConfig:
23+
return RailsConfig.from_content(config={"models": []})
24+
25+
26+
def test_constructor_keeps_public_state_visible():
27+
config = _config()
28+
llm = FakeLLMModel(responses=[])
29+
30+
rails = LLMRails(config=config, llm=llm)
31+
32+
assert rails.config is config
33+
assert rails.llm is llm
34+
assert rails.runtime is not None
35+
assert rails.llm_generation_actions is not None
36+
assert rails.events_history_cache == {}
37+
assert rails.explain_info is None
38+
39+
40+
def test_update_llm_keeps_runtime_generation_actions_and_public_attr_in_sync():
41+
rails = LLMRails(config=_config(), llm=FakeLLMModel(responses=[]))
42+
new_llm = FakeLLMModel(responses=["updated"])
43+
44+
rails.update_llm(new_llm)
45+
46+
assert rails.llm is new_llm
47+
assert rails.llm_generation_actions.llm is new_llm
48+
assert rails.runtime.registered_action_params["llm"] is new_llm
49+
50+
51+
@pytest.mark.asyncio
52+
async def test_sync_wrappers_raise_when_called_from_async_loop():
53+
rails = LLMRails(config=_config(), llm=FakeLLMModel(responses=[]))
54+
55+
with pytest.raises(RuntimeError, match="sync `generate` inside async code"):
56+
rails.generate(prompt="hi")
57+
58+
with pytest.raises(RuntimeError, match="sync `generate_events` inside async code"):
59+
rails.generate_events([])
60+
61+
with pytest.raises(RuntimeError, match="sync `generate_events` inside async code"):
62+
rails.process_events([])
63+
64+
with pytest.raises(RuntimeError, match="sync `check` inside async code"):
65+
rails.check([{"role": "user", "content": "hi"}])
66+
67+
68+
def test_getstate_serializes_config_only():
69+
rails = LLMRails(config=_config(), llm=FakeLLMModel(responses=[]))
70+
rails.events_history_cache["cached"] = [{"type": "CachedEvent"}]
71+
rails.register_action_param("custom_param", object())
72+
73+
state = rails.__getstate__()
74+
75+
assert state == {"config": rails.config}

0 commit comments

Comments
 (0)