Coverage for tests/test_dbAuth.py: 8%
136 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-26 02:02 -0700
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-26 02:02 -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 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 unittest
25from lsst.daf.butler.registry import DbAuth, DbAuthError
27TESTDIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "config", "dbAuth")
30class DbAuthTestCase(unittest.TestCase):
31 """Test DbAuth class."""
33 def test_patterns(self):
34 """Test various patterns against a fixed connection URL."""
35 for matchPattern in [
36 "postgresql://*",
37 "postgresql://*.example.com",
38 "postgresql://*.example.com/my_*",
39 "postgresql://host.example.com/my_database",
40 "postgresql://host.example.com:5432/my_database",
41 "postgresql://user@host.example.com/my_database",
42 ]:
43 auth = DbAuth(authList=[dict(url=matchPattern, username="foo", password="bar")])
44 user, pwd = auth.getAuth("postgresql", "user", "host.example.com", "5432", "my_database")
45 self.assertEqual(user, "user")
46 self.assertEqual(pwd, "bar")
48 def test_connStrings(self):
49 """Test various connection URLs against a fixed pattern."""
50 auth = DbAuth(
51 authList=[dict(url="postgresql://host.example.com/my_database", username="foo", password="bar")]
52 )
53 for connComponents in [
54 ("postgresql", "user", "host.example.com", 5432, "my_database"),
55 ("postgresql", "user", "host.example.com", None, "my_database"),
56 ]:
57 user, pwd = auth.getAuth(*connComponents)
58 self.assertEqual(user, "user")
59 self.assertEqual(pwd, "bar")
60 for connComponents in [
61 ("postgresql", None, "host.example.com", None, "my_database"),
62 ("postgresql", None, "host.example.com", "5432", "my_database"),
63 ]:
64 user, pwd = auth.getAuth(*connComponents)
65 self.assertEqual(user, "foo")
66 self.assertEqual(pwd, "bar")
68 def test_load(self):
69 """Test loading from a YAML file and matching in order."""
70 filePath = os.path.join(TESTDIR, "db-auth.yaml")
71 os.chmod(filePath, 0o600)
72 auth = DbAuth(filePath)
73 self.assertEqual(
74 auth.getAuth("postgresql", "user", "host.example.com", "5432", "my_database"), ("user", "test1")
75 )
76 self.assertEqual(
77 auth.getAuth("postgresql", "user", "host.example.com", "3360", "my_database"), ("user", "test2")
78 )
79 self.assertEqual(
80 auth.getAuth("postgresql", "", "host.example.com", "5432", "my_database"), ("user", "test3")
81 )
82 self.assertEqual(
83 auth.getAuth("postgresql", None, "host.example.com", "", "my_database"), ("user", "test4")
84 )
85 self.assertEqual(
86 auth.getAuth("postgresql", "", "host2.example.com", None, "my_other"), ("user", "test5")
87 )
88 self.assertEqual(
89 auth.getAuth("postgresql", None, "host3.example.com", 3360, "some_database"), ("user", "test6")
90 )
91 self.assertEqual(
92 auth.getAuth("postgresql", "user", "host4.other.com", None, "other_database"), ("user", "test8")
93 )
95 def test_ipv6(self):
96 """Test IPv6 addresses as host names."""
97 auth = DbAuth(
98 authList=[
99 dict(url="postgresql://user@[fe80::1ff:fe23:4567:890a]:5432/db", password="pwd"),
100 dict(url="postgresql://[fe80::1ff:fe23:4567:890a]:5432/db", password="pwd2"),
101 dict(url="postgresql://user3@[fe80::1ff:fe23:4567:890a]/db", password="pwd3"),
102 dict(url="postgresql://[fe80::1ff:fe23:4567:890a]/db", password="pwd4"),
103 ]
104 )
105 self.assertEqual(
106 auth.getAuth("postgresql", "user", "fe80::1ff:fe23:4567:890a", "5432", "db"), ("user", "pwd")
107 )
108 self.assertEqual(
109 auth.getAuth("postgresql", "user2", "fe80::1ff:fe23:4567:890a", "5432", "db"), ("user2", "pwd2")
110 )
111 self.assertEqual(
112 auth.getAuth("postgresql", "user3", "fe80::1ff:fe23:4567:890a", "3360", "db"), ("user3", "pwd3")
113 )
114 self.assertEqual(
115 auth.getAuth("postgresql", "user4", "fe80::1ff:fe23:4567:890a", "3360", "db"), ("user4", "pwd4")
116 )
118 def test_search(self):
119 """Test ordered searching."""
120 auth = DbAuth(
121 authList=[
122 dict(url="postgresql://user1@host2.example.com:3360/database3", password="first"),
123 dict(
124 url="postgresql://host2.example.com:3360/database3",
125 username="second_u",
126 password="second",
127 ),
128 dict(url="postgresql://host2.example.com:5432/database3", username="wrong", password="port"),
129 dict(url="postgresql://host3.example.com/", username="third_u", password="third"),
130 dict(url="oracle://oracle.example.com/other_database", username="scott", password="tiger"),
131 dict(url="postgresql://*.example.com/database3", username="fourth_u", password="fourth"),
132 dict(url="postgresql://*.example.com", username="fifth_u", password="fifth"),
133 ]
134 )
135 self.assertEqual(
136 auth.getAuth("postgresql", "user1", "host2.example.com", "3360", "database3"), ("user1", "first")
137 )
138 self.assertEqual(
139 auth.getAuth("postgresql", "user2", "host2.example.com", "3360", "database3"), ("user2", "second")
140 )
141 self.assertEqual(
142 auth.getAuth("postgresql", "", "host2.example.com", "3360", "database3"), ("second_u", "second")
143 )
144 self.assertEqual(
145 auth.getAuth("postgresql", None, "host2.example.com", "3360", "database3"), ("second_u", "second")
146 )
147 self.assertEqual(
148 auth.getAuth("postgresql", None, "host3.example.com", "3360", "database3"), ("third_u", "third")
149 )
150 self.assertEqual(
151 auth.getAuth("postgresql", None, "host3.example.com", "3360", "database4"), ("third_u", "third")
152 )
153 self.assertEqual(
154 auth.getAuth("postgresql", None, "host4.example.com", "3360", "database3"), ("fourth_u", "fourth")
155 )
156 self.assertEqual(
157 auth.getAuth("postgresql", None, "host4.example.com", "3360", "database4"), ("fifth_u", "fifth")
158 )
160 def test_errors(self):
161 """Test for error exceptions."""
162 with self.assertRaisesRegex(DbAuthError, r"^No default path provided to DbAuth configuration file$"):
163 auth = DbAuth()
164 with self.assertRaisesRegex(DbAuthError, r"^No DbAuth configuration file: .*this_does_not_exist$"):
165 auth = DbAuth(os.path.join(TESTDIR, "this_does_not_exist"))
166 with self.assertRaisesRegex(DbAuthError, r"^No DbAuth configuration file: .*this_does_not_exist$"):
167 auth = DbAuth(os.path.join(TESTDIR, "this_does_not_exist"), envVar="LSST_NONEXISTENT")
168 with self.assertRaisesRegex(
169 DbAuthError,
170 r"^DbAuth configuration file .*badDbAuth1.yaml has incorrect " r"permissions: \d*644$",
171 ):
172 filePath = os.path.join(TESTDIR, "badDbAuth1.yaml")
173 os.chmod(filePath, 0o644)
174 auth = DbAuth(filePath)
175 with self.assertRaisesRegex(
176 DbAuthError, r"^Unable to load DbAuth configuration file: " r".*badDbAuth2.yaml"
177 ):
178 filePath = os.path.join(TESTDIR, "badDbAuth2.yaml")
179 os.chmod(filePath, 0o600)
180 os.environ["LSST_DB_AUTH_TEST"] = filePath
181 auth = DbAuth(envVar="LSST_DB_AUTH_TEST")
183 auth = DbAuth(authList=[])
184 with self.assertRaisesRegex(DbAuthError, r"^Missing dialectname parameter$"):
185 auth.getAuth(None, None, None, None, None)
186 with self.assertRaisesRegex(DbAuthError, r"^Missing dialectname parameter$"):
187 auth.getAuth("", None, None, None, None)
188 with self.assertRaisesRegex(DbAuthError, r"^Missing host parameter$"):
189 auth.getAuth("postgresql", None, None, None, None)
190 with self.assertRaisesRegex(DbAuthError, r"^Missing host parameter$"):
191 auth.getAuth("postgresql", None, "", None, None)
192 with self.assertRaisesRegex(DbAuthError, r"^Missing database parameter$"):
193 auth.getAuth("postgresql", None, "example.com", None, None)
194 with self.assertRaisesRegex(DbAuthError, r"^Missing database parameter$"):
195 auth.getAuth("postgresql", None, "example.com", None, "")
196 with self.assertRaisesRegex(
197 DbAuthError,
198 r"^No matching DbAuth configuration for: " r"\(postgresql, None, example\.com, None, foo\)$",
199 ):
200 auth.getAuth("postgresql", None, "example.com", None, "foo")
202 auth = DbAuth(authList=[dict(password="testing")])
203 with self.assertRaisesRegex(DbAuthError, r"^Missing URL in DbAuth configuration$"):
204 auth.getAuth("postgresql", None, "example.com", None, "foo")
206 auth = DbAuth(authList=[dict(url="testing", password="testing")])
207 with self.assertRaisesRegex(DbAuthError, r"^Missing database dialect in URL: testing$"):
208 auth.getAuth("postgresql", None, "example.com", None, "foo")
210 auth = DbAuth(authList=[dict(url="postgresql:///foo", password="testing")])
211 with self.assertRaisesRegex(DbAuthError, r"^Missing host in URL: postgresql:///foo$"):
212 auth.getAuth("postgresql", None, "example.com", None, "foo")
214 def test_getUrl(self):
215 """Repeat relevant tests using getUrl interface."""
216 for matchPattern in [
217 "postgresql://*",
218 "postgresql://*.example.com",
219 "postgresql://*.example.com/my_*",
220 "postgresql://host.example.com/my_database",
221 "postgresql://host.example.com:5432/my_database",
222 "postgresql://user@host.example.com/my_database",
223 ]:
224 auth = DbAuth(authList=[dict(url=matchPattern, username="foo", password="bar")])
225 self.assertEqual(
226 auth.getUrl("postgresql://user@host.example.com:5432/my_database"),
227 "postgresql://user:bar@host.example.com:5432/my_database",
228 )
230 auth = DbAuth(
231 authList=[dict(url="postgresql://host.example.com/my_database", username="foo", password="bar")]
232 )
233 self.assertEqual(
234 auth.getUrl("postgresql://user@host.example.com:5432/my_database"),
235 "postgresql://user:bar@host.example.com:5432/my_database",
236 ),
237 self.assertEqual(
238 auth.getUrl("postgresql://user@host.example.com/my_database"),
239 "postgresql://user:bar@host.example.com/my_database",
240 ),
241 self.assertEqual(
242 auth.getUrl("postgresql://host.example.com/my_database"),
243 "postgresql://foo:bar@host.example.com/my_database",
244 ),
245 self.assertEqual(
246 auth.getUrl("postgresql://host.example.com:5432/my_database"),
247 "postgresql://foo:bar@host.example.com:5432/my_database",
248 ),
250 filePath = os.path.join(TESTDIR, "db-auth.yaml")
251 os.chmod(filePath, 0o600)
252 auth = DbAuth(filePath)
253 self.assertEqual(
254 auth.getUrl("postgresql://user@host.example.com:5432/my_database"),
255 "postgresql://user:test1@host.example.com:5432/my_database",
256 )
257 self.assertEqual(
258 auth.getUrl("postgresql://user@host.example.com:3360/my_database"),
259 "postgresql://user:test2@host.example.com:3360/my_database",
260 )
261 self.assertEqual(
262 auth.getUrl("postgresql://host.example.com:5432/my_database"),
263 "postgresql://user:test3@host.example.com:5432/my_database",
264 )
265 self.assertEqual(
266 auth.getUrl("postgresql://host.example.com/my_database"),
267 "postgresql://user:test4@host.example.com/my_database",
268 )
269 self.assertEqual(
270 auth.getUrl("postgresql://host2.example.com/my_other"),
271 "postgresql://user:test5@host2.example.com/my_other",
272 )
273 self.assertEqual(
274 auth.getUrl("postgresql://host3.example.com:3360/some_database"),
275 "postgresql://user:test6@host3.example.com:3360/some_database",
276 )
277 self.assertEqual(
278 auth.getUrl("postgresql://user@host4.other.com/other_database"),
279 "postgresql://user:test8@host4.other.com/other_database",
280 )
282 auth = DbAuth(
283 authList=[
284 dict(url="postgresql://user@[fe80::1ff:fe23:4567:890a]:5432/db", password="pwd"),
285 dict(url="postgresql://[fe80::1ff:fe23:4567:890a]:5432/db", password="pwd2"),
286 dict(url="postgresql://user3@[fe80::1ff:fe23:4567:890a]/db", password="pwd3"),
287 dict(url="postgresql://[fe80::1ff:fe23:4567:890a]/db", password="pwd4"),
288 ]
289 )
290 self.assertEqual(
291 auth.getUrl("postgresql://user@[fe80::1ff:fe23:4567:890a]:5432/db"),
292 "postgresql://user:pwd@[fe80::1ff:fe23:4567:890a]:5432/db",
293 )
294 self.assertEqual(
295 auth.getUrl("postgresql://user2@[fe80::1ff:fe23:4567:890a]:5432/db"),
296 "postgresql://user2:pwd2@[fe80::1ff:fe23:4567:890a]:5432/db",
297 )
298 self.assertEqual(
299 auth.getUrl("postgresql://user3@[fe80::1ff:fe23:4567:890a]:3360/db"),
300 "postgresql://user3:pwd3@[fe80::1ff:fe23:4567:890a]:3360/db",
301 )
302 self.assertEqual(
303 auth.getUrl("postgresql://user4@[fe80::1ff:fe23:4567:890a]:3360/db"),
304 "postgresql://user4:pwd4@[fe80::1ff:fe23:4567:890a]:3360/db",
305 )
307 auth = DbAuth(
308 authList=[
309 dict(url="postgresql://user1@host2.example.com:3360/database3", password="first"),
310 dict(
311 url="postgresql://host2.example.com:3360/database3",
312 username="second_u",
313 password="second",
314 ),
315 dict(url="postgresql://host2.example.com:5432/database3", username="wrong", password="port"),
316 dict(url="postgresql://host3.example.com/", username="third_u", password="third"),
317 dict(url="oracle://oracle.example.com/other_database", username="scott", password="tiger"),
318 dict(url="postgresql://*.example.com/database3", username="fourth_u", password="fourth"),
319 dict(url="postgresql://*.example.com", username="fifth_u", password="fifth"),
320 ]
321 )
322 self.assertEqual(
323 auth.getUrl("postgresql://user1@host2.example.com:3360/database3"),
324 "postgresql://user1:first@host2.example.com:3360/database3",
325 )
326 self.assertEqual(
327 auth.getUrl("postgresql://user2@host2.example.com:3360/database3"),
328 "postgresql://user2:second@host2.example.com:3360/database3",
329 )
330 self.assertEqual(
331 auth.getUrl("postgresql://host2.example.com:3360/database3"),
332 "postgresql://second_u:second@host2.example.com:3360/database3",
333 )
334 self.assertEqual(
335 auth.getUrl("postgresql://host3.example.com:3360/database3"),
336 "postgresql://third_u:third@host3.example.com:3360/database3",
337 )
338 self.assertEqual(
339 auth.getUrl("postgresql://host3.example.com:3360/database4"),
340 "postgresql://third_u:third@host3.example.com:3360/database4",
341 )
342 self.assertEqual(
343 auth.getUrl("postgresql://host4.example.com:3360/database3"),
344 "postgresql://fourth_u:fourth@host4.example.com:3360/database3",
345 )
346 self.assertEqual(
347 auth.getUrl("postgresql://host4.example.com:3360/database4"),
348 "postgresql://fifth_u:fifth@host4.example.com:3360/database4",
349 )
351 auth = DbAuth(authList=[])
352 with self.assertRaisesRegex(DbAuthError, r"^Missing dialectname parameter$"):
353 auth.getUrl("/")
354 with self.assertRaisesRegex(DbAuthError, r"^Missing host parameter$"):
355 auth.getUrl("postgresql:///")
356 with self.assertRaisesRegex(DbAuthError, r"^Missing database parameter$"):
357 auth.getUrl("postgresql://example.com")
358 with self.assertRaisesRegex(DbAuthError, r"^Missing database parameter$"):
359 auth.getUrl("postgresql://example.com/")
360 with self.assertRaisesRegex(
361 DbAuthError,
362 r"^No matching DbAuth configuration for: " r"\(postgresql, None, example\.com, None, foo\)$",
363 ):
364 auth.getUrl("postgresql://example.com/foo")
366 def test_urlEncoding(self):
367 """Test URL encoding of username and password."""
368 auth = DbAuth(
369 authList=[
370 dict(
371 url="postgresql://host.example.com/my_database",
372 username="foo:étude",
373 password="bar,.@%&/*[]",
374 )
375 ]
376 )
377 self.assertEqual(
378 auth.getUrl("postgresql://host.example.com:5432/my_database"),
379 "postgresql://foo%3A%C3%A9tude:bar%2C.%40%25%26%2F%2A%5B%5D@host.example.com:5432/my_database",
380 )
383if __name__ == "__main__": 383 ↛ 384line 383 didn't jump to line 384, because the condition on line 383 was never true
384 unittest.main()