Coverage for tests/test_packages.py: 17%
Shortcuts 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
Shortcuts 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#!/usr/bin/env python
2#
3# LSST Data Management System
4# Copyright 2016 AURA/LSST.
5#
6# This product includes software developed by the
7# LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20# the GNU General Public License along with this program. If not,
21# see <https://www.lsstcorp.org/LegalNotices/>.
22#
23import os
24import unittest
25import tempfile
27from collections.abc import Mapping
29import lsst.base
31TESTDIR = os.path.abspath(os.path.dirname(__file__))
34class PackagesTestCase(unittest.TestCase):
35 """Tests for package version collection
37 Unfortunately, we're somewhat limited in what we can test because
38 we only get the versions of things being used at runtime, and this
39 package sits rather low in the dependency chain so there's not
40 usually a lot of other packages available when this test gets run.
41 Therefore some of the tests are only checking that things don't
42 explode, since they are incapable of testing much more than that.
43 """
45 def testPython(self):
46 """Test that we get the right version for this python package"""
47 versions = lsst.base.getPythonPackages()
48 expected = (lsst.base.version.__version__)
49 self.assertEqual(versions["base"], expected)
51 def testEnvironment(self):
52 """Test getting versions from the environment
54 Unfortunately, none of the products that need their versions divined
55 from the environment are dependencies of this package, and so all we
56 can do is test that this doesn't fall over.
57 """
58 lsst.base.getEnvironmentPackages()
60 def testRuntime(self):
61 """Test getting versions from runtime libraries
63 Unfortunately, none of the products that we get runtime versions from
64 are dependencies of this package, and so all we can do is test that
65 this doesn't fall over.
66 """
67 lsst.base.getRuntimeVersions()
69 def testConda(self):
70 """Test getting versions from conda environement
72 We do not rely on being run in a conda environment so all we can do is
73 test that this doesn't fall over.
74 """
75 lsst.base.getCondaPackages()
77 def _writeTempFile(self, packages, suffix):
78 """Write packages to a temp file using the supplied suffix and read
79 back.
80 """
81 # Can't use lsst.utils.tests.getTempFilePath because we're its
82 # dependency
83 temp = tempfile.NamedTemporaryFile(prefix="packages.", suffix=suffix, delete=False)
84 tempName = temp.name
85 temp.close() # We don't use the fd, just want a filename
86 try:
87 packages.write(tempName)
88 new = lsst.base.Packages.read(tempName)
89 finally:
90 os.unlink(tempName)
91 return new
93 def testPackages(self):
94 """Test the Packages class"""
95 packages = lsst.base.Packages.fromSystem()
96 self.assertIsInstance(packages, Mapping)
98 # Check that stringification is not crashing.
99 self.assertTrue(str(packages).startswith("Packages({"))
100 self.assertTrue(repr(packages).startswith("Packages({"))
102 # Test pickling and YAML
103 new = self._writeTempFile(packages, ".pickle")
104 new_pkl = self._writeTempFile(packages, ".pkl")
105 new_yaml = self._writeTempFile(packages, ".yaml")
107 self.assertIsInstance(new, lsst.base.Packages,
108 f"Checking type ({type(new)}) from pickle")
109 self.assertIsInstance(new_yaml, lsst.base.Packages,
110 f"Checking type ({type(new_yaml)}) from YAML")
111 self.assertEqual(new, packages)
112 self.assertEqual(new_pkl, new)
113 self.assertEqual(new, new_yaml)
115 # Dict compatibility.
116 for k, v in new.items():
117 self.assertEqual(new[k], v)
119 with self.assertRaises(ValueError):
120 self._writeTempFile(packages, ".txt")
122 with self.assertRaises(ValueError):
123 # .txt extension is not recognized
124 lsst.base.Packages.read("something.txt")
126 # 'packages' and 'new' should have identical content
127 self.assertDictEqual(packages.difference(new), {})
128 self.assertDictEqual(packages.missing(new), {})
129 self.assertDictEqual(packages.extra(new), {})
130 self.assertEqual(len(packages), len(new))
132 # Check inverted comparisons
133 self.assertDictEqual(new.difference(packages), {})
134 self.assertDictEqual(new.missing(packages), {})
135 self.assertDictEqual(new.extra(packages), {})
137 # Now load an obscure python package and the list of packages should
138 # change
139 # Shouldn't be used by anything we've previously imported
140 import smtpd # noqa: F401
141 new = lsst.base.Packages.fromSystem()
142 self.assertDictEqual(packages.difference(new), {}) # No inconsistencies
143 self.assertDictEqual(packages.extra(new), {}) # Nothing in 'packages' that's not in 'new'
144 missing = packages.missing(new)
145 self.assertGreater(len(missing), 0) # 'packages' should be missing some stuff in 'new'
146 self.assertIn("smtpd", missing)
148 # Inverted comparisons
149 self.assertDictEqual(new.difference(packages), {})
150 self.assertDictEqual(new.missing(packages), {}) # Nothing in 'new' that's not in 'packages'
151 extra = new.extra(packages)
152 self.assertGreater(len(extra), 0) # 'new' has extra stuff compared to 'packages'
153 self.assertIn("smtpd", extra)
154 self.assertIn("smtpd", new)
156 # Run with both a Packages and a dict
157 for new_pkg in (new, dict(new)):
158 packages.update(new_pkg) # Should now be identical
159 self.assertDictEqual(packages.difference(new_pkg), {})
160 self.assertDictEqual(packages.missing(new_pkg), {})
161 self.assertDictEqual(packages.extra(new_pkg), {})
162 self.assertEqual(len(packages), len(new_pkg))
164 # Loop over keys to check iterator.
165 keys = {k for k in new}
166 self.assertEqual(keys, set(dict(new).keys()))
168 # Loop over values to check that we do get them all.
169 values = {v for v in new.values()}
170 self.assertEqual(values, set(dict(new).values()))
172 # Serialize via bytes
173 for format in ("pickle", "yaml"):
174 asbytes = new.toBytes(format)
175 from_bytes = lsst.base.Packages.fromBytes(asbytes, format)
176 self.assertEqual(from_bytes, new)
178 with self.assertRaises(ValueError):
179 new.toBytes("unknown_format")
181 with self.assertRaises(ValueError):
182 lsst.base.Packages.fromBytes(from_bytes, "unknown_format")
184 with self.assertRaises(TypeError):
185 some_yaml = b"list: [1, 2]"
186 lsst.base.Packages.fromBytes(some_yaml, "yaml")
188 def testBackwardsCompatibility(self):
189 """Test if we can read old data files."""
191 # Pickle contents changed when moving to dict base class.
192 packages_p = lsst.base.Packages.read(os.path.join(TESTDIR, "data", "v1.pickle"))
194 # YAML format is unchanged when moving from special class to dict
195 # but test anyway.
196 packages_y = lsst.base.Packages.read(os.path.join(TESTDIR, "data", "v1.yaml"))
198 self.assertEqual(packages_p, packages_y)
201if __name__ == "__main__": 201 ↛ 202line 201 didn't jump to line 202, because the condition on line 201 was never true
202 unittest.main()