NBA IE (Closes #590)
[youtube-dl] / test / test_download.py
index 987f53ecb08dfc87a7c932a23fc32624518ac75b..bce0e4fcdc8e6e0595e75fdba90c7e257e5c53fa 100644 (file)
@@ -1,37 +1,95 @@
-#!/usr/bin/env python2
-import unittest
+#!/usr/bin/env python
+
 import hashlib
+import io
 import os
+import json
+import unittest
+import sys
+import socket
+
+# Allow direct execution
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+import youtube_dl.FileDownloader
+import youtube_dl.InfoExtractors
+from youtube_dl.utils import *
+
+DEF_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tests.json')
+PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
+
+# General configuration (from __init__, not very elegant...)
+jar = compat_cookiejar.CookieJar()
+cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
+proxy_handler = compat_urllib_request.ProxyHandler()
+opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
+compat_urllib_request.install_opener(opener)
+socket.setdefaulttimeout(300) # 5 minutes should be enough (famous last words)
+
+class FileDownloader(youtube_dl.FileDownloader):
+    def __init__(self, *args, **kwargs):
+        youtube_dl.FileDownloader.__init__(self, *args, **kwargs)
+        self.to_stderr = self.to_screen
+
+def _file_md5(fn):
+    with open(fn, 'rb') as f:
+        return hashlib.md5(f.read()).hexdigest()
+
+with io.open(DEF_FILE, encoding='utf-8') as deff:
+    defs = json.load(deff)
+with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
+    parameters = json.load(pf)
+
+class TestDownload(unittest.TestCase):
+    def setUp(self):
+        self.parameters = parameters
+        self.defs = defs
+
+        # Clear old files
+        self.tearDown()
+
+    def tearDown(self):
+        for fn in [ test.get('file', False) for test in self.defs ]:
+            if fn and os.path.exists(fn):
+                os.remove(fn)
+
+
+### Dinamically generate tests
+def generator(test_case):
+
+    def test_template(self):
+        ie = getattr(youtube_dl.InfoExtractors, test_case['name'] + 'IE')
+        if not ie._WORKING:
+            print('Skipping: IE marked as not _WORKING')
+            return
+        if not test_case['file']:
+            print('Skipping: No output file specified')
+            return
+        if 'skip' in test_case:
+            print('Skipping: {0}'.format(test_case['skip']))
+            return
+        params = dict(self.parameters) # Duplicate it locally
+        for p in test_case.get('params', {}):
+            params[p] = test_case['params'][p]
+        fd = FileDownloader(params)
+        fd.add_info_extractor(ie())
+        for ien in test_case.get('add_ie', []):
+            fd.add_info_extractor(getattr(youtube_dl.InfoExtractors, ien + 'IE')())
+        fd.download([test_case['url']])
+        self.assertTrue(os.path.exists(test_case['file']))
+        if 'md5' in test_case:
+            md5_for_file = _file_md5(test_case['file'])
+            self.assertEqual(md5_for_file, test_case['md5'])
+
+    return test_template
+
+### And add them to TestDownload
+for test_case in defs:
+    test_method = generator(test_case)
+    test_method.__name__ = "test_{0}".format(test_case["name"])
+    setattr(TestDownload, test_method.__name__, test_method)
+    del test_method
+
 
-from youtube_dl.FileDownloader import FileDownloader
-from youtube_dl.InfoExtractors  import YoutubeIE
-
-class DownloadTest(unittest.TestCase):
-    #calculated with the md5sum utility
-    #md5sum (GNU coreutils) 8.19
-    YOUTUBE_MD5 = "8547978241cb87dd6782b10b8e90acc3"
-    YOUTUBE_URL = "http://www.youtube.com/watch?v=BaW_jenozKc"
-    YOUTUBE_FILE = "BaW_jenozKc.flv"
-
-    def test_youtube(self):
-        #let's download a file from youtube
-        global YOUTUBE_URL
-        fd = FileDownloader({})
-        fd.add_info_extractor(YoutubeIE())
-        fd.download([DownloadTest.YOUTUBE_URL])
-        self.assertTrue(os.path.exists(DownloadTest.YOUTUBE_FILE))
-        md5_down_file = md5_for_file(DownloadTest.YOUTUBE_FILE)
-        self.assertEqual(md5_down_file, DownloadTest.YOUTUBE_MD5)
-
-    def cleanUp(self):
-        if os.path.exists(DownloadTest.YOUTUBE_FILE):
-            os.remove(DownloadTest.YOUTUBE_FILE)
-
-def md5_for_file(f, block_size=2**20):
-    md5 = hashlib.md5()
-    while True:
-        data = f.read(block_size)
-        if not data:
-            break
-        md5.update(data)
-        return md5.digest()
+if __name__ == '__main__':
+    unittest.main()