Skip to content

Commit 50421d7

Browse files
committed
Add test for cylc reinstall with permissions changed
1 parent 9db9521 commit 50421d7

File tree

1 file changed

+57
-28
lines changed

1 file changed

+57
-28
lines changed

tests/integration/test_reinstall.py

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,23 @@
1919
import asyncio
2020
from contextlib import asynccontextmanager
2121
from pathlib import Path
22+
from secrets import token_hex
2223
from types import SimpleNamespace
23-
from uuid import uuid1
2424

2525
import pytest
2626

27-
from cylc.flow.exceptions import (
28-
WorkflowFilesError,
29-
)
30-
from cylc.flow.install import (
31-
reinstall_workflow,
32-
)
27+
from cylc.flow.exceptions import WorkflowFilesError
28+
from cylc.flow.install import reinstall_workflow
3329
from cylc.flow.option_parsers import Options
3430
from cylc.flow.scripts.reinstall import (
3531
get_option_parser as reinstall_gop,
3632
reinstall_cli,
3733
)
38-
from cylc.flow.workflow_files import (
39-
WorkflowFiles,
40-
)
34+
from cylc.flow.workflow_files import WorkflowFiles
4135

4236
from .utils.entry_points import EntryPointWrapper
4337

38+
4439
ReInstallOptions = Options(reinstall_gop())
4540

4641
# cli opts
@@ -66,6 +61,18 @@ def non_interactive(monkeypatch):
6661
)
6762

6863

64+
@pytest.fixture
65+
def answer_prompt(monkeypatch: pytest.MonkeyPatch):
66+
"""Answer reinstall prompt."""
67+
68+
def inner(answer: str):
69+
monkeypatch.setattr(
70+
'cylc.flow.scripts.reinstall._input', lambda x: answer
71+
)
72+
73+
return inner
74+
75+
6976
@pytest.fixture
7077
def one_src(tmp_path):
7178
src_dir = tmp_path / 'src'
@@ -77,7 +84,7 @@ def one_src(tmp_path):
7784

7885
@pytest.fixture
7986
def one_run(one_src, test_dir, run_dir):
80-
w_run_dir = test_dir / str(uuid1())
87+
w_run_dir = test_dir / token_hex(4)
8188
w_run_dir.mkdir()
8289
(w_run_dir / 'flow.cylc').touch()
8390
(w_run_dir / 'rose-suite.conf').touch()
@@ -148,7 +155,7 @@ async def test_interactive(
148155
capsys,
149156
capcall,
150157
interactive,
151-
monkeypatch
158+
answer_prompt
152159
):
153160
"""It should perform a dry-run and prompt in interactive mode."""
154161
# capture reinstall calls
@@ -159,23 +166,18 @@ async def test_interactive(
159166
# give it something to reinstall
160167
(one_src.path / 'a').touch()
161168

162-
# reinstall answering "no" to any prompt
163-
monkeypatch.setattr(
164-
'cylc.flow.scripts.reinstall._input',
165-
lambda x: 'n'
169+
answer_prompt('n')
170+
assert (
171+
await reinstall_cli(opts=ReInstallOptions(), workflow_id=one_run.id)
172+
is False
166173
)
167-
assert await reinstall_cli(opts=ReInstallOptions(), workflow_id=one_run.id) is False
168174

169175
# only one rsync call should have been made (i.e. the --dry-run)
170176
assert [call[1].get('dry_run') for call in reinstall_calls] == [True]
171177
assert 'Reinstall canceled, no changes made.' in capsys.readouterr().out
172178
reinstall_calls.clear()
173179

174-
# reinstall answering "yes" to any prompt
175-
monkeypatch.setattr(
176-
'cylc.flow.scripts.reinstall._input',
177-
lambda x: 'y'
178-
)
180+
answer_prompt('y')
179181
assert await reinstall_cli(opts=ReInstallOptions(), workflow_id=one_run.id)
180182

181183
# two rsync calls should have been made (i.e. the --dry-run and the real)
@@ -234,7 +236,9 @@ async def test_rsync_stuff(one_src, one_run, capsys, non_interactive):
234236
assert not (one_run.path / 'c').exists()
235237

236238

237-
async def test_rose_warning(one_src, one_run, capsys, interactive, monkeypatch):
239+
async def test_rose_warning(
240+
one_src, one_run, capsys, interactive, answer_prompt
241+
):
238242
"""It should warn that Rose installed files will be deleted.
239243
240244
See https://github.com/cylc/cylc-rose/issues/149
@@ -244,11 +248,7 @@ async def test_rose_warning(one_src, one_run, capsys, interactive, monkeypatch):
244248
'Files created by Rose file installation will show as deleted'
245249
)
246250

247-
# reinstall answering "no" to any prompt
248-
monkeypatch.setattr(
249-
'cylc.flow.scripts.reinstall._input',
250-
lambda x: 'n'
251-
)
251+
answer_prompt('n')
252252
(one_src.path / 'a').touch() # give it something to install
253253

254254
# reinstall (with rose-suite.conf file)
@@ -303,6 +303,35 @@ async def test_rsync_fail(one_src, one_run, mock_glbl_cfg, non_interactive):
303303
assert 'An error occurred reinstalling' in str(exc_ctx.value)
304304

305305

306+
async def test_permissions_change(
307+
one_src,
308+
one_run,
309+
interactive,
310+
answer_prompt,
311+
monkeypatch: pytest.MonkeyPatch,
312+
capsys: pytest.CaptureFixture,
313+
):
314+
"""It detects permissions changes."""
315+
# Add script file:
316+
script_path: Path = one_src.path / 'myscript'
317+
script_path.touch()
318+
await reinstall_cli(
319+
opts=ReInstallOptions(skip_interactive=True), workflow_id=one_run.id
320+
)
321+
assert (one_run.path / 'myscript').is_file()
322+
capsys.readouterr() # clears capsys
323+
324+
# Change permissions (e.g. user forgot to make it executable before)
325+
script_path.chmod(0o777)
326+
# Answer "no" to reinstall prompt (we just want to test dry run)
327+
answer_prompt('n')
328+
await reinstall_cli(
329+
opts=ReInstallOptions(), workflow_id=one_run.id
330+
)
331+
out, _ = capsys.readouterr()
332+
assert "send myscript" in out
333+
334+
306335
@pytest.fixture
307336
def my_install_plugin(monkeypatch):
308337
"""This configures a single post_install plugin.

0 commit comments

Comments
 (0)