Skip to content

Commit

Permalink
fixes #62678 increase file.tidied flexibility with regard to age and …
Browse files Browse the repository at this point in the history
…size
  • Loading branch information
nicholasmhughes authored and Megan Wilhite committed Sep 20, 2022
1 parent 7bb2f61 commit bbe4cab
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 21 deletions.
1 change: 1 addition & 0 deletions changelog/62678.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Increase file.tidied flexibility with regard to age and size
31 changes: 11 additions & 20 deletions salt/states/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -2092,21 +2092,6 @@ def _matches(name):
return True
return False

def _compare_age_size(mysize, myage):
"""
Helper to perform age and size evaluation based on defined parameters
"""
if age_size_only and age_size_only.lower() in ["age", "size"]:
if age_size_only.lower() == "age":
ret = myage.days >= age
else:
ret = mysize >= size
elif age_size_logical_operator.upper() == "AND":
ret = mysize >= size and myage.days >= age
else:
ret = mysize >= size or myage.days >= age
return ret

# Iterate over given directory tree, depth-first
for root, dirs, files in os.walk(top=name, topdown=False, followlinks=followlinks):
# Check criteria for the found files and directories
Expand Down Expand Up @@ -2146,11 +2131,17 @@ def _compare_age_size(mysize, myage):
filename = path

# Verify against given criteria, collect all elements that should be removed
if (
_compare_age_size(mysize, myage)
and _matches(name=filename)
and deleteme
):
if age_size_only and age_size_only.lower() in ["age", "size"]:
if age_size_only.lower() == "age":
compare_age_size = myage.days >= age
else:
compare_age_size = mysize >= size
elif age_size_logical_operator.upper() == "AND":
compare_age_size = mysize >= size and myage.days >= age
else:
compare_age_size = mysize >= size or myage.days >= age

if compare_age_size and _matches(name=filename) and deleteme:
todelete.append(path)

# Now delete the stuff
Expand Down
225 changes: 224 additions & 1 deletion tests/pytests/unit/states/file/test_tidied.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import os
from datetime import datetime
from datetime import datetime, timedelta

import pytest

Expand Down Expand Up @@ -327,3 +327,226 @@ def test_tidied_with_full_path_exclude():
}
assert exp == ret
assert remove.call_count == 6


def test_tidied_age_size_args_AND_operator_age_not_size():
name = os.sep + "test"
if salt.utils.platform.is_windows():
name = "c:" + name
walker = [
(os.path.join("test", "test1"), [], ["file1"]),
(os.path.join("test", "test2", "test3"), [], []),
(os.path.join("test", "test2"), ["test3"], ["file2"]),
("test", ["test1", "test2"], ["file3"]),
]
today_delta = (datetime.today() - timedelta(days=14)) - datetime.utcfromtimestamp(0)
remove = MagicMock(name="file.remove")
with patch("os.walk", return_value=walker), patch(
"os.path.islink", return_value=False
), patch("os.path.getatime", return_value=today_delta.total_seconds()), patch(
"os.path.getsize", return_value=10
), patch.dict(
filestate.__opts__, {"test": False}
), patch.dict(
filestate.__salt__, {"file.remove": remove}
), patch(
"os.path.isdir", return_value=True
):
ret = filestate.tidied(
name=name,
exclude=[os.path.join("test", "test2", "file2").replace("\\", "\\\\")],
age=1,
size=11,
age_size_logical_operator="AND",
age_size_only=None,
)
exp = {
"name": name,
"changes": {},
"result": True,
"comment": "Nothing to remove from directory {}".format(name),
}
assert ret == exp
assert remove.call_count == 0


def test_tidied_age_size_args_AND_operator_age_not_size_age_only():
name = os.sep + "test"
if salt.utils.platform.is_windows():
name = "c:" + name
walker = [
(os.path.join("test", "test1"), [], ["file1"]),
(os.path.join("test", "test2", "test3"), [], []),
(os.path.join("test", "test2"), ["test3"], ["file2"]),
("test", ["test1", "test2"], ["file3"]),
]
today_delta = (datetime.today() - timedelta(days=14)) - datetime.utcfromtimestamp(0)
remove = MagicMock(name="file.remove")
with patch("os.walk", return_value=walker), patch(
"os.path.islink", return_value=False
), patch("os.path.getatime", return_value=today_delta.total_seconds()), patch(
"os.path.getsize", return_value=10
), patch.dict(
filestate.__opts__, {"test": False}
), patch.dict(
filestate.__salt__, {"file.remove": remove}
), patch(
"os.path.isdir", return_value=True
):
ret = filestate.tidied(
name=name,
exclude=[os.path.join("test", "test2", "file2").replace("\\", "\\\\")],
age=1,
size=11,
age_size_logical_operator="AND",
age_size_only="age",
)
exp = {
"name": name,
"changes": {
"removed": [
os.path.join("test", "test1", "file1"),
os.path.join("test", "test2", "file2"),
os.path.join("test", "file3"),
]
},
"result": True,
"comment": "Removed 3 files or directories from directory {}".format(name),
}
assert ret == exp
assert remove.call_count == 3


def test_tidied_age_size_args_AND_operator_size_not_age():
name = os.sep + "test"
if salt.utils.platform.is_windows():
name = "c:" + name
walker = [
(os.path.join("test", "test1"), [], ["file1"]),
(os.path.join("test", "test2", "test3"), [], []),
(os.path.join("test", "test2"), ["test3"], ["file2"]),
("test", ["test1", "test2"], ["file3"]),
]
today_delta = (datetime.today() - timedelta(days=14)) - datetime.utcfromtimestamp(0)
remove = MagicMock(name="file.remove")
with patch("os.walk", return_value=walker), patch(
"os.path.islink", return_value=False
), patch("os.path.getatime", return_value=today_delta.total_seconds()), patch(
"os.path.getsize", return_value=10
), patch.dict(
filestate.__opts__, {"test": False}
), patch.dict(
filestate.__salt__, {"file.remove": remove}
), patch(
"os.path.isdir", return_value=True
):
ret = filestate.tidied(
name=name,
exclude=[os.path.join("test", "test2", "file2").replace("\\", "\\\\")],
age=(today_delta.days + 1),
size=9,
age_size_logical_operator="AND",
age_size_only=None,
)
exp = {
"name": name,
"changes": {},
"result": True,
"comment": "Nothing to remove from directory {}".format(name),
}
assert ret == exp
assert remove.call_count == 0


def test_tidied_age_size_args_AND_operator_size_not_age_size_only():
name = os.sep + "test"
if salt.utils.platform.is_windows():
name = "c:" + name
walker = [
(os.path.join("test", "test1"), [], ["file1"]),
(os.path.join("test", "test2", "test3"), [], []),
(os.path.join("test", "test2"), ["test3"], ["file2"]),
("test", ["test1", "test2"], ["file3"]),
]
today_delta = (datetime.today() - timedelta(days=14)) - datetime.utcfromtimestamp(0)
remove = MagicMock(name="file.remove")
with patch("os.walk", return_value=walker), patch(
"os.path.islink", return_value=False
), patch("os.path.getatime", return_value=today_delta.total_seconds()), patch(
"os.path.getsize", return_value=10
), patch.dict(
filestate.__opts__, {"test": False}
), patch.dict(
filestate.__salt__, {"file.remove": remove}
), patch(
"os.path.isdir", return_value=True
):
ret = filestate.tidied(
name=name,
exclude=[os.path.join("test", "test2", "file2").replace("\\", "\\\\")],
age=(today_delta.days + 1),
size=9,
age_size_logical_operator="AND",
age_size_only="size",
)
exp = {
"name": name,
"changes": {
"removed": [
os.path.join("test", "test1", "file1"),
os.path.join("test", "test2", "file2"),
os.path.join("test", "file3"),
]
},
"result": True,
"comment": "Removed 3 files or directories from directory {}".format(name),
}
assert ret == exp
assert remove.call_count == 3


def test_tidied_age_size_args_AND_operator_size_and_age():
name = os.sep + "test"
if salt.utils.platform.is_windows():
name = "c:" + name
walker = [
(os.path.join("test", "test1"), [], ["file1"]),
(os.path.join("test", "test2", "test3"), [], []),
(os.path.join("test", "test2"), ["test3"], ["file2"]),
("test", ["test1", "test2"], ["file3"]),
]
today_delta = (datetime.today() - timedelta(days=14)) - datetime.utcfromtimestamp(0)
remove = MagicMock(name="file.remove")
with patch("os.walk", return_value=walker), patch(
"os.path.islink", return_value=False
), patch("os.path.getatime", return_value=today_delta.total_seconds()), patch(
"os.path.getsize", return_value=10
), patch.dict(
filestate.__opts__, {"test": False}
), patch.dict(
filestate.__salt__, {"file.remove": remove}
), patch(
"os.path.isdir", return_value=True
):
ret = filestate.tidied(
name=name,
exclude=[os.path.join("test", "test2", "file2").replace("\\", "\\\\")],
age=1,
size=9,
age_size_logical_operator="AND",
age_size_only=None,
)
exp = {
"name": name,
"changes": {
"removed": [
os.path.join("test", "test1", "file1"),
os.path.join("test", "test2", "file2"),
os.path.join("test", "file3"),
]
},
"result": True,
"comment": "Removed 3 files or directories from directory {}".format(name),
}
assert ret == exp
assert remove.call_count == 3

0 comments on commit bbe4cab

Please sign in to comment.