11import asyncpg
2+ import contextlib
3+ import os
4+ import unittest
25
36from asyncpg import _testbase as tb
47
@@ -9,3 +12,211 @@ async def test_connect_1(self):
912 with self .assertRaisesRegex (
1013 Exception , 'role "__does_not_exist__" does not exist' ):
1114 await asyncpg .connect (user = "__does_not_exist__" , loop = self .loop )
15+
16+
17+ class TestConnectParams (unittest .TestCase ):
18+
19+ TESTS = [
20+ {
21+ 'env' : {
22+ 'PGUSER' : 'user' ,
23+ 'PGDATABASE' : 'testdb' ,
24+ 'PGPASSWORD' : 'passw' ,
25+ 'PGHOST' : 'host' ,
26+ 'PGPORT' : '123'
27+ },
28+ 'result' : (['host' ], 123 , 'user' , 'passw' , 'testdb' , {})
29+ },
30+
31+ {
32+ 'env' : {
33+ 'PGUSER' : 'user' ,
34+ 'PGDATABASE' : 'testdb' ,
35+ 'PGPASSWORD' : 'passw' ,
36+ 'PGHOST' : 'host' ,
37+ 'PGPORT' : '123'
38+ },
39+
40+ 'host' : 'host2' ,
41+ 'port' : '456' ,
42+ 'user' : 'user2' ,
43+ 'password' : 'passw2' ,
44+ 'database' : 'db2' ,
45+
46+ 'result' : (['host2' ], 456 , 'user2' , 'passw2' , 'db2' , {})
47+ },
48+
49+ {
50+ 'env' : {
51+ 'PGUSER' : 'user' ,
52+ 'PGDATABASE' : 'testdb' ,
53+ 'PGPASSWORD' : 'passw' ,
54+ 'PGHOST' : 'host' ,
55+ 'PGPORT' : '123'
56+ },
57+
58+ 'dsn' : 'postgres://user3:123123@localhost/abcdef' ,
59+
60+ 'host' : 'host2' ,
61+ 'port' : '456' ,
62+ 'user' : 'user2' ,
63+ 'password' : 'passw2' ,
64+ 'database' : 'db2' ,
65+
66+ 'result' : (['host2' ], 456 , 'user2' , 'passw2' , 'db2' , {})
67+ },
68+
69+ {
70+ 'env' : {
71+ 'PGUSER' : 'user' ,
72+ 'PGDATABASE' : 'testdb' ,
73+ 'PGPASSWORD' : 'passw' ,
74+ 'PGHOST' : 'host' ,
75+ 'PGPORT' : '123'
76+ },
77+
78+ 'dsn' : 'postgres://user3:123123@localhost:5555/abcdef' ,
79+
80+ 'result' : (['localhost' ], 5555 , 'user3' , '123123' , 'abcdef' , {})
81+ },
82+
83+ {
84+ 'dsn' : 'postgres://user3:123123@localhost:5555/abcdef' ,
85+ 'result' : (['localhost' ], 5555 , 'user3' , '123123' , 'abcdef' , {})
86+ },
87+
88+ {
89+ 'dsn' : 'postgresql://user3:123123@localhost:5555/'
90+ 'abcdef?param=sss¶m=123&host=testhost&user=testuser'
91+ '&port=2222&database=testdb' ,
92+ 'host' : '127.0.0.1' ,
93+ 'port' : '888' ,
94+ 'user' : 'me' ,
95+ 'password' : 'ask' ,
96+ 'database' : 'db' ,
97+ 'result' : (['127.0.0.1' ], 888 , 'me' , 'ask' , 'db' , {'param' : '123' })
98+ },
99+
100+ {
101+ 'dsn' : 'postgresql:///dbname?host=/unix_sock/test&user=spam' ,
102+ 'result' : (['/unix_sock/test' ], 5432 , 'spam' , None , 'dbname' , {})
103+ },
104+
105+ {
106+ 'dsn' : 'pq:///dbname?host=/unix_sock/test&user=spam' ,
107+ 'error' : (ValueError , 'invalid DSN' )
108+ },
109+ ]
110+
111+ @contextlib .contextmanager
112+ def environ (self , ** kwargs ):
113+ old_vals = {}
114+ for key in kwargs :
115+ if key in os .environ :
116+ old_vals [key ] = os .environ [key ]
117+
118+ for key , val in kwargs .items ():
119+ if val is None :
120+ if key in os .environ :
121+ del os .environ [key ]
122+ else :
123+ os .environ [key ] = val
124+
125+ try :
126+ yield
127+ finally :
128+ for key in kwargs :
129+ if key in os .environ :
130+ del os .environ [key ]
131+ for key , val in old_vals .items ():
132+ os .environ [key ] = val
133+
134+ def run_testcase (self , testcase ):
135+ env = testcase .get ('env' , {})
136+ test_env = {'PGHOST' : None , 'PGPORT' : None ,
137+ 'PGUSER' : None , 'PGPASSWORD' : None ,
138+ 'PGDATABASE' : None }
139+ test_env .update (env )
140+
141+ dsn = testcase .get ('dsn' )
142+ kwargs = testcase .get ('kwargs' , {})
143+ user = testcase .get ('user' )
144+ port = testcase .get ('port' )
145+ host = testcase .get ('host' )
146+ password = testcase .get ('password' )
147+ database = testcase .get ('database' )
148+
149+ expected = testcase .get ('result' )
150+ expected_error = testcase .get ('error' )
151+ if expected is None and expected_error is None :
152+ raise RuntimeError (
153+ 'invalid test case: either "result" or "error" key '
154+ 'has to be specified' )
155+ if expected is not None and expected_error is not None :
156+ raise RuntimeError (
157+ 'invalid test case: either "result" or "error" key '
158+ 'has to be specified, got both' )
159+
160+ with contextlib .ExitStack () as es :
161+ es .enter_context (self .subTest (dsn = dsn , kwargs = kwargs , env = env ))
162+ es .enter_context (self .environ (** test_env ))
163+
164+ if expected_error :
165+ es .enter_context (self .assertRaisesRegex (* expected_error ))
166+
167+ result = asyncpg ._parse_connect_params (
168+ dsn = dsn , host = host , port = port , user = user , password = password ,
169+ database = database , kwargs = kwargs )
170+
171+ if expected is not None :
172+ self .assertEqual (expected , result )
173+
174+ def test_test_connect_params_environ (self ):
175+ self .assertNotIn ('AAAAAAAAAA123' , os .environ )
176+ self .assertNotIn ('AAAAAAAAAA456' , os .environ )
177+ self .assertNotIn ('AAAAAAAAAA789' , os .environ )
178+
179+ try :
180+
181+ os .environ ['AAAAAAAAAA456' ] = '123'
182+ os .environ ['AAAAAAAAAA789' ] = '123'
183+
184+ with self .environ (AAAAAAAAAA123 = '1' ,
185+ AAAAAAAAAA456 = '2' ,
186+ AAAAAAAAAA789 = None ):
187+
188+ self .assertEqual (os .environ ['AAAAAAAAAA123' ], '1' )
189+ self .assertEqual (os .environ ['AAAAAAAAAA456' ], '2' )
190+ self .assertNotIn ('AAAAAAAAAA789' , os .environ )
191+
192+ self .assertNotIn ('AAAAAAAAAA123' , os .environ )
193+ self .assertEqual (os .environ ['AAAAAAAAAA456' ], '123' )
194+ self .assertEqual (os .environ ['AAAAAAAAAA789' ], '123' )
195+
196+ finally :
197+ for key in {'AAAAAAAAAA123' , 'AAAAAAAAAA456' , 'AAAAAAAAAA789' }:
198+ if key in os .environ :
199+ del os .environ [key ]
200+
201+ def test_test_connect_params_run_testcase (self ):
202+ with self .environ (PGPORT = '777' ):
203+ self .run_testcase ({
204+ 'env' : {
205+ 'PGUSER' : '__test__'
206+ },
207+ 'host' : 'abc' ,
208+ 'result' : (['abc' ], 5432 , '__test__' , None , None , {})
209+ })
210+
211+ with self .assertRaises (AssertionError ):
212+ self .run_testcase ({
213+ 'env' : {
214+ 'PGUSER' : '__test__'
215+ },
216+ 'host' : 'abc' ,
217+ 'result' : (['abc' ], 5432 , 'wrong_user' , None , None , {})
218+ })
219+
220+ def test_connect_params (self ):
221+ for testcase in self .TESTS :
222+ self .run_testcase (testcase )
0 commit comments