Skip to content

Commit fa84b8b

Browse files
committed
Merge latest feature/puzzletron_v2 into PR 2125 branch
Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
2 parents 16b1b27 + 5d1c3c1 commit fa84b8b

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
"""Failure-path tests for atomic PuzzleTron v2 wizard state persistence."""
17+
18+
from __future__ import annotations
19+
20+
import pytest
21+
22+
from puzzletron_setup import SetupError
23+
from puzzletron_setup.v2 import state as state_module
24+
from puzzletron_setup.v2.state import WizardState
25+
26+
27+
def test_failed_atomic_replace_preserves_last_resumable_state(tmp_path, monkeypatch):
28+
state = WizardState.start(tmp_path / "campaign", defaults_path=None)
29+
state.set_field("model.source", "/models/teacher")
30+
durable_snapshot = state.path.read_bytes()
31+
real_replace = state_module.os.replace
32+
replace_targets = []
33+
34+
def fail_replace(source, destination):
35+
replace_targets.append(destination)
36+
if destination == state.path:
37+
raise OSError("injected replace failure")
38+
return real_replace(source, destination)
39+
40+
monkeypatch.setattr(state_module.os, "replace", fail_replace)
41+
42+
with pytest.raises(SetupError, match="Cannot save v2 setup state"):
43+
state.set_field("model.source", "/models/candidate")
44+
45+
assert state.path in replace_targets
46+
assert state.path.read_bytes() == durable_snapshot
47+
assert WizardState.resume(state.path).get_field("model.source") == "/models/teacher"

0 commit comments

Comments
 (0)