Coverage for tests/test_dbAuth.py: 8%

136 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-09 02:51 -0800

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/>. 

21 

22import os 

23import unittest 

24 

25from lsst.daf.butler.registry import DbAuth, DbAuthError 

26 

27TESTDIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "config", "dbAuth") 

28 

29 

30class DbAuthTestCase(unittest.TestCase): 

31 """Test DbAuth class.""" 

32 

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") 

47 

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") 

67 

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 ) 

94 

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 ) 

117 

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 ) 

159 

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") 

182 

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") 

201 

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") 

205 

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") 

209 

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") 

213 

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 ) 

229 

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 ), 

249 

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 ) 

281 

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 ) 

306 

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 ) 

350 

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") 

365 

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 ) 

381 

382 

383if __name__ == "__main__": 383 ↛ 384line 383 didn't jump to line 384, because the condition on line 383 was never true

384 unittest.main()