def clean(ctx): """Cleanup (temporary) test artifacts.""" dry_run = ctx.config.run.dry directories = ctx.test.clean.directories or [] files = ctx.test.clean.files or [] cleanup_dirs(directories, dry_run=dry_run) cleanup_files(files, dry_run=dry_run)
def test_remove_raises_oserror(self, tmp_path, monkeypatch, capsys): def mock_remove(p): raise OSError("MOCK_REMOVE: %s" % p) setup_workdir(tmp_path, [ "foo/one.xxx", "more/two.xxx", ]) problematic_file1 = tmp_path / "foo/one.xxx" problematic_file1 = problematic_file1.relative_to(tmp_path) problematic_file2 = tmp_path / "more/two.xxx" problematic_file2 = problematic_file2.relative_to(tmp_path) with cd(str(tmp_path)): monkeypatch.setattr("path.Path.remove_p", mock_remove) cleanup_files(["**/*.xxx"]) captured = capsys.readouterr() print(captured.out) expected1 = "REMOVE: %s" % problematic_file1 expected2 = "OSError: MOCK_REMOVE: %s" % problematic_file1 assert expected1 in captured.out assert expected2 in captured.out expected2 = "OSError: MOCK_REMOVE: %s" % problematic_file2 assert expected2 in captured.out
def test_with_file_in_readonly_dir_is_not_removed(self, tmp_path, capsys): # -- SETUP: readonly_mode = 0o555 # dr-xr-xr-x (disabled: write-mode) setup_workdir(tmp_path, [ "readonly.dir/one.xxx", ]) my_dir = tmp_path/"readonly.dir" my_file1 = my_dir/"one.xxx" my_dir.chmod(readonly_mode) assert my_file1.exists() and my_file1.is_file() my_dir_mode = stat.S_IMODE(my_file1.stat().st_mode) print("DIAG: my_dir.mode= 0o%o" % my_dir_mode) assert path_is_readable(my_dir) assert not path_is_writable(my_dir) # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) # with pytest.raises(OSError, match="Permission denied"): cwd = tmp_path cleanup_files(["**/*.xxx"], cwd) captured = capsys.readouterr() assert my_file1.exists(), "OOPS: my_file1 was removed." if python_version < python35: # -- REASON: OSError is not raised for newer py3 versions. assert "OSError" in captured.out assert "Permission denied:" in captured.out assert str(my_file1) in captured.out
def test_dry_run__should_removes_no_files(self, tmp_path): # -- SETUP: my_file1 = tmp_path/"one.xxx" my_file1.write_text(u"one.xxx") assert my_file1.exists() and my_file1.is_file() # -- EXECUTE AND VERIFY: cwd = tmp_path cleanup_files(["*.xxx"], cwd, dry_run=True) assert my_file1.exists(), "OOPS: my_file1 was removed."
def test_with_one_pattern_in_other_workdir_subtree(self, tmp_path): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "other/more/two.xxx" ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"other/more/two.xxx" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() # -- EXECUTE AND VERIFY: cwd = tmp_path cleanup_files(["**/*.xxx"], cwd/"other") assert my_file1.exists() assert not my_file2.exists()
def test_with_no_permissions_file_is_removed(self, tmp_path): # -- SETUP: readonly_mode = 0o000 # mask: -.---.---.--- NO_PERMISSIONS my_file1 = tmp_path/"one.xxx" my_file1.write_text(u"one.xxx") my_file1.chmod(readonly_mode) make_path_readonly(my_file1) assert my_file1.exists() and my_file1.is_file() assert path_is_readonly(my_file1) file1_mode = stat.S_IMODE(my_file1.stat().st_mode) print("DIAG: my_file1.mode= 0o%o" % file1_mode) # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) cwd = tmp_path cleanup_files(["*.xxx"], cwd) assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED"
def test_with_two_patterns(self, tmp_path): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "more/two.zzz" ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"more/two.zzz" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() # -- EXECUTE AND VERIFY: cwd = tmp_path cleanup_files(["**/*.xxx", "**/*.zzz"], cwd) assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED" assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED"
def test_without_any_matching_files(self, tmp_path): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "more/two.xxx" ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"more/two.xxx" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) # with pytest.raises(OSError, match="Permission denied"): cwd = tmp_path cleanup_files(["**/*.zzz"], cwd) assert my_file1.exists(), "OOPS: my_file1 was REMOVED" assert my_file2.exists(), "OOPS: my_file2 was REMOVED"
def test_with_readonly_file_is_removed(self, tmp_path): # -- SETUP: readonly_mode = 0o400 # mask: -.r--.---.--- my_file1 = tmp_path/"one.xxx" my_file1.write_text(u"one.xxx") my_file1.chmod(readonly_mode) make_path_readonly(my_file1) assert my_file1.exists() and my_file1.is_file() assert path_is_readonly(my_file1) file1_mode = stat.S_IMODE(my_file1.stat().st_mode) print("DIAG: my_file1.mode= 0o%o" % file1_mode) # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) # with pytest.raises(OSError, match=".* Permission denied:.*"): cwd = tmp_path cleanup_files(["*.xxx"], cwd) assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED"
def test_with_exact_name(self, tmp_path): remove_pattern = "more/two.xxx" # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "more/two.xxx" ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"more/two.xxx" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) # with pytest.raises(OSError, match="Permission denied"): cwd = tmp_path cleanup_files([remove_pattern], cwd) assert my_file1.exists(), "OOPS: my_file1 was REMOVED" assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED"
def test_with_one_pattern_in_current_workdir(self, tmp_path): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "two.xxx", "more/ignored.xxx", ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"two.xxx" my_file3 = tmp_path/"more/ignored.xxx" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() assert my_file3.exists() and my_file3.is_file() # -- EXECUTE AND VERIFY: cwd = tmp_path cleanup_files(["*.xxx"], cwd) assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED" assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED" assert my_file3.exists(), "OOPS: my_file3 was REMOVED"
def test_without_workdir_param_uses_current_directory(self, tmp_path): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "two.xxx", "more/ignored.xxx", ]) my_file1 = tmp_path/"one.xxx" my_file2 = tmp_path/"two.xxx" my_file3 = tmp_path/"more/ignored.xxx" assert my_file1.exists() and my_file1.is_file() assert my_file2.exists() and my_file2.is_file() assert my_file3.exists() and my_file3.is_file() # -- EXECUTE AND VERIFY: with cd(str(tmp_path)): # -- STRING-CONVERSION (needed for: python2.7) cleanup_files(["*.xxx"]) assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED" assert not my_file2.exists(), "OOPS: my_file2 was NOT_REMOVED" assert my_file3.exists(), "OOPS: my_file3 was REMOVED"
def test_skips_remove_below_sys_executable_basedir(self, tmp_path, monkeypatch, capsys): """SKIP-SUICIDE in context of cleanup_dirs in virtual environment.""" setup_workdir(tmp_path, [ "opt/python_x.y/bin/python", "opt/python_x.y/foo/one.xxx", "foo2/two.xxx" ]) python_basedir = tmp_path / "opt/python_x.y" mock_sys_executable = python_basedir / "bin/python" mock_sys_executable = str(mock_sys_executable.absolute()) problematic_file = python_basedir / "foo/one.xxx" problematic_file = problematic_file.relative_to(tmp_path) with cd(str(tmp_path)): monkeypatch.setattr("sys.executable", mock_sys_executable) cleanup_files(["**/*.xxx"], dry_run=True) captured = capsys.readouterr() print(captured.out) expected = "REMOVE: %s" % problematic_file assert expected not in captured.out
def test_with_matching_directory__should_skip_remove_and_showit_in_verbose_mode(self, tmp_path, capsys): # -- SETUP: setup_workdir(tmp_path, [ "one.xxx", "more/two.xxx/.dir" ]) my_file1 = tmp_path/"one.xxx" my_dir2 = tmp_path/"more/two.xxx" assert my_file1.exists() and my_file1.is_file() assert my_dir2.exists() and my_dir2.is_dir() # -- EXECUTE AND VERIFY: Best-effort, ignore read-only file(s) # with pytest.raises(OSError, match="Permission denied"): cwd = tmp_path cleanup_files(["**/*.xxx"], cwd, verbose=True) captured = capsys.readouterr() assert not my_file1.exists(), "OOPS: my_file1 was NOT_REMOVED" assert my_dir2.exists(), "OOPS: my_dir2 was REMOVED" # -- ONLY IN VERBOSE MODE: expected = "REMOVE: {0} (SKIPPED: Not a file)".format(my_dir2) assert expected in captured.out