Coverage for tests/test_storageClass.py : 11%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22import os
23import pickle
24import unittest
26from lsst.daf.butler import StorageClass, StorageClassFactory, StorageClassConfig, StorageClassDelegate
28"""Tests related to the StorageClass infrastructure.
29"""
31TESTDIR = os.path.abspath(os.path.dirname(__file__))
34class PythonType:
35 """A dummy class to test the registry of Python types."""
36 pass
39class StorageClassFactoryTestCase(unittest.TestCase):
40 """Tests of the storage class infrastructure.
41 """
43 def testCreation(self):
44 """Test that we can dynamically create storage class subclasses.
46 This is critical for testing the factory functions."""
47 className = "TestImage"
48 sc = StorageClass(className, pytype=dict)
49 self.assertIsInstance(sc, StorageClass)
50 self.assertEqual(sc.name, className)
51 self.assertEqual(str(sc), className)
52 self.assertFalse(sc.components)
53 self.assertTrue(sc.validateInstance({}))
54 self.assertFalse(sc.validateInstance(""))
56 r = repr(sc)
57 self.assertIn("StorageClass", r)
58 self.assertIn(className, r)
59 self.assertNotIn("parameters", r)
60 self.assertIn("pytype='dict'", r)
62 # Ensure we do not have a delegate
63 with self.assertRaises(TypeError):
64 sc.delegate()
66 # Allow no definition of python type
67 scn = StorageClass(className)
68 self.assertIs(scn.pytype, object)
70 # Include some components
71 scc = StorageClass(className, pytype=PythonType, components={"comp1": sc, "comp2": sc})
72 self.assertIn("comp1", scc.components)
73 r = repr(scc)
74 self.assertIn("comp1", r)
75 self.assertIn("lsst.daf.butler.core.storageClassDelegate.StorageClassDelegate", r)
77 # Ensure that we have a delegate
78 self.assertIsInstance(scc.delegate(), StorageClassDelegate)
80 # Check we can create a storageClass using the name of an importable
81 # type.
82 sc2 = StorageClass("TestImage2",
83 "lsst.daf.butler.core.storageClass.StorageClassFactory")
84 self.assertIsInstance(sc2.pytype(), StorageClassFactory)
85 self.assertIn("butler.core", repr(sc2))
87 def testParameters(self):
88 """Test that we can set parameters and validate them"""
89 pt = ("a", "b")
90 ps = {"a", "b"}
91 pl = ["a", "b"]
92 for p in (pt, ps, pl):
93 sc1 = StorageClass("ParamClass", pytype=dict, parameters=p)
94 self.assertEqual(sc1.parameters, ps)
95 sc1.validateParameters(p)
97 sc1.validateParameters()
98 sc1.validateParameters({"a": None, "b": None})
99 sc1.validateParameters(["a", ])
100 with self.assertRaises(KeyError):
101 sc1.validateParameters({"a", "c"})
103 def testEquality(self):
104 """Test that StorageClass equality works"""
105 className = "TestImage"
106 sc1 = StorageClass(className, pytype=dict)
107 sc2 = StorageClass(className, pytype=dict)
108 self.assertEqual(sc1, sc2)
109 sc3 = StorageClass(className + "2", pytype=str)
110 self.assertNotEqual(sc1, sc3)
112 # Same StorageClass name but different python type
113 sc4 = StorageClass(className, pytype=str)
114 self.assertNotEqual(sc1, sc4)
116 # Parameters
117 scp = StorageClass("Params", pytype=PythonType, parameters=["a", "b", "c"])
118 scp1 = StorageClass("Params", pytype=PythonType, parameters=["a", "b", "c"])
119 scp2 = StorageClass("Params", pytype=PythonType, parameters=["a", "b", "d", "e"])
120 self.assertEqual(scp, scp1)
121 self.assertNotEqual(scp, scp2)
123 # Now with components
124 sc5 = StorageClass("Composite", pytype=PythonType,
125 components={"comp1": sc1, "comp2": sc3})
126 sc6 = StorageClass("Composite", pytype=PythonType,
127 components={"comp1": sc1, "comp2": sc3})
128 self.assertEqual(sc5, sc6)
129 self.assertNotEqual(sc5, sc3)
130 sc7 = StorageClass("Composite", pytype=PythonType,
131 components={"comp1": sc4, "comp2": sc3})
132 self.assertNotEqual(sc5, sc7)
133 sc8 = StorageClass("Composite", pytype=PythonType,
134 components={"comp2": sc3, "comp3": sc3})
135 self.assertNotEqual(sc5, sc8)
136 sc9 = StorageClass("Composite", pytype=PythonType,
137 components={"comp1": sc1, "comp2": sc3},
138 delegate="lsst.daf.butler.Butler")
139 self.assertNotEqual(sc5, sc9)
141 def testRegistry(self):
142 """Check that storage classes can be created on the fly and stored
143 in a registry."""
144 className = "TestImage"
145 factory = StorageClassFactory()
146 newclass = StorageClass(className, pytype=PythonType)
147 factory.registerStorageClass(newclass)
148 sc = factory.getStorageClass(className)
149 self.assertIsInstance(sc, StorageClass)
150 self.assertEqual(sc.name, className)
151 self.assertFalse(sc.components)
152 self.assertEqual(sc.pytype, PythonType)
153 self.assertIn(sc, factory)
154 newclass2 = StorageClass("Temporary2", pytype=str)
155 self.assertNotIn(newclass2, factory)
156 factory.registerStorageClass(newclass2)
157 self.assertIn(newclass2, factory)
158 self.assertIn("Temporary2", factory)
159 self.assertNotIn("Temporary3", factory)
160 self.assertNotIn({}, factory)
162 # Make sure we can't register a storage class with the same name
163 # but different values
164 newclass3 = StorageClass("Temporary2", pytype=dict)
165 with self.assertRaises(ValueError):
166 factory.registerStorageClass(newclass3)
168 factory._unregisterStorageClass(newclass3.name)
169 self.assertNotIn(newclass3, factory)
170 self.assertNotIn(newclass3.name, factory)
171 factory.registerStorageClass(newclass3)
172 self.assertIn(newclass3, factory)
173 self.assertIn(newclass3.name, factory)
175 # Check you can silently insert something that is already there
176 factory.registerStorageClass(newclass3)
178 def testFactoryConfig(self):
179 factory = StorageClassFactory()
180 factory.addFromConfig(StorageClassConfig())
181 image = factory.getStorageClass("Image")
182 imageF = factory.getStorageClass("ImageF")
183 self.assertIsInstance(imageF, type(image))
184 self.assertNotEqual(imageF, image)
186 # Check component inheritance
187 exposure = factory.getStorageClass("Exposure")
188 exposureF = factory.getStorageClass("ExposureF")
189 self.assertIsInstance(exposureF, type(exposure))
190 self.assertIsInstance(exposure.components["image"], type(image))
191 self.assertNotIsInstance(exposure.components["image"], type(imageF))
192 self.assertIsInstance(exposureF.components["image"], type(image))
193 self.assertIsInstance(exposureF.components["image"], type(imageF))
194 self.assertIn("wcs", exposure.components)
195 self.assertIn("wcs", exposureF.components)
197 # Check parameters
198 factory.addFromConfig(os.path.join(TESTDIR, "config", "basic", "storageClasses.yaml"))
199 thing1 = factory.getStorageClass("ThingOne")
200 thing2 = factory.getStorageClass("ThingTwo")
201 self.assertIsInstance(thing2, type(thing1))
202 param1 = thing1.parameters
203 param2 = thing2.parameters
204 self.assertIn("param3", thing2.parameters)
205 self.assertNotIn("param3", thing1.parameters)
206 param2.remove("param3")
207 self.assertEqual(param1, param2)
209 # Check that we can't have a new StorageClass that does not
210 # inherit from StorageClass
211 with self.assertRaises(ValueError):
212 factory.makeNewStorageClass("ClassName", baseClass=StorageClassFactory)
214 sc = factory.makeNewStorageClass("ClassName")
215 self.assertIsInstance(sc(), StorageClass)
217 def testPickle(self):
218 """Test that we can pickle storageclasses.
219 """
220 className = "TestImage"
221 sc = StorageClass(className, pytype=dict)
222 self.assertIsInstance(sc, StorageClass)
223 self.assertEqual(sc.name, className)
224 self.assertFalse(sc.components)
225 sc2 = pickle.loads(pickle.dumps(sc))
226 self.assertEqual(sc2, sc)
229if __name__ == "__main__": 229 ↛ 230line 229 didn't jump to line 230, because the condition on line 229 was never true
230 unittest.main()