From d577afef70eb1601aca83e819b7b5199d3ced679 Mon Sep 17 00:00:00 2001 From: twangboy Date: Fri, 30 Aug 2024 11:55:46 -0600 Subject: [PATCH] Add tests and changelog --- changelog/64630.fixed.md | 3 + .../functional/states/file/test_recurse.py | 89 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 changelog/64630.fixed.md diff --git a/changelog/64630.fixed.md b/changelog/64630.fixed.md new file mode 100644 index 000000000000..f49c58d4c2e0 --- /dev/null +++ b/changelog/64630.fixed.md @@ -0,0 +1,3 @@ +Fixed an intermittent issue with file.recurse where the state would +report failure even on success. Makes sure symlinks are created +after the target file is created diff --git a/tests/pytests/functional/states/file/test_recurse.py b/tests/pytests/functional/states/file/test_recurse.py index c735d5128dac..53583b26b2d4 100644 --- a/tests/pytests/functional/states/file/test_recurse.py +++ b/tests/pytests/functional/states/file/test_recurse.py @@ -7,6 +7,19 @@ ] +@pytest.fixture(scope="module") +def symlink(state_tree): + # Create directory structure + source_dir = state_tree / "test_symlink" + if not source_dir.is_dir(): + source_dir.mkdir() + source_file = source_dir / "source_file.txt" + source_file.write_text("This is the source file...") + symlink_file = source_dir / "symlink" + symlink_file.symlink_to(source_file) + yield + + @pytest.mark.parametrize("test", (False, True)) def test_recurse(file, tmp_path, grail, test): """ @@ -249,3 +262,79 @@ def test_issue_2726_mode_kwarg(modules, tmp_path, state_tree): ret = modules.state.template_str("\n".join(good_template)) for state_run in ret: assert state_run.result is True + + +def test_issue_64630_keep_symlinks_true(file, symlink, tmp_path): + """ + Make sure that symlinks are created and that there isn't an error + """ + target_dir = tmp_path / "test_symlink" # Target for the file.recurse state + target_file = target_dir / "source_file.txt" + target_symlink = target_dir / "symlink" + + ret = file.recurse( + name=str(target_dir), source=f"salt://{target_dir.name}", keep_symlinks=True + ) + assert ret.result is True + + assert target_dir.exists() + assert target_file.is_file() + assert target_symlink.is_symlink() + + +def test_issue_64630_keep_symlinks_false(file, symlink, tmp_path): + """ + Make sure that symlinks are created and that there isn't an error + """ + target_dir = tmp_path / "test_symlink" # Target for the file.recurse state + target_file = target_dir / "source_file.txt" + target_symlink = target_dir / "symlink" + + ret = file.recurse( + name=str(target_dir), source=f"salt://{target_dir.name}", keep_symlinks=False + ) + assert ret.result is True + + assert target_dir.exists() + assert target_file.is_file() + assert target_symlink.is_file() + assert target_file.read_text() == target_symlink.read_text() + + +def test_issue_64630_force_symlinks_true(file, symlink, tmp_path): + """ + Make sure that symlinks are created and that there isn't an error + """ + target_dir = tmp_path / "test_symlink" # Target for the file.recurse state + target_file = target_dir / "source_file.txt" + target_symlink = target_dir / "symlink" + + ret = file.recurse( + name=str(target_dir), source=f"salt://{target_dir.name}", force_symlinks=True + ) + assert ret.result is True + + assert target_dir.exists() + assert target_file.is_file() + assert target_symlink.is_file() + + +def test_issue_64630_force_symlinks_keep_symlinks_true(file, symlink, tmp_path): + """ + Make sure that symlinks are created and that there isn't an error + """ + target_dir = tmp_path / "test_symlink" # Target for the file.recurse state + target_file = target_dir / "source_file.txt" + target_symlink = target_dir / "symlink" + + ret = file.recurse( + name=str(target_dir), + source=f"salt://{target_dir.name}", + force_symlinks=True, + keep_symlinks=True, + ) + assert ret.result is True + + assert target_dir.exists() + assert target_file.is_file() + assert target_symlink.is_symlink()