Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test__datasource.py329 linesDownload Raw Back to tests
1import os
2import urllib.request as urllib_request
3from shutil import rmtree
4from tempfile import NamedTemporaryFile, mkdtemp, mkstemp
5from urllib.error import URLError
6from urllib.parse import urlparse
7
8import pytest
9
10import numpy.lib._datasource as datasource
11from numpy.testing import assert_, assert_equal, assert_raises
12
13
14def urlopen_stub(url, data=None):
15    '''Stub to replace urlopen for testing.'''
16    if url == valid_httpurl():
17        tmpfile = NamedTemporaryFile(prefix='urltmp_')
18        return tmpfile
19    else:
20        raise URLError('Name or service not known')
21
22
23# setup and teardown
24old_urlopen = None
25
26
27def setup_module():
28    global old_urlopen
29
30    old_urlopen = urllib_request.urlopen
31    urllib_request.urlopen = urlopen_stub
32
33
34def teardown_module():
35    urllib_request.urlopen = old_urlopen
36
37
38# A valid website for more robust testing
39http_path = 'http://www.google.com/'
40http_file = 'index.html'
41
42http_fakepath = 'http://fake.abc.web/site/'
43http_fakefile = 'fake.txt'
44
45malicious_files = ['/etc/shadow', '../../shadow',
46                   '..\\system.dat', 'c:\\windows\\system.dat']
47
48magic_line = b'three is the magic number'
49
50
51# Utility functions used by many tests
52def valid_textfile(filedir):
53    # Generate and return a valid temporary file.
54    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir, text=True)
55    os.close(fd)
56    return path
57
58
59def invalid_textfile(filedir):
60    # Generate and return an invalid filename.
61    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir)
62    os.close(fd)
63    os.remove(path)
64    return path
65
66
67def valid_httpurl():
68    return http_path + http_file
69
70
71def invalid_httpurl():
72    return http_fakepath + http_fakefile
73
74
75def valid_baseurl():
76    return http_path
77
78
79def invalid_baseurl():
80    return http_fakepath
81
82
83def valid_httpfile():
84    return http_file
85
86
87def invalid_httpfile():
88    return http_fakefile
89
90
91class TestDataSourceOpen:
92    def test_ValidHTTP(self, tmp_path):
93        ds = datasource.DataSource(tmp_path)
94        fh = ds.open(valid_httpurl())
95        assert_(fh)
96        fh.close()
97
98    def test_InvalidHTTP(self, tmp_path):
99        ds = datasource.DataSource(tmp_path)
100        url = invalid_httpurl()
101        assert_raises(OSError, ds.open, url)
102        try:
103            ds.open(url)
104        except OSError as e:
105            # Regression test for bug fixed in r4342.
106            assert_(e.errno is None)
107
108    def test_InvalidHTTPCacheURLError(self, tmp_path):
109        ds = datasource.DataSource(tmp_path)
110        assert_raises(URLError, ds._cache, invalid_httpurl())
111
112    def test_ValidFile(self, tmp_path):
113        ds = datasource.DataSource(tmp_path)
114        local_file = valid_textfile(tmp_path)
115        fh = ds.open(local_file)
116        assert_(fh)
117        fh.close()
118
119    def test_InvalidFile(self, tmp_path):
120        ds = datasource.DataSource(tmp_path)
121        invalid_file = invalid_textfile(tmp_path)
122        assert_raises(OSError, ds.open, invalid_file)
123
124    def test_ValidGzipFile(self, tmp_path):
125        try:
126            import gzip
127        except ImportError:
128            # We don't have the gzip capabilities to test.
129            pytest.skip()
130        # Test datasource's internal file_opener for Gzip files.
131        ds = datasource.DataSource(tmp_path)
132        filepath = os.path.join(tmp_path, 'foobar.txt.gz')
133        fp = gzip.open(filepath, 'w')
134        fp.write(magic_line)
135        fp.close()
136        fp = ds.open(filepath)
137        result = fp.readline()
138        fp.close()
139        assert_equal(magic_line, result)
140
141    def test_ValidBz2File(self, tmp_path):
142        try:
143            import bz2
144        except ImportError:
145            # We don't have the bz2 capabilities to test.
146            pytest.skip()
147        # Test datasource's internal file_opener for BZip2 files.
148        ds = datasource.DataSource(tmp_path)
149        filepath = os.path.join(tmp_path, 'foobar.txt.bz2')
150        fp = bz2.BZ2File(filepath, 'w')
151        fp.write(magic_line)
152        fp.close()
153        fp = ds.open(filepath)
154        result = fp.readline()
155        fp.close()
156        assert_equal(magic_line, result)
157
158
159class TestDataSourceExists:
160    def test_ValidHTTP(self, tmp_path):
161        ds = datasource.DataSource(tmp_path)
162        assert_(ds.exists(valid_httpurl()))
163
164    def test_InvalidHTTP(self, tmp_path):
165        ds = datasource.DataSource(tmp_path)
166        assert_equal(ds.exists(invalid_httpurl()), False)
167
168    def test_ValidFile(self, tmp_path):
169        # Test valid file in destpath
170        ds = datasource.DataSource(tmp_path)
171        tmpfile = valid_textfile(tmp_path)
172        assert_(ds.exists(tmpfile))
173        # Test valid local file not in destpath
174        localdir = mkdtemp()
175        tmpfile = valid_textfile(localdir)
176        assert_(ds.exists(tmpfile))
177        rmtree(localdir)
178
179    def test_InvalidFile(self, tmp_path):
180        ds = datasource.DataSource(tmp_path)
181        tmpfile = invalid_textfile(tmp_path)
182        assert_equal(ds.exists(tmpfile), False)
183
184
185class TestDataSourceAbspath:
186    def test_ValidHTTP(self, tmp_path):
187        ds = datasource.DataSource(tmp_path)
188        _, netloc, upath, _, _, _ = urlparse(valid_httpurl())
189        local_path = os.path.join(tmp_path, netloc,
190                                  upath.strip(os.sep).strip('/'))
191        assert_equal(local_path, ds.abspath(valid_httpurl()))
192
193    def test_ValidFile(self, tmp_path):
194        ds = datasource.DataSource(tmp_path)
195        tmpfile = valid_textfile(tmp_path)
196        tmpfilename = os.path.split(tmpfile)[-1]
197        # Test with filename only
198        assert_equal(tmpfile, ds.abspath(tmpfilename))
199        # Test filename with complete path
200        assert_equal(tmpfile, ds.abspath(tmpfile))
201
202    def test_InvalidHTTP(self, tmp_path):
203        ds = datasource.DataSource(tmp_path)
204        _, netloc, upath, _, _, _ = urlparse(invalid_httpurl())
205        invalidhttp = os.path.join(tmp_path, netloc,
206                                   upath.strip(os.sep).strip('/'))
207        assert_(invalidhttp != ds.abspath(valid_httpurl()))
208
209    def test_InvalidFile(self, tmp_path):
210        ds = datasource.DataSource(tmp_path)
211        invalidfile = valid_textfile(tmp_path)
212        tmpfile = valid_textfile(tmp_path)
213        tmpfilename = os.path.split(tmpfile)[-1]
214        # Test with filename only
215        assert_(invalidfile != ds.abspath(tmpfilename))
216        # Test filename with complete path
217        assert_(invalidfile != ds.abspath(tmpfile))
218
219    def test_sandboxing(self, tmp_path):
220        ds = datasource.DataSource(tmp_path)
221        tmpfile = valid_textfile(tmp_path)
222        tmpfilename = os.path.split(tmpfile)[-1]
223
224        path = lambda x: os.path.abspath(ds.abspath(x))
225
226        assert_(path(valid_httpurl()).startswith(str(tmp_path)))
227        assert_(path(invalid_httpurl()).startswith(str(tmp_path)))
228        assert_(path(tmpfile).startswith(str(tmp_path)))
229        assert_(path(tmpfilename).startswith(str(tmp_path)))
230        for fn in malicious_files:
231            assert_(path(http_path + fn).startswith(str(tmp_path)))
232            assert_(path(fn).startswith(str(tmp_path)))
233
234    def test_windows_os_sep(self, tmp_path):
235        orig_os_sep = os.sep
236        try:
237            os.sep = '\\'
238            self.test_ValidHTTP(tmp_path)
239            self.test_ValidFile(tmp_path)
240            self.test_InvalidHTTP(tmp_path)
241            self.test_InvalidFile(tmp_path)
242            self.test_sandboxing(tmp_path)
243        finally:
244            os.sep = orig_os_sep
245
246
247class TestRepositoryAbspath:
248    def test_ValidHTTP(self, tmp_path):
249        repos = datasource.Repository(valid_baseurl(), tmp_path)
250        _, netloc, upath, _, _, _ = urlparse(valid_httpurl())
251        local_path = os.path.join(repos._destpath, netloc,
252                                  upath.strip(os.sep).strip('/'))
253        filepath = repos.abspath(valid_httpfile())
254        assert_equal(local_path, filepath)
255
256    def test_sandboxing(self, tmp_path):
257        repos = datasource.Repository(valid_baseurl(), tmp_path)
258        path = lambda x: os.path.abspath(repos.abspath(x))
259        assert_(path(valid_httpfile()).startswith(str(tmp_path)))
260        for fn in malicious_files:
261            assert_(path(http_path + fn).startswith(str(tmp_path)))
262            assert_(path(fn).startswith(str(tmp_path)))
263
264    def test_windows_os_sep(self, tmp_path):
265        orig_os_sep = os.sep
266        try:
267            os.sep = '\\'
268            self.test_ValidHTTP(tmp_path)
269            self.test_sandboxing(tmp_path)
270        finally:
271            os.sep = orig_os_sep
272
273
274class TestRepositoryExists:
275    def test_ValidFile(self, tmp_path):
276        # Create local temp file
277        repos = datasource.Repository(valid_baseurl(), tmp_path)
278        tmpfile = valid_textfile(tmp_path)
279        assert_(repos.exists(tmpfile))
280
281    def test_InvalidFile(self, tmp_path):
282        repos = datasource.Repository(valid_baseurl(), tmp_path)
283        tmpfile = invalid_textfile(tmp_path)
284        assert_equal(repos.exists(tmpfile), False)
285
286    def test_RemoveHTTPFile(self, tmp_path):
287        repos = datasource.Repository(valid_baseurl(), tmp_path)
288        assert_(repos.exists(valid_httpurl()))
289
290    def test_CachedHTTPFile(self, tmp_path):
291        localfile = valid_httpurl()
292        # Create a locally cached temp file with an URL based
293        # directory structure.  This is similar to what Repository.open
294        # would do.
295        repos = datasource.Repository(valid_baseurl(), tmp_path)
296        _, netloc, _, _, _, _ = urlparse(localfile)
297        local_path = os.path.join(repos._destpath, netloc)
298        os.mkdir(local_path, 0o0700)
299        tmpfile = valid_textfile(local_path)
300        assert_(repos.exists(tmpfile))
301
302
303class TestOpenFunc:
304    def test_DataSourceOpen(self, tmp_path):
305        local_file = valid_textfile(tmp_path)
306        # Test case where destpath is passed in
307        fp = datasource.open(local_file, destpath=tmp_path)
308        assert_(fp)
309        fp.close()
310        # Test case where default destpath is used
311        fp = datasource.open(local_file)
312        assert_(fp)
313        fp.close()
314
315def test_del_attr_handling():
316    # DataSource __del__ can be called
317    # even if __init__ fails when the
318    # Exception object is caught by the
319    # caller as happens in refguide_check
320    # is_deprecated() function
321
322    ds = datasource.DataSource()
323    # simulate failed __init__ by removing key attribute
324    # produced within __init__ and expected by __del__
325    del ds._istmpdest
326    # should not raise an AttributeError if __del__
327    # gracefully handles failed __init__:
328    ds.__del__()
329 
codekingpro/portable-devtools · Team Ai