Coverage for tests/test_constraints.py: 14%
94 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 02:46 -0700
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 02:46 -0700
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This software is dual licensed under the GNU General Public License and also
10# under a 3-clause BSD license. Recipients may choose which of these licenses
11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12# respectively. If you choose the GPL option then the following text applies
13# (but note that there is still no warranty even if you opt for BSD instead):
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 3 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
28"""Test the constraints model."""
30import unittest
32from lsst.daf.butler import DimensionUniverse, StorageClass, ValidationError
33from lsst.daf.butler.datastore.constraints import Constraints, ConstraintsConfig
34from lsst.daf.butler.tests import DatasetTestHelper
37class ConstraintsTestCase(unittest.TestCase, DatasetTestHelper):
38 """Test constraints system."""
40 def setUp(self):
41 self.id = 0
43 # Create DatasetRefs to test against constraints model
44 self.universe = DimensionUniverse()
45 dimensions = self.universe.conform(("visit", "physical_filter", "instrument"))
46 sc = StorageClass("DummySC", dict, None)
47 self.calexpA = self.makeDatasetRef(
48 "calexp",
49 dimensions,
50 sc,
51 {"instrument": "A", "physical_filter": "u", "visit": 3},
52 )
54 dimensions = self.universe.conform(("visit", "detector", "instrument"))
55 self.pviA = self.makeDatasetRef(
56 "pvi",
57 dimensions,
58 sc,
59 {"instrument": "A", "visit": 1, "detector": 0},
60 )
61 self.pviB = self.makeDatasetRef(
62 "pvi",
63 dimensions,
64 sc,
65 {"instrument": "B", "visit": 2, "detector": 0},
66 )
68 def testSimpleAccept(self):
69 config = ConstraintsConfig({"accept": ["calexp", "ExposureF"]})
70 constraints = Constraints(config, universe=self.universe)
72 self.assertTrue(constraints.isAcceptable(self.calexpA))
73 self.assertFalse(constraints.isAcceptable(self.pviA))
75 # Dimension accept
76 config = ConstraintsConfig({"accept": ["visit+physical_filter+instrument", "ExposureF"]})
77 constraints = Constraints(config, universe=self.universe)
79 self.assertTrue(constraints.isAcceptable(self.calexpA))
80 self.assertFalse(constraints.isAcceptable(self.pviA))
82 config = ConstraintsConfig({"accept": ["visit+detector+instrument", "ExposureF"]})
83 constraints = Constraints(config, universe=self.universe)
85 self.assertFalse(constraints.isAcceptable(self.calexpA))
86 self.assertTrue(constraints.isAcceptable(self.pviA))
87 self.assertTrue(constraints.isAcceptable(self.pviA))
89 # Only accept instrument A pvi
90 config = ConstraintsConfig({"accept": [{"instrument<A>": ["pvi"]}]})
91 constraints = Constraints(config, universe=self.universe)
93 self.assertFalse(constraints.isAcceptable(self.calexpA))
94 self.assertTrue(constraints.isAcceptable(self.pviA))
95 self.assertFalse(constraints.isAcceptable(self.pviB))
97 # Accept PVI for instrument B but not instrument A
98 config = ConstraintsConfig({"accept": ["calexp", {"instrument<B>": ["pvi"]}]})
99 constraints = Constraints(config, universe=self.universe)
101 self.assertTrue(constraints.isAcceptable(self.calexpA))
102 self.assertFalse(constraints.isAcceptable(self.pviA))
103 self.assertTrue(constraints.isAcceptable(self.pviB))
105 def testSimpleReject(self):
106 config = ConstraintsConfig({"reject": ["calexp", "ExposureF"]})
107 constraints = Constraints(config, universe=self.universe)
109 self.assertFalse(constraints.isAcceptable(self.calexpA))
110 self.assertTrue(constraints.isAcceptable(self.pviA))
112 def testAcceptReject(self):
113 # Reject everything except calexp
114 config = ConstraintsConfig({"accept": ["calexp"], "reject": ["all"]})
115 constraints = Constraints(config, universe=self.universe)
117 self.assertTrue(constraints.isAcceptable(self.calexpA))
118 self.assertFalse(constraints.isAcceptable(self.pviA))
120 # Accept everything except calexp
121 config = ConstraintsConfig({"reject": ["calexp"], "accept": ["all"]})
122 constraints = Constraints(config, universe=self.universe)
124 self.assertFalse(constraints.isAcceptable(self.calexpA))
125 self.assertTrue(constraints.isAcceptable(self.pviA))
127 # Reject pvi but explicitly accept pvi for instrument A
128 # Reject all instrument A but accept everything else
129 # The reject here is superfluous
130 config = ConstraintsConfig({"accept": [{"instrument<A>": ["pvi"]}], "reject": ["pvi"]})
131 constraints = Constraints(config, universe=self.universe)
133 self.assertFalse(constraints.isAcceptable(self.calexpA))
134 self.assertTrue(constraints.isAcceptable(self.pviA))
135 self.assertFalse(constraints.isAcceptable(self.pviB))
137 # Accept everything except pvi from other than instrument A
138 config = ConstraintsConfig({"accept": ["all", {"instrument<A>": ["pvi"]}], "reject": ["pvi"]})
139 constraints = Constraints(config, universe=self.universe)
141 self.assertTrue(constraints.isAcceptable(self.calexpA))
142 self.assertTrue(constraints.isAcceptable(self.pviA))
143 self.assertFalse(constraints.isAcceptable(self.pviB))
145 def testWildcardReject(self):
146 # Reject everything
147 config = ConstraintsConfig({"reject": ["all"]})
148 constraints = Constraints(config, universe=self.universe)
150 self.assertFalse(constraints.isAcceptable(self.calexpA))
151 self.assertFalse(constraints.isAcceptable(self.pviA))
153 # Reject all instrument A but accept everything else
154 config = ConstraintsConfig({"reject": [{"instrument<A>": ["all"]}]})
155 constraints = Constraints(config, universe=self.universe)
157 self.assertFalse(constraints.isAcceptable(self.calexpA))
158 self.assertFalse(constraints.isAcceptable(self.pviA))
159 self.assertTrue(constraints.isAcceptable(self.pviB))
161 def testWildcardAccept(self):
162 # Accept everything
163 config = ConstraintsConfig({})
164 constraints = Constraints(config, universe=self.universe)
166 self.assertTrue(constraints.isAcceptable(self.calexpA))
167 self.assertTrue(constraints.isAcceptable(self.pviA))
169 # Accept everything
170 constraints = Constraints(None, universe=self.universe)
172 self.assertTrue(constraints.isAcceptable(self.calexpA))
173 self.assertTrue(constraints.isAcceptable(self.pviA))
175 # Accept everything explicitly
176 config = ConstraintsConfig({"accept": ["all"]})
177 constraints = Constraints(config, universe=self.universe)
179 self.assertTrue(constraints.isAcceptable(self.calexpA))
180 self.assertTrue(constraints.isAcceptable(self.pviA))
182 # Accept all instrument A but reject everything else
183 config = ConstraintsConfig({"accept": [{"instrument<A>": ["all"]}]})
184 constraints = Constraints(config, universe=self.universe)
186 self.assertTrue(constraints.isAcceptable(self.calexpA))
187 self.assertTrue(constraints.isAcceptable(self.pviA))
188 self.assertFalse(constraints.isAcceptable(self.pviB))
190 def testEdgeCases(self):
191 # Accept everything and reject everything
192 config = ConstraintsConfig({"accept": ["all"], "reject": ["all"]})
193 with self.assertRaises(ValidationError):
194 Constraints(config, universe=self.universe)
197if __name__ == "__main__":
198 unittest.main()