]> jfr.im git - yt-dlp.git/blame - test/test_download.py
print WARNINGs during test + minor fix to NBAIE
[yt-dlp.git] / test / test_download.py
CommitLineData
fd5ff020
FV
1#!/usr/bin/env python
2
5c892b0b 3import errno
efe8902f 4import hashlib
fd5ff020 5import io
efe8902f 6import os
7f60b5aa 7import json
cdab8aa3
PH
8import unittest
9import sys
0eaf520d 10import hashlib
6b3aef80 11import socket
fd5ff020
FV
12
13# Allow direct execution
14sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
cdab8aa3 15
fd5ff020
FV
16import youtube_dl.FileDownloader
17import youtube_dl.InfoExtractors
18from youtube_dl.utils import *
1535ac2a 19
20DEF_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tests.json')
fd5ff020
FV
21PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
22
8cc83b8d
FV
23RETRIES = 3
24
fd5ff020
FV
25# General configuration (from __init__, not very elegant...)
26jar = compat_cookiejar.CookieJar()
27cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
28proxy_handler = compat_urllib_request.ProxyHandler()
29opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
30compat_urllib_request.install_opener(opener)
d8bbf201 31socket.setdefaulttimeout(10)
fd5ff020 32
5c892b0b
PH
33def _try_rm(filename):
34 """ Remove a file if it exists """
35 try:
36 os.remove(filename)
37 except OSError as ose:
38 if ose.errno != errno.ENOENT:
39 raise
40
fd5ff020
FV
41class FileDownloader(youtube_dl.FileDownloader):
42 def __init__(self, *args, **kwargs):
476203d0 43 self._to_stderr = self.to_stderr
fd5ff020 44 self.to_stderr = self.to_screen
0eaf520d
FV
45 self.processed_info_dicts = []
46 return youtube_dl.FileDownloader.__init__(self, *args, **kwargs)
476203d0
FV
47 def report_warning(self, message):
48 # let warnings pass to output
49 if sys.stderr.isatty() and os.name != 'nt':
50 _msg_header=u'\033[0;33mWARNING:\033[0m'
51 else:
52 _msg_header=u'WARNING:'
53 warning_message=u'%s %s' % (_msg_header,message)
54 self._to_stderr(warning_message)
0eaf520d
FV
55 def process_info(self, info_dict):
56 self.processed_info_dicts.append(info_dict)
57 return youtube_dl.FileDownloader.process_info(self, info_dict)
1535ac2a 58
fd5ff020
FV
59def _file_md5(fn):
60 with open(fn, 'rb') as f:
61 return hashlib.md5(f.read()).hexdigest()
62
63with io.open(DEF_FILE, encoding='utf-8') as deff:
64 defs = json.load(deff)
65with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
66 parameters = json.load(pf)
1535ac2a 67
0eaf520d 68
1535ac2a 69class TestDownload(unittest.TestCase):
744435f2 70 maxDiff = None
fd5ff020
FV
71 def setUp(self):
72 self.parameters = parameters
73 self.defs = defs
74
911ee27e 75### Dynamically generate tests
5d01a647
PH
76def generator(test_case):
77
1535ac2a 78 def test_template(self):
ba7c775a 79 ie = youtube_dl.InfoExtractors.get_info_extractor(test_case['name'])
fd5ff020
FV
80 if not ie._WORKING:
81 print('Skipping: IE marked as not _WORKING')
82 return
5c892b0b 83 if 'playlist' not in test_case and not test_case['file']:
6985325e
PH
84 print('Skipping: No output file specified')
85 return
fd5ff020
FV
86 if 'skip' in test_case:
87 print('Skipping: {0}'.format(test_case['skip']))
88 return
0eaf520d 89
c073e35b
PH
90 params = self.parameters.copy()
91 params.update(test_case.get('params', {}))
0eaf520d 92
fd5ff020 93 fd = FileDownloader(params)
f375d4b7
FV
94 for ie in youtube_dl.InfoExtractors.gen_extractors():
95 fd.add_info_extractor(ie)
bffbd5f0
PH
96 finished_hook_called = set()
97 def _hook(status):
98 if status['status'] == 'finished':
99 finished_hook_called.add(status['filename'])
100 fd.add_progress_hook(_hook)
5c892b0b
PH
101
102 test_cases = test_case.get('playlist', [test_case])
103 for tc in test_cases:
104 _try_rm(tc['file'])
3a648b20 105 _try_rm(tc['file'] + '.part')
5c892b0b
PH
106 _try_rm(tc['file'] + '.info.json')
107 try:
8cc83b8d
FV
108 for retry in range(1, RETRIES + 1):
109 try:
110 fd.download([test_case['url']])
111 except (DownloadError, ExtractorError) as err:
112 if retry == RETRIES: raise
113
114 # Check if the exception is not a network related one
90a99c1b 115 if not err.exc_info[0] in (compat_urllib_error.URLError, socket.timeout, UnavailableVideoError):
8cc83b8d
FV
116 raise
117
118 print('Retrying: {0} failed tries\n\n##########\n\n'.format(retry))
119 else:
120 break
5c892b0b
PH
121
122 for tc in test_cases:
511eda8e 123 if not test_case.get('params', {}).get('skip_download', False):
233a2296 124 self.assertTrue(os.path.exists(tc['file']), msg='Missing file ' + tc['file'])
bffbd5f0 125 self.assertTrue(tc['file'] in finished_hook_called)
5c892b0b
PH
126 self.assertTrue(os.path.exists(tc['file'] + '.info.json'))
127 if 'md5' in tc:
128 md5_for_file = _file_md5(tc['file'])
129 self.assertEqual(md5_for_file, tc['md5'])
130 with io.open(tc['file'] + '.info.json', encoding='utf-8') as infof:
131 info_dict = json.load(infof)
132 for (info_field, value) in tc.get('info_dict', {}).items():
30e9f449 133 self.assertEqual(value, info_dict.get(info_field))
5c892b0b
PH
134 finally:
135 for tc in test_cases:
136 _try_rm(tc['file'])
3a648b20 137 _try_rm(tc['file'] + '.part')
5c892b0b 138 _try_rm(tc['file'] + '.info.json')
fd5ff020 139
1535ac2a 140 return test_template
fd5ff020 141
5d01a647 142### And add them to TestDownload
fd5ff020 143for test_case in defs:
5d01a647 144 test_method = generator(test_case)
fd5ff020
FV
145 test_method.__name__ = "test_{0}".format(test_case["name"])
146 setattr(TestDownload, test_method.__name__, test_method)
5d01a647 147 del test_method
cdab8aa3
PH
148
149
150if __name__ == '__main__':
151 unittest.main()