Skip to content

Commit aeeb3c6

Browse files
author
Sky NSS
committed
Added test http auth test case.
1 parent cb66c6c commit aeeb3c6

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

pandas/tests/io/test_http_auth.py

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import pytest
2+
import pandas as pd
3+
import pandas.util.testing as tm
4+
5+
if pd.io.common._REQUESTS_INSTALLED:
6+
from requests.packages.urllib3.exceptions import InsecureRequestWarning
7+
import requests
8+
requests_pkg = True
9+
else:
10+
requests_pkg = False
11+
12+
13+
def _skip_if_no_requests():
14+
if not requests_pkg:
15+
pytest.skip('python-requests not installed, skipping')
16+
17+
18+
uname = 'pandasusr'
19+
pwd = 'pandaspwd'
20+
no_auth_path = 'no_auth/'
21+
basic_auth_path = 'basic_auth/'
22+
valid_ssl_url = 'handsome-equator.000webhostapp.com'
23+
invalid_ssl_url = 'pandas-unittest.site11.com'
24+
25+
26+
def gen_http_auth_ssl_test_cases(uname,
27+
pwd,
28+
is_auth,
29+
sub_path):
30+
"""
31+
Generate list of test case to test for : http/https, username/pwd in url
32+
or as parameters, self signed ssl certs or trusted ssl certs, no auth
33+
or basic auth
34+
"""
35+
def gen_level1_tc():
36+
test_cases = []
37+
# The following host doesn't seem to handle urllib but handles
38+
# python requests package. This is because:
39+
# 'urlopen' sets header 'Host' : '<fqdn>:<port>' - acceptable RFC7230
40+
# 'requests' sets header 'Host' : '<fqdn>'
41+
# so pandas fails on following hosting server (uses some 'apex' server)
42+
# but pandas succeeds on nginx even if port is non-default.
43+
for host, verify_ssl in [(invalid_ssl_url, False),
44+
(valid_ssl_url, True)
45+
]:
46+
pre_ports = [('http', ''),
47+
('https', '')]
48+
for pre, port in pre_ports:
49+
test_cases.append(
50+
[host, verify_ssl, pre, port, sub_path, is_auth])
51+
return test_cases
52+
53+
def gen_base_url(pre, auth_prefix, host, port, su_pa):
54+
return '{}://{}{}{}/{}'.format(pre, auth_prefix, host, port, su_pa)
55+
tc2 = []
56+
for host, verify_ssl, pre, port, sp, is_auth in gen_level1_tc():
57+
u = uname if is_auth else None
58+
p = pwd if is_auth else None
59+
u_no_uname = gen_base_url(pre, '', host, port, sp)
60+
u_with_uname = None
61+
if is_auth:
62+
auth_prefix = '{}:{}@'.format(u, p) if is_auth else ''
63+
u_with_uname = gen_base_url(pre, auth_prefix, host, port, sp)
64+
tc2.append([u_no_uname, u, p, verify_ssl])
65+
if u_with_uname and u_with_uname != u_no_uname:
66+
tc2.append([u_with_uname, None, None, verify_ssl])
67+
else:
68+
tc2.append([u_no_uname, None, None, verify_ssl])
69+
return tc2
70+
71+
72+
valid_no_auth = gen_http_auth_ssl_test_cases(uname='',
73+
pwd='',
74+
is_auth=False,
75+
sub_path=no_auth_path)
76+
77+
valid_auth = gen_http_auth_ssl_test_cases(uname=uname,
78+
pwd=pwd,
79+
is_auth=True,
80+
sub_path=basic_auth_path)
81+
82+
83+
@pytest.mark.slow
84+
@pytest.mark.parametrize('url, uname, pwd, verify_ssl',
85+
valid_auth)
86+
def test_http_valid_auth(url, uname, pwd, verify_ssl):
87+
_skip_if_no_requests()
88+
check_http_auth(url, uname, pwd, verify_ssl)
89+
90+
91+
@pytest.mark.slow
92+
@pytest.mark.parametrize('url, uname, pwd, verify_ssl',
93+
valid_no_auth)
94+
def test_http_valid_no_auth(url, uname, pwd, verify_ssl):
95+
if verify_ssl is False:
96+
_skip_if_no_requests()
97+
if (verify_ssl in [True, False] or uname or pwd) and not requests_pkg:
98+
with pytest.raises(ValueError):
99+
check_http_auth(url, uname, pwd, verify_ssl)
100+
else:
101+
check_http_auth(url, uname, pwd, verify_ssl)
102+
103+
104+
wrong_auth = gen_http_auth_ssl_test_cases(uname='fakepwd',
105+
pwd='fakepwd',
106+
is_auth=True,
107+
sub_path=basic_auth_path)
108+
109+
110+
@pytest.mark.slow
111+
@pytest.mark.parametrize('url, uname, pwd, verify_ssl',
112+
wrong_auth)
113+
def test_http_invalid_auth(url, uname, pwd, verify_ssl):
114+
_skip_if_no_requests()
115+
with pytest.raises(requests.exceptions.HTTPError):
116+
check_http_auth(url, uname, pwd, verify_ssl)
117+
118+
119+
blank_uname = gen_http_auth_ssl_test_cases(uname='',
120+
pwd='fakepwd',
121+
is_auth=True,
122+
sub_path=basic_auth_path)
123+
124+
blank_pwd = gen_http_auth_ssl_test_cases(uname='fakepwd',
125+
pwd='',
126+
is_auth=True,
127+
sub_path=basic_auth_path)
128+
129+
130+
def match_csv(df):
131+
tcsv = 'animal,bird\ndog,pigeon\ncat,emu\n'
132+
return str(df.to_csv(index=False)) == tcsv
133+
134+
135+
def match_json(df):
136+
j = '{"animal":{"0":"dog","1":"cat"},"bird":{"0":"pigeon","1":"emu"}}'
137+
return str(df.to_json()) == j
138+
139+
140+
@tm.network
141+
def check_http_auth(url, uname, pwd, verify_ssl):
142+
143+
def get_df(url, uname, pwd, verify_ssl, pd_read_fn, fname):
144+
furl = url + fname
145+
http_params = {}
146+
if uname or pwd:
147+
http_params['auth'] = (uname, pwd)
148+
if verify_ssl is not None:
149+
http_params['verify'] = verify_ssl
150+
msg = '{0: <90} -- auth:[{1: <10}/{2: <10}] v:[{3: <5}]'.format(
151+
furl, str(uname), str(pwd), str(verify_ssl))
152+
if verify_ssl or furl.lower().startswith('http://'):
153+
df = pd_read_fn(furl, http_params=http_params)
154+
else:
155+
with tm.assert_produces_warning(InsecureRequestWarning):
156+
df = pd_read_fn(furl, http_params=http_params)
157+
if type(df) is list: # html
158+
df = df[0]
159+
smatch = match_csv(df)
160+
jmatch = match_json(df)
161+
res = 'Json : {} -- String: {}'.format(jmatch, smatch)
162+
if not jmatch or not smatch:
163+
raise Exception(' ** ERROR:' + res)
164+
else:
165+
res += ' OK'
166+
print(msg + ' ' + res)
167+
return True
168+
169+
for pd_read_fn, fname in [(pd.read_csv, 'aaa.csv'),
170+
(pd.read_json, 'jdoc.json'),
171+
(pd.read_excel, 'ex_doc.xlsx'),
172+
(pd.read_html, 'html_file.html')
173+
]:
174+
assert get_df(url, uname, pwd, verify_ssl, pd_read_fn, fname)
175+
return
176+
177+
178+
@pytest.mark.parametrize('up',
179+
[
180+
None,
181+
{},
182+
{'auth': ('uname', 'pwd')},
183+
{'verify': False},
184+
{'auth': ('uname', 'pwd'), 'verify': False},
185+
]
186+
)
187+
def test_http_params(up):
188+
_skip_if_no_requests()
189+
s = pd.io.common.gen_session(http_params=up)
190+
assert type(s) is requests.sessions.Session
191+
if up and up.get('auth', None):
192+
assert s.auth == up.get('auth', None)
193+
if up and (up.get('verify', True) is False):
194+
assert s.verify == up.get('verify', True)
195+
196+
197+
def test_pass_session_obj():
198+
_skip_if_no_requests()
199+
s = requests.sessions.Session()
200+
s.auth = ('uname', 'pwd')
201+
s.verify = False
202+
t = pd.io.common.gen_session(http_params=s)
203+
assert s == t
204+
assert s.auth == t.auth
205+
assert s.verify == t.verify
206+
207+
208+
def test_skip_requests():
209+
with pytest.raises(ValueError):
210+
a = (uname, pwd)
211+
resp, content_bytes = pd.io.common.fetch_url('http://cnn.com',
212+
http_params={'auth': a},
213+
skip_requests=True)

0 commit comments

Comments
 (0)