Skip to content

Commit 08e9715

Browse files
committed
Merge branch 'issue_1237-ts-filter'
2 parents 6368f33 + 059ec34 commit 08e9715

File tree

2 files changed

+219
-2
lines changed

2 files changed

+219
-2
lines changed

src/rez/package_filter.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,21 +499,27 @@ class TimestampRule(Rule):
499499
"""
500500
name = "timestamp"
501501

502-
def __init__(self, timestamp, family=None, reverse=False):
502+
def __init__(self, timestamp, family=None, reverse=False,
503+
match_untimestamped=False):
503504
"""Create a timestamp rule.
504505
505506
Args:
506507
timestamp (int): Epoch time.
507508
family (str): Package family to apply the rule to.
508509
reverse (bool): If True, reverse the logic so that packages released
509510
*after* the timestamp are matched.
511+
match_untimestamped (bool): Defines behaviour on non-timestamped
512+
packages.
510513
"""
511514
self.timestamp = timestamp
512515
self.reverse = reverse
516+
self.match_untimestamped = match_untimestamped
513517
self._family = family
514518

515519
def match(self, package):
516-
if self.reverse:
520+
if not package.timestamp:
521+
return self.match_untimestamped
522+
elif self.reverse:
517523
return (package.timestamp > self.timestamp)
518524
else:
519525
return (package.timestamp <= self.timestamp)
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Copyright Contributors to the Rez Project
3+
4+
5+
"""
6+
Test cases for package_filter.py (package filtering)
7+
"""
8+
from rez.tests.util import TestBase
9+
from rez.packages import iter_packages
10+
from rez.vendor.version.requirement import Requirement
11+
from rez.package_filter import PackageFilter, PackageFilterList, GlobRule, \
12+
RegexRule, RangeRule, TimestampRule
13+
14+
15+
class TestPackageFilter(TestBase):
16+
"""Tests package filtering.
17+
"""
18+
@classmethod
19+
def setUpClass(cls):
20+
cls.py_packages_path = cls.data_path("packages", "py_packages")
21+
cls.solver_packages_path = cls.data_path("solver", "packages")
22+
23+
cls.settings = dict(
24+
packages_path=[
25+
cls.solver_packages_path,
26+
cls.py_packages_path
27+
],
28+
package_filter=None)
29+
30+
def _test(self, fltr, pkg_family, expected_result):
31+
32+
# convert from json if required
33+
if isinstance(fltr, dict):
34+
fltr = PackageFilter.from_pod(fltr)
35+
elif isinstance(fltr, list):
36+
fltr = PackageFilterList.from_pod(fltr)
37+
38+
def filter_versions(fltr_):
39+
matching_versions = set()
40+
41+
for pkg in iter_packages(pkg_family):
42+
if not fltr_.excludes(pkg):
43+
matching_versions.add(str(pkg.version))
44+
45+
self.assertEqual(matching_versions, set(expected_result))
46+
47+
# apply filter to all pkg versions
48+
filter_versions(fltr)
49+
50+
# serialise to/from json and do it again
51+
data = fltr.to_pod()
52+
fltr2 = fltr.from_pod(data)
53+
filter_versions(fltr2)
54+
55+
def test_empty_filter(self):
56+
"""Test that empty filter has no effect
57+
"""
58+
fltr = PackageFilter()
59+
self._test(
60+
fltr,
61+
"pydad",
62+
["1", "2", "3"]
63+
)
64+
65+
def test_empty_filter_list(self):
66+
"""Test that empty filter list has no effect
67+
"""
68+
fltr = PackageFilterList()
69+
self._test(
70+
fltr,
71+
"pydad",
72+
["1", "2", "3"]
73+
)
74+
75+
def test_glob_filter(self):
76+
"""Test the glob filter.
77+
"""
78+
fltr = PackageFilter()
79+
fltr.add_exclusion(GlobRule("timestamped-*.5"))
80+
81+
self._test(
82+
fltr,
83+
"timestamped",
84+
[
85+
"1.0.6",
86+
"1.1.0",
87+
"1.1.1",
88+
"1.2.0",
89+
"2.0.0",
90+
"2.1.0"
91+
]
92+
)
93+
94+
def test_regex_filter(self):
95+
"""Test the regex filter.
96+
"""
97+
fltr = PackageFilter()
98+
fltr.add_exclusion(RegexRule("timestamped-1.[1|2].*"))
99+
100+
self._test(
101+
fltr,
102+
"timestamped",
103+
[
104+
"1.0.5",
105+
"1.0.6",
106+
"2.0.0",
107+
"2.1.0",
108+
"2.1.5"
109+
]
110+
)
111+
112+
def test_range_filter(self):
113+
"""Test the range filter.
114+
"""
115+
fltr = PackageFilter()
116+
fltr.add_exclusion(RangeRule(Requirement("timestamped-1.1+")))
117+
118+
self._test(
119+
fltr,
120+
"timestamped",
121+
[
122+
"1.0.5",
123+
"1.0.6"
124+
]
125+
)
126+
127+
def test_timestamp_filter(self):
128+
"""Test the timestamp filter.
129+
"""
130+
fltr = PackageFilter()
131+
fltr.add_exclusion(TimestampRule(6999, family="timestamped"))
132+
133+
self._test(
134+
fltr,
135+
"timestamped",
136+
[
137+
"2.1.0",
138+
"2.1.5"
139+
]
140+
)
141+
142+
def test_otherfam_filter(self):
143+
"""Test that a filter on a different fam has no effect
144+
"""
145+
fltr = PackageFilter()
146+
fltr.add_exclusion(GlobRule("timestamped-*"))
147+
148+
self._test(
149+
fltr,
150+
"pydad",
151+
["1", "2", "3"]
152+
)
153+
154+
def test_excl_and_incl(self):
155+
"""Test that combo of exclusion and inclusion works as expected
156+
"""
157+
self._test(
158+
{
159+
"excludes": ["glob(*.5)"],
160+
"includes": ["range(timestamped-2)"]
161+
},
162+
"timestamped",
163+
[
164+
# "1.0.5", due to excludes
165+
"1.0.6",
166+
"1.1.0",
167+
"1.1.1",
168+
"1.2.0",
169+
"2.0.0",
170+
"2.1.0",
171+
"2.1.5" # due to includes
172+
]
173+
)
174+
175+
def test_filter_list(self):
176+
"""Test that logic wrt list of filters works as expected
177+
"""
178+
179+
# exclude all *.0 packages, and all 2.* packages except for pymum
180+
fltrs = [
181+
# fltr-1
182+
{
183+
"excludes": ["*.0"]
184+
},
185+
# fltr-2
186+
{
187+
"excludes": ["*-2.*"],
188+
"includes": ["pymum"]
189+
}
190+
]
191+
192+
self._test(
193+
fltrs,
194+
"timestamped",
195+
[
196+
"1.0.5",
197+
"1.0.6",
198+
# "1.1.0", due to fltr-1
199+
"1.1.1",
200+
# "1.2.0", due to fltr-1
201+
# "2.0.0", due to fltr-1 and fltr-2
202+
# "2.1.0", due to fltr-1 and fltr-2
203+
# "2.1.5" due to fltr-2
204+
]
205+
)
206+
207+
self._test(
208+
fltrs,
209+
"pymum",
210+
["1", "2", "3"]
211+
)

0 commit comments

Comments
 (0)