|
1 | 1 | import shutil |
2 | 2 | import subprocess |
3 | 3 | from pathlib import Path |
4 | | -from unittest.mock import Mock, patch |
| 4 | +from unittest.mock import Mock, patch, MagicMock |
5 | 5 |
|
6 | 6 | import pytest |
7 | 7 | import yaml |
@@ -556,3 +556,69 @@ def test_experiments_check_experiment_error(tmp_path): |
556 | 556 | ) |
557 | 557 | with pytest.raises(RuntimeError, match=error_msg): |
558 | 558 | exps.check_experiment("error_exp") |
| 559 | + |
| 560 | +@patch("subprocess.run") |
| 561 | +def test_setup_reproduce_error(mock_run, exp): |
| 562 | + """Test that payu setup --repro fails raises an error and return to original work directory""" |
| 563 | + # Mock the payu setup --repro to fail |
| 564 | + mock_result = MagicMock() |
| 565 | + mock_result.returncode = 1 |
| 566 | + mock_result.stderr = "MD5 mismatch" |
| 567 | + mock_result.stdout = "Check manifest" |
| 568 | + mock_run.return_value = mock_result |
| 569 | + |
| 570 | + with pytest.raises(RuntimeError) as excinfo: |
| 571 | + exp.setup_reproduce() |
| 572 | + |
| 573 | + assert f"Failed to run payu setup with --reproduce. Error: {mock_result.stderr}" in str(excinfo.value) |
| 574 | + assert f"Full output: {mock_result.stdout}" in str(excinfo.value) |
| 575 | + |
| 576 | + # assert returning to the original work directory |
| 577 | + assert Path.cwd() == exp.control_path |
| 578 | + |
| 579 | +@patch("subprocess.run") |
| 580 | +def test_setup_manifests_unchanged_fail_setup(mock_run, exp): |
| 581 | + """Test that an error is raised when payu setup fails in setup_manifests_unchanged()""" |
| 582 | + # Mock the payu setup --repro to fail with unchanged manifests |
| 583 | + mock_result = MagicMock() |
| 584 | + mock_result.returncode = 1 |
| 585 | + mock_result.stderr = "Setup failed" |
| 586 | + mock_result.stdout = "Payu setup output" |
| 587 | + mock_run.return_value = mock_result |
| 588 | + |
| 589 | + with pytest.raises(RuntimeError) as excinfo: |
| 590 | + exp.setup_manifests_unchanged() |
| 591 | + |
| 592 | + assert "Error during payu setup." in str(excinfo.value) |
| 593 | + assert f"{'='*10}STDOUT{'='*10}\n {mock_result.stdout}\n" in str(excinfo.value) |
| 594 | + |
| 595 | + # assert returning to the original work directory |
| 596 | + assert Path.cwd() == exp.control_path |
| 597 | + |
| 598 | +@patch("subprocess.run") |
| 599 | +def test_setup_manifests_unchanged_show_changes(mock_run, exp): |
| 600 | + """Test that when manifests are changed, the `git diff` results are printed to stdout""" |
| 601 | + # Mock the `payu setup` succeed first |
| 602 | + setup_success = MagicMock(returncode=0, stdout="Payu setup succeeded") |
| 603 | + |
| 604 | + # Then mock the `git diff --name-only` to show which files are changed |
| 605 | + git_diff_name_only = MagicMock(returncode=1, stdout="manifests/input.yaml") |
| 606 | + |
| 607 | + # Mock the `git diff` to show the detailed changes in the file |
| 608 | + git_diff_output = "--- a/manifests/input.yaml\n+++ b/manifests/input.yaml\n+new line\n-old line" |
| 609 | + git_diff_run = MagicMock( |
| 610 | + returncode=0, |
| 611 | + stdout=git_diff_output |
| 612 | + ) |
| 613 | + |
| 614 | + # Run these mocks in sequence |
| 615 | + mock_run.side_effect = [setup_success, git_diff_name_only, git_diff_run] |
| 616 | + |
| 617 | + with pytest.raises(RuntimeError) as excinfo: |
| 618 | + exp.setup_manifests_unchanged() |
| 619 | + |
| 620 | + assert "Modifications are detected in file:\n" in str(excinfo.value) |
| 621 | + assert git_diff_output in str(excinfo.value) |
| 622 | + |
| 623 | + # assert returning to the original work directory |
| 624 | + assert Path.cwd() == exp.control_path |
0 commit comments